Skip to content

Commit bb7505d

Browse files
authored
Merge pull request #3848 from apple/lldb-Implement-LLDBMemoryReader-resolvePointer
[lldb] Implement LLDBMemoryReader::resolvePointer
2 parents 0a3a4fd + 845de1c commit bb7505d

File tree

14 files changed

+130
-0
lines changed

14 files changed

+130
-0
lines changed

lldb/include/lldb/Core/Section.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ class Section : public std::enable_shared_from_this<Section>,
201201
ObjectFile *GetObjectFile() { return m_obj_file; }
202202
const ObjectFile *GetObjectFile() const { return m_obj_file; }
203203

204+
bool CanContainSwiftReflectionData() const;
205+
204206
/// Read the section data from the object file that the section
205207
/// resides in.
206208
///

lldb/include/lldb/Symbol/ObjectFile.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,12 @@ class ObjectFile : public std::enable_shared_from_this<ObjectFile>,
689689
virtual llvm::StringRef
690690
GetReflectionSectionIdentifier(swift::ReflectionSectionKind section);
691691

692+
#ifdef LLDB_ENABLE_SWIFT
693+
virtual bool CanContainSwiftReflectionData(const Section &section) {
694+
return false;
695+
}
696+
#endif // LLDB_ENABLE_SWIFT
697+
692698
/// Load binaries listed in a corefile
693699
///
694700
/// A corefile may have metadata listing binaries that can be loaded,

