diff --git a/include/swift/Basic/RelativePointer.h b/include/swift/Basic/RelativePointer.h index a42801d0d7400..4d53652a949e7 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 3805b76c7cdad..6cb8b7f277a02 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 @@ class CMemoryReader final : public MemoryReader { 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 @@ class CMemoryReader final : public MemoryReader { 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 @@ class CMemoryReader final : public MemoryReader { return ReadBytesResult(Ptr, freeLambda); } }; - -} -} +} // namespace remote +} // namespace swift #endif diff --git a/include/swift/Remote/Failure.h b/include/swift/Remote/Failure.h index 908e6357c0261..916c74892928d 100644 --- a/include/swift/Remote/Failure.h +++ b/include/swift/Remote/Failure.h @@ -288,7 +288,7 @@ class Failure { 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 9fa78a28308d6..dbe7351317a62 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 7e077a5f7d068..fddcc495d0834 100644 --- a/include/swift/Remote/MemoryReader.h +++ b/include/swift/Remote/MemoryReader.h @@ -57,13 +57,31 @@ class MemoryReader { /// /// 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 @@ 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, address.getAddressSpace())); } /// Performs the inverse operation of \ref resolvePointer. @@ -166,7 +185,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 @@ -263,7 +282,7 @@ class MemoryReader { 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 a7d9485e6ad03..5c682f9233a51 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 @@ class RemoteRef { return *this; } - uint64_t getAddressData() const { - return Address; - } + RemoteAddress getRemoteAddress() const { return Address; } const T *getLocalBuffer() const { return LocalBuffer; @@ -113,23 +109,23 @@ class RemoteRef { 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 @@ class MetadataReader { /// 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 @@ class MetadataReader { /// 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 @@ class MetadataReader { 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 @@ class MetadataReader { /// 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 @@ class MetadataReader { StoredPointer IsaIndexShift; StoredPointer IsaMagicMask; StoredPointer IsaMagicValue; - StoredPointer IndexedClassesPointer; - StoredPointer IndexedClassesCountPointer; + RemoteAddress IndexedClassesPointer; + RemoteAddress IndexedClassesCountPointer; StoredPointer LastIndexedClassesCount = 0; enum class TaggedPointerEncodingKind { @@ -389,11 +385,11 @@ class MetadataReader { 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,16 +407,21 @@ class MetadataReader { 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) { - if (P.isResolved()) { - return RemoteAbsolutePointer("", - P.getResolvedAddress().getAddressData() & PtrAuthMask); - } - return P; + auto Stripped = stripSignedPointer(P.getResolvedAddress()); + return RemoteAbsolutePointer(P.getSymbol(), P.getOffset(), Stripped); } StoredPointer queryPtrAuthMask() { @@ -433,11 +434,9 @@ class MetadataReader { } 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; @@ -464,7 +463,7 @@ class MetadataReader { auto offsetInMangledName = (const char *)base - mangledName.getLocalBuffer(); auto remoteAddress = - mangledName.getAddressData() + offsetInMangledName + offset; + mangledName.getRemoteAddress() + offsetInMangledName + offset; RemoteAbsolutePointer resolved; if (directness == Directness::Indirect) { @@ -474,7 +473,7 @@ class MetadataReader { return nullptr; } } else { - resolved = Reader->getSymbol(RemoteAddress(remoteAddress)); + resolved = Reader->getSymbol(remoteAddress); } switch (kind) { @@ -488,9 +487,13 @@ class MetadataReader { 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); @@ -504,43 +507,27 @@ class MetadataReader { // 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. - // 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); + 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)); - - // 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()); - } + resolved = Reader->getSymbol(addrOfTypeRef); // Dig out the protocol from the protocol list. auto protocolList = readMangledName(resolved.getResolvedAddress(), @@ -594,10 +581,9 @@ class MetadataReader { /// 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); @@ -625,7 +611,7 @@ class MetadataReader { /// 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; @@ -634,11 +620,10 @@ class MetadataReader { } /// 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); @@ -647,7 +632,7 @@ class MetadataReader { /// 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; @@ -656,7 +641,7 @@ class MetadataReader { // 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; @@ -664,7 +649,7 @@ class MetadataReader { 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; @@ -694,19 +679,19 @@ class MetadataReader { /// 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; } @@ -718,8 +703,7 @@ class MetadataReader { 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; @@ -748,18 +732,15 @@ class MetadataReader { 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. @@ -775,7 +756,7 @@ class MetadataReader { // 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 @@ -788,10 +769,8 @@ class MetadataReader { 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 @@ -801,10 +780,11 @@ class MetadataReader { // 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; @@ -816,20 +796,19 @@ class MetadataReader { // 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 @@ -839,10 +818,12 @@ class MetadataReader { // 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; @@ -855,11 +836,10 @@ class MetadataReader { } /// 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. @@ -895,8 +875,7 @@ class MetadataReader { #endif // Swift-native protocol. - auto Demangled = - readDemanglingForContextDescriptor( + auto Demangled = readDemanglingForContextDescriptor( stripSignedPointer({ProtocolAddress.getSwiftProtocol()}), dem); if (!Demangled) return resolver.failure(); @@ -906,10 +885,10 @@ class MetadataReader { /// 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()) @@ -952,17 +931,20 @@ class MetadataReader { 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; @@ -988,8 +970,10 @@ class MetadataReader { 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(); @@ -999,8 +983,10 @@ class MetadataReader { 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(); @@ -1012,8 +998,10 @@ class MetadataReader { 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(); } @@ -1035,8 +1023,10 @@ class MetadataReader { 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(); } @@ -1055,9 +1045,12 @@ class MetadataReader { 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; @@ -1087,7 +1080,10 @@ class MetadataReader { 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(); @@ -1101,7 +1097,7 @@ class MetadataReader { 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(); @@ -1113,7 +1109,10 @@ class MetadataReader { 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); @@ -1123,8 +1122,8 @@ class MetadataReader { 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(); @@ -1158,8 +1157,8 @@ class MetadataReader { 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(); @@ -1178,8 +1177,10 @@ class MetadataReader { 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; @@ -1187,7 +1188,8 @@ class MetadataReader { } 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)) @@ -1199,8 +1201,10 @@ class MetadataReader { } 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; @@ -1281,8 +1285,13 @@ class MetadataReader { 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); @@ -1323,7 +1332,9 @@ class MetadataReader { 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."); @@ -1335,8 +1346,13 @@ class MetadataReader { } 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); @@ -1379,21 +1395,18 @@ 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( - 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); @@ -1403,8 +1416,7 @@ class MetadataReader { 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. @@ -1414,8 +1426,7 @@ class MetadataReader { 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 @@ -1433,7 +1444,7 @@ class MetadataReader { reqSigGenericSize; if (size > MaxMetadataSize) return nullptr; - auto readResult = Reader->readBytes(RemoteAddress(address), size); + auto readResult = Reader->readBytes(address, size); if (!readResult) return nullptr; @@ -1447,22 +1458,21 @@ class MetadataReader { } /// 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 ( @@ -1512,8 +1522,9 @@ class MetadataReader { 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 @@ -1626,19 +1637,17 @@ class MetadataReader { /// 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; @@ -1654,13 +1663,12 @@ class MetadataReader { 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, @@ -1670,31 +1678,33 @@ class MetadataReader { 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); @@ -1708,13 +1718,13 @@ class MetadataReader { /// 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()) { @@ -1731,11 +1741,12 @@ class MetadataReader { 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) { @@ -1761,10 +1772,10 @@ class MetadataReader { 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; } @@ -1865,7 +1876,7 @@ class MetadataReader { 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. @@ -1883,14 +1894,14 @@ class MetadataReader { 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; } @@ -1910,8 +1921,8 @@ class MetadataReader { 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); @@ -1927,8 +1938,8 @@ class MetadataReader { /// 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; @@ -1958,9 +1969,9 @@ class MetadataReader { 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; @@ -1968,7 +1979,7 @@ class MetadataReader { /// 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(); @@ -1977,7 +1988,7 @@ class MetadataReader { } /// 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); @@ -2001,7 +2012,7 @@ class MetadataReader { /// 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; @@ -2010,15 +2021,15 @@ class MetadataReader { 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->isResolved()) + if (!pointer->getResolvedAddress()) return std::nullopt; - return (StoredPointer)pointer->getResolvedAddress().getAddressData(); + return pointer->getResolvedAddress(); } return std::nullopt; } @@ -2027,13 +2038,13 @@ class MetadataReader { 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; @@ -2043,15 +2054,14 @@ class MetadataReader { } 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 @@ -2067,9 +2077,9 @@ class MetadataReader { 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) { @@ -2078,16 +2088,16 @@ class MetadataReader { } return std::nullopt; } - - return RemoteAbsolutePointer("", 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. @@ -2096,18 +2106,19 @@ class MetadataReader { + 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, @@ -2115,7 +2126,7 @@ class MetadataReader { cached->second.get())); StoredPointer KindValue = 0; - if (!Reader->readInteger(RemoteAddress(address), &KindValue)) + if (!Reader->readInteger(address, &KindValue)) return nullptr; switch (getEnumeratedMetadataKind(KindValue)) { @@ -2128,20 +2139,17 @@ class MetadataReader { 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 @@ -2162,9 +2170,10 @@ class MetadataReader { 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); @@ -2186,7 +2195,7 @@ class MetadataReader { StoredSize flagsValue; auto flagsAddr = address + TargetFunctionTypeMetadata::OffsetToFlags; - if (!Reader->readInteger(RemoteAddress(flagsAddr), &flagsValue)) + if (!Reader->readInteger(flagsAddr, &flagsValue)) return nullptr; auto flags = @@ -2223,8 +2232,7 @@ class MetadataReader { 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); @@ -2245,7 +2253,7 @@ class MetadataReader { return nullptr; } - StoredPointer + RemoteAddress readAddressOfNominalTypeDescriptor(MetadataRef &metadata, bool skipArtificialSubclasses = false) { switch (metadata->getKind()) { @@ -2253,28 +2261,29 @@ class MetadataReader { 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; @@ -2286,39 +2295,42 @@ class MetadataReader { 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