From e2c8b761cd916cb2c9d92356647422d54f63a1f8 Mon Sep 17 00:00:00 2001 From: Augusto Noronha Date: Wed, 9 Jul 2025 14:52:42 -0700 Subject: [PATCH] [NFC][RemoteInspection] Add an opaque AddressSpace field to RemoteAddress Add an extra opaque field to AddressSpace, which can be used by clients of RemoteInspection to distinguish between different address spaces. LLDB employs an optimization where it reads memory from files instead of the running process whenever it can to speed up memory reads (these can be slow when debugging something over a network). To do this, it needs to keep track whether an address originated from a process or a file. It currently distinguishes addresses by setting an unused high bit on the address, but because of pointer authentication this is not a reliable solution. In order to keep this optimization working, this patch adds an extra opaque AddressSpace field to RemoteAddress, which LLDB can use on its own implementation of MemoryReader to distinguish between addresses. This patch is NFC for the other RemoteInspection clients, as it adds extra information to RemoteAddress, which is entirely optional and if unused should not change the behavior of the library. Although this patch is quite big the changes are largely mechanical, replacing threading StoredPointer with RemoteAddress. rdar://148361743 (cherry picked from commit 58df5534d2917ca545463b40ca738e5c54c40c89) (cherry picked from commit 8f3862b5e758fa7348760e772e6fcf95c52b06ab) --- include/swift/Basic/RelativePointer.h | 3 + include/swift/Remote/CMemoryReader.h | 14 +- include/swift/Remote/Failure.h | 2 +- include/swift/Remote/InProcessMemoryReader.h | 6 +- include/swift/Remote/MemoryReader.h | 25 +- include/swift/Remote/MetadataReader.h | 636 +++++++++--------- include/swift/Remote/RemoteAddress.h | 203 +++++- .../RemoteInspection/ReflectionContext.h | 285 ++++---- .../swift/RemoteInspection/TypeRefBuilder.h | 237 +++---- .../swift/StaticMirror/ObjectFileContext.h | 11 +- lib/RemoteAST/InProcessMemoryReader.cpp | 2 +- lib/RemoteAST/RemoteAST.cpp | 36 +- lib/StaticMirror/ObjectFileContext.cpp | 54 +- .../public/RemoteInspection/TypeLowering.cpp | 3 +- .../RemoteInspection/TypeRefBuilder.cpp | 35 +- .../SwiftRemoteMirror/SwiftRemoteMirror.cpp | 94 ++- .../swift-reflection-fuzzer.cpp | 9 +- .../swift-remoteast-test.cpp | 23 +- 18 files changed, 970 insertions(+), 708 deletions(-) diff --git a/include/swift/Basic/RelativePointer.h b/include/swift/Basic/RelativePointer.h index a42801d0d74..4d53652a949 100644 --- a/include/swift/Basic/RelativePointer.h +++ b/include/swift/Basic/RelativePointer.h @@ -132,7 +132,10 @@ #ifndef SWIFT_BASIC_RELATIVEPOINTER_H #define SWIFT_BASIC_RELATIVEPOINTER_H +#include #include +#include +#include namespace swift { diff --git a/include/swift/Remote/CMemoryReader.h b/include/swift/Remote/CMemoryReader.h index 3805b76c7cd..6cb8b7f277a 100644 --- a/include/swift/Remote/CMemoryReader.h +++ b/include/swift/Remote/CMemoryReader.h @@ -69,7 +69,7 @@ class CMemoryReader final : public MemoryReader { // that we're likely failing to strip a signed pointer when reading from it. bool hasSignatureBits(RemoteAddress address) { return false; - uint64_t addressData = address.getAddressData(); + uint64_t addressData = address.getRawAddress(); return addressData != (addressData & getPtrauthMask()); } @@ -89,13 +89,12 @@ public: RemoteAddress getSymbolAddress(const std::string &name) override { auto addressData = Impl.getSymbolAddress(Impl.reader_context, name.c_str(), name.size()); - return RemoteAddress(addressData); + return RemoteAddress(addressData, RemoteAddress::DefaultAddressSpace); } uint64_t getStringLength(RemoteAddress address) { assert(!hasSignatureBits(address)); - return Impl.getStringLength(Impl.reader_context, - address.getAddressData()); + return Impl.getStringLength(Impl.reader_context, address.getRawAddress()); } bool readString(RemoteAddress address, std::string &dest) override { @@ -120,7 +119,7 @@ public: ReadBytesResult readBytes(RemoteAddress address, uint64_t size) override { assert(!hasSignatureBits(address)); void *FreeContext; - auto Ptr = Impl.readBytes(Impl.reader_context, address.getAddressData(), + auto Ptr = Impl.readBytes(Impl.reader_context, address.getRawAddress(), size, &FreeContext); auto Free = Impl.free; @@ -134,8 +133,7 @@ public: return ReadBytesResult(Ptr, freeLambda); } }; - -} -} +} // namespace remote +} // namespace swift #endif diff --git a/include/swift/Remote/Failure.h b/include/swift/Remote/Failure.h index 908e6357c02..916c7489292 100644 --- a/include/swift/Remote/Failure.h +++ b/include/swift/Remote/Failure.h @@ -288,7 +288,7 @@ public: case ArgStorageKind::Address: { result += '0'; result += 'x'; - uint64_t address = Args[argIndex].Address.getAddressData(); + uint64_t address = Args[argIndex].Address.getRawAddress(); unsigned max = ((address >> 32) != 0 ? 16 : 8); for (unsigned i = 0; i != max; ++i) { result += "0123456789abcdef"[(address >> (max - 1 - i) * 4) & 0xF]; diff --git a/include/swift/Remote/InProcessMemoryReader.h b/include/swift/Remote/InProcessMemoryReader.h index 9fa78a28308..dbe7351317a 100644 --- a/include/swift/Remote/InProcessMemoryReader.h +++ b/include/swift/Remote/InProcessMemoryReader.h @@ -105,8 +105,8 @@ class InProcessMemoryReader final : public MemoryReader { return ReadBytesResult(address.getLocalPointer(), [](const void *) {}); } }; - -} -} + +} // namespace remote +} // namespace swift #endif diff --git a/include/swift/Remote/MemoryReader.h b/include/swift/Remote/MemoryReader.h index 772bcfbdfbc..fddcc495d08 100644 --- a/include/swift/Remote/MemoryReader.h +++ b/include/swift/Remote/MemoryReader.h @@ -57,13 +57,31 @@ public: /// /// Returns false if the operation failed. virtual bool readString(RemoteAddress address, std::string &dest) = 0; - + + /// Attempts to read a remote address from the given address in the remote + /// process. + /// + /// 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; + } + /// Attempts to read an integer from the given address in the remote /// process. /// /// Returns false if the operation failed. template bool readInteger(RemoteAddress address, IntegerType *dest) { + static_assert(!std::is_same(), + "RemoteAddress cannot be read in directly, use " + "readRemoteAddress instead."); + return readBytes(address, reinterpret_cast(dest), sizeof(IntegerType)); } @@ -147,7 +165,8 @@ public: virtual RemoteAbsolutePointer resolvePointer(RemoteAddress address, uint64_t readValue) { // Default implementation returns the read value as is. - return RemoteAbsolutePointer(RemoteAddress(readValue)); + return RemoteAbsolutePointer( + RemoteAddress(readValue, address.getAddressSpace())); } /// Performs the inverse operation of \ref resolvePointer. @@ -263,7 +282,7 @@ public: virtual ~MemoryReader() = default; }; -} // end namespace reflection +} // end namespace remote } // end namespace swift #endif // SWIFT_REFLECTION_READER_H diff --git a/include/swift/Remote/MetadataReader.h b/include/swift/Remote/MetadataReader.h index ee4dc8e0cdc..5c682f9233a 100644 --- a/include/swift/Remote/MetadataReader.h +++ b/include/swift/Remote/MetadataReader.h @@ -58,19 +58,17 @@ enum class MangledNameKind { template class RemoteRef { private: - uint64_t Address; + RemoteAddress Address; const T *LocalBuffer; public: - RemoteRef() - : Address(0), LocalBuffer(nullptr) {} + RemoteRef() : Address(), LocalBuffer(nullptr) {} /*implicit*/ RemoteRef(std::nullptr_t _) : RemoteRef() {} - template - explicit RemoteRef(StoredPointer address, const T *localBuffer) - : Address((uint64_t)address), LocalBuffer(localBuffer) {} + explicit RemoteRef(RemoteAddress address, const T *localBuffer) + : Address(address), LocalBuffer(localBuffer) {} // Some versions of clang++ sometimes fail to generate the // copy constructor for this type correctly - add a workaround @@ -83,9 +81,7 @@ public: return *this; } - uint64_t getAddressData() const { - return Address; - } + RemoteAddress getRemoteAddress() const { return Address; } const T *getLocalBuffer() const { return LocalBuffer; @@ -113,23 +109,23 @@ public: template RemoteRef getField(U &field) const { auto offset = (intptr_t)&field - (intptr_t)LocalBuffer; - return RemoteRef((uint64_t)(Address + (int64_t)offset), &field); + return RemoteRef((Address + (int64_t)offset), &field); } /// Resolve the remote address of a relative offset stored at the remote address. - uint64_t resolveRelativeAddressData() const { + RemoteAddress resolveRelativeAddressData() const { int32_t offset; memcpy(&offset, LocalBuffer, sizeof(int32_t)); if (offset == 0) - return 0; + return RemoteAddress(); return Address + (int64_t)offset; } - - template - uint64_t resolveRelativeFieldData(U &field) const { + + template + RemoteAddress resolveRelativeFieldData(U &field) const { return getField(field).resolveRelativeAddressData(); } - + RemoteRef atByteOffset(int64_t Offset) const { return RemoteRef(Address + Offset, (const T *)((intptr_t)LocalBuffer + Offset)); @@ -195,10 +191,10 @@ private: /// amounts of data when we encounter corrupt values for sizes/counts. static const uint64_t MaxMetadataSize = 1048576; // 1MB - /// The dense map info for a std::pair. + /// The dense map info for a std::pair. struct DenseMapInfoTypeCacheKey { - using Pair = std::pair; - using StoredPointerInfo = llvm::DenseMapInfo; + using Pair = std::pair; + using StoredPointerInfo = llvm::DenseMapInfo; static inline Pair getEmptyKey() { // Since bool doesn't have an empty key implementation, we only use the @@ -223,7 +219,7 @@ private: /// A cache of built types, keyed by the address of the type and whether the /// request ignored articial superclasses or not. - llvm::DenseMap, BuiltType, + llvm::DenseMap, BuiltType, DenseMapInfoTypeCacheKey> TypeCache; @@ -231,7 +227,7 @@ private: using OwnedMetadataRef = MemoryReader::ReadBytesResult; /// A cache of read type metadata, keyed by the address of the metadata. - llvm::DenseMap MetadataCache; + llvm::DenseMap MetadataCache; using ContextDescriptorRef = RemoteRef>; @@ -313,14 +309,14 @@ private: /// A cache of read nominal type descriptors, keyed by the address of the /// nominal type descriptor. - llvm::DenseMap + llvm::DenseMap ContextDescriptorCache; using OwnedProtocolDescriptorRef = std::unique_ptr, delete_with_free>; /// A cache of read extended existential shape metadata, keyed by the /// address of the shape metadata. - llvm::DenseMap ShapeCache; + llvm::DenseMap ShapeCache; enum class IsaEncodingKind { /// We haven't checked yet. @@ -359,8 +355,8 @@ private: StoredPointer IsaIndexShift; StoredPointer IsaMagicMask; StoredPointer IsaMagicValue; - StoredPointer IndexedClassesPointer; - StoredPointer IndexedClassesCountPointer; + RemoteAddress IndexedClassesPointer; + RemoteAddress IndexedClassesCountPointer; StoredPointer LastIndexedClassesCount = 0; enum class TaggedPointerEncodingKind { @@ -389,11 +385,11 @@ private: StoredPointer TaggedPointerMask; StoredPointer TaggedPointerSlotShift; StoredPointer TaggedPointerSlotMask; - StoredPointer TaggedPointerClasses; + RemoteAddress TaggedPointerClasses; StoredPointer TaggedPointerExtendedMask; StoredPointer TaggedPointerExtendedSlotShift; StoredPointer TaggedPointerExtendedSlotMask; - StoredPointer TaggedPointerExtendedClasses; + RemoteAddress TaggedPointerExtendedClasses; StoredPointer TaggedPointerObfuscator; Demangle::NodeFactory Factory; @@ -411,14 +407,21 @@ public: StoredPointer PtrAuthMask; - StoredPointer stripSignedPointer(StoredSignedPointer P) { - return P.SignedValue & PtrAuthMask; + RemoteAddress stripSignedPointer(RemoteAddress P) { + // Only pointers in the default address space are signed. + if (P.getAddressSpace() == RemoteAddress::DefaultAddressSpace) + return P & PtrAuthMask; + return P; + } + + RemoteAddress stripSignedPointer(StoredSignedPointer P) { + return RemoteAddress(P.SignedValue & PtrAuthMask, + RemoteAddress::DefaultAddressSpace); } RemoteAbsolutePointer stripSignedPointer(const RemoteAbsolutePointer &P) { - return RemoteAbsolutePointer( - P.getSymbol(), P.getOffset(), - RemoteAddress(P.getResolvedAddress().getAddressData() & PtrAuthMask)); + auto Stripped = stripSignedPointer(P.getResolvedAddress()); + return RemoteAbsolutePointer(P.getSymbol(), P.getOffset(), Stripped); } StoredPointer queryPtrAuthMask() { @@ -431,11 +434,9 @@ public: } template - MetadataReader(std::shared_ptr reader, T &&... args) - : Builder(std::forward(args)...), - Reader(std::move(reader)), - PtrAuthMask(queryPtrAuthMask()) { - } + MetadataReader(std::shared_ptr reader, T &&...args) + : Builder(std::forward(args)...), Reader(std::move(reader)), + PtrAuthMask(queryPtrAuthMask()) {} MetadataReader(const MetadataReader &other) = delete; MetadataReader &operator=(const MetadataReader &other) = delete; @@ -462,7 +463,7 @@ public: auto offsetInMangledName = (const char *)base - mangledName.getLocalBuffer(); auto remoteAddress = - mangledName.getAddressData() + offsetInMangledName + offset; + mangledName.getRemoteAddress() + offsetInMangledName + offset; RemoteAbsolutePointer resolved; if (directness == Directness::Indirect) { @@ -472,7 +473,7 @@ public: return nullptr; } } else { - resolved = Reader->getSymbol(RemoteAddress(remoteAddress)); + resolved = Reader->getSymbol(remoteAddress); } switch (kind) { @@ -486,9 +487,13 @@ public: if (useOpaqueTypeSymbolicReferences && context.isResolved() && context.getResolved()->getKind() == ContextDescriptorKind::OpaqueType){ + // FIXME: this loses the address space. This can be fixed by adding an + // opaque field in Node that can store the address space. This + // wouldn't degrade performance as Node's address is part of an union + // which is 16 bytes longs return dem.createNode( - Node::Kind::OpaqueTypeDescriptorSymbolicReference, - context.getResolved().getAddressData()); + Node::Kind::OpaqueTypeDescriptorSymbolicReference, + context.getResolved().getRemoteAddress().getRawAddress()); } return buildContextMangling(context, dem); @@ -502,27 +507,27 @@ public: // The symbolic reference points at a unique extended // existential type shape. return dem.createNode( - Node::Kind::UniqueExtendedExistentialTypeShapeSymbolicReference, - resolved.getResolvedAddress().getAddressData()); + Node::Kind::UniqueExtendedExistentialTypeShapeSymbolicReference, + resolved.getResolvedAddress().getRawAddress()); } case Demangle::SymbolicReferenceKind::NonUniqueExtendedExistentialTypeShape: { // The symbolic reference points at a non-unique extended // existential type shape. + // FIXME: this loses the address space. return dem.createNode( - Node::Kind::NonUniqueExtendedExistentialTypeShapeSymbolicReference, - resolved.getResolvedAddress().getAddressData()); + Node::Kind::NonUniqueExtendedExistentialTypeShapeSymbolicReference, + resolved.getResolvedAddress().getRawAddress()); } case Demangle::SymbolicReferenceKind::ObjectiveCProtocol: { // 'resolved' points to a struct of two relative addresses. // The second entry is a relative address to the mangled protocol // without symbolic references. - auto addr = - resolved.getResolvedAddress().getAddressData() + sizeof(int32_t); + auto addr = resolved.getResolvedAddress() + sizeof(int32_t); int32_t offset; - Reader->readInteger(RemoteAddress(addr), &offset); + Reader->readInteger(addr, &offset); auto addrOfTypeRef = addr + offset; - resolved = Reader->getSymbol(RemoteAddress(addrOfTypeRef)); + resolved = Reader->getSymbol(addrOfTypeRef); // Dig out the protocol from the protocol list. auto protocolList = readMangledName(resolved.getResolvedAddress(), @@ -576,10 +581,9 @@ public: /// Demangle a mangled name from a potentially temporary std::string. The /// demangler may produce pointers into the string data, so this copies the /// string into the demangler's allocation first. - Demangle::NodePointer demangle(uint64_t remoteAddress, + Demangle::NodePointer demangle(RemoteAddress remoteAddress, const std::string &mangledName, - MangledNameKind kind, - Demangler &dem) { + MangledNameKind kind, Demangler &dem) { StringRef mangledNameCopy = dem.copyString(mangledName); return demangle(RemoteRef(remoteAddress, mangledNameCopy.data()), kind, dem); @@ -607,7 +611,7 @@ public: /// Given a remote pointer to metadata, attempt to discover its MetadataKind. std::optional - readKindFromMetadata(StoredPointer MetadataAddress) { + readKindFromMetadata(RemoteAddress MetadataAddress) { auto meta = readMetadata(MetadataAddress); if (!meta) return std::nullopt; @@ -616,11 +620,10 @@ public: } /// Given a remote pointer to class metadata, attempt to read its superclass. - StoredPointer - readSuperClassFromClassMetadata(StoredPointer MetadataAddress) { + RemoteAddress readSuperClassFromClassMetadata(RemoteAddress MetadataAddress) { auto meta = readMetadata(MetadataAddress); if (!meta || meta->getKind() != MetadataKind::Class) - return StoredPointer(); + return RemoteAddress(); auto classMeta = cast(meta); return stripSignedPointer(classMeta->Superclass); @@ -629,7 +632,7 @@ public: /// Given a remote pointer to class metadata, attempt to discover its class /// instance size and whether fields should use the resilient layout strategy. std::optional - readInstanceStartFromClassMetadata(StoredPointer MetadataAddress) { + readInstanceStartFromClassMetadata(RemoteAddress MetadataAddress) { auto meta = readMetadata(MetadataAddress); if (!meta || meta->getKind() != MetadataKind::Class) return std::nullopt; @@ -638,7 +641,7 @@ public: // The following algorithm only works on the non-fragile Apple runtime. // Grab the RO-data pointer. This part is not ABI. - StoredPointer roDataPtr = readObjCRODataPtr(MetadataAddress); + RemoteAddress roDataPtr = readObjCRODataPtr(MetadataAddress); if (!roDataPtr) return std::nullopt; @@ -646,7 +649,7 @@ public: auto address = roDataPtr + sizeof(uint32_t) * 1; unsigned start; - if (!Reader->readInteger(RemoteAddress(address), &start)) + if (!Reader->readInteger(address, &start)) return std::nullopt; return start; @@ -676,19 +679,19 @@ public: /// witness table. Note that it's not safe to access any non-mandatory /// members of the value witness table, like extra inhabitants or enum members. std::optional> - readValueWitnessTable(StoredPointer MetadataAddress) { + readValueWitnessTable(RemoteAddress MetadataAddress) { // The value witness table pointer is at offset -1 from the metadata // pointer, that is, the pointer-sized word immediately before the // pointer's referenced address. TargetValueWitnessTable VWT; auto ValueWitnessTableAddrAddr = MetadataAddress - sizeof(StoredPointer); StoredSignedPointer SignedValueWitnessTableAddr; - if (!Reader->readInteger(RemoteAddress(ValueWitnessTableAddrAddr), + if (!Reader->readInteger(ValueWitnessTableAddrAddr, &SignedValueWitnessTableAddr)) return std::nullopt; - auto ValueWitnessTableAddr = stripSignedPointer(SignedValueWitnessTableAddr); - if (!Reader->readBytes(RemoteAddress(ValueWitnessTableAddr), - (uint8_t *)&VWT, sizeof(VWT))) + auto ValueWitnessTableAddr = + stripSignedPointer(SignedValueWitnessTableAddr); + if (!Reader->readBytes(ValueWitnessTableAddr, (uint8_t *)&VWT, sizeof(VWT))) return std::nullopt; return VWT; } @@ -700,8 +703,7 @@ public: std::optional readMetadataAndValueErrorExistential(RemoteAddress ExistentialAddress) { // An pointer to an error existential is always an heap object. - auto MetadataAddress = - readMetadataFromInstance(ExistentialAddress.getAddressData()); + auto MetadataAddress = readMetadataFromInstance(ExistentialAddress); if (!MetadataAddress) return std::nullopt; @@ -730,18 +732,15 @@ public: if (isBridged) { // NSError instances don't need to be unwrapped. - return RemoteExistential(RemoteAddress(*MetadataAddress), - ExistentialAddress, - isBridged); + return RemoteExistential(*MetadataAddress, ExistentialAddress, isBridged); } // In addition to the isa pointer and two 32-bit reference counts, if the // error existential is layout-compatible with NSError, we also need to // skip over its three word-sized fields: the error code, the domain, // and userInfo. - StoredPointer InstanceMetadataAddressAddress = - ExistentialAddress.getAddressData() + - (isObjC ? 5 : 2) * sizeof(StoredPointer); + RemoteAddress InstanceMetadataAddressAddress = + ExistentialAddress + (isObjC ? 5 : 2) * sizeof(StoredPointer); // We need to get the instance's alignment info so we can get the exact // offset of the start of its data in the class. @@ -757,7 +756,7 @@ public: // Now we need to skip over the instance metadata pointer and instance's // conformance pointer for Swift.Error. - StoredPointer InstanceAddress = + RemoteAddress InstanceAddress = InstanceMetadataAddressAddress + 2 * sizeof(StoredPointer); // When built with Objective-C interop, the runtime also stores a conformance @@ -770,10 +769,8 @@ public: auto AlignmentMask = VWT->getAlignmentMask(); InstanceAddress = (InstanceAddress + AlignmentMask) & ~AlignmentMask; - return RemoteExistential( - RemoteAddress(*InstanceMetadataAddress), - RemoteAddress(InstanceAddress), - isBridged); + return RemoteExistential(*InstanceMetadataAddress, InstanceAddress, + isBridged); } /// Given a known-opaque existential, attempt to discover the pointer to its @@ -783,10 +780,11 @@ public: // OpaqueExistentialContainer is the layout of an opaque existential. // `Type` is the pointer to the metadata. TargetOpaqueExistentialContainer Container; - if (!Reader->readBytes(RemoteAddress(ExistentialAddress), - (uint8_t *)&Container, sizeof(Container))) + if (!Reader->readBytes(ExistentialAddress, (uint8_t *)&Container, + sizeof(Container))) return std::nullopt; - auto MetadataAddress = static_cast(Container.Type); + auto MetadataAddress = + RemoteAddress(Container.Type, ExistentialAddress.getAddressSpace()); auto Metadata = readMetadata(MetadataAddress); if (!Metadata) return std::nullopt; @@ -798,20 +796,19 @@ public: // Inline representation (the value fits in the existential container). // So, the value starts at the first word of the container. if (VWT->isValueInline()) - return RemoteExistential(RemoteAddress(MetadataAddress), - ExistentialAddress); + return RemoteExistential(MetadataAddress, ExistentialAddress); // Non-inline (box'ed) representation. // The first word of the container stores the address to the box. - StoredPointer BoxAddress; - if (!Reader->readInteger(ExistentialAddress, &BoxAddress)) + RemoteAddress BoxAddress; + if (!Reader->readRemoteAddress(ExistentialAddress, + BoxAddress)) return std::nullopt; auto AlignmentMask = VWT->getAlignmentMask(); auto Offset = (sizeof(HeapObject) + AlignmentMask) & ~AlignmentMask; auto StartOfValue = BoxAddress + Offset; - return RemoteExistential(RemoteAddress(MetadataAddress), - RemoteAddress(StartOfValue)); + return RemoteExistential(MetadataAddress, StartOfValue); } /// Given a known-opaque existential, discover if its value is inlined in @@ -821,10 +818,12 @@ public: // OpaqueExistentialContainer is the layout of an opaque existential. // `Type` is the pointer to the metadata. TargetOpaqueExistentialContainer Container; - if (!Reader->readBytes(RemoteAddress(ExistentialAddress), - (uint8_t *)&Container, sizeof(Container))) + if (!Reader->readBytes(ExistentialAddress, (uint8_t *)&Container, + sizeof(Container))) return std::nullopt; - auto MetadataAddress = static_cast(Container.Type); + auto MetadataAddress = + RemoteAddress(Container.Type, ExistentialAddress.getAddressSpace()); + auto Metadata = readMetadata(MetadataAddress); if (!Metadata) return std::nullopt; @@ -837,11 +836,10 @@ public: } /// Read a protocol from a reference to said protocol. - template + template typename Resolver::Result readProtocol( - const TargetProtocolDescriptorRef &ProtocolAddress, - Demangler &dem, - Resolver resolver) { + const RemoteTargetProtocolDescriptorRef &ProtocolAddress, + Demangler &dem, Resolver resolver) { #if SWIFT_OBJC_INTEROP if (Runtime::ObjCInterop) { // Check whether we have an Objective-C protocol. @@ -877,8 +875,7 @@ public: #endif // Swift-native protocol. - auto Demangled = - readDemanglingForContextDescriptor( + auto Demangled = readDemanglingForContextDescriptor( stripSignedPointer({ProtocolAddress.getSwiftProtocol()}), dem); if (!Demangled) return resolver.failure(); @@ -888,10 +885,10 @@ public: /// Given a remote pointer to metadata, attempt to turn it into a type. BuiltType - readTypeFromMetadata(StoredPointer MetadataAddress, + readTypeFromMetadata(RemoteAddress MetadataAddress, bool skipArtificialSubclasses = false, int recursion_limit = defaultTypeRecursionLimit) { - std::pair TypeCacheKey(MetadataAddress, + std::pair TypeCacheKey(MetadataAddress, skipArtificialSubclasses); auto Cached = TypeCache.find(TypeCacheKey); if (Cached != TypeCache.end()) @@ -934,17 +931,20 @@ public: for (unsigned i = 0, n = tupleMeta->NumElements; i != n; ++i) { auto &element = tupleMeta->getElement(i); - if (auto elementType = - readTypeFromMetadata(element.Type, false, recursion_limit)) + auto elementTypeAddress = + RemoteAddress(element.Type, MetadataAddress.getAddressSpace()); + if (auto elementType = readTypeFromMetadata(elementTypeAddress, false, + recursion_limit)) elementTypes.push_back(elementType); else return BuiltType(); } // Read the labels string. + auto labelAddress = + RemoteAddress(tupleMeta->Labels, MetadataAddress.getAddressSpace()); std::string labelStr; - if (tupleMeta->Labels && - !Reader->readString(RemoteAddress(tupleMeta->Labels), labelStr)) + if (labelAddress && !Reader->readString(labelAddress, labelStr)) return BuiltType(); std::vector labels; @@ -970,8 +970,10 @@ public: std::vector> Parameters; for (unsigned i = 0, n = Function->getNumParameters(); i != n; ++i) { - auto ParamTypeRef = readTypeFromMetadata(Function->getParameter(i), - false, recursion_limit); + auto paramAddress = RemoteAddress(Function->getParameter(i), + MetadataAddress.getAddressSpace()); + auto ParamTypeRef = + readTypeFromMetadata(paramAddress, false, recursion_limit); if (!ParamTypeRef) return BuiltType(); @@ -981,8 +983,10 @@ public: Parameters.push_back(std::move(Param)); } + auto resultTypeAddress = RemoteAddress(Function->ResultType, + MetadataAddress.getAddressSpace()); auto Result = - readTypeFromMetadata(Function->ResultType, false, recursion_limit); + readTypeFromMetadata(resultTypeAddress, false, recursion_limit); if (!Result) return BuiltType(); @@ -994,8 +998,10 @@ public: BuiltType globalActor = BuiltType(); if (Function->hasGlobalActor()) { - globalActor = readTypeFromMetadata(Function->getGlobalActor(), false, - recursion_limit); + auto globalActorAddress = RemoteAddress( + Function->getGlobalActor(), MetadataAddress.getAddressSpace()); + globalActor = + readTypeFromMetadata(globalActorAddress, false, recursion_limit); if (!globalActor) return BuiltType(); } @@ -1017,8 +1023,10 @@ public: BuiltType thrownError = BuiltType(); if (Function->hasThrownError()) { - thrownError = readTypeFromMetadata(Function->getThrownError(), false, - recursion_limit); + auto thrownErrorAddress = RemoteAddress( + Function->getThrownError(), MetadataAddress.getAddressSpace()); + thrownError = + readTypeFromMetadata(thrownErrorAddress, false, recursion_limit); if (!thrownError) return BuiltType(); } @@ -1037,9 +1045,12 @@ public: BuiltType SuperclassType = BuiltType(); if (Exist->Flags.hasSuperclassConstraint()) { + auto superclassContraintAddress = + RemoteAddress(Exist->getSuperclassConstraint(), + MetadataAddress.getAddressSpace()); // The superclass is stored after the list of protocols. - SuperclassType = readTypeFromMetadata(Exist->getSuperclassConstraint(), - false, recursion_limit); + SuperclassType = readTypeFromMetadata(superclassContraintAddress, false, + recursion_limit); if (!SuperclassType) return BuiltType(); HasExplicitAnyObject = true; @@ -1069,7 +1080,10 @@ public: Demangler dem; std::vector Protocols; for (auto ProtocolAddress : Exist->getProtocols()) { - if (auto Protocol = readProtocol(ProtocolAddress, dem, resolver)) + auto ProtocolRef = RemoteTargetProtocolDescriptorRef( + RemoteAddress(ProtocolAddress.getRawData(), + MetadataAddress.getAddressSpace())); + if (auto Protocol = readProtocol(ProtocolRef, dem, resolver)) Protocols.push_back(Protocol); else return BuiltType(); @@ -1083,7 +1097,7 @@ public: auto Exist = cast>(Meta); // Read the shape for this existential. - StoredPointer shapeAddress = stripSignedPointer(Exist->Shape); + RemoteAddress shapeAddress = stripSignedPointer(Exist->Shape); ShapeRef Shape = readShape(shapeAddress); if (!Shape) return BuiltType(); @@ -1095,7 +1109,10 @@ public: std::vector builtArgs; for (unsigned i = 0; i < shapeArgumentCount; ++i) { auto remoteArg = Exist->getGeneralizationArguments()[i]; - auto builtArg = readTypeFromMetadata(remoteArg, false, recursion_limit); + auto remoteArgAddress = + RemoteAddress(remoteArg, MetadataAddress.getAddressSpace()); + auto builtArg = + readTypeFromMetadata(remoteArgAddress, false, recursion_limit); if (!builtArg) return BuiltType(); builtArgs.push_back(builtArg); @@ -1105,8 +1122,8 @@ public: Demangler dem; auto mangledExistentialAddr = resolveRelativeField(Shape, Shape->ExistentialType); - auto node = readMangledName(RemoteAddress(mangledExistentialAddr), - MangledNameKind::Type, dem); + auto node = + readMangledName(mangledExistentialAddr, MangledNameKind::Type, dem); if (!node) return BuiltType(); @@ -1140,8 +1157,8 @@ public: auto mangledContextName = Shape->getTypeExpression(); auto mangledNameAddress = resolveRelativeField(Shape, mangledContextName->name); - auto node = readMangledName(RemoteAddress(mangledNameAddress), - MangledNameKind::Type, dem); + auto node = + readMangledName(mangledNameAddress, MangledNameKind::Type, dem); if (!node) return BuiltType(); @@ -1160,8 +1177,10 @@ public: case MetadataKind::Metatype: { auto Metatype = cast>(Meta); + auto InstanceTypeAddress = RemoteAddress( + Metatype->InstanceType, MetadataAddress.getAddressSpace()); auto Instance = - readTypeFromMetadata(Metatype->InstanceType, false, recursion_limit); + readTypeFromMetadata(InstanceTypeAddress, false, recursion_limit); if (!Instance) return BuiltType(); auto BuiltMetatype = Builder.createMetatypeType(Instance); TypeCache[TypeCacheKey] = BuiltMetatype; @@ -1169,7 +1188,8 @@ public: } case MetadataKind::ObjCClassWrapper: { auto objcWrapper = cast>(Meta); - auto classAddress = objcWrapper->Class; + auto classAddress = + RemoteAddress(objcWrapper->Class, MetadataAddress.getAddressSpace()); std::string className; if (!readObjCClassName(classAddress, className)) @@ -1181,8 +1201,10 @@ public: } case MetadataKind::ExistentialMetatype: { auto Exist = cast>(Meta); + auto classAddress = + RemoteAddress(Exist->InstanceType, MetadataAddress.getAddressSpace()); auto Instance = - readTypeFromMetadata(Exist->InstanceType, false, recursion_limit); + readTypeFromMetadata(classAddress, false, recursion_limit); if (!Instance) return BuiltType(); auto BuiltExist = Builder.createExistentialMetatypeType(Instance); TypeCache[TypeCacheKey] = BuiltExist; @@ -1263,8 +1285,13 @@ public: switch (req.Flags.getKind()) { case GenericRequirementKind::SameType: { Demangler rdem; + // FIXME: This should not work since the mangled name pointer is on the + // local process. + auto mangledNameAddress = + RemoteAddress((uint64_t)req.getMangledTypeName().data(), + RemoteAddress::DefaultAddressSpace); auto demangledConstraint = - demangle(RemoteRef(req.getMangledTypeName().data(), + demangle(RemoteRef(mangledNameAddress, req.getMangledTypeName().data()), MangledNameKind::Type, rdem); auto constraintType = decodeMangledType(demangledConstraint); @@ -1305,7 +1332,9 @@ public: Demangler dem; auto protocolAddress = resolveRelativeIndirectProtocol(contextRef, req.Protocol); - auto protocol = readProtocol(protocolAddress, dem, resolver); + auto protocolRef = + RemoteTargetProtocolDescriptorRef(protocolAddress); + auto protocol = readProtocol(protocolRef, dem, resolver); if (!protocol) { return TypeLookupError("Failed to read protocol type in conformance " "requirement of runtime generic signature."); @@ -1317,8 +1346,13 @@ public: } case GenericRequirementKind::BaseClass: { Demangler rdem; + // FIXME: This should not work since the mangled name pointer is on the + // local process. + auto mangledNameAddress = + RemoteAddress((uint64_t)req.getMangledTypeName().data(), + RemoteAddress::DefaultAddressSpace); auto demangledConstraint = - demangle(RemoteRef(req.getMangledTypeName().data(), + demangle(RemoteRef(mangledNameAddress, req.getMangledTypeName().data()), MangledNameKind::Type, rdem); auto constraintType = decodeMangledType(demangledConstraint); @@ -1366,14 +1400,13 @@ public: if (address.getOffset() == 0) return ParentContextDescriptorRef(address.getSymbol()); } - + return ParentContextDescriptorRef( - readContextDescriptor(address.getResolvedAddress().getAddressData())); + readContextDescriptor(address.getResolvedAddress())); } - ShapeRef - readShape(StoredPointer address) { - if (address == 0) + ShapeRef readShape(RemoteAddress address) { + if (!address) return nullptr; auto cached = ShapeCache.find(address); @@ -1383,8 +1416,7 @@ public: cached->second.get())); ExtendedExistentialTypeShapeFlags flags; - if (!Reader->readBytes(RemoteAddress(address), (uint8_t*)&flags, - sizeof(flags))) + if (!Reader->readBytes(address, (uint8_t *)&flags, sizeof(flags))) return nullptr; // Read the size of the requirement signature. @@ -1394,8 +1426,7 @@ public: GenericContextDescriptorHeader header; auto headerAddr = address + sizeof(flags); - if (!Reader->readBytes(RemoteAddress(headerAddr), - (uint8_t*)&header, sizeof(header))) + if (!Reader->readBytes(headerAddr, (uint8_t *)&header, sizeof(header))) return nullptr; reqSigGenericSize = reqSigGenericSize @@ -1413,7 +1444,7 @@ public: reqSigGenericSize; if (size > MaxMetadataSize) return nullptr; - auto readResult = Reader->readBytes(RemoteAddress(address), size); + auto readResult = Reader->readBytes(address, size); if (!readResult) return nullptr; @@ -1427,22 +1458,21 @@ public: } /// Given the address of a context descriptor, attempt to read it. - ContextDescriptorRef - readContextDescriptor(StoredPointer address) { - if (address == 0) + ContextDescriptorRef readContextDescriptor(RemoteAddress remoteAddress) { + if (!remoteAddress) return nullptr; - auto remoteAddress = RemoteAddress(address); auto ptr = Reader->readBytes(remoteAddress, sizeof(TargetContextDescriptor)); if (!ptr) return nullptr; - auto cached = ContextDescriptorCache.find(address); + auto cached = ContextDescriptorCache.find(remoteAddress); if (cached != ContextDescriptorCache.end()) return ContextDescriptorRef( - address, reinterpret_cast *>( - cached->second.get())); + remoteAddress, + reinterpret_cast *>( + cached->second.get())); bool success = false; switch ( @@ -1492,8 +1522,9 @@ public: auto *descriptor = reinterpret_cast *>(ptr.get()); - ContextDescriptorCache.insert(std::make_pair(address, std::move(ptr))); - return ContextDescriptorRef(address, descriptor); + ContextDescriptorCache.insert( + std::make_pair(remoteAddress, std::move(ptr))); + return ContextDescriptorRef(remoteAddress, descriptor); } template @@ -1606,19 +1637,17 @@ public: /// Read a context descriptor from the given address and build a mangling /// tree representing it. Demangle::NodePointer - readDemanglingForContextDescriptor(StoredPointer contextAddress, + readDemanglingForContextDescriptor(RemoteAddress contextAddress, Demangler &Dem) { auto context = readContextDescriptor(contextAddress); if (!context) return nullptr; return buildContextMangling(context, Dem); } - + /// Read the mangled underlying type from an opaque type descriptor. - Demangle::NodePointer - readUnderlyingTypeManglingForOpaqueTypeDescriptor(StoredPointer contextAddr, - unsigned ordinal, - Demangler &Dem) { + Demangle::NodePointer readUnderlyingTypeManglingForOpaqueTypeDescriptor( + RemoteAddress contextAddr, unsigned ordinal, Demangler &Dem) { auto context = readContextDescriptor(contextAddr); if (!context) return nullptr; @@ -1634,13 +1663,12 @@ public: auto nameAddr = resolveRelativeField(context, opaqueType->getUnderlyingTypeArgumentMangledName(ordinal)); - - return readMangledName(RemoteAddress(nameAddr), - MangledNameKind::Type, Dem); + + return readMangledName(nameAddr, MangledNameKind::Type, Dem); } TypeLookupErrorOr - readUnderlyingTypeForOpaqueTypeDescriptor(StoredPointer contextAddr, + readUnderlyingTypeForOpaqueTypeDescriptor(RemoteAddress contextAddr, unsigned ordinal) { Demangle::Demangler Dem; auto node = readUnderlyingTypeManglingForOpaqueTypeDescriptor(contextAddr, @@ -1650,31 +1678,33 @@ public: return decodeMangledType(node); } - bool isTaggedPointer(StoredPointer objectAddress) { + bool isTaggedPointer(RemoteAddress objectAddress) { if (getTaggedPointerEncoding() != TaggedPointerEncodingKind::Extended) return false; - - return (objectAddress ^ TaggedPointerObfuscator) & TaggedPointerMask; + + return (bool)((objectAddress ^ TaggedPointerObfuscator) & + TaggedPointerMask); } /// Read the isa pointer of an Object-C tagged pointer value. - std::optional - readMetadataFromTaggedPointer(StoredPointer objectAddress) { + std::optional + readMetadataFromTaggedPointer(RemoteAddress objectAddress) { auto readArrayElement = - [&](StoredPointer base, - StoredPointer tag) -> std::optional { - StoredPointer addr = base + tag * sizeof(StoredPointer); - StoredPointer isa; - if (!Reader->readInteger(RemoteAddress(addr), &isa)) + [&](RemoteAddress base, + StoredPointer tag) -> std::optional { + RemoteAddress addr = base + tag * sizeof(StoredPointer); + RemoteAddress isa; + if (!Reader->readRemoteAddress(addr, isa)) return std::nullopt; return isa; }; // Extended pointers have a tag of 0b111, using 8 additional bits // to specify the class. - if (TaggedPointerExtendedMask != 0 && - (((objectAddress ^ TaggedPointerObfuscator) & TaggedPointerExtendedMask) - == TaggedPointerExtendedMask)) { + if (TaggedPointerExtendedMask && + ((((StoredPointer)objectAddress.getRawAddress() ^ + TaggedPointerObfuscator) & + TaggedPointerExtendedMask) == TaggedPointerExtendedMask)) { auto tag = ((objectAddress >> TaggedPointerExtendedSlotShift) & TaggedPointerExtendedSlotMask); return readArrayElement(TaggedPointerExtendedClasses, tag); @@ -1688,13 +1718,13 @@ public: /// Read the isa pointer of a class or closure context instance and apply /// the isa mask. - std::optional - readMetadataFromInstance(StoredPointer objectAddress) { + std::optional + readMetadataFromInstance(RemoteAddress objectAddress) { if (isTaggedPointer(objectAddress)) return readMetadataFromTaggedPointer(objectAddress); - StoredPointer isa; - if (!Reader->readInteger(RemoteAddress(objectAddress), &isa)) + RemoteAddress isa; + if (!Reader->readRemoteAddress(objectAddress, isa)) return std::nullopt; switch (getIsaEncoding()) { @@ -1711,11 +1741,12 @@ public: case IsaEncodingKind::Indexed: { // If applying the magic mask doesn't give us the magic value, // it's not an indexed isa. - if ((isa & IsaMagicMask) != IsaMagicValue) + if (((StoredPointer)(isa & IsaMagicMask).getRawAddress()) != + IsaMagicValue) return isa; // Extract the index. - auto classIndex = (isa & IsaIndexMask) >> IsaIndexShift; + StoredPointer classIndex = (isa & IsaIndexMask) >> IsaIndexShift; // 0 is never a valid index. if (classIndex == 0) { @@ -1741,10 +1772,10 @@ public: RemoteAddress eltPointer = RemoteAddress(IndexedClassesPointer + classIndex * sizeof(StoredPointer)); - StoredPointer metadataPointer; - if (!Reader->readInteger(eltPointer, &metadataPointer)) { + RemoteAddress metadataPointer; + if (!Reader->readRemoteAddress(eltPointer, + metadataPointer)) return std::nullopt; - } return metadataPointer; } @@ -1845,7 +1876,7 @@ public: return cls->getClassBoundsAsSwiftSuperclass(); }, - [](StoredPointer objcClassName) + [](RemoteAddress objcClassName) -> std::optional { // We have no ability to look up an ObjC class by name. // FIXME: add a query for this; clients may have a way to do it. @@ -1863,14 +1894,14 @@ public: template std::optional forTypeReference(TypeReferenceKind refKind, - StoredPointer ref, + RemoteAddress ref, const DescriptorFn &descriptorFn, const MetadataFn &metadataFn, const ClassNameFn &classNameFn) { switch (refKind) { case TypeReferenceKind::IndirectTypeDescriptor: { StoredSignedPointer descriptorAddress; - if (!Reader->readInteger(RemoteAddress(ref), &descriptorAddress)) { + if (!Reader->readInteger(ref, &descriptorAddress)) { return std::nullopt; } @@ -1890,8 +1921,8 @@ public: return classNameFn(ref); case TypeReferenceKind::IndirectObjCClass: { - StoredPointer classRef = 0; - if (!Reader->readInteger(RemoteAddress(ref), &classRef)) + RemoteAddress classRef; + if (!Reader->readRemoteAddress(ref, classRef)) return std::nullopt; auto metadata = readMetadata(classRef); @@ -1907,8 +1938,8 @@ public: /// Read a single generic type argument from a bound generic type /// metadata. - std::optional - readGenericArgFromMetadata(StoredPointer metadata, unsigned index) { + std::optional + readGenericArgFromMetadata(RemoteAddress metadata, unsigned index) { auto Meta = readMetadata(metadata); if (!Meta) return std::nullopt; @@ -1938,9 +1969,9 @@ public: if (index >= generics->getGenericContextHeader().getNumArguments()) return std::nullopt; - StoredPointer genericArgAddress; - if (!Reader->readInteger(RemoteAddress(addressOfGenericArgAddress), - &genericArgAddress)) + RemoteAddress genericArgAddress; + if (!Reader->readRemoteAddress(addressOfGenericArgAddress, + genericArgAddress)) return std::nullopt; return genericArgAddress; @@ -1948,7 +1979,7 @@ public: /// Given the address of a nominal type descriptor, attempt to resolve /// its nominal type declaration. - BuiltTypeDecl readNominalTypeFromDescriptor(StoredPointer address) { + BuiltTypeDecl readNominalTypeFromDescriptor(RemoteAddress address) { auto descriptor = readContextDescriptor(address); if (!descriptor) return BuiltTypeDecl(); @@ -1957,7 +1988,7 @@ public: } /// Try to read the offset of a tuple element from a tuple metadata. - bool readTupleElementOffset(StoredPointer metadataAddress, unsigned eltIndex, + bool readTupleElementOffset(RemoteAddress metadataAddress, unsigned eltIndex, StoredSize *offset) { // Read the metadata. auto metadata = readMetadata(metadataAddress); @@ -1981,7 +2012,7 @@ public: /// Given a remote pointer to class metadata, attempt to read its superclass. std::optional - readOffsetToFirstCaptureFromMetadata(StoredPointer MetadataAddress) { + readOffsetToFirstCaptureFromMetadata(RemoteAddress MetadataAddress) { auto meta = readMetadata(MetadataAddress); if (!meta || meta->getKind() != MetadataKind::HeapLocalVariable) return std::nullopt; @@ -1990,15 +2021,15 @@ public: return heapMeta->OffsetToFirstCapture; } - std::optional readPointer(StoredPointer address) { - return Reader->readPointer(RemoteAddress(address), sizeof(StoredPointer)); + std::optional readPointer(RemoteAddress address) { + return Reader->readPointer(address, sizeof(StoredPointer)); } - std::optional readResolvedPointerValue(StoredPointer address) { + std::optional readResolvedPointerValue(RemoteAddress address) { if (auto pointer = readPointer(address)) { if (!pointer->getResolvedAddress()) return std::nullopt; - return (StoredPointer)pointer->getResolvedAddress().getAddressData(); + return pointer->getResolvedAddress(); } return std::nullopt; } @@ -2007,13 +2038,13 @@ public: RemoteAbsolutePointer resolvePointerField(RemoteRef base, const U &field) { auto pointerRef = base.getField(field); - return Reader->resolvePointer(RemoteAddress(getAddress(pointerRef)), + return Reader->resolvePointer(getAddress(pointerRef), *pointerRef.getLocalBuffer()); } /// Given a remote pointer to class metadata, attempt to read its superclass. std::optional - readCaptureDescriptorFromMetadata(StoredPointer MetadataAddress) { + readCaptureDescriptorFromMetadata(RemoteAddress MetadataAddress) { auto meta = readMetadata(MetadataAddress); if (!meta || meta->getKind() != MetadataKind::HeapLocalVariable) return std::nullopt; @@ -2023,15 +2054,14 @@ public: } protected: - template - StoredPointer getAddress(RemoteRef base) { - return (StoredPointer)base.getAddressData(); + template + RemoteAddress getAddress(RemoteRef base) { + return base.getRemoteAddress(); } - - template - StoredPointer resolveRelativeField( - RemoteRef base, const Field &field) { - return (StoredPointer)base.resolveRelativeFieldData(field); + + template + RemoteAddress resolveRelativeField(RemoteRef base, const Field &field) { + return base.resolveRelativeFieldData(field); } template @@ -2047,9 +2077,9 @@ protected: offset &= ~1u; using SignedPointer = typename std::make_signed::type; - - StoredPointer resultAddress = getAddress(fieldRef) + (SignedPointer)offset; - + + RemoteAddress resultAddress = getAddress(fieldRef) + (SignedPointer)offset; + // Low bit set in the offset indicates that the offset leads to the absolute // address in memory. if (indirect) { @@ -2058,16 +2088,16 @@ protected: } return std::nullopt; } - - return RemoteAbsolutePointer(RemoteAddress(resultAddress)); + + return RemoteAbsolutePointer(resultAddress); } /// Given a pointer to an Objective-C class, try to read its class name. - bool readObjCClassName(StoredPointer classAddress, std::string &className) { + bool readObjCClassName(RemoteAddress classAddress, std::string &className) { // The following algorithm only works on the non-fragile Apple runtime. // Grab the RO-data pointer. This part is not ABI. - StoredPointer roDataPtr = readObjCRODataPtr(classAddress); + RemoteAddress roDataPtr = readObjCRODataPtr(classAddress); if (!roDataPtr) return false; // This is ABI. @@ -2076,18 +2106,19 @@ protected: + sizeof(StoredPointer); // Read the name pointer. - StoredPointer namePtr; - if (!Reader->readInteger(RemoteAddress(roDataPtr + OffsetToName), &namePtr)) + RemoteAddress namePtr; + if (!Reader->readRemoteAddress(roDataPtr + OffsetToName, + namePtr)) return false; // If the name pointer is null, treat that as an error. if (!namePtr) return false; - return Reader->readString(RemoteAddress(namePtr), className); + return Reader->readString(namePtr, className); } - MetadataRef readMetadata(StoredPointer address) { + MetadataRef readMetadata(RemoteAddress address) { auto cached = MetadataCache.find(address); if (cached != MetadataCache.end()) return MetadataRef(address, @@ -2095,7 +2126,7 @@ protected: cached->second.get())); StoredPointer KindValue = 0; - if (!Reader->readInteger(RemoteAddress(address), &KindValue)) + if (!Reader->readInteger(address, &KindValue)) return nullptr; switch (getEnumeratedMetadataKind(KindValue)) { @@ -2108,20 +2139,17 @@ protected: case MetadataKind::ErrorObject: return _readMetadata(address); case MetadataKind::Existential: { - StoredPointer flagsAddress = address + - sizeof(StoredPointer); + RemoteAddress flagsAddress = address + sizeof(StoredPointer); ExistentialTypeFlags::int_type flagsData; - if (!Reader->readInteger(RemoteAddress(flagsAddress), - &flagsData)) + if (!Reader->readInteger(flagsAddress, &flagsData)) return nullptr; ExistentialTypeFlags flags(flagsData); - StoredPointer numProtocolsAddress = flagsAddress + sizeof(flagsData); + RemoteAddress numProtocolsAddress = flagsAddress + sizeof(flagsData); uint32_t numProtocols; - if (!Reader->readInteger(RemoteAddress(numProtocolsAddress), - &numProtocols)) + if (!Reader->readInteger(numProtocolsAddress, &numProtocols)) return nullptr; // Make sure the number of protocols is reasonable @@ -2142,9 +2170,10 @@ protected: case MetadataKind::ExtendedExistential: { // We need to read the shape in order to figure out how large // the generalization arguments are. - StoredPointer shapeAddress = address + sizeof(StoredPointer); - StoredSignedPointer signedShapePtr; - if (!Reader->readInteger(RemoteAddress(shapeAddress), &signedShapePtr)) + RemoteAddress shapeAddress = address + sizeof(StoredPointer); + RemoteAddress signedShapePtr; + if (!Reader->readRemoteAddress(shapeAddress, + signedShapePtr)) return nullptr; auto shapePtr = stripSignedPointer(signedShapePtr); @@ -2166,7 +2195,7 @@ protected: StoredSize flagsValue; auto flagsAddr = address + TargetFunctionTypeMetadata::OffsetToFlags; - if (!Reader->readInteger(RemoteAddress(flagsAddr), &flagsValue)) + if (!Reader->readInteger(flagsAddr, &flagsValue)) return nullptr; auto flags = @@ -2203,8 +2232,7 @@ protected: auto numElementsAddress = address + TargetTupleTypeMetadata::getOffsetToNumElements(); StoredSize numElements; - if (!Reader->readInteger(RemoteAddress(numElementsAddress), - &numElements)) + if (!Reader->readInteger(numElementsAddress, &numElements)) return nullptr; auto totalSize = sizeof(TargetTupleTypeMetadata) + numElements * sizeof(TupleTypeMetadata::Element); @@ -2225,7 +2253,7 @@ protected: return nullptr; } - StoredPointer + RemoteAddress readAddressOfNominalTypeDescriptor(MetadataRef &metadata, bool skipArtificialSubclasses = false) { switch (metadata->getKind()) { @@ -2233,28 +2261,29 @@ protected: auto classMeta = cast(metadata); while (true) { if (!classMeta->isTypeMetadata()) - return 0; + return RemoteAddress(); StoredSignedPointer descriptorAddressSigned = classMeta->getDescriptionAsSignedPointer(); - StoredPointer descriptorAddress = stripSignedPointer(descriptorAddressSigned); + RemoteAddress descriptorAddress = + stripSignedPointer(descriptorAddressSigned); // If this class has a null descriptor, it's artificial, // and we need to skip it upon request. Otherwise, we're done. if (descriptorAddress || !skipArtificialSubclasses) - return static_cast(descriptorAddress); + return descriptorAddress; auto superclassMetadataAddress = stripSignedPointer(classMeta->Superclass); if (!superclassMetadataAddress) - return 0; + return RemoteAddress(); auto superMeta = readMetadata(superclassMetadataAddress); if (!superMeta) - return 0; + return RemoteAddress(); auto superclassMeta = dyn_cast(superMeta); if (!superclassMeta) - return 0; + return RemoteAddress(); classMeta = superclassMeta; metadata = superMeta; @@ -2266,39 +2295,42 @@ protected: case MetadataKind::Enum: { auto valueMeta = cast>(metadata); StoredSignedPointer descriptorAddressSigned = valueMeta->getDescriptionAsSignedPointer(); - StoredPointer descriptorAddress = stripSignedPointer(descriptorAddressSigned); + RemoteAddress descriptorAddress = + stripSignedPointer(descriptorAddressSigned); return descriptorAddress; } case MetadataKind::ForeignClass: { auto foreignMeta = cast>(metadata); StoredSignedPointer descriptorAddressSigned = foreignMeta->getDescriptionAsSignedPointer(); - StoredPointer descriptorAddress = stripSignedPointer(descriptorAddressSigned); + RemoteAddress descriptorAddress = + stripSignedPointer(descriptorAddressSigned); return descriptorAddress; } case MetadataKind::ForeignReferenceType: { auto foreignMeta = cast>(metadata); StoredSignedPointer descriptorAddressSigned = foreignMeta->getDescriptionAsSignedPointer(); - StoredPointer descriptorAddress = stripSignedPointer(descriptorAddressSigned); + RemoteAddress descriptorAddress = + stripSignedPointer(descriptorAddressSigned); return descriptorAddress; } default: - return 0; + return RemoteAddress(); } } private: template