From ac62ffcbf81522a695ea480f08d76c8c61f778c1 Mon Sep 17 00:00:00 2001 From: Augusto Noronha Date: Thu, 10 Jul 2025 17:48:11 -0700 Subject: [PATCH 1/2] [NFC][RemoteMirrors] Add "template" in front of calls to readRemoteAddress (cherry picked from commit 16591e4d0ebe903adf80767fcf005ea91b335423) --- include/swift/Remote/MetadataReader.h | 35 ++++++++++++++------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/include/swift/Remote/MetadataReader.h b/include/swift/Remote/MetadataReader.h index 5c682f9233a51..d156ff67b3cf4 100644 --- a/include/swift/Remote/MetadataReader.h +++ b/include/swift/Remote/MetadataReader.h @@ -801,8 +801,8 @@ class MetadataReader { // Non-inline (box'ed) representation. // The first word of the container stores the address to the box. RemoteAddress BoxAddress; - if (!Reader->readRemoteAddress(ExistentialAddress, - BoxAddress)) + if (!Reader->template readRemoteAddress(ExistentialAddress, + BoxAddress)) return std::nullopt; auto AlignmentMask = VWT->getAlignmentMask(); @@ -1694,7 +1694,7 @@ class MetadataReader { StoredPointer tag) -> std::optional { RemoteAddress addr = base + tag * sizeof(StoredPointer); RemoteAddress isa; - if (!Reader->readRemoteAddress(addr, isa)) + if (!Reader->template readRemoteAddress(addr, isa)) return std::nullopt; return isa; }; @@ -1724,7 +1724,7 @@ class MetadataReader { return readMetadataFromTaggedPointer(objectAddress); RemoteAddress isa; - if (!Reader->readRemoteAddress(objectAddress, isa)) + if (!Reader->template readRemoteAddress(objectAddress, isa)) return std::nullopt; switch (getIsaEncoding()) { @@ -1773,8 +1773,8 @@ class MetadataReader { RemoteAddress(IndexedClassesPointer + classIndex * sizeof(StoredPointer)); RemoteAddress metadataPointer; - if (!Reader->readRemoteAddress(eltPointer, - metadataPointer)) + if (!Reader->template readRemoteAddress(eltPointer, + metadataPointer)) return std::nullopt; return metadataPointer; @@ -1922,7 +1922,7 @@ class MetadataReader { case TypeReferenceKind::IndirectObjCClass: { RemoteAddress classRef; - if (!Reader->readRemoteAddress(ref, classRef)) + if (!Reader->template readRemoteAddress(ref, classRef)) return std::nullopt; auto metadata = readMetadata(classRef); @@ -1970,8 +1970,8 @@ class MetadataReader { return std::nullopt; RemoteAddress genericArgAddress; - if (!Reader->readRemoteAddress(addressOfGenericArgAddress, - genericArgAddress)) + if (!Reader->template readRemoteAddress( + addressOfGenericArgAddress, genericArgAddress)) return std::nullopt; return genericArgAddress; @@ -2107,8 +2107,8 @@ class MetadataReader { // Read the name pointer. RemoteAddress namePtr; - if (!Reader->readRemoteAddress(roDataPtr + OffsetToName, - namePtr)) + if (!Reader->template readRemoteAddress( + roDataPtr + OffsetToName, namePtr)) return false; // If the name pointer is null, treat that as an error. @@ -2172,8 +2172,8 @@ class MetadataReader { // the generalization arguments are. RemoteAddress shapeAddress = address + sizeof(StoredPointer); RemoteAddress signedShapePtr; - if (!Reader->readRemoteAddress(shapeAddress, - signedShapePtr)) + if (!Reader->template readRemoteAddress(shapeAddress, + signedShapePtr)) return nullptr; auto shapePtr = stripSignedPointer(signedShapePtr); @@ -2637,8 +2637,8 @@ class MetadataReader { // Low bit set in the offset indicates that the offset leads to the absolute // address in memory. if (indirect) { - if (!Reader->readRemoteAddress(resultAddress, - resultAddress)) + if (!Reader->template readRemoteAddress(resultAddress, + resultAddress)) return RemoteAddress(); } @@ -3152,7 +3152,8 @@ class MetadataReader { --numGenericArgs; RemoteAddress arg; - if (!Reader->readRemoteAddress(genericArgsAddr, arg)) { + if (!Reader->template readRemoteAddress( + genericArgsAddr, arg)) { return {}; } genericArgsAddr += sizeof(StoredPointer); @@ -3281,7 +3282,7 @@ class MetadataReader { #if SWIFT_OBJC_INTEROP RemoteAddress dataPtr; - if (!Reader->readRemoteAddress( + if (!Reader->template readRemoteAddress( classAddress + TargetClassMetadataObjCInterop::offsetToData(), dataPtr)) return RemoteAddress(); From 2ec8f057caba5098ed6ccbc8f0c7f8092fe67c0a Mon Sep 17 00:00:00 2001 From: Augusto Noronha Date: Wed, 16 Jul 2025 21:22:32 -0700 Subject: [PATCH 2/2] [RemoteInspection] Make MemoryReader::readRemoteAddress virtual Allow subclasses to override the behavior of readRemoteAddress. LLDB in particular needs this to correctly set the address space of the result remote address. rdar://148361743 (cherry picked from commit 45d6d456234f7f1a46b7d2bb159fc3f08cfb513a) --- include/swift/Remote/MemoryReader.h | 44 ++++++++++++++++++++++++---- include/swift/Remote/RemoteAddress.h | 2 +- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/include/swift/Remote/MemoryReader.h b/include/swift/Remote/MemoryReader.h index fddcc495d0834..88d58d1ee6e60 100644 --- a/include/swift/Remote/MemoryReader.h +++ b/include/swift/Remote/MemoryReader.h @@ -64,12 +64,10 @@ class MemoryReader { /// Returns false if the operator failed. template bool readRemoteAddress(RemoteAddress address, RemoteAddress &out) { - IntegerType buf; - if (!readInteger(address, &buf)) - return false; - - out = RemoteAddress((uint64_t)buf, address.getAddressSpace()); - return true; + constexpr std::size_t integerSize = sizeof(IntegerType); + static_assert((integerSize == 4 || integerSize == 8) && + "Only 32 or 64 bit architectures are supported!"); + return readRemoteAddressImpl(address, out, integerSize); } /// Attempts to read an integer from the given address in the remote @@ -280,6 +278,40 @@ class MemoryReader { } virtual ~MemoryReader() = default; + +protected: + /// Implementation detail of remoteRemoteAddress. This exists because + /// templated functions cannot be virtual. + /// + /// Attempts to read a remote address of a given size from the given address + /// in the remote process. + /// + /// Returns false if the operator failed. + virtual bool readRemoteAddressImpl(RemoteAddress address, RemoteAddress &out, + std::size_t integerSize) { + assert((integerSize == 4 || integerSize == 8) && + "Only 32 or 64 bit architectures are supported!"); + auto Buf = std::malloc(integerSize); + if (!Buf) + return false; + + // Free Buf when this function return. + ReadBytesResult Result( + Buf, [](const void *ptr) { free(const_cast(ptr)); }); + if (!readBytes(address, reinterpret_cast(Buf), integerSize)) + return false; + + if (integerSize == 4) + out = RemoteAddress(*reinterpret_cast(Buf), + address.getAddressSpace()); + else if (integerSize == 8) + out = RemoteAddress(*reinterpret_cast(Buf), + address.getAddressSpace()); + else + return false; + + return true; + } }; } // end namespace remote diff --git a/include/swift/Remote/RemoteAddress.h b/include/swift/Remote/RemoteAddress.h index 91313cbd31b92..ccb886d6f83b7 100644 --- a/include/swift/Remote/RemoteAddress.h +++ b/include/swift/Remote/RemoteAddress.h @@ -56,7 +56,7 @@ class RemoteAddress { } bool inRange(const RemoteAddress &begin, const RemoteAddress &end) const { - assert(begin.AddressSpace != end.AddressSpace && + assert(begin.AddressSpace == end.AddressSpace && "Unexpected address spaces"); if (AddressSpace != begin.AddressSpace) return false;