1 //===-- DynamicLoaderMacOSXDYLD.cpp -----------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Breakpoint/StoppointCallbackContext.h" 11 #include "lldb/Core/DataBuffer.h" 12 #include "lldb/Core/DataBufferHeap.h" 13 #include "lldb/Core/Log.h" 14 #include "lldb/Core/Module.h" 15 #include "lldb/Core/PluginManager.h" 16 #include "lldb/Core/State.h" 17 #include "lldb/Symbol/ObjectFile.h" 18 #include "lldb/Target/ObjCLanguageRuntime.h" 19 #include "lldb/Target/RegisterContext.h" 20 #include "lldb/Target/Target.h" 21 #include "lldb/Target/Thread.h" 22 #include "lldb/Target/ThreadPlanRunToAddress.h" 23 #include "lldb/Target/StackFrame.h" 24 25 #include "DynamicLoaderMacOSXDYLD.h" 26 27 //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN 28 #ifdef ENABLE_DEBUG_PRINTF 29 #include <stdio.h> 30 #define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__) 31 #else 32 #define DEBUG_PRINTF(fmt, ...) 33 #endif 34 35 using namespace lldb; 36 using namespace lldb_private; 37 38 /// FIXME - The ObjC Runtime trampoline handler doesn't really belong here. 39 /// I am putting it here so I can invoke it in the Trampoline code here, but 40 /// it should be moved to the ObjC Runtime support when it is set up. 41 42 43 DynamicLoaderMacOSXDYLD::DYLDImageInfo * 44 DynamicLoaderMacOSXDYLD::GetImageInfo (Module *module) 45 { 46 const UUID &module_uuid = module->GetUUID(); 47 DYLDImageInfo::collection::iterator pos, end = m_dyld_image_infos.end(); 48 49 // First try just by UUID as it is the safest. 50 if (module_uuid.IsValid()) 51 { 52 for (pos = m_dyld_image_infos.begin(); pos != end; ++pos) 53 { 54 if (pos->uuid == module_uuid) 55 return &(*pos); 56 } 57 58 if (m_dyld.uuid == module_uuid) 59 return &m_dyld; 60 } 61 62 // Next try by platform path only for things that don't have a valid UUID 63 // since if a file has a valid UUID in real life it should also in the 64 // dyld info. This is the next safest because the paths in the dyld info 65 // are platform paths, not local paths. For local debugging platform == local 66 // paths. 67 const FileSpec &platform_file_spec = module->GetPlatformFileSpec(); 68 for (pos = m_dyld_image_infos.begin(); pos != end; ++pos) 69 { 70 if (pos->file_spec == platform_file_spec && pos->uuid.IsValid() == false) 71 return &(*pos); 72 } 73 74 if (m_dyld.file_spec == platform_file_spec && m_dyld.uuid.IsValid() == false) 75 return &m_dyld; 76 77 return NULL; 78 } 79 80 //---------------------------------------------------------------------- 81 // Create an instance of this class. This function is filled into 82 // the plugin info class that gets handed out by the plugin factory and 83 // allows the lldb to instantiate an instance of this class. 84 //---------------------------------------------------------------------- 85 DynamicLoader * 86 DynamicLoaderMacOSXDYLD::CreateInstance (Process* process, bool force) 87 { 88 bool create = force; 89 if (!create) 90 { 91 const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple(); 92 if (triple_ref.getOS() == llvm::Triple::Darwin && triple_ref.getVendor() == llvm::Triple::Apple) 93 create = true; 94 } 95 96 if (create) 97 return new DynamicLoaderMacOSXDYLD (process); 98 return NULL; 99 } 100 101 //---------------------------------------------------------------------- 102 // Constructor 103 //---------------------------------------------------------------------- 104 DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD (Process* process) : 105 DynamicLoader(process), 106 m_dyld(), 107 m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS), 108 m_dyld_all_image_infos(), 109 m_dyld_all_image_infos_stop_id (UINT32_MAX), 110 m_break_id(LLDB_INVALID_BREAK_ID), 111 m_dyld_image_infos(), 112 m_dyld_image_infos_stop_id (UINT32_MAX), 113 m_mutex(Mutex::eMutexTypeRecursive) 114 { 115 } 116 117 //---------------------------------------------------------------------- 118 // Destructor 119 //---------------------------------------------------------------------- 120 DynamicLoaderMacOSXDYLD::~DynamicLoaderMacOSXDYLD() 121 { 122 Clear(true); 123 } 124 125 //------------------------------------------------------------------ 126 /// Called after attaching a process. 127 /// 128 /// Allow DynamicLoader plug-ins to execute some code after 129 /// attaching to a process. 130 //------------------------------------------------------------------ 131 void 132 DynamicLoaderMacOSXDYLD::DidAttach () 133 { 134 PrivateInitialize(m_process); 135 LocateDYLD (); 136 SetNotificationBreakpoint (); 137 } 138 139 //------------------------------------------------------------------ 140 /// Called after attaching a process. 141 /// 142 /// Allow DynamicLoader plug-ins to execute some code after 143 /// attaching to a process. 144 //------------------------------------------------------------------ 145 void 146 DynamicLoaderMacOSXDYLD::DidLaunch () 147 { 148 PrivateInitialize(m_process); 149 LocateDYLD (); 150 SetNotificationBreakpoint (); 151 } 152 153 154 //---------------------------------------------------------------------- 155 // Clear out the state of this class. 156 //---------------------------------------------------------------------- 157 void 158 DynamicLoaderMacOSXDYLD::Clear (bool clear_process) 159 { 160 Mutex::Locker locker(m_mutex); 161 162 if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id)) 163 m_process->ClearBreakpointSiteByID(m_break_id); 164 165 if (clear_process) 166 m_process = NULL; 167 m_dyld.Clear(false); 168 m_dyld_all_image_infos_addr = LLDB_INVALID_ADDRESS; 169 m_dyld_all_image_infos.Clear(); 170 m_break_id = LLDB_INVALID_BREAK_ID; 171 m_dyld_image_infos.clear(); 172 } 173 174 //---------------------------------------------------------------------- 175 // Check if we have found DYLD yet 176 //---------------------------------------------------------------------- 177 bool 178 DynamicLoaderMacOSXDYLD::DidSetNotificationBreakpoint() const 179 { 180 return LLDB_BREAK_ID_IS_VALID (m_break_id); 181 } 182 183 //---------------------------------------------------------------------- 184 // Try and figure out where dyld is by first asking the Process 185 // if it knows (which currently calls down in the the lldb::Process 186 // to get the DYLD info (available on SnowLeopard only). If that fails, 187 // then check in the default addresses. 188 //---------------------------------------------------------------------- 189 bool 190 DynamicLoaderMacOSXDYLD::LocateDYLD() 191 { 192 if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS) 193 m_dyld_all_image_infos_addr = m_process->GetImageInfoAddress (); 194 195 if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) 196 { 197 if (ReadAllImageInfosStructure ()) 198 { 199 if (m_dyld_all_image_infos.dyldImageLoadAddress != LLDB_INVALID_ADDRESS) 200 return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos.dyldImageLoadAddress); 201 else 202 return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos_addr & 0xfffffffffff00000ull); 203 } 204 } 205 206 // Check some default values 207 Module *executable = m_process->GetTarget().GetExecutableModule().get(); 208 209 if (executable) 210 { 211 if (executable->GetArchitecture().GetAddressByteSize() == 8) 212 { 213 return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x7fff5fc00000ull); 214 } 215 #if defined (__arm__) 216 else 217 { 218 ArchSpec arm_arch("arm"); 219 if (arm_arch == executable->Arch()) 220 return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x2fe00000); 221 } 222 #endif 223 return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x8fe00000); 224 } 225 return false; 226 } 227 228 ModuleSP 229 DynamicLoaderMacOSXDYLD::FindTargetModuleForDYLDImageInfo (const DYLDImageInfo &image_info, bool can_create, bool *did_create_ptr) 230 { 231 if (did_create_ptr) 232 *did_create_ptr = false; 233 ModuleSP module_sp; 234 ModuleList &target_images = m_process->GetTarget().GetImages(); 235 const bool image_info_uuid_is_valid = image_info.uuid.IsValid(); 236 if (image_info_uuid_is_valid) 237 module_sp = target_images.FindModule(image_info.uuid); 238 239 if (!module_sp) 240 { 241 ArchSpec arch(image_info.GetArchitecture ()); 242 243 module_sp = target_images.FindFirstModuleForFileSpec (image_info.file_spec, &arch, NULL); 244 245 if (can_create && !module_sp) 246 { 247 module_sp = m_process->GetTarget().GetSharedModule (image_info.file_spec, 248 arch, 249 image_info_uuid_is_valid ? &image_info.uuid : NULL); 250 if (did_create_ptr) 251 *did_create_ptr = module_sp; 252 } 253 } 254 return module_sp; 255 } 256 257 //---------------------------------------------------------------------- 258 // Assume that dyld is in memory at ADDR and try to parse it's load 259 // commands 260 //---------------------------------------------------------------------- 261 bool 262 DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::addr_t addr) 263 { 264 DataExtractor data; // Load command data 265 if (ReadMachHeader (addr, &m_dyld.header, &data)) 266 { 267 if (m_dyld.header.filetype == llvm::MachO::HeaderFileTypeDynamicLinkEditor) 268 { 269 m_dyld.address = addr; 270 ModuleSP dyld_module_sp; 271 if (ParseLoadCommands (data, m_dyld, &m_dyld.file_spec)) 272 { 273 if (m_dyld.file_spec) 274 { 275 dyld_module_sp = FindTargetModuleForDYLDImageInfo (m_dyld, true, NULL); 276 277 if (dyld_module_sp) 278 UpdateImageLoadAddress (dyld_module_sp.get(), m_dyld); 279 } 280 } 281 282 if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS && dyld_module_sp.get()) 283 { 284 static ConstString g_dyld_all_image_infos ("dyld_all_image_infos"); 285 const Symbol *symbol = dyld_module_sp->FindFirstSymbolWithNameAndType (g_dyld_all_image_infos, eSymbolTypeData); 286 if (symbol) 287 m_dyld_all_image_infos_addr = symbol->GetValue().GetLoadAddress(&m_process->GetTarget()); 288 } 289 290 // Update all image infos 291 UpdateAllImageInfos(); 292 293 // If we didn't have an executable before, but now we do, then the 294 // dyld module shared pointer might be unique and we may need to add 295 // it again (since Target::SetExecutableModule() will clear the 296 // images). So append the dyld module back to the list if it is 297 /// unique! 298 if (dyld_module_sp && m_process->GetTarget().GetImages().AppendIfNeeded (dyld_module_sp)) 299 UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld); 300 301 return true; 302 } 303 } 304 return false; 305 } 306 307 bool 308 DynamicLoaderMacOSXDYLD::NeedToLocateDYLD () const 309 { 310 return m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS; 311 } 312 313 bool 314 DynamicLoaderMacOSXDYLD::UpdateCommPageLoadAddress(Module *module) 315 { 316 bool changed = false; 317 if (module) 318 { 319 ObjectFile *image_object_file = module->GetObjectFile(); 320 if (image_object_file) 321 { 322 SectionList *section_list = image_object_file->GetSectionList (); 323 if (section_list) 324 { 325 uint32_t num_sections = section_list->GetSize(); 326 for (uint32_t i=0; i<num_sections; ++i) 327 { 328 Section* section = section_list->GetSectionAtIndex (i).get(); 329 if (section) 330 { 331 const addr_t new_section_load_addr = section->GetFileAddress (); 332 const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section); 333 if (old_section_load_addr == LLDB_INVALID_ADDRESS || 334 old_section_load_addr != new_section_load_addr) 335 { 336 if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress ())) 337 changed = true; 338 } 339 } 340 } 341 } 342 } 343 } 344 return changed; 345 } 346 347 //---------------------------------------------------------------------- 348 // Update the load addresses for all segments in MODULE using the 349 // updated INFO that is passed in. 350 //---------------------------------------------------------------------- 351 bool 352 DynamicLoaderMacOSXDYLD::UpdateImageLoadAddress (Module *module, DYLDImageInfo& info) 353 { 354 bool changed = false; 355 if (module) 356 { 357 ObjectFile *image_object_file = module->GetObjectFile(); 358 if (image_object_file) 359 { 360 SectionList *section_list = image_object_file->GetSectionList (); 361 if (section_list) 362 { 363 // We now know the slide amount, so go through all sections 364 // and update the load addresses with the correct values. 365 uint32_t num_segments = info.segments.size(); 366 for (uint32_t i=0; i<num_segments; ++i) 367 { 368 SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name)); 369 assert (section_sp.get() != NULL); 370 const addr_t new_section_load_addr = info.segments[i].vmaddr + info.slide; 371 const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp.get()); 372 if (old_section_load_addr == LLDB_INVALID_ADDRESS || 373 old_section_load_addr != new_section_load_addr) 374 { 375 if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), new_section_load_addr)) 376 changed = true; 377 } 378 } 379 } 380 } 381 } 382 return changed; 383 } 384 385 //---------------------------------------------------------------------- 386 // Update the load addresses for all segments in MODULE using the 387 // updated INFO that is passed in. 388 //---------------------------------------------------------------------- 389 bool 390 DynamicLoaderMacOSXDYLD::UnloadImageLoadAddress (Module *module, DYLDImageInfo& info) 391 { 392 bool changed = false; 393 if (module) 394 { 395 ObjectFile *image_object_file = module->GetObjectFile(); 396 if (image_object_file) 397 { 398 SectionList *section_list = image_object_file->GetSectionList (); 399 if (section_list) 400 { 401 uint32_t num_segments = info.segments.size(); 402 for (uint32_t i=0; i<num_segments; ++i) 403 { 404 SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name)); 405 assert (section_sp.get() != NULL); 406 const addr_t old_section_load_addr = info.segments[i].vmaddr + info.slide; 407 if (m_process->GetTarget().GetSectionLoadList().SetSectionUnloaded (section_sp.get(), old_section_load_addr)) 408 changed = true; 409 } 410 } 411 } 412 } 413 return changed; 414 } 415 416 417 //---------------------------------------------------------------------- 418 // Static callback function that gets called when our DYLD notification 419 // breakpoint gets hit. We update all of our image infos and then 420 // let our super class DynamicLoader class decide if we should stop 421 // or not (based on global preference). 422 //---------------------------------------------------------------------- 423 bool 424 DynamicLoaderMacOSXDYLD::NotifyBreakpointHit (void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id) 425 { 426 // Let the event know that the images have changed 427 DynamicLoaderMacOSXDYLD* dyld_instance = (DynamicLoaderMacOSXDYLD*) baton; 428 dyld_instance->UpdateAllImageInfos(); 429 // Return true to stop the target, false to just let the target run 430 return dyld_instance->GetStopWhenImagesChange(); 431 } 432 433 bool 434 DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure () 435 { 436 Mutex::Locker locker(m_mutex); 437 438 // the all image infos is already valid for this process stop ID 439 if (m_process->GetStopID() == m_dyld_all_image_infos_stop_id) 440 return true; 441 442 m_dyld_all_image_infos.Clear(); 443 if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) 444 { 445 ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder(); 446 uint32_t addr_size = 4; 447 if (m_dyld_all_image_infos_addr > UINT32_MAX) 448 addr_size = 8; 449 450 uint8_t buf[256]; 451 DataExtractor data (buf, sizeof(buf), byte_order, addr_size); 452 uint32_t offset = 0; 453 454 const size_t count_v2 = sizeof (uint32_t) + // version 455 sizeof (uint32_t) + // infoArrayCount 456 addr_size + // infoArray 457 addr_size + // notification 458 addr_size + // processDetachedFromSharedRegion + libSystemInitialized + pad 459 addr_size; // dyldImageLoadAddress 460 const size_t count_v11 = count_v2 + 461 addr_size + // jitInfo 462 addr_size + // dyldVersion 463 addr_size + // errorMessage 464 addr_size + // terminationFlags 465 addr_size + // coreSymbolicationShmPage 466 addr_size + // systemOrderFlag 467 addr_size + // uuidArrayCount 468 addr_size + // uuidArray 469 addr_size + // dyldAllImageInfosAddress 470 addr_size + // initialImageCount 471 addr_size + // errorKind 472 addr_size + // errorClientOfDylibPath 473 addr_size + // errorTargetDylibPath 474 addr_size; // errorSymbol 475 assert (sizeof (buf) > count_v11); 476 477 int count; 478 Error error; 479 if (m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, 4, error) == 4) 480 { 481 m_dyld_all_image_infos.version = data.GetU32(&offset); 482 // If anything in the high byte is set, we probably got the byte 483 // order incorrect (the process might not have it set correctly 484 // yet due to attaching to a program without a specified file). 485 if (m_dyld_all_image_infos.version & 0xff000000) 486 { 487 // We have guessed the wrong byte order. Swap it and try 488 // reading the version again. 489 if (byte_order == eByteOrderLittle) 490 byte_order = eByteOrderBig; 491 else 492 byte_order = eByteOrderLittle; 493 494 data.SetByteOrder (byte_order); 495 offset = 0; 496 m_dyld_all_image_infos.version = data.GetU32(&offset); 497 } 498 } 499 else 500 { 501 return false; 502 } 503 504 if (m_dyld_all_image_infos.version >= 11) 505 count = count_v11; 506 else 507 count = count_v2; 508 509 const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, count, error); 510 if (bytes_read == count) 511 { 512 offset = 0; 513 m_dyld_all_image_infos.version = data.GetU32(&offset); 514 m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset); 515 m_dyld_all_image_infos.dylib_info_addr = data.GetPointer(&offset); 516 m_dyld_all_image_infos.notification = data.GetPointer(&offset); 517 m_dyld_all_image_infos.processDetachedFromSharedRegion = data.GetU8(&offset); 518 m_dyld_all_image_infos.libSystemInitialized = data.GetU8(&offset); 519 // Adjust for padding. 520 offset += addr_size - 2; 521 m_dyld_all_image_infos.dyldImageLoadAddress = data.GetPointer(&offset); 522 if (m_dyld_all_image_infos.version >= 11) 523 { 524 offset += addr_size * 8; 525 uint64_t dyld_all_image_infos_addr = data.GetPointer(&offset); 526 527 // When we started, we were given the actual address of the all_image_infos 528 // struct (probably via TASK_DYLD_INFO) in memory - this address is stored in 529 // m_dyld_all_image_infos_addr and is the most accurate address we have. 530 531 // We read the dyld_all_image_infos struct from memory; it contains its own address. 532 // If the address in the struct does not match the actual address, 533 // the dyld we're looking at has been loaded at a different location (slid) from 534 // where it intended to load. The addresses in the dyld_all_image_infos struct 535 // are the original, non-slid addresses, and need to be adjusted. Most importantly 536 // the address of dyld and the notification address need to be adjusted. 537 538 if (dyld_all_image_infos_addr != m_dyld_all_image_infos_addr) 539 { 540 uint64_t image_infos_offset = dyld_all_image_infos_addr - m_dyld_all_image_infos.dyldImageLoadAddress; 541 uint64_t notification_offset = m_dyld_all_image_infos.notification - m_dyld_all_image_infos.dyldImageLoadAddress; 542 m_dyld_all_image_infos.dyldImageLoadAddress = m_dyld_all_image_infos_addr - image_infos_offset; 543 m_dyld_all_image_infos.notification = m_dyld_all_image_infos.dyldImageLoadAddress + notification_offset; 544 } 545 } 546 m_dyld_all_image_infos_stop_id = m_process->GetStopID(); 547 return true; 548 } 549 } 550 return false; 551 } 552 553 //---------------------------------------------------------------------- 554 // If we have found where the "_dyld_all_image_infos" lives in memory, 555 // read the current info from it, and then update all image load 556 // addresses (or lack thereof). 557 //---------------------------------------------------------------------- 558 uint32_t 559 DynamicLoaderMacOSXDYLD::UpdateAllImageInfos() 560 { 561 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 562 ModuleList& target_images = m_process->GetTarget().GetImages(); 563 564 if (ReadAllImageInfosStructure ()) 565 { 566 Mutex::Locker locker(m_mutex); 567 if (m_process->GetStopID() == m_dyld_image_infos_stop_id) 568 m_dyld_image_infos.size(); 569 570 uint32_t idx; 571 uint32_t i = 0; 572 // Since we can't downsize a vector, we must do this using the swap method 573 DYLDImageInfo::collection old_dyld_all_image_infos; 574 old_dyld_all_image_infos.swap(m_dyld_image_infos); 575 576 // If we made it here, we are assuming that the all dylib info data should 577 // be valid, lets read the info array. 578 const ByteOrder endian = m_dyld.GetByteOrder(); 579 const uint32_t addr_size = m_dyld.GetAddressByteSize(); 580 581 if (m_dyld_all_image_infos.dylib_info_count > 0) 582 { 583 if (m_dyld_all_image_infos.dylib_info_addr == 0) 584 { 585 // DYLD is updating the images right now... 586 } 587 else 588 { 589 m_dyld_image_infos.resize(m_dyld_all_image_infos.dylib_info_count); 590 const size_t count = m_dyld_image_infos.size() * 3 * addr_size; 591 DataBufferHeap info_data(count, 0); 592 Error error; 593 const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos.dylib_info_addr, 594 info_data.GetBytes(), 595 info_data.GetByteSize(), 596 error); 597 if (bytes_read == count) 598 { 599 uint32_t info_data_offset = 0; 600 DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size); 601 for (i = 0; info_data_ref.ValidOffset(info_data_offset); i++) 602 { 603 assert (i < m_dyld_image_infos.size()); 604 m_dyld_image_infos[i].address = info_data_ref.GetPointer(&info_data_offset); 605 lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset); 606 m_dyld_image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset); 607 608 char raw_path[PATH_MAX]; 609 m_process->ReadCStringFromMemory (path_addr, raw_path, sizeof(raw_path)); 610 // don't resolve the path 611 const bool resolve_path = false; 612 m_dyld_image_infos[i].file_spec.SetFile(raw_path, resolve_path); 613 } 614 assert(i == m_dyld_all_image_infos.dylib_info_count); 615 616 UpdateAllImageInfosHeaderAndLoadCommands(); 617 } 618 else 619 { 620 DEBUG_PRINTF( "unable to read all data for all_dylib_infos."); 621 m_dyld_image_infos.clear(); 622 } 623 } 624 } 625 626 // If our new list is smaller than our old list, we have unloaded 627 // some shared libraries 628 if (m_dyld_image_infos.size() != old_dyld_all_image_infos.size()) 629 { 630 ModuleList unloaded_module_list; 631 if (old_dyld_all_image_infos.size() == 0) 632 { 633 // This is the first time we are loading shared libraries, 634 // we need to make sure to trim anything that isn't in the 635 // m_dyld_image_infos out of the target module list since 636 // we might have shared libraries that got loaded from 637 // elsewhere due to DYLD_FRAMEWORK_PATH, or DYLD_LIBRARY_PATH 638 // environment variables... 639 const size_t num_images = target_images.GetSize(); 640 for (idx = 0; idx < num_images; ++idx) 641 { 642 ModuleSP module_sp (target_images.GetModuleAtIndex (idx)); 643 644 if (GetImageInfo (module_sp.get()) == NULL) 645 unloaded_module_list.AppendIfNeeded (module_sp); 646 } 647 } 648 else 649 { 650 uint32_t old_idx; 651 for (idx = 0; idx < old_dyld_all_image_infos.size(); ++idx) 652 { 653 for (old_idx = idx; old_idx < old_dyld_all_image_infos.size(); ++old_idx) 654 { 655 if (m_dyld_image_infos[idx].file_spec == old_dyld_all_image_infos[old_idx].file_spec) 656 { 657 old_dyld_all_image_infos[old_idx].address = LLDB_INVALID_ADDRESS; 658 break; 659 } 660 } 661 } 662 663 for (old_idx = 0; old_idx < old_dyld_all_image_infos.size(); ++old_idx) 664 { 665 if (old_dyld_all_image_infos[old_idx].address != LLDB_INVALID_ADDRESS) 666 { 667 if (log) 668 old_dyld_all_image_infos[old_idx].PutToLog (log.get()); 669 ModuleSP unload_image_module_sp (FindTargetModuleForDYLDImageInfo (old_dyld_all_image_infos[old_idx], false, NULL)); 670 if (unload_image_module_sp.get()) 671 { 672 if (UnloadImageLoadAddress (unload_image_module_sp.get(), old_dyld_all_image_infos[old_idx])) 673 unloaded_module_list.AppendIfNeeded (unload_image_module_sp); 674 } 675 } 676 } 677 } 678 679 if (unloaded_module_list.GetSize() > 0) 680 { 681 if (log) 682 { 683 log->PutCString("Unloaded:"); 684 unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload"); 685 } 686 m_process->GetTarget().ModulesDidUnload (unloaded_module_list); 687 } 688 } 689 else 690 { 691 if (log) 692 PutToLog(log.get()); 693 } 694 m_dyld_image_infos_stop_id = m_process->GetStopID(); 695 } 696 else 697 { 698 m_dyld_image_infos.clear(); 699 } 700 701 const uint32_t num_dylibs = m_dyld_image_infos.size(); 702 if (num_dylibs > 0) 703 { 704 ModuleList loaded_module_list; 705 for (uint32_t idx = 0; idx<num_dylibs; ++idx) 706 { 707 ModuleSP image_module_sp (FindTargetModuleForDYLDImageInfo (m_dyld_image_infos[idx], true, NULL)); 708 709 if (image_module_sp) 710 { 711 if (m_dyld_image_infos[idx].header.filetype == llvm::MachO::HeaderFileTypeDynamicLinkEditor) 712 image_module_sp->SetIsDynamicLinkEditor (true); 713 714 ObjectFile *objfile = image_module_sp->GetObjectFile (); 715 if (objfile) 716 { 717 SectionList *sections = objfile->GetSectionList(); 718 if (sections) 719 { 720 ConstString commpage_dbstr("__commpage"); 721 Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get(); 722 if (commpage_section) 723 { 724 const FileSpec objfile_file_spec = objfile->GetFileSpec(); 725 ArchSpec arch (m_dyld_image_infos[idx].GetArchitecture ()); 726 ModuleSP commpage_image_module_sp(target_images.FindFirstModuleForFileSpec (objfile_file_spec, &arch, &commpage_dbstr)); 727 if (!commpage_image_module_sp) 728 { 729 commpage_image_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[idx].file_spec, 730 arch, 731 NULL, 732 &commpage_dbstr, 733 objfile->GetOffset() + commpage_section->GetFileOffset()); 734 } 735 if (commpage_image_module_sp) 736 UpdateCommPageLoadAddress (commpage_image_module_sp.get()); 737 } 738 } 739 } 740 741 // UpdateImageLoadAddress will return true if any segments 742 // change load address. We need to check this so we don't 743 // mention that all loaded shared libraries are newly loaded 744 // each time we hit out dyld breakpoint since dyld will list all 745 // shared libraries each time. 746 if (UpdateImageLoadAddress (image_module_sp.get(), m_dyld_image_infos[idx])) 747 { 748 loaded_module_list.AppendIfNeeded (image_module_sp); 749 } 750 } 751 } 752 if (loaded_module_list.GetSize() > 0) 753 { 754 // FIXME: This should really be in the Runtime handlers class, which should get 755 // called by the target's ModulesDidLoad, but we're doing it all locally for now 756 // to save time. 757 // Also, I'm assuming there can be only one libobjc dylib loaded... 758 759 ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime(); 760 if (objc_runtime != NULL && !objc_runtime->HasReadObjCLibrary()) 761 { 762 size_t num_modules = loaded_module_list.GetSize(); 763 for (int i = 0; i < num_modules; i++) 764 { 765 if (objc_runtime->IsModuleObjCLibrary (loaded_module_list.GetModuleAtIndex (i))) 766 { 767 objc_runtime->ReadObjCLibrary (loaded_module_list.GetModuleAtIndex (i)); 768 break; 769 } 770 } 771 } 772 if (log) 773 loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidLoad"); 774 m_process->GetTarget().ModulesDidLoad (loaded_module_list); 775 } 776 } 777 return m_dyld_image_infos.size(); 778 } 779 780 //---------------------------------------------------------------------- 781 // Read a mach_header at ADDR into HEADER, and also fill in the load 782 // command data into LOAD_COMMAND_DATA if it is non-NULL. 783 // 784 // Returns true if we succeed, false if we fail for any reason. 785 //---------------------------------------------------------------------- 786 bool 787 DynamicLoaderMacOSXDYLD::ReadMachHeader (lldb::addr_t addr, llvm::MachO::mach_header *header, DataExtractor *load_command_data) 788 { 789 DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0); 790 Error error; 791 size_t bytes_read = m_process->ReadMemory (addr, 792 header_bytes.GetBytes(), 793 header_bytes.GetByteSize(), 794 error); 795 if (bytes_read == sizeof(llvm::MachO::mach_header)) 796 { 797 uint32_t offset = 0; 798 ::memset (header, 0, sizeof(header)); 799 800 // Get the magic byte unswapped so we can figure out what we are dealing with 801 DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), lldb::endian::InlHostByteOrder(), 4); 802 header->magic = data.GetU32(&offset); 803 lldb::addr_t load_cmd_addr = addr; 804 data.SetByteOrder(DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header->magic)); 805 switch (header->magic) 806 { 807 case llvm::MachO::HeaderMagic32: 808 case llvm::MachO::HeaderMagic32Swapped: 809 data.SetAddressByteSize(4); 810 load_cmd_addr += sizeof(llvm::MachO::mach_header); 811 break; 812 813 case llvm::MachO::HeaderMagic64: 814 case llvm::MachO::HeaderMagic64Swapped: 815 data.SetAddressByteSize(8); 816 load_cmd_addr += sizeof(llvm::MachO::mach_header_64); 817 break; 818 819 default: 820 return false; 821 } 822 823 // Read the rest of dyld's mach header 824 if (data.GetU32(&offset, &header->cputype, (sizeof(llvm::MachO::mach_header)/sizeof(uint32_t)) - 1)) 825 { 826 if (load_command_data == NULL) 827 return true; // We were able to read the mach_header and weren't asked to read the load command bytes 828 829 DataBufferSP load_cmd_data_sp(new DataBufferHeap(header->sizeofcmds, 0)); 830 831 size_t load_cmd_bytes_read = m_process->ReadMemory (load_cmd_addr, 832 load_cmd_data_sp->GetBytes(), 833 load_cmd_data_sp->GetByteSize(), 834 error); 835 836 if (load_cmd_bytes_read == header->sizeofcmds) 837 { 838 // Set the load command data and also set the correct endian 839 // swap settings and the correct address size 840 load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds); 841 load_command_data->SetByteOrder(data.GetByteOrder()); 842 load_command_data->SetAddressByteSize(data.GetAddressByteSize()); 843 return true; // We successfully read the mach_header and the load command data 844 } 845 846 return false; // We weren't able to read the load command data 847 } 848 } 849 return false; // We failed the read the mach_header 850 } 851 852 853 //---------------------------------------------------------------------- 854 // Parse the load commands for an image 855 //---------------------------------------------------------------------- 856 uint32_t 857 DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, DYLDImageInfo& dylib_info, FileSpec *lc_id_dylinker) 858 { 859 uint32_t offset = 0; 860 uint32_t cmd_idx; 861 Segment segment; 862 dylib_info.Clear (true); 863 864 for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++) 865 { 866 // Clear out any load command specific data from DYLIB_INFO since 867 // we are about to read it. 868 869 if (data.ValidOffsetForDataOfSize (offset, sizeof(llvm::MachO::load_command))) 870 { 871 llvm::MachO::load_command load_cmd; 872 uint32_t load_cmd_offset = offset; 873 load_cmd.cmd = data.GetU32 (&offset); 874 load_cmd.cmdsize = data.GetU32 (&offset); 875 switch (load_cmd.cmd) 876 { 877 case llvm::MachO::LoadCommandSegment32: 878 { 879 segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16); 880 // We are putting 4 uint32_t values 4 uint64_t values so 881 // we have to use multiple 32 bit gets below. 882 segment.vmaddr = data.GetU32 (&offset); 883 segment.vmsize = data.GetU32 (&offset); 884 segment.fileoff = data.GetU32 (&offset); 885 segment.filesize = data.GetU32 (&offset); 886 // Extract maxprot, initprot, nsects and flags all at once 887 data.GetU32(&offset, &segment.maxprot, 4); 888 dylib_info.segments.push_back (segment); 889 } 890 break; 891 892 case llvm::MachO::LoadCommandSegment64: 893 { 894 segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16); 895 // Extract vmaddr, vmsize, fileoff, and filesize all at once 896 data.GetU64(&offset, &segment.vmaddr, 4); 897 // Extract maxprot, initprot, nsects and flags all at once 898 data.GetU32(&offset, &segment.maxprot, 4); 899 dylib_info.segments.push_back (segment); 900 } 901 break; 902 903 case llvm::MachO::LoadCommandDynamicLinkerIdent: 904 if (lc_id_dylinker) 905 { 906 uint32_t name_offset = load_cmd_offset + data.GetU32 (&offset); 907 const char *path = data.PeekCStr (name_offset); 908 lc_id_dylinker->SetFile (path, true); 909 } 910 break; 911 912 case llvm::MachO::LoadCommandUUID: 913 dylib_info.uuid.SetBytes(data.GetData (&offset, 16)); 914 break; 915 916 default: 917 break; 918 } 919 // Set offset to be the beginning of the next load command. 920 offset = load_cmd_offset + load_cmd.cmdsize; 921 } 922 } 923 924 // All sections listed in the dyld image info structure will all 925 // either be fixed up already, or they will all be off by a single 926 // slide amount that is determined by finding the first segment 927 // that is at file offset zero which also has bytes (a file size 928 // that is greater than zero) in the object file. 929 930 // Determine the slide amount (if any) 931 const size_t num_sections = dylib_info.segments.size(); 932 for (size_t i = 0; i < num_sections; ++i) 933 { 934 // Iterate through the object file sections to find the 935 // first section that starts of file offset zero and that 936 // has bytes in the file... 937 if (dylib_info.segments[i].fileoff == 0 && dylib_info.segments[i].filesize > 0) 938 { 939 dylib_info.slide = dylib_info.address - dylib_info.segments[i].vmaddr; 940 // We have found the slide amount, so we can exit 941 // this for loop. 942 break; 943 } 944 } 945 return cmd_idx; 946 } 947 948 //---------------------------------------------------------------------- 949 // Read the mach_header and load commands for each image that the 950 // _dyld_all_image_infos structure points to and cache the results. 951 //---------------------------------------------------------------------- 952 void 953 DynamicLoaderMacOSXDYLD::UpdateAllImageInfosHeaderAndLoadCommands() 954 { 955 uint32_t exe_idx = UINT32_MAX; 956 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 957 // Read any UUID values that we can get 958 for (uint32_t i = 0; i < m_dyld_all_image_infos.dylib_info_count; i++) 959 { 960 if (!m_dyld_image_infos[i].UUIDValid()) 961 { 962 DataExtractor data; // Load command data 963 if (!ReadMachHeader (m_dyld_image_infos[i].address, &m_dyld_image_infos[i].header, &data)) 964 continue; 965 966 ParseLoadCommands (data, m_dyld_image_infos[i], NULL); 967 968 if (m_dyld_image_infos[i].header.filetype == llvm::MachO::HeaderFileTypeExecutable) 969 exe_idx = i; 970 971 if (log) 972 m_dyld_image_infos[i].PutToLog (log.get()); 973 } 974 } 975 976 if (exe_idx < m_dyld_image_infos.size()) 977 { 978 ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (m_dyld_image_infos[exe_idx], false, NULL)); 979 980 if (!exe_module_sp) 981 { 982 ArchSpec exe_arch_spec (m_dyld_image_infos[exe_idx].GetArchitecture ()); 983 exe_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[exe_idx].file_spec, 984 exe_arch_spec, 985 &m_dyld_image_infos[exe_idx].uuid); 986 } 987 988 if (exe_module_sp) 989 { 990 if (exe_module_sp.get() != m_process->GetTarget().GetExecutableModule().get()) 991 { 992 // Don't load dependent images since we are in dyld where we will know 993 // and find out about all images that are loaded 994 bool get_dependent_images = false; 995 m_process->GetTarget().SetExecutableModule (exe_module_sp, 996 get_dependent_images); 997 } 998 } 999 } 1000 } 1001 1002 //---------------------------------------------------------------------- 1003 // Dump a Segment to the file handle provided. 1004 //---------------------------------------------------------------------- 1005 void 1006 DynamicLoaderMacOSXDYLD::Segment::PutToLog (Log *log, lldb::addr_t slide) const 1007 { 1008 if (log) 1009 { 1010 if (slide == 0) 1011 log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx)", 1012 name.AsCString(""), 1013 vmaddr + slide, 1014 vmaddr + slide + vmsize); 1015 else 1016 log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx) slide = 0x%llx", 1017 name.AsCString(""), 1018 vmaddr + slide, 1019 vmaddr + slide + vmsize, 1020 slide); 1021 } 1022 } 1023 1024 const DynamicLoaderMacOSXDYLD::Segment * 1025 DynamicLoaderMacOSXDYLD::DYLDImageInfo::FindSegment (const ConstString &name) const 1026 { 1027 const size_t num_segments = segments.size(); 1028 for (size_t i=0; i<num_segments; ++i) 1029 { 1030 if (segments[i].name == name) 1031 return &segments[i]; 1032 } 1033 return NULL; 1034 } 1035 1036 1037 //---------------------------------------------------------------------- 1038 // Dump an image info structure to the file handle provided. 1039 //---------------------------------------------------------------------- 1040 void 1041 DynamicLoaderMacOSXDYLD::DYLDImageInfo::PutToLog (Log *log) const 1042 { 1043 if (log == NULL) 1044 return; 1045 uint8_t *u = (uint8_t *)uuid.GetBytes(); 1046 1047 if (address == LLDB_INVALID_ADDRESS) 1048 { 1049 if (u) 1050 { 1051 log->Printf("\t modtime=0x%8.8llx uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s/%s' (UNLOADED)", 1052 mod_date, 1053 u[ 0], u[ 1], u[ 2], u[ 3], 1054 u[ 4], u[ 5], u[ 6], u[ 7], 1055 u[ 8], u[ 9], u[10], u[11], 1056 u[12], u[13], u[14], u[15], 1057 file_spec.GetDirectory().AsCString(), 1058 file_spec.GetFilename().AsCString()); 1059 } 1060 else 1061 log->Printf("\t modtime=0x%8.8llx path='%s/%s' (UNLOADED)", 1062 mod_date, 1063 file_spec.GetDirectory().AsCString(), 1064 file_spec.GetFilename().AsCString()); 1065 } 1066 else 1067 { 1068 if (u) 1069 { 1070 log->Printf("\taddress=0x%16.16llx modtime=0x%8.8llx uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s/%s'", 1071 address, 1072 mod_date, 1073 u[ 0], u[ 1], u[ 2], u[ 3], 1074 u[ 4], u[ 5], u[ 6], u[ 7], 1075 u[ 8], u[ 9], u[10], u[11], 1076 u[12], u[13], u[14], u[15], 1077 file_spec.GetDirectory().AsCString(), 1078 file_spec.GetFilename().AsCString()); 1079 } 1080 else 1081 { 1082 log->Printf("\taddress=0x%16.16llx modtime=0x%8.8llx path='%s/%s'", 1083 address, 1084 mod_date, 1085 file_spec.GetDirectory().AsCString(), 1086 file_spec.GetFilename().AsCString()); 1087 1088 } 1089 for (uint32_t i=0; i<segments.size(); ++i) 1090 segments[i].PutToLog(log, slide); 1091 } 1092 } 1093 1094 //---------------------------------------------------------------------- 1095 // Dump the _dyld_all_image_infos members and all current image infos 1096 // that we have parsed to the file handle provided. 1097 //---------------------------------------------------------------------- 1098 void 1099 DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const 1100 { 1101 if (log == NULL) 1102 return; 1103 1104 Mutex::Locker locker(m_mutex); 1105 log->Printf("dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8llx, notify=0x%8.8llx }", 1106 m_dyld_all_image_infos.version, 1107 m_dyld_all_image_infos.dylib_info_count, 1108 (uint64_t)m_dyld_all_image_infos.dylib_info_addr, 1109 (uint64_t)m_dyld_all_image_infos.notification); 1110 size_t i; 1111 const size_t count = m_dyld_image_infos.size(); 1112 if (count > 0) 1113 { 1114 log->PutCString("Loaded:"); 1115 for (i = 0; i<count; i++) 1116 m_dyld_image_infos[i].PutToLog(log); 1117 } 1118 } 1119 1120 void 1121 DynamicLoaderMacOSXDYLD::PrivateInitialize(Process *process) 1122 { 1123 DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); 1124 Clear(true); 1125 m_process = process; 1126 m_process->GetTarget().GetSectionLoadList().Clear(); 1127 } 1128 1129 bool 1130 DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint () 1131 { 1132 DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); 1133 if (m_break_id == LLDB_INVALID_BREAK_ID) 1134 { 1135 if (m_dyld_all_image_infos.notification != LLDB_INVALID_ADDRESS) 1136 { 1137 Address so_addr; 1138 // Set the notification breakpoint and install a breakpoint 1139 // callback function that will get called each time the 1140 // breakpoint gets hit. We will use this to track when shared 1141 // libraries get loaded/unloaded. 1142 1143 if (m_process->GetTarget().GetSectionLoadList().ResolveLoadAddress(m_dyld_all_image_infos.notification, so_addr)) 1144 { 1145 Breakpoint *dyld_break = m_process->GetTarget().CreateBreakpoint (so_addr, true).get(); 1146 dyld_break->SetCallback (DynamicLoaderMacOSXDYLD::NotifyBreakpointHit, this, true); 1147 m_break_id = dyld_break->GetID(); 1148 } 1149 } 1150 } 1151 return m_break_id != LLDB_INVALID_BREAK_ID; 1152 } 1153 1154 //---------------------------------------------------------------------- 1155 // Member function that gets called when the process state changes. 1156 //---------------------------------------------------------------------- 1157 void 1158 DynamicLoaderMacOSXDYLD::PrivateProcessStateChanged (Process *process, StateType state) 1159 { 1160 DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s(%s)\n", __FUNCTION__, StateAsCString(state)); 1161 switch (state) 1162 { 1163 case eStateConnected: 1164 case eStateAttaching: 1165 case eStateLaunching: 1166 case eStateInvalid: 1167 case eStateUnloaded: 1168 case eStateExited: 1169 case eStateDetached: 1170 Clear(false); 1171 break; 1172 1173 case eStateStopped: 1174 // Keep trying find dyld and set our notification breakpoint each time 1175 // we stop until we succeed 1176 if (!DidSetNotificationBreakpoint () && m_process->IsAlive()) 1177 { 1178 if (NeedToLocateDYLD ()) 1179 LocateDYLD (); 1180 1181 SetNotificationBreakpoint (); 1182 } 1183 break; 1184 1185 case eStateRunning: 1186 case eStateStepping: 1187 case eStateCrashed: 1188 case eStateSuspended: 1189 break; 1190 1191 default: 1192 break; 1193 } 1194 } 1195 1196 ThreadPlanSP 1197 DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) 1198 { 1199 ThreadPlanSP thread_plan_sp; 1200 StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get(); 1201 const SymbolContext ¤t_context = current_frame->GetSymbolContext(eSymbolContextSymbol); 1202 Symbol *current_symbol = current_context.symbol; 1203 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 1204 1205 if (current_symbol != NULL) 1206 { 1207 if (current_symbol->IsTrampoline()) 1208 { 1209 const ConstString &trampoline_name = current_symbol->GetMangled().GetName(Mangled::ePreferMangled); 1210 1211 if (trampoline_name) 1212 { 1213 SymbolContextList target_symbols; 1214 ModuleList &images = thread.GetProcess().GetTarget().GetImages(); 1215 images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, target_symbols); 1216 // FIXME - Make the Run to Address take multiple addresses, and 1217 // run to any of them. 1218 uint32_t num_symbols = target_symbols.GetSize(); 1219 if (num_symbols == 1) 1220 { 1221 SymbolContext context; 1222 AddressRange addr_range; 1223 if (target_symbols.GetContextAtIndex(0, context)) 1224 { 1225 context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range); 1226 thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addr_range.GetBaseAddress(), stop_others)); 1227 } 1228 else 1229 { 1230 if (log) 1231 log->Printf ("Couldn't resolve the symbol context."); 1232 } 1233 } 1234 else if (num_symbols > 1) 1235 { 1236 std::vector<lldb::addr_t> addresses; 1237 addresses.resize (num_symbols); 1238 for (uint32_t i = 0; i < num_symbols; i++) 1239 { 1240 SymbolContext context; 1241 AddressRange addr_range; 1242 if (target_symbols.GetContextAtIndex(i, context)) 1243 { 1244 context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range); 1245 lldb::addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(&thread.GetProcess().GetTarget()); 1246 addresses[i] = load_addr; 1247 } 1248 } 1249 if (addresses.size() > 0) 1250 thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addresses, stop_others)); 1251 else 1252 { 1253 if (log) 1254 log->Printf ("Couldn't resolve the symbol contexts."); 1255 } 1256 } 1257 else 1258 { 1259 if (log) 1260 { 1261 log->Printf ("Could not find symbol for trampoline target: \"%s\"", trampoline_name.AsCString()); 1262 } 1263 } 1264 } 1265 } 1266 } 1267 else 1268 { 1269 if (log) 1270 log->Printf ("Could not find symbol for step through."); 1271 } 1272 1273 return thread_plan_sp; 1274 } 1275 1276 Error 1277 DynamicLoaderMacOSXDYLD::CanLoadImage () 1278 { 1279 Error error; 1280 // In order for us to tell if we can load a shared library we verify that 1281 // the dylib_info_addr isn't zero (which means no shared libraries have 1282 // been set yet, or dyld is currently mucking with the shared library list). 1283 if (ReadAllImageInfosStructure ()) 1284 { 1285 // TODO: also check the _dyld_global_lock_held variable in libSystem.B.dylib? 1286 // TODO: check the malloc lock? 1287 // TODO: check the objective C lock? 1288 if (m_dyld_all_image_infos.dylib_info_addr != 0) 1289 return error; // Success 1290 } 1291 1292 error.SetErrorString("unsafe to load or unload shared libraries"); 1293 return error; 1294 } 1295 1296 void 1297 DynamicLoaderMacOSXDYLD::Initialize() 1298 { 1299 PluginManager::RegisterPlugin (GetPluginNameStatic(), 1300 GetPluginDescriptionStatic(), 1301 CreateInstance); 1302 } 1303 1304 void 1305 DynamicLoaderMacOSXDYLD::Terminate() 1306 { 1307 PluginManager::UnregisterPlugin (CreateInstance); 1308 } 1309 1310 1311 const char * 1312 DynamicLoaderMacOSXDYLD::GetPluginNameStatic() 1313 { 1314 return "dynamic-loader.macosx-dyld"; 1315 } 1316 1317 const char * 1318 DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic() 1319 { 1320 return "Dynamic loader plug-in that watches for shared library loads/unloads in MacOSX user processes."; 1321 } 1322 1323 1324 //------------------------------------------------------------------ 1325 // PluginInterface protocol 1326 //------------------------------------------------------------------ 1327 const char * 1328 DynamicLoaderMacOSXDYLD::GetPluginName() 1329 { 1330 return "DynamicLoaderMacOSXDYLD"; 1331 } 1332 1333 const char * 1334 DynamicLoaderMacOSXDYLD::GetShortPluginName() 1335 { 1336 return GetPluginNameStatic(); 1337 } 1338 1339 uint32_t 1340 DynamicLoaderMacOSXDYLD::GetPluginVersion() 1341 { 1342 return 1; 1343 } 1344 1345