lldb/include/lldb/Target/Target.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ class TargetProperties : public Properties {
173173

174174
bool GetSwiftReadMetadataFromFileCache() const;
175175

176+
bool GetSwiftUseReflectionSymbols() const;
177+
176178
bool GetEnableAutoImportClangModules() const;
177179

178180
bool GetUseAllCompilerFlags() const;

lldb/source/Core/Section.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,14 @@ void Section::SetPermissions(uint32_t permissions) {
390390
m_executable = (permissions & ePermissionsExecutable) != 0;
391391
}
392392

393+
bool Section::CanContainSwiftReflectionData() const {
394+
#ifdef LLDB_ENABLE_SWIFT
395+
return m_obj_file->CanContainSwiftReflectionData(*this);
396+
#else
397+
return false;
398+
#endif // LLDB_ENABLE_SWIFT
399+
}
400+
393401
lldb::offset_t Section::GetSectionData(void *dst, lldb::offset_t dst_len,
394402
lldb::offset_t offset) {
395403
if (m_obj_file)

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

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#include "LLDBMemoryReader.h"
2+
#include "lldb/Core/Address.h"
23
#include "lldb/Core/Section.h"
34
#include "lldb/Utility/Log.h"
45
#include "lldb/Utility/Logging.h"
6+
#include "swift/Demangling/Demangle.h"
57

68
#include "llvm/Support/MathExtras.h"
79

@@ -117,6 +119,50 @@ LLDBMemoryReader::getSymbolAddress(const std::string &name) {
117119
return swift::remote::RemoteAddress(load_addr);
118120
}
119121

122+
swift::remote::RemoteAbsolutePointer
123+
LLDBMemoryReader::resolvePointer(swift::remote::RemoteAddress address,
124+
uint64_t readValue) {
125+
// If an address has a symbol, that symbol provides additional useful data to
126+
// MetadataReader. Without the symbol, MetadataReader can derive the symbol
127+
// by loading other parts of reflection metadata, but that work has a cost.
128+
// For lldb, that data loading can be a significant performance hit. Providing
129+
// a symbol greatly reduces memory read traffic to the process.
130+
auto pointer = swift::remote::RemoteAbsolutePointer("", readValue);
131+
132+
auto &target = m_process.GetTarget();
133+
if (!target.GetSwiftUseReflectionSymbols())
134+
return pointer;
135+
136+
llvm::Optional<Address> maybeAddr =
137+
resolveRemoteAddress(address.getAddressData());
138+
// This is not an assert, but should never happen.
139+
if (!maybeAddr)
140+
return pointer;
141+
142+
Address addr;
143+
if (maybeAddr->IsSectionOffset()) {
144+
// `address` was tagged, and then successfully mapped (resolved).
145+
addr = *maybeAddr;
146+
} else {
147+
// `address` is a real load address.
148+
if (!target.ResolveLoadAddress(address.getAddressData(), addr))
149+
return pointer;
150+
}
151+
152+
if (!addr.GetSection()->CanContainSwiftReflectionData())
153+
return pointer;
154+
155+
if (auto *symbol = addr.CalculateSymbolContextSymbol()) {
156+
auto mangledName = symbol->GetMangled().GetMangledName().GetStringRef();
157+
// MemoryReader requires this to be a Swift symbol. LLDB can also be
158+
// aware of local symbols, so avoid returning those.
159+
if (swift::Demangle::isSwiftSymbol(mangledName))
160+
return {mangledName, 0};
161+
}
162+
163+
return pointer;
164+
}
165+
120166
bool LLDBMemoryReader::readBytes(swift::remote::RemoteAddress address,
121167
uint8_t *dest, uint64_t size) {
122168
if (m_local_buffer) {

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ class LLDBMemoryReader : public swift::remote::MemoryReader {
2323
swift::remote::RemoteAddress
2424
getSymbolAddress(const std::string &name) override;
2525

26+
swift::remote::RemoteAbsolutePointer
27+
resolvePointer(swift::remote::RemoteAddress address,
28+
uint64_t readValue) override;
29+
2630
bool readBytes(swift::remote::RemoteAddress address, uint8_t *dest,
2731
uint64_t size) override;
2832

lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3429,3 +3429,11 @@ llvm::StringRef ObjectFileELF::GetReflectionSectionIdentifier(
34293429
llvm_unreachable("Swift support disabled");
34303430
#endif //LLDB_ENABLE_SWIFT
34313431
}
3432+
3433+
#ifdef LLDB_ENABLE_SWIFT
3434+
bool ObjectFileELF::CanContainSwiftReflectionData(const Section &section) {
3435+
swift::SwiftObjectFileFormatELF file_format;
3436+
return file_format.sectionContainsReflectionData(
3437+
section.GetName().GetStringRef());
3438+
}
3439+
#endif // LLDB_ENABLE_SWIFT

lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,11 @@ class ObjectFileELF : public lldb_private::ObjectFile {
395395

396396
llvm::StringRef
397397
GetReflectionSectionIdentifier(swift::ReflectionSectionKind section) override;
398+
399+
#ifdef LLDB_ENABLE_SWIFT
400+
bool
401+
CanContainSwiftReflectionData(const lldb_private::Section &section) override;
402+
#endif // LLDB_ENABLE_SWIFT
398403
};
399404

400405
#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H

lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7019,6 +7019,23 @@ llvm::StringRef ObjectFileMachO::GetReflectionSectionIdentifier(
70197019
#endif //LLDB_ENABLE_SWIFT
70207020
}
70217021

7022+
#ifdef LLDB_ENABLE_SWIFT
7023+
bool ObjectFileMachO::CanContainSwiftReflectionData(const Section &section) {
7024+
swift::SwiftObjectFileFormatMachO file_format;
7025+
if (file_format.sectionContainsReflectionData(
7026+
section.GetName().GetStringRef()))
7027+
return true;
7028+
// Some section names are not unique, such as `__const`, which could be in
7029+
// `__TEXT` or `__DATA`. For these, also check the segment,section name.
7030+
if (auto segment = section.GetParent()) {
7031+
std::string segmentSectionName =
7032+
llvm::formatv("{0},{1}", segment->GetName(), section.GetName()).str();
7033+
return file_format.sectionContainsReflectionData(segmentSectionName);
7034+
}
7035+
return false;
7036+
}
7037+
#endif // LLDB_ENABLE_SWIFT
7038+
70227039
ObjectFileMachO::MachOCorefileAllImageInfos
70237040
ObjectFileMachO::GetCorefileAllImageInfos() {
70247041
MachOCorefileAllImageInfos image_infos;

lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,11 @@ class ObjectFileMachO : public lldb_private::ObjectFile {
220220
llvm::StringRef
221221
GetReflectionSectionIdentifier(swift::ReflectionSectionKind section) override;
222222

223+
#ifdef LLDB_ENABLE_SWIFT
224+
bool
225+
CanContainSwiftReflectionData(const lldb_private::Section &section) override;
226+
#endif // LLDB_ENABLE_SWIFT
227+
223228
/// A corefile may include metadata about all of the binaries that were
224229
/// present in the process when the corefile was taken. This is only
225230
/// implemented for Mach-O files for now; we'll generalize it when we

lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,3 +1217,10 @@ llvm::StringRef ObjectFilePECOFF::GetReflectionSectionIdentifier(
12171217
#endif //LLDB_ENABLE_SWIFT
12181218
}
12191219

1220+
#ifdef LLDB_ENABLE_SWIFT
1221+
bool ObjectFilePECOFF::CanContainSwiftReflectionData(const Section &section) {
1222+
swift::SwiftObjectFileFormatCOFF file_format;
1223+
return file_format.sectionContainsReflectionData(
1224+
section.GetName().GetStringRef());
1225+
}
1226+
#endif // LLDB_ENABLE_SWIFT

lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,11 @@ class ObjectFilePECOFF : public lldb_private::ObjectFile {
288288
llvm::StringRef
289289
GetReflectionSectionIdentifier(swift::ReflectionSectionKind section) override;
290290

291+
#ifdef LLDB_ENABLE_SWIFT
292+
bool
293+
CanContainSwiftReflectionData(const lldb_private::Section &section) override;
294+
#endif // LLDB_ENABLE_SWIFT
295+
291296
typedef std::vector<section_header_t> SectionHeaderColl;
292297
typedef SectionHeaderColl::iterator SectionHeaderCollIter;
293298
typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter;

lldb/source/Target/Target.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4170,6 +4170,18 @@ bool TargetProperties::GetSwiftReadMetadataFromFileCache() const {
41704170
return true;
41714171
}
41724172

4173+
bool TargetProperties::GetSwiftUseReflectionSymbols() const {
4174+
const Property *exp_property = m_collection_sp->GetPropertyAtIndex(
4175+
nullptr, false, ePropertyExperimental);
4176+
OptionValueProperties *exp_values =
4177+
exp_property->GetValue()->GetAsProperties();
4178+
if (exp_values)
4179+
return exp_values->GetPropertyAtIndexAsBoolean(
4180+
nullptr, ePropertySwiftUseReflectionSymbols, true);
4181+
else
4182+
return true;
4183+
}
4184+
41734185
ArchSpec TargetProperties::GetDefaultArchitecture() const {
41744186
OptionValueArch *value = m_collection_sp->GetPropertyAtIndexAsOptionValueArch(
41754187
nullptr, ePropertyDefaultArch);

lldb/source/Target/TargetProperties.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ let Definition = "target_experimental" in {
1010
def SwiftReadMetadataFromFileCache: Property<"swift-read-metadata-from-file-cache", "Boolean">,
1111
DefaultTrue,
1212
Desc<"Read Swift reflection metadata from the file cache instead of the process when possible">;
13+
def SwiftUseReflectionSymbols : Property<"swift-use-reflection-symbols", "Boolean">,
14+
Global, DefaultTrue,
15+
Desc<"if true, optimize the loading of Swift reflection metadata by making use of available symbols.">;
1316
}
1417

1518
let Definition = "target" in {

0 commit comments

Comments
 (0)