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/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(); 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;