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