88
99#include " DynamicLoaderDarwin.h"
1010
11+ #include " DynamicLoaderDarwinProperties.h"
1112#include " lldb/Breakpoint/StoppointCallbackContext.h"
1213#include " lldb/Core/Debugger.h"
1314#include " lldb/Core/Module.h"
3132#include " lldb/Utility/LLDBLog.h"
3233#include " lldb/Utility/Log.h"
3334#include " lldb/Utility/State.h"
35+ #include " llvm/Support/ThreadPool.h"
3436
3537#include " Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
3638#include " Plugins/TypeSystem/Clang/TypeSystemClang.h"
@@ -77,6 +79,17 @@ void DynamicLoaderDarwin::DidLaunch() {
7779 SetNotificationBreakpoint ();
7880}
7981
82+ void DynamicLoaderDarwin::CreateSettings (lldb_private::Debugger &debugger) {
83+ if (!PluginManager::GetSettingForDynamicLoaderPlugin (
84+ debugger, DynamicLoaderDarwinProperties::GetSettingName ())) {
85+ const bool is_global_setting = true ;
86+ PluginManager::CreateSettingForDynamicLoaderPlugin (
87+ debugger,
88+ DynamicLoaderDarwinProperties::GetGlobal ().GetValueProperties (),
89+ " Properties for the DynamicLoaderDarwin plug-in." , is_global_setting);
90+ }
91+ }
92+
8093// Clear out the state of this class.
8194void DynamicLoaderDarwin::Clear (bool clear_process) {
8295 std::lock_guard<std::recursive_mutex> guard (m_mutex);
@@ -88,7 +101,7 @@ void DynamicLoaderDarwin::Clear(bool clear_process) {
88101}
89102
90103ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo (
91- ImageInfo &image_info, bool can_create, bool *did_create_ptr) {
104+ const ImageInfo &image_info, bool can_create, bool *did_create_ptr) {
92105 if (did_create_ptr)
93106 *did_create_ptr = false ;
94107
@@ -517,44 +530,43 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
517530 return true ;
518531}
519532
520- void DynamicLoaderDarwin::UpdateSpecialBinariesFromNewImageInfos (
521- ImageInfo::collection &image_infos ) {
533+ void DynamicLoaderDarwin::UpdateSpecialBinariesFromPreloadedModules (
534+ std::vector<std::pair<ImageInfo, ModuleSP>> &images ) {
522535 uint32_t exe_idx = UINT32_MAX;
523536 uint32_t dyld_idx = UINT32_MAX;
524537 Target &target = m_process->GetTarget ();
525538 Log *log = GetLog (LLDBLog::DynamicLoader);
526539 ConstString g_dyld_sim_filename (" dyld_sim" );
527540
528541 ArchSpec target_arch = target.GetArchitecture ();
529- const size_t image_infos_size = image_infos.size ();
530- for (size_t i = 0 ; i < image_infos_size; i++) {
531- if (image_infos[i].header .filetype == llvm::MachO::MH_DYLINKER) {
542+ const size_t images_size = images.size ();
543+ for (size_t i = 0 ; i < images_size; i++) {
544+ const auto &image_info = images[i].first ;
545+ if (image_info.header .filetype == llvm::MachO::MH_DYLINKER) {
532546 // In a "simulator" process we will have two dyld modules --
533547 // a "dyld" that we want to keep track of, and a "dyld_sim" which
534548 // we don't need to keep track of here. dyld_sim will have a non-macosx
535549 // OS.
536550 if (target_arch.GetTriple ().getEnvironment () == llvm::Triple::Simulator &&
537- image_infos[i] .os_type != llvm::Triple::OSType::MacOSX) {
551+ image_info .os_type != llvm::Triple::OSType::MacOSX) {
538552 continue ;
539553 }
540554
541555 dyld_idx = i;
542556 }
543- if (image_infos[i] .header .filetype == llvm::MachO::MH_EXECUTE) {
557+ if (image_info .header .filetype == llvm::MachO::MH_EXECUTE) {
544558 exe_idx = i;
545559 }
546560 }
547561
548562 // Set the target executable if we haven't found one so far.
549563 if (exe_idx != UINT32_MAX && !target.GetExecutableModule ()) {
550- const bool can_create = true ;
551- ModuleSP exe_module_sp (FindTargetModuleForImageInfo (image_infos[exe_idx],
552- can_create, nullptr ));
564+ ModuleSP exe_module_sp = images[exe_idx].second ;
553565 if (exe_module_sp) {
554566 LLDB_LOGF (log, " Found executable module: %s" ,
555567 exe_module_sp->GetFileSpec ().GetPath ().c_str ());
556568 target.GetImages ().AppendIfNeeded (exe_module_sp);
557- UpdateImageLoadAddress (exe_module_sp.get (), image_infos [exe_idx]);
569+ UpdateImageLoadAddress (exe_module_sp.get (), images [exe_idx]. first );
558570 if (exe_module_sp.get () != target.GetExecutableModulePointer ())
559571 target.SetExecutableModule (exe_module_sp, eLoadDependentsNo);
560572
@@ -581,14 +593,12 @@ void DynamicLoaderDarwin::UpdateSpecialBinariesFromNewImageInfos(
581593 }
582594
583595 if (dyld_idx != UINT32_MAX) {
584- const bool can_create = true ;
585- ModuleSP dyld_sp = FindTargetModuleForImageInfo (image_infos[dyld_idx],
586- can_create, nullptr );
596+ ModuleSP dyld_sp = images[dyld_idx].second ;
587597 if (dyld_sp.get ()) {
588598 LLDB_LOGF (log, " Found dyld module: %s" ,
589599 dyld_sp->GetFileSpec ().GetPath ().c_str ());
590600 target.GetImages ().AppendIfNeeded (dyld_sp);
591- UpdateImageLoadAddress (dyld_sp.get (), image_infos [dyld_idx]);
601+ UpdateImageLoadAddress (dyld_sp.get (), images [dyld_idx]. first );
592602 SetDYLDModule (dyld_sp);
593603 }
594604 }
@@ -642,26 +652,58 @@ ModuleSP DynamicLoaderDarwin::GetDYLDModule() {
642652
643653void DynamicLoaderDarwin::ClearDYLDModule () { m_dyld_module_wp.reset (); }
644654
655+ std::vector<std::pair<DynamicLoaderDarwin::ImageInfo, ModuleSP>>
656+ DynamicLoaderDarwin::PreloadModulesFromImageInfos (
657+ const ImageInfo::collection &image_infos) {
658+ const auto size = image_infos.size ();
659+ std::vector<std::pair<DynamicLoaderDarwin::ImageInfo, ModuleSP>> images (size);
660+ auto LoadImage = [&](size_t i, ImageInfo::collection::const_iterator it) {
661+ const auto &image_info = *it;
662+ images[i] = std::make_pair (
663+ image_info, FindTargetModuleForImageInfo (image_info, true , nullptr ));
664+ };
665+ auto it = image_infos.begin ();
666+ bool is_parallel_load =
667+ DynamicLoaderDarwinProperties::GetGlobal ().GetEnableParallelImageLoad ();
668+ if (is_parallel_load) {
669+ llvm::ThreadPoolTaskGroup taskGroup (Debugger::GetThreadPool ());
670+ for (size_t i = 0 ; i < size; ++i, ++it) {
671+ taskGroup.async (LoadImage, i, it);
672+ }
673+ taskGroup.wait ();
674+ } else {
675+ for (size_t i = 0 ; i < size; ++i, ++it) {
676+ LoadImage (i, it);
677+ }
678+ }
679+ return images;
680+ }
681+
645682bool DynamicLoaderDarwin::AddModulesUsingImageInfos (
646683 ImageInfo::collection &image_infos) {
647684 std::lock_guard<std::recursive_mutex> guard (m_mutex);
685+ auto images = PreloadModulesFromImageInfos (image_infos);
686+ return AddModulesUsingPreloadedModules (images);
687+ }
688+
689+ bool DynamicLoaderDarwin::AddModulesUsingPreloadedModules (
690+ std::vector<std::pair<ImageInfo, ModuleSP>> &images) {
691+ std::lock_guard<std::recursive_mutex> guard (m_mutex);
648692 // Now add these images to the main list.
649693 ModuleList loaded_module_list;
650694 Log *log = GetLog (LLDBLog::DynamicLoader);
651695 Target &target = m_process->GetTarget ();
652696 ModuleList &target_images = target.GetImages ();
653697
654- for (uint32_t idx = 0 ; idx < image_infos.size (); ++idx) {
698+ for (uint32_t idx = 0 ; idx < images.size (); ++idx) {
699+ auto &image_info = images[idx].first ;
700+ const auto &image_module_sp = images[idx].second ;
655701 if (log) {
656702 LLDB_LOGF (log, " Adding new image at address=0x%16.16" PRIx64 " ." ,
657- image_infos[idx] .address );
658- image_infos[idx] .PutToLog (log);
703+ image_info .address );
704+ image_info .PutToLog (log);
659705 }
660-
661- m_dyld_image_infos.push_back (image_infos[idx]);
662-
663- ModuleSP image_module_sp (
664- FindTargetModuleForImageInfo (image_infos[idx], true , nullptr ));
706+ m_dyld_image_infos.push_back (image_info);
665707
666708 if (image_module_sp) {
667709 ObjectFile *objfile = image_module_sp->GetObjectFile ();
@@ -673,7 +715,7 @@ bool DynamicLoaderDarwin::AddModulesUsingImageInfos(
673715 sections->FindSectionByName (commpage_dbstr).get ();
674716 if (commpage_section) {
675717 ModuleSpec module_spec (objfile->GetFileSpec (),
676- image_infos[idx] .GetArchitecture ());
718+ image_info .GetArchitecture ());
677719 module_spec.GetObjectName () = commpage_dbstr;
678720 ModuleSP commpage_image_module_sp (
679721 target_images.FindFirstModule (module_spec));
@@ -686,17 +728,17 @@ bool DynamicLoaderDarwin::AddModulesUsingImageInfos(
686728 if (!commpage_image_module_sp ||
687729 commpage_image_module_sp->GetObjectFile () == nullptr ) {
688730 commpage_image_module_sp = m_process->ReadModuleFromMemory (
689- image_infos[idx] .file_spec , image_infos[idx] .address );
731+ image_info .file_spec , image_info .address );
690732 // Always load a memory image right away in the target in case
691733 // we end up trying to read the symbol table from memory... The
692734 // __LINKEDIT will need to be mapped so we can figure out where
693735 // the symbol table bits are...
694736 bool changed = false ;
695737 UpdateImageLoadAddress (commpage_image_module_sp.get (),
696- image_infos[idx] );
738+ image_info );
697739 target.GetImages ().Append (commpage_image_module_sp);
698740 if (changed) {
699- image_infos[idx] .load_stop_id = m_process->GetStopID ();
741+ image_info .load_stop_id = m_process->GetStopID ();
700742 loaded_module_list.AppendIfNeeded (commpage_image_module_sp);
701743 }
702744 }
@@ -709,14 +751,14 @@ bool DynamicLoaderDarwin::AddModulesUsingImageInfos(
709751 // address. We need to check this so we don't mention that all loaded
710752 // shared libraries are newly loaded each time we hit out dyld breakpoint
711753 // since dyld will list all shared libraries each time.
712- if (UpdateImageLoadAddress (image_module_sp.get (), image_infos[idx] )) {
754+ if (UpdateImageLoadAddress (image_module_sp.get (), image_info )) {
713755 target_images.AppendIfNeeded (image_module_sp);
714756 loaded_module_list.AppendIfNeeded (image_module_sp);
715757 }
716758
717759 // To support macCatalyst and legacy iOS simulator,
718760 // update the module's platform with the DYLD info.
719- ArchSpec dyld_spec = image_infos[idx] .GetArchitecture ();
761+ ArchSpec dyld_spec = image_info .GetArchitecture ();
720762 auto &dyld_triple = dyld_spec.GetTriple ();
721763 if ((dyld_triple.getEnvironment () == llvm::Triple::MacABI &&
722764 dyld_triple.getOS () == llvm::Triple::IOS) ||
0 commit comments