Skip to content

Commit cfe0b97

Browse files
authored
[Reflection] Update MemoryReader to distinguish related operations (swiftlang#41530)
Until recently, `MemoryReader` had a single function `resovlePointer` which did two things, and has a somewhat vague name. The two things were: 1. Tool-specific mapping between real addresses and tagged addresses (first implemented in `swift-reflection-dump` and then later in lldb) 2. Finding a "symbol" for a given address Recently, `resolvePointerAsSymbol` was added, which overloaded the term "resolve" and it added another way to deal with symbols for addresses. Symbols themselves were a bit muddled, as `swift-reflection-dump` was dealing with dynamic symbols aka bindings, while lldb was dealing in regular (static) symbols. This change separates these two parts of functionality, and also divides symbol lookup into two cases. The API surface will now be: 1. `resolvePointer` for mapping/tagging addresses 3. `getSymbol` for looking up a symbol for an address 4. `getDynamicSymbol` for looking up a dyld binding for an address Note: each of these names could be improved. Some alternative terms: `lookup` instead of `get`, `Binding` or `BindingName` instead of `DynamicSymbol`. Maybe even another term instead of "resolve". Suggestions welcome! Currently, `swift-reflection-dump` supports `getDynamicSymbol` but not `getSymbol`. For lldb it's the reverse, `getSymbol` is supported but `getDynamicSymbol` needs to be implemented. For everything but lldb, this change is NFC. For lldb it fixes a bug where `LLDBMemoryReader` returns regular symbols where we should instead be returning dynamic symbols.
1 parent cb56373 commit cfe0b97

File tree

4 files changed

+56
-33
lines changed

4 files changed

+56
-33
lines changed

include/swift/Remote/MemoryReader.h

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,19 +149,32 @@ class MemoryReader {
149149
return RemoteAbsolutePointer("", readValue);
150150
}
151151

152-
/// Atempt to resolve the pointer to a symbol for the given remote address.
153152
virtual llvm::Optional<RemoteAbsolutePointer>
154153
resolvePointerAsSymbol(RemoteAddress address) {
155154
return llvm::None;
156155
}
157156

157+
/// Lookup a symbol for the given remote address.
158+
virtual RemoteAbsolutePointer getSymbol(RemoteAddress address) {
159+
if (auto symbol = resolvePointerAsSymbol(address))
160+
return *symbol;
161+
return RemoteAbsolutePointer("", address.getAddressData());
162+
}
163+
164+
/// Lookup a dynamic symbol name (ie dynamic loader binding) for the given
165+
/// remote address. Note: An address can be referenced by both dynamic and
166+
/// regular symbols, this function must return a dynamic symbol only.
167+
virtual RemoteAbsolutePointer getDynamicSymbol(RemoteAddress address) {
168+
return nullptr;
169+
}
170+
158171
/// Attempt to read and resolve a pointer value at the given remote address.
159172
llvm::Optional<RemoteAbsolutePointer> readPointer(RemoteAddress address,
160173
unsigned pointerSize) {
161-
// Try to resolve the pointer as a symbol first, as reading memory
162-
// may potentially be expensive.
163-
if (auto symbolPointer = resolvePointerAsSymbol(address))
164-
return symbolPointer;
174+
// First, try to lookup the pointer as a dynamic symbol (binding), as
175+
// reading memory may potentially be expensive.
176+
if (auto dynamicSymbol = getDynamicSymbol(address))
177+
return dynamicSymbol;
165178

166179
auto result = readBytes(address, pointerSize);
167180
if (!result)

include/swift/Remote/MetadataReader.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -420,11 +420,7 @@ class MetadataReader {
420420
return nullptr;
421421
}
422422
} else {
423-
resolved = Reader->resolvePointer(RemoteAddress(remoteAddress), 0);
424-
if (resolved.getSymbol().empty()) {
425-
// No symbol found, use the already calculated address.
426-
resolved = RemoteAbsolutePointer("", remoteAddress);
427-
}
423+
resolved = Reader->getSymbol(RemoteAddress(remoteAddress));
428424
}
429425

430426
switch (kind) {

include/swift/StaticMirror/ObjectFileContext.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ class Image {
7070

7171
remote::RemoteAbsolutePointer resolvePointer(uint64_t Addr,
7272
uint64_t pointerValue) const;
73+
74+
remote::RemoteAbsolutePointer getDynamicSymbol(uint64_t Addr) const;
7375
};
7476

7577
/// MemoryReader that reads from the on-disk representation of an executable
@@ -118,6 +120,9 @@ class ObjectMemoryReader : public reflection::MemoryReader {
118120

119121
remote::RemoteAbsolutePointer resolvePointer(reflection::RemoteAddress Addr,
120122
uint64_t pointerValue) override;
123+
124+
remote::RemoteAbsolutePointer
125+
getDynamicSymbol(reflection::RemoteAddress Addr) override;
121126
};
122127

123128
using ReflectionContextOwner = std::unique_ptr<void, void (*)(void *)>;

lib/StaticMirror/ObjectFileContext.cpp

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -279,22 +279,23 @@ StringRef Image::getContentsAtAddress(uint64_t Addr, uint64_t Size) const {
279279

280280
remote::RemoteAbsolutePointer
281281
Image::resolvePointer(uint64_t Addr, uint64_t pointerValue) const {
282+
// In Mach-O images with ptrauth, the pointer value has an offset from the
283+
// base address in the low 32 bits, and ptrauth discriminator info in the top
284+
// 32 bits.
285+
if (isMachOWithPtrAuth()) {
286+
return remote::RemoteAbsolutePointer(
287+
"", HeaderAddress + (pointerValue & 0xffffffffull));
288+
} else {
289+
return remote::RemoteAbsolutePointer("", pointerValue);
290+
}
291+
}
292+
293+
remote::RemoteAbsolutePointer Image::getDynamicSymbol(uint64_t Addr) const {
282294
auto found = DynamicRelocations.find(Addr);
283-
remote::RemoteAbsolutePointer result;
284295
if (found == DynamicRelocations.end())
285-
// In Mach-O images with ptrauth, the pointer value has an offset from
286-
// the base address in the low 32 bits, and ptrauth discriminator info
287-
// in the top 32 bits.
288-
if (isMachOWithPtrAuth()) {
289-
result = remote::RemoteAbsolutePointer(
290-
"", HeaderAddress + (pointerValue & 0xffffffffull));
291-
} else {
292-
result = remote::RemoteAbsolutePointer("", pointerValue);
293-
}
294-
else
295-
result = remote::RemoteAbsolutePointer(found->second.Symbol,
296-
found->second.Offset);
297-
return result;
296+
return nullptr;
297+
return remote::RemoteAbsolutePointer(found->second.Symbol,
298+
found->second.Offset);
298299
}
299300

300301
std::pair<const Image *, uint64_t>
@@ -482,16 +483,24 @@ ObjectMemoryReader::resolvePointer(reflection::RemoteAddress Addr,
482483
return remote::RemoteAbsolutePointer();
483484

484485
auto resolved = image->resolvePointer(imageAddr, pointerValue);
486+
// Mix in the image index again to produce a remote address pointing into the
487+
// same image.
488+
return remote::RemoteAbsolutePointer(
489+
"", encodeImageIndexAndAddress(
490+
image, resolved.getResolvedAddress().getAddressData()));
491+
}
485492

486-
if (resolved && resolved.isResolved()) {
487-
// Mix in the image index again to produce a remote address pointing into
488-
// the same image.
489-
return remote::RemoteAbsolutePointer(
490-
"", encodeImageIndexAndAddress(
491-
image, resolved.getResolvedAddress().getAddressData()));
492-
}
493-
// If the pointer is relative to an unresolved relocation, leave it as is.
494-
return resolved;
493+
remote::RemoteAbsolutePointer
494+
ObjectMemoryReader::getDynamicSymbol(reflection::RemoteAddress Addr) {
495+
auto addrValue = Addr.getAddressData();
496+
const Image *image;
497+
uint64_t imageAddr;
498+
std::tie(image, imageAddr) = decodeImageIndexAndAddress(addrValue);
499+
500+
if (!image)
501+
return nullptr;
502+
503+
return image->getDynamicSymbol(imageAddr);
495504
}
496505

497506
template <typename Runtime>

0 commit comments

Comments
 (0)