[RemoteInspection] Change RemoteAbsolutePointer (NFC)

This patch changes RemoteAbsolutePointer to store both the symbol and
the resolved address. This allows us to retire some ugly workarounds
to deal with non-symbolic addresses and it fixes code paths that would
need these workarounds, but haven't implemented them yet (i.e., the
pack shape handling in the symbolicReferenceResolver in MetadatyaReader.

Addresses parts of rdar://146273066.
rdar://153687085
This commit is contained in:
Adrian Prantl
2025-06-17 16:57:19 -07:00
parent e42b564800
commit 9381a54c67
6 changed files with 46 additions and 70 deletions

View File

@@ -147,7 +147,7 @@ public:
virtual RemoteAbsolutePointer resolvePointer(RemoteAddress address, virtual RemoteAbsolutePointer resolvePointer(RemoteAddress address,
uint64_t readValue) { uint64_t readValue) {
// Default implementation returns the read value as is. // Default implementation returns the read value as is.
return RemoteAbsolutePointer("", readValue); return RemoteAbsolutePointer(RemoteAddress(readValue));
} }
/// Performs the inverse operation of \ref resolvePointer. /// Performs the inverse operation of \ref resolvePointer.
@@ -166,7 +166,7 @@ public:
virtual RemoteAbsolutePointer getSymbol(RemoteAddress address) { virtual RemoteAbsolutePointer getSymbol(RemoteAddress address) {
if (auto symbol = resolvePointerAsSymbol(address)) if (auto symbol = resolvePointerAsSymbol(address))
return *symbol; return *symbol;
return RemoteAbsolutePointer("", address.getAddressData()); return RemoteAbsolutePointer(address);
} }
/// Lookup a dynamic symbol name (ie dynamic loader binding) for the given /// Lookup a dynamic symbol name (ie dynamic loader binding) for the given

View File

@@ -416,11 +416,9 @@ public:
} }
RemoteAbsolutePointer stripSignedPointer(const RemoteAbsolutePointer &P) { RemoteAbsolutePointer stripSignedPointer(const RemoteAbsolutePointer &P) {
if (P.isResolved()) { return RemoteAbsolutePointer(
return RemoteAbsolutePointer("", P.getSymbol(), P.getOffset(),
P.getResolvedAddress().getAddressData() & PtrAuthMask); RemoteAddress(P.getResolvedAddress().getAddressData() & PtrAuthMask));
}
return P;
} }
StoredPointer queryPtrAuthMask() { StoredPointer queryPtrAuthMask() {
@@ -519,14 +517,6 @@ public:
// The second entry is a relative address to the mangled protocol // The second entry is a relative address to the mangled protocol
// without symbolic references. // without symbolic references.
// lldb might return an unresolved remote absolute pointer from its
// resolvePointerAsSymbol implementation -- workaround this.
if (!resolved.isResolved()) {
auto remoteAddr = RemoteAddress(remoteAddress);
resolved =
RemoteAbsolutePointer("", remoteAddr.getAddressData());
}
auto addr = auto addr =
resolved.getResolvedAddress().getAddressData() + sizeof(int32_t); resolved.getResolvedAddress().getAddressData() + sizeof(int32_t);
int32_t offset; int32_t offset;
@@ -534,14 +524,6 @@ public:
auto addrOfTypeRef = addr + offset; auto addrOfTypeRef = addr + offset;
resolved = Reader->getSymbol(RemoteAddress(addrOfTypeRef)); resolved = Reader->getSymbol(RemoteAddress(addrOfTypeRef));
// lldb might return an unresolved remote absolute pointer from its
// resolvePointerAsSymbol implementation -- workaround this.
if (!resolved.isResolved()) {
auto remoteAddr = RemoteAddress(addrOfTypeRef);
resolved =
RemoteAbsolutePointer("", remoteAddr.getAddressData());
}
// Dig out the protocol from the protocol list. // Dig out the protocol from the protocol list.
auto protocolList = readMangledName(resolved.getResolvedAddress(), auto protocolList = readMangledName(resolved.getResolvedAddress(),
MangledNameKind::Type, dem); MangledNameKind::Type, dem);
@@ -1379,12 +1361,10 @@ public:
ParentContextDescriptorRef ParentContextDescriptorRef
readContextDescriptor(const RemoteAbsolutePointer &address) { readContextDescriptor(const RemoteAbsolutePointer &address) {
// Map an unresolved pointer to an unresolved context ref. // Map an unresolved pointer to an unresolved context ref.
if (!address.isResolved()) { if (!address.getSymbol().empty()) {
// We can only handle references to a symbol without an offset currently. // We can only handle references to a symbol without an offset currently.
if (address.getOffset() != 0) { if (address.getOffset() == 0)
return ParentContextDescriptorRef(); return ParentContextDescriptorRef(address.getSymbol());
}
return ParentContextDescriptorRef(address.getSymbol());
} }
return ParentContextDescriptorRef( return ParentContextDescriptorRef(
@@ -2016,7 +1996,7 @@ public:
std::optional<StoredPointer> readResolvedPointerValue(StoredPointer address) { std::optional<StoredPointer> readResolvedPointerValue(StoredPointer address) {
if (auto pointer = readPointer(address)) { if (auto pointer = readPointer(address)) {
if (!pointer->isResolved()) if (!pointer->getResolvedAddress())
return std::nullopt; return std::nullopt;
return (StoredPointer)pointer->getResolvedAddress().getAddressData(); return (StoredPointer)pointer->getResolvedAddress().getAddressData();
} }
@@ -2079,7 +2059,7 @@ protected:
return std::nullopt; return std::nullopt;
} }
return RemoteAbsolutePointer("", resultAddress); return RemoteAbsolutePointer(RemoteAddress(resultAddress));
} }
/// Given a pointer to an Objective-C class, try to read its class name. /// Given a pointer to an Objective-C class, try to read its class name.
@@ -2335,13 +2315,11 @@ private:
auto parentAddress = resolveRelativeIndirectableField(base, base->Parent); auto parentAddress = resolveRelativeIndirectableField(base, base->Parent);
if (!parentAddress) if (!parentAddress)
return std::nullopt; return std::nullopt;
if (!parentAddress->isResolved()) { if (!parentAddress->getSymbol().empty()) {
// Currently we can only handle references directly to a symbol without // Currently we can only handle references directly to a symbol without
// an offset. // an offset.
if (parentAddress->getOffset() != 0) { if (parentAddress->getOffset() == 0)
return std::nullopt; return ParentContextDescriptorRef(parentAddress->getSymbol());
}
return ParentContextDescriptorRef(parentAddress->getSymbol());
} }
auto addr = parentAddress->getResolvedAddress(); auto addr = parentAddress->getResolvedAddress();
if (!addr) if (!addr)

View File

@@ -63,35 +63,30 @@ public:
/// A symbolic relocated absolute pointer value. /// A symbolic relocated absolute pointer value.
class RemoteAbsolutePointer { class RemoteAbsolutePointer {
/// The symbol name that the pointer refers to. Empty if the value is absolute. /// The symbol name that the pointer refers to. Empty if only an absolute
/// address is available.
std::string Symbol; std::string Symbol;
/// The offset from the symbol, or the resolved remote address if \c Symbol is empty. /// The offset from the symbol.
int64_t Offset; int64_t Offset = 0;
/// The resolved remote address.
RemoteAddress Address = RemoteAddress{(uint64_t)0};
public: public:
RemoteAbsolutePointer() RemoteAbsolutePointer() = default;
: Symbol(), Offset(0) RemoteAbsolutePointer(std::nullptr_t) : RemoteAbsolutePointer() {}
{}
RemoteAbsolutePointer(llvm::StringRef Symbol, int64_t Offset,
RemoteAbsolutePointer(std::nullptr_t) RemoteAddress Address)
: RemoteAbsolutePointer() : Symbol(Symbol), Offset(Offset), Address(Address) {}
{} RemoteAbsolutePointer(RemoteAddress Address) : Address(Address) {}
RemoteAbsolutePointer(llvm::StringRef Symbol, int64_t Offset)
: Symbol(Symbol), Offset(Offset)
{}
bool isResolved() const { return Symbol.empty(); }
llvm::StringRef getSymbol() const { return Symbol; } llvm::StringRef getSymbol() const { return Symbol; }
int64_t getOffset() const { return Offset; } int64_t getOffset() const { return Offset; }
RemoteAddress getResolvedAddress() const { RemoteAddress getResolvedAddress() const { return Address; }
assert(isResolved());
return RemoteAddress(Offset);
}
explicit operator bool() const { explicit operator bool() const {
return Offset != 0 || !Symbol.empty(); return Address || !Symbol.empty();
} }
}; };

View File

@@ -1019,7 +1019,7 @@ public:
auto CDAddr = this->readCaptureDescriptorFromMetadata(*MetadataAddress); auto CDAddr = this->readCaptureDescriptorFromMetadata(*MetadataAddress);
if (!CDAddr) if (!CDAddr)
return nullptr; return nullptr;
if (!CDAddr->isResolved()) if (!CDAddr->getResolvedAddress())
return nullptr; return nullptr;
// FIXME: Non-generic SIL boxes also use the HeapLocalVariable metadata // FIXME: Non-generic SIL boxes also use the HeapLocalVariable metadata

View File

@@ -1871,7 +1871,7 @@ private:
if (auto symbol = OpaquePointerReader( if (auto symbol = OpaquePointerReader(
remote::RemoteAddress(adjustedProtocolDescriptorTarget), remote::RemoteAddress(adjustedProtocolDescriptorTarget),
PointerSize)) { PointerSize)) {
if (!symbol->getSymbol().empty()) { if (!symbol->getSymbol().empty() && symbol->getOffset() == 0) {
Demangle::Context Ctx; Demangle::Context Ctx;
auto demangledRoot = auto demangledRoot =
Ctx.demangleSymbolAsNode(symbol->getSymbol().str()); Ctx.demangleSymbolAsNode(symbol->getSymbol().str());
@@ -1882,7 +1882,8 @@ private:
nodeToString(demangledRoot->getChild(0)->getChild(0)); nodeToString(demangledRoot->getChild(0)->getChild(0));
} else { } else {
// This is an absolute address of a protocol descriptor // This is an absolute address of a protocol descriptor
auto protocolDescriptorAddress = (uintptr_t)symbol->getOffset(); auto protocolDescriptorAddress =
(uintptr_t)symbol->getResolvedAddress().getAddressData();
protocolName = readFullyQualifiedProtocolNameFromProtocolDescriptor( protocolName = readFullyQualifiedProtocolNameFromProtocolDescriptor(
protocolDescriptorAddress); protocolDescriptorAddress);
} }
@@ -2026,7 +2027,7 @@ private:
if (auto symbol = OpaquePointerReader( if (auto symbol = OpaquePointerReader(
remote::RemoteAddress(adjustedParentTargetAddress), remote::RemoteAddress(adjustedParentTargetAddress),
PointerSize)) { PointerSize)) {
if (!symbol->getSymbol().empty()) { if (!symbol->getSymbol().empty() && symbol->getOffset() == 0) {
Demangle::Context Ctx; Demangle::Context Ctx;
auto demangledRoot = auto demangledRoot =
Ctx.demangleSymbolAsNode(symbol->getSymbol().str()); Ctx.demangleSymbolAsNode(symbol->getSymbol().str());
@@ -2264,7 +2265,7 @@ private:
// external, check that first // external, check that first
if (auto symbol = OpaqueDynamicSymbolResolver( if (auto symbol = OpaqueDynamicSymbolResolver(
remote::RemoteAddress(contextTypeDescriptorAddress))) { remote::RemoteAddress(contextTypeDescriptorAddress))) {
if (!symbol->isResolved()) { if (!symbol->getSymbol().empty() && symbol->getOffset() == 0) {
Demangle::Context Ctx; Demangle::Context Ctx;
auto demangledRoot = auto demangledRoot =
Ctx.demangleSymbolAsNode(symbol->getSymbol().str()); Ctx.demangleSymbolAsNode(symbol->getSymbol().str());
@@ -2283,10 +2284,11 @@ private:
mangledTypeName = typeMangling.result(); mangledTypeName = typeMangling.result();
return std::make_pair(mangledTypeName, typeName); return std::make_pair(mangledTypeName, typeName);
} else if (symbol->getOffset()) { } else if (symbol->getResolvedAddress()) {
// If symbol is empty and has an offset, this is the resolved remote // If symbol is empty and has an offset, this is the resolved remote
// address // address
contextTypeDescriptorAddress = symbol->getOffset(); contextTypeDescriptorAddress =
symbol->getResolvedAddress().getAddressData();
} }
} }

View File

@@ -322,9 +322,9 @@ Image::resolvePointer(uint64_t Addr, uint64_t pointerValue) const {
// 32 bits. // 32 bits.
if (isMachOWithPtrAuth()) { if (isMachOWithPtrAuth()) {
return remote::RemoteAbsolutePointer( return remote::RemoteAbsolutePointer(
"", HeaderAddress + (pointerValue & 0xffffffffull)); remote::RemoteAddress(HeaderAddress + (pointerValue & 0xffffffffull)));
} else { } else {
return remote::RemoteAbsolutePointer("", pointerValue); return remote::RemoteAbsolutePointer(remote::RemoteAddress(pointerValue));
} }
} }
@@ -333,7 +333,8 @@ remote::RemoteAbsolutePointer Image::getDynamicSymbol(uint64_t Addr) const {
if (found == DynamicRelocations.end()) if (found == DynamicRelocations.end())
return nullptr; return nullptr;
return remote::RemoteAbsolutePointer(found->second.Symbol, return remote::RemoteAbsolutePointer(found->second.Symbol,
found->second.Offset); found->second.Offset,
remote::RemoteAddress((uint64_t)0));
} }
std::pair<const Image *, uint64_t> std::pair<const Image *, uint64_t>
@@ -526,8 +527,8 @@ ObjectMemoryReader::resolvePointer(reflection::RemoteAddress Addr,
// Mix in the image index again to produce a remote address pointing into the // Mix in the image index again to produce a remote address pointing into the
// same image. // same image.
return remote::RemoteAbsolutePointer( return remote::RemoteAbsolutePointer(
"", encodeImageIndexAndAddress( remote::RemoteAddress(encodeImageIndexAndAddress(
image, resolved.getResolvedAddress().getAddressData())); image, resolved.getResolvedAddress().getAddressData())));
} }
remote::RemoteAbsolutePointer remote::RemoteAbsolutePointer