diff --git a/include/swift/Remote/MemoryReader.h b/include/swift/Remote/MemoryReader.h index 835ea59b93b6c..c6928a3f76fbc 100644 --- a/include/swift/Remote/MemoryReader.h +++ b/include/swift/Remote/MemoryReader.h @@ -192,6 +192,20 @@ class MemoryReader { return ReadObjResult(reinterpret_cast(ptr), deleter); } + /// Resolves an indirect address at the given relative offset. + /// + /// \param address The base address which contains the relative offset. + /// \param offset The offset read. + /// \param directnessEncodedInOffset Whether the relative offset encodes the + /// directness as the last bit. Note that this is not the offset passed in as + /// a parameter, but whether the offset read at address would have the last + /// bit set. + virtual RemoteAddress + resolveIndirectAddressAtOffset(RemoteAddress address, uint64_t offset, + bool directnessEncodedInOffset) { + return address + offset; + } + /// Attempts to read 'size' bytes from the given address in the remote process. /// /// Returns a pointer to the requested data and a function that must be called to diff --git a/include/swift/Remote/MetadataReader.h b/include/swift/Remote/MetadataReader.h index 9187685f49b3b..770024ecc4e59 100644 --- a/include/swift/Remote/MetadataReader.h +++ b/include/swift/Remote/MetadataReader.h @@ -457,18 +457,20 @@ class MetadataReader { swift::Demangle::NodePointer { // Resolve the reference to a remote address. auto offsetInMangledName = - (const char *)base - mangledName.getLocalBuffer(); - auto remoteAddress = - mangledName.getRemoteAddress() + offsetInMangledName + offset; + (const char *)base - mangledName.getLocalBuffer(); + auto offsetAddress = mangledName.getRemoteAddress() + offsetInMangledName; RemoteAbsolutePointer resolved; if (directness == Directness::Indirect) { + auto remoteAddress = Reader->resolveIndirectAddressAtOffset( + offsetAddress, offset, /*directnessEncodedInOffset=*/false); if (auto indirectAddress = readPointer(remoteAddress)) { resolved = stripSignedPointer(*indirectAddress); } else { return nullptr; } } else { + auto remoteAddress = offsetAddress + offset; resolved = Reader->getSymbol(remoteAddress); } @@ -2084,17 +2086,19 @@ class MetadataReader { using SignedPointer = typename std::make_signed::type; - 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) { + RemoteAddress resultAddress = Reader->resolveIndirectAddressAtOffset( + getAddress(fieldRef), (SignedPointer)offset, + /*directnessEncodedInOffset=*/true); if (auto ptr = readPointer(resultAddress)) { return stripSignedPointer(*ptr); } return std::nullopt; } + RemoteAddress resultAddress = getAddress(fieldRef) + (SignedPointer)offset; return RemoteAbsolutePointer(resultAddress); }