From 9381a54c67a0df88a266a0a0e45f95d065eb7eaf Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 17 Jun 2025 16:57:19 -0700 Subject: [PATCH] [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 --- include/swift/Remote/MemoryReader.h | 4 +- include/swift/Remote/MetadataReader.h | 44 +++++-------------- include/swift/Remote/RemoteAddress.h | 41 ++++++++--------- .../RemoteInspection/ReflectionContext.h | 2 +- .../swift/RemoteInspection/TypeRefBuilder.h | 14 +++--- lib/StaticMirror/ObjectFileContext.cpp | 11 ++--- 6 files changed, 46 insertions(+), 70 deletions(-) diff --git a/include/swift/Remote/MemoryReader.h b/include/swift/Remote/MemoryReader.h index 7e077a5f7d068..772bcfbdfbc3e 100644 --- a/include/swift/Remote/MemoryReader.h +++ b/include/swift/Remote/MemoryReader.h @@ -147,7 +147,7 @@ class MemoryReader { virtual RemoteAbsolutePointer resolvePointer(RemoteAddress address, uint64_t readValue) { // Default implementation returns the read value as is. - return RemoteAbsolutePointer("", readValue); + return RemoteAbsolutePointer(RemoteAddress(readValue)); } /// Performs the inverse operation of \ref resolvePointer. @@ -166,7 +166,7 @@ class MemoryReader { virtual RemoteAbsolutePointer getSymbol(RemoteAddress address) { if (auto symbol = resolvePointerAsSymbol(address)) return *symbol; - return RemoteAbsolutePointer("", address.getAddressData()); + return RemoteAbsolutePointer(address); } /// Lookup a dynamic symbol name (ie dynamic loader binding) for the given diff --git a/include/swift/Remote/MetadataReader.h b/include/swift/Remote/MetadataReader.h index a7d9485e6ad03..ee4dc8e0cdc16 100644 --- a/include/swift/Remote/MetadataReader.h +++ b/include/swift/Remote/MetadataReader.h @@ -416,11 +416,9 @@ class MetadataReader { } RemoteAbsolutePointer stripSignedPointer(const RemoteAbsolutePointer &P) { - if (P.isResolved()) { - return RemoteAbsolutePointer("", - P.getResolvedAddress().getAddressData() & PtrAuthMask); - } - return P; + return RemoteAbsolutePointer( + P.getSymbol(), P.getOffset(), + RemoteAddress(P.getResolvedAddress().getAddressData() & PtrAuthMask)); } StoredPointer queryPtrAuthMask() { @@ -519,14 +517,6 @@ class MetadataReader { // The second entry is a relative address to the mangled protocol // 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 = resolved.getResolvedAddress().getAddressData() + sizeof(int32_t); int32_t offset; @@ -534,14 +524,6 @@ class MetadataReader { auto addrOfTypeRef = addr + offset; 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. auto protocolList = readMangledName(resolved.getResolvedAddress(), MangledNameKind::Type, dem); @@ -1379,12 +1361,10 @@ class MetadataReader { ParentContextDescriptorRef readContextDescriptor(const RemoteAbsolutePointer &address) { // 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. - if (address.getOffset() != 0) { - return ParentContextDescriptorRef(); - } - return ParentContextDescriptorRef(address.getSymbol()); + if (address.getOffset() == 0) + return ParentContextDescriptorRef(address.getSymbol()); } return ParentContextDescriptorRef( @@ -2016,7 +1996,7 @@ class MetadataReader { std::optional readResolvedPointerValue(StoredPointer address) { if (auto pointer = readPointer(address)) { - if (!pointer->isResolved()) + if (!pointer->getResolvedAddress()) return std::nullopt; return (StoredPointer)pointer->getResolvedAddress().getAddressData(); } @@ -2079,7 +2059,7 @@ class MetadataReader { return std::nullopt; } - return RemoteAbsolutePointer("", resultAddress); + return RemoteAbsolutePointer(RemoteAddress(resultAddress)); } /// Given a pointer to an Objective-C class, try to read its class name. @@ -2335,13 +2315,11 @@ class MetadataReader { auto parentAddress = resolveRelativeIndirectableField(base, base->Parent); if (!parentAddress) return std::nullopt; - if (!parentAddress->isResolved()) { + if (!parentAddress->getSymbol().empty()) { // Currently we can only handle references directly to a symbol without // an offset. - if (parentAddress->getOffset() != 0) { - return std::nullopt; - } - return ParentContextDescriptorRef(parentAddress->getSymbol()); + if (parentAddress->getOffset() == 0) + return ParentContextDescriptorRef(parentAddress->getSymbol()); } auto addr = parentAddress->getResolvedAddress(); if (!addr) diff --git a/include/swift/Remote/RemoteAddress.h b/include/swift/Remote/RemoteAddress.h index 15c10aa23c216..611234f205cfe 100644 --- a/include/swift/Remote/RemoteAddress.h +++ b/include/swift/Remote/RemoteAddress.h @@ -63,35 +63,30 @@ class RemoteAddress { /// A symbolic relocated absolute pointer value. 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; - /// The offset from the symbol, or the resolved remote address if \c Symbol is empty. - int64_t Offset; + /// The offset from the symbol. + int64_t Offset = 0; + /// The resolved remote address. + RemoteAddress Address = RemoteAddress{(uint64_t)0}; public: - RemoteAbsolutePointer() - : Symbol(), Offset(0) - {} - - RemoteAbsolutePointer(std::nullptr_t) - : RemoteAbsolutePointer() - {} - - RemoteAbsolutePointer(llvm::StringRef Symbol, int64_t Offset) - : Symbol(Symbol), Offset(Offset) - {} - - bool isResolved() const { return Symbol.empty(); } + RemoteAbsolutePointer() = default; + RemoteAbsolutePointer(std::nullptr_t) : RemoteAbsolutePointer() {} + + RemoteAbsolutePointer(llvm::StringRef Symbol, int64_t Offset, + RemoteAddress Address) + : Symbol(Symbol), Offset(Offset), Address(Address) {} + RemoteAbsolutePointer(RemoteAddress Address) : Address(Address) {} + llvm::StringRef getSymbol() const { return Symbol; } int64_t getOffset() const { return Offset; } - - RemoteAddress getResolvedAddress() const { - assert(isResolved()); - return RemoteAddress(Offset); - } - + + RemoteAddress getResolvedAddress() const { return Address; } + explicit operator bool() const { - return Offset != 0 || !Symbol.empty(); + return Address || !Symbol.empty(); } }; diff --git a/include/swift/RemoteInspection/ReflectionContext.h b/include/swift/RemoteInspection/ReflectionContext.h index 76f5e33365c25..4001d58064b09 100644 --- a/include/swift/RemoteInspection/ReflectionContext.h +++ b/include/swift/RemoteInspection/ReflectionContext.h @@ -1019,7 +1019,7 @@ class ReflectionContext auto CDAddr = this->readCaptureDescriptorFromMetadata(*MetadataAddress); if (!CDAddr) return nullptr; - if (!CDAddr->isResolved()) + if (!CDAddr->getResolvedAddress()) return nullptr; // FIXME: Non-generic SIL boxes also use the HeapLocalVariable metadata diff --git a/include/swift/RemoteInspection/TypeRefBuilder.h b/include/swift/RemoteInspection/TypeRefBuilder.h index 63d2f4dc1719a..960536977a9a1 100644 --- a/include/swift/RemoteInspection/TypeRefBuilder.h +++ b/include/swift/RemoteInspection/TypeRefBuilder.h @@ -1871,7 +1871,7 @@ class TypeRefBuilder { if (auto symbol = OpaquePointerReader( remote::RemoteAddress(adjustedProtocolDescriptorTarget), PointerSize)) { - if (!symbol->getSymbol().empty()) { + if (!symbol->getSymbol().empty() && symbol->getOffset() == 0) { Demangle::Context Ctx; auto demangledRoot = Ctx.demangleSymbolAsNode(symbol->getSymbol().str()); @@ -1882,7 +1882,8 @@ class TypeRefBuilder { nodeToString(demangledRoot->getChild(0)->getChild(0)); } else { // This is an absolute address of a protocol descriptor - auto protocolDescriptorAddress = (uintptr_t)symbol->getOffset(); + auto protocolDescriptorAddress = + (uintptr_t)symbol->getResolvedAddress().getAddressData(); protocolName = readFullyQualifiedProtocolNameFromProtocolDescriptor( protocolDescriptorAddress); } @@ -2026,7 +2027,7 @@ class TypeRefBuilder { if (auto symbol = OpaquePointerReader( remote::RemoteAddress(adjustedParentTargetAddress), PointerSize)) { - if (!symbol->getSymbol().empty()) { + if (!symbol->getSymbol().empty() && symbol->getOffset() == 0) { Demangle::Context Ctx; auto demangledRoot = Ctx.demangleSymbolAsNode(symbol->getSymbol().str()); @@ -2264,7 +2265,7 @@ class TypeRefBuilder { // external, check that first if (auto symbol = OpaqueDynamicSymbolResolver( remote::RemoteAddress(contextTypeDescriptorAddress))) { - if (!symbol->isResolved()) { + if (!symbol->getSymbol().empty() && symbol->getOffset() == 0) { Demangle::Context Ctx; auto demangledRoot = Ctx.demangleSymbolAsNode(symbol->getSymbol().str()); @@ -2283,10 +2284,11 @@ class TypeRefBuilder { mangledTypeName = typeMangling.result(); 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 // address - contextTypeDescriptorAddress = symbol->getOffset(); + contextTypeDescriptorAddress = + symbol->getResolvedAddress().getAddressData(); } } diff --git a/lib/StaticMirror/ObjectFileContext.cpp b/lib/StaticMirror/ObjectFileContext.cpp index 397321d8254c1..a2bca9bcc0d77 100644 --- a/lib/StaticMirror/ObjectFileContext.cpp +++ b/lib/StaticMirror/ObjectFileContext.cpp @@ -322,9 +322,9 @@ Image::resolvePointer(uint64_t Addr, uint64_t pointerValue) const { // 32 bits. if (isMachOWithPtrAuth()) { return remote::RemoteAbsolutePointer( - "", HeaderAddress + (pointerValue & 0xffffffffull)); + remote::RemoteAddress(HeaderAddress + (pointerValue & 0xffffffffull))); } 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()) return nullptr; return remote::RemoteAbsolutePointer(found->second.Symbol, - found->second.Offset); + found->second.Offset, + remote::RemoteAddress((uint64_t)0)); } std::pair @@ -526,8 +527,8 @@ ObjectMemoryReader::resolvePointer(reflection::RemoteAddress Addr, // Mix in the image index again to produce a remote address pointing into the // same image. return remote::RemoteAbsolutePointer( - "", encodeImageIndexAndAddress( - image, resolved.getResolvedAddress().getAddressData())); + remote::RemoteAddress(encodeImageIndexAndAddress( + image, resolved.getResolvedAddress().getAddressData()))); } remote::RemoteAbsolutePointer