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