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/Debugger.h" 14 #include "lldb/Core/Log.h" 15 #include "lldb/Core/Module.h" 16 #include "lldb/Core/ModuleSpec.h" 17 #include "lldb/Core/PluginManager.h" 18 #include "lldb/Core/Section.h" 19 #include "lldb/Core/State.h" 20 #include "lldb/Symbol/ClangASTContext.h" 21 #include "lldb/Symbol/Function.h" 22 #include "lldb/Symbol/ObjectFile.h" 23 #include "lldb/Target/ABI.h" 24 #include "lldb/Target/ObjCLanguageRuntime.h" 25 #include "lldb/Target/RegisterContext.h" 26 #include "lldb/Target/StackFrame.h" 27 #include "lldb/Target/Target.h" 28 #include "lldb/Target/Thread.h" 29 #include "lldb/Target/ThreadPlanRunToAddress.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 Error 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 = 4; 434 if (m_dyld_all_image_infos_addr > UINT32_MAX) 435 addr_size = 8; 436 437 uint8_t buf[256]; 438 DataExtractor data(buf, sizeof(buf), byte_order, addr_size); 439 lldb::offset_t offset = 0; 440 441 const size_t count_v2 = sizeof(uint32_t) + // version 442 sizeof(uint32_t) + // infoArrayCount 443 addr_size + // infoArray 444 addr_size + // notification 445 addr_size + // processDetachedFromSharedRegion + 446 // libSystemInitialized + pad 447 addr_size; // dyldImageLoadAddress 448 const size_t count_v11 = count_v2 + addr_size + // jitInfo 449 addr_size + // dyldVersion 450 addr_size + // errorMessage 451 addr_size + // terminationFlags 452 addr_size + // coreSymbolicationShmPage 453 addr_size + // systemOrderFlag 454 addr_size + // uuidArrayCount 455 addr_size + // uuidArray 456 addr_size + // dyldAllImageInfosAddress 457 addr_size + // initialImageCount 458 addr_size + // errorKind 459 addr_size + // errorClientOfDylibPath 460 addr_size + // errorTargetDylibPath 461 addr_size; // errorSymbol 462 const size_t count_v13 = count_v11 + addr_size + // sharedCacheSlide 463 sizeof(uuid_t); // sharedCacheUUID 464 UNUSED_IF_ASSERT_DISABLED(count_v13); 465 assert(sizeof(buf) >= count_v13); 466 467 Error error; 468 if (m_process->ReadMemory(m_dyld_all_image_infos_addr, buf, 4, error) == 469 4) { 470 m_dyld_all_image_infos.version = data.GetU32(&offset); 471 // If anything in the high byte is set, we probably got the byte 472 // order incorrect (the process might not have it set correctly 473 // yet due to attaching to a program without a specified file). 474 if (m_dyld_all_image_infos.version & 0xff000000) { 475 // We have guessed the wrong byte order. Swap it and try 476 // reading the version again. 477 if (byte_order == eByteOrderLittle) 478 byte_order = eByteOrderBig; 479 else 480 byte_order = eByteOrderLittle; 481 482 data.SetByteOrder(byte_order); 483 offset = 0; 484 m_dyld_all_image_infos.version = data.GetU32(&offset); 485 } 486 } else { 487 return false; 488 } 489 490 const size_t count = 491 (m_dyld_all_image_infos.version >= 11) ? count_v11 : count_v2; 492 493 const size_t bytes_read = 494 m_process->ReadMemory(m_dyld_all_image_infos_addr, buf, count, error); 495 if (bytes_read == count) { 496 offset = 0; 497 m_dyld_all_image_infos.version = data.GetU32(&offset); 498 m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset); 499 m_dyld_all_image_infos.dylib_info_addr = data.GetPointer(&offset); 500 m_dyld_all_image_infos.notification = data.GetPointer(&offset); 501 m_dyld_all_image_infos.processDetachedFromSharedRegion = 502 data.GetU8(&offset); 503 m_dyld_all_image_infos.libSystemInitialized = data.GetU8(&offset); 504 // Adjust for padding. 505 offset += addr_size - 2; 506 m_dyld_all_image_infos.dyldImageLoadAddress = data.GetPointer(&offset); 507 if (m_dyld_all_image_infos.version >= 11) { 508 offset += addr_size * 8; 509 uint64_t dyld_all_image_infos_addr = data.GetPointer(&offset); 510 511 // When we started, we were given the actual address of the 512 // all_image_infos 513 // struct (probably via TASK_DYLD_INFO) in memory - this address is 514 // stored in 515 // m_dyld_all_image_infos_addr and is the most accurate address we have. 516 517 // We read the dyld_all_image_infos struct from memory; it contains its 518 // own address. 519 // If the address in the struct does not match the actual address, 520 // the dyld we're looking at has been loaded at a different location 521 // (slid) from 522 // where it intended to load. The addresses in the dyld_all_image_infos 523 // struct 524 // are the original, non-slid addresses, and need to be adjusted. Most 525 // importantly 526 // the address of dyld and the notification address need to be adjusted. 527 528 if (dyld_all_image_infos_addr != m_dyld_all_image_infos_addr) { 529 uint64_t image_infos_offset = 530 dyld_all_image_infos_addr - 531 m_dyld_all_image_infos.dyldImageLoadAddress; 532 uint64_t notification_offset = 533 m_dyld_all_image_infos.notification - 534 m_dyld_all_image_infos.dyldImageLoadAddress; 535 m_dyld_all_image_infos.dyldImageLoadAddress = 536 m_dyld_all_image_infos_addr - image_infos_offset; 537 m_dyld_all_image_infos.notification = 538 m_dyld_all_image_infos.dyldImageLoadAddress + notification_offset; 539 } 540 } 541 m_dyld_all_image_infos_stop_id = m_process->GetStopID(); 542 return true; 543 } 544 } 545 return false; 546 } 547 548 bool DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress( 549 lldb::addr_t image_infos_addr, uint32_t image_infos_count) { 550 ImageInfo::collection image_infos; 551 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); 552 if (log) 553 log->Printf("Adding %d modules.\n", image_infos_count); 554 555 std::lock_guard<std::recursive_mutex> guard(m_mutex); 556 std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); 557 if (m_process->GetStopID() == m_dyld_image_infos_stop_id) 558 return true; 559 560 StructuredData::ObjectSP image_infos_json_sp = 561 m_process->GetLoadedDynamicLibrariesInfos(image_infos_addr, 562 image_infos_count); 563 if (image_infos_json_sp.get() && image_infos_json_sp->GetAsDictionary() && 564 image_infos_json_sp->GetAsDictionary()->HasKey("images") && 565 image_infos_json_sp->GetAsDictionary() 566 ->GetValueForKey("images") 567 ->GetAsArray() && 568 image_infos_json_sp->GetAsDictionary() 569 ->GetValueForKey("images") 570 ->GetAsArray() 571 ->GetSize() == image_infos_count) { 572 bool return_value = false; 573 if (JSONImageInformationIntoImageInfo(image_infos_json_sp, image_infos)) { 574 UpdateSpecialBinariesFromNewImageInfos(image_infos); 575 return_value = AddModulesUsingImageInfos(image_infos); 576 } 577 m_dyld_image_infos_stop_id = m_process->GetStopID(); 578 return return_value; 579 } 580 581 if (!ReadImageInfos(image_infos_addr, image_infos_count, image_infos)) 582 return false; 583 584 UpdateImageInfosHeaderAndLoadCommands(image_infos, image_infos_count, false); 585 bool return_value = AddModulesUsingImageInfos(image_infos); 586 m_dyld_image_infos_stop_id = m_process->GetStopID(); 587 return return_value; 588 } 589 590 bool DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress( 591 lldb::addr_t image_infos_addr, uint32_t image_infos_count) { 592 ImageInfo::collection image_infos; 593 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); 594 595 std::lock_guard<std::recursive_mutex> guard(m_mutex); 596 std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); 597 if (m_process->GetStopID() == m_dyld_image_infos_stop_id) 598 return true; 599 600 // First read in the image_infos for the removed modules, and their headers & 601 // load commands. 602 if (!ReadImageInfos(image_infos_addr, image_infos_count, image_infos)) { 603 if (log) 604 log->PutCString("Failed reading image infos array."); 605 return false; 606 } 607 608 if (log) 609 log->Printf("Removing %d modules.", image_infos_count); 610 611 ModuleList unloaded_module_list; 612 for (uint32_t idx = 0; idx < image_infos.size(); ++idx) { 613 if (log) { 614 log->Printf("Removing module at address=0x%16.16" PRIx64 ".", 615 image_infos[idx].address); 616 image_infos[idx].PutToLog(log); 617 } 618 619 // Remove this image_infos from the m_all_image_infos. We do the comparison 620 // by address 621 // rather than by file spec because we can have many modules with the same 622 // "file spec" in the 623 // case that they are modules loaded from memory. 624 // 625 // Also copy over the uuid from the old entry to the removed entry so we can 626 // use it to lookup the module in the module list. 627 628 ImageInfo::collection::iterator pos, end = m_dyld_image_infos.end(); 629 for (pos = m_dyld_image_infos.begin(); pos != end; pos++) { 630 if (image_infos[idx].address == (*pos).address) { 631 image_infos[idx].uuid = (*pos).uuid; 632 633 // Add the module from this image_info to the "unloaded_module_list". 634 // We'll remove them all at 635 // one go later on. 636 637 ModuleSP unload_image_module_sp( 638 FindTargetModuleForImageInfo(image_infos[idx], false, NULL)); 639 if (unload_image_module_sp.get()) { 640 // When we unload, be sure to use the image info from the old list, 641 // since that has sections correctly filled in. 642 UnloadModuleSections(unload_image_module_sp.get(), *pos); 643 unloaded_module_list.AppendIfNeeded(unload_image_module_sp); 644 } else { 645 if (log) { 646 log->Printf("Could not find module for unloading info entry:"); 647 image_infos[idx].PutToLog(log); 648 } 649 } 650 651 // Then remove it from the m_dyld_image_infos: 652 653 m_dyld_image_infos.erase(pos); 654 break; 655 } 656 } 657 658 if (pos == end) { 659 if (log) { 660 log->Printf("Could not find image_info entry for unloading image:"); 661 image_infos[idx].PutToLog(log); 662 } 663 } 664 } 665 if (unloaded_module_list.GetSize() > 0) { 666 if (log) { 667 log->PutCString("Unloaded:"); 668 unloaded_module_list.LogUUIDAndPaths( 669 log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload"); 670 } 671 m_process->GetTarget().GetImages().Remove(unloaded_module_list); 672 } 673 m_dyld_image_infos_stop_id = m_process->GetStopID(); 674 return true; 675 } 676 677 bool DynamicLoaderMacOSXDYLD::ReadImageInfos( 678 lldb::addr_t image_infos_addr, uint32_t image_infos_count, 679 ImageInfo::collection &image_infos) { 680 std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); 681 const ByteOrder endian = GetByteOrderFromMagic(m_dyld.header.magic); 682 const uint32_t addr_size = m_dyld.GetAddressByteSize(); 683 684 image_infos.resize(image_infos_count); 685 const size_t count = image_infos.size() * 3 * addr_size; 686 DataBufferHeap info_data(count, 0); 687 Error error; 688 const size_t bytes_read = m_process->ReadMemory( 689 image_infos_addr, info_data.GetBytes(), info_data.GetByteSize(), error); 690 if (bytes_read == count) { 691 lldb::offset_t info_data_offset = 0; 692 DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), 693 endian, addr_size); 694 for (size_t i = 0; 695 i < image_infos.size() && info_data_ref.ValidOffset(info_data_offset); 696 i++) { 697 image_infos[i].address = info_data_ref.GetPointer(&info_data_offset); 698 lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset); 699 image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset); 700 701 char raw_path[PATH_MAX]; 702 m_process->ReadCStringFromMemory(path_addr, raw_path, sizeof(raw_path), 703 error); 704 // don't resolve the path 705 if (error.Success()) { 706 const bool resolve_path = false; 707 image_infos[i].file_spec.SetFile(raw_path, resolve_path); 708 } 709 } 710 return true; 711 } else { 712 return false; 713 } 714 } 715 716 //---------------------------------------------------------------------- 717 // If we have found where the "_dyld_all_image_infos" lives in memory, 718 // read the current info from it, and then update all image load 719 // addresses (or lack thereof). Only do this if this is the first time 720 // we're reading the dyld infos. Return true if we actually read anything, 721 // and false otherwise. 722 //---------------------------------------------------------------------- 723 bool DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos() { 724 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); 725 726 std::lock_guard<std::recursive_mutex> guard(m_mutex); 727 std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); 728 if (m_process->GetStopID() == m_dyld_image_infos_stop_id || 729 m_dyld_image_infos.size() != 0) 730 return false; 731 732 if (ReadAllImageInfosStructure()) { 733 // Nothing to load or unload? 734 if (m_dyld_all_image_infos.dylib_info_count == 0) 735 return true; 736 737 if (m_dyld_all_image_infos.dylib_info_addr == 0) { 738 // DYLD is updating the images now. So we should say we have no images, 739 // and then we'll 740 // figure it out when we hit the added breakpoint. 741 return false; 742 } else { 743 if (!AddModulesUsingImageInfosAddress( 744 m_dyld_all_image_infos.dylib_info_addr, 745 m_dyld_all_image_infos.dylib_info_count)) { 746 DEBUG_PRINTF("%s", "unable to read all data for all_dylib_infos."); 747 m_dyld_image_infos.clear(); 748 } 749 } 750 751 // Now we have one more bit of business. If there is a library left in the 752 // images for our target that 753 // doesn't have a load address, then it must be something that we were 754 // expecting to load (for instance we 755 // read a load command for it) but it didn't in fact load - probably because 756 // DYLD_*_PATH pointed 757 // to an equivalent version. We don't want it to stay in the target's 758 // module list or it will confuse 759 // us, so unload it here. 760 Target &target = m_process->GetTarget(); 761 const ModuleList &target_modules = target.GetImages(); 762 ModuleList not_loaded_modules; 763 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex()); 764 765 size_t num_modules = target_modules.GetSize(); 766 for (size_t i = 0; i < num_modules; i++) { 767 ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked(i); 768 if (!module_sp->IsLoadedInTarget(&target)) { 769 if (log) { 770 StreamString s; 771 module_sp->GetDescription(&s); 772 log->Printf("Unloading pre-run module: %s.", s.GetData()); 773 } 774 not_loaded_modules.Append(module_sp); 775 } 776 } 777 778 if (not_loaded_modules.GetSize() != 0) { 779 target.GetImages().Remove(not_loaded_modules); 780 } 781 782 return true; 783 } else 784 return false; 785 } 786 787 //---------------------------------------------------------------------- 788 // Read a mach_header at ADDR into HEADER, and also fill in the load 789 // command data into LOAD_COMMAND_DATA if it is non-NULL. 790 // 791 // Returns true if we succeed, false if we fail for any reason. 792 //---------------------------------------------------------------------- 793 bool DynamicLoaderMacOSXDYLD::ReadMachHeader(lldb::addr_t addr, 794 llvm::MachO::mach_header *header, 795 DataExtractor *load_command_data) { 796 DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0); 797 Error error; 798 size_t bytes_read = m_process->ReadMemory(addr, header_bytes.GetBytes(), 799 header_bytes.GetByteSize(), error); 800 if (bytes_read == sizeof(llvm::MachO::mach_header)) { 801 lldb::offset_t offset = 0; 802 ::memset(header, 0, sizeof(llvm::MachO::mach_header)); 803 804 // Get the magic byte unswapped so we can figure out what we are dealing 805 // with 806 DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), 807 endian::InlHostByteOrder(), 4); 808 header->magic = data.GetU32(&offset); 809 lldb::addr_t load_cmd_addr = addr; 810 data.SetByteOrder( 811 DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header->magic)); 812 switch (header->magic) { 813 case llvm::MachO::MH_MAGIC: 814 case llvm::MachO::MH_CIGAM: 815 data.SetAddressByteSize(4); 816 load_cmd_addr += sizeof(llvm::MachO::mach_header); 817 break; 818 819 case llvm::MachO::MH_MAGIC_64: 820 case llvm::MachO::MH_CIGAM_64: 821 data.SetAddressByteSize(8); 822 load_cmd_addr += sizeof(llvm::MachO::mach_header_64); 823 break; 824 825 default: 826 return false; 827 } 828 829 // Read the rest of dyld's mach header 830 if (data.GetU32(&offset, &header->cputype, 831 (sizeof(llvm::MachO::mach_header) / sizeof(uint32_t)) - 832 1)) { 833 if (load_command_data == NULL) 834 return true; // We were able to read the mach_header and weren't asked 835 // to read the load command bytes 836 837 DataBufferSP load_cmd_data_sp(new DataBufferHeap(header->sizeofcmds, 0)); 838 839 size_t load_cmd_bytes_read = 840 m_process->ReadMemory(load_cmd_addr, load_cmd_data_sp->GetBytes(), 841 load_cmd_data_sp->GetByteSize(), error); 842 843 if (load_cmd_bytes_read == header->sizeofcmds) { 844 // Set the load command data and also set the correct endian 845 // swap settings and the correct address size 846 load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds); 847 load_command_data->SetByteOrder(data.GetByteOrder()); 848 load_command_data->SetAddressByteSize(data.GetAddressByteSize()); 849 return true; // We successfully read the mach_header and the load 850 // command data 851 } 852 853 return false; // We weren't able to read the load command data 854 } 855 } 856 return false; // We failed the read the mach_header 857 } 858 859 //---------------------------------------------------------------------- 860 // Parse the load commands for an image 861 //---------------------------------------------------------------------- 862 uint32_t DynamicLoaderMacOSXDYLD::ParseLoadCommands(const DataExtractor &data, 863 ImageInfo &dylib_info, 864 FileSpec *lc_id_dylinker) { 865 lldb::offset_t offset = 0; 866 uint32_t cmd_idx; 867 Segment segment; 868 dylib_info.Clear(true); 869 870 for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++) { 871 // Clear out any load command specific data from DYLIB_INFO since 872 // we are about to read it. 873 874 if (data.ValidOffsetForDataOfSize(offset, 875 sizeof(llvm::MachO::load_command))) { 876 llvm::MachO::load_command load_cmd; 877 lldb::offset_t load_cmd_offset = offset; 878 load_cmd.cmd = data.GetU32(&offset); 879 load_cmd.cmdsize = data.GetU32(&offset); 880 switch (load_cmd.cmd) { 881 case llvm::MachO::LC_SEGMENT: { 882 segment.name.SetTrimmedCStringWithLength( 883 (const char *)data.GetData(&offset, 16), 16); 884 // We are putting 4 uint32_t values 4 uint64_t values so 885 // we have to use multiple 32 bit gets below. 886 segment.vmaddr = data.GetU32(&offset); 887 segment.vmsize = data.GetU32(&offset); 888 segment.fileoff = data.GetU32(&offset); 889 segment.filesize = data.GetU32(&offset); 890 // Extract maxprot, initprot, nsects and flags all at once 891 data.GetU32(&offset, &segment.maxprot, 4); 892 dylib_info.segments.push_back(segment); 893 } break; 894 895 case llvm::MachO::LC_SEGMENT_64: { 896 segment.name.SetTrimmedCStringWithLength( 897 (const char *)data.GetData(&offset, 16), 16); 898 // Extract vmaddr, vmsize, fileoff, and filesize all at once 899 data.GetU64(&offset, &segment.vmaddr, 4); 900 // Extract maxprot, initprot, nsects and flags all at once 901 data.GetU32(&offset, &segment.maxprot, 4); 902 dylib_info.segments.push_back(segment); 903 } break; 904 905 case llvm::MachO::LC_ID_DYLINKER: 906 if (lc_id_dylinker) { 907 const lldb::offset_t name_offset = 908 load_cmd_offset + data.GetU32(&offset); 909 const char *path = data.PeekCStr(name_offset); 910 lc_id_dylinker->SetFile(path, true); 911 } 912 break; 913 914 case llvm::MachO::LC_UUID: 915 dylib_info.uuid.SetBytes(data.GetData(&offset, 16)); 916 break; 917 918 default: 919 break; 920 } 921 // Set offset to be the beginning of the next load command. 922 offset = load_cmd_offset + load_cmd.cmdsize; 923 } 924 } 925 926 // All sections listed in the dyld image info structure will all 927 // either be fixed up already, or they will all be off by a single 928 // slide amount that is determined by finding the first segment 929 // that is at file offset zero which also has bytes (a file size 930 // that is greater than zero) in the object file. 931 932 // Determine the slide amount (if any) 933 const size_t num_sections = dylib_info.segments.size(); 934 for (size_t i = 0; i < num_sections; ++i) { 935 // Iterate through the object file sections to find the 936 // first section that starts of file offset zero and that 937 // has bytes in the file... 938 if ((dylib_info.segments[i].fileoff == 0 && 939 dylib_info.segments[i].filesize > 0) || 940 (dylib_info.segments[i].name == ConstString("__TEXT"))) { 941 dylib_info.slide = dylib_info.address - dylib_info.segments[i].vmaddr; 942 // We have found the slide amount, so we can exit 943 // this for loop. 944 break; 945 } 946 } 947 return cmd_idx; 948 } 949 950 //---------------------------------------------------------------------- 951 // Read the mach_header and load commands for each image that the 952 // _dyld_all_image_infos structure points to and cache the results. 953 //---------------------------------------------------------------------- 954 955 void DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands( 956 ImageInfo::collection &image_infos, uint32_t infos_count, 957 bool update_executable) { 958 uint32_t exe_idx = UINT32_MAX; 959 // Read any UUID values that we can get 960 for (uint32_t i = 0; i < infos_count; i++) { 961 if (!image_infos[i].UUIDValid()) { 962 DataExtractor data; // Load command data 963 if (!ReadMachHeader(image_infos[i].address, &image_infos[i].header, 964 &data)) 965 continue; 966 967 ParseLoadCommands(data, image_infos[i], NULL); 968 969 if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE) 970 exe_idx = i; 971 } 972 } 973 974 Target &target = m_process->GetTarget(); 975 976 if (exe_idx < image_infos.size()) { 977 const bool can_create = true; 978 ModuleSP exe_module_sp( 979 FindTargetModuleForImageInfo(image_infos[exe_idx], can_create, NULL)); 980 981 if (exe_module_sp) { 982 UpdateImageLoadAddress(exe_module_sp.get(), image_infos[exe_idx]); 983 984 if (exe_module_sp.get() != target.GetExecutableModulePointer()) { 985 // Don't load dependent images since we are in dyld where we will know 986 // and find out about all images that are loaded. Also when setting the 987 // executable module, it will clear the targets module list, and if we 988 // have an in memory dyld module, it will get removed from the list 989 // so we will need to add it back after setting the executable module, 990 // so we first try and see if we already have a weak pointer to the 991 // dyld module, make it into a shared pointer, then add the executable, 992 // then re-add it back to make sure it is always in the list. 993 ModuleSP dyld_module_sp(GetDYLDModule()); 994 995 const bool get_dependent_images = false; 996 m_process->GetTarget().SetExecutableModule(exe_module_sp, 997 get_dependent_images); 998 999 if (dyld_module_sp) { 1000 if (target.GetImages().AppendIfNeeded(dyld_module_sp)) { 1001 std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); 1002 1003 // Also add it to the section list. 1004 UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld); 1005 } 1006 } 1007 } 1008 } 1009 } 1010 } 1011 1012 //---------------------------------------------------------------------- 1013 // Dump the _dyld_all_image_infos members and all current image infos 1014 // that we have parsed to the file handle provided. 1015 //---------------------------------------------------------------------- 1016 void DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const { 1017 if (log == NULL) 1018 return; 1019 1020 std::lock_guard<std::recursive_mutex> guard(m_mutex); 1021 std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); 1022 log->Printf( 1023 "dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8" PRIx64 1024 ", notify=0x%8.8" PRIx64 " }", 1025 m_dyld_all_image_infos.version, m_dyld_all_image_infos.dylib_info_count, 1026 (uint64_t)m_dyld_all_image_infos.dylib_info_addr, 1027 (uint64_t)m_dyld_all_image_infos.notification); 1028 size_t i; 1029 const size_t count = m_dyld_image_infos.size(); 1030 if (count > 0) { 1031 log->PutCString("Loaded:"); 1032 for (i = 0; i < count; i++) 1033 m_dyld_image_infos[i].PutToLog(log); 1034 } 1035 } 1036 1037 bool DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint() { 1038 DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", 1039 __FUNCTION__, StateAsCString(m_process->GetState())); 1040 if (m_break_id == LLDB_INVALID_BREAK_ID) { 1041 if (m_dyld_all_image_infos.notification != LLDB_INVALID_ADDRESS) { 1042 Address so_addr; 1043 // Set the notification breakpoint and install a breakpoint 1044 // callback function that will get called each time the 1045 // breakpoint gets hit. We will use this to track when shared 1046 // libraries get loaded/unloaded. 1047 bool resolved = m_process->GetTarget().ResolveLoadAddress( 1048 m_dyld_all_image_infos.notification, so_addr); 1049 if (!resolved) { 1050 ModuleSP dyld_module_sp = GetDYLDModule(); 1051 if (dyld_module_sp) { 1052 std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); 1053 1054 UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld); 1055 resolved = m_process->GetTarget().ResolveLoadAddress( 1056 m_dyld_all_image_infos.notification, so_addr); 1057 } 1058 } 1059 1060 if (resolved) { 1061 Breakpoint *dyld_break = 1062 m_process->GetTarget().CreateBreakpoint(so_addr, true, false).get(); 1063 dyld_break->SetCallback(DynamicLoaderMacOSXDYLD::NotifyBreakpointHit, 1064 this, true); 1065 dyld_break->SetBreakpointKind("shared-library-event"); 1066 m_break_id = dyld_break->GetID(); 1067 } 1068 } 1069 } 1070 return m_break_id != LLDB_INVALID_BREAK_ID; 1071 } 1072 1073 Error DynamicLoaderMacOSXDYLD::CanLoadImage() { 1074 Error error; 1075 // In order for us to tell if we can load a shared library we verify that 1076 // the dylib_info_addr isn't zero (which means no shared libraries have 1077 // been set yet, or dyld is currently mucking with the shared library list). 1078 if (ReadAllImageInfosStructure()) { 1079 // TODO: also check the _dyld_global_lock_held variable in 1080 // libSystem.B.dylib? 1081 // TODO: check the malloc lock? 1082 // TODO: check the objective C lock? 1083 if (m_dyld_all_image_infos.dylib_info_addr != 0) 1084 return error; // Success 1085 } 1086 1087 error.SetErrorString("unsafe to load or unload shared libraries"); 1088 return error; 1089 } 1090 1091 bool DynamicLoaderMacOSXDYLD::GetSharedCacheInformation( 1092 lldb::addr_t &base_address, UUID &uuid, LazyBool &using_shared_cache, 1093 LazyBool &private_shared_cache) { 1094 base_address = LLDB_INVALID_ADDRESS; 1095 uuid.Clear(); 1096 using_shared_cache = eLazyBoolCalculate; 1097 private_shared_cache = eLazyBoolCalculate; 1098 1099 if (m_process) { 1100 addr_t all_image_infos = m_process->GetImageInfoAddress(); 1101 1102 // The address returned by GetImageInfoAddress may be the address of dyld 1103 // (don't want) 1104 // or it may be the address of the dyld_all_image_infos structure (want). 1105 // The first four 1106 // bytes will be either the version field (all_image_infos) or a Mach-O file 1107 // magic constant. 1108 // Version 13 and higher of dyld_all_image_infos is required to get the 1109 // sharedCacheUUID field. 1110 1111 Error err; 1112 uint32_t version_or_magic = 1113 m_process->ReadUnsignedIntegerFromMemory(all_image_infos, 4, -1, err); 1114 if (version_or_magic != static_cast<uint32_t>(-1) && 1115 version_or_magic != llvm::MachO::MH_MAGIC && 1116 version_or_magic != llvm::MachO::MH_CIGAM && 1117 version_or_magic != llvm::MachO::MH_MAGIC_64 && 1118 version_or_magic != llvm::MachO::MH_CIGAM_64 && 1119 version_or_magic >= 13) { 1120 addr_t sharedCacheUUID_address = LLDB_INVALID_ADDRESS; 1121 int wordsize = m_process->GetAddressByteSize(); 1122 if (wordsize == 8) { 1123 sharedCacheUUID_address = 1124 all_image_infos + 160; // sharedCacheUUID <mach-o/dyld_images.h> 1125 } 1126 if (wordsize == 4) { 1127 sharedCacheUUID_address = 1128 all_image_infos + 84; // sharedCacheUUID <mach-o/dyld_images.h> 1129 } 1130 if (sharedCacheUUID_address != LLDB_INVALID_ADDRESS) { 1131 uuid_t shared_cache_uuid; 1132 if (m_process->ReadMemory(sharedCacheUUID_address, shared_cache_uuid, 1133 sizeof(uuid_t), err) == sizeof(uuid_t)) { 1134 uuid.SetBytes(shared_cache_uuid); 1135 if (uuid.IsValid()) { 1136 using_shared_cache = eLazyBoolYes; 1137 } 1138 } 1139 1140 if (version_or_magic >= 15) { 1141 // The sharedCacheBaseAddress field is the next one in the 1142 // dyld_all_image_infos struct. 1143 addr_t sharedCacheBaseAddr_address = sharedCacheUUID_address + 16; 1144 Error error; 1145 base_address = m_process->ReadUnsignedIntegerFromMemory( 1146 sharedCacheBaseAddr_address, wordsize, LLDB_INVALID_ADDRESS, 1147 error); 1148 if (error.Fail()) 1149 base_address = LLDB_INVALID_ADDRESS; 1150 } 1151 1152 return true; 1153 } 1154 1155 // 1156 // add 1157 // NB: sharedCacheBaseAddress is the next field in dyld_all_image_infos 1158 // after 1159 // sharedCacheUUID -- that is, 16 bytes after it, if we wanted to fetch 1160 // it. 1161 } 1162 } 1163 return false; 1164 } 1165 1166 void DynamicLoaderMacOSXDYLD::Initialize() { 1167 PluginManager::RegisterPlugin(GetPluginNameStatic(), 1168 GetPluginDescriptionStatic(), CreateInstance); 1169 } 1170 1171 void DynamicLoaderMacOSXDYLD::Terminate() { 1172 PluginManager::UnregisterPlugin(CreateInstance); 1173 } 1174 1175 lldb_private::ConstString DynamicLoaderMacOSXDYLD::GetPluginNameStatic() { 1176 static ConstString g_name("macosx-dyld"); 1177 return g_name; 1178 } 1179 1180 const char *DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic() { 1181 return "Dynamic loader plug-in that watches for shared library loads/unloads " 1182 "in MacOSX user processes."; 1183 } 1184 1185 //------------------------------------------------------------------ 1186 // PluginInterface protocol 1187 //------------------------------------------------------------------ 1188 lldb_private::ConstString DynamicLoaderMacOSXDYLD::GetPluginName() { 1189 return GetPluginNameStatic(); 1190 } 1191 1192 uint32_t DynamicLoaderMacOSXDYLD::GetPluginVersion() { return 1; } 1193 1194 uint32_t DynamicLoaderMacOSXDYLD::AddrByteSize() { 1195 std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); 1196 1197 switch (m_dyld.header.magic) { 1198 case llvm::MachO::MH_MAGIC: 1199 case llvm::MachO::MH_CIGAM: 1200 return 4; 1201 1202 case llvm::MachO::MH_MAGIC_64: 1203 case llvm::MachO::MH_CIGAM_64: 1204 return 8; 1205 1206 default: 1207 break; 1208 } 1209 return 0; 1210 } 1211 1212 lldb::ByteOrder DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(uint32_t magic) { 1213 switch (magic) { 1214 case llvm::MachO::MH_MAGIC: 1215 case llvm::MachO::MH_MAGIC_64: 1216 return endian::InlHostByteOrder(); 1217 1218 case llvm::MachO::MH_CIGAM: 1219 case llvm::MachO::MH_CIGAM_64: 1220 if (endian::InlHostByteOrder() == lldb::eByteOrderBig) 1221 return lldb::eByteOrderLittle; 1222 else 1223 return lldb::eByteOrderBig; 1224 1225 default: 1226 break; 1227 } 1228 return lldb::eByteOrderInvalid; 1229 } 1230