Skip to content

Commit fce5889

Browse files
GeorgeHuyuboGeorge HuGeorge Hu
authored
[lldb] Enable locate module callback for all module loading (#160199)
Main executables were bypassing the locate module callback that shared libraries use, preventing custom symbol file location logic from working consistently. This PR fix this by * Adding target context to ModuleSpec * Leveraging that context to use target search path and platform's locate module callback in ModuleList::GetSharedModule This ensures both main executables and shared libraries get the same callback treatment for symbol file resolution. --------- Co-authored-by: George Hu <[email protected]> Co-authored-by: George Hu <[email protected]>
1 parent c12cb28 commit fce5889

36 files changed

+383
-178
lines changed

lldb/include/lldb/API/SBModuleSpec.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,16 @@ class LLDB_API SBModuleSpec {
8787

8888
bool GetDescription(lldb::SBStream &description);
8989

90+
lldb::SBTarget GetTarget();
91+
92+
/// Set the target to be used when resolving a module.
93+
///
94+
/// A target can help locate a module specified by a SBModuleSpec. The
95+
/// target settings, like the executable and debug info search paths, can
96+
/// be essential. The target's platform can also be used to locate or download
97+
/// the specified module.
98+
void SetTarget(lldb::SBTarget target);
99+
90100
private:
91101
friend class SBModuleSpecList;
92102
friend class SBModule;

lldb/include/lldb/API/SBTarget.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,7 @@ class LLDB_API SBTarget {
999999
friend class SBFunction;
10001000
friend class SBInstruction;
10011001
friend class SBModule;
1002+
friend class SBModuleSpec;
10021003
friend class SBPlatform;
10031004
friend class SBProcess;
10041005
friend class SBSection;

lldb/include/lldb/Core/ModuleList.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -476,9 +476,9 @@ class ModuleList {
476476

477477
static Status
478478
GetSharedModule(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
479-
const FileSpecList *module_search_paths_ptr,
480479
llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules,
481-
bool *did_create_ptr, bool always_create = false);
480+
bool *did_create_ptr, bool always_create = false,
481+
bool invoke_locate_callback = true);
482482

483483
static bool RemoveSharedModule(lldb::ModuleSP &module_sp);
484484

lldb/include/lldb/Core/ModuleSpec.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
#include "lldb/Utility/Iterable.h"
1717
#include "lldb/Utility/Stream.h"
1818
#include "lldb/Utility/UUID.h"
19+
#include "lldb/lldb-forward.h"
1920

2021
#include "llvm/Support/Chrono.h"
2122

23+
#include <memory>
2224
#include <mutex>
2325
#include <vector>
2426

@@ -126,6 +128,16 @@ class ModuleSpec {
126128

127129
lldb::DataBufferSP GetData() const { return m_data; }
128130

131+
lldb::TargetSP GetTargetSP() const { return m_target_wp.lock(); }
132+
133+
/// Set the target to be used when resolving a module.
134+
///
135+
/// A target can help locate a module specified by a ModuleSpec. The target
136+
/// settings, like the executable and debug info search paths, can be
137+
/// essential. The target's platform can also be used to locate or download
138+
/// the specified module.
139+
void SetTarget(std::shared_ptr<Target> target) { m_target_wp = target; }
140+
129141
void Clear() {
130142
m_file.Clear();
131143
m_platform_file.Clear();
@@ -137,6 +149,7 @@ class ModuleSpec {
137149
m_object_size = 0;
138150
m_source_mappings.Clear(false);
139151
m_object_mod_time = llvm::sys::TimePoint<>();
152+
m_target_wp.reset();
140153
}
141154

142155
explicit operator bool() const {
@@ -265,6 +278,11 @@ class ModuleSpec {
265278
ArchSpec m_arch;
266279
UUID m_uuid;
267280
ConstString m_object_name;
281+
/// The target used when resolving a module. A target can help locate a module
282+
/// specified by a ModuleSpec. The target settings, like the executable and
283+
/// debug info search paths, can be essential. The target's platform can also
284+
/// be used to locate or download the specified module.
285+
std::weak_ptr<Target> m_target_wp;
268286
uint64_t m_object_offset = 0;
269287
uint64_t m_object_size = 0;
270288
llvm::sys::TimePoint<> m_object_mod_time;

lldb/include/lldb/Target/Platform.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,7 @@ class Platform : public PluginInterface {
127127
/// Returns \b true if this Platform plug-in was able to find
128128
/// a suitable executable, \b false otherwise.
129129
virtual Status ResolveExecutable(const ModuleSpec &module_spec,
130-
lldb::ModuleSP &exe_module_sp,
131-
const FileSpecList *module_search_paths_ptr);
130+
lldb::ModuleSP &exe_module_sp);
132131

133132
/// Find a symbol file given a symbol file module specification.
134133
///
@@ -304,10 +303,11 @@ class Platform : public PluginInterface {
304303
/// \return
305304
/// The Status object for any errors found while searching for
306305
/// the binary.
307-
virtual Status GetSharedModule(
308-
const ModuleSpec &module_spec, Process *process,
309-
lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr,
310-
llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool *did_create_ptr);
306+
virtual Status
307+
GetSharedModule(const ModuleSpec &module_spec, Process *process,
308+
lldb::ModuleSP &module_sp,
309+
llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules,
310+
bool *did_create_ptr);
311311

312312
void CallLocateModuleCallbackIfSet(const ModuleSpec &module_spec,
313313
lldb::ModuleSP &module_sp,
@@ -1039,8 +1039,8 @@ class Platform : public PluginInterface {
10391039
/// predefined trap handlers, this method may be a no-op.
10401040
virtual void CalculateTrapHandlerSymbolNames() = 0;
10411041

1042-
Status GetCachedExecutable(ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
1043-
const FileSpecList *module_search_paths_ptr);
1042+
Status GetCachedExecutable(ModuleSpec &module_spec,
1043+
lldb::ModuleSP &module_sp);
10441044

10451045
virtual Status DownloadModuleSlice(const FileSpec &src_file_spec,
10461046
const uint64_t src_offset,

lldb/include/lldb/Target/RemoteAwarePlatform.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,8 @@ class RemoteAwarePlatform : public Platform {
2020
public:
2121
using Platform::Platform;
2222

23-
virtual Status
24-
ResolveExecutable(const ModuleSpec &module_spec,
25-
lldb::ModuleSP &exe_module_sp,
26-
const FileSpecList *module_search_paths_ptr) override;
23+
virtual Status ResolveExecutable(const ModuleSpec &module_spec,
24+
lldb::ModuleSP &exe_module_sp) override;
2725

2826
bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch,
2927
ModuleSpec &module_spec) override;

lldb/source/API/SBModule.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ SBModule::SBModule(const SBModuleSpec &module_spec) {
3737
LLDB_INSTRUMENT_VA(this, module_spec);
3838

3939
ModuleSP module_sp;
40-
Status error = ModuleList::GetSharedModule(
41-
*module_spec.m_opaque_up, module_sp, nullptr, nullptr, nullptr);
40+
Status error = ModuleList::GetSharedModule(*module_spec.m_opaque_up,
41+
module_sp, nullptr, nullptr);
4242
if (module_sp)
4343
SetSP(module_sp);
4444
}

lldb/source/API/SBModuleSpec.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "lldb/API/SBModuleSpec.h"
1010
#include "Utils.h"
1111
#include "lldb/API/SBStream.h"
12+
#include "lldb/API/SBTarget.h"
1213
#include "lldb/Core/Module.h"
1314
#include "lldb/Core/ModuleSpec.h"
1415
#include "lldb/Host/Host.h"
@@ -174,6 +175,18 @@ void SBModuleSpec::SetObjectSize(uint64_t object_size) {
174175
m_opaque_up->SetObjectSize(object_size);
175176
}
176177

178+
SBTarget SBModuleSpec::GetTarget() {
179+
LLDB_INSTRUMENT_VA(this);
180+
181+
return SBTarget(m_opaque_up->GetTargetSP());
182+
}
183+
184+
void SBModuleSpec::SetTarget(SBTarget target) {
185+
LLDB_INSTRUMENT_VA(this, target);
186+
187+
m_opaque_up->SetTarget(target.GetSP());
188+
}
189+
177190
SBModuleSpecList::SBModuleSpecList() : m_opaque_up(new ModuleSpecList()) {
178191
LLDB_INSTRUMENT_VA(this);
179192
}

lldb/source/Core/DynamicLoader.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
227227
}
228228
}
229229
ModuleSpec module_spec;
230+
module_spec.SetTarget(target.shared_from_this());
230231
module_spec.GetUUID() = uuid;
231232
FileSpec name_filespec(name);
232233
if (FileSystem::Instance().Exists(name_filespec))
@@ -238,8 +239,8 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
238239
// Has lldb already seen a module with this UUID?
239240
// Or have external lookup enabled in DebugSymbols on macOS.
240241
if (!module_sp)
241-
error = ModuleList::GetSharedModule(module_spec, module_sp, nullptr,
242-
nullptr, nullptr);
242+
error =
243+
ModuleList::GetSharedModule(module_spec, module_sp, nullptr, nullptr);
243244

244245
// Can lldb's symbol/executable location schemes
245246
// find an executable and symbol file.

lldb/source/Core/ModuleList.cpp

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "lldb/Symbol/SymbolContext.h"
2020
#include "lldb/Symbol/TypeList.h"
2121
#include "lldb/Symbol/VariableList.h"
22+
#include "lldb/Target/Platform.h"
23+
#include "lldb/Target/Target.h"
2224
#include "lldb/Utility/ArchSpec.h"
2325
#include "lldb/Utility/ConstString.h"
2426
#include "lldb/Utility/FileSpecList.h"
@@ -1038,9 +1040,9 @@ size_t ModuleList::RemoveOrphanSharedModules(bool mandatory) {
10381040

10391041
Status
10401042
ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp,
1041-
const FileSpecList *module_search_paths_ptr,
10421043
llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules,
1043-
bool *did_create_ptr, bool always_create) {
1044+
bool *did_create_ptr, bool always_create,
1045+
bool invoke_locate_callback) {
10441046
SharedModuleList &shared_module_list = GetSharedModuleList();
10451047
std::lock_guard<std::recursive_mutex> guard(shared_module_list.GetMutex());
10461048
char path[PATH_MAX];
@@ -1095,6 +1097,22 @@ ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp,
10951097
if (module_sp)
10961098
return error;
10971099

1100+
// Try target's platform locate module callback before second attempt.
1101+
if (invoke_locate_callback) {
1102+
TargetSP target_sp = module_spec.GetTargetSP();
1103+
if (target_sp && target_sp->IsValid()) {
1104+
if (PlatformSP platform_sp = target_sp->GetPlatform()) {
1105+
FileSpec symbol_file_spec;
1106+
platform_sp->CallLocateModuleCallbackIfSet(
1107+
module_spec, module_sp, symbol_file_spec, did_create_ptr);
1108+
if (module_sp) {
1109+
// The callback found a module.
1110+
return error;
1111+
}
1112+
}
1113+
}
1114+
}
1115+
10981116
module_sp = std::make_shared<Module>(module_spec);
10991117
// Make sure there are a module and an object file since we can specify a
11001118
// valid file path with an architecture that might not be in that file. By
@@ -1122,10 +1140,16 @@ ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp,
11221140
module_sp.reset();
11231141
}
11241142

1125-
if (module_search_paths_ptr) {
1126-
const auto num_directories = module_search_paths_ptr->GetSize();
1143+
// Get module search paths from the target if available.
1144+
lldb::TargetSP target_sp = module_spec.GetTargetSP();
1145+
FileSpecList module_search_paths;
1146+
if (target_sp)
1147+
module_search_paths = target_sp->GetExecutableSearchPaths();
1148+
1149+
if (!module_search_paths.IsEmpty()) {
1150+
const auto num_directories = module_search_paths.GetSize();
11271151
for (size_t idx = 0; idx < num_directories; ++idx) {
1128-
auto search_path_spec = module_search_paths_ptr->GetFileSpecAtIndex(idx);
1152+
auto search_path_spec = module_search_paths.GetFileSpecAtIndex(idx);
11291153
FileSystem::Instance().Resolve(search_path_spec);
11301154
namespace fs = llvm::sys::fs;
11311155
if (!FileSystem::Instance().IsDirectory(search_path_spec))

0 commit comments

Comments
 (0)