1 //===-- DynamicLoaderMacOSXDYLD.cpp ---------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "DynamicLoaderMacOSXDYLD.h" 10 #include "DynamicLoaderDarwin.h" 11 #include "DynamicLoaderMacOS.h" 12 #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" 13 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" 14 #include "lldb/Breakpoint/StoppointCallbackContext.h" 15 #include "lldb/Core/Debugger.h" 16 #include "lldb/Core/Module.h" 17 #include "lldb/Core/ModuleSpec.h" 18 #include "lldb/Core/PluginManager.h" 19 #include "lldb/Core/Section.h" 20 #include "lldb/Symbol/Function.h" 21 #include "lldb/Symbol/ObjectFile.h" 22 #include "lldb/Target/ABI.h" 23 #include "lldb/Target/RegisterContext.h" 24 #include "lldb/Target/StackFrame.h" 25 #include "lldb/Target/Target.h" 26 #include "lldb/Target/Thread.h" 27 #include "lldb/Target/ThreadPlanRunToAddress.h" 28 #include "lldb/Utility/DataBuffer.h" 29 #include "lldb/Utility/DataBufferHeap.h" 30 #include "lldb/Utility/LLDBLog.h" 31 #include "lldb/Utility/Log.h" 32 #include "lldb/Utility/State.h" 33 34 //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN 35 #ifdef ENABLE_DEBUG_PRINTF 36 #include <cstdio> 37 #define DEBUG_PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__) 38 #else 39 #define DEBUG_PRINTF(fmt, ...) 40 #endif 41 42 #ifndef __APPLE__ 43 #include "lldb/Utility/AppleUuidCompatibility.h" 44 #else 45 #include <uuid/uuid.h> 46 #endif 47 48 using namespace lldb; 49 using namespace lldb_private; 50 51 LLDB_PLUGIN_DEFINE(DynamicLoaderMacOSXDYLD) 52 53 // Create an instance of this class. This function is filled into the plugin 54 // info class that gets handed out by the plugin factory and allows the lldb to 55 // instantiate an instance of this class. 56 DynamicLoader *DynamicLoaderMacOSXDYLD::CreateInstance(Process *process, 57 bool force) { 58 bool create = force; 59 if (!create) { 60 create = true; 61 Module *exe_module = process->GetTarget().GetExecutableModulePointer(); 62 if (exe_module) { 63 ObjectFile *object_file = exe_module->GetObjectFile(); 64 if (object_file) { 65 create = (object_file->GetStrata() == ObjectFile::eStrataUser); 66 } 67 } 68 69 if (create) { 70 const llvm::Triple &triple_ref = 71 process->GetTarget().GetArchitecture().GetTriple(); 72 switch (triple_ref.getOS()) { 73 case llvm::Triple::Darwin: 74 case llvm::Triple::MacOSX: 75 case llvm::Triple::IOS: 76 case llvm::Triple::TvOS: 77 case llvm::Triple::WatchOS: 78 case llvm::Triple::XROS: 79 case llvm::Triple::BridgeOS: 80 create = triple_ref.getVendor() == llvm::Triple::Apple; 81 break; 82 default: 83 create = false; 84 break; 85 } 86 } 87 } 88 89 if (UseDYLDSPI(process)) { 90 create = false; 91 } 92 93 if (create) 94 return new DynamicLoaderMacOSXDYLD(process); 95 return nullptr; 96 } 97 98 // Constructor 99 DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD(Process *process) 100 : DynamicLoaderDarwin(process), 101 m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS), 102 m_dyld_all_image_infos(), m_dyld_all_image_infos_stop_id(UINT32_MAX), 103 m_break_id(LLDB_INVALID_BREAK_ID), m_mutex(), 104 m_process_image_addr_is_all_images_infos(false) {} 105 106 // Destructor 107 DynamicLoaderMacOSXDYLD::~DynamicLoaderMacOSXDYLD() { 108 if (LLDB_BREAK_ID_IS_VALID(m_break_id)) 109 m_process->GetTarget().RemoveBreakpointByID(m_break_id); 110 } 111 112 bool DynamicLoaderMacOSXDYLD::ProcessDidExec() { 113 std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); 114 bool did_exec = false; 115 if (m_process) { 116 // If we are stopped after an exec, we will have only one thread... 117 if (m_process->GetThreadList().GetSize() == 1) { 118 // We know if a process has exec'ed if our "m_dyld_all_image_infos_addr" 119 // value differs from the Process' image info address. When a process 120 // execs itself it might cause a change if ASLR is enabled. 121 const addr_t shlib_addr = m_process->GetImageInfoAddress(); 122 if (m_process_image_addr_is_all_images_infos && 123 shlib_addr != m_dyld_all_image_infos_addr) { 124 // The image info address from the process is the 125 // 'dyld_all_image_infos' address and it has changed. 126 did_exec = true; 127 } else if (!m_process_image_addr_is_all_images_infos && 128 shlib_addr == m_dyld.address) { 129 // The image info address from the process is the mach_header address 130 // for dyld and it has changed. 131 did_exec = true; 132 } else { 133 // ASLR might be disabled and dyld could have ended up in the same 134 // location. We should try and detect if we are stopped at 135 // '_dyld_start' 136 ThreadSP thread_sp(m_process->GetThreadList().GetThreadAtIndex(0)); 137 if (thread_sp) { 138 lldb::StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0)); 139 if (frame_sp) { 140 const Symbol *symbol = 141 frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol; 142 if (symbol) { 143 if (symbol->GetName() == "_dyld_start") 144 did_exec = true; 145 } 146 } 147 } 148 } 149 150 if (did_exec) { 151 m_libpthread_module_wp.reset(); 152 m_pthread_getspecific_addr.Clear(); 153 } 154 } 155 } 156 return did_exec; 157 } 158 159 // Clear out the state of this class. 160 void DynamicLoaderMacOSXDYLD::DoClear() { 161 std::lock_guard<std::recursive_mutex> guard(m_mutex); 162 163 if (LLDB_BREAK_ID_IS_VALID(m_break_id)) 164 m_process->GetTarget().RemoveBreakpointByID(m_break_id); 165 166 m_dyld_all_image_infos_addr = LLDB_INVALID_ADDRESS; 167 m_dyld_all_image_infos.Clear(); 168 m_break_id = LLDB_INVALID_BREAK_ID; 169 } 170 171 // Check if we have found DYLD yet 172 bool DynamicLoaderMacOSXDYLD::DidSetNotificationBreakpoint() { 173 return LLDB_BREAK_ID_IS_VALID(m_break_id); 174 } 175 176 void DynamicLoaderMacOSXDYLD::ClearNotificationBreakpoint() { 177 if (LLDB_BREAK_ID_IS_VALID(m_break_id)) { 178 m_process->GetTarget().RemoveBreakpointByID(m_break_id); 179 } 180 } 181 182 // Try and figure out where dyld is by first asking the Process if it knows 183 // (which currently calls down in the lldb::Process to get the DYLD info 184 // (available on SnowLeopard only). If that fails, then check in the default 185 // addresses. 186 void DynamicLoaderMacOSXDYLD::DoInitialImageFetch() { 187 if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS) { 188 // Check the image info addr as it might point to the mach header for dyld, 189 // or it might point to the dyld_all_image_infos struct 190 const addr_t shlib_addr = m_process->GetImageInfoAddress(); 191 if (shlib_addr != LLDB_INVALID_ADDRESS) { 192 ByteOrder byte_order = 193 m_process->GetTarget().GetArchitecture().GetByteOrder(); 194 uint8_t buf[4]; 195 DataExtractor data(buf, sizeof(buf), byte_order, 4); 196 Status error; 197 if (m_process->ReadMemory(shlib_addr, buf, 4, error) == 4) { 198 lldb::offset_t offset = 0; 199 uint32_t magic = data.GetU32(&offset); 200 switch (magic) { 201 case llvm::MachO::MH_MAGIC: 202 case llvm::MachO::MH_MAGIC_64: 203 case llvm::MachO::MH_CIGAM: 204 case llvm::MachO::MH_CIGAM_64: 205 m_process_image_addr_is_all_images_infos = false; 206 ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr); 207 return; 208 209 default: 210 break; 211 } 212 } 213 // Maybe it points to the all image infos? 214 m_dyld_all_image_infos_addr = shlib_addr; 215 m_process_image_addr_is_all_images_infos = true; 216 } 217 } 218 219 if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) { 220 if (ReadAllImageInfosStructure()) { 221 if (m_dyld_all_image_infos.dyldImageLoadAddress != LLDB_INVALID_ADDRESS) 222 ReadDYLDInfoFromMemoryAndSetNotificationCallback( 223 m_dyld_all_image_infos.dyldImageLoadAddress); 224 else 225 ReadDYLDInfoFromMemoryAndSetNotificationCallback( 226 m_dyld_all_image_infos_addr & 0xfffffffffff00000ull); 227 return; 228 } 229 } 230 231 // Check some default values 232 Module *executable = m_process->GetTarget().GetExecutableModulePointer(); 233 234 if (executable) { 235 const ArchSpec &exe_arch = executable->GetArchitecture(); 236 if (exe_arch.GetAddressByteSize() == 8) { 237 ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x7fff5fc00000ull); 238 } else if (exe_arch.GetMachine() == llvm::Triple::arm || 239 exe_arch.GetMachine() == llvm::Triple::thumb || 240 exe_arch.GetMachine() == llvm::Triple::aarch64 || 241 exe_arch.GetMachine() == llvm::Triple::aarch64_32) { 242 ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x2fe00000); 243 } else { 244 ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x8fe00000); 245 } 246 } 247 } 248 249 // Assume that dyld is in memory at ADDR and try to parse it's load commands 250 bool DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback( 251 lldb::addr_t addr) { 252 std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); 253 DataExtractor data; // Load command data 254 static ConstString g_dyld_all_image_infos("dyld_all_image_infos"); 255 static ConstString g_new_dyld_all_image_infos("dyld4::dyld_all_image_infos"); 256 if (ReadMachHeader(addr, &m_dyld.header, &data)) { 257 if (m_dyld.header.filetype == llvm::MachO::MH_DYLINKER) { 258 m_dyld.address = addr; 259 ModuleSP dyld_module_sp; 260 if (ParseLoadCommands(data, m_dyld, &m_dyld.file_spec)) { 261 if (m_dyld.file_spec) { 262 if (!UpdateDYLDImageInfoFromNewImageInfo(m_dyld)) 263 return false; 264 } 265 } 266 dyld_module_sp = GetDYLDModule(); 267 if (!dyld_module_sp) 268 return false; 269 270 Target &target = m_process->GetTarget(); 271 272 if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS && 273 dyld_module_sp.get()) { 274 const Symbol *symbol = dyld_module_sp->FindFirstSymbolWithNameAndType( 275 g_dyld_all_image_infos, eSymbolTypeData); 276 if (!symbol) { 277 symbol = dyld_module_sp->FindFirstSymbolWithNameAndType( 278 g_new_dyld_all_image_infos, eSymbolTypeData); 279 } 280 if (symbol) 281 m_dyld_all_image_infos_addr = symbol->GetLoadAddress(&target); 282 } 283 284 if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS) { 285 ConstString g_sect_name("__all_image_info"); 286 SectionSP dyld_aii_section_sp = 287 dyld_module_sp->GetSectionList()->FindSectionByName(g_sect_name); 288 if (dyld_aii_section_sp) { 289 Address dyld_aii_addr(dyld_aii_section_sp, 0); 290 m_dyld_all_image_infos_addr = dyld_aii_addr.GetLoadAddress(&target); 291 } 292 } 293 294 // Update all image infos 295 InitializeFromAllImageInfos(); 296 297 // If we didn't have an executable before, but now we do, then the dyld 298 // module shared pointer might be unique and we may need to add it again 299 // (since Target::SetExecutableModule() will clear the images). So append 300 // the dyld module back to the list if it is 301 /// unique! 302 if (dyld_module_sp) { 303 target.GetImages().AppendIfNeeded(dyld_module_sp); 304 305 // At this point we should have read in dyld's module, and so we should 306 // set breakpoints in it: 307 ModuleList modules; 308 modules.Append(dyld_module_sp); 309 target.ModulesDidLoad(modules); 310 SetDYLDModule(dyld_module_sp); 311 } 312 313 return true; 314 } 315 } 316 return false; 317 } 318 319 bool DynamicLoaderMacOSXDYLD::NeedToDoInitialImageFetch() { 320 return m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS; 321 } 322 323 // Static callback function that gets called when our DYLD notification 324 // breakpoint gets hit. We update all of our image infos and then let our super 325 // class DynamicLoader class decide if we should stop or not (based on global 326 // preference). 327 bool DynamicLoaderMacOSXDYLD::NotifyBreakpointHit( 328 void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, 329 lldb::user_id_t break_loc_id) { 330 // Let the event know that the images have changed 331 // DYLD passes three arguments to the notification breakpoint. 332 // Arg1: enum dyld_image_mode mode - 0 = adding, 1 = removing Arg2: uint32_t 333 // infoCount - Number of shared libraries added Arg3: dyld_image_info 334 // info[] - Array of structs of the form: 335 // const struct mach_header 336 // *imageLoadAddress 337 // const char *imageFilePath 338 // uintptr_t imageFileModDate (a time_t) 339 340 DynamicLoaderMacOSXDYLD *dyld_instance = (DynamicLoaderMacOSXDYLD *)baton; 341 342 // First step is to see if we've already initialized the all image infos. If 343 // we haven't then this function will do so and return true. In the course 344 // of initializing the all_image_infos it will read the complete current 345 // state, so we don't need to figure out what has changed from the data 346 // passed in to us. 347 348 ExecutionContext exe_ctx(context->exe_ctx_ref); 349 Process *process = exe_ctx.GetProcessPtr(); 350 351 // This is a sanity check just in case this dyld_instance is an old dyld 352 // plugin's breakpoint still lying around. 353 if (process != dyld_instance->m_process) 354 return false; 355 356 if (dyld_instance->InitializeFromAllImageInfos()) 357 return dyld_instance->GetStopWhenImagesChange(); 358 359 const lldb::ABISP &abi = process->GetABI(); 360 if (abi) { 361 // Build up the value array to store the three arguments given above, then 362 // get the values from the ABI: 363 364 TypeSystemClangSP scratch_ts_sp = 365 ScratchTypeSystemClang::GetForTarget(process->GetTarget()); 366 if (!scratch_ts_sp) 367 return false; 368 369 ValueList argument_values; 370 Value input_value; 371 372 CompilerType clang_void_ptr_type = 373 scratch_ts_sp->GetBasicType(eBasicTypeVoid).GetPointerType(); 374 CompilerType clang_uint32_type = 375 scratch_ts_sp->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint, 376 32); 377 input_value.SetValueType(Value::ValueType::Scalar); 378 input_value.SetCompilerType(clang_uint32_type); 379 // input_value.SetContext (Value::eContextTypeClangType, 380 // clang_uint32_type); 381 argument_values.PushValue(input_value); 382 argument_values.PushValue(input_value); 383 input_value.SetCompilerType(clang_void_ptr_type); 384 // input_value.SetContext (Value::eContextTypeClangType, 385 // clang_void_ptr_type); 386 argument_values.PushValue(input_value); 387 388 if (abi->GetArgumentValues(exe_ctx.GetThreadRef(), argument_values)) { 389 uint32_t dyld_mode = 390 argument_values.GetValueAtIndex(0)->GetScalar().UInt(-1); 391 if (dyld_mode != static_cast<uint32_t>(-1)) { 392 // Okay the mode was right, now get the number of elements, and the 393 // array of new elements... 394 uint32_t image_infos_count = 395 argument_values.GetValueAtIndex(1)->GetScalar().UInt(-1); 396 if (image_infos_count != static_cast<uint32_t>(-1)) { 397 // Got the number added, now go through the array of added elements, 398 // putting out the mach header address, and adding the image. Note, 399 // I'm not putting in logging here, since the AddModules & 400 // RemoveModules functions do all the logging internally. 401 402 lldb::addr_t image_infos_addr = 403 argument_values.GetValueAtIndex(2)->GetScalar().ULongLong(); 404 if (dyld_mode == 0) { 405 // This is add: 406 dyld_instance->AddModulesUsingImageInfosAddress(image_infos_addr, 407 image_infos_count); 408 } else { 409 // This is remove: 410 dyld_instance->RemoveModulesUsingImageInfosAddress( 411 image_infos_addr, image_infos_count); 412 } 413 } 414 } 415 } 416 } else { 417 Target &target = process->GetTarget(); 418 Debugger::ReportWarning( 419 "no ABI plugin located for triple " + 420 target.GetArchitecture().GetTriple().getTriple() + 421 ": shared libraries will not be registered", 422 target.GetDebugger().GetID()); 423 } 424 425 // Return true to stop the target, false to just let the target run 426 return dyld_instance->GetStopWhenImagesChange(); 427 } 428 429 bool DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure() { 430 std::lock_guard<std::recursive_mutex> guard(m_mutex); 431 432 // the all image infos is already valid for this process stop ID 433 if (m_process->GetStopID() == m_dyld_all_image_infos_stop_id) 434 return true; 435 436 m_dyld_all_image_infos.Clear(); 437 if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) { 438 ByteOrder byte_order = 439 m_process->GetTarget().GetArchitecture().GetByteOrder(); 440 uint32_t addr_size = 441 m_process->GetTarget().GetArchitecture().GetAddressByteSize(); 442 443 uint8_t buf[256]; 444 DataExtractor data(buf, sizeof(buf), byte_order, addr_size); 445 lldb::offset_t offset = 0; 446 447 const size_t count_v2 = sizeof(uint32_t) + // version 448 sizeof(uint32_t) + // infoArrayCount 449 addr_size + // infoArray 450 addr_size + // notification 451 addr_size + // processDetachedFromSharedRegion + 452 // libSystemInitialized + pad 453 addr_size; // dyldImageLoadAddress 454 const size_t count_v11 = count_v2 + addr_size + // jitInfo 455 addr_size + // dyldVersion 456 addr_size + // errorMessage 457 addr_size + // terminationFlags 458 addr_size + // coreSymbolicationShmPage 459 addr_size + // systemOrderFlag 460 addr_size + // uuidArrayCount 461 addr_size + // uuidArray 462 addr_size + // dyldAllImageInfosAddress 463 addr_size + // initialImageCount 464 addr_size + // errorKind 465 addr_size + // errorClientOfDylibPath 466 addr_size + // errorTargetDylibPath 467 addr_size; // errorSymbol 468 const size_t count_v13 = count_v11 + addr_size + // sharedCacheSlide 469 sizeof(uuid_t); // sharedCacheUUID 470 UNUSED_IF_ASSERT_DISABLED(count_v13); 471 assert(sizeof(buf) >= count_v13); 472 473 Status error; 474 if (m_process->ReadMemory(m_dyld_all_image_infos_addr, buf, 4, error) == 475 4) { 476 m_dyld_all_image_infos.version = data.GetU32(&offset); 477 // If anything in the high byte is set, we probably got the byte order 478 // incorrect (the process might not have it set correctly yet due to 479 // attaching to a program without a specified file). 480 if (m_dyld_all_image_infos.version & 0xff000000) { 481 // We have guessed the wrong byte order. Swap it and try reading the 482 // version again. 483 if (byte_order == eByteOrderLittle) 484 byte_order = eByteOrderBig; 485 else 486 byte_order = eByteOrderLittle; 487 488 data.SetByteOrder(byte_order); 489 offset = 0; 490 m_dyld_all_image_infos.version = data.GetU32(&offset); 491 } 492 } else { 493 return false; 494 } 495 496 const size_t count = 497 (m_dyld_all_image_infos.version >= 11) ? count_v11 : count_v2; 498 499 const size_t bytes_read = 500 m_process->ReadMemory(m_dyld_all_image_infos_addr, buf, count, error); 501 if (bytes_read == count) { 502 offset = 0; 503 m_dyld_all_image_infos.version = data.GetU32(&offset); 504 m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset); 505 m_dyld_all_image_infos.dylib_info_addr = data.GetAddress(&offset); 506 m_dyld_all_image_infos.notification = data.GetAddress(&offset); 507 m_dyld_all_image_infos.processDetachedFromSharedRegion = 508 data.GetU8(&offset); 509 m_dyld_all_image_infos.libSystemInitialized = data.GetU8(&offset); 510 // Adjust for padding. 511 offset += addr_size - 2; 512 m_dyld_all_image_infos.dyldImageLoadAddress = data.GetAddress(&offset); 513 if (m_dyld_all_image_infos.version >= 11) { 514 offset += addr_size * 8; 515 uint64_t dyld_all_image_infos_addr = data.GetAddress(&offset); 516 517 // When we started, we were given the actual address of the 518 // all_image_infos struct (probably via TASK_DYLD_INFO) in memory - 519 // this address is stored in m_dyld_all_image_infos_addr and is the 520 // most accurate address we have. 521 522 // We read the dyld_all_image_infos struct from memory; it contains its 523 // own address. If the address in the struct does not match the actual 524 // address, the dyld we're looking at has been loaded at a different 525 // location (slid) from where it intended to load. The addresses in 526 // the dyld_all_image_infos struct are the original, non-slid 527 // addresses, and need to be adjusted. Most importantly the address of 528 // dyld and the notification address need to be adjusted. 529 530 if (dyld_all_image_infos_addr != m_dyld_all_image_infos_addr) { 531 uint64_t image_infos_offset = 532 dyld_all_image_infos_addr - 533 m_dyld_all_image_infos.dyldImageLoadAddress; 534 uint64_t notification_offset = 535 m_dyld_all_image_infos.notification - 536 m_dyld_all_image_infos.dyldImageLoadAddress; 537 m_dyld_all_image_infos.dyldImageLoadAddress = 538 m_dyld_all_image_infos_addr - image_infos_offset; 539 m_dyld_all_image_infos.notification = 540 m_dyld_all_image_infos.dyldImageLoadAddress + notification_offset; 541 } 542 } 543 m_dyld_all_image_infos_stop_id = m_process->GetStopID(); 544 return true; 545 } 546 } 547 return false; 548 } 549 550 bool DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress( 551 lldb::addr_t image_infos_addr, uint32_t image_infos_count) { 552 ImageInfo::collection image_infos; 553 Log *log = GetLog(LLDBLog::DynamicLoader); 554 LLDB_LOGF(log, "Adding %d modules.\n", image_infos_count); 555 556 std::lock_guard<std::recursive_mutex> guard(m_mutex); 557 std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); 558 if (m_process->GetStopID() == m_dyld_image_infos_stop_id) 559 return true; 560 561 StructuredData::ObjectSP image_infos_json_sp = 562 m_process->GetLoadedDynamicLibrariesInfos(image_infos_addr, 563 image_infos_count); 564 if (image_infos_json_sp.get() && image_infos_json_sp->GetAsDictionary() && 565 image_infos_json_sp->GetAsDictionary()->HasKey("images") && 566 image_infos_json_sp->GetAsDictionary() 567 ->GetValueForKey("images") 568 ->GetAsArray() && 569 image_infos_json_sp->GetAsDictionary() 570 ->GetValueForKey("images") 571 ->GetAsArray() 572 ->GetSize() == image_infos_count) { 573 bool return_value = false; 574 if (JSONImageInformationIntoImageInfo(image_infos_json_sp, image_infos)) { 575 auto images = PreloadModulesFromImageInfos(image_infos); 576 UpdateSpecialBinariesFromPreloadedModules(images); 577 return_value = AddModulesUsingPreloadedModules(images); 578 } 579 m_dyld_image_infos_stop_id = m_process->GetStopID(); 580 return return_value; 581 } 582 583 if (!ReadImageInfos(image_infos_addr, image_infos_count, image_infos)) 584 return false; 585 586 UpdateImageInfosHeaderAndLoadCommands(image_infos, image_infos_count, false); 587 bool return_value = AddModulesUsingImageInfos(image_infos); 588 m_dyld_image_infos_stop_id = m_process->GetStopID(); 589 return return_value; 590 } 591 592 bool DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress( 593 lldb::addr_t image_infos_addr, uint32_t image_infos_count) { 594 ImageInfo::collection image_infos; 595 Log *log = GetLog(LLDBLog::DynamicLoader); 596 597 std::lock_guard<std::recursive_mutex> guard(m_mutex); 598 std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); 599 if (m_process->GetStopID() == m_dyld_image_infos_stop_id) 600 return true; 601 602 // First read in the image_infos for the removed modules, and their headers & 603 // load commands. 604 if (!ReadImageInfos(image_infos_addr, image_infos_count, image_infos)) { 605 if (log) 606 log->PutCString("Failed reading image infos array."); 607 return false; 608 } 609 610 LLDB_LOGF(log, "Removing %d modules.", image_infos_count); 611 612 ModuleList unloaded_module_list; 613 for (uint32_t idx = 0; idx < image_infos.size(); ++idx) { 614 if (log) { 615 LLDB_LOGF(log, "Removing module at address=0x%16.16" PRIx64 ".", 616 image_infos[idx].address); 617 image_infos[idx].PutToLog(log); 618 } 619 620 // Remove this image_infos from the m_all_image_infos. We do the 621 // comparison by address rather than by file spec because we can have many 622 // modules with the same "file spec" in the case that they are modules 623 // loaded from memory. 624 // 625 // Also copy over the uuid from the old entry to the removed entry so we 626 // can use it to lookup the module in the module list. 627 628 bool found = false; 629 630 for (ImageInfo::collection::iterator pos = m_dyld_image_infos.begin(); 631 pos != m_dyld_image_infos.end(); pos++) { 632 if (image_infos[idx].address == (*pos).address) { 633 image_infos[idx].uuid = (*pos).uuid; 634 635 // Add the module from this image_info to the "unloaded_module_list". 636 // We'll remove them all at one go later on. 637 638 ModuleSP unload_image_module_sp( 639 FindTargetModuleForImageInfo(image_infos[idx], false, nullptr)); 640 if (unload_image_module_sp.get()) { 641 // When we unload, be sure to use the image info from the old list, 642 // since that has sections correctly filled in. 643 UnloadModuleSections(unload_image_module_sp.get(), *pos); 644 unloaded_module_list.AppendIfNeeded(unload_image_module_sp); 645 } else { 646 if (log) { 647 LLDB_LOGF(log, "Could not find module for unloading info entry:"); 648 image_infos[idx].PutToLog(log); 649 } 650 } 651 652 // Then remove it from the m_dyld_image_infos: 653 654 m_dyld_image_infos.erase(pos); 655 found = true; 656 break; 657 } 658 } 659 660 if (!found) { 661 if (log) { 662 LLDB_LOGF(log, "Could not find image_info entry for unloading image:"); 663 image_infos[idx].PutToLog(log); 664 } 665 } 666 } 667 if (unloaded_module_list.GetSize() > 0) { 668 if (log) { 669 log->PutCString("Unloaded:"); 670 unloaded_module_list.LogUUIDAndPaths( 671 log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload"); 672 } 673 m_process->GetTarget().GetImages().Remove(unloaded_module_list); 674 } 675 m_dyld_image_infos_stop_id = m_process->GetStopID(); 676 return true; 677 } 678 679 bool DynamicLoaderMacOSXDYLD::ReadImageInfos( 680 lldb::addr_t image_infos_addr, uint32_t image_infos_count, 681 ImageInfo::collection &image_infos) { 682 std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); 683 const ByteOrder endian = GetByteOrderFromMagic(m_dyld.header.magic); 684 const uint32_t addr_size = m_dyld.GetAddressByteSize(); 685 686 image_infos.resize(image_infos_count); 687 const size_t count = image_infos.size() * 3 * addr_size; 688 DataBufferHeap info_data(count, 0); 689 Status error; 690 const size_t bytes_read = m_process->ReadMemory( 691 image_infos_addr, info_data.GetBytes(), info_data.GetByteSize(), error); 692 if (bytes_read == count) { 693 lldb::offset_t info_data_offset = 0; 694 DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), 695 endian, addr_size); 696 for (size_t i = 0; 697 i < image_infos.size() && info_data_ref.ValidOffset(info_data_offset); 698 i++) { 699 image_infos[i].address = info_data_ref.GetAddress(&info_data_offset); 700 lldb::addr_t path_addr = info_data_ref.GetAddress(&info_data_offset); 701 info_data_ref.GetAddress(&info_data_offset); // mod_date, unused */ 702 703 char raw_path[PATH_MAX]; 704 m_process->ReadCStringFromMemory(path_addr, raw_path, sizeof(raw_path), 705 error); 706 // don't resolve the path 707 if (error.Success()) { 708 image_infos[i].file_spec.SetFile(raw_path, FileSpec::Style::native); 709 } 710 } 711 return true; 712 } else { 713 return false; 714 } 715 } 716 717 // If we have found where the "_dyld_all_image_infos" lives in memory, read the 718 // current info from it, and then update all image load addresses (or lack 719 // thereof). Only do this if this is the first time we're reading the dyld 720 // infos. Return true if we actually read anything, and false otherwise. 721 bool DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos() { 722 Log *log = GetLog(LLDBLog::DynamicLoader); 723 724 std::lock_guard<std::recursive_mutex> guard(m_mutex); 725 std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); 726 if (m_process->GetStopID() == m_dyld_image_infos_stop_id || 727 m_dyld_image_infos.size() != 0) 728 return false; 729 730 if (ReadAllImageInfosStructure()) { 731 // Nothing to load or unload? 732 if (m_dyld_all_image_infos.dylib_info_count == 0) 733 return true; 734 735 if (m_dyld_all_image_infos.dylib_info_addr == 0) { 736 // DYLD is updating the images now. So we should say we have no images, 737 // and then we'll 738 // figure it out when we hit the added breakpoint. 739 return false; 740 } else { 741 if (!AddModulesUsingImageInfosAddress( 742 m_dyld_all_image_infos.dylib_info_addr, 743 m_dyld_all_image_infos.dylib_info_count)) { 744 DEBUG_PRINTF("%s", "unable to read all data for all_dylib_infos."); 745 m_dyld_image_infos.clear(); 746 } 747 } 748 749 // Now we have one more bit of business. If there is a library left in the 750 // images for our target that doesn't have a load address, then it must be 751 // something that we were expecting to load (for instance we read a load 752 // command for it) but it didn't in fact load - probably because 753 // DYLD_*_PATH pointed to an equivalent version. We don't want it to stay 754 // in the target's module list or it will confuse us, so unload it here. 755 Target &target = m_process->GetTarget(); 756 ModuleList not_loaded_modules; 757 for (ModuleSP module_sp : target.GetImages().Modules()) { 758 if (!module_sp->IsLoadedInTarget(&target)) { 759 if (log) { 760 StreamString s; 761 module_sp->GetDescription(s.AsRawOstream()); 762 LLDB_LOGF(log, "Unloading pre-run module: %s.", s.GetData()); 763 } 764 not_loaded_modules.Append(module_sp); 765 } 766 } 767 768 if (not_loaded_modules.GetSize() != 0) { 769 target.GetImages().Remove(not_loaded_modules); 770 } 771 772 return true; 773 } else 774 return false; 775 } 776 777 // Read a mach_header at ADDR into HEADER, and also fill in the load command 778 // data into LOAD_COMMAND_DATA if it is non-NULL. 779 // 780 // Returns true if we succeed, false if we fail for any reason. 781 bool DynamicLoaderMacOSXDYLD::ReadMachHeader(lldb::addr_t addr, 782 llvm::MachO::mach_header *header, 783 DataExtractor *load_command_data) { 784 DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0); 785 Status error; 786 size_t bytes_read = m_process->ReadMemory(addr, header_bytes.GetBytes(), 787 header_bytes.GetByteSize(), error); 788 if (bytes_read == sizeof(llvm::MachO::mach_header)) { 789 lldb::offset_t offset = 0; 790 ::memset(header, 0, sizeof(llvm::MachO::mach_header)); 791 792 // Get the magic byte unswapped so we can figure out what we are dealing 793 // with 794 DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), 795 endian::InlHostByteOrder(), 4); 796 header->magic = data.GetU32(&offset); 797 lldb::addr_t load_cmd_addr = addr; 798 data.SetByteOrder( 799 DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header->magic)); 800 switch (header->magic) { 801 case llvm::MachO::MH_MAGIC: 802 case llvm::MachO::MH_CIGAM: 803 data.SetAddressByteSize(4); 804 load_cmd_addr += sizeof(llvm::MachO::mach_header); 805 break; 806 807 case llvm::MachO::MH_MAGIC_64: 808 case llvm::MachO::MH_CIGAM_64: 809 data.SetAddressByteSize(8); 810 load_cmd_addr += sizeof(llvm::MachO::mach_header_64); 811 break; 812 813 default: 814 return false; 815 } 816 817 // Read the rest of dyld's mach header 818 if (data.GetU32(&offset, &header->cputype, 819 (sizeof(llvm::MachO::mach_header) / sizeof(uint32_t)) - 820 1)) { 821 if (load_command_data == nullptr) 822 return true; // We were able to read the mach_header and weren't asked 823 // to read the load command bytes 824 825 WritableDataBufferSP load_cmd_data_sp( 826 new DataBufferHeap(header->sizeofcmds, 0)); 827 828 size_t load_cmd_bytes_read = 829 m_process->ReadMemory(load_cmd_addr, load_cmd_data_sp->GetBytes(), 830 load_cmd_data_sp->GetByteSize(), error); 831 832 if (load_cmd_bytes_read == header->sizeofcmds) { 833 // Set the load command data and also set the correct endian swap 834 // settings and the correct address size 835 load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds); 836 load_command_data->SetByteOrder(data.GetByteOrder()); 837 load_command_data->SetAddressByteSize(data.GetAddressByteSize()); 838 return true; // We successfully read the mach_header and the load 839 // command data 840 } 841 842 return false; // We weren't able to read the load command data 843 } 844 } 845 return false; // We failed the read the mach_header 846 } 847 848 // Parse the load commands for an image 849 uint32_t DynamicLoaderMacOSXDYLD::ParseLoadCommands(const DataExtractor &data, 850 ImageInfo &dylib_info, 851 FileSpec *lc_id_dylinker) { 852 lldb::offset_t offset = 0; 853 uint32_t cmd_idx; 854 Segment segment; 855 dylib_info.Clear(true); 856 857 for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++) { 858 // Clear out any load command specific data from DYLIB_INFO since we are 859 // about to read it. 860 861 if (data.ValidOffsetForDataOfSize(offset, 862 sizeof(llvm::MachO::load_command))) { 863 llvm::MachO::load_command load_cmd; 864 lldb::offset_t load_cmd_offset = offset; 865 load_cmd.cmd = data.GetU32(&offset); 866 load_cmd.cmdsize = data.GetU32(&offset); 867 switch (load_cmd.cmd) { 868 case llvm::MachO::LC_SEGMENT: { 869 segment.name.SetTrimmedCStringWithLength( 870 (const char *)data.GetData(&offset, 16), 16); 871 // We are putting 4 uint32_t values 4 uint64_t values so we have to use 872 // multiple 32 bit gets below. 873 segment.vmaddr = data.GetU32(&offset); 874 segment.vmsize = data.GetU32(&offset); 875 segment.fileoff = data.GetU32(&offset); 876 segment.filesize = data.GetU32(&offset); 877 // Extract maxprot, initprot, nsects and flags all at once 878 data.GetU32(&offset, &segment.maxprot, 4); 879 dylib_info.segments.push_back(segment); 880 } break; 881 882 case llvm::MachO::LC_SEGMENT_64: { 883 segment.name.SetTrimmedCStringWithLength( 884 (const char *)data.GetData(&offset, 16), 16); 885 // Extract vmaddr, vmsize, fileoff, and filesize all at once 886 data.GetU64(&offset, &segment.vmaddr, 4); 887 // Extract maxprot, initprot, nsects and flags all at once 888 data.GetU32(&offset, &segment.maxprot, 4); 889 dylib_info.segments.push_back(segment); 890 } break; 891 892 case llvm::MachO::LC_ID_DYLINKER: 893 if (lc_id_dylinker) { 894 const lldb::offset_t name_offset = 895 load_cmd_offset + data.GetU32(&offset); 896 const char *path = data.PeekCStr(name_offset); 897 lc_id_dylinker->SetFile(path, FileSpec::Style::native); 898 FileSystem::Instance().Resolve(*lc_id_dylinker); 899 } 900 break; 901 902 case llvm::MachO::LC_UUID: 903 dylib_info.uuid = UUID(data.GetData(&offset, 16), 16); 904 break; 905 906 default: 907 break; 908 } 909 // Set offset to be the beginning of the next load command. 910 offset = load_cmd_offset + load_cmd.cmdsize; 911 } 912 } 913 914 // All sections listed in the dyld image info structure will all either be 915 // fixed up already, or they will all be off by a single slide amount that is 916 // determined by finding the first segment that is at file offset zero which 917 // also has bytes (a file size that is greater than zero) in the object file. 918 919 // Determine the slide amount (if any) 920 const size_t num_sections = dylib_info.segments.size(); 921 for (size_t i = 0; i < num_sections; ++i) { 922 // Iterate through the object file sections to find the first section that 923 // starts of file offset zero and that has bytes in the file... 924 if ((dylib_info.segments[i].fileoff == 0 && 925 dylib_info.segments[i].filesize > 0) || 926 (dylib_info.segments[i].name == "__TEXT")) { 927 dylib_info.slide = dylib_info.address - dylib_info.segments[i].vmaddr; 928 // We have found the slide amount, so we can exit this for loop. 929 break; 930 } 931 } 932 return cmd_idx; 933 } 934 935 // Read the mach_header and load commands for each image that the 936 // _dyld_all_image_infos structure points to and cache the results. 937 938 void DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands( 939 ImageInfo::collection &image_infos, uint32_t infos_count, 940 bool update_executable) { 941 uint32_t exe_idx = UINT32_MAX; 942 // Read any UUID values that we can get 943 for (uint32_t i = 0; i < infos_count; i++) { 944 if (!image_infos[i].UUIDValid()) { 945 DataExtractor data; // Load command data 946 if (!ReadMachHeader(image_infos[i].address, &image_infos[i].header, 947 &data)) 948 continue; 949 950 ParseLoadCommands(data, image_infos[i], nullptr); 951 952 if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE) 953 exe_idx = i; 954 } 955 } 956 957 Target &target = m_process->GetTarget(); 958 959 if (exe_idx < image_infos.size()) { 960 const bool can_create = true; 961 ModuleSP exe_module_sp(FindTargetModuleForImageInfo(image_infos[exe_idx], 962 can_create, nullptr)); 963 964 if (exe_module_sp) { 965 UpdateImageLoadAddress(exe_module_sp.get(), image_infos[exe_idx]); 966 967 if (exe_module_sp.get() != target.GetExecutableModulePointer()) { 968 // Don't load dependent images since we are in dyld where we will know 969 // and find out about all images that are loaded. Also when setting the 970 // executable module, it will clear the targets module list, and if we 971 // have an in memory dyld module, it will get removed from the list so 972 // we will need to add it back after setting the executable module, so 973 // we first try and see if we already have a weak pointer to the dyld 974 // module, make it into a shared pointer, then add the executable, then 975 // re-add it back to make sure it is always in the list. 976 ModuleSP dyld_module_sp(GetDYLDModule()); 977 978 m_process->GetTarget().SetExecutableModule(exe_module_sp, 979 eLoadDependentsNo); 980 981 if (dyld_module_sp) { 982 if (target.GetImages().AppendIfNeeded(dyld_module_sp)) { 983 std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); 984 985 // Also add it to the section list. 986 UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld); 987 } 988 } 989 } 990 } 991 } 992 } 993 994 // Dump the _dyld_all_image_infos members and all current image infos that we 995 // have parsed to the file handle provided. 996 void DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const { 997 if (log == nullptr) 998 return; 999 1000 std::lock_guard<std::recursive_mutex> guard(m_mutex); 1001 std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); 1002 LLDB_LOGF(log, 1003 "dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8" PRIx64 1004 ", notify=0x%8.8" PRIx64 " }", 1005 m_dyld_all_image_infos.version, 1006 m_dyld_all_image_infos.dylib_info_count, 1007 (uint64_t)m_dyld_all_image_infos.dylib_info_addr, 1008 (uint64_t)m_dyld_all_image_infos.notification); 1009 size_t i; 1010 const size_t count = m_dyld_image_infos.size(); 1011 if (count > 0) { 1012 log->PutCString("Loaded:"); 1013 for (i = 0; i < count; i++) 1014 m_dyld_image_infos[i].PutToLog(log); 1015 } 1016 } 1017 1018 bool DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint() { 1019 DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", 1020 __FUNCTION__, StateAsCString(m_process->GetState())); 1021 if (m_break_id == LLDB_INVALID_BREAK_ID) { 1022 if (m_dyld_all_image_infos.notification != LLDB_INVALID_ADDRESS) { 1023 Address so_addr; 1024 // Set the notification breakpoint and install a breakpoint callback 1025 // function that will get called each time the breakpoint gets hit. We 1026 // will use this to track when shared libraries get loaded/unloaded. 1027 bool resolved = m_process->GetTarget().ResolveLoadAddress( 1028 m_dyld_all_image_infos.notification, so_addr); 1029 if (!resolved) { 1030 ModuleSP dyld_module_sp = GetDYLDModule(); 1031 if (dyld_module_sp) { 1032 std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); 1033 1034 UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld); 1035 resolved = m_process->GetTarget().ResolveLoadAddress( 1036 m_dyld_all_image_infos.notification, so_addr); 1037 } 1038 } 1039 1040 if (resolved) { 1041 Breakpoint *dyld_break = 1042 m_process->GetTarget().CreateBreakpoint(so_addr, true, false).get(); 1043 dyld_break->SetCallback(DynamicLoaderMacOSXDYLD::NotifyBreakpointHit, 1044 this, true); 1045 dyld_break->SetBreakpointKind("shared-library-event"); 1046 m_break_id = dyld_break->GetID(); 1047 } 1048 } 1049 } 1050 return m_break_id != LLDB_INVALID_BREAK_ID; 1051 } 1052 1053 Status DynamicLoaderMacOSXDYLD::CanLoadImage() { 1054 Status error; 1055 // In order for us to tell if we can load a shared library we verify that the 1056 // dylib_info_addr isn't zero (which means no shared libraries have been set 1057 // yet, or dyld is currently mucking with the shared library list). 1058 if (ReadAllImageInfosStructure()) { 1059 // TODO: also check the _dyld_global_lock_held variable in 1060 // libSystem.B.dylib? 1061 // TODO: check the malloc lock? 1062 // TODO: check the objective C lock? 1063 if (m_dyld_all_image_infos.dylib_info_addr != 0) 1064 return error; // Success 1065 } 1066 1067 error = Status::FromErrorString("unsafe to load or unload shared libraries"); 1068 return error; 1069 } 1070 1071 bool DynamicLoaderMacOSXDYLD::GetSharedCacheInformation( 1072 lldb::addr_t &base_address, UUID &uuid, LazyBool &using_shared_cache, 1073 LazyBool &private_shared_cache) { 1074 base_address = LLDB_INVALID_ADDRESS; 1075 uuid.Clear(); 1076 using_shared_cache = eLazyBoolCalculate; 1077 private_shared_cache = eLazyBoolCalculate; 1078 1079 if (m_process) { 1080 addr_t all_image_infos = m_process->GetImageInfoAddress(); 1081 1082 // The address returned by GetImageInfoAddress may be the address of dyld 1083 // (don't want) or it may be the address of the dyld_all_image_infos 1084 // structure (want). The first four bytes will be either the version field 1085 // (all_image_infos) or a Mach-O file magic constant. Version 13 and higher 1086 // of dyld_all_image_infos is required to get the sharedCacheUUID field. 1087 1088 Status err; 1089 uint32_t version_or_magic = 1090 m_process->ReadUnsignedIntegerFromMemory(all_image_infos, 4, -1, err); 1091 if (version_or_magic != static_cast<uint32_t>(-1) && 1092 version_or_magic != llvm::MachO::MH_MAGIC && 1093 version_or_magic != llvm::MachO::MH_CIGAM && 1094 version_or_magic != llvm::MachO::MH_MAGIC_64 && 1095 version_or_magic != llvm::MachO::MH_CIGAM_64 && 1096 version_or_magic >= 13) { 1097 addr_t sharedCacheUUID_address = LLDB_INVALID_ADDRESS; 1098 int wordsize = m_process->GetAddressByteSize(); 1099 if (wordsize == 8) { 1100 sharedCacheUUID_address = 1101 all_image_infos + 160; // sharedCacheUUID <mach-o/dyld_images.h> 1102 } 1103 if (wordsize == 4) { 1104 sharedCacheUUID_address = 1105 all_image_infos + 84; // sharedCacheUUID <mach-o/dyld_images.h> 1106 } 1107 if (sharedCacheUUID_address != LLDB_INVALID_ADDRESS) { 1108 uuid_t shared_cache_uuid; 1109 if (m_process->ReadMemory(sharedCacheUUID_address, shared_cache_uuid, 1110 sizeof(uuid_t), err) == sizeof(uuid_t)) { 1111 uuid = UUID(shared_cache_uuid, 16); 1112 if (uuid.IsValid()) { 1113 using_shared_cache = eLazyBoolYes; 1114 } 1115 } 1116 1117 if (version_or_magic >= 15) { 1118 // The sharedCacheBaseAddress field is the next one in the 1119 // dyld_all_image_infos struct. 1120 addr_t sharedCacheBaseAddr_address = sharedCacheUUID_address + 16; 1121 Status error; 1122 base_address = m_process->ReadUnsignedIntegerFromMemory( 1123 sharedCacheBaseAddr_address, wordsize, LLDB_INVALID_ADDRESS, 1124 error); 1125 if (error.Fail()) 1126 base_address = LLDB_INVALID_ADDRESS; 1127 } 1128 1129 return true; 1130 } 1131 1132 // 1133 // add 1134 // NB: sharedCacheBaseAddress is the next field in dyld_all_image_infos 1135 // after 1136 // sharedCacheUUID -- that is, 16 bytes after it, if we wanted to fetch 1137 // it. 1138 } 1139 } 1140 return false; 1141 } 1142 1143 bool DynamicLoaderMacOSXDYLD::IsFullyInitialized() { 1144 if (ReadAllImageInfosStructure()) 1145 return m_dyld_all_image_infos.libSystemInitialized; 1146 return false; 1147 } 1148 1149 void DynamicLoaderMacOSXDYLD::Initialize() { 1150 PluginManager::RegisterPlugin(GetPluginNameStatic(), 1151 GetPluginDescriptionStatic(), CreateInstance, 1152 DebuggerInitialize); 1153 DynamicLoaderMacOS::Initialize(); 1154 } 1155 1156 void DynamicLoaderMacOSXDYLD::Terminate() { 1157 DynamicLoaderMacOS::Terminate(); 1158 PluginManager::UnregisterPlugin(CreateInstance); 1159 } 1160 1161 void DynamicLoaderMacOSXDYLD::DebuggerInitialize( 1162 lldb_private::Debugger &debugger) { 1163 CreateSettings(debugger); 1164 } 1165 1166 llvm::StringRef DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic() { 1167 return "Dynamic loader plug-in that watches for shared library loads/unloads " 1168 "in MacOSX user processes."; 1169 } 1170 1171 uint32_t DynamicLoaderMacOSXDYLD::AddrByteSize() { 1172 std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); 1173 1174 switch (m_dyld.header.magic) { 1175 case llvm::MachO::MH_MAGIC: 1176 case llvm::MachO::MH_CIGAM: 1177 return 4; 1178 1179 case llvm::MachO::MH_MAGIC_64: 1180 case llvm::MachO::MH_CIGAM_64: 1181 return 8; 1182 1183 default: 1184 break; 1185 } 1186 return 0; 1187 } 1188 1189 lldb::ByteOrder DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(uint32_t magic) { 1190 switch (magic) { 1191 case llvm::MachO::MH_MAGIC: 1192 case llvm::MachO::MH_MAGIC_64: 1193 return endian::InlHostByteOrder(); 1194 1195 case llvm::MachO::MH_CIGAM: 1196 case llvm::MachO::MH_CIGAM_64: 1197 if (endian::InlHostByteOrder() == lldb::eByteOrderBig) 1198 return lldb::eByteOrderLittle; 1199 else 1200 return lldb::eByteOrderBig; 1201 1202 default: 1203 break; 1204 } 1205 return lldb::eByteOrderInvalid; 1206 } 1207