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