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/ModuleSpec.h" 16 #include "lldb/Core/PluginManager.h" 17 #include "lldb/Core/Section.h" 18 #include "lldb/Core/State.h" 19 #include "lldb/Symbol/ClangASTContext.h" 20 #include "lldb/Symbol/Function.h" 21 #include "lldb/Symbol/ObjectFile.h" 22 #include "lldb/Target/ObjCLanguageRuntime.h" 23 #include "lldb/Target/ABI.h" 24 #include "lldb/Target/RegisterContext.h" 25 #include "lldb/Target/Target.h" 26 #include "lldb/Target/Thread.h" 27 #include "lldb/Target/ThreadPlanRunToAddress.h" 28 #include "lldb/Target/StackFrame.h" 29 30 #include "DynamicLoaderMacOSXDYLD.h" 31 32 //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN 33 #ifdef ENABLE_DEBUG_PRINTF 34 #include <stdio.h> 35 #define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__) 36 #else 37 #define DEBUG_PRINTF(fmt, ...) 38 #endif 39 40 #ifndef __APPLE__ 41 #include "Utility/UuidCompatibility.h" 42 #else 43 #include <uuid/uuid.h> 44 #endif 45 46 using namespace lldb; 47 using namespace lldb_private; 48 49 /// FIXME - The ObjC Runtime trampoline handler doesn't really belong here. 50 /// I am putting it here so I can invoke it in the Trampoline code here, but 51 /// it should be moved to the ObjC Runtime support when it is set up. 52 53 54 DynamicLoaderMacOSXDYLD::DYLDImageInfo * 55 DynamicLoaderMacOSXDYLD::GetImageInfo (Module *module) 56 { 57 const UUID &module_uuid = module->GetUUID(); 58 DYLDImageInfo::collection::iterator pos, end = m_dyld_image_infos.end(); 59 60 // First try just by UUID as it is the safest. 61 if (module_uuid.IsValid()) 62 { 63 for (pos = m_dyld_image_infos.begin(); pos != end; ++pos) 64 { 65 if (pos->uuid == module_uuid) 66 return &(*pos); 67 } 68 69 if (m_dyld.uuid == module_uuid) 70 return &m_dyld; 71 } 72 73 // Next try by platform path only for things that don't have a valid UUID 74 // since if a file has a valid UUID in real life it should also in the 75 // dyld info. This is the next safest because the paths in the dyld info 76 // are platform paths, not local paths. For local debugging platform == local 77 // paths. 78 const FileSpec &platform_file_spec = module->GetPlatformFileSpec(); 79 for (pos = m_dyld_image_infos.begin(); pos != end; ++pos) 80 { 81 if (pos->file_spec == platform_file_spec && pos->uuid.IsValid() == false) 82 return &(*pos); 83 } 84 85 if (m_dyld.file_spec == platform_file_spec && m_dyld.uuid.IsValid() == false) 86 return &m_dyld; 87 88 return NULL; 89 } 90 91 //---------------------------------------------------------------------- 92 // Create an instance of this class. This function is filled into 93 // the plugin info class that gets handed out by the plugin factory and 94 // allows the lldb to instantiate an instance of this class. 95 //---------------------------------------------------------------------- 96 DynamicLoader * 97 DynamicLoaderMacOSXDYLD::CreateInstance (Process* process, bool force) 98 { 99 bool create = force; 100 if (!create) 101 { 102 create = true; 103 Module* exe_module = process->GetTarget().GetExecutableModulePointer(); 104 if (exe_module) 105 { 106 ObjectFile *object_file = exe_module->GetObjectFile(); 107 if (object_file) 108 { 109 create = (object_file->GetStrata() == ObjectFile::eStrataUser); 110 } 111 } 112 113 if (create) 114 { 115 const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple(); 116 switch (triple_ref.getOS()) 117 { 118 case llvm::Triple::Darwin: 119 case llvm::Triple::MacOSX: 120 case llvm::Triple::IOS: 121 case llvm::Triple::TvOS: 122 case llvm::Triple::WatchOS: 123 create = triple_ref.getVendor() == llvm::Triple::Apple; 124 break; 125 default: 126 create = false; 127 break; 128 } 129 } 130 } 131 132 if (create) 133 return new DynamicLoaderMacOSXDYLD (process); 134 return NULL; 135 } 136 137 //---------------------------------------------------------------------- 138 // Constructor 139 //---------------------------------------------------------------------- 140 DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD (Process* process) : 141 DynamicLoader(process), 142 m_dyld(), 143 m_dyld_module_wp(), 144 m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS), 145 m_dyld_all_image_infos(), 146 m_dyld_all_image_infos_stop_id (UINT32_MAX), 147 m_break_id(LLDB_INVALID_BREAK_ID), 148 m_dyld_image_infos(), 149 m_dyld_image_infos_stop_id (UINT32_MAX), 150 m_mutex(Mutex::eMutexTypeRecursive), 151 m_process_image_addr_is_all_images_infos (false) 152 { 153 } 154 155 //---------------------------------------------------------------------- 156 // Destructor 157 //---------------------------------------------------------------------- 158 DynamicLoaderMacOSXDYLD::~DynamicLoaderMacOSXDYLD() 159 { 160 Clear(true); 161 } 162 163 //------------------------------------------------------------------ 164 /// Called after attaching a process. 165 /// 166 /// Allow DynamicLoader plug-ins to execute some code after 167 /// attaching to a process. 168 //------------------------------------------------------------------ 169 void 170 DynamicLoaderMacOSXDYLD::DidAttach () 171 { 172 PrivateInitialize(m_process); 173 LocateDYLD (); 174 SetNotificationBreakpoint (); 175 } 176 177 //------------------------------------------------------------------ 178 /// Called after attaching a process. 179 /// 180 /// Allow DynamicLoader plug-ins to execute some code after 181 /// attaching to a process. 182 //------------------------------------------------------------------ 183 void 184 DynamicLoaderMacOSXDYLD::DidLaunch () 185 { 186 PrivateInitialize(m_process); 187 LocateDYLD (); 188 SetNotificationBreakpoint (); 189 } 190 191 bool 192 DynamicLoaderMacOSXDYLD::ProcessDidExec () 193 { 194 if (m_process) 195 { 196 // If we are stopped after an exec, we will have only one thread... 197 if (m_process->GetThreadList().GetSize() == 1) 198 { 199 // We know if a process has exec'ed if our "m_dyld_all_image_infos_addr" 200 // value differs from the Process' image info address. When a process 201 // execs itself it might cause a change if ASLR is enabled. 202 const addr_t shlib_addr = m_process->GetImageInfoAddress (); 203 if (m_process_image_addr_is_all_images_infos == true && shlib_addr != m_dyld_all_image_infos_addr) 204 { 205 // The image info address from the process is the 'dyld_all_image_infos' 206 // address and it has changed. 207 return true; 208 } 209 210 if (m_process_image_addr_is_all_images_infos == false && shlib_addr == m_dyld.address) 211 { 212 // The image info address from the process is the mach_header 213 // address for dyld and it has changed. 214 return true; 215 } 216 217 // ASLR might be disabled and dyld could have ended up in the same 218 // location. We should try and detect if we are stopped at '_dyld_start' 219 ThreadSP thread_sp (m_process->GetThreadList().GetThreadAtIndex(0)); 220 if (thread_sp) 221 { 222 lldb::StackFrameSP frame_sp (thread_sp->GetStackFrameAtIndex(0)); 223 if (frame_sp) 224 { 225 const Symbol *symbol = frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol; 226 if (symbol) 227 { 228 if (symbol->GetName() == ConstString("_dyld_start")) 229 return true; 230 } 231 } 232 } 233 } 234 } 235 return false; 236 } 237 238 239 240 //---------------------------------------------------------------------- 241 // Clear out the state of this class. 242 //---------------------------------------------------------------------- 243 void 244 DynamicLoaderMacOSXDYLD::Clear (bool clear_process) 245 { 246 Mutex::Locker locker(m_mutex); 247 248 if (LLDB_BREAK_ID_IS_VALID(m_break_id)) 249 m_process->GetTarget().RemoveBreakpointByID (m_break_id); 250 251 if (clear_process) 252 m_process = NULL; 253 m_dyld.Clear(false); 254 m_dyld_all_image_infos_addr = LLDB_INVALID_ADDRESS; 255 m_dyld_all_image_infos.Clear(); 256 m_break_id = LLDB_INVALID_BREAK_ID; 257 m_dyld_image_infos.clear(); 258 } 259 260 //---------------------------------------------------------------------- 261 // Check if we have found DYLD yet 262 //---------------------------------------------------------------------- 263 bool 264 DynamicLoaderMacOSXDYLD::DidSetNotificationBreakpoint() const 265 { 266 return LLDB_BREAK_ID_IS_VALID (m_break_id); 267 } 268 269 //---------------------------------------------------------------------- 270 // Try and figure out where dyld is by first asking the Process 271 // if it knows (which currently calls down in the lldb::Process 272 // to get the DYLD info (available on SnowLeopard only). If that fails, 273 // then check in the default addresses. 274 //---------------------------------------------------------------------- 275 bool 276 DynamicLoaderMacOSXDYLD::LocateDYLD() 277 { 278 if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS) 279 { 280 // Check the image info addr as it might point to the 281 // mach header for dyld, or it might point to the 282 // dyld_all_image_infos struct 283 const addr_t shlib_addr = m_process->GetImageInfoAddress (); 284 if (shlib_addr != LLDB_INVALID_ADDRESS) 285 { 286 ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder(); 287 uint8_t buf[4]; 288 DataExtractor data (buf, sizeof(buf), byte_order, 4); 289 Error error; 290 if (m_process->ReadMemory (shlib_addr, buf, 4, error) == 4) 291 { 292 lldb::offset_t offset = 0; 293 uint32_t magic = data.GetU32 (&offset); 294 switch (magic) 295 { 296 case llvm::MachO::MH_MAGIC: 297 case llvm::MachO::MH_MAGIC_64: 298 case llvm::MachO::MH_CIGAM: 299 case llvm::MachO::MH_CIGAM_64: 300 m_process_image_addr_is_all_images_infos = false; 301 return ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr); 302 303 default: 304 break; 305 } 306 } 307 // Maybe it points to the all image infos? 308 m_dyld_all_image_infos_addr = shlib_addr; 309 m_process_image_addr_is_all_images_infos = true; 310 } 311 } 312 313 if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) 314 { 315 if (ReadAllImageInfosStructure ()) 316 { 317 if (m_dyld_all_image_infos.dyldImageLoadAddress != LLDB_INVALID_ADDRESS) 318 return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos.dyldImageLoadAddress); 319 else 320 return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos_addr & 0xfffffffffff00000ull); 321 } 322 } 323 324 // Check some default values 325 Module *executable = m_process->GetTarget().GetExecutableModulePointer(); 326 327 if (executable) 328 { 329 const ArchSpec &exe_arch = executable->GetArchitecture(); 330 if (exe_arch.GetAddressByteSize() == 8) 331 { 332 return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x7fff5fc00000ull); 333 } 334 else if (exe_arch.GetMachine() == llvm::Triple::arm || exe_arch.GetMachine() == llvm::Triple::thumb || exe_arch.GetMachine() == llvm::Triple::aarch64) 335 { 336 return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x2fe00000); 337 } 338 else 339 { 340 return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x8fe00000); 341 } 342 } 343 return false; 344 } 345 346 ModuleSP 347 DynamicLoaderMacOSXDYLD::FindTargetModuleForDYLDImageInfo (DYLDImageInfo &image_info, bool can_create, bool *did_create_ptr) 348 { 349 if (did_create_ptr) 350 *did_create_ptr = false; 351 352 Target &target = m_process->GetTarget(); 353 const ModuleList &target_images = target.GetImages(); 354 ModuleSpec module_spec (image_info.file_spec); 355 module_spec.GetUUID() = image_info.uuid; 356 ModuleSP module_sp (target_images.FindFirstModule (module_spec)); 357 358 if (module_sp && !module_spec.GetUUID().IsValid() && !module_sp->GetUUID().IsValid()) 359 { 360 // No UUID, we must rely upon the cached module modification 361 // time and the modification time of the file on disk 362 if (module_sp->GetModificationTime() != module_sp->GetFileSpec().GetModificationTime()) 363 module_sp.reset(); 364 } 365 366 if (!module_sp) 367 { 368 if (can_create) 369 { 370 module_sp = target.GetSharedModule (module_spec); 371 if (!module_sp || module_sp->GetObjectFile() == NULL) 372 module_sp = m_process->ReadModuleFromMemory (image_info.file_spec, image_info.address); 373 374 if (did_create_ptr) 375 *did_create_ptr = (bool) module_sp; 376 } 377 } 378 return module_sp; 379 } 380 381 //---------------------------------------------------------------------- 382 // Assume that dyld is in memory at ADDR and try to parse it's load 383 // commands 384 //---------------------------------------------------------------------- 385 bool 386 DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::addr_t addr) 387 { 388 DataExtractor data; // Load command data 389 if (ReadMachHeader (addr, &m_dyld.header, &data)) 390 { 391 if (m_dyld.header.filetype == llvm::MachO::MH_DYLINKER) 392 { 393 m_dyld.address = addr; 394 ModuleSP dyld_module_sp; 395 if (ParseLoadCommands (data, m_dyld, &m_dyld.file_spec)) 396 { 397 if (m_dyld.file_spec) 398 { 399 dyld_module_sp = FindTargetModuleForDYLDImageInfo (m_dyld, true, NULL); 400 401 if (dyld_module_sp) 402 UpdateImageLoadAddress (dyld_module_sp.get(), m_dyld); 403 } 404 } 405 406 Target &target = m_process->GetTarget(); 407 408 if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS && dyld_module_sp.get()) 409 { 410 static ConstString g_dyld_all_image_infos ("dyld_all_image_infos"); 411 const Symbol *symbol = dyld_module_sp->FindFirstSymbolWithNameAndType (g_dyld_all_image_infos, eSymbolTypeData); 412 if (symbol) 413 m_dyld_all_image_infos_addr = symbol->GetLoadAddress(&target); 414 } 415 416 // Update all image infos 417 InitializeFromAllImageInfos (); 418 419 // If we didn't have an executable before, but now we do, then the 420 // dyld module shared pointer might be unique and we may need to add 421 // it again (since Target::SetExecutableModule() will clear the 422 // images). So append the dyld module back to the list if it is 423 /// unique! 424 if (dyld_module_sp) 425 { 426 target.GetImages().AppendIfNeeded (dyld_module_sp); 427 428 // At this point we should have read in dyld's module, and so we should set breakpoints in it: 429 ModuleList modules; 430 modules.Append(dyld_module_sp); 431 target.ModulesDidLoad(modules); 432 m_dyld_module_wp = dyld_module_sp; 433 } 434 return true; 435 } 436 } 437 return false; 438 } 439 440 bool 441 DynamicLoaderMacOSXDYLD::NeedToLocateDYLD () const 442 { 443 return m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS; 444 } 445 446 //---------------------------------------------------------------------- 447 // Update the load addresses for all segments in MODULE using the 448 // updated INFO that is passed in. 449 //---------------------------------------------------------------------- 450 bool 451 DynamicLoaderMacOSXDYLD::UpdateImageLoadAddress (Module *module, DYLDImageInfo& info) 452 { 453 bool changed = false; 454 if (module) 455 { 456 ObjectFile *image_object_file = module->GetObjectFile(); 457 if (image_object_file) 458 { 459 SectionList *section_list = image_object_file->GetSectionList (); 460 if (section_list) 461 { 462 std::vector<uint32_t> inaccessible_segment_indexes; 463 // We now know the slide amount, so go through all sections 464 // and update the load addresses with the correct values. 465 const size_t num_segments = info.segments.size(); 466 for (size_t i=0; i<num_segments; ++i) 467 { 468 // Only load a segment if it has protections. Things like 469 // __PAGEZERO don't have any protections, and they shouldn't 470 // be slid 471 SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name)); 472 473 if (info.segments[i].maxprot == 0) 474 { 475 inaccessible_segment_indexes.push_back(i); 476 } 477 else 478 { 479 const addr_t new_section_load_addr = info.segments[i].vmaddr + info.slide; 480 static ConstString g_section_name_LINKEDIT ("__LINKEDIT"); 481 482 if (section_sp) 483 { 484 // __LINKEDIT sections from files in the shared cache 485 // can overlap so check to see what the segment name is 486 // and pass "false" so we don't warn of overlapping 487 // "Section" objects, and "true" for all other sections. 488 const bool warn_multiple = section_sp->GetName() != g_section_name_LINKEDIT; 489 490 changed = m_process->GetTarget().SetSectionLoadAddress (section_sp, new_section_load_addr, warn_multiple); 491 } 492 else 493 { 494 Host::SystemLog (Host::eSystemLogWarning, 495 "warning: unable to find and load segment named '%s' at 0x%" PRIx64 " in '%s' in macosx dynamic loader plug-in.\n", 496 info.segments[i].name.AsCString("<invalid>"), 497 (uint64_t)new_section_load_addr, 498 image_object_file->GetFileSpec().GetPath().c_str()); 499 } 500 } 501 } 502 503 // If the loaded the file (it changed) and we have segments that 504 // are not readable or writeable, add them to the invalid memory 505 // region cache for the process. This will typically only be 506 // the __PAGEZERO segment in the main executable. We might be able 507 // to apply this more generally to more sections that have no 508 // protections in the future, but for now we are going to just 509 // do __PAGEZERO. 510 if (changed && !inaccessible_segment_indexes.empty()) 511 { 512 for (uint32_t i=0; i<inaccessible_segment_indexes.size(); ++i) 513 { 514 const uint32_t seg_idx = inaccessible_segment_indexes[i]; 515 SectionSP section_sp(section_list->FindSectionByName(info.segments[seg_idx].name)); 516 517 if (section_sp) 518 { 519 static ConstString g_pagezero_section_name("__PAGEZERO"); 520 if (g_pagezero_section_name == section_sp->GetName()) 521 { 522 // __PAGEZERO never slides... 523 const lldb::addr_t vmaddr = info.segments[seg_idx].vmaddr; 524 const lldb::addr_t vmsize = info.segments[seg_idx].vmsize; 525 Process::LoadRange pagezero_range (vmaddr, vmsize); 526 m_process->AddInvalidMemoryRegion(pagezero_range); 527 } 528 } 529 } 530 } 531 } 532 } 533 } 534 // We might have an in memory image that was loaded as soon as it was created 535 if (info.load_stop_id == m_process->GetStopID()) 536 changed = true; 537 else if (changed) 538 { 539 // Update the stop ID when this library was updated 540 info.load_stop_id = m_process->GetStopID(); 541 } 542 return changed; 543 } 544 545 //---------------------------------------------------------------------- 546 // Update the load addresses for all segments in MODULE using the 547 // updated INFO that is passed in. 548 //---------------------------------------------------------------------- 549 bool 550 DynamicLoaderMacOSXDYLD::UnloadImageLoadAddress (Module *module, DYLDImageInfo& info) 551 { 552 bool changed = false; 553 if (module) 554 { 555 ObjectFile *image_object_file = module->GetObjectFile(); 556 if (image_object_file) 557 { 558 SectionList *section_list = image_object_file->GetSectionList (); 559 if (section_list) 560 { 561 const size_t num_segments = info.segments.size(); 562 for (size_t i=0; i<num_segments; ++i) 563 { 564 SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name)); 565 if (section_sp) 566 { 567 const addr_t old_section_load_addr = info.segments[i].vmaddr + info.slide; 568 if (m_process->GetTarget().SetSectionUnloaded (section_sp, old_section_load_addr)) 569 changed = true; 570 } 571 else 572 { 573 Host::SystemLog (Host::eSystemLogWarning, 574 "warning: unable to find and unload segment named '%s' in '%s' in macosx dynamic loader plug-in.\n", 575 info.segments[i].name.AsCString("<invalid>"), 576 image_object_file->GetFileSpec().GetPath().c_str()); 577 } 578 } 579 } 580 } 581 } 582 return changed; 583 } 584 585 586 //---------------------------------------------------------------------- 587 // Static callback function that gets called when our DYLD notification 588 // breakpoint gets hit. We update all of our image infos and then 589 // let our super class DynamicLoader class decide if we should stop 590 // or not (based on global preference). 591 //---------------------------------------------------------------------- 592 bool 593 DynamicLoaderMacOSXDYLD::NotifyBreakpointHit (void *baton, 594 StoppointCallbackContext *context, 595 lldb::user_id_t break_id, 596 lldb::user_id_t break_loc_id) 597 { 598 // Let the event know that the images have changed 599 // DYLD passes three arguments to the notification breakpoint. 600 // Arg1: enum dyld_image_mode mode - 0 = adding, 1 = removing 601 // Arg2: uint32_t infoCount - Number of shared libraries added 602 // Arg3: dyld_image_info info[] - Array of structs of the form: 603 // const struct mach_header *imageLoadAddress 604 // const char *imageFilePath 605 // uintptr_t imageFileModDate (a time_t) 606 607 DynamicLoaderMacOSXDYLD* dyld_instance = (DynamicLoaderMacOSXDYLD*) baton; 608 609 // First step is to see if we've already initialized the all image infos. If we haven't then this function 610 // will do so and return true. In the course of initializing the all_image_infos it will read the complete 611 // current state, so we don't need to figure out what has changed from the data passed in to us. 612 613 ExecutionContext exe_ctx (context->exe_ctx_ref); 614 Process *process = exe_ctx.GetProcessPtr(); 615 616 // This is a sanity check just in case this dyld_instance is an old dyld plugin's breakpoint still lying around. 617 if (process != dyld_instance->m_process) 618 return false; 619 620 if (dyld_instance->InitializeFromAllImageInfos()) 621 return dyld_instance->GetStopWhenImagesChange(); 622 623 const lldb::ABISP &abi = process->GetABI(); 624 if (abi) 625 { 626 // Build up the value array to store the three arguments given above, then get the values from the ABI: 627 628 ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext(); 629 ValueList argument_values; 630 Value input_value; 631 632 CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); 633 CompilerType clang_uint32_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint, 32); 634 input_value.SetValueType (Value::eValueTypeScalar); 635 input_value.SetCompilerType (clang_uint32_type); 636 // input_value.SetContext (Value::eContextTypeClangType, clang_uint32_type); 637 argument_values.PushValue (input_value); 638 argument_values.PushValue (input_value); 639 input_value.SetCompilerType (clang_void_ptr_type); 640 // input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type); 641 argument_values.PushValue (input_value); 642 643 if (abi->GetArgumentValues (exe_ctx.GetThreadRef(), argument_values)) 644 { 645 uint32_t dyld_mode = argument_values.GetValueAtIndex(0)->GetScalar().UInt (-1); 646 if (dyld_mode != static_cast<uint32_t>(-1)) 647 { 648 // Okay the mode was right, now get the number of elements, and the array of new elements... 649 uint32_t image_infos_count = argument_values.GetValueAtIndex(1)->GetScalar().UInt (-1); 650 if (image_infos_count != static_cast<uint32_t>(-1)) 651 { 652 // Got the number added, now go through the array of added elements, putting out the mach header 653 // address, and adding the image. 654 // Note, I'm not putting in logging here, since the AddModules & RemoveModules functions do 655 // all the logging internally. 656 657 lldb::addr_t image_infos_addr = argument_values.GetValueAtIndex(2)->GetScalar().ULongLong(); 658 if (dyld_mode == 0) 659 { 660 // This is add: 661 dyld_instance->AddModulesUsingImageInfosAddress (image_infos_addr, image_infos_count); 662 } 663 else 664 { 665 // This is remove: 666 dyld_instance->RemoveModulesUsingImageInfosAddress (image_infos_addr, image_infos_count); 667 } 668 669 } 670 } 671 } 672 } 673 674 // Return true to stop the target, false to just let the target run 675 return dyld_instance->GetStopWhenImagesChange(); 676 } 677 678 bool 679 DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure () 680 { 681 Mutex::Locker locker(m_mutex); 682 683 // the all image infos is already valid for this process stop ID 684 if (m_process->GetStopID() == m_dyld_all_image_infos_stop_id) 685 return true; 686 687 m_dyld_all_image_infos.Clear(); 688 if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) 689 { 690 ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder(); 691 uint32_t addr_size = 4; 692 if (m_dyld_all_image_infos_addr > UINT32_MAX) 693 addr_size = 8; 694 695 uint8_t buf[256]; 696 DataExtractor data (buf, sizeof(buf), byte_order, addr_size); 697 lldb::offset_t offset = 0; 698 699 const size_t count_v2 = sizeof (uint32_t) + // version 700 sizeof (uint32_t) + // infoArrayCount 701 addr_size + // infoArray 702 addr_size + // notification 703 addr_size + // processDetachedFromSharedRegion + libSystemInitialized + pad 704 addr_size; // dyldImageLoadAddress 705 const size_t count_v11 = count_v2 + 706 addr_size + // jitInfo 707 addr_size + // dyldVersion 708 addr_size + // errorMessage 709 addr_size + // terminationFlags 710 addr_size + // coreSymbolicationShmPage 711 addr_size + // systemOrderFlag 712 addr_size + // uuidArrayCount 713 addr_size + // uuidArray 714 addr_size + // dyldAllImageInfosAddress 715 addr_size + // initialImageCount 716 addr_size + // errorKind 717 addr_size + // errorClientOfDylibPath 718 addr_size + // errorTargetDylibPath 719 addr_size; // errorSymbol 720 const size_t count_v13 = count_v11 + 721 addr_size + // sharedCacheSlide 722 sizeof (uuid_t); // sharedCacheUUID 723 UNUSED_IF_ASSERT_DISABLED(count_v13); 724 assert (sizeof (buf) >= count_v13); 725 726 Error error; 727 if (m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, 4, error) == 4) 728 { 729 m_dyld_all_image_infos.version = data.GetU32(&offset); 730 // If anything in the high byte is set, we probably got the byte 731 // order incorrect (the process might not have it set correctly 732 // yet due to attaching to a program without a specified file). 733 if (m_dyld_all_image_infos.version & 0xff000000) 734 { 735 // We have guessed the wrong byte order. Swap it and try 736 // reading the version again. 737 if (byte_order == eByteOrderLittle) 738 byte_order = eByteOrderBig; 739 else 740 byte_order = eByteOrderLittle; 741 742 data.SetByteOrder (byte_order); 743 offset = 0; 744 m_dyld_all_image_infos.version = data.GetU32(&offset); 745 } 746 } 747 else 748 { 749 return false; 750 } 751 752 const size_t count = (m_dyld_all_image_infos.version >= 11) ? count_v11 : count_v2; 753 754 const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, count, error); 755 if (bytes_read == count) 756 { 757 offset = 0; 758 m_dyld_all_image_infos.version = data.GetU32(&offset); 759 m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset); 760 m_dyld_all_image_infos.dylib_info_addr = data.GetPointer(&offset); 761 m_dyld_all_image_infos.notification = data.GetPointer(&offset); 762 m_dyld_all_image_infos.processDetachedFromSharedRegion = data.GetU8(&offset); 763 m_dyld_all_image_infos.libSystemInitialized = data.GetU8(&offset); 764 // Adjust for padding. 765 offset += addr_size - 2; 766 m_dyld_all_image_infos.dyldImageLoadAddress = data.GetPointer(&offset); 767 if (m_dyld_all_image_infos.version >= 11) 768 { 769 offset += addr_size * 8; 770 uint64_t dyld_all_image_infos_addr = data.GetPointer(&offset); 771 772 // When we started, we were given the actual address of the all_image_infos 773 // struct (probably via TASK_DYLD_INFO) in memory - this address is stored in 774 // m_dyld_all_image_infos_addr and is the most accurate address we have. 775 776 // We read the dyld_all_image_infos struct from memory; it contains its own address. 777 // If the address in the struct does not match the actual address, 778 // the dyld we're looking at has been loaded at a different location (slid) from 779 // where it intended to load. The addresses in the dyld_all_image_infos struct 780 // are the original, non-slid addresses, and need to be adjusted. Most importantly 781 // the address of dyld and the notification address need to be adjusted. 782 783 if (dyld_all_image_infos_addr != m_dyld_all_image_infos_addr) 784 { 785 uint64_t image_infos_offset = dyld_all_image_infos_addr - m_dyld_all_image_infos.dyldImageLoadAddress; 786 uint64_t notification_offset = m_dyld_all_image_infos.notification - m_dyld_all_image_infos.dyldImageLoadAddress; 787 m_dyld_all_image_infos.dyldImageLoadAddress = m_dyld_all_image_infos_addr - image_infos_offset; 788 m_dyld_all_image_infos.notification = m_dyld_all_image_infos.dyldImageLoadAddress + notification_offset; 789 } 790 } 791 m_dyld_all_image_infos_stop_id = m_process->GetStopID(); 792 return true; 793 } 794 } 795 return false; 796 } 797 798 799 // This method is an amalgamation of code from 800 // ReadMachHeader() 801 // ParseLoadCommands() 802 // UpdateImageInfosHeaderAndLoadCommands() 803 // but written to extract everything from the JSON packet from debugserver, instead of using memory reads. 804 805 bool 806 DynamicLoaderMacOSXDYLD::AddModulesUsingInfosFromDebugserver (StructuredData::ObjectSP image_details, DYLDImageInfo::collection &image_infos) 807 { 808 StructuredData::ObjectSP images_sp = image_details->GetAsDictionary()->GetValueForKey("images"); 809 if (images_sp.get() == nullptr) 810 return false; 811 812 image_infos.resize (images_sp->GetAsArray()->GetSize()); 813 814 uint32_t exe_idx = UINT32_MAX; 815 816 for (size_t i = 0; i < image_infos.size(); i++) 817 { 818 StructuredData::ObjectSP image_sp = images_sp->GetAsArray()->GetItemAtIndex(i); 819 if (image_sp.get() == nullptr || image_sp->GetAsDictionary() == nullptr) 820 return false; 821 StructuredData::Dictionary *image = image_sp->GetAsDictionary(); 822 if (image->HasKey("load_address") == false 823 || image->HasKey("pathname") == false 824 || image->HasKey("mod_date") == false 825 || image->HasKey("mach_header") == false 826 || image->GetValueForKey("mach_header")->GetAsDictionary() == nullptr 827 || image->HasKey("segments") == false 828 || image->GetValueForKey("segments")->GetAsArray() == nullptr 829 || image->HasKey("uuid") == false ) 830 { 831 return false; 832 } 833 image_infos[i].address = image->GetValueForKey("load_address")->GetAsInteger()->GetValue(); 834 image_infos[i].mod_date = image->GetValueForKey("mod_date")->GetAsInteger()->GetValue(); 835 image_infos[i].file_spec.SetFile(image->GetValueForKey("pathname")->GetAsString()->GetValue().c_str(), false); 836 837 StructuredData::Dictionary *mh = image->GetValueForKey("mach_header")->GetAsDictionary(); 838 image_infos[i].header.magic = mh->GetValueForKey("magic")->GetAsInteger()->GetValue(); 839 image_infos[i].header.cputype = mh->GetValueForKey("cputype")->GetAsInteger()->GetValue(); 840 image_infos[i].header.cpusubtype = mh->GetValueForKey("cpusubtype")->GetAsInteger()->GetValue(); 841 image_infos[i].header.filetype = mh->GetValueForKey("filetype")->GetAsInteger()->GetValue(); 842 843 // Fields that aren't used by DynamicLoaderMacOSXDYLD so debugserver doesn't currently send them 844 // in the reply. 845 846 if (mh->HasKey("flags")) 847 image_infos[i].header.flags = mh->GetValueForKey("flags")->GetAsInteger()->GetValue(); 848 else 849 image_infos[i].header.flags = 0; 850 851 if (mh->HasKey("ncmds")) 852 image_infos[i].header.ncmds = mh->GetValueForKey("ncmds")->GetAsInteger()->GetValue(); 853 else 854 image_infos[i].header.ncmds = 0; 855 856 if (mh->HasKey("sizeofcmds")) 857 image_infos[i].header.sizeofcmds = mh->GetValueForKey("sizeofcmds")->GetAsInteger()->GetValue(); 858 else 859 image_infos[i].header.sizeofcmds = 0; 860 861 if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE) 862 exe_idx = i; 863 864 StructuredData::Array *segments = image->GetValueForKey("segments")->GetAsArray(); 865 uint32_t segcount = segments->GetSize(); 866 for (size_t j = 0; j < segcount; j++) 867 { 868 Segment segment; 869 StructuredData::Dictionary *seg = segments->GetItemAtIndex(j)->GetAsDictionary(); 870 segment.name = ConstString(seg->GetValueForKey("name")->GetAsString()->GetValue().c_str()); 871 segment.vmaddr = seg->GetValueForKey("vmaddr")->GetAsInteger()->GetValue(); 872 segment.vmsize = seg->GetValueForKey("vmsize")->GetAsInteger()->GetValue(); 873 segment.fileoff = seg->GetValueForKey("fileoff")->GetAsInteger()->GetValue(); 874 segment.filesize = seg->GetValueForKey("filesize")->GetAsInteger()->GetValue(); 875 segment.maxprot = seg->GetValueForKey("maxprot")->GetAsInteger()->GetValue(); 876 877 // Fields that aren't used by DynamicLoaderMacOSXDYLD so debugserver doesn't currently send them 878 // in the reply. 879 880 if (seg->HasKey("initprot")) 881 segment.initprot = seg->GetValueForKey("initprot")->GetAsInteger()->GetValue(); 882 else 883 segment.initprot = 0; 884 885 if (seg->HasKey("flags")) 886 segment.flags = seg->GetValueForKey("flags")->GetAsInteger()->GetValue(); 887 else 888 segment.flags = 0; 889 890 if (seg->HasKey("nsects")) 891 segment.nsects = seg->GetValueForKey("nsects")->GetAsInteger()->GetValue(); 892 else 893 segment.nsects = 0; 894 895 image_infos[i].segments.push_back (segment); 896 } 897 898 image_infos[i].uuid.SetFromCString (image->GetValueForKey("uuid")->GetAsString()->GetValue().c_str()); 899 900 // All sections listed in the dyld image info structure will all 901 // either be fixed up already, or they will all be off by a single 902 // slide amount that is determined by finding the first segment 903 // that is at file offset zero which also has bytes (a file size 904 // that is greater than zero) in the object file. 905 906 // Determine the slide amount (if any) 907 const size_t num_sections = image_infos[i].segments.size(); 908 for (size_t k = 0; k < num_sections; ++k) 909 { 910 // Iterate through the object file sections to find the 911 // first section that starts of file offset zero and that 912 // has bytes in the file... 913 if ((image_infos[i].segments[k].fileoff == 0 && image_infos[i].segments[k].filesize > 0) 914 || (image_infos[i].segments[k].name == ConstString("__TEXT"))) 915 { 916 image_infos[i].slide = image_infos[i].address - image_infos[i].segments[k].vmaddr; 917 // We have found the slide amount, so we can exit 918 // this for loop. 919 break; 920 } 921 } 922 } 923 924 Target &target = m_process->GetTarget(); 925 926 if (exe_idx < image_infos.size()) 927 { 928 const bool can_create = true; 929 ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[exe_idx], can_create, NULL)); 930 931 if (exe_module_sp) 932 { 933 UpdateImageLoadAddress (exe_module_sp.get(), image_infos[exe_idx]); 934 935 if (exe_module_sp.get() != target.GetExecutableModulePointer()) 936 { 937 // Don't load dependent images since we are in dyld where we will know 938 // and find out about all images that are loaded. Also when setting the 939 // executable module, it will clear the targets module list, and if we 940 // have an in memory dyld module, it will get removed from the list 941 // so we will need to add it back after setting the executable module, 942 // so we first try and see if we already have a weak pointer to the 943 // dyld module, make it into a shared pointer, then add the executable, 944 // then re-add it back to make sure it is always in the list. 945 ModuleSP dyld_module_sp(m_dyld_module_wp.lock()); 946 947 const bool get_dependent_images = false; 948 m_process->GetTarget().SetExecutableModule (exe_module_sp, 949 get_dependent_images); 950 951 if (dyld_module_sp) 952 { 953 if(target.GetImages().AppendIfNeeded (dyld_module_sp)) 954 { 955 // Also add it to the section list. 956 UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld); 957 } 958 } 959 } 960 } 961 } 962 return true; 963 } 964 965 bool 966 DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count) 967 { 968 DYLDImageInfo::collection image_infos; 969 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 970 if (log) 971 log->Printf ("Adding %d modules.\n", image_infos_count); 972 973 Mutex::Locker locker(m_mutex); 974 if (m_process->GetStopID() == m_dyld_image_infos_stop_id) 975 return true; 976 977 StructuredData::ObjectSP image_infos_json_sp = m_process->GetLoadedDynamicLibrariesInfos (image_infos_addr, image_infos_count); 978 if (image_infos_json_sp.get() 979 && image_infos_json_sp->GetAsDictionary() 980 && image_infos_json_sp->GetAsDictionary()->HasKey("images") 981 && image_infos_json_sp->GetAsDictionary()->GetValueForKey("images")->GetAsArray() 982 && image_infos_json_sp->GetAsDictionary()->GetValueForKey("images")->GetAsArray()->GetSize() == image_infos_count) 983 { 984 bool return_value = false; 985 if (AddModulesUsingInfosFromDebugserver (image_infos_json_sp, image_infos)) 986 { 987 return_value = AddModulesUsingImageInfos (image_infos); 988 } 989 m_dyld_image_infos_stop_id = m_process->GetStopID(); 990 return return_value; 991 } 992 993 if (!ReadImageInfos (image_infos_addr, image_infos_count, image_infos)) 994 return false; 995 996 UpdateImageInfosHeaderAndLoadCommands (image_infos, image_infos_count, false); 997 bool return_value = AddModulesUsingImageInfos (image_infos); 998 m_dyld_image_infos_stop_id = m_process->GetStopID(); 999 return return_value; 1000 } 1001 1002 // Adds the modules in image_infos to m_dyld_image_infos. 1003 // NB don't call this passing in m_dyld_image_infos. 1004 1005 bool 1006 DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfos (DYLDImageInfo::collection &image_infos) 1007 { 1008 // Now add these images to the main list. 1009 ModuleList loaded_module_list; 1010 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 1011 Target &target = m_process->GetTarget(); 1012 ModuleList& target_images = target.GetImages(); 1013 1014 for (uint32_t idx = 0; idx < image_infos.size(); ++idx) 1015 { 1016 if (log) 1017 { 1018 log->Printf ("Adding new image at address=0x%16.16" PRIx64 ".", image_infos[idx].address); 1019 image_infos[idx].PutToLog (log); 1020 } 1021 1022 m_dyld_image_infos.push_back(image_infos[idx]); 1023 1024 ModuleSP image_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[idx], true, NULL)); 1025 1026 if (image_module_sp) 1027 { 1028 ObjectFile *objfile = image_module_sp->GetObjectFile (); 1029 if (objfile) 1030 { 1031 SectionList *sections = objfile->GetSectionList(); 1032 if (sections) 1033 { 1034 ConstString commpage_dbstr("__commpage"); 1035 Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get(); 1036 if (commpage_section) 1037 { 1038 ModuleSpec module_spec (objfile->GetFileSpec(), image_infos[idx].GetArchitecture ()); 1039 module_spec.GetObjectName() = commpage_dbstr; 1040 ModuleSP commpage_image_module_sp(target_images.FindFirstModule (module_spec)); 1041 if (!commpage_image_module_sp) 1042 { 1043 module_spec.SetObjectOffset (objfile->GetFileOffset() + commpage_section->GetFileOffset()); 1044 module_spec.SetObjectSize (objfile->GetByteSize()); 1045 commpage_image_module_sp = target.GetSharedModule (module_spec); 1046 if (!commpage_image_module_sp || commpage_image_module_sp->GetObjectFile() == NULL) 1047 { 1048 commpage_image_module_sp = m_process->ReadModuleFromMemory (image_infos[idx].file_spec, 1049 image_infos[idx].address); 1050 // Always load a memory image right away in the target in case 1051 // we end up trying to read the symbol table from memory... The 1052 // __LINKEDIT will need to be mapped so we can figure out where 1053 // the symbol table bits are... 1054 bool changed = false; 1055 UpdateImageLoadAddress (commpage_image_module_sp.get(), image_infos[idx]); 1056 target.GetImages().Append(commpage_image_module_sp); 1057 if (changed) 1058 { 1059 image_infos[idx].load_stop_id = m_process->GetStopID(); 1060 loaded_module_list.AppendIfNeeded (commpage_image_module_sp); 1061 } 1062 } 1063 } 1064 } 1065 } 1066 } 1067 1068 // UpdateImageLoadAddress will return true if any segments 1069 // change load address. We need to check this so we don't 1070 // mention that all loaded shared libraries are newly loaded 1071 // each time we hit out dyld breakpoint since dyld will list all 1072 // shared libraries each time. 1073 if (UpdateImageLoadAddress (image_module_sp.get(), image_infos[idx])) 1074 { 1075 target_images.AppendIfNeeded(image_module_sp); 1076 loaded_module_list.AppendIfNeeded (image_module_sp); 1077 } 1078 } 1079 } 1080 1081 if (loaded_module_list.GetSize() > 0) 1082 { 1083 if (log) 1084 loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidLoad"); 1085 m_process->GetTarget().ModulesDidLoad (loaded_module_list); 1086 } 1087 return true; 1088 } 1089 1090 bool 1091 DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count) 1092 { 1093 DYLDImageInfo::collection image_infos; 1094 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 1095 1096 Mutex::Locker locker(m_mutex); 1097 if (m_process->GetStopID() == m_dyld_image_infos_stop_id) 1098 return true; 1099 1100 // First read in the image_infos for the removed modules, and their headers & load commands. 1101 if (!ReadImageInfos (image_infos_addr, image_infos_count, image_infos)) 1102 { 1103 if (log) 1104 log->PutCString ("Failed reading image infos array."); 1105 return false; 1106 } 1107 1108 if (log) 1109 log->Printf ("Removing %d modules.", image_infos_count); 1110 1111 ModuleList unloaded_module_list; 1112 for (uint32_t idx = 0; idx < image_infos.size(); ++idx) 1113 { 1114 if (log) 1115 { 1116 log->Printf ("Removing module at address=0x%16.16" PRIx64 ".", image_infos[idx].address); 1117 image_infos[idx].PutToLog (log); 1118 } 1119 1120 // Remove this image_infos from the m_all_image_infos. We do the comparison by address 1121 // rather than by file spec because we can have many modules with the same "file spec" in the 1122 // case that they are modules loaded from memory. 1123 // 1124 // Also copy over the uuid from the old entry to the removed entry so we can 1125 // use it to lookup the module in the module list. 1126 1127 DYLDImageInfo::collection::iterator pos, end = m_dyld_image_infos.end(); 1128 for (pos = m_dyld_image_infos.begin(); pos != end; pos++) 1129 { 1130 if (image_infos[idx].address == (*pos).address) 1131 { 1132 image_infos[idx].uuid = (*pos).uuid; 1133 1134 // Add the module from this image_info to the "unloaded_module_list". We'll remove them all at 1135 // one go later on. 1136 1137 ModuleSP unload_image_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[idx], false, NULL)); 1138 if (unload_image_module_sp.get()) 1139 { 1140 // When we unload, be sure to use the image info from the old list, 1141 // since that has sections correctly filled in. 1142 UnloadImageLoadAddress (unload_image_module_sp.get(), *pos); 1143 unloaded_module_list.AppendIfNeeded (unload_image_module_sp); 1144 } 1145 else 1146 { 1147 if (log) 1148 { 1149 log->Printf ("Could not find module for unloading info entry:"); 1150 image_infos[idx].PutToLog(log); 1151 } 1152 } 1153 1154 // Then remove it from the m_dyld_image_infos: 1155 1156 m_dyld_image_infos.erase(pos); 1157 break; 1158 } 1159 } 1160 1161 if (pos == end) 1162 { 1163 if (log) 1164 { 1165 log->Printf ("Could not find image_info entry for unloading image:"); 1166 image_infos[idx].PutToLog(log); 1167 } 1168 } 1169 } 1170 if (unloaded_module_list.GetSize() > 0) 1171 { 1172 if (log) 1173 { 1174 log->PutCString("Unloaded:"); 1175 unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload"); 1176 } 1177 m_process->GetTarget().GetImages().Remove (unloaded_module_list); 1178 } 1179 m_dyld_image_infos_stop_id = m_process->GetStopID(); 1180 return true; 1181 } 1182 1183 bool 1184 DynamicLoaderMacOSXDYLD::ReadImageInfos (lldb::addr_t image_infos_addr, 1185 uint32_t image_infos_count, 1186 DYLDImageInfo::collection &image_infos) 1187 { 1188 const ByteOrder endian = m_dyld.GetByteOrder(); 1189 const uint32_t addr_size = m_dyld.GetAddressByteSize(); 1190 1191 image_infos.resize(image_infos_count); 1192 const size_t count = image_infos.size() * 3 * addr_size; 1193 DataBufferHeap info_data(count, 0); 1194 Error error; 1195 const size_t bytes_read = m_process->ReadMemory (image_infos_addr, 1196 info_data.GetBytes(), 1197 info_data.GetByteSize(), 1198 error); 1199 if (bytes_read == count) 1200 { 1201 lldb::offset_t info_data_offset = 0; 1202 DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size); 1203 for (size_t i = 0; i < image_infos.size() && info_data_ref.ValidOffset(info_data_offset); i++) 1204 { 1205 image_infos[i].address = info_data_ref.GetPointer(&info_data_offset); 1206 lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset); 1207 image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset); 1208 1209 char raw_path[PATH_MAX]; 1210 m_process->ReadCStringFromMemory (path_addr, raw_path, sizeof(raw_path), error); 1211 // don't resolve the path 1212 if (error.Success()) 1213 { 1214 const bool resolve_path = false; 1215 image_infos[i].file_spec.SetFile(raw_path, resolve_path); 1216 } 1217 } 1218 return true; 1219 } 1220 else 1221 { 1222 return false; 1223 } 1224 } 1225 1226 //---------------------------------------------------------------------- 1227 // If we have found where the "_dyld_all_image_infos" lives in memory, 1228 // read the current info from it, and then update all image load 1229 // addresses (or lack thereof). Only do this if this is the first time 1230 // we're reading the dyld infos. Return true if we actually read anything, 1231 // and false otherwise. 1232 //---------------------------------------------------------------------- 1233 bool 1234 DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos () 1235 { 1236 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 1237 1238 Mutex::Locker locker(m_mutex); 1239 if (m_process->GetStopID() == m_dyld_image_infos_stop_id 1240 || m_dyld_image_infos.size() != 0) 1241 return false; 1242 1243 if (ReadAllImageInfosStructure ()) 1244 { 1245 // Nothing to load or unload? 1246 if (m_dyld_all_image_infos.dylib_info_count == 0) 1247 return true; 1248 1249 if (m_dyld_all_image_infos.dylib_info_addr == 0) 1250 { 1251 // DYLD is updating the images now. So we should say we have no images, and then we'll 1252 // figure it out when we hit the added breakpoint. 1253 return false; 1254 } 1255 else 1256 { 1257 if (!AddModulesUsingImageInfosAddress (m_dyld_all_image_infos.dylib_info_addr, 1258 m_dyld_all_image_infos.dylib_info_count)) 1259 { 1260 DEBUG_PRINTF("%s", "unable to read all data for all_dylib_infos."); 1261 m_dyld_image_infos.clear(); 1262 } 1263 } 1264 1265 // Now we have one more bit of business. If there is a library left in the images for our target that 1266 // doesn't have a load address, then it must be something that we were expecting to load (for instance we 1267 // read a load command for it) but it didn't in fact load - probably because DYLD_*_PATH pointed 1268 // to an equivalent version. We don't want it to stay in the target's module list or it will confuse 1269 // us, so unload it here. 1270 Target &target = m_process->GetTarget(); 1271 const ModuleList &target_modules = target.GetImages(); 1272 ModuleList not_loaded_modules; 1273 Mutex::Locker modules_locker(target_modules.GetMutex()); 1274 1275 size_t num_modules = target_modules.GetSize(); 1276 for (size_t i = 0; i < num_modules; i++) 1277 { 1278 ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked (i); 1279 if (!module_sp->IsLoadedInTarget (&target)) 1280 { 1281 if (log) 1282 { 1283 StreamString s; 1284 module_sp->GetDescription (&s); 1285 log->Printf ("Unloading pre-run module: %s.", s.GetData ()); 1286 } 1287 not_loaded_modules.Append (module_sp); 1288 } 1289 } 1290 1291 if (not_loaded_modules.GetSize() != 0) 1292 { 1293 target.GetImages().Remove(not_loaded_modules); 1294 } 1295 1296 return true; 1297 } 1298 else 1299 return false; 1300 } 1301 1302 //---------------------------------------------------------------------- 1303 // Read a mach_header at ADDR into HEADER, and also fill in the load 1304 // command data into LOAD_COMMAND_DATA if it is non-NULL. 1305 // 1306 // Returns true if we succeed, false if we fail for any reason. 1307 //---------------------------------------------------------------------- 1308 bool 1309 DynamicLoaderMacOSXDYLD::ReadMachHeader (lldb::addr_t addr, llvm::MachO::mach_header *header, DataExtractor *load_command_data) 1310 { 1311 DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0); 1312 Error error; 1313 size_t bytes_read = m_process->ReadMemory (addr, 1314 header_bytes.GetBytes(), 1315 header_bytes.GetByteSize(), 1316 error); 1317 if (bytes_read == sizeof(llvm::MachO::mach_header)) 1318 { 1319 lldb::offset_t offset = 0; 1320 ::memset (header, 0, sizeof(llvm::MachO::mach_header)); 1321 1322 // Get the magic byte unswapped so we can figure out what we are dealing with 1323 DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), lldb::endian::InlHostByteOrder(), 4); 1324 header->magic = data.GetU32(&offset); 1325 lldb::addr_t load_cmd_addr = addr; 1326 data.SetByteOrder(DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header->magic)); 1327 switch (header->magic) 1328 { 1329 case llvm::MachO::MH_MAGIC: 1330 case llvm::MachO::MH_CIGAM: 1331 data.SetAddressByteSize(4); 1332 load_cmd_addr += sizeof(llvm::MachO::mach_header); 1333 break; 1334 1335 case llvm::MachO::MH_MAGIC_64: 1336 case llvm::MachO::MH_CIGAM_64: 1337 data.SetAddressByteSize(8); 1338 load_cmd_addr += sizeof(llvm::MachO::mach_header_64); 1339 break; 1340 1341 default: 1342 return false; 1343 } 1344 1345 // Read the rest of dyld's mach header 1346 if (data.GetU32(&offset, &header->cputype, (sizeof(llvm::MachO::mach_header)/sizeof(uint32_t)) - 1)) 1347 { 1348 if (load_command_data == NULL) 1349 return true; // We were able to read the mach_header and weren't asked to read the load command bytes 1350 1351 DataBufferSP load_cmd_data_sp(new DataBufferHeap(header->sizeofcmds, 0)); 1352 1353 size_t load_cmd_bytes_read = m_process->ReadMemory (load_cmd_addr, 1354 load_cmd_data_sp->GetBytes(), 1355 load_cmd_data_sp->GetByteSize(), 1356 error); 1357 1358 if (load_cmd_bytes_read == header->sizeofcmds) 1359 { 1360 // Set the load command data and also set the correct endian 1361 // swap settings and the correct address size 1362 load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds); 1363 load_command_data->SetByteOrder(data.GetByteOrder()); 1364 load_command_data->SetAddressByteSize(data.GetAddressByteSize()); 1365 return true; // We successfully read the mach_header and the load command data 1366 } 1367 1368 return false; // We weren't able to read the load command data 1369 } 1370 } 1371 return false; // We failed the read the mach_header 1372 } 1373 1374 1375 //---------------------------------------------------------------------- 1376 // Parse the load commands for an image 1377 //---------------------------------------------------------------------- 1378 uint32_t 1379 DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, DYLDImageInfo& dylib_info, FileSpec *lc_id_dylinker) 1380 { 1381 lldb::offset_t offset = 0; 1382 uint32_t cmd_idx; 1383 Segment segment; 1384 dylib_info.Clear (true); 1385 1386 for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++) 1387 { 1388 // Clear out any load command specific data from DYLIB_INFO since 1389 // we are about to read it. 1390 1391 if (data.ValidOffsetForDataOfSize (offset, sizeof(llvm::MachO::load_command))) 1392 { 1393 llvm::MachO::load_command load_cmd; 1394 lldb::offset_t load_cmd_offset = offset; 1395 load_cmd.cmd = data.GetU32 (&offset); 1396 load_cmd.cmdsize = data.GetU32 (&offset); 1397 switch (load_cmd.cmd) 1398 { 1399 case llvm::MachO::LC_SEGMENT: 1400 { 1401 segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16); 1402 // We are putting 4 uint32_t values 4 uint64_t values so 1403 // we have to use multiple 32 bit gets below. 1404 segment.vmaddr = data.GetU32 (&offset); 1405 segment.vmsize = data.GetU32 (&offset); 1406 segment.fileoff = data.GetU32 (&offset); 1407 segment.filesize = data.GetU32 (&offset); 1408 // Extract maxprot, initprot, nsects and flags all at once 1409 data.GetU32(&offset, &segment.maxprot, 4); 1410 dylib_info.segments.push_back (segment); 1411 } 1412 break; 1413 1414 case llvm::MachO::LC_SEGMENT_64: 1415 { 1416 segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16); 1417 // Extract vmaddr, vmsize, fileoff, and filesize all at once 1418 data.GetU64(&offset, &segment.vmaddr, 4); 1419 // Extract maxprot, initprot, nsects and flags all at once 1420 data.GetU32(&offset, &segment.maxprot, 4); 1421 dylib_info.segments.push_back (segment); 1422 } 1423 break; 1424 1425 case llvm::MachO::LC_ID_DYLINKER: 1426 if (lc_id_dylinker) 1427 { 1428 const lldb::offset_t name_offset = load_cmd_offset + data.GetU32 (&offset); 1429 const char *path = data.PeekCStr (name_offset); 1430 lc_id_dylinker->SetFile (path, true); 1431 } 1432 break; 1433 1434 case llvm::MachO::LC_UUID: 1435 dylib_info.uuid.SetBytes(data.GetData (&offset, 16)); 1436 break; 1437 1438 default: 1439 break; 1440 } 1441 // Set offset to be the beginning of the next load command. 1442 offset = load_cmd_offset + load_cmd.cmdsize; 1443 } 1444 } 1445 1446 // All sections listed in the dyld image info structure will all 1447 // either be fixed up already, or they will all be off by a single 1448 // slide amount that is determined by finding the first segment 1449 // that is at file offset zero which also has bytes (a file size 1450 // that is greater than zero) in the object file. 1451 1452 // Determine the slide amount (if any) 1453 const size_t num_sections = dylib_info.segments.size(); 1454 for (size_t i = 0; i < num_sections; ++i) 1455 { 1456 // Iterate through the object file sections to find the 1457 // first section that starts of file offset zero and that 1458 // has bytes in the file... 1459 if ((dylib_info.segments[i].fileoff == 0 && dylib_info.segments[i].filesize > 0) || (dylib_info.segments[i].name == ConstString("__TEXT"))) 1460 { 1461 dylib_info.slide = dylib_info.address - dylib_info.segments[i].vmaddr; 1462 // We have found the slide amount, so we can exit 1463 // this for loop. 1464 break; 1465 } 1466 } 1467 return cmd_idx; 1468 } 1469 1470 //---------------------------------------------------------------------- 1471 // Read the mach_header and load commands for each image that the 1472 // _dyld_all_image_infos structure points to and cache the results. 1473 //---------------------------------------------------------------------- 1474 1475 void 1476 DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::collection &image_infos, 1477 uint32_t infos_count, 1478 bool update_executable) 1479 { 1480 uint32_t exe_idx = UINT32_MAX; 1481 // Read any UUID values that we can get 1482 for (uint32_t i = 0; i < infos_count; i++) 1483 { 1484 if (!image_infos[i].UUIDValid()) 1485 { 1486 DataExtractor data; // Load command data 1487 if (!ReadMachHeader (image_infos[i].address, &image_infos[i].header, &data)) 1488 continue; 1489 1490 ParseLoadCommands (data, image_infos[i], NULL); 1491 1492 if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE) 1493 exe_idx = i; 1494 1495 } 1496 } 1497 1498 Target &target = m_process->GetTarget(); 1499 1500 if (exe_idx < image_infos.size()) 1501 { 1502 const bool can_create = true; 1503 ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[exe_idx], can_create, NULL)); 1504 1505 if (exe_module_sp) 1506 { 1507 UpdateImageLoadAddress (exe_module_sp.get(), image_infos[exe_idx]); 1508 1509 if (exe_module_sp.get() != target.GetExecutableModulePointer()) 1510 { 1511 // Don't load dependent images since we are in dyld where we will know 1512 // and find out about all images that are loaded. Also when setting the 1513 // executable module, it will clear the targets module list, and if we 1514 // have an in memory dyld module, it will get removed from the list 1515 // so we will need to add it back after setting the executable module, 1516 // so we first try and see if we already have a weak pointer to the 1517 // dyld module, make it into a shared pointer, then add the executable, 1518 // then re-add it back to make sure it is always in the list. 1519 ModuleSP dyld_module_sp(m_dyld_module_wp.lock()); 1520 1521 const bool get_dependent_images = false; 1522 m_process->GetTarget().SetExecutableModule (exe_module_sp, 1523 get_dependent_images); 1524 1525 if (dyld_module_sp) 1526 { 1527 if(target.GetImages().AppendIfNeeded (dyld_module_sp)) 1528 { 1529 // Also add it to the section list. 1530 UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld); 1531 } 1532 } 1533 } 1534 } 1535 } 1536 } 1537 1538 //---------------------------------------------------------------------- 1539 // On Mac OS X libobjc (the Objective-C runtime) has several critical dispatch 1540 // functions written in hand-written assembly, and also have hand-written unwind 1541 // information in the eh_frame section. Normally we prefer analyzing the 1542 // assembly instructions of a currently executing frame to unwind from that frame -- 1543 // but on hand-written functions this profiling can fail. We should use the 1544 // eh_frame instructions for these functions all the time. 1545 // 1546 // As an aside, it would be better if the eh_frame entries had a flag (or were 1547 // extensible so they could have an Apple-specific flag) which indicates that 1548 // the instructions are asynchronous -- accurate at every instruction, instead 1549 // of our normal default assumption that they are not. 1550 //---------------------------------------------------------------------- 1551 1552 bool 1553 DynamicLoaderMacOSXDYLD::AlwaysRelyOnEHUnwindInfo (SymbolContext &sym_ctx) 1554 { 1555 ModuleSP module_sp; 1556 if (sym_ctx.symbol) 1557 { 1558 module_sp = sym_ctx.symbol->GetAddressRef().GetModule(); 1559 } 1560 if (module_sp.get() == NULL && sym_ctx.function) 1561 { 1562 module_sp = sym_ctx.function->GetAddressRange().GetBaseAddress().GetModule(); 1563 } 1564 if (module_sp.get() == NULL) 1565 return false; 1566 1567 ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime(); 1568 if (objc_runtime != NULL && objc_runtime->IsModuleObjCLibrary (module_sp)) 1569 { 1570 return true; 1571 } 1572 1573 return false; 1574 } 1575 1576 1577 1578 //---------------------------------------------------------------------- 1579 // Dump a Segment to the file handle provided. 1580 //---------------------------------------------------------------------- 1581 void 1582 DynamicLoaderMacOSXDYLD::Segment::PutToLog (Log *log, lldb::addr_t slide) const 1583 { 1584 if (log) 1585 { 1586 if (slide == 0) 1587 log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")", 1588 name.AsCString(""), 1589 vmaddr + slide, 1590 vmaddr + slide + vmsize); 1591 else 1592 log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") slide = 0x%" PRIx64, 1593 name.AsCString(""), 1594 vmaddr + slide, 1595 vmaddr + slide + vmsize, 1596 slide); 1597 } 1598 } 1599 1600 const DynamicLoaderMacOSXDYLD::Segment * 1601 DynamicLoaderMacOSXDYLD::DYLDImageInfo::FindSegment (const ConstString &name) const 1602 { 1603 const size_t num_segments = segments.size(); 1604 for (size_t i=0; i<num_segments; ++i) 1605 { 1606 if (segments[i].name == name) 1607 return &segments[i]; 1608 } 1609 return NULL; 1610 } 1611 1612 1613 //---------------------------------------------------------------------- 1614 // Dump an image info structure to the file handle provided. 1615 //---------------------------------------------------------------------- 1616 void 1617 DynamicLoaderMacOSXDYLD::DYLDImageInfo::PutToLog (Log *log) const 1618 { 1619 if (log == NULL) 1620 return; 1621 const uint8_t *u = (const uint8_t *)uuid.GetBytes(); 1622 1623 if (address == LLDB_INVALID_ADDRESS) 1624 { 1625 if (u) 1626 { 1627 log->Printf("\t modtime=0x%8.8" PRIx64 " 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' (UNLOADED)", 1628 mod_date, 1629 u[ 0], u[ 1], u[ 2], u[ 3], 1630 u[ 4], u[ 5], u[ 6], u[ 7], 1631 u[ 8], u[ 9], u[10], u[11], 1632 u[12], u[13], u[14], u[15], 1633 file_spec.GetPath().c_str()); 1634 } 1635 else 1636 log->Printf("\t modtime=0x%8.8" PRIx64 " path='%s' (UNLOADED)", 1637 mod_date, 1638 file_spec.GetPath().c_str()); 1639 } 1640 else 1641 { 1642 if (u) 1643 { 1644 log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 " 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'", 1645 address, 1646 mod_date, 1647 u[ 0], u[ 1], u[ 2], u[ 3], 1648 u[ 4], u[ 5], u[ 6], u[ 7], 1649 u[ 8], u[ 9], u[10], u[11], 1650 u[12], u[13], u[14], u[15], 1651 file_spec.GetPath().c_str()); 1652 } 1653 else 1654 { 1655 log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 " path='%s'", 1656 address, 1657 mod_date, 1658 file_spec.GetPath().c_str()); 1659 1660 } 1661 for (uint32_t i=0; i<segments.size(); ++i) 1662 segments[i].PutToLog(log, slide); 1663 } 1664 } 1665 1666 //---------------------------------------------------------------------- 1667 // Dump the _dyld_all_image_infos members and all current image infos 1668 // that we have parsed to the file handle provided. 1669 //---------------------------------------------------------------------- 1670 void 1671 DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const 1672 { 1673 if (log == NULL) 1674 return; 1675 1676 Mutex::Locker locker(m_mutex); 1677 log->Printf("dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8" PRIx64 ", notify=0x%8.8" PRIx64 " }", 1678 m_dyld_all_image_infos.version, 1679 m_dyld_all_image_infos.dylib_info_count, 1680 (uint64_t)m_dyld_all_image_infos.dylib_info_addr, 1681 (uint64_t)m_dyld_all_image_infos.notification); 1682 size_t i; 1683 const size_t count = m_dyld_image_infos.size(); 1684 if (count > 0) 1685 { 1686 log->PutCString("Loaded:"); 1687 for (i = 0; i<count; i++) 1688 m_dyld_image_infos[i].PutToLog(log); 1689 } 1690 } 1691 1692 void 1693 DynamicLoaderMacOSXDYLD::PrivateInitialize(Process *process) 1694 { 1695 DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); 1696 Clear(true); 1697 m_process = process; 1698 m_process->GetTarget().ClearAllLoadedSections(); 1699 } 1700 1701 bool 1702 DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint () 1703 { 1704 DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); 1705 if (m_break_id == LLDB_INVALID_BREAK_ID) 1706 { 1707 if (m_dyld_all_image_infos.notification != LLDB_INVALID_ADDRESS) 1708 { 1709 Address so_addr; 1710 // Set the notification breakpoint and install a breakpoint 1711 // callback function that will get called each time the 1712 // breakpoint gets hit. We will use this to track when shared 1713 // libraries get loaded/unloaded. 1714 bool resolved = m_process->GetTarget().ResolveLoadAddress(m_dyld_all_image_infos.notification, so_addr); 1715 if (!resolved) 1716 { 1717 ModuleSP dyld_module_sp = m_dyld_module_wp.lock(); 1718 if (dyld_module_sp) 1719 { 1720 UpdateImageLoadAddress (dyld_module_sp.get(), m_dyld); 1721 resolved = m_process->GetTarget().ResolveLoadAddress(m_dyld_all_image_infos.notification, so_addr); 1722 } 1723 } 1724 1725 if (resolved) 1726 { 1727 Breakpoint *dyld_break = m_process->GetTarget().CreateBreakpoint (so_addr, true, false).get(); 1728 dyld_break->SetCallback (DynamicLoaderMacOSXDYLD::NotifyBreakpointHit, this, true); 1729 dyld_break->SetBreakpointKind ("shared-library-event"); 1730 m_break_id = dyld_break->GetID(); 1731 } 1732 } 1733 } 1734 return m_break_id != LLDB_INVALID_BREAK_ID; 1735 } 1736 1737 //---------------------------------------------------------------------- 1738 // Member function that gets called when the process state changes. 1739 //---------------------------------------------------------------------- 1740 void 1741 DynamicLoaderMacOSXDYLD::PrivateProcessStateChanged (Process *process, StateType state) 1742 { 1743 DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s(%s)\n", __FUNCTION__, StateAsCString(state)); 1744 switch (state) 1745 { 1746 case eStateConnected: 1747 case eStateAttaching: 1748 case eStateLaunching: 1749 case eStateInvalid: 1750 case eStateUnloaded: 1751 case eStateExited: 1752 case eStateDetached: 1753 Clear(false); 1754 break; 1755 1756 case eStateStopped: 1757 // Keep trying find dyld and set our notification breakpoint each time 1758 // we stop until we succeed 1759 if (!DidSetNotificationBreakpoint () && m_process->IsAlive()) 1760 { 1761 if (NeedToLocateDYLD ()) 1762 LocateDYLD (); 1763 1764 SetNotificationBreakpoint (); 1765 } 1766 break; 1767 1768 case eStateRunning: 1769 case eStateStepping: 1770 case eStateCrashed: 1771 case eStateSuspended: 1772 break; 1773 } 1774 } 1775 1776 ThreadPlanSP 1777 DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) 1778 { 1779 ThreadPlanSP thread_plan_sp; 1780 StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get(); 1781 const SymbolContext ¤t_context = current_frame->GetSymbolContext(eSymbolContextSymbol); 1782 Symbol *current_symbol = current_context.symbol; 1783 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 1784 TargetSP target_sp (thread.CalculateTarget()); 1785 1786 if (current_symbol != NULL) 1787 { 1788 std::vector<Address> addresses; 1789 1790 if (current_symbol->IsTrampoline()) 1791 { 1792 const ConstString &trampoline_name = current_symbol->GetMangled().GetName(current_symbol->GetLanguage(), Mangled::ePreferMangled); 1793 1794 if (trampoline_name) 1795 { 1796 const ModuleList &images = target_sp->GetImages(); 1797 1798 SymbolContextList code_symbols; 1799 images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, code_symbols); 1800 size_t num_code_symbols = code_symbols.GetSize(); 1801 1802 if (num_code_symbols > 0) 1803 { 1804 for (uint32_t i = 0; i < num_code_symbols; i++) 1805 { 1806 SymbolContext context; 1807 AddressRange addr_range; 1808 if (code_symbols.GetContextAtIndex(i, context)) 1809 { 1810 context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range); 1811 addresses.push_back(addr_range.GetBaseAddress()); 1812 if (log) 1813 { 1814 addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get()); 1815 1816 log->Printf ("Found a trampoline target symbol at 0x%" PRIx64 ".", load_addr); 1817 } 1818 } 1819 } 1820 } 1821 1822 SymbolContextList reexported_symbols; 1823 images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeReExported, reexported_symbols); 1824 size_t num_reexported_symbols = reexported_symbols.GetSize(); 1825 if (num_reexported_symbols > 0) 1826 { 1827 for (uint32_t i = 0; i < num_reexported_symbols; i++) 1828 { 1829 SymbolContext context; 1830 if (reexported_symbols.GetContextAtIndex(i, context)) 1831 { 1832 if (context.symbol) 1833 { 1834 Symbol *actual_symbol = context.symbol->ResolveReExportedSymbol(*target_sp.get()); 1835 if (actual_symbol) 1836 { 1837 const Address actual_symbol_addr = actual_symbol->GetAddress(); 1838 if (actual_symbol_addr.IsValid()) 1839 { 1840 addresses.push_back(actual_symbol_addr); 1841 if (log) 1842 { 1843 lldb::addr_t load_addr = actual_symbol_addr.GetLoadAddress(target_sp.get()); 1844 log->Printf ("Found a re-exported symbol: %s at 0x%" PRIx64 ".", 1845 actual_symbol->GetName().GetCString(), load_addr); 1846 } 1847 } 1848 } 1849 } 1850 } 1851 } 1852 } 1853 1854 SymbolContextList indirect_symbols; 1855 images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeResolver, indirect_symbols); 1856 size_t num_indirect_symbols = indirect_symbols.GetSize(); 1857 if (num_indirect_symbols > 0) 1858 { 1859 for (uint32_t i = 0; i < num_indirect_symbols; i++) 1860 { 1861 SymbolContext context; 1862 AddressRange addr_range; 1863 if (indirect_symbols.GetContextAtIndex(i, context)) 1864 { 1865 context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range); 1866 addresses.push_back(addr_range.GetBaseAddress()); 1867 if (log) 1868 { 1869 addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get()); 1870 1871 log->Printf ("Found an indirect target symbol at 0x%" PRIx64 ".", load_addr); 1872 } 1873 } 1874 } 1875 } 1876 } 1877 } 1878 else if (current_symbol->GetType() == eSymbolTypeReExported) 1879 { 1880 // I am not sure we could ever end up stopped AT a re-exported symbol. But just in case: 1881 1882 const Symbol *actual_symbol = current_symbol->ResolveReExportedSymbol(*(target_sp.get())); 1883 if (actual_symbol) 1884 { 1885 Address target_addr(actual_symbol->GetAddress()); 1886 if (target_addr.IsValid()) 1887 { 1888 if (log) 1889 log->Printf ("Found a re-exported symbol: %s pointing to: %s at 0x%" PRIx64 ".", 1890 current_symbol->GetName().GetCString(), 1891 actual_symbol->GetName().GetCString(), 1892 target_addr.GetLoadAddress(target_sp.get())); 1893 addresses.push_back (target_addr.GetLoadAddress(target_sp.get())); 1894 1895 } 1896 } 1897 } 1898 1899 if (addresses.size() > 0) 1900 { 1901 // First check whether any of the addresses point to Indirect symbols, and if they do, resolve them: 1902 std::vector<lldb::addr_t> load_addrs; 1903 for (Address address : addresses) 1904 { 1905 Symbol *symbol = address.CalculateSymbolContextSymbol(); 1906 if (symbol && symbol->IsIndirect()) 1907 { 1908 Error error; 1909 Address symbol_address = symbol->GetAddress(); 1910 addr_t resolved_addr = thread.GetProcess()->ResolveIndirectFunction(&symbol_address, error); 1911 if (error.Success()) 1912 { 1913 load_addrs.push_back(resolved_addr); 1914 if (log) 1915 log->Printf("ResolveIndirectFunction found resolved target for %s at 0x%" PRIx64 ".", 1916 symbol->GetName().GetCString(), resolved_addr); 1917 } 1918 } 1919 else 1920 { 1921 load_addrs.push_back(address.GetLoadAddress(target_sp.get())); 1922 } 1923 1924 } 1925 thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, load_addrs, stop_others)); 1926 } 1927 } 1928 else 1929 { 1930 if (log) 1931 log->Printf ("Could not find symbol for step through."); 1932 } 1933 1934 return thread_plan_sp; 1935 } 1936 1937 size_t 1938 DynamicLoaderMacOSXDYLD::FindEquivalentSymbols (lldb_private::Symbol *original_symbol, 1939 lldb_private::ModuleList &images, 1940 lldb_private::SymbolContextList &equivalent_symbols) 1941 { 1942 const ConstString &trampoline_name = original_symbol->GetMangled().GetName(original_symbol->GetLanguage(), Mangled::ePreferMangled); 1943 if (!trampoline_name) 1944 return 0; 1945 1946 size_t initial_size = equivalent_symbols.GetSize(); 1947 1948 static const char *resolver_name_regex = "(_gc|_non_gc|\\$[A-Za-z0-9\\$]+)$"; 1949 std::string equivalent_regex_buf("^"); 1950 equivalent_regex_buf.append (trampoline_name.GetCString()); 1951 equivalent_regex_buf.append (resolver_name_regex); 1952 1953 RegularExpression equivalent_name_regex (equivalent_regex_buf.c_str()); 1954 const bool append = true; 1955 images.FindSymbolsMatchingRegExAndType (equivalent_name_regex, eSymbolTypeCode, equivalent_symbols, append); 1956 1957 return equivalent_symbols.GetSize() - initial_size; 1958 } 1959 1960 Error 1961 DynamicLoaderMacOSXDYLD::CanLoadImage () 1962 { 1963 Error error; 1964 // In order for us to tell if we can load a shared library we verify that 1965 // the dylib_info_addr isn't zero (which means no shared libraries have 1966 // been set yet, or dyld is currently mucking with the shared library list). 1967 if (ReadAllImageInfosStructure ()) 1968 { 1969 // TODO: also check the _dyld_global_lock_held variable in libSystem.B.dylib? 1970 // TODO: check the malloc lock? 1971 // TODO: check the objective C lock? 1972 if (m_dyld_all_image_infos.dylib_info_addr != 0) 1973 return error; // Success 1974 } 1975 1976 error.SetErrorString("unsafe to load or unload shared libraries"); 1977 return error; 1978 } 1979 1980 void 1981 DynamicLoaderMacOSXDYLD::Initialize() 1982 { 1983 PluginManager::RegisterPlugin (GetPluginNameStatic(), 1984 GetPluginDescriptionStatic(), 1985 CreateInstance); 1986 } 1987 1988 void 1989 DynamicLoaderMacOSXDYLD::Terminate() 1990 { 1991 PluginManager::UnregisterPlugin (CreateInstance); 1992 } 1993 1994 1995 lldb_private::ConstString 1996 DynamicLoaderMacOSXDYLD::GetPluginNameStatic() 1997 { 1998 static ConstString g_name("macosx-dyld"); 1999 return g_name; 2000 } 2001 2002 const char * 2003 DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic() 2004 { 2005 return "Dynamic loader plug-in that watches for shared library loads/unloads in MacOSX user processes."; 2006 } 2007 2008 2009 //------------------------------------------------------------------ 2010 // PluginInterface protocol 2011 //------------------------------------------------------------------ 2012 lldb_private::ConstString 2013 DynamicLoaderMacOSXDYLD::GetPluginName() 2014 { 2015 return GetPluginNameStatic(); 2016 } 2017 2018 uint32_t 2019 DynamicLoaderMacOSXDYLD::GetPluginVersion() 2020 { 2021 return 1; 2022 } 2023 2024 uint32_t 2025 DynamicLoaderMacOSXDYLD::AddrByteSize() 2026 { 2027 switch (m_dyld.header.magic) 2028 { 2029 case llvm::MachO::MH_MAGIC: 2030 case llvm::MachO::MH_CIGAM: 2031 return 4; 2032 2033 case llvm::MachO::MH_MAGIC_64: 2034 case llvm::MachO::MH_CIGAM_64: 2035 return 8; 2036 2037 default: 2038 break; 2039 } 2040 return 0; 2041 } 2042 2043 lldb::ByteOrder 2044 DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic (uint32_t magic) 2045 { 2046 switch (magic) 2047 { 2048 case llvm::MachO::MH_MAGIC: 2049 case llvm::MachO::MH_MAGIC_64: 2050 return lldb::endian::InlHostByteOrder(); 2051 2052 case llvm::MachO::MH_CIGAM: 2053 case llvm::MachO::MH_CIGAM_64: 2054 if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig) 2055 return lldb::eByteOrderLittle; 2056 else 2057 return lldb::eByteOrderBig; 2058 2059 default: 2060 break; 2061 } 2062 return lldb::eByteOrderInvalid; 2063 } 2064 2065 lldb::ByteOrder 2066 DynamicLoaderMacOSXDYLD::DYLDImageInfo::GetByteOrder() 2067 { 2068 return DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header.magic); 2069 } 2070 2071