Skip to content

Commit 766ba98

Browse files
[lldb][swift] Add helper function to find Swift concurrency's module version
1 parent a9e3fcf commit 766ba98

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ const char *SwiftLanguageRuntime::GetStandardLibraryBaseName() {
9191
return "swiftCore";
9292
}
9393

94+
const char *SwiftLanguageRuntime::GetConcurrencyLibraryBaseName() {
95+
return "swift_Concurrency";
96+
}
97+
9498
static ConstString GetStandardLibraryName(Process &process) {
9599
// This result needs to be stored in the constructor.
96100
PlatformSP platform_sp(process.GetTarget().GetPlatform());
@@ -100,6 +104,14 @@ static ConstString GetStandardLibraryName(Process &process) {
100104
return {};
101105
}
102106

107+
static ConstString GetConcurrencyLibraryName(Process &process) {
108+
PlatformSP platform_sp = process.GetTarget().GetPlatform();
109+
if (platform_sp)
110+
return platform_sp->GetFullNameForDylib(
111+
ConstString(SwiftLanguageRuntime::GetConcurrencyLibraryBaseName()));
112+
return {};
113+
}
114+
103115
ConstString SwiftLanguageRuntime::GetStandardLibraryName() {
104116
return ::GetStandardLibraryName(*m_process);
105117
}
@@ -109,6 +121,12 @@ static bool IsModuleSwiftRuntime(lldb_private::Process &process,
109121
return module.GetFileSpec().GetFilename() == GetStandardLibraryName(process);
110122
}
111123

124+
static bool IsModuleSwiftConcurrency(lldb_private::Process &process,
125+
lldb_private::Module &module) {
126+
return module.GetFileSpec().GetFilename() ==
127+
GetConcurrencyLibraryName(process);
128+
}
129+
112130
AppleObjCRuntimeV2 *
113131
SwiftLanguageRuntime::GetObjCRuntime(lldb_private::Process &process) {
114132
if (auto objc_runtime = ObjCLanguageRuntime::Get(process)) {
@@ -131,6 +149,11 @@ static bool IsStaticSwiftRuntime(Module &image) {
131149
return image.FindFirstSymbolWithNameAndType(swift_reflection_version_sym);
132150
}
133151

152+
static bool IsStaticSwiftConcurrency(Module &image) {
153+
static const ConstString task_switch_symbol("_swift_task_switch");
154+
return image.FindFirstSymbolWithNameAndType(task_switch_symbol);
155+
}
156+
134157
/// \return the Swift or Objective-C runtime found in the loaded images.
135158
static ModuleSP findRuntime(Process &process, RuntimeKind runtime_kind) {
136159
AppleObjCRuntimeV2 *objc_runtime = nullptr;
@@ -168,6 +191,52 @@ static ModuleSP findRuntime(Process &process, RuntimeKind runtime_kind) {
168191
return runtime_image;
169192
}
170193

194+
ModuleSP SwiftLanguageRuntime::FindConcurrencyModule(Process &process) {
195+
ModuleSP concurrency_module;
196+
process.GetTarget().GetImages().ForEach([&](const ModuleSP &candidate) {
197+
if (candidate && IsModuleSwiftConcurrency(process, *candidate)) {
198+
concurrency_module = candidate;
199+
return false;
200+
}
201+
return true;
202+
});
203+
if (concurrency_module)
204+
return concurrency_module;
205+
206+
// Do a more expensive search for a statically linked Swift runtime.
207+
process.GetTarget().GetImages().ForEach([&](const ModuleSP &candidate) {
208+
if (candidate && IsStaticSwiftConcurrency(*candidate)) {
209+
concurrency_module = candidate;
210+
return false;
211+
}
212+
return true;
213+
});
214+
return concurrency_module;
215+
}
216+
217+
std::optional<uint32_t>
218+
SwiftLanguageRuntime::FindConcurrencyDebugVersion(Process &process) {
219+
ModuleSP concurrency_module = FindConcurrencyModule(process);
220+
if (!concurrency_module)
221+
return {};
222+
223+
const Symbol *version_symbol =
224+
concurrency_module->FindFirstSymbolWithNameAndType(
225+
ConstString("_swift_concurrency_debug_internal_layout_version"));
226+
if (!version_symbol)
227+
return 0;
228+
229+
addr_t symbol_addr = version_symbol->GetLoadAddress(&process.GetTarget());
230+
if (symbol_addr == LLDB_INVALID_ADDRESS)
231+
return {};
232+
Status error;
233+
uint64_t version = process.ReadUnsignedIntegerFromMemory(
234+
symbol_addr, /*width*/ 4, /*fail_value=*/0, error);
235+
if (error.Fail())
236+
return {};
237+
return version;
238+
}
239+
171240
static std::optional<lldb::addr_t>
172241
FindSymbolForSwiftObject(Process &process, RuntimeKind runtime_kind,
173242
StringRef object, const SymbolType sym_type) {

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,16 @@ class SwiftLanguageRuntime : public LanguageRuntime {
9898
static SwiftLanguageRuntime *Get(lldb::ProcessSP process_sp) {
9999
return SwiftLanguageRuntime::Get(process_sp.get());
100100
}
101+
102+
/// Returns the Module containing the Swift Concurrency runtime, if it exists.
103+
static lldb::ModuleSP FindConcurrencyModule(Process &process);
104+
105+
/// Returns the version of the swift concurrency runtime debug layout.
106+
/// If no Concurrency module is found, or if errors occur, nullopt is
107+
/// returned.
108+
/// Returns 0 for versions of the module prior to the introduction
109+
/// of versioning.
110+
static std::optional<uint32_t> FindConcurrencyDebugVersion(Process &process);
101111
/// \}
102112

103113
/// PluginInterface protocol.
@@ -481,6 +491,8 @@ class SwiftLanguageRuntime : public LanguageRuntime {
481491
static const char *GetErrorBackstopName();
482492
ConstString GetStandardLibraryName();
483493
static const char *GetStandardLibraryBaseName();
494+
static const char *GetConcurrencyLibraryBaseName();
495+
484496
static bool IsSwiftClassName(const char *name);
485497
/// Determines wether \c variable is the "self" object.
486498
static bool IsSelf(Variable &variable);

0 commit comments

Comments
 (0)