Skip to content

[Reflection] Separate MemoryReader::resolvePointer to distinguish related operations #41530

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions include/swift/Remote/MemoryReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,19 +148,32 @@ class MemoryReader {
return RemoteAbsolutePointer("", readValue);
}

/// Atempt to resolve the pointer to a symbol for the given remote address.
virtual llvm::Optional<RemoteAbsolutePointer>
resolvePointerAsSymbol(RemoteAddress address) {
return llvm::None;
}
Comment on lines 151 to 154
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have kept this in to allow this change to allow this PR to be free of a dependent change in llvm-project. Later, it will be removed.


/// Lookup a symbol for the given remote address.
virtual RemoteAbsolutePointer getSymbol(RemoteAddress address) {
if (auto symbol = resolvePointerAsSymbol(address))
return *symbol;
return RemoteAbsolutePointer("", address.getAddressData());
}

/// Lookup a dynamic symbol name (ie dynamic loader binding) for the given
/// remote address. Note: An address can be referenced by both dynamic and
/// regular symbols, this function must return a dynamic symbol only.
virtual RemoteAbsolutePointer getDynamicSymbol(RemoteAddress address) {
return nullptr;
}

/// Attempt to read and resolve a pointer value at the given remote address.
llvm::Optional<RemoteAbsolutePointer> readPointer(RemoteAddress address,
unsigned pointerSize) {
// Try to resolve the pointer as a symbol first, as reading memory
// may potentially be expensive.
if (auto symbolPointer = resolvePointerAsSymbol(address))
return symbolPointer;
// First, try to lookup the pointer as a dynamic symbol (binding), as
// reading memory may potentially be expensive.
if (auto dynamicSymbol = getDynamicSymbol(address))
return dynamicSymbol;

auto result = readBytes(address, pointerSize);
if (!result)
Expand Down
6 changes: 1 addition & 5 deletions include/swift/Remote/MetadataReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -420,11 +420,7 @@ class MetadataReader {
return nullptr;
}
} else {
resolved = Reader->resolvePointer(RemoteAddress(remoteAddress), 0);
if (resolved.getSymbol().empty()) {
// No symbol found, use the already calculated address.
resolved = RemoteAbsolutePointer("", remoteAddress);
}
resolved = Reader->getSymbol(RemoteAddress(remoteAddress));
}

switch (kind) {
Expand Down
5 changes: 5 additions & 0 deletions include/swift/StaticMirror/ObjectFileContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ class Image {

remote::RemoteAbsolutePointer resolvePointer(uint64_t Addr,
uint64_t pointerValue) const;

remote::RemoteAbsolutePointer getDynamicSymbol(uint64_t Addr) const;
};

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

remote::RemoteAbsolutePointer resolvePointer(reflection::RemoteAddress Addr,
uint64_t pointerValue) override;

remote::RemoteAbsolutePointer
getDynamicSymbol(reflection::RemoteAddress Addr) override;
};

using ReflectionContextOwner = std::unique_ptr<void, void (*)(void *)>;
Expand Down
55 changes: 32 additions & 23 deletions lib/StaticMirror/ObjectFileContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,22 +279,23 @@ StringRef Image::getContentsAtAddress(uint64_t Addr, uint64_t Size) const {

remote::RemoteAbsolutePointer
Image::resolvePointer(uint64_t Addr, uint64_t pointerValue) const {
// In Mach-O images with ptrauth, the pointer value has an offset from the
// base address in the low 32 bits, and ptrauth discriminator info in the top
// 32 bits.
if (isMachOWithPtrAuth()) {
return remote::RemoteAbsolutePointer(
"", HeaderAddress + (pointerValue & 0xffffffffull));
} else {
return remote::RemoteAbsolutePointer("", pointerValue);
}
}

remote::RemoteAbsolutePointer Image::getDynamicSymbol(uint64_t Addr) const {
auto found = DynamicRelocations.find(Addr);
remote::RemoteAbsolutePointer result;
if (found == DynamicRelocations.end())
// In Mach-O images with ptrauth, the pointer value has an offset from
// the base address in the low 32 bits, and ptrauth discriminator info
// in the top 32 bits.
if (isMachOWithPtrAuth()) {
result = remote::RemoteAbsolutePointer(
"", HeaderAddress + (pointerValue & 0xffffffffull));
} else {
result = remote::RemoteAbsolutePointer("", pointerValue);
}
else
result = remote::RemoteAbsolutePointer(found->second.Symbol,
found->second.Offset);
return result;
return nullptr;
return remote::RemoteAbsolutePointer(found->second.Symbol,
found->second.Offset);
}

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

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

if (resolved && resolved.isResolved()) {
// Mix in the image index again to produce a remote address pointing into
// the same image.
return remote::RemoteAbsolutePointer(
"", encodeImageIndexAndAddress(
image, resolved.getResolvedAddress().getAddressData()));
}
// If the pointer is relative to an unresolved relocation, leave it as is.
return resolved;
remote::RemoteAbsolutePointer
ObjectMemoryReader::getDynamicSymbol(reflection::RemoteAddress Addr) {
auto addrValue = Addr.getAddressData();
const Image *image;
uint64_t imageAddr;
std::tie(image, imageAddr) = decodeImageIndexAndAddress(addrValue);

if (!image)
return nullptr;

return image->getDynamicSymbol(imageAddr);
}

template <typename Runtime>
Expand Down