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