Skip to content

Commit cd2992b

Browse files
authored
Merge pull request #3882 from augusto2112/resolve-pointer-symbol
[lldb] Move resolvePointer code to resolvePointerAsSymbol and implement resolvePointer to map process addresses to tagged addressess
2 parents 6adbce2 + 3d63cec commit cd2992b

File tree

2 files changed

+75
-11
lines changed

2 files changed

+75
-11
lines changed

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

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,25 +119,22 @@ LLDBMemoryReader::getSymbolAddress(const std::string &name) {
119119
return swift::remote::RemoteAddress(load_addr);
120120
}
121121

122-
swift::remote::RemoteAbsolutePointer
123-
LLDBMemoryReader::resolvePointer(swift::remote::RemoteAddress address,
124-
uint64_t readValue) {
122+
llvm::Optional<swift::remote::RemoteAbsolutePointer>
123+
LLDBMemoryReader::resolvePointerAsSymbol(swift::remote::RemoteAddress address) {
125124
// If an address has a symbol, that symbol provides additional useful data to
126125
// MetadataReader. Without the symbol, MetadataReader can derive the symbol
127126
// by loading other parts of reflection metadata, but that work has a cost.
128127
// For lldb, that data loading can be a significant performance hit. Providing
129128
// a symbol greatly reduces memory read traffic to the process.
130-
auto pointer = swift::remote::RemoteAbsolutePointer("", readValue);
131-
132129
auto &target = m_process.GetTarget();
133130
if (!target.GetSwiftUseReflectionSymbols())
134-
return pointer;
131+
return {};
135132

136133
llvm::Optional<Address> maybeAddr =
137134
resolveRemoteAddress(address.getAddressData());
138135
// This is not an assert, but should never happen.
139136
if (!maybeAddr)
140-
return pointer;
137+
return {};
141138

142139
Address addr;
143140
if (maybeAddr->IsSectionOffset()) {
@@ -146,21 +143,85 @@ LLDBMemoryReader::resolvePointer(swift::remote::RemoteAddress address,
146143
} else {
147144
// `address` is a real load address.
148145
if (!target.ResolveLoadAddress(address.getAddressData(), addr))
149-
return pointer;
146+
return {};
150147
}
151148

152149
if (!addr.GetSection()->CanContainSwiftReflectionData())
153-
return pointer;
150+
return {};
154151

155152
if (auto *symbol = addr.CalculateSymbolContextSymbol()) {
156153
auto mangledName = symbol->GetMangled().GetMangledName().GetStringRef();
157154
// MemoryReader requires this to be a Swift symbol. LLDB can also be
158155
// aware of local symbols, so avoid returning those.
159156
if (swift::Demangle::isSwiftSymbol(mangledName))
160-
return {mangledName, 0};
157+
return {{mangledName, 0}};
158+
}
159+
160+
return {};
161+
}
162+
163+
swift::remote::RemoteAbsolutePointer
164+
LLDBMemoryReader::resolvePointer(swift::remote::RemoteAddress address,
165+
uint64_t readValue) {
166+
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES));
167+
168+
// We may have gotten a pointer to a process address, try to map it back
169+
// to a tagged address so further memory reads originating from it benefit
170+
// from the file-cache optimization.
171+
swift::remote::RemoteAbsolutePointer process_pointer("", readValue);
172+
173+
auto &target = m_process.GetTarget();
174+
Address addr;
175+
if (!target.ResolveLoadAddress(readValue, addr)) {
176+
LLDB_LOGV(log,
177+
"[MemoryReader] Could not resolve load address of pointer {0:x} "
178+
"read from {1:x}.",
179+
readValue, address.getAddressData());
180+
return process_pointer;
181+
}
182+
183+
auto module_containing_pointer = addr.GetSection()->GetModule();
184+
185+
// Check if the module containing the pointer is registered with
186+
// LLDBMemoryReader.
187+
auto pair_iterator = std::find_if(
188+
m_range_module_map.begin(), m_range_module_map.end(), [&](auto pair) {
189+
return std::get<ModuleSP>(pair) == module_containing_pointer;
190+
});
191+
192+
// We haven't registered the image that contains the pointer.
193+
if (pair_iterator == m_range_module_map.end()) {
194+
LLDB_LOG(log,
195+
"[MemoryReader] Could not resolve find module containing pointer "
196+
"{0:x} read from {1:x}.",
197+
readValue, address.getAddressData());
198+
return process_pointer;
199+
}
200+
201+
// If the containing image is the first registered one, the image's tagged
202+
// start address for it is the first tagged address. Otherwise, the previous
203+
// pair's address is the start tagged address.
204+
uint64_t start_tagged_address = pair_iterator == m_range_module_map.begin()
205+
? LLDB_FILE_ADDRESS_BIT
206+
: std::prev(pair_iterator)->first;
207+
208+
uint64_t tagged_address = start_tagged_address + addr.GetFileAddress();
209+
210+
if (tagged_address >= std::get<uint64_t>(*pair_iterator)) {
211+
// If the tagged address invades the next image's tagged address space,
212+
// something went wrong. Log it and just return the process address.
213+
LLDB_LOG(log,
214+
"[MemoryReader] Pointer {0:x} read from {1:x} resolved to tagged "
215+
"address {2:x}, which is outside its image address space.",
216+
readValue, address.getAddressData(), tagged_address);
217+
return process_pointer;
161218
}
162219

163-
return pointer;
220+
LLDB_LOGV(log,
221+
"[MemoryReader] Successfully resolved pointer {0:x} read from "
222+
"{1:x} to tagged address {2:x}.",
223+
readValue, address.getAddressData(), tagged_address);
224+
return swift::remote::RemoteAbsolutePointer("", tagged_address);
164225
}
165226

166227
bool LLDBMemoryReader::readBytes(swift::remote::RemoteAddress address,

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

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

26+
llvm::Optional<swift::remote::RemoteAbsolutePointer>
27+
resolvePointerAsSymbol(swift::remote::RemoteAddress address) override;
28+
2629
swift::remote::RemoteAbsolutePointer
2730
resolvePointer(swift::remote::RemoteAddress address,
2831
uint64_t readValue) override;

0 commit comments

Comments
 (0)