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