From c6534a14078ee8644c2403d51e9df613cddce22b Mon Sep 17 00:00:00 2001 From: George Hu Date: Mon, 22 Sep 2025 13:42:31 -0700 Subject: [PATCH 1/7] Call locate module callback for main executable --- lldb/source/Target/Platform.cpp | 50 +++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp index 8681adaf5ea76..bbbe066cdea9e 100644 --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -750,12 +750,30 @@ Platform::ResolveExecutable(const ModuleSpec &module_spec, if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid()) { - Status error = - ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, - module_search_paths_ptr, nullptr, nullptr); + // Call locate module callback first to give it a chance to find/register + // symbol file specs for the main executable, similar to how shared + // libraries are handled in Platform::GetRemoteSharedModule() + FileSpec symbol_file_spec; + CallLocateModuleCallbackIfSet(resolved_module_spec, exe_module_sp, + symbol_file_spec, nullptr); - if (exe_module_sp && exe_module_sp->GetObjectFile()) - return error; + Status error; + if (!exe_module_sp) { + // If locate module callback didn't provide a module, fallback to standard + // path + error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, + module_search_paths_ptr, nullptr, + nullptr); + } + + if (exe_module_sp && exe_module_sp->GetObjectFile()) { + // Set the symbol file if locate module callback returned one + if (symbol_file_spec) { + exe_module_sp->SetSymbolFileFileSpec(symbol_file_spec); + } + return error; // Return the actual status from GetSharedModule (or success + // from callback) + } exe_module_sp.reset(); } // No valid architecture was specified or the exact arch wasn't found. @@ -767,12 +785,26 @@ Platform::ResolveExecutable(const ModuleSpec &module_spec, Status error; for (const ArchSpec &arch : GetSupportedArchitectures(process_host_arch)) { resolved_module_spec.GetArchitecture() = arch; - error = - ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, - module_search_paths_ptr, nullptr, nullptr); + + // Call locate module callback first, then fallback to standard path + FileSpec symbol_file_spec; + CallLocateModuleCallbackIfSet(resolved_module_spec, exe_module_sp, + symbol_file_spec, nullptr); + + if (!exe_module_sp) { + error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, + module_search_paths_ptr, nullptr, + nullptr); + } + if (error.Success()) { - if (exe_module_sp && exe_module_sp->GetObjectFile()) + if (exe_module_sp && exe_module_sp->GetObjectFile()) { + // Set the symbol file if locate module callback returned one + if (symbol_file_spec) { + exe_module_sp->SetSymbolFileFileSpec(symbol_file_spec); + } break; + } error = Status::FromErrorString("no exe object file"); } From 2dc6595e89a26ff3d9774dc3d82daac0f0576aca Mon Sep 17 00:00:00 2001 From: George Hu Date: Fri, 26 Sep 2025 16:45:58 -0700 Subject: [PATCH 2/7] [lldb] Refactor add target into ModuleSpec --- lldb/include/lldb/Core/ModuleList.h | 1 - lldb/include/lldb/Core/ModuleSpec.h | 9 ++++ lldb/include/lldb/Target/Platform.h | 16 +++--- .../include/lldb/Target/RemoteAwarePlatform.h | 6 +-- lldb/source/API/SBModule.cpp | 4 +- lldb/source/Core/DynamicLoader.cpp | 5 +- lldb/source/Core/ModuleList.cpp | 12 ++++- .../DynamicLoaderDarwinKernel.cpp | 6 +-- .../POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp | 5 +- .../MacOSX/PlatformAppleSimulator.cpp | 8 +-- .../Platform/MacOSX/PlatformAppleSimulator.h | 1 - .../Platform/MacOSX/PlatformDarwin.cpp | 39 +++++++++----- .../Plugins/Platform/MacOSX/PlatformDarwin.h | 3 +- .../Platform/MacOSX/PlatformDarwinDevice.cpp | 10 ++-- .../Platform/MacOSX/PlatformDarwinDevice.h | 1 - .../Platform/MacOSX/PlatformDarwinKernel.cpp | 22 +++----- .../Platform/MacOSX/PlatformDarwinKernel.h | 11 ++-- .../Platform/MacOSX/PlatformMacOSX.cpp | 9 ++-- .../Plugins/Platform/MacOSX/PlatformMacOSX.h | 1 - .../MacOSX/PlatformRemoteDarwinDevice.cpp | 18 +++---- .../MacOSX/PlatformRemoteDarwinDevice.h | 1 - .../Process/elf-core/ProcessElfCore.cpp | 3 +- .../Process/mach-core/ProcessMachCore.cpp | 3 +- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 2 +- lldb/source/Target/ModuleCache.cpp | 2 +- lldb/source/Target/Platform.cpp | 53 +++++++++---------- lldb/source/Target/RemoteAwarePlatform.cpp | 11 ++-- lldb/source/Target/Target.cpp | 18 +++---- lldb/source/Target/TargetList.cpp | 8 +-- .../Target/RemoteAwarePlatformTest.cpp | 14 +++-- 30 files changed, 145 insertions(+), 157 deletions(-) diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h index 6ecdcf10fa85f..c538eef699ed9 100644 --- a/lldb/include/lldb/Core/ModuleList.h +++ b/lldb/include/lldb/Core/ModuleList.h @@ -476,7 +476,6 @@ class ModuleList { static Status GetSharedModule(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr, bool always_create = false); diff --git a/lldb/include/lldb/Core/ModuleSpec.h b/lldb/include/lldb/Core/ModuleSpec.h index 86be0383f8b47..fbbab299d86cd 100644 --- a/lldb/include/lldb/Core/ModuleSpec.h +++ b/lldb/include/lldb/Core/ModuleSpec.h @@ -126,6 +126,12 @@ class ModuleSpec { lldb::DataBufferSP GetData() const { return m_data; } + Target *GetTargetPtr() { return m_target; } + + const Target *GetTargetPtr() const { return m_target; } + + void SetTarget(Target *target) { m_target = target; } + void Clear() { m_file.Clear(); m_platform_file.Clear(); @@ -137,6 +143,7 @@ class ModuleSpec { m_object_size = 0; m_source_mappings.Clear(false); m_object_mod_time = llvm::sys::TimePoint<>(); + m_target = nullptr; } explicit operator bool() const { @@ -265,6 +272,8 @@ class ModuleSpec { ArchSpec m_arch; UUID m_uuid; ConstString m_object_name; + Target *m_target; // This is set to take advantage of the target's search path + // and platform's locate module callback uint64_t m_object_offset = 0; uint64_t m_object_size = 0; llvm::sys::TimePoint<> m_object_mod_time; diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h index 35ffdabf907e7..1104722f52c70 100644 --- a/lldb/include/lldb/Target/Platform.h +++ b/lldb/include/lldb/Target/Platform.h @@ -127,8 +127,7 @@ class Platform : public PluginInterface { /// Returns \b true if this Platform plug-in was able to find /// a suitable executable, \b false otherwise. virtual Status ResolveExecutable(const ModuleSpec &module_spec, - lldb::ModuleSP &exe_module_sp, - const FileSpecList *module_search_paths_ptr); + lldb::ModuleSP &exe_module_sp); /// Find a symbol file given a symbol file module specification. /// @@ -304,10 +303,11 @@ class Platform : public PluginInterface { /// \return /// The Status object for any errors found while searching for /// the binary. - virtual Status GetSharedModule( - const ModuleSpec &module_spec, Process *process, - lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, - llvm::SmallVectorImpl *old_modules, bool *did_create_ptr); + virtual Status + GetSharedModule(const ModuleSpec &module_spec, Process *process, + lldb::ModuleSP &module_sp, + llvm::SmallVectorImpl *old_modules, + bool *did_create_ptr); void CallLocateModuleCallbackIfSet(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, @@ -1039,8 +1039,8 @@ class Platform : public PluginInterface { /// predefined trap handlers, this method may be a no-op. virtual void CalculateTrapHandlerSymbolNames() = 0; - Status GetCachedExecutable(ModuleSpec &module_spec, lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr); + Status GetCachedExecutable(ModuleSpec &module_spec, + lldb::ModuleSP &module_sp); virtual Status DownloadModuleSlice(const FileSpec &src_file_spec, const uint64_t src_offset, diff --git a/lldb/include/lldb/Target/RemoteAwarePlatform.h b/lldb/include/lldb/Target/RemoteAwarePlatform.h index fb2eecfaa23a8..de13b18f30d85 100644 --- a/lldb/include/lldb/Target/RemoteAwarePlatform.h +++ b/lldb/include/lldb/Target/RemoteAwarePlatform.h @@ -20,10 +20,8 @@ class RemoteAwarePlatform : public Platform { public: using Platform::Platform; - virtual Status - ResolveExecutable(const ModuleSpec &module_spec, - lldb::ModuleSP &exe_module_sp, - const FileSpecList *module_search_paths_ptr) override; + virtual Status ResolveExecutable(const ModuleSpec &module_spec, + lldb::ModuleSP &exe_module_sp) override; bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, ModuleSpec &module_spec) override; diff --git a/lldb/source/API/SBModule.cpp b/lldb/source/API/SBModule.cpp index 5a57f45f0d475..32067ac1c650f 100644 --- a/lldb/source/API/SBModule.cpp +++ b/lldb/source/API/SBModule.cpp @@ -37,8 +37,8 @@ SBModule::SBModule(const SBModuleSpec &module_spec) { LLDB_INSTRUMENT_VA(this, module_spec); ModuleSP module_sp; - Status error = ModuleList::GetSharedModule( - *module_spec.m_opaque_up, module_sp, nullptr, nullptr, nullptr); + Status error = ModuleList::GetSharedModule(*module_spec.m_opaque_up, + module_sp, nullptr, nullptr); if (module_sp) SetSP(module_sp); } diff --git a/lldb/source/Core/DynamicLoader.cpp b/lldb/source/Core/DynamicLoader.cpp index 7580b15c02ce1..52f9c3cd5e5a6 100644 --- a/lldb/source/Core/DynamicLoader.cpp +++ b/lldb/source/Core/DynamicLoader.cpp @@ -227,6 +227,7 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress( } } ModuleSpec module_spec; + module_spec.SetTarget(&target); module_spec.GetUUID() = uuid; FileSpec name_filespec(name); if (FileSystem::Instance().Exists(name_filespec)) @@ -238,8 +239,8 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress( // Has lldb already seen a module with this UUID? // Or have external lookup enabled in DebugSymbols on macOS. if (!module_sp) - error = ModuleList::GetSharedModule(module_spec, module_sp, nullptr, - nullptr, nullptr); + error = + ModuleList::GetSharedModule(module_spec, module_sp, nullptr, nullptr); // Can lldb's symbol/executable location schemes // find an executable and symbol file. diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index bc63a41c90d17..f38c2d03f85d3 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -19,6 +19,7 @@ #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/TypeList.h" #include "lldb/Symbol/VariableList.h" +#include "lldb/Target/Target.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpecList.h" @@ -1029,7 +1030,6 @@ size_t ModuleList::RemoveOrphanSharedModules(bool mandatory) { Status ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr, bool always_create) { ModuleList &shared_module_list = GetSharedModuleList(); @@ -1114,6 +1114,16 @@ ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp, module_sp.reset(); } + // Get module search paths from the target if available + ModuleSpec module_spec_copy(module_spec); + Target *target = module_spec_copy.GetTargetPtr(); + FileSpecList module_search_paths; + FileSpecList *module_search_paths_ptr = nullptr; + if (target) { + module_search_paths = target->GetExecutableSearchPaths(); + module_search_paths_ptr = &module_search_paths; + } + if (module_search_paths_ptr) { const auto num_directories = module_search_paths_ptr->GetSize(); for (size_t idx = 0; idx < num_directories; ++idx) { diff --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp index 1d210ea78df1a..3d0b41c452a11 100644 --- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp +++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp @@ -789,6 +789,7 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule( // Search for the kext on the local filesystem via the UUID if (!m_module_sp && m_uuid.IsValid()) { ModuleSpec module_spec; + module_spec.SetTarget(&target); module_spec.GetUUID() = m_uuid; if (!m_uuid.IsValid()) module_spec.GetArchitecture() = target.GetArchitecture(); @@ -801,9 +802,8 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule( // system. PlatformSP platform_sp(target.GetPlatform()); if (platform_sp) { - FileSpecList search_paths = target.GetExecutableSearchPaths(); - platform_sp->GetSharedModule(module_spec, process, m_module_sp, - &search_paths, nullptr, nullptr); + platform_sp->GetSharedModule(module_spec, process, m_module_sp, nullptr, + nullptr); } // Ask the Target to find this file on the local system, if possible. diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index 326b6910b5267..5f365878acdc6 100644 --- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -901,10 +901,9 @@ void DynamicLoaderPOSIXDYLD::ResolveExecutableModule( if (module_sp && module_sp->MatchesModuleSpec(module_spec)) return; + module_spec.SetTarget(&target); const auto executable_search_paths(Target::GetDefaultExecutableSearchPaths()); - auto error = platform_sp->ResolveExecutable( - module_spec, module_sp, - !executable_search_paths.IsEmpty() ? &executable_search_paths : nullptr); + auto error = platform_sp->ResolveExecutable(module_spec, module_sp); if (error.Fail()) { StreamString stream; module_spec.Dump(stream); diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp index 4cfb0a81dc6e4..81db5731aeebf 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp @@ -420,7 +420,6 @@ Status PlatformAppleSimulator::GetSymbolFile(const FileSpec &platform_file, Status PlatformAppleSimulator::GetSharedModule( const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { // For iOS/tvOS/watchOS, the SDK files are all cached locally on the // host system. So first we ask for the file in the cached SDK, then @@ -432,12 +431,10 @@ Status PlatformAppleSimulator::GetSharedModule( error = GetSymbolFile(platform_file, module_spec.GetUUIDPtr(), platform_module_spec.GetFileSpec()); if (error.Success()) { - error = ResolveExecutable(platform_module_spec, module_sp, - module_search_paths_ptr); + error = ResolveExecutable(platform_module_spec, module_sp); } else { const bool always_create = false; - error = ModuleList::GetSharedModule(module_spec, module_sp, - module_search_paths_ptr, old_modules, + error = ModuleList::GetSharedModule(module_spec, module_sp, old_modules, did_create_ptr, always_create); } if (module_sp) @@ -660,4 +657,3 @@ void PlatformAppleSimulator::Terminate() { PlatformDarwin::Terminate(); } } - diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h index 7fcf2c502ca6a..77d2a3b4e1cce 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h @@ -89,7 +89,6 @@ class PlatformAppleSimulator : public PlatformDarwin { Status GetSharedModule(const ModuleSpec &module_spec, Process *process, lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) override; diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index cd72454fe0287..a0e1f9e307219 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -331,7 +331,6 @@ Status PlatformDarwin::ResolveSymbolFile(Target &target, Status PlatformDarwin::GetSharedModule( const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { Status error; module_sp.reset(); @@ -341,18 +340,25 @@ Status PlatformDarwin::GetSharedModule( // module first. if (m_remote_platform_sp) { error = m_remote_platform_sp->GetSharedModule( - module_spec, process, module_sp, module_search_paths_ptr, old_modules, - did_create_ptr); + module_spec, process, module_sp, old_modules, did_create_ptr); } } if (!module_sp) { // Fall back to the local platform and find the file locally error = Platform::GetSharedModule(module_spec, process, module_sp, - module_search_paths_ptr, old_modules, - did_create_ptr); + old_modules, did_create_ptr); const FileSpec &platform_file = module_spec.GetFileSpec(); + // Get module search paths from the target if available + ModuleSpec module_spec_copy(module_spec); + Target *target = module_spec_copy.GetTargetPtr(); + FileSpecList module_search_paths; + FileSpecList *module_search_paths_ptr = nullptr; + if (target) { + module_search_paths = target->GetExecutableSearchPaths(); + module_search_paths_ptr = &module_search_paths; + } if (!module_sp && module_search_paths_ptr && platform_file) { // We can try to pull off part of the file path up to the bundle // directory level and try any module search paths... @@ -362,9 +368,9 @@ Status PlatformDarwin::GetSharedModule( ModuleSpec new_module_spec(module_spec); new_module_spec.GetFileSpec() = bundle_directory; if (Host::ResolveExecutableInBundle(new_module_spec.GetFileSpec())) { - Status new_error(Platform::GetSharedModule( - new_module_spec, process, module_sp, nullptr, old_modules, - did_create_ptr)); + Status new_error(Platform::GetSharedModule(new_module_spec, process, + module_sp, old_modules, + did_create_ptr)); if (module_sp) return new_error; @@ -390,7 +396,7 @@ Status PlatformDarwin::GetSharedModule( ModuleSpec new_module_spec(module_spec); new_module_spec.GetFileSpec() = new_file_spec; Status new_error(Platform::GetSharedModule( - new_module_spec, process, module_sp, nullptr, old_modules, + new_module_spec, process, module_sp, old_modules, did_create_ptr)); if (module_sp) { @@ -1303,9 +1309,16 @@ PlatformDarwin::LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) { lldb_private::Status PlatformDarwin::FindBundleBinaryInExecSearchPaths( const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { const FileSpec &platform_file = module_spec.GetFileSpec(); + ModuleSpec module_spec_copy(module_spec); + Target *target = module_spec_copy.GetTargetPtr(); + FileSpecList module_search_paths; + FileSpecList *module_search_paths_ptr = nullptr; + if (target) { + module_search_paths = target->GetExecutableSearchPaths(); + module_search_paths_ptr = &module_search_paths; + } // See if the file is present in any of the module_search_paths_ptr // directories. if (!module_sp && module_search_paths_ptr && platform_file) { @@ -1356,9 +1369,9 @@ lldb_private::Status PlatformDarwin::FindBundleBinaryInExecSearchPaths( if (FileSystem::Instance().Exists(path_to_try)) { ModuleSpec new_module_spec(module_spec); new_module_spec.GetFileSpec() = path_to_try; - Status new_error( - Platform::GetSharedModule(new_module_spec, process, module_sp, - nullptr, old_modules, did_create_ptr)); + Status new_error(Platform::GetSharedModule(new_module_spec, process, + module_sp, old_modules, + did_create_ptr)); if (module_sp) { module_sp->SetPlatformFileSpec(path_to_try); diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h index f8a62ceb958fe..82e69e36dca0c 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h @@ -73,7 +73,6 @@ class PlatformDarwin : public PlatformPOSIX { Status GetSharedModule(const ModuleSpec &module_spec, Process *process, lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) override; @@ -189,7 +188,7 @@ class PlatformDarwin : public PlatformPOSIX { Status FindBundleBinaryInExecSearchPaths( const ModuleSpec &module_spec, Process *process, - lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, + lldb::ModuleSP &module_sp, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr); // The OSType where lldb is running. diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp index 68ef81789b089..a72d94ea79c49 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp @@ -295,7 +295,6 @@ BringInRemoteFile(Platform *platform, lldb_private::Status PlatformDarwinDevice::GetSharedModuleWithLocalCache( const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp, - const lldb_private::FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { Log *log = GetLog(LLDBLog::Platform); @@ -329,8 +328,7 @@ lldb_private::Status PlatformDarwinDevice::GetSharedModuleWithLocalCache( ModuleSpec shared_cache_spec(module_spec.GetFileSpec(), image_info.uuid, image_info.data_sp); err = ModuleList::GetSharedModule(shared_cache_spec, module_sp, - module_search_paths_ptr, old_modules, - did_create_ptr); + old_modules, did_create_ptr); if (module_sp) { LLDB_LOGF(log, "[%s] module %s was found in the in-memory shared cache", (IsHost() ? "host" : "remote"), @@ -348,8 +346,7 @@ lldb_private::Status PlatformDarwinDevice::GetSharedModuleWithLocalCache( FileSystem::Instance().Resolve(device_support_spec); if (FileSystem::Instance().Exists(device_support_spec)) { ModuleSpec local_spec(device_support_spec, module_spec.GetUUID()); - err = ModuleList::GetSharedModule(local_spec, module_sp, - module_search_paths_ptr, old_modules, + err = ModuleList::GetSharedModule(local_spec, module_sp, old_modules, did_create_ptr); if (module_sp) { LLDB_LOGF(log, @@ -363,8 +360,7 @@ lldb_private::Status PlatformDarwinDevice::GetSharedModuleWithLocalCache( } } - err = ModuleList::GetSharedModule(module_spec, module_sp, - module_search_paths_ptr, old_modules, + err = ModuleList::GetSharedModule(module_spec, module_sp, old_modules, did_create_ptr); if (module_sp) return err; diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.h index e1eba08fb5584..e0142ab7ca4cb 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.h @@ -26,7 +26,6 @@ class PlatformDarwinDevice : public PlatformDarwin { protected: virtual Status GetSharedModuleWithLocalCache( const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr); struct SDKDirectoryInfo { diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp index 07c5a523161ed..04e87b9dea699 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp @@ -719,7 +719,6 @@ void PlatformDarwinKernel::UpdateKextandKernelsLocalScan() { Status PlatformDarwinKernel::GetSharedModule( const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { Status error; module_sp.reset(); @@ -734,14 +733,12 @@ Status PlatformDarwinKernel::GetSharedModule( // UUID search can get here with no name - and it may be a kernel. if (kext_bundle_id == "mach_kernel" || kext_bundle_id.empty()) { error = GetSharedModuleKernel(module_spec, process, module_sp, - module_search_paths_ptr, old_modules, - did_create_ptr); + old_modules, did_create_ptr); if (error.Success() && module_sp) { return error; } } else { - return GetSharedModuleKext(module_spec, process, module_sp, - module_search_paths_ptr, old_modules, + return GetSharedModuleKext(module_spec, process, module_sp, old_modules, did_create_ptr); } } @@ -749,13 +746,11 @@ Status PlatformDarwinKernel::GetSharedModule( // Give the generic methods, including possibly calling into DebugSymbols // framework on macOS systems, a chance. return PlatformDarwin::GetSharedModule(module_spec, process, module_sp, - module_search_paths_ptr, old_modules, - did_create_ptr); + old_modules, did_create_ptr); } Status PlatformDarwinKernel::GetSharedModuleKext( const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { Status error; module_sp.reset(); @@ -782,8 +777,7 @@ Status PlatformDarwinKernel::GetSharedModuleKext( // Give the generic methods, including possibly calling into DebugSymbols // framework on macOS systems, a chance. error = PlatformDarwin::GetSharedModule(module_spec, process, module_sp, - module_search_paths_ptr, old_modules, - did_create_ptr); + old_modules, did_create_ptr); if (error.Success() && module_sp.get()) { return error; } @@ -793,7 +787,6 @@ Status PlatformDarwinKernel::GetSharedModuleKext( Status PlatformDarwinKernel::GetSharedModuleKernel( const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { assert(module_sp.get() == nullptr); UpdateKextandKernelsLocalScan(); @@ -848,8 +841,7 @@ Status PlatformDarwinKernel::GetSharedModuleKernel( // Give the generic methods, including possibly calling into DebugSymbols // framework on macOS systems, a chance. return PlatformDarwin::GetSharedModule(module_spec, process, module_sp, - module_search_paths_ptr, old_modules, - did_create_ptr); + old_modules, did_create_ptr); } std::vector @@ -888,8 +880,8 @@ Status PlatformDarwinKernel::ExamineKextForMatchingUUID( ModuleSP module_sp(new Module(exe_spec)); if (module_sp && module_sp->GetObjectFile() && module_sp->MatchesModuleSpec(exe_spec)) { - Status error = ModuleList::GetSharedModule(exe_spec, exe_module_sp, - NULL, NULL, NULL); + Status error = + ModuleList::GetSharedModule(exe_spec, exe_module_sp, NULL, NULL); if (exe_module_sp && exe_module_sp->GetObjectFile()) { return error; } diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h index 9db9c0065613d..b5cf701a76b4d 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h @@ -60,7 +60,6 @@ class PlatformDarwinKernel : public PlatformDarwin { Status GetSharedModule(const ModuleSpec &module_spec, Process *process, lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) override; @@ -142,14 +141,14 @@ class PlatformDarwinKernel : public PlatformDarwin { Status GetSharedModuleKext(const ModuleSpec &module_spec, Process *process, lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr); - Status GetSharedModuleKernel( - const ModuleSpec &module_spec, Process *process, - lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, - llvm::SmallVectorImpl *old_modules, bool *did_create_ptr); + Status + GetSharedModuleKernel(const ModuleSpec &module_spec, Process *process, + lldb::ModuleSP &module_sp, + llvm::SmallVectorImpl *old_modules, + bool *did_create_ptr); Status ExamineKextForMatchingUUID(const FileSpec &kext_bundle_path, const UUID &uuid, const ArchSpec &arch, diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp index dad6dcd133955..e6ea75a35f921 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp @@ -182,10 +182,8 @@ PlatformMacOSX::GetSupportedArchitectures(const ArchSpec &process_host_arch) { lldb_private::Status PlatformMacOSX::GetSharedModule( const lldb_private::ModuleSpec &module_spec, Process *process, lldb::ModuleSP &module_sp, - const lldb_private::FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { Status error = GetSharedModuleWithLocalCache(module_spec, module_sp, - module_search_paths_ptr, old_modules, did_create_ptr); if (module_sp) { @@ -199,9 +197,9 @@ lldb_private::Status PlatformMacOSX::GetSharedModule( lldb::ModuleSP x86_64_module_sp; llvm::SmallVector old_x86_64_modules; bool did_create = false; - Status x86_64_error = GetSharedModuleWithLocalCache( - module_spec_x86_64, x86_64_module_sp, module_search_paths_ptr, - &old_x86_64_modules, &did_create); + Status x86_64_error = + GetSharedModuleWithLocalCache(module_spec_x86_64, x86_64_module_sp, + &old_x86_64_modules, &did_create); if (x86_64_module_sp && x86_64_module_sp->GetObjectFile()) { module_sp = x86_64_module_sp; if (old_modules) @@ -217,7 +215,6 @@ lldb_private::Status PlatformMacOSX::GetSharedModule( if (!module_sp) { error = FindBundleBinaryInExecSearchPaths(module_spec, process, module_sp, - module_search_paths_ptr, old_modules, did_create_ptr); } return error; diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h index be844856ef923..9555b16551d5a 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h @@ -48,7 +48,6 @@ class PlatformMacOSX : public PlatformDarwinDevice { Status GetSharedModule(const ModuleSpec &module_spec, Process *process, lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) override; diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp index b83d07b19235c..47fe640836e30 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp @@ -158,7 +158,6 @@ Status PlatformRemoteDarwinDevice::GetSymbolFile(const FileSpec &platform_file, Status PlatformRemoteDarwinDevice::GetSharedModule( const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { // For iOS, the SDK files are all cached locally on the host system. So first // we ask for the file in the cached SDK, then we attempt to get a shared @@ -185,7 +184,7 @@ Status PlatformRemoteDarwinDevice::GetSharedModule( if (GetFileInSDK(platform_file_path, connected_sdk_idx, platform_module_spec.GetFileSpec())) { module_sp.reset(); - error = ResolveExecutable(platform_module_spec, module_sp, nullptr); + error = ResolveExecutable(platform_module_spec, module_sp); if (module_sp) { m_last_module_sdk_idx = connected_sdk_idx; error.Clear(); @@ -202,7 +201,7 @@ Status PlatformRemoteDarwinDevice::GetSharedModule( if (GetFileInSDK(platform_file_path, m_last_module_sdk_idx, platform_module_spec.GetFileSpec())) { module_sp.reset(); - error = ResolveExecutable(platform_module_spec, module_sp, nullptr); + error = ResolveExecutable(platform_module_spec, module_sp); if (module_sp) { error.Clear(); return error; @@ -224,7 +223,7 @@ Status PlatformRemoteDarwinDevice::GetSharedModule( if (GetFileInSDK(platform_file_path, current_sdk_idx, platform_module_spec.GetFileSpec())) { module_sp.reset(); - error = ResolveExecutable(platform_module_spec, module_sp, nullptr); + error = ResolveExecutable(platform_module_spec, module_sp); if (module_sp) { m_last_module_sdk_idx = current_sdk_idx; error.Clear(); @@ -245,7 +244,7 @@ Status PlatformRemoteDarwinDevice::GetSharedModule( platform_module_spec.GetFileSpec())) { // printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str()); - error = ResolveExecutable(platform_module_spec, module_sp, nullptr); + error = ResolveExecutable(platform_module_spec, module_sp); if (module_sp) { // Remember the index of the last SDK that we found a file in in case // the wrong SDK was selected. @@ -261,8 +260,7 @@ Status PlatformRemoteDarwinDevice::GetSharedModule( // This may not be an SDK-related module. Try whether we can bring in the // thing to our local cache. - error = GetSharedModuleWithLocalCache(module_spec, module_sp, - module_search_paths_ptr, old_modules, + error = GetSharedModuleWithLocalCache(module_spec, module_sp, old_modules, did_create_ptr); if (error.Success()) return error; @@ -271,15 +269,13 @@ Status PlatformRemoteDarwinDevice::GetSharedModule( // directories. if (!module_sp) error = PlatformDarwin::FindBundleBinaryInExecSearchPaths( - module_spec, process, module_sp, module_search_paths_ptr, old_modules, - did_create_ptr); + module_spec, process, module_sp, old_modules, did_create_ptr); if (error.Success()) return error; const bool always_create = false; - error = ModuleList::GetSharedModule(module_spec, module_sp, - module_search_paths_ptr, old_modules, + error = ModuleList::GetSharedModule(module_spec, module_sp, old_modules, did_create_ptr, always_create); if (module_sp) diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h index 557f4876e91ab..4abd74ed07584 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h @@ -47,7 +47,6 @@ class PlatformRemoteDarwinDevice : public PlatformDarwinDevice { Status GetSharedModule(const ModuleSpec &module_spec, Process *process, lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) override; diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index b7029fb3a95b3..cb47a5e0a2766 100644 --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -84,8 +84,9 @@ bool ProcessElfCore::CanDebug(lldb::TargetSP target_sp, // For now we are just making sure the file exists for a given module if (!m_core_module_sp && FileSystem::Instance().Exists(m_core_file)) { ModuleSpec core_module_spec(m_core_file, target_sp->GetArchitecture()); + core_module_spec.SetTarget(target_sp.get()); Status error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp, - nullptr, nullptr, nullptr)); + nullptr, nullptr)); if (m_core_module_sp) { ObjectFile *core_objfile = m_core_module_sp->GetObjectFile(); if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile) diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp index a780b3f59aded..7352b8e63f19a 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp @@ -95,8 +95,9 @@ bool ProcessMachCore::CanDebug(lldb::TargetSP target_sp, // header but we should still try to use it - // ModuleSpecList::FindMatchingModuleSpec enforces a strict arch mach. ModuleSpec core_module_spec(m_core_file); + core_module_spec.SetTarget(target_sp.get()); Status error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp, - nullptr, nullptr, nullptr)); + nullptr, nullptr)); if (m_core_module_sp) { ObjectFile *core_objfile = m_core_module_sp->GetObjectFile(); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 881268bc4ca03..f00e94aee9847 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -2018,7 +2018,7 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { } Status error = ModuleList::GetSharedModule(dwo_module_spec, module_sp, - nullptr, nullptr, nullptr); + nullptr, nullptr); if (!module_sp) { // ReportWarning also rate-limits based on the warning string, // but in a -gmodules build, each object file has a similar DAG diff --git a/lldb/source/Target/ModuleCache.cpp b/lldb/source/Target/ModuleCache.cpp index f737836e0d971..9978946105456 100644 --- a/lldb/source/Target/ModuleCache.cpp +++ b/lldb/source/Target/ModuleCache.cpp @@ -255,7 +255,7 @@ Status ModuleCache::Get(const FileSpec &root_dir_spec, const char *hostname, cached_module_spec.GetPlatformFileSpec() = module_spec.GetFileSpec(); error = ModuleList::GetSharedModule(cached_module_spec, cached_module_sp, - nullptr, nullptr, did_create_ptr, false); + nullptr, did_create_ptr, false); if (error.Fail()) return error; diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp index bbbe066cdea9e..a61f55e6395c0 100644 --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -163,11 +163,12 @@ Platform::LocateExecutableScriptingResources(Target *target, Module &module, Status Platform::GetSharedModule( const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { if (IsHost()) - return ModuleList::GetSharedModule(module_spec, module_sp, - module_search_paths_ptr, old_modules, + // Note: module_search_paths_ptr functionality is now handled internally + // by getting target from module_spec and calling + // target->GetExecutableSearchPaths() + return ModuleList::GetSharedModule(module_spec, module_sp, old_modules, did_create_ptr, false); // Module resolver lambda. @@ -180,16 +181,14 @@ Status Platform::GetSharedModule( resolved_spec = spec; resolved_spec.GetFileSpec().PrependPathComponent(m_sdk_sysroot); // Try to get shared module with resolved spec. - error = ModuleList::GetSharedModule(resolved_spec, module_sp, - module_search_paths_ptr, old_modules, + error = ModuleList::GetSharedModule(resolved_spec, module_sp, old_modules, did_create_ptr, false); } // If we don't have sysroot or it didn't work then // try original module spec. if (!error.Success()) { resolved_spec = spec; - error = ModuleList::GetSharedModule(resolved_spec, module_sp, - module_search_paths_ptr, old_modules, + error = ModuleList::GetSharedModule(resolved_spec, module_sp, old_modules, did_create_ptr, false); } if (error.Success() && module_sp) @@ -731,10 +730,8 @@ bool Platform::SetOSVersion(llvm::VersionTuple version) { return false; } -Status -Platform::ResolveExecutable(const ModuleSpec &module_spec, - lldb::ModuleSP &exe_module_sp, - const FileSpecList *module_search_paths_ptr) { +Status Platform::ResolveExecutable(const ModuleSpec &module_spec, + lldb::ModuleSP &exe_module_sp) { // We may connect to a process and use the provided executable (Don't use // local $PATH). @@ -750,20 +747,16 @@ Platform::ResolveExecutable(const ModuleSpec &module_spec, if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid()) { - // Call locate module callback first to give it a chance to find/register - // symbol file specs for the main executable, similar to how shared - // libraries are handled in Platform::GetRemoteSharedModule() - FileSpec symbol_file_spec; - CallLocateModuleCallbackIfSet(resolved_module_spec, exe_module_sp, - symbol_file_spec, nullptr); + Status error = + ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, + nullptr, nullptr); Status error; if (!exe_module_sp) { // If locate module callback didn't provide a module, fallback to standard // path error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, - module_search_paths_ptr, nullptr, - nullptr); + nullptr, nullptr); } if (exe_module_sp && exe_module_sp->GetObjectFile()) { @@ -785,6 +778,7 @@ Platform::ResolveExecutable(const ModuleSpec &module_spec, Status error; for (const ArchSpec &arch : GetSupportedArchitectures(process_host_arch)) { resolved_module_spec.GetArchitecture() = arch; +<<<<<<< Updated upstream // Call locate module callback first, then fallback to standard path FileSpec symbol_file_spec; @@ -793,10 +787,14 @@ Platform::ResolveExecutable(const ModuleSpec &module_spec, if (!exe_module_sp) { error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, - module_search_paths_ptr, nullptr, - nullptr); + nullptr, nullptr); } +======= + error = + ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, + nullptr, nullptr); +>>>>>>> Stashed changes if (error.Success()) { if (exe_module_sp && exe_module_sp->GetObjectFile()) { // Set the symbol file if locate module callback returned one @@ -1478,16 +1476,13 @@ const std::vector &Platform::GetTrapHandlerSymbolNames() { return m_trap_handlers; } -Status -Platform::GetCachedExecutable(ModuleSpec &module_spec, - lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr) { +Status Platform::GetCachedExecutable(ModuleSpec &module_spec, + lldb::ModuleSP &module_sp) { FileSpec platform_spec = module_spec.GetFileSpec(); Status error = GetRemoteSharedModule( module_spec, nullptr, module_sp, [&](const ModuleSpec &spec) { - return Platform::ResolveExecutable(spec, module_sp, - module_search_paths_ptr); + return Platform::ResolveExecutable(spec, module_sp); }, nullptr); if (error.Success()) { @@ -1529,7 +1524,7 @@ Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec, for (const ArchSpec &arch : GetSupportedArchitectures(process_host_arch)) { arch_module_spec.GetArchitecture() = arch; error = ModuleList::GetSharedModule(arch_module_spec, module_sp, nullptr, - nullptr, nullptr); + nullptr); // Did we find an executable using one of the if (error.Success() && module_sp) break; @@ -1709,7 +1704,7 @@ void Platform::CallLocateModuleCallbackIfSet(const ModuleSpec &module_spec, cached_module_spec.SetObjectOffset(0); error = ModuleList::GetSharedModule(cached_module_spec, module_sp, nullptr, - nullptr, did_create_ptr, false); + did_create_ptr, false); if (error.Success() && module_sp) { // Succeeded to load the module file. LLDB_LOGF(log, "%s: locate module callback succeeded: module=%s symbol=%s", diff --git a/lldb/source/Target/RemoteAwarePlatform.cpp b/lldb/source/Target/RemoteAwarePlatform.cpp index cac738ea67b4c..89b946ba75162 100644 --- a/lldb/source/Target/RemoteAwarePlatform.cpp +++ b/lldb/source/Target/RemoteAwarePlatform.cpp @@ -29,9 +29,8 @@ bool RemoteAwarePlatform::GetModuleSpec(const FileSpec &module_file_spec, return false; } -Status RemoteAwarePlatform::ResolveExecutable( - const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp, - const FileSpecList *module_search_paths_ptr) { +Status RemoteAwarePlatform::ResolveExecutable(const ModuleSpec &module_spec, + lldb::ModuleSP &exe_module_sp) { ModuleSpec resolved_module_spec(module_spec); // The host platform can resolve the path more aggressively. @@ -47,12 +46,10 @@ Status RemoteAwarePlatform::ResolveExecutable( if (!FileSystem::Instance().Exists(resolved_file_spec)) FileSystem::Instance().ResolveExecutableLocation(resolved_file_spec); } else if (m_remote_platform_sp) { - return GetCachedExecutable(resolved_module_spec, exe_module_sp, - module_search_paths_ptr); + return GetCachedExecutable(resolved_module_spec, exe_module_sp); } - return Platform::ResolveExecutable(resolved_module_spec, exe_module_sp, - module_search_paths_ptr); + return Platform::ResolveExecutable(resolved_module_spec, exe_module_sp); } Status RemoteAwarePlatform::RunShellCommand( diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index fa98c24606492..e49ec2ab99a76 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -1773,9 +1773,9 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform, arch_spec.GetArchitectureName(), arch_spec.GetTriple().getTriple().c_str()); ModuleSpec module_spec(executable_sp->GetFileSpec(), other); - FileSpecList search_paths = GetExecutableSearchPaths(); + module_spec.SetTarget(this); Status error = ModuleList::GetSharedModule(module_spec, executable_sp, - &search_paths, nullptr, nullptr); + nullptr, nullptr); if (!error.Fail() && executable_sp) { SetExecutableModule(executable_sp, eLoadDependentsYes); @@ -2344,6 +2344,7 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &orig_module_spec, // Apply any remappings specified in target.object-map: ModuleSpec module_spec(orig_module_spec); + module_spec.SetTarget(this); PathMappingList &obj_mapping = GetObjectPathMap(); if (std::optional remapped_obj_file = obj_mapping.RemapPath(orig_module_spec.GetFileSpec().GetPath(), @@ -2402,9 +2403,9 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &orig_module_spec, transformed_spec.GetFileSpec().SetDirectory(transformed_dir); transformed_spec.GetFileSpec().SetFilename( module_spec.GetFileSpec().GetFilename()); + transformed_spec.SetTarget(this); error = ModuleList::GetSharedModule(transformed_spec, module_sp, - &search_paths, &old_modules, - &did_create_module); + &old_modules, &did_create_module); } } } @@ -2420,9 +2421,8 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &orig_module_spec, // cache. if (module_spec.GetUUID().IsValid()) { // We have a UUID, it is OK to check the global module list... - error = - ModuleList::GetSharedModule(module_spec, module_sp, &search_paths, - &old_modules, &did_create_module); + error = ModuleList::GetSharedModule(module_spec, module_sp, + &old_modules, &did_create_module); } if (!module_sp) { @@ -2430,8 +2430,8 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &orig_module_spec, // module in the shared module cache. if (m_platform_sp) { error = m_platform_sp->GetSharedModule( - module_spec, m_process_sp.get(), module_sp, &search_paths, - &old_modules, &did_create_module); + module_spec, m_process_sp.get(), module_sp, &old_modules, + &did_create_module); } else { error = Status::FromErrorString("no platform is currently set"); } diff --git a/lldb/source/Target/TargetList.cpp b/lldb/source/Target/TargetList.cpp index 7037dc2bea3cc..48a5d2f33793b 100644 --- a/lldb/source/Target/TargetList.cpp +++ b/lldb/source/Target/TargetList.cpp @@ -304,13 +304,9 @@ Status TargetList::CreateTargetInternal(Debugger &debugger, ModuleSP exe_module_sp; if (platform_sp) { - FileSpecList executable_search_paths( - Target::GetDefaultExecutableSearchPaths()); ModuleSpec module_spec(file, arch); - error = platform_sp->ResolveExecutable(module_spec, exe_module_sp, - executable_search_paths.GetSize() - ? &executable_search_paths - : nullptr); + module_spec.SetTarget(target_sp.get()); + error = platform_sp->ResolveExecutable(module_spec, exe_module_sp); } if (error.Success() && exe_module_sp) { diff --git a/lldb/unittests/Target/RemoteAwarePlatformTest.cpp b/lldb/unittests/Target/RemoteAwarePlatformTest.cpp index 3278674ed0a05..408739a4962f3 100644 --- a/lldb/unittests/Target/RemoteAwarePlatformTest.cpp +++ b/lldb/unittests/Target/RemoteAwarePlatformTest.cpp @@ -32,15 +32,13 @@ class RemoteAwarePlatformTester : public RemoteAwarePlatform { ProcessSP(ProcessAttachInfo &, Debugger &, Target *, Status &)); MOCK_METHOD0(CalculateTrapHandlerSymbolNames, void()); - MOCK_METHOD2(ResolveExecutable, - std::pair(const ModuleSpec &, - const FileSpecList *)); + MOCK_METHOD1(ResolveExecutable, + std::pair(const ModuleSpec &)); Status ResolveExecutable(const ModuleSpec &module_spec, - lldb::ModuleSP &exe_module_sp, - const FileSpecList *module_search_paths_ptr) /*override*/ + lldb::ModuleSP &exe_module_sp) /*override*/ { // NOLINT(modernize-use-override) - auto pair = ResolveExecutable(module_spec, module_search_paths_ptr); + auto pair = ResolveExecutable(module_spec); exe_module_sp = pair.second; return pair.first ? Status() : Status::FromErrorString("error"); } @@ -80,14 +78,14 @@ TEST_F(RemoteAwarePlatformTest, TestResolveExecutabelOnClientByPlatform) { static const ArchSpec process_host_arch; EXPECT_CALL(platform, GetSupportedArchitectures(process_host_arch)) .WillRepeatedly(Return(std::vector())); - EXPECT_CALL(platform, ResolveExecutable(_, _)) + EXPECT_CALL(platform, ResolveExecutable(_)) .WillRepeatedly(Return(std::make_pair(true, expected_executable))); platform.SetRemotePlatform(std::make_shared(false)); ModuleSP resolved_sp; lldb_private::Status status = - platform.ResolveExecutable(executable_spec, resolved_sp, nullptr); + platform.ResolveExecutable(executable_spec, resolved_sp); ASSERT_TRUE(status.Success()); EXPECT_EQ(expected_executable.get(), resolved_sp.get()); From 1c8dcac7c994a7b94b537e03b0ce6aa99421209e Mon Sep 17 00:00:00 2001 From: George Hu Date: Fri, 26 Sep 2025 16:51:00 -0700 Subject: [PATCH 3/7] Revert "Call locate module callback for main executable" This reverts commit c6534a14078ee8644c2403d51e9df613cddce22b. --- lldb/source/Target/Platform.cpp | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp index a61f55e6395c0..28802e0b39116 100644 --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -751,22 +751,8 @@ Status Platform::ResolveExecutable(const ModuleSpec &module_spec, ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, nullptr, nullptr); - Status error; - if (!exe_module_sp) { - // If locate module callback didn't provide a module, fallback to standard - // path - error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, - nullptr, nullptr); - } - - if (exe_module_sp && exe_module_sp->GetObjectFile()) { - // Set the symbol file if locate module callback returned one - if (symbol_file_spec) { - exe_module_sp->SetSymbolFileFileSpec(symbol_file_spec); - } - return error; // Return the actual status from GetSharedModule (or success - // from callback) - } + if (exe_module_sp && exe_module_sp->GetObjectFile()) + return error; exe_module_sp.reset(); } // No valid architecture was specified or the exact arch wasn't found. @@ -778,7 +764,6 @@ Status Platform::ResolveExecutable(const ModuleSpec &module_spec, Status error; for (const ArchSpec &arch : GetSupportedArchitectures(process_host_arch)) { resolved_module_spec.GetArchitecture() = arch; -<<<<<<< Updated upstream // Call locate module callback first, then fallback to standard path FileSpec symbol_file_spec; @@ -790,19 +775,12 @@ Status Platform::ResolveExecutable(const ModuleSpec &module_spec, nullptr, nullptr); } -======= error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, nullptr, nullptr); ->>>>>>> Stashed changes if (error.Success()) { - if (exe_module_sp && exe_module_sp->GetObjectFile()) { - // Set the symbol file if locate module callback returned one - if (symbol_file_spec) { - exe_module_sp->SetSymbolFileFileSpec(symbol_file_spec); - } + if (exe_module_sp && exe_module_sp->GetObjectFile()) break; - } error = Status::FromErrorString("no exe object file"); } From cfe7d17fa4d24e8d614055268d963bab347acf9a Mon Sep 17 00:00:00 2001 From: George Hu Date: Fri, 26 Sep 2025 17:24:09 -0700 Subject: [PATCH 4/7] [lldb] Enable locate module callback in GetSharedModule --- lldb/include/lldb/Core/ModuleList.h | 3 ++- lldb/include/lldb/Core/ModuleSpec.h | 20 +++++++++++----- lldb/source/Core/DynamicLoader.cpp | 2 +- lldb/source/Core/ModuleList.cpp | 24 +++++++++++++++++-- .../DynamicLoaderDarwinKernel.cpp | 2 +- .../POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp | 2 +- .../Process/elf-core/ProcessElfCore.cpp | 2 +- .../Process/mach-core/ProcessMachCore.cpp | 2 +- lldb/source/Target/Platform.cpp | 13 +++++----- lldb/source/Target/Target.cpp | 6 ++--- lldb/source/Target/TargetList.cpp | 2 +- .../Target/LocateModuleCallbackTest.cpp | 20 ++++++++-------- .../Target/RemoteAwarePlatformTest.cpp | 5 ++-- 13 files changed, 65 insertions(+), 38 deletions(-) diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h index c538eef699ed9..cd511ee8117e7 100644 --- a/lldb/include/lldb/Core/ModuleList.h +++ b/lldb/include/lldb/Core/ModuleList.h @@ -477,7 +477,8 @@ class ModuleList { static Status GetSharedModule(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, llvm::SmallVectorImpl *old_modules, - bool *did_create_ptr, bool always_create = false); + bool *did_create_ptr, bool always_create = false, + bool allow_locate_callback = true); static bool RemoveSharedModule(lldb::ModuleSP &module_sp); diff --git a/lldb/include/lldb/Core/ModuleSpec.h b/lldb/include/lldb/Core/ModuleSpec.h index fbbab299d86cd..5c1e3877a736f 100644 --- a/lldb/include/lldb/Core/ModuleSpec.h +++ b/lldb/include/lldb/Core/ModuleSpec.h @@ -19,6 +19,7 @@ #include "llvm/Support/Chrono.h" +#include #include #include @@ -126,11 +127,17 @@ class ModuleSpec { lldb::DataBufferSP GetData() const { return m_data; } - Target *GetTargetPtr() { return m_target; } + Target *GetTargetPtr() { + auto locked = m_target.lock(); + return locked.get(); + } - const Target *GetTargetPtr() const { return m_target; } + const Target *GetTargetPtr() const { + auto locked = m_target.lock(); + return locked.get(); + } - void SetTarget(Target *target) { m_target = target; } + void SetTarget(std::shared_ptr target) { m_target = target; } void Clear() { m_file.Clear(); @@ -143,7 +150,7 @@ class ModuleSpec { m_object_size = 0; m_source_mappings.Clear(false); m_object_mod_time = llvm::sys::TimePoint<>(); - m_target = nullptr; + m_target.reset(); } explicit operator bool() const { @@ -272,8 +279,9 @@ class ModuleSpec { ArchSpec m_arch; UUID m_uuid; ConstString m_object_name; - Target *m_target; // This is set to take advantage of the target's search path - // and platform's locate module callback + std::weak_ptr + m_target; // This is set to take advantage of the target's search path + // and platform's locate module callback uint64_t m_object_offset = 0; uint64_t m_object_size = 0; llvm::sys::TimePoint<> m_object_mod_time; diff --git a/lldb/source/Core/DynamicLoader.cpp b/lldb/source/Core/DynamicLoader.cpp index 52f9c3cd5e5a6..b309e0f0a72fd 100644 --- a/lldb/source/Core/DynamicLoader.cpp +++ b/lldb/source/Core/DynamicLoader.cpp @@ -227,7 +227,7 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress( } } ModuleSpec module_spec; - module_spec.SetTarget(&target); + module_spec.SetTarget(target.shared_from_this()); module_spec.GetUUID() = uuid; FileSpec name_filespec(name); if (FileSystem::Instance().Exists(name_filespec)) diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index f38c2d03f85d3..4d28c88a53d6e 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -19,6 +19,7 @@ #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/TypeList.h" #include "lldb/Symbol/VariableList.h" +#include "lldb/Target/Platform.h" #include "lldb/Target/Target.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/ConstString.h" @@ -1031,7 +1032,8 @@ size_t ModuleList::RemoveOrphanSharedModules(bool mandatory) { Status ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp, llvm::SmallVectorImpl *old_modules, - bool *did_create_ptr, bool always_create) { + bool *did_create_ptr, bool always_create, + bool allow_locate_callback) { ModuleList &shared_module_list = GetSharedModuleList(); std::lock_guard guard( shared_module_list.m_modules_mutex); @@ -1087,6 +1089,24 @@ ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp, if (module_sp) return error; + // Try target's platform locate module callback before second attempt + if (allow_locate_callback) { + ModuleSpec module_spec_copy(module_spec); + Target *target = module_spec_copy.GetTargetPtr(); + if (target && target->IsValid()) { + Platform *platform = target->GetPlatform().get(); + if (platform) { + FileSpec symbol_file_spec; + platform->CallLocateModuleCallbackIfSet( + module_spec, module_sp, symbol_file_spec, did_create_ptr); + if (module_sp) { + // Success! The callback found a module + return error; + } + } + } + } + module_sp = std::make_shared(module_spec); // Make sure there are a module and an object file since we can specify a // valid file path with an architecture that might not be in that file. By @@ -1119,7 +1139,7 @@ ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp, Target *target = module_spec_copy.GetTargetPtr(); FileSpecList module_search_paths; FileSpecList *module_search_paths_ptr = nullptr; - if (target) { + if (target && target->IsValid()) { module_search_paths = target->GetExecutableSearchPaths(); module_search_paths_ptr = &module_search_paths; } diff --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp index 3d0b41c452a11..2d0a4f67499ee 100644 --- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp +++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp @@ -789,7 +789,7 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule( // Search for the kext on the local filesystem via the UUID if (!m_module_sp && m_uuid.IsValid()) { ModuleSpec module_spec; - module_spec.SetTarget(&target); + module_spec.SetTarget(target.shared_from_this()); module_spec.GetUUID() = m_uuid; if (!m_uuid.IsValid()) module_spec.GetArchitecture() = target.GetArchitecture(); diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index 5f365878acdc6..470fc2a2fdbb9 100644 --- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -901,7 +901,7 @@ void DynamicLoaderPOSIXDYLD::ResolveExecutableModule( if (module_sp && module_sp->MatchesModuleSpec(module_spec)) return; - module_spec.SetTarget(&target); + module_spec.SetTarget(target.shared_from_this()); const auto executable_search_paths(Target::GetDefaultExecutableSearchPaths()); auto error = platform_sp->ResolveExecutable(module_spec, module_sp); if (error.Fail()) { diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index cb47a5e0a2766..f8e33eac614a4 100644 --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -84,7 +84,7 @@ bool ProcessElfCore::CanDebug(lldb::TargetSP target_sp, // For now we are just making sure the file exists for a given module if (!m_core_module_sp && FileSystem::Instance().Exists(m_core_file)) { ModuleSpec core_module_spec(m_core_file, target_sp->GetArchitecture()); - core_module_spec.SetTarget(target_sp.get()); + core_module_spec.SetTarget(target_sp); Status error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp, nullptr, nullptr)); if (m_core_module_sp) { diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp index 7352b8e63f19a..83d684e9ca528 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp @@ -95,7 +95,7 @@ bool ProcessMachCore::CanDebug(lldb::TargetSP target_sp, // header but we should still try to use it - // ModuleSpecList::FindMatchingModuleSpec enforces a strict arch mach. ModuleSpec core_module_spec(m_core_file); - core_module_spec.SetTarget(target_sp.get()); + core_module_spec.SetTarget(target_sp); Status error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp, nullptr, nullptr)); diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp index 28802e0b39116..5db6e05717e14 100644 --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -747,9 +747,8 @@ Status Platform::ResolveExecutable(const ModuleSpec &module_spec, if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid()) { - Status error = - ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, - nullptr, nullptr); + Status error = ModuleList::GetSharedModule(resolved_module_spec, + exe_module_sp, nullptr, nullptr); if (exe_module_sp && exe_module_sp->GetObjectFile()) return error; @@ -775,9 +774,8 @@ Status Platform::ResolveExecutable(const ModuleSpec &module_spec, nullptr, nullptr); } - error = - ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, - nullptr, nullptr); + error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, + nullptr, nullptr); if (error.Success()) { if (exe_module_sp && exe_module_sp->GetObjectFile()) break; @@ -1678,11 +1676,12 @@ void Platform::CallLocateModuleCallbackIfSet(const ModuleSpec &module_spec, cached_module_spec.GetUUID().Clear(); // Clear UUID since it may contain md5 // content hash instead of real UUID. cached_module_spec.GetFileSpec() = module_file_spec; + cached_module_spec.GetSymbolFileSpec() = symbol_file_spec; cached_module_spec.GetPlatformFileSpec() = module_spec.GetFileSpec(); cached_module_spec.SetObjectOffset(0); error = ModuleList::GetSharedModule(cached_module_spec, module_sp, nullptr, - did_create_ptr, false); + did_create_ptr, false, false); if (error.Success() && module_sp) { // Succeeded to load the module file. LLDB_LOGF(log, "%s: locate module callback succeeded: module=%s symbol=%s", diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index e49ec2ab99a76..9d0d3614353f0 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -1773,7 +1773,7 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform, arch_spec.GetArchitectureName(), arch_spec.GetTriple().getTriple().c_str()); ModuleSpec module_spec(executable_sp->GetFileSpec(), other); - module_spec.SetTarget(this); + module_spec.SetTarget(this->shared_from_this()); Status error = ModuleList::GetSharedModule(module_spec, executable_sp, nullptr, nullptr); @@ -2344,7 +2344,7 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &orig_module_spec, // Apply any remappings specified in target.object-map: ModuleSpec module_spec(orig_module_spec); - module_spec.SetTarget(this); + module_spec.SetTarget(this->shared_from_this()); PathMappingList &obj_mapping = GetObjectPathMap(); if (std::optional remapped_obj_file = obj_mapping.RemapPath(orig_module_spec.GetFileSpec().GetPath(), @@ -2403,7 +2403,7 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &orig_module_spec, transformed_spec.GetFileSpec().SetDirectory(transformed_dir); transformed_spec.GetFileSpec().SetFilename( module_spec.GetFileSpec().GetFilename()); - transformed_spec.SetTarget(this); + transformed_spec.SetTarget(this->shared_from_this()); error = ModuleList::GetSharedModule(transformed_spec, module_sp, &old_modules, &did_create_module); } diff --git a/lldb/source/Target/TargetList.cpp b/lldb/source/Target/TargetList.cpp index 48a5d2f33793b..8d2c1cc861128 100644 --- a/lldb/source/Target/TargetList.cpp +++ b/lldb/source/Target/TargetList.cpp @@ -305,7 +305,7 @@ Status TargetList::CreateTargetInternal(Debugger &debugger, ModuleSP exe_module_sp; if (platform_sp) { ModuleSpec module_spec(file, arch); - module_spec.SetTarget(target_sp.get()); + module_spec.SetTarget(target_sp); error = platform_sp->ResolveExecutable(module_spec, exe_module_sp); } diff --git a/lldb/unittests/Target/LocateModuleCallbackTest.cpp b/lldb/unittests/Target/LocateModuleCallbackTest.cpp index 6ffa41b16b4ff..d727cea9f6eae 100644 --- a/lldb/unittests/Target/LocateModuleCallbackTest.cpp +++ b/lldb/unittests/Target/LocateModuleCallbackTest.cpp @@ -362,7 +362,7 @@ TEST_F(LocateModuleCallbackTest, GetOrCreateModuleCallbackFailureNoCache) { }); m_module_sp = m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false); - ASSERT_EQ(callback_call_count, 2); + ASSERT_EQ(callback_call_count, 3); ASSERT_FALSE(m_module_sp); } @@ -383,7 +383,7 @@ TEST_F(LocateModuleCallbackTest, GetOrCreateModuleCallbackFailureCached) { }); m_module_sp = m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false); - ASSERT_EQ(callback_call_count, 2); + ASSERT_EQ(callback_call_count, 3); CheckModule(m_module_sp); ASSERT_EQ(m_module_sp->GetFileSpec(), uuid_view); ASSERT_FALSE(m_module_sp->GetSymbolFileFileSpec()); @@ -409,7 +409,7 @@ TEST_F(LocateModuleCallbackTest, GetOrCreateModuleCallbackNoFiles) { }); m_module_sp = m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false); - ASSERT_EQ(callback_call_count, 2); + ASSERT_EQ(callback_call_count, 3); CheckModule(m_module_sp); ASSERT_EQ(m_module_sp->GetFileSpec(), uuid_view); ASSERT_FALSE(m_module_sp->GetSymbolFileFileSpec()); @@ -435,7 +435,7 @@ TEST_F(LocateModuleCallbackTest, GetOrCreateModuleCallbackNonExistentModule) { }); m_module_sp = m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false); - ASSERT_EQ(callback_call_count, 2); + ASSERT_EQ(callback_call_count, 3); CheckModule(m_module_sp); ASSERT_EQ(m_module_sp->GetFileSpec(), uuid_view); ASSERT_FALSE(m_module_sp->GetSymbolFileFileSpec()); @@ -464,7 +464,7 @@ TEST_F(LocateModuleCallbackTest, GetOrCreateModuleCallbackNonExistentSymbol) { }); m_module_sp = m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false); - ASSERT_EQ(callback_call_count, 2); + ASSERT_EQ(callback_call_count, 3); CheckModule(m_module_sp); ASSERT_EQ(m_module_sp->GetFileSpec(), uuid_view); ASSERT_TRUE(m_module_sp->GetSymbolFileFileSpec().GetPath().empty()); @@ -622,7 +622,7 @@ TEST_F(LocateModuleCallbackTest, }); m_module_sp = m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false); - ASSERT_EQ(callback_call_count, 2); + ASSERT_EQ(callback_call_count, 3); CheckModule(m_module_sp); ASSERT_EQ(m_module_sp->GetFileSpec(), uuid_view); ASSERT_EQ(m_module_sp->GetSymbolFileFileSpec(), @@ -650,7 +650,7 @@ TEST_F(LocateModuleCallbackTest, }); m_module_sp = m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false); - ASSERT_EQ(callback_call_count, 2); + ASSERT_EQ(callback_call_count, 3); CheckModule(m_module_sp); ASSERT_EQ(m_module_sp->GetFileSpec(), uuid_view); ASSERT_EQ(m_module_sp->GetSymbolFileFileSpec(), @@ -682,7 +682,7 @@ TEST_F(LocateModuleCallbackTest, }); m_module_sp = m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false); - ASSERT_EQ(callback_call_count, 2); + ASSERT_EQ(callback_call_count, 3); CheckModule(m_module_sp); ASSERT_EQ(m_module_sp->GetFileSpec(), uuid_view); ASSERT_EQ(m_module_sp->GetSymbolFileFileSpec(), @@ -709,7 +709,7 @@ TEST_F(LocateModuleCallbackTest, }); m_module_sp = m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false); - ASSERT_EQ(callback_call_count, 2); + ASSERT_EQ(callback_call_count, 3); ASSERT_FALSE(m_module_sp); } @@ -731,7 +731,7 @@ TEST_F(LocateModuleCallbackTest, }); m_module_sp = m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false); - ASSERT_EQ(callback_call_count, 2); + ASSERT_EQ(callback_call_count, 3); ASSERT_FALSE(m_module_sp); } diff --git a/lldb/unittests/Target/RemoteAwarePlatformTest.cpp b/lldb/unittests/Target/RemoteAwarePlatformTest.cpp index 408739a4962f3..cfcec693b8742 100644 --- a/lldb/unittests/Target/RemoteAwarePlatformTest.cpp +++ b/lldb/unittests/Target/RemoteAwarePlatformTest.cpp @@ -34,9 +34,8 @@ class RemoteAwarePlatformTester : public RemoteAwarePlatform { MOCK_METHOD1(ResolveExecutable, std::pair(const ModuleSpec &)); - Status - ResolveExecutable(const ModuleSpec &module_spec, - lldb::ModuleSP &exe_module_sp) /*override*/ + Status ResolveExecutable(const ModuleSpec &module_spec, + lldb::ModuleSP &exe_module_sp) /*override*/ { // NOLINT(modernize-use-override) auto pair = ResolveExecutable(module_spec); exe_module_sp = pair.second; From 23f1b986977fa55bba479bcd9c91fe8b3928f21a Mon Sep 17 00:00:00 2001 From: George Hu Date: Thu, 2 Oct 2025 16:54:48 -0700 Subject: [PATCH 5/7] Address comment --- lldb/include/lldb/Core/ModuleList.h | 2 +- lldb/include/lldb/Core/ModuleSpec.h | 11 ++---- lldb/source/Core/ModuleList.cpp | 27 +++++++------- .../Platform/MacOSX/PlatformDarwin.cpp | 36 ++++++++----------- lldb/source/Target/Platform.cpp | 5 ++- 5 files changed, 33 insertions(+), 48 deletions(-) diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h index cd511ee8117e7..1f8e3d191df99 100644 --- a/lldb/include/lldb/Core/ModuleList.h +++ b/lldb/include/lldb/Core/ModuleList.h @@ -478,7 +478,7 @@ class ModuleList { GetSharedModule(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr, bool always_create = false, - bool allow_locate_callback = true); + bool invoke_locate_callback = true); static bool RemoveSharedModule(lldb::ModuleSP &module_sp); diff --git a/lldb/include/lldb/Core/ModuleSpec.h b/lldb/include/lldb/Core/ModuleSpec.h index 5c1e3877a736f..a9e504c7768a6 100644 --- a/lldb/include/lldb/Core/ModuleSpec.h +++ b/lldb/include/lldb/Core/ModuleSpec.h @@ -16,6 +16,7 @@ #include "lldb/Utility/Iterable.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/UUID.h" +#include "lldb/lldb-forward.h" #include "llvm/Support/Chrono.h" @@ -127,15 +128,9 @@ class ModuleSpec { lldb::DataBufferSP GetData() const { return m_data; } - Target *GetTargetPtr() { - auto locked = m_target.lock(); - return locked.get(); - } + lldb::TargetSP GetTargetSP() { return m_target.lock(); } - const Target *GetTargetPtr() const { - auto locked = m_target.lock(); - return locked.get(); - } + lldb::TargetSP GetTargetSP() const { return m_target.lock(); } void SetTarget(std::shared_ptr target) { m_target = target; } diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index 4d28c88a53d6e..6cb787b875989 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -1033,7 +1033,7 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr, bool always_create, - bool allow_locate_callback) { + bool invoke_locate_callback) { ModuleList &shared_module_list = GetSharedModuleList(); std::lock_guard guard( shared_module_list.m_modules_mutex); @@ -1089,18 +1089,16 @@ ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp, if (module_sp) return error; - // Try target's platform locate module callback before second attempt - if (allow_locate_callback) { - ModuleSpec module_spec_copy(module_spec); - Target *target = module_spec_copy.GetTargetPtr(); - if (target && target->IsValid()) { - Platform *platform = target->GetPlatform().get(); - if (platform) { + // Try target's platform locate module callback before second attempt. + if (invoke_locate_callback) { + TargetSP target_sp = module_spec.GetTargetSP(); + if (target_sp && target_sp->IsValid()) { + if (PlatformSP platform_sp = target_sp->GetPlatform()) { FileSpec symbol_file_spec; - platform->CallLocateModuleCallbackIfSet( + platform_sp->CallLocateModuleCallbackIfSet( module_spec, module_sp, symbol_file_spec, did_create_ptr); if (module_sp) { - // Success! The callback found a module + // The callback found a module. return error; } } @@ -1134,13 +1132,12 @@ ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp, module_sp.reset(); } - // Get module search paths from the target if available - ModuleSpec module_spec_copy(module_spec); - Target *target = module_spec_copy.GetTargetPtr(); + // Get module search paths from the target if available. + lldb::TargetSP target_sp = module_spec.GetTargetSP(); FileSpecList module_search_paths; FileSpecList *module_search_paths_ptr = nullptr; - if (target && target->IsValid()) { - module_search_paths = target->GetExecutableSearchPaths(); + if (target_sp && target_sp->IsValid()) { + module_search_paths = target_sp->GetExecutableSearchPaths(); module_search_paths_ptr = &module_search_paths; } diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index a0e1f9e307219..9ddc4488f62d0 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -350,16 +350,13 @@ Status PlatformDarwin::GetSharedModule( old_modules, did_create_ptr); const FileSpec &platform_file = module_spec.GetFileSpec(); - // Get module search paths from the target if available - ModuleSpec module_spec_copy(module_spec); - Target *target = module_spec_copy.GetTargetPtr(); + // Get module search paths from the target if available. + TargetSP target_sp = module_spec.GetTargetSP(); FileSpecList module_search_paths; - FileSpecList *module_search_paths_ptr = nullptr; - if (target) { - module_search_paths = target->GetExecutableSearchPaths(); - module_search_paths_ptr = &module_search_paths; + if (target_sp) { + module_search_paths = target_sp->GetExecutableSearchPaths(); } - if (!module_sp && module_search_paths_ptr && platform_file) { + if (!module_sp && !module_search_paths.IsEmpty() && platform_file) { // We can try to pull off part of the file path up to the bundle // directory level and try any module search paths... FileSpec bundle_directory; @@ -382,10 +379,10 @@ Status PlatformDarwin::GetSharedModule( const size_t bundle_directory_len = bundle_directory.GetPath(bundle_dir, sizeof(bundle_dir)); char new_path[PATH_MAX]; - size_t num_module_search_paths = module_search_paths_ptr->GetSize(); + size_t num_module_search_paths = module_search_paths.GetSize(); for (size_t i = 0; i < num_module_search_paths; ++i) { const size_t search_path_len = - module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath( + module_search_paths.GetFileSpecAtIndex(i).GetPath( new_path, sizeof(new_path)); if (search_path_len < sizeof(new_path)) { snprintf(new_path + search_path_len, @@ -1311,17 +1308,14 @@ lldb_private::Status PlatformDarwin::FindBundleBinaryInExecSearchPaths( const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { const FileSpec &platform_file = module_spec.GetFileSpec(); - ModuleSpec module_spec_copy(module_spec); - Target *target = module_spec_copy.GetTargetPtr(); + TargetSP target_sp = module_spec.GetTargetSP(); FileSpecList module_search_paths; - FileSpecList *module_search_paths_ptr = nullptr; - if (target) { - module_search_paths = target->GetExecutableSearchPaths(); - module_search_paths_ptr = &module_search_paths; + if (target_sp) { + module_search_paths = target_sp->GetExecutableSearchPaths(); } - // See if the file is present in any of the module_search_paths_ptr + // See if the file is present in any of the module_search_paths // directories. - if (!module_sp && module_search_paths_ptr && platform_file) { + if (!module_sp && !module_search_paths.IsEmpty() && platform_file) { // create a vector of all the file / directory names in platform_file e.g. // this might be // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation @@ -1335,21 +1329,21 @@ lldb_private::Status PlatformDarwin::FindBundleBinaryInExecSearchPaths( std::reverse(path_parts.begin(), path_parts.end()); const size_t path_parts_size = path_parts.size(); - size_t num_module_search_paths = module_search_paths_ptr->GetSize(); + size_t num_module_search_paths = module_search_paths.GetSize(); for (size_t i = 0; i < num_module_search_paths; ++i) { Log *log_verbose = GetLog(LLDBLog::Host); LLDB_LOGF( log_verbose, "PlatformRemoteDarwinDevice::GetSharedModule searching for binary in " "search-path %s", - module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath().c_str()); + module_search_paths.GetFileSpecAtIndex(i).GetPath().c_str()); // Create a new FileSpec with this module_search_paths_ptr plus just the // filename ("UIFoundation"), then the parent dir plus filename // ("UIFoundation.framework/UIFoundation") etc - up to four names (to // handle "Foo.framework/Contents/MacOS/Foo") for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) { - FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i)); + FileSpec path_to_try(module_search_paths.GetFileSpecAtIndex(i)); // Add the components backwards. For // .../PrivateFrameworks/UIFoundation.framework/UIFoundation path_parts diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp index 5db6e05717e14..cd97cc43b8b8e 100644 --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -764,15 +764,14 @@ Status Platform::ResolveExecutable(const ModuleSpec &module_spec, for (const ArchSpec &arch : GetSupportedArchitectures(process_host_arch)) { resolved_module_spec.GetArchitecture() = arch; - // Call locate module callback first, then fallback to standard path + // Call locate module callback first, then fallback to standard path. FileSpec symbol_file_spec; CallLocateModuleCallbackIfSet(resolved_module_spec, exe_module_sp, symbol_file_spec, nullptr); - if (!exe_module_sp) { + if (!exe_module_sp) error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, nullptr, nullptr); - } error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, nullptr, nullptr); From f8a3cbb4ba0811b3215be16ad50e5165282dff13 Mon Sep 17 00:00:00 2001 From: George Hu Date: Tue, 14 Oct 2025 15:50:06 -0700 Subject: [PATCH 6/7] Code style fix --- lldb/include/lldb/Core/ModuleSpec.h | 6 +++--- lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp | 6 ++---- lldb/source/Target/Target.cpp | 6 +++--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/lldb/include/lldb/Core/ModuleSpec.h b/lldb/include/lldb/Core/ModuleSpec.h index a9e504c7768a6..6df4c7564ea4e 100644 --- a/lldb/include/lldb/Core/ModuleSpec.h +++ b/lldb/include/lldb/Core/ModuleSpec.h @@ -274,9 +274,9 @@ class ModuleSpec { ArchSpec m_arch; UUID m_uuid; ConstString m_object_name; - std::weak_ptr - m_target; // This is set to take advantage of the target's search path - // and platform's locate module callback + /// This is set to take advantage of the target's search path and platform's + /// locate module callback + std::weak_ptr m_target; uint64_t m_object_offset = 0; uint64_t m_object_size = 0; llvm::sys::TimePoint<> m_object_mod_time; diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index 9ddc4488f62d0..91bb339460a1d 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -353,9 +353,8 @@ Status PlatformDarwin::GetSharedModule( // Get module search paths from the target if available. TargetSP target_sp = module_spec.GetTargetSP(); FileSpecList module_search_paths; - if (target_sp) { + if (target_sp) module_search_paths = target_sp->GetExecutableSearchPaths(); - } if (!module_sp && !module_search_paths.IsEmpty() && platform_file) { // We can try to pull off part of the file path up to the bundle // directory level and try any module search paths... @@ -1310,9 +1309,8 @@ lldb_private::Status PlatformDarwin::FindBundleBinaryInExecSearchPaths( const FileSpec &platform_file = module_spec.GetFileSpec(); TargetSP target_sp = module_spec.GetTargetSP(); FileSpecList module_search_paths; - if (target_sp) { + if (target_sp) module_search_paths = target_sp->GetExecutableSearchPaths(); - } // See if the file is present in any of the module_search_paths // directories. if (!module_sp && !module_search_paths.IsEmpty() && platform_file) { diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 881637db562da..e4fb57f203935 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -1776,7 +1776,7 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform, arch_spec.GetArchitectureName(), arch_spec.GetTriple().getTriple().c_str()); ModuleSpec module_spec(executable_sp->GetFileSpec(), other); - module_spec.SetTarget(this->shared_from_this()); + module_spec.SetTarget(shared_from_this()); Status error = ModuleList::GetSharedModule(module_spec, executable_sp, nullptr, nullptr); @@ -2347,7 +2347,7 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &orig_module_spec, // Apply any remappings specified in target.object-map: ModuleSpec module_spec(orig_module_spec); - module_spec.SetTarget(this->shared_from_this()); + module_spec.SetTarget(shared_from_this()); PathMappingList &obj_mapping = GetObjectPathMap(); if (std::optional remapped_obj_file = obj_mapping.RemapPath(orig_module_spec.GetFileSpec().GetPath(), @@ -2406,7 +2406,7 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &orig_module_spec, transformed_spec.GetFileSpec().SetDirectory(transformed_dir); transformed_spec.GetFileSpec().SetFilename( module_spec.GetFileSpec().GetFilename()); - transformed_spec.SetTarget(this->shared_from_this()); + transformed_spec.SetTarget(shared_from_this()); error = ModuleList::GetSharedModule(transformed_spec, module_sp, &old_modules, &did_create_module); } From 8d6ef4d51f54ccfcd59cf21272efc4052653cdac Mon Sep 17 00:00:00 2001 From: George Hu Date: Tue, 14 Oct 2025 21:24:34 -0700 Subject: [PATCH 7/7] Add test --- lldb/unittests/Core/CMakeLists.txt | 1 + lldb/unittests/Core/ModuleListTest.cpp | 178 +++++++++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 lldb/unittests/Core/ModuleListTest.cpp diff --git a/lldb/unittests/Core/CMakeLists.txt b/lldb/unittests/Core/CMakeLists.txt index 6e609a63ad9b6..f0c9a9a9d5056 100644 --- a/lldb/unittests/Core/CMakeLists.txt +++ b/lldb/unittests/Core/CMakeLists.txt @@ -7,6 +7,7 @@ add_lldb_unittest(LLDBCoreTests DumpRegisterInfoTest.cpp FormatEntityTest.cpp MangledTest.cpp + ModuleListTest.cpp ModuleSpecTest.cpp PluginManagerTest.cpp ProgressReportTest.cpp diff --git a/lldb/unittests/Core/ModuleListTest.cpp b/lldb/unittests/Core/ModuleListTest.cpp new file mode 100644 index 0000000000000..3c70b0a4b21b8 --- /dev/null +++ b/lldb/unittests/Core/ModuleListTest.cpp @@ -0,0 +1,178 @@ +//===-- ModuleListTest.cpp ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/ModuleList.h" +#include "TestingSupport/SubsystemRAII.h" +#include "TestingSupport/TestUtilities.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/UUID.h" + +#include "Plugins/ObjectFile/ELF/ObjectFileELF.h" + +#include "gtest/gtest.h" + +using namespace lldb; +using namespace lldb_private; + +// Test that when we already have a module in the shared_module_list with a +// specific UUID, the next call to GetSharedModule with a module_spec with the +// same UUID should return the existing module instead of creating a new one. +TEST(ModuleListTest, GetSharedModuleReusesExistingModuleWithSameUUID) { + SubsystemRAII subsystems; + + auto ExpectedFile = TestFile::fromYaml(R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000010 +... +)"); + ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); + + // First, let's verify that calling GetSharedModule twice with the same + // module_spec returns the same module pointer + + ModuleSP first_module; + bool first_did_create = false; + Status error_first = + ModuleList::GetSharedModule(ExpectedFile->moduleSpec(), first_module, + nullptr, &first_did_create, false); + + // Second call with the same spec + ModuleSP second_module; + bool second_did_create = false; + Status error_second = + ModuleList::GetSharedModule(ExpectedFile->moduleSpec(), second_module, + nullptr, &second_did_create, false); + + if (error_first.Success() && error_second.Success()) { + // If both succeeded, verify they're the same module + EXPECT_EQ(first_module.get(), second_module.get()) + << "GetSharedModule should return the same module for the same spec"; + EXPECT_TRUE(first_did_create) << "First call should create the module"; + EXPECT_FALSE(second_did_create) + << "Second call should reuse the existing module"; + } +} + +// Test that UUID-based lookup finds existing modules +TEST(ModuleListTest, FindSharedModuleByUUID) { + SubsystemRAII subsystems; + + auto ExpectedFile = TestFile::fromYaml(R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000010 +... +)"); + ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); + + // Create and add a module to the shared module list using the moduleSpec() + ModuleSP created_module; + bool did_create = false; + Status error = ModuleList::GetSharedModule( + ExpectedFile->moduleSpec(), created_module, nullptr, &did_create, false); + + if (error.Success() && created_module) { + // Get the UUID of the created module + UUID module_uuid = created_module->GetUUID(); + + if (module_uuid.IsValid()) { + // Now try to find the module by UUID + ModuleSP found_module = ModuleList::FindSharedModule(module_uuid); + + ASSERT_NE(found_module.get(), nullptr) + << "FindSharedModule should find the module by UUID"; + EXPECT_EQ(found_module.get(), created_module.get()) + << "FindSharedModule should return the same module instance"; + EXPECT_EQ(found_module->GetUUID(), module_uuid) + << "Found module should have the same UUID"; + } + } +} + +// Test that GetSharedModule with UUID finds existing module even with different +// path +TEST(ModuleListTest, GetSharedModuleByUUIDIgnoresPath) { + SubsystemRAII subsystems; + + auto ExpectedFile = TestFile::fromYaml(R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000010 +... +)"); + ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); + + // Create and add a module to the shared module list + ModuleSP first_module; + bool first_did_create = false; + Status first_error = + ModuleList::GetSharedModule(ExpectedFile->moduleSpec(), first_module, + nullptr, &first_did_create, false); + + if (first_error.Success() && first_module) { + UUID module_uuid = first_module->GetUUID(); + + if (module_uuid.IsValid()) { + // Now try to get a module with the same UUID but different path + ModuleSpec second_spec; + second_spec.GetFileSpec() = FileSpec("/different/path/to/module.so"); + second_spec.GetArchitecture() = ArchSpec("x86_64-pc-linux"); + second_spec.GetUUID() = module_uuid; + + ModuleSP second_module; + bool second_did_create = false; + Status second_error = ModuleList::GetSharedModule( + second_spec, second_module, nullptr, &second_did_create, false); + + if (second_error.Success() && second_module) { + // If we got a module back, check if it's the same one + bool is_same_module = (second_module.get() == first_module.get()); + + // Document the behavior: ideally UUID should take precedence + // and return the existing module + EXPECT_TRUE(is_same_module) + << "GetSharedModule with matching UUID should return existing " + "module, " + << "even with different path (per PR #160199)"; + + if (is_same_module) { + EXPECT_FALSE(second_did_create) + << "Should not create a new module when UUID matches"; + } + } + } + } +}