1 //===-- DynamicLoaderDarwin.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/Expression/DiagnosticManager.h" 21 #include "lldb/Symbol/ClangASTContext.h" 22 #include "lldb/Symbol/Function.h" 23 #include "lldb/Symbol/ObjectFile.h" 24 #include "lldb/Target/ABI.h" 25 #include "lldb/Target/ObjCLanguageRuntime.h" 26 #include "lldb/Target/RegisterContext.h" 27 #include "lldb/Target/StackFrame.h" 28 #include "lldb/Target/Target.h" 29 #include "lldb/Target/Thread.h" 30 #include "lldb/Target/ThreadPlanCallFunction.h" 31 #include "lldb/Target/ThreadPlanRunToAddress.h" 32 33 #include "DynamicLoaderDarwin.h" 34 35 //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN 36 #ifdef ENABLE_DEBUG_PRINTF 37 #include <stdio.h> 38 #define DEBUG_PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__) 39 #else 40 #define DEBUG_PRINTF(fmt, ...) 41 #endif 42 43 #ifndef __APPLE__ 44 #include "Utility/UuidCompatibility.h" 45 #else 46 #include <uuid/uuid.h> 47 #endif 48 49 using namespace lldb; 50 using namespace lldb_private; 51 52 //---------------------------------------------------------------------- 53 // Constructor 54 //---------------------------------------------------------------------- 55 DynamicLoaderDarwin::DynamicLoaderDarwin(Process *process) 56 : DynamicLoader(process), m_dyld_module_wp(), m_libpthread_module_wp(), 57 m_pthread_getspecific_addr(), m_tid_to_tls_map(), m_dyld_image_infos(), 58 m_dyld_image_infos_stop_id(UINT32_MAX), m_dyld(), m_mutex() {} 59 60 //---------------------------------------------------------------------- 61 // Destructor 62 //---------------------------------------------------------------------- 63 DynamicLoaderDarwin::~DynamicLoaderDarwin() {} 64 65 //------------------------------------------------------------------ 66 /// Called after attaching a process. 67 /// 68 /// Allow DynamicLoader plug-ins to execute some code after 69 /// attaching to a process. 70 //------------------------------------------------------------------ 71 void DynamicLoaderDarwin::DidAttach() { 72 PrivateInitialize(m_process); 73 DoInitialImageFetch(); 74 SetNotificationBreakpoint(); 75 } 76 77 //------------------------------------------------------------------ 78 /// Called after attaching a process. 79 /// 80 /// Allow DynamicLoader plug-ins to execute some code after 81 /// attaching to a process. 82 //------------------------------------------------------------------ 83 void DynamicLoaderDarwin::DidLaunch() { 84 PrivateInitialize(m_process); 85 DoInitialImageFetch(); 86 SetNotificationBreakpoint(); 87 } 88 89 //---------------------------------------------------------------------- 90 // Clear out the state of this class. 91 //---------------------------------------------------------------------- 92 void DynamicLoaderDarwin::Clear(bool clear_process) { 93 std::lock_guard<std::recursive_mutex> guard(m_mutex); 94 if (clear_process) 95 m_process = NULL; 96 m_dyld_image_infos.clear(); 97 m_dyld_image_infos_stop_id = UINT32_MAX; 98 m_dyld.Clear(false); 99 } 100 101 ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo( 102 ImageInfo &image_info, bool can_create, bool *did_create_ptr) { 103 if (did_create_ptr) 104 *did_create_ptr = false; 105 106 Target &target = m_process->GetTarget(); 107 const ModuleList &target_images = target.GetImages(); 108 ModuleSpec module_spec(image_info.file_spec); 109 module_spec.GetUUID() = image_info.uuid; 110 ModuleSP module_sp(target_images.FindFirstModule(module_spec)); 111 112 if (module_sp && !module_spec.GetUUID().IsValid() && 113 !module_sp->GetUUID().IsValid()) { 114 // No UUID, we must rely upon the cached module modification 115 // time and the modification time of the file on disk 116 if (module_sp->GetModificationTime() != 117 module_sp->GetFileSpec().GetModificationTime()) 118 module_sp.reset(); 119 } 120 121 if (!module_sp) { 122 if (can_create) { 123 module_sp = target.GetSharedModule(module_spec); 124 if (!module_sp || module_sp->GetObjectFile() == NULL) 125 module_sp = m_process->ReadModuleFromMemory(image_info.file_spec, 126 image_info.address); 127 128 if (did_create_ptr) 129 *did_create_ptr = (bool)module_sp; 130 } 131 } 132 return module_sp; 133 } 134 135 void DynamicLoaderDarwin::UnloadImages( 136 const std::vector<lldb::addr_t> &solib_addresses) { 137 std::lock_guard<std::recursive_mutex> guard(m_mutex); 138 if (m_process->GetStopID() == m_dyld_image_infos_stop_id) 139 return; 140 141 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); 142 Target &target = m_process->GetTarget(); 143 if (log) 144 log->Printf("Removing %" PRId64 " modules.", 145 (uint64_t)solib_addresses.size()); 146 147 ModuleList unloaded_module_list; 148 149 for (addr_t solib_addr : solib_addresses) { 150 Address header; 151 if (header.SetLoadAddress(solib_addr, &target)) { 152 if (header.GetOffset() == 0) { 153 ModuleSP module_to_remove(header.GetModule()); 154 if (module_to_remove.get()) { 155 if (log) 156 log->Printf("Removing module at address 0x%" PRIx64, solib_addr); 157 // remove the sections from the Target 158 UnloadSections(module_to_remove); 159 // add this to the list of modules to remove 160 unloaded_module_list.AppendIfNeeded(module_to_remove); 161 // remove the entry from the m_dyld_image_infos 162 ImageInfo::collection::iterator pos, end = m_dyld_image_infos.end(); 163 for (pos = m_dyld_image_infos.begin(); pos != end; pos++) { 164 if (solib_addr == (*pos).address) { 165 m_dyld_image_infos.erase(pos); 166 break; 167 } 168 } 169 } 170 } 171 } 172 } 173 174 if (unloaded_module_list.GetSize() > 0) { 175 if (log) { 176 log->PutCString("Unloaded:"); 177 unloaded_module_list.LogUUIDAndPaths( 178 log, "DynamicLoaderDarwin::UnloadModules"); 179 } 180 m_process->GetTarget().GetImages().Remove(unloaded_module_list); 181 m_dyld_image_infos_stop_id = m_process->GetStopID(); 182 } 183 } 184 185 void DynamicLoaderDarwin::UnloadAllImages() { 186 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); 187 ModuleList unloaded_modules_list; 188 189 Target &target = m_process->GetTarget(); 190 const ModuleList &target_modules = target.GetImages(); 191 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex()); 192 193 size_t num_modules = target_modules.GetSize(); 194 ModuleSP dyld_sp(GetDYLDModule()); 195 196 for (size_t i = 0; i < num_modules; i++) { 197 ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked(i); 198 199 // Don't remove dyld - else we'll lose our breakpoint notifying us about 200 // libraries 201 // being re-loaded... 202 if (module_sp.get() != nullptr && module_sp.get() != dyld_sp.get()) { 203 UnloadSections(module_sp); 204 unloaded_modules_list.Append(module_sp); 205 } 206 } 207 208 if (unloaded_modules_list.GetSize() != 0) { 209 if (log) { 210 log->PutCString("Unloaded:"); 211 unloaded_modules_list.LogUUIDAndPaths( 212 log, "DynamicLoaderDarwin::UnloadAllImages"); 213 } 214 target.GetImages().Remove(unloaded_modules_list); 215 m_dyld_image_infos.clear(); 216 m_dyld_image_infos_stop_id = m_process->GetStopID(); 217 } 218 } 219 220 //---------------------------------------------------------------------- 221 // Update the load addresses for all segments in MODULE using the 222 // updated INFO that is passed in. 223 //---------------------------------------------------------------------- 224 bool DynamicLoaderDarwin::UpdateImageLoadAddress(Module *module, 225 ImageInfo &info) { 226 bool changed = false; 227 if (module) { 228 ObjectFile *image_object_file = module->GetObjectFile(); 229 if (image_object_file) { 230 SectionList *section_list = image_object_file->GetSectionList(); 231 if (section_list) { 232 std::vector<uint32_t> inaccessible_segment_indexes; 233 // We now know the slide amount, so go through all sections 234 // and update the load addresses with the correct values. 235 const size_t num_segments = info.segments.size(); 236 for (size_t i = 0; i < num_segments; ++i) { 237 // Only load a segment if it has protections. Things like 238 // __PAGEZERO don't have any protections, and they shouldn't 239 // be slid 240 SectionSP section_sp( 241 section_list->FindSectionByName(info.segments[i].name)); 242 243 if (info.segments[i].maxprot == 0) { 244 inaccessible_segment_indexes.push_back(i); 245 } else { 246 const addr_t new_section_load_addr = 247 info.segments[i].vmaddr + info.slide; 248 static ConstString g_section_name_LINKEDIT("__LINKEDIT"); 249 250 if (section_sp) { 251 // __LINKEDIT sections from files in the shared cache 252 // can overlap so check to see what the segment name is 253 // and pass "false" so we don't warn of overlapping 254 // "Section" objects, and "true" for all other sections. 255 const bool warn_multiple = 256 section_sp->GetName() != g_section_name_LINKEDIT; 257 258 changed = m_process->GetTarget().SetSectionLoadAddress( 259 section_sp, new_section_load_addr, warn_multiple); 260 } else { 261 Host::SystemLog( 262 Host::eSystemLogWarning, 263 "warning: unable to find and load segment named '%s' at " 264 "0x%" PRIx64 " in '%s' in macosx dynamic loader plug-in.\n", 265 info.segments[i].name.AsCString("<invalid>"), 266 (uint64_t)new_section_load_addr, 267 image_object_file->GetFileSpec().GetPath().c_str()); 268 } 269 } 270 } 271 272 // If the loaded the file (it changed) and we have segments that 273 // are not readable or writeable, add them to the invalid memory 274 // region cache for the process. This will typically only be 275 // the __PAGEZERO segment in the main executable. We might be able 276 // to apply this more generally to more sections that have no 277 // protections in the future, but for now we are going to just 278 // do __PAGEZERO. 279 if (changed && !inaccessible_segment_indexes.empty()) { 280 for (uint32_t i = 0; i < inaccessible_segment_indexes.size(); ++i) { 281 const uint32_t seg_idx = inaccessible_segment_indexes[i]; 282 SectionSP section_sp( 283 section_list->FindSectionByName(info.segments[seg_idx].name)); 284 285 if (section_sp) { 286 static ConstString g_pagezero_section_name("__PAGEZERO"); 287 if (g_pagezero_section_name == section_sp->GetName()) { 288 // __PAGEZERO never slides... 289 const lldb::addr_t vmaddr = info.segments[seg_idx].vmaddr; 290 const lldb::addr_t vmsize = info.segments[seg_idx].vmsize; 291 Process::LoadRange pagezero_range(vmaddr, vmsize); 292 m_process->AddInvalidMemoryRegion(pagezero_range); 293 } 294 } 295 } 296 } 297 } 298 } 299 } 300 // We might have an in memory image that was loaded as soon as it was created 301 if (info.load_stop_id == m_process->GetStopID()) 302 changed = true; 303 else if (changed) { 304 // Update the stop ID when this library was updated 305 info.load_stop_id = m_process->GetStopID(); 306 } 307 return changed; 308 } 309 310 //---------------------------------------------------------------------- 311 // Unload the segments in MODULE using the INFO that is passed in. 312 //---------------------------------------------------------------------- 313 bool DynamicLoaderDarwin::UnloadModuleSections(Module *module, 314 ImageInfo &info) { 315 bool changed = false; 316 if (module) { 317 ObjectFile *image_object_file = module->GetObjectFile(); 318 if (image_object_file) { 319 SectionList *section_list = image_object_file->GetSectionList(); 320 if (section_list) { 321 const size_t num_segments = info.segments.size(); 322 for (size_t i = 0; i < num_segments; ++i) { 323 SectionSP section_sp( 324 section_list->FindSectionByName(info.segments[i].name)); 325 if (section_sp) { 326 const addr_t old_section_load_addr = 327 info.segments[i].vmaddr + info.slide; 328 if (m_process->GetTarget().SetSectionUnloaded( 329 section_sp, old_section_load_addr)) 330 changed = true; 331 } else { 332 Host::SystemLog(Host::eSystemLogWarning, 333 "warning: unable to find and unload segment named " 334 "'%s' in '%s' in macosx dynamic loader plug-in.\n", 335 info.segments[i].name.AsCString("<invalid>"), 336 image_object_file->GetFileSpec().GetPath().c_str()); 337 } 338 } 339 } 340 } 341 } 342 return changed; 343 } 344 345 // Given a JSON dictionary (from debugserver, most likely) of binary images 346 // loaded in the inferior 347 // process, add the images to the ImageInfo collection. 348 349 bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo( 350 StructuredData::ObjectSP image_details, 351 ImageInfo::collection &image_infos) { 352 StructuredData::ObjectSP images_sp = 353 image_details->GetAsDictionary()->GetValueForKey("images"); 354 if (images_sp.get() == nullptr) 355 return false; 356 357 image_infos.resize(images_sp->GetAsArray()->GetSize()); 358 359 for (size_t i = 0; i < image_infos.size(); i++) { 360 StructuredData::ObjectSP image_sp = 361 images_sp->GetAsArray()->GetItemAtIndex(i); 362 if (image_sp.get() == nullptr || image_sp->GetAsDictionary() == nullptr) 363 return false; 364 StructuredData::Dictionary *image = image_sp->GetAsDictionary(); 365 if (image->HasKey("load_address") == false || 366 image->HasKey("pathname") == false || 367 image->HasKey("mod_date") == false || 368 image->HasKey("mach_header") == false || 369 image->GetValueForKey("mach_header")->GetAsDictionary() == nullptr || 370 image->HasKey("segments") == false || 371 image->GetValueForKey("segments")->GetAsArray() == nullptr || 372 image->HasKey("uuid") == false) { 373 return false; 374 } 375 image_infos[i].address = 376 image->GetValueForKey("load_address")->GetAsInteger()->GetValue(); 377 image_infos[i].mod_date = 378 image->GetValueForKey("mod_date")->GetAsInteger()->GetValue(); 379 image_infos[i].file_spec.SetFile( 380 image->GetValueForKey("pathname")->GetAsString()->GetValue().c_str(), 381 false); 382 383 StructuredData::Dictionary *mh = 384 image->GetValueForKey("mach_header")->GetAsDictionary(); 385 image_infos[i].header.magic = 386 mh->GetValueForKey("magic")->GetAsInteger()->GetValue(); 387 image_infos[i].header.cputype = 388 mh->GetValueForKey("cputype")->GetAsInteger()->GetValue(); 389 image_infos[i].header.cpusubtype = 390 mh->GetValueForKey("cpusubtype")->GetAsInteger()->GetValue(); 391 image_infos[i].header.filetype = 392 mh->GetValueForKey("filetype")->GetAsInteger()->GetValue(); 393 394 if (image->HasKey("min_version_os_name")) { 395 std::string os_name = image->GetValueForKey("min_version_os_name") 396 ->GetAsString() 397 ->GetValue(); 398 if (os_name == "macosx") 399 image_infos[i].os_type = llvm::Triple::MacOSX; 400 else if (os_name == "ios" || os_name == "iphoneos") 401 image_infos[i].os_type = llvm::Triple::IOS; 402 else if (os_name == "tvos") 403 image_infos[i].os_type = llvm::Triple::TvOS; 404 else if (os_name == "watchos") 405 image_infos[i].os_type = llvm::Triple::WatchOS; 406 } 407 if (image->HasKey("min_version_os_sdk")) { 408 image_infos[i].min_version_os_sdk = 409 image->GetValueForKey("min_version_os_sdk") 410 ->GetAsString() 411 ->GetValue(); 412 } 413 414 // Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't 415 // currently send them 416 // in the reply. 417 418 if (mh->HasKey("flags")) 419 image_infos[i].header.flags = 420 mh->GetValueForKey("flags")->GetAsInteger()->GetValue(); 421 else 422 image_infos[i].header.flags = 0; 423 424 if (mh->HasKey("ncmds")) 425 image_infos[i].header.ncmds = 426 mh->GetValueForKey("ncmds")->GetAsInteger()->GetValue(); 427 else 428 image_infos[i].header.ncmds = 0; 429 430 if (mh->HasKey("sizeofcmds")) 431 image_infos[i].header.sizeofcmds = 432 mh->GetValueForKey("sizeofcmds")->GetAsInteger()->GetValue(); 433 else 434 image_infos[i].header.sizeofcmds = 0; 435 436 StructuredData::Array *segments = 437 image->GetValueForKey("segments")->GetAsArray(); 438 uint32_t segcount = segments->GetSize(); 439 for (size_t j = 0; j < segcount; j++) { 440 Segment segment; 441 StructuredData::Dictionary *seg = 442 segments->GetItemAtIndex(j)->GetAsDictionary(); 443 segment.name = ConstString( 444 seg->GetValueForKey("name")->GetAsString()->GetValue().c_str()); 445 segment.vmaddr = 446 seg->GetValueForKey("vmaddr")->GetAsInteger()->GetValue(); 447 segment.vmsize = 448 seg->GetValueForKey("vmsize")->GetAsInteger()->GetValue(); 449 segment.fileoff = 450 seg->GetValueForKey("fileoff")->GetAsInteger()->GetValue(); 451 segment.filesize = 452 seg->GetValueForKey("filesize")->GetAsInteger()->GetValue(); 453 segment.maxprot = 454 seg->GetValueForKey("maxprot")->GetAsInteger()->GetValue(); 455 456 // Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't 457 // currently send them 458 // in the reply. 459 460 if (seg->HasKey("initprot")) 461 segment.initprot = 462 seg->GetValueForKey("initprot")->GetAsInteger()->GetValue(); 463 else 464 segment.initprot = 0; 465 466 if (seg->HasKey("flags")) 467 segment.flags = 468 seg->GetValueForKey("flags")->GetAsInteger()->GetValue(); 469 else 470 segment.flags = 0; 471 472 if (seg->HasKey("nsects")) 473 segment.nsects = 474 seg->GetValueForKey("nsects")->GetAsInteger()->GetValue(); 475 else 476 segment.nsects = 0; 477 478 image_infos[i].segments.push_back(segment); 479 } 480 481 image_infos[i].uuid.SetFromCString( 482 image->GetValueForKey("uuid")->GetAsString()->GetValue().c_str()); 483 484 // All sections listed in the dyld image info structure will all 485 // either be fixed up already, or they will all be off by a single 486 // slide amount that is determined by finding the first segment 487 // that is at file offset zero which also has bytes (a file size 488 // that is greater than zero) in the object file. 489 490 // Determine the slide amount (if any) 491 const size_t num_sections = image_infos[i].segments.size(); 492 for (size_t k = 0; k < num_sections; ++k) { 493 // Iterate through the object file sections to find the 494 // first section that starts of file offset zero and that 495 // has bytes in the file... 496 if ((image_infos[i].segments[k].fileoff == 0 && 497 image_infos[i].segments[k].filesize > 0) || 498 (image_infos[i].segments[k].name == ConstString("__TEXT"))) { 499 image_infos[i].slide = 500 image_infos[i].address - image_infos[i].segments[k].vmaddr; 501 // We have found the slide amount, so we can exit 502 // this for loop. 503 break; 504 } 505 } 506 } 507 508 return true; 509 } 510 511 void DynamicLoaderDarwin::UpdateSpecialBinariesFromNewImageInfos( 512 ImageInfo::collection &image_infos) { 513 uint32_t exe_idx = UINT32_MAX; 514 uint32_t dyld_idx = UINT32_MAX; 515 Target &target = m_process->GetTarget(); 516 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); 517 ConstString g_dyld_sim_filename("dyld_sim"); 518 519 ArchSpec target_arch = target.GetArchitecture(); 520 const size_t image_infos_size = image_infos.size(); 521 for (size_t i = 0; i < image_infos_size; i++) { 522 if (image_infos[i].header.filetype == llvm::MachO::MH_DYLINKER) { 523 // In a "simulator" process (an x86 process that is ios/tvos/watchos) 524 // we will have two dyld modules -- a "dyld" that we want to keep track 525 // of, 526 // and a "dyld_sim" which we don't need to keep track of here. 527 // If the target is an x86 system and the OS of the dyld binary is 528 // ios/tvos/watchos, then we are looking at dyld_sym. 529 530 // debugserver has only recently (late 2016) started sending up the 531 // os type for each binary it sees -- so if we don't have an os 532 // type, use a filename check as our next best guess. 533 if (image_infos[i].os_type == llvm::Triple::OSType::UnknownOS) { 534 if (image_infos[i].file_spec.GetFilename() != g_dyld_sim_filename) { 535 dyld_idx = i; 536 } 537 } else if (target_arch.GetTriple().getArch() == llvm::Triple::x86 || 538 target_arch.GetTriple().getArch() == llvm::Triple::x86_64) { 539 if (image_infos[i].os_type != llvm::Triple::OSType::IOS && 540 image_infos[i].os_type != llvm::Triple::TvOS && 541 image_infos[i].os_type != llvm::Triple::WatchOS) { 542 dyld_idx = i; 543 } 544 } 545 } else if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE) { 546 exe_idx = i; 547 } 548 } 549 550 if (exe_idx != UINT32_MAX) { 551 const bool can_create = true; 552 ModuleSP exe_module_sp( 553 FindTargetModuleForImageInfo(image_infos[exe_idx], can_create, NULL)); 554 if (exe_module_sp) { 555 if (log) 556 log->Printf("Found executable module: %s", 557 exe_module_sp->GetFileSpec().GetPath().c_str()); 558 target.GetImages().AppendIfNeeded(exe_module_sp); 559 UpdateImageLoadAddress(exe_module_sp.get(), image_infos[exe_idx]); 560 if (exe_module_sp.get() != target.GetExecutableModulePointer()) { 561 const bool get_dependent_images = false; 562 target.SetExecutableModule(exe_module_sp, get_dependent_images); 563 } 564 } 565 } 566 567 if (dyld_idx != UINT32_MAX) { 568 const bool can_create = true; 569 ModuleSP dyld_sp = 570 FindTargetModuleForImageInfo(image_infos[dyld_idx], can_create, NULL); 571 if (dyld_sp.get()) { 572 if (log) 573 log->Printf("Found dyld module: %s", 574 dyld_sp->GetFileSpec().GetPath().c_str()); 575 target.GetImages().AppendIfNeeded(dyld_sp); 576 UpdateImageLoadAddress(dyld_sp.get(), image_infos[dyld_idx]); 577 SetDYLDModule(dyld_sp); 578 } 579 } 580 } 581 582 void DynamicLoaderDarwin::UpdateDYLDImageInfoFromNewImageInfo( 583 ImageInfo &image_info) { 584 if (image_info.header.filetype == llvm::MachO::MH_DYLINKER) { 585 const bool can_create = true; 586 ModuleSP dyld_sp = 587 FindTargetModuleForImageInfo(image_info, can_create, NULL); 588 if (dyld_sp.get()) { 589 Target &target = m_process->GetTarget(); 590 target.GetImages().AppendIfNeeded(dyld_sp); 591 UpdateImageLoadAddress(dyld_sp.get(), image_info); 592 SetDYLDModule(dyld_sp); 593 } 594 } 595 } 596 597 void DynamicLoaderDarwin::SetDYLDModule(lldb::ModuleSP &dyld_module_sp) { 598 m_dyld_module_wp = dyld_module_sp; 599 } 600 601 ModuleSP DynamicLoaderDarwin::GetDYLDModule() { 602 ModuleSP dyld_sp(m_dyld_module_wp.lock()); 603 return dyld_sp; 604 } 605 606 bool DynamicLoaderDarwin::AddModulesUsingImageInfos( 607 ImageInfo::collection &image_infos) { 608 std::lock_guard<std::recursive_mutex> guard(m_mutex); 609 // Now add these images to the main list. 610 ModuleList loaded_module_list; 611 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); 612 Target &target = m_process->GetTarget(); 613 ModuleList &target_images = target.GetImages(); 614 615 for (uint32_t idx = 0; idx < image_infos.size(); ++idx) { 616 if (log) { 617 log->Printf("Adding new image at address=0x%16.16" PRIx64 ".", 618 image_infos[idx].address); 619 image_infos[idx].PutToLog(log); 620 } 621 622 m_dyld_image_infos.push_back(image_infos[idx]); 623 624 ModuleSP image_module_sp( 625 FindTargetModuleForImageInfo(image_infos[idx], true, NULL)); 626 627 if (image_module_sp) { 628 ObjectFile *objfile = image_module_sp->GetObjectFile(); 629 if (objfile) { 630 SectionList *sections = objfile->GetSectionList(); 631 if (sections) { 632 ConstString commpage_dbstr("__commpage"); 633 Section *commpage_section = 634 sections->FindSectionByName(commpage_dbstr).get(); 635 if (commpage_section) { 636 ModuleSpec module_spec(objfile->GetFileSpec(), 637 image_infos[idx].GetArchitecture()); 638 module_spec.GetObjectName() = commpage_dbstr; 639 ModuleSP commpage_image_module_sp( 640 target_images.FindFirstModule(module_spec)); 641 if (!commpage_image_module_sp) { 642 module_spec.SetObjectOffset(objfile->GetFileOffset() + 643 commpage_section->GetFileOffset()); 644 module_spec.SetObjectSize(objfile->GetByteSize()); 645 commpage_image_module_sp = target.GetSharedModule(module_spec); 646 if (!commpage_image_module_sp || 647 commpage_image_module_sp->GetObjectFile() == NULL) { 648 commpage_image_module_sp = m_process->ReadModuleFromMemory( 649 image_infos[idx].file_spec, image_infos[idx].address); 650 // Always load a memory image right away in the target in case 651 // we end up trying to read the symbol table from memory... The 652 // __LINKEDIT will need to be mapped so we can figure out where 653 // the symbol table bits are... 654 bool changed = false; 655 UpdateImageLoadAddress(commpage_image_module_sp.get(), 656 image_infos[idx]); 657 target.GetImages().Append(commpage_image_module_sp); 658 if (changed) { 659 image_infos[idx].load_stop_id = m_process->GetStopID(); 660 loaded_module_list.AppendIfNeeded(commpage_image_module_sp); 661 } 662 } 663 } 664 } 665 } 666 } 667 668 // UpdateImageLoadAddress will return true if any segments 669 // change load address. We need to check this so we don't 670 // mention that all loaded shared libraries are newly loaded 671 // each time we hit out dyld breakpoint since dyld will list all 672 // shared libraries each time. 673 if (UpdateImageLoadAddress(image_module_sp.get(), image_infos[idx])) { 674 target_images.AppendIfNeeded(image_module_sp); 675 loaded_module_list.AppendIfNeeded(image_module_sp); 676 } 677 } 678 } 679 680 if (loaded_module_list.GetSize() > 0) { 681 if (log) 682 loaded_module_list.LogUUIDAndPaths(log, 683 "DynamicLoaderDarwin::ModulesDidLoad"); 684 m_process->GetTarget().ModulesDidLoad(loaded_module_list); 685 } 686 return true; 687 } 688 689 //---------------------------------------------------------------------- 690 // On Mac OS X libobjc (the Objective-C runtime) has several critical dispatch 691 // functions written in hand-written assembly, and also have hand-written unwind 692 // information in the eh_frame section. Normally we prefer analyzing the 693 // assembly instructions of a currently executing frame to unwind from that 694 // frame -- 695 // but on hand-written functions this profiling can fail. We should use the 696 // eh_frame instructions for these functions all the time. 697 // 698 // As an aside, it would be better if the eh_frame entries had a flag (or were 699 // extensible so they could have an Apple-specific flag) which indicates that 700 // the instructions are asynchronous -- accurate at every instruction, instead 701 // of our normal default assumption that they are not. 702 //---------------------------------------------------------------------- 703 704 bool DynamicLoaderDarwin::AlwaysRelyOnEHUnwindInfo(SymbolContext &sym_ctx) { 705 ModuleSP module_sp; 706 if (sym_ctx.symbol) { 707 module_sp = sym_ctx.symbol->GetAddressRef().GetModule(); 708 } 709 if (module_sp.get() == NULL && sym_ctx.function) { 710 module_sp = 711 sym_ctx.function->GetAddressRange().GetBaseAddress().GetModule(); 712 } 713 if (module_sp.get() == NULL) 714 return false; 715 716 ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime(); 717 if (objc_runtime != NULL && objc_runtime->IsModuleObjCLibrary(module_sp)) { 718 return true; 719 } 720 721 return false; 722 } 723 724 //---------------------------------------------------------------------- 725 // Dump a Segment to the file handle provided. 726 //---------------------------------------------------------------------- 727 void DynamicLoaderDarwin::Segment::PutToLog(Log *log, 728 lldb::addr_t slide) const { 729 if (log) { 730 if (slide == 0) 731 log->Printf("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")", 732 name.AsCString(""), vmaddr + slide, vmaddr + slide + vmsize); 733 else 734 log->Printf("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 735 ") slide = 0x%" PRIx64, 736 name.AsCString(""), vmaddr + slide, vmaddr + slide + vmsize, 737 slide); 738 } 739 } 740 741 const DynamicLoaderDarwin::Segment * 742 DynamicLoaderDarwin::ImageInfo::FindSegment(const ConstString &name) const { 743 const size_t num_segments = segments.size(); 744 for (size_t i = 0; i < num_segments; ++i) { 745 if (segments[i].name == name) 746 return &segments[i]; 747 } 748 return NULL; 749 } 750 751 //---------------------------------------------------------------------- 752 // Dump an image info structure to the file handle provided. 753 //---------------------------------------------------------------------- 754 void DynamicLoaderDarwin::ImageInfo::PutToLog(Log *log) const { 755 if (log == NULL) 756 return; 757 const uint8_t *u = (const uint8_t *)uuid.GetBytes(); 758 759 if (address == LLDB_INVALID_ADDRESS) { 760 if (u) { 761 log->Printf("\t modtime=0x%8.8" PRIx64 762 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-" 763 "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s' (UNLOADED)", 764 mod_date, u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7], 765 u[8], u[9], u[10], u[11], u[12], u[13], u[14], u[15], 766 file_spec.GetPath().c_str()); 767 } else 768 log->Printf("\t modtime=0x%8.8" PRIx64 769 " path='%s' (UNLOADED)", 770 mod_date, file_spec.GetPath().c_str()); 771 } else { 772 if (u) { 773 log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 774 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-" 775 "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s'", 776 address, mod_date, u[0], u[1], u[2], u[3], u[4], u[5], u[6], 777 u[7], u[8], u[9], u[10], u[11], u[12], u[13], u[14], u[15], 778 file_spec.GetPath().c_str()); 779 } else { 780 log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 781 " path='%s'", 782 address, mod_date, file_spec.GetPath().c_str()); 783 } 784 for (uint32_t i = 0; i < segments.size(); ++i) 785 segments[i].PutToLog(log, slide); 786 } 787 } 788 789 void DynamicLoaderDarwin::PrivateInitialize(Process *process) { 790 DEBUG_PRINTF("DynamicLoaderDarwin::%s() process state = %s\n", __FUNCTION__, 791 StateAsCString(m_process->GetState())); 792 Clear(true); 793 m_process = process; 794 m_process->GetTarget().ClearAllLoadedSections(); 795 } 796 797 //---------------------------------------------------------------------- 798 // Member function that gets called when the process state changes. 799 //---------------------------------------------------------------------- 800 void DynamicLoaderDarwin::PrivateProcessStateChanged(Process *process, 801 StateType state) { 802 DEBUG_PRINTF("DynamicLoaderDarwin::%s(%s)\n", __FUNCTION__, 803 StateAsCString(state)); 804 switch (state) { 805 case eStateConnected: 806 case eStateAttaching: 807 case eStateLaunching: 808 case eStateInvalid: 809 case eStateUnloaded: 810 case eStateExited: 811 case eStateDetached: 812 Clear(false); 813 break; 814 815 case eStateStopped: 816 // Keep trying find dyld and set our notification breakpoint each time 817 // we stop until we succeed 818 if (!DidSetNotificationBreakpoint() && m_process->IsAlive()) { 819 if (NeedToDoInitialImageFetch()) 820 DoInitialImageFetch(); 821 822 SetNotificationBreakpoint(); 823 } 824 break; 825 826 case eStateRunning: 827 case eStateStepping: 828 case eStateCrashed: 829 case eStateSuspended: 830 break; 831 } 832 } 833 834 ThreadPlanSP 835 DynamicLoaderDarwin::GetStepThroughTrampolinePlan(Thread &thread, 836 bool stop_others) { 837 ThreadPlanSP thread_plan_sp; 838 StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get(); 839 const SymbolContext ¤t_context = 840 current_frame->GetSymbolContext(eSymbolContextSymbol); 841 Symbol *current_symbol = current_context.symbol; 842 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); 843 TargetSP target_sp(thread.CalculateTarget()); 844 845 if (current_symbol != NULL) { 846 std::vector<Address> addresses; 847 848 if (current_symbol->IsTrampoline()) { 849 const ConstString &trampoline_name = current_symbol->GetMangled().GetName( 850 current_symbol->GetLanguage(), Mangled::ePreferMangled); 851 852 if (trampoline_name) { 853 const ModuleList &images = target_sp->GetImages(); 854 855 SymbolContextList code_symbols; 856 images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, 857 code_symbols); 858 size_t num_code_symbols = code_symbols.GetSize(); 859 860 if (num_code_symbols > 0) { 861 for (uint32_t i = 0; i < num_code_symbols; i++) { 862 SymbolContext context; 863 AddressRange addr_range; 864 if (code_symbols.GetContextAtIndex(i, context)) { 865 context.GetAddressRange(eSymbolContextEverything, 0, false, 866 addr_range); 867 addresses.push_back(addr_range.GetBaseAddress()); 868 if (log) { 869 addr_t load_addr = 870 addr_range.GetBaseAddress().GetLoadAddress(target_sp.get()); 871 872 log->Printf("Found a trampoline target symbol at 0x%" PRIx64 873 ".", 874 load_addr); 875 } 876 } 877 } 878 } 879 880 SymbolContextList reexported_symbols; 881 images.FindSymbolsWithNameAndType( 882 trampoline_name, eSymbolTypeReExported, reexported_symbols); 883 size_t num_reexported_symbols = reexported_symbols.GetSize(); 884 if (num_reexported_symbols > 0) { 885 for (uint32_t i = 0; i < num_reexported_symbols; i++) { 886 SymbolContext context; 887 if (reexported_symbols.GetContextAtIndex(i, context)) { 888 if (context.symbol) { 889 Symbol *actual_symbol = 890 context.symbol->ResolveReExportedSymbol(*target_sp.get()); 891 if (actual_symbol) { 892 const Address actual_symbol_addr = 893 actual_symbol->GetAddress(); 894 if (actual_symbol_addr.IsValid()) { 895 addresses.push_back(actual_symbol_addr); 896 if (log) { 897 lldb::addr_t load_addr = 898 actual_symbol_addr.GetLoadAddress(target_sp.get()); 899 log->Printf( 900 "Found a re-exported symbol: %s at 0x%" PRIx64 ".", 901 actual_symbol->GetName().GetCString(), load_addr); 902 } 903 } 904 } 905 } 906 } 907 } 908 } 909 910 SymbolContextList indirect_symbols; 911 images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeResolver, 912 indirect_symbols); 913 size_t num_indirect_symbols = indirect_symbols.GetSize(); 914 if (num_indirect_symbols > 0) { 915 for (uint32_t i = 0; i < num_indirect_symbols; i++) { 916 SymbolContext context; 917 AddressRange addr_range; 918 if (indirect_symbols.GetContextAtIndex(i, context)) { 919 context.GetAddressRange(eSymbolContextEverything, 0, false, 920 addr_range); 921 addresses.push_back(addr_range.GetBaseAddress()); 922 if (log) { 923 addr_t load_addr = 924 addr_range.GetBaseAddress().GetLoadAddress(target_sp.get()); 925 926 log->Printf("Found an indirect target symbol at 0x%" PRIx64 ".", 927 load_addr); 928 } 929 } 930 } 931 } 932 } 933 } else if (current_symbol->GetType() == eSymbolTypeReExported) { 934 // I am not sure we could ever end up stopped AT a re-exported symbol. 935 // But just in case: 936 937 const Symbol *actual_symbol = 938 current_symbol->ResolveReExportedSymbol(*(target_sp.get())); 939 if (actual_symbol) { 940 Address target_addr(actual_symbol->GetAddress()); 941 if (target_addr.IsValid()) { 942 if (log) 943 log->Printf( 944 "Found a re-exported symbol: %s pointing to: %s at 0x%" PRIx64 945 ".", 946 current_symbol->GetName().GetCString(), 947 actual_symbol->GetName().GetCString(), 948 target_addr.GetLoadAddress(target_sp.get())); 949 addresses.push_back(target_addr.GetLoadAddress(target_sp.get())); 950 } 951 } 952 } 953 954 if (addresses.size() > 0) { 955 // First check whether any of the addresses point to Indirect symbols, and 956 // if they do, resolve them: 957 std::vector<lldb::addr_t> load_addrs; 958 for (Address address : addresses) { 959 Symbol *symbol = address.CalculateSymbolContextSymbol(); 960 if (symbol && symbol->IsIndirect()) { 961 Error error; 962 Address symbol_address = symbol->GetAddress(); 963 addr_t resolved_addr = thread.GetProcess()->ResolveIndirectFunction( 964 &symbol_address, error); 965 if (error.Success()) { 966 load_addrs.push_back(resolved_addr); 967 if (log) 968 log->Printf("ResolveIndirectFunction found resolved target for " 969 "%s at 0x%" PRIx64 ".", 970 symbol->GetName().GetCString(), resolved_addr); 971 } 972 } else { 973 load_addrs.push_back(address.GetLoadAddress(target_sp.get())); 974 } 975 } 976 thread_plan_sp.reset( 977 new ThreadPlanRunToAddress(thread, load_addrs, stop_others)); 978 } 979 } else { 980 if (log) 981 log->Printf("Could not find symbol for step through."); 982 } 983 984 return thread_plan_sp; 985 } 986 987 size_t DynamicLoaderDarwin::FindEquivalentSymbols( 988 lldb_private::Symbol *original_symbol, lldb_private::ModuleList &images, 989 lldb_private::SymbolContextList &equivalent_symbols) { 990 const ConstString &trampoline_name = original_symbol->GetMangled().GetName( 991 original_symbol->GetLanguage(), Mangled::ePreferMangled); 992 if (!trampoline_name) 993 return 0; 994 995 size_t initial_size = equivalent_symbols.GetSize(); 996 997 static const char *resolver_name_regex = "(_gc|_non_gc|\\$[A-Za-z0-9\\$]+)$"; 998 std::string equivalent_regex_buf("^"); 999 equivalent_regex_buf.append(trampoline_name.GetCString()); 1000 equivalent_regex_buf.append(resolver_name_regex); 1001 1002 RegularExpression equivalent_name_regex(equivalent_regex_buf); 1003 const bool append = true; 1004 images.FindSymbolsMatchingRegExAndType(equivalent_name_regex, eSymbolTypeCode, 1005 equivalent_symbols, append); 1006 1007 return equivalent_symbols.GetSize() - initial_size; 1008 } 1009 1010 lldb::ModuleSP DynamicLoaderDarwin::GetPThreadLibraryModule() { 1011 ModuleSP module_sp = m_libpthread_module_wp.lock(); 1012 if (!module_sp) { 1013 SymbolContextList sc_list; 1014 ModuleSpec module_spec; 1015 module_spec.GetFileSpec().GetFilename().SetCString( 1016 "libsystem_pthread.dylib"); 1017 ModuleList module_list; 1018 if (m_process->GetTarget().GetImages().FindModules(module_spec, 1019 module_list)) { 1020 if (module_list.GetSize() == 1) { 1021 module_sp = module_list.GetModuleAtIndex(0); 1022 if (module_sp) 1023 m_libpthread_module_wp = module_sp; 1024 } 1025 } 1026 } 1027 return module_sp; 1028 } 1029 1030 Address DynamicLoaderDarwin::GetPthreadSetSpecificAddress() { 1031 if (!m_pthread_getspecific_addr.IsValid()) { 1032 ModuleSP module_sp = GetPThreadLibraryModule(); 1033 if (module_sp) { 1034 lldb_private::SymbolContextList sc_list; 1035 module_sp->FindSymbolsWithNameAndType(ConstString("pthread_getspecific"), 1036 eSymbolTypeCode, sc_list); 1037 SymbolContext sc; 1038 if (sc_list.GetContextAtIndex(0, sc)) { 1039 if (sc.symbol) 1040 m_pthread_getspecific_addr = sc.symbol->GetAddress(); 1041 } 1042 } 1043 } 1044 return m_pthread_getspecific_addr; 1045 } 1046 1047 lldb::addr_t 1048 DynamicLoaderDarwin::GetThreadLocalData(const lldb::ModuleSP module_sp, 1049 const lldb::ThreadSP thread_sp, 1050 lldb::addr_t tls_file_addr) { 1051 if (!thread_sp || !module_sp) 1052 return LLDB_INVALID_ADDRESS; 1053 1054 std::lock_guard<std::recursive_mutex> guard(m_mutex); 1055 1056 const uint32_t addr_size = m_process->GetAddressByteSize(); 1057 uint8_t buf[sizeof(lldb::addr_t) * 3]; 1058 1059 lldb_private::Address tls_addr; 1060 if (module_sp->ResolveFileAddress(tls_file_addr, tls_addr)) { 1061 Error error; 1062 const size_t tsl_data_size = addr_size * 3; 1063 Target &target = m_process->GetTarget(); 1064 if (target.ReadMemory(tls_addr, false, buf, tsl_data_size, error) == 1065 tsl_data_size) { 1066 const ByteOrder byte_order = m_process->GetByteOrder(); 1067 DataExtractor data(buf, sizeof(buf), byte_order, addr_size); 1068 lldb::offset_t offset = addr_size; // Skip the first pointer 1069 const lldb::addr_t pthread_key = data.GetAddress(&offset); 1070 const lldb::addr_t tls_offset = data.GetAddress(&offset); 1071 if (pthread_key != 0) { 1072 // First check to see if we have already figured out the location 1073 // of TLS data for the pthread_key on a specific thread yet. If we 1074 // have we can re-use it since its location will not change unless 1075 // the process execs. 1076 const tid_t tid = thread_sp->GetID(); 1077 auto tid_pos = m_tid_to_tls_map.find(tid); 1078 if (tid_pos != m_tid_to_tls_map.end()) { 1079 auto tls_pos = tid_pos->second.find(pthread_key); 1080 if (tls_pos != tid_pos->second.end()) { 1081 return tls_pos->second + tls_offset; 1082 } 1083 } 1084 StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex(0); 1085 if (frame_sp) { 1086 ClangASTContext *clang_ast_context = 1087 target.GetScratchClangASTContext(); 1088 1089 if (!clang_ast_context) 1090 return LLDB_INVALID_ADDRESS; 1091 1092 CompilerType clang_void_ptr_type = 1093 clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); 1094 Address pthread_getspecific_addr = GetPthreadSetSpecificAddress(); 1095 if (pthread_getspecific_addr.IsValid()) { 1096 EvaluateExpressionOptions options; 1097 1098 lldb::ThreadPlanSP thread_plan_sp(new ThreadPlanCallFunction( 1099 *thread_sp, pthread_getspecific_addr, clang_void_ptr_type, 1100 llvm::ArrayRef<lldb::addr_t>(pthread_key), options)); 1101 1102 DiagnosticManager execution_errors; 1103 ExecutionContext exe_ctx(thread_sp); 1104 lldb::ExpressionResults results = m_process->RunThreadPlan( 1105 exe_ctx, thread_plan_sp, options, execution_errors); 1106 1107 if (results == lldb::eExpressionCompleted) { 1108 lldb::ValueObjectSP result_valobj_sp = 1109 thread_plan_sp->GetReturnValueObject(); 1110 if (result_valobj_sp) { 1111 const lldb::addr_t pthread_key_data = 1112 result_valobj_sp->GetValueAsUnsigned(0); 1113 if (pthread_key_data) { 1114 m_tid_to_tls_map[tid].insert( 1115 std::make_pair(pthread_key, pthread_key_data)); 1116 return pthread_key_data + tls_offset; 1117 } 1118 } 1119 } 1120 } 1121 } 1122 } 1123 } 1124 } 1125 return LLDB_INVALID_ADDRESS; 1126 } 1127 1128 bool DynamicLoaderDarwin::UseDYLDSPI(Process *process) { 1129 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); 1130 uint32_t major, minor, update; 1131 1132 bool use_new_spi_interface = false; 1133 1134 if (process->GetHostOSVersion(major, minor, update)) { 1135 const llvm::Triple::OSType os_type = 1136 process->GetTarget().GetArchitecture().GetTriple().getOS(); 1137 1138 // macOS 10.12 and newer 1139 if (os_type == llvm::Triple::MacOSX && 1140 (major >= 10 || (major == 10 && minor >= 12))) { 1141 use_new_spi_interface = true; 1142 } 1143 1144 // iOS 10 and newer 1145 if (os_type == llvm::Triple::IOS && major >= 10) { 1146 use_new_spi_interface = true; 1147 } 1148 1149 // tvOS 10 and newer 1150 if (os_type == llvm::Triple::TvOS && major >= 10) { 1151 use_new_spi_interface = true; 1152 } 1153 1154 // watchOS 3 and newer 1155 if (os_type == llvm::Triple::WatchOS && major >= 3) { 1156 use_new_spi_interface = true; 1157 } 1158 } 1159 1160 // FIXME: Temporarily force the use of the old DynamicLoader plugin until all 1161 // the different use cases have been tested & the updated SPIs are available 1162 // everywhere. 1163 use_new_spi_interface = false; 1164 1165 if (log) { 1166 if (use_new_spi_interface) 1167 log->Printf( 1168 "DynamicLoaderDarwin::UseDYLDSPI: Use new DynamicLoader plugin"); 1169 else 1170 log->Printf( 1171 "DynamicLoaderDarwin::UseDYLDSPI: Use old DynamicLoader plugin"); 1172 } 1173 return use_new_spi_interface; 1174 } 1175