[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 58df5534d2)
This commit is contained in:
Augusto Noronha
2025-07-09 14:52:42 -07:00
parent a6eafcb311
commit 8f3862b5e7
18 changed files with 972 additions and 711 deletions

View File

@@ -132,7 +132,10 @@
#ifndef SWIFT_BASIC_RELATIVEPOINTER_H
#define SWIFT_BASIC_RELATIVEPOINTER_H
#include <cassert>
#include <cstdint>
#include <type_traits>
#include <utility>
namespace swift {

View File

@@ -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

View File

@@ -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];

View File

@@ -105,8 +105,8 @@ class InProcessMemoryReader final : public MemoryReader {
return ReadBytesResult(address.getLocalPointer<void>(), [](const void *) {});
}
};
}
}
} // namespace remote
} // namespace swift
#endif

View File

@@ -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 <typename IntegerType>
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 <typename IntegerType>
bool readInteger(RemoteAddress address, IntegerType *dest) {
static_assert(!std::is_same<RemoteAddress, IntegerType>(),
"RemoteAddress cannot be read in directly, use "
"readRemoteAddress instead.");
return readBytes(address, reinterpret_cast<uint8_t*>(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

File diff suppressed because it is too large Load Diff

View File

@@ -18,47 +18,154 @@
#ifndef SWIFT_REMOTE_REMOTEADDRESS_H
#define SWIFT_REMOTE_REMOTEADDRESS_H
#include <cstdint>
#include <string>
#include <llvm/ADT/StringRef.h>
#include "swift/ABI/MetadataRef.h"
#include "swift/Basic/RelativePointer.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/Hashing.h"
#include <cassert>
#include <cstdint>
#include <functional>
#include <iostream>
#include <llvm/ADT/StringRef.h>
#include <ostream>
#include <sstream>
#include <string>
namespace swift {
namespace remote {
/// An abstract address in the remote process's address space.
class RemoteAddress {
uint64_t Data;
public:
explicit RemoteAddress(const void *localPtr)
: Data(reinterpret_cast<uintptr_t>(localPtr)) {}
// The default address space, meaning the remote process address space.
static constexpr uint8_t DefaultAddressSpace = 0;
explicit RemoteAddress(uint64_t addressData) : Data(addressData) {}
explicit RemoteAddress(uint64_t addressData, uint8_t addressSpace)
: Data(addressData), AddressSpace(addressSpace) {}
explicit operator bool() const {
return Data != 0;
explicit RemoteAddress() {}
explicit operator bool() const { return Data != 0; }
bool operator==(const RemoteAddress rhs) const {
return Data == rhs.Data && AddressSpace == rhs.AddressSpace;
}
template <class T>
const T *getLocalPointer() const {
return reinterpret_cast<const T*>(static_cast<uintptr_t>(Data));
bool operator!=(const RemoteAddress other) const {
return !operator==(other);
}
uint64_t getAddressData() const {
return Data;
bool operator<(const RemoteAddress rhs) const {
assert(AddressSpace == rhs.AddressSpace &&
"Comparing remote addresses of different address spaces");
return Data < rhs.Data;
}
template<typename IntegerType>
RemoteAddress& operator+=(const IntegerType& rhs) {
bool operator<=(const RemoteAddress rhs) const {
assert(AddressSpace == rhs.AddressSpace &&
"Comparing remote addresses of different address spaces");
return Data <= rhs.Data;
}
bool operator>(const RemoteAddress &rhs) const {
assert(AddressSpace == rhs.AddressSpace &&
"Comparing remote addresses of different address spaces");
return Data > rhs.Data;
}
bool operator>=(const RemoteAddress &rhs) const { return Data >= rhs.Data; }
template <typename IntegerType>
RemoteAddress &operator+=(const IntegerType rhs) {
Data += rhs;
return *this;
}
template<typename IntegerType>
friend RemoteAddress operator+(RemoteAddress lhs,
const IntegerType& rhs) {
return lhs += rhs;
template <typename IntegerType>
RemoteAddress operator+(const IntegerType &rhs) const {
return RemoteAddress(Data + rhs, getAddressSpace());
}
template <typename IntegerType>
RemoteAddress operator-(const IntegerType &rhs) const {
return RemoteAddress(Data - rhs, getAddressSpace());
}
RemoteAddress operator-(const RemoteAddress &rhs) const {
if (AddressSpace != rhs.AddressSpace)
return RemoteAddress();
return RemoteAddress(Data - rhs.Data, getAddressSpace());
}
template <typename IntegerType>
RemoteAddress operator^(const IntegerType &rhs) const {
return RemoteAddress(Data ^ rhs, getAddressSpace());
}
template <class IntegerType>
RemoteAddress operator&(IntegerType other) const {
return RemoteAddress(Data & other, getAddressSpace());
}
template <typename IntegerType>
RemoteAddress &operator&=(const IntegerType rhs) {
Data &= rhs;
return *this;
}
template <typename IntegerType>
RemoteAddress &operator|=(const IntegerType rhs) {
Data |= rhs;
return *this;
}
template <typename IntegerType>
IntegerType operator>>(const IntegerType rhs) const {
return (IntegerType)Data >> rhs;
}
uint64_t getRawAddress() const { return Data; }
uint8_t getAddressSpace() const { return AddressSpace; }
template <class IntegerType>
RemoteAddress applyRelativeOffset(IntegerType offset) const {
auto atOffset = detail::applyRelativeOffset((const char *)Data, offset);
return RemoteAddress(atOffset, getAddressSpace());
}
template <typename T, bool Nullable, typename Offset>
RemoteAddress getRelative(
const RelativeDirectPointer<T, Nullable, Offset> *relative) const {
auto ptr = relative->getRelative((void *)Data);
return RemoteAddress((uint64_t)ptr, getAddressSpace());
}
template <class T>
const T *getLocalPointer() const {
return reinterpret_cast<const T *>(static_cast<uintptr_t>(Data));
}
std::string getDescription() const {
std::stringstream sstream;
// FIXME: this should print the address space too, but because Node can't
// carry the address space yet, comparing the strings produced by this type
// and a Node that carries an address would produce incorrect results.
// Revisit this once Node carries the address space.
sstream << std::hex << Data;
return sstream.str();
}
friend llvm::hash_code hash_value(const RemoteAddress &address) {
using llvm::hash_value;
return hash_value(address.Data);
}
friend struct std::hash<swift::remote::RemoteAddress>;
private:
uint64_t Data = 0;
uint8_t AddressSpace = 0;
};
/// A symbolic relocated absolute pointer value.
@@ -69,7 +176,7 @@ class RemoteAbsolutePointer {
/// The offset from the symbol.
int64_t Offset = 0;
/// The resolved remote address.
RemoteAddress Address = RemoteAddress{(uint64_t)0};
RemoteAddress Address = RemoteAddress();
public:
RemoteAbsolutePointer() = default;
@@ -90,8 +197,60 @@ public:
}
};
template <typename Runtime>
class RemoteTargetProtocolDescriptorRef {
TargetProtocolDescriptorRef<Runtime> ProtocolRef;
RemoteAddress address;
public:
RemoteTargetProtocolDescriptorRef(RemoteAddress address)
: ProtocolRef(address.getRawAddress()), address(address) {}
bool isObjC() const { return ProtocolRef.isObjC(); }
RemoteAddress getObjCProtocol() const {
auto pointer = ProtocolRef.getObjCProtocol();
return RemoteAddress(pointer, address.getAddressSpace());
}
RemoteAddress getSwiftProtocol() const {
auto pointer = ProtocolRef.getSwiftProtocol();
return RemoteAddress(pointer, address.getAddressSpace());
}
};
} // end namespace remote
} // end namespace swift
#endif // SWIFT_REMOTE_REMOTEADDRESS_H
namespace std {
template <>
struct hash<swift::remote::RemoteAddress> {
size_t operator()(const swift::remote::RemoteAddress &address) const {
return llvm::hash_combine(address.Data, address.AddressSpace);
}
};
} // namespace std
namespace llvm {
template <>
struct DenseMapInfo<swift::remote::RemoteAddress> {
static swift::remote::RemoteAddress getEmptyKey() {
return swift::remote::RemoteAddress(DenseMapInfo<uint64_t>::getEmptyKey(),
0);
}
static swift::remote::RemoteAddress getTombstoneKey() {
return swift::remote::RemoteAddress(
DenseMapInfo<uint64_t>::getTombstoneKey(), 0);
}
static unsigned getHashValue(swift::remote::RemoteAddress address) {
return std::hash<swift::remote::RemoteAddress>()(address);
}
static bool isEqual(swift::remote::RemoteAddress lhs,
swift::remote::RemoteAddress rhs) {
return lhs == rhs;
}
};
} // namespace llvm
#endif // SWIFT_REMOTE_REMOTEADDRESS_H

View File

@@ -123,8 +123,7 @@ class ReflectionContext
using super::readMetadata;
using super::readObjCClassName;
using super::readResolvedPointerValue;
llvm::DenseMap<std::pair<typename super::StoredPointer,
remote::TypeInfoProvider::IdType>,
llvm::DenseMap<std::pair<RemoteAddress, remote::TypeInfoProvider::IdType>,
const RecordTypeInfo *>
Cache;
@@ -256,17 +255,15 @@ public:
// The layout of the executable is such that the commands immediately follow
// the header.
auto CmdStartAddress =
RemoteAddress(ImageStart.getAddressData() + sizeof(typename T::Header));
auto CmdStartAddress = ImageStart + sizeof(typename T::Header);
uint32_t SegmentCmdHdrSize = sizeof(typename T::SegmentCmd);
uint64_t Offset = 0;
// Find the __TEXT segment.
typename T::SegmentCmd *TextCommand = nullptr;
for (unsigned I = 0; I < NumCommands; ++I) {
auto CmdBuf = this->getReader().readBytes(
RemoteAddress(CmdStartAddress.getAddressData() + Offset),
SegmentCmdHdrSize);
auto CmdBuf = this->getReader().readBytes(CmdStartAddress + Offset,
SegmentCmdHdrSize);
if (!CmdBuf)
return {};
auto CmdHdr = reinterpret_cast<typename T::SegmentCmd *>(CmdBuf.get());
@@ -283,26 +280,24 @@ public:
return {};
// Find the load command offset.
auto loadCmdOffset = ImageStart.getAddressData() + Offset + sizeof(typename T::Header);
auto loadCmdOffset = ImageStart + Offset + sizeof(typename T::Header);
// Read the load command.
auto LoadCmdAddress = reinterpret_cast<const char *>(loadCmdOffset);
auto LoadCmdBuf = this->getReader().readBytes(
RemoteAddress(LoadCmdAddress), sizeof(typename T::SegmentCmd));
loadCmdOffset, sizeof(typename T::SegmentCmd));
if (!LoadCmdBuf)
return {};
auto LoadCmd = reinterpret_cast<typename T::SegmentCmd *>(LoadCmdBuf.get());
// The sections start immediately after the load command.
unsigned NumSect = LoadCmd->nsects;
auto SectAddress = reinterpret_cast<const char *>(loadCmdOffset) +
sizeof(typename T::SegmentCmd);
auto SectAddress = loadCmdOffset + sizeof(typename T::SegmentCmd);
auto Sections = this->getReader().readBytes(
RemoteAddress(SectAddress), NumSect * sizeof(typename T::Section));
SectAddress, NumSect * sizeof(typename T::Section));
if (!Sections)
return {};
auto Slide = ImageStart.getAddressData() - TextCommand->vmaddr;
auto Slide = ImageStart - TextCommand->vmaddr;
auto SectionsBuf = reinterpret_cast<const char *>(Sections.get());
auto findMachOSectionByName = [&](llvm::StringRef Name)
@@ -313,9 +308,9 @@ public:
if (strncmp(S->sectname, Name.data(), sizeof(S->sectname)) != 0)
continue;
auto RemoteSecStart = S->addr + Slide;
auto RemoteSecStart = Slide + S->addr;
auto LocalSectBuf =
this->getReader().readBytes(RemoteAddress(RemoteSecStart), S->size);
this->getReader().readBytes(RemoteSecStart, S->size);
if (!LocalSectBuf)
return {nullptr, 0};
@@ -368,14 +363,12 @@ public:
auto TextSegmentStart = Slide + TextCommand->vmaddr;
auto TextSegmentEnd = TextSegmentStart + TextCommand->vmsize;
textRanges.push_back(std::make_tuple(RemoteAddress(TextSegmentStart),
RemoteAddress(TextSegmentEnd)));
textRanges.push_back(std::make_tuple(TextSegmentStart, TextSegmentEnd));
// Find the __DATA segments.
for (unsigned I = 0; I < NumCommands; ++I) {
auto CmdBuf = this->getReader().readBytes(
RemoteAddress(CmdStartAddress.getAddressData() + Offset),
SegmentCmdHdrSize);
auto CmdBuf = this->getReader().readBytes(CmdStartAddress + Offset,
SegmentCmdHdrSize);
if (!CmdBuf)
return {};
auto CmdHdr = reinterpret_cast<typename T::SegmentCmd *>(CmdBuf.get());
@@ -384,10 +377,9 @@ public:
strncmp(CmdHdr->segname, "__AUTH", 6) == 0) {
auto DataSegmentStart = Slide + CmdHdr->vmaddr;
auto DataSegmentEnd = DataSegmentStart + CmdHdr->vmsize;
assert(DataSegmentStart > ImageStart.getAddressData() &&
assert(DataSegmentStart > ImageStart &&
"invalid range for __DATA/__AUTH");
dataRanges.push_back(std::make_tuple(RemoteAddress(DataSegmentStart),
RemoteAddress(DataSegmentEnd)));
dataRanges.push_back(std::make_tuple(DataSegmentStart, DataSegmentEnd));
}
Offset += CmdHdr->cmdsize;
}
@@ -407,12 +399,11 @@ public:
return {};
auto DOSHdr =
reinterpret_cast<const llvm::object::dos_header *>(DOSHdrBuf.get());
auto COFFFileHdrAddr = ImageStart.getAddressData() +
DOSHdr->AddressOfNewExeHeader +
auto COFFFileHdrAddr = ImageStart + DOSHdr->AddressOfNewExeHeader +
sizeof(llvm::COFF::PEMagic);
auto COFFFileHdrBuf = this->getReader().readBytes(
RemoteAddress(COFFFileHdrAddr), sizeof(llvm::object::coff_file_header));
COFFFileHdrAddr, sizeof(llvm::object::coff_file_header));
if (!COFFFileHdrBuf)
return {};
auto COFFFileHdr = reinterpret_cast<const llvm::object::coff_file_header *>(
@@ -422,7 +413,7 @@ public:
sizeof(llvm::object::coff_file_header) +
COFFFileHdr->SizeOfOptionalHeader;
auto SectionTableBuf = this->getReader().readBytes(
RemoteAddress(SectionTableAddr),
SectionTableAddr,
sizeof(llvm::object::coff_section) * COFFFileHdr->NumberOfSections);
if (!SectionTableBuf)
return {};
@@ -440,9 +431,8 @@ public:
: llvm::StringRef(COFFSec->Name, llvm::COFF::NameSize);
if (SectionName != Name)
continue;
auto Addr = ImageStart.getAddressData() + COFFSec->VirtualAddress;
auto Buf = this->getReader().readBytes(RemoteAddress(Addr),
COFFSec->VirtualSize);
auto Addr = ImageStart + COFFSec->VirtualAddress;
auto Buf = this->getReader().readBytes(Addr, COFFSec->VirtualSize);
if (!Buf)
return {nullptr, 0};
auto BufStart = Buf.get();
@@ -512,10 +502,9 @@ public:
auto DOSHdr = reinterpret_cast<const llvm::object::dos_header *>(Buf.get());
auto PEHeaderAddress =
ImageStart.getAddressData() + DOSHdr->AddressOfNewExeHeader;
auto PEHeaderAddress = ImageStart + DOSHdr->AddressOfNewExeHeader;
Buf = this->getReader().readBytes(RemoteAddress(PEHeaderAddress),
Buf = this->getReader().readBytes(PEHeaderAddress,
sizeof(llvm::COFF::PEMagic));
if (!Buf)
return {};
@@ -647,8 +636,7 @@ public:
continue;
if (Retained != bool(Hdr->sh_flags & llvm::ELF::SHF_GNU_RETAIN))
continue;
RemoteAddress SecStart =
RemoteAddress(ImageStart.getAddressData() + Hdr->sh_addr);
RemoteAddress SecStart = ImageStart + Hdr->sh_addr;
auto SecSize = Hdr->sh_size;
MemoryReader::ReadBytesResult SecBuf;
if (FileBuffer.has_value()) {
@@ -670,8 +658,7 @@ public:
}
if (!SecBuf)
return {nullptr, 0};
auto SecContents =
RemoteRef<void>(SecStart.getAddressData(), SecBuf.get());
auto SecContents = RemoteRef<void>(SecStart, SecBuf.get());
savedBuffers.push_back(std::move(SecBuf));
return {SecContents, SecSize};
}
@@ -904,10 +891,10 @@ public:
}
bool ownsObject(RemoteAddress ObjectAddress) {
auto MetadataAddress = readMetadataFromInstance(ObjectAddress.getAddressData());
auto MetadataAddress = readMetadataFromInstance(ObjectAddress);
if (!MetadataAddress)
return true;
return ownsAddress(RemoteAddress(*MetadataAddress));
return ownsAddress(*MetadataAddress);
}
/// Returns true if the address falls within the given address ranges.
@@ -917,8 +904,7 @@ public:
for (auto Range : ranges) {
auto Start = std::get<0>(Range);
auto End = std::get<1>(Range);
if (Start.getAddressData() <= Address.getAddressData()
&& Address.getAddressData() < End.getAddressData())
if (Start <= Address && Address < End)
return true;
}
@@ -940,10 +926,10 @@ public:
// This is usually called on a Metadata address which might have been
// on the heap. Try reading it and looking up its type context descriptor
// instead.
if (auto Metadata = readMetadata(Address.getAddressData()))
if (auto Metadata = readMetadata(Address))
if (auto DescriptorAddress =
super::readAddressOfNominalTypeDescriptor(Metadata, true))
if (ownsAddress(RemoteAddress(DescriptorAddress), textRanges))
if (ownsAddress(DescriptorAddress, textRanges))
return true;
}
return false;
@@ -951,17 +937,18 @@ public:
/// Returns the address of the nominal type descriptor given a metadata
/// address.
StoredPointer nominalTypeDescriptorFromMetadata(StoredPointer MetadataAddress) {
RemoteAddress
nominalTypeDescriptorFromMetadata(RemoteAddress MetadataAddress) {
auto Metadata = readMetadata(MetadataAddress);
if (!Metadata)
return 0;
return RemoteAddress();
return super::readAddressOfNominalTypeDescriptor(Metadata, true);
}
/// Return a description of the layout of a class instance with the given
/// metadata as its isa pointer.
const RecordTypeInfo *
getMetadataTypeInfo(StoredPointer MetadataAddress,
getMetadataTypeInfo(RemoteAddress MetadataAddress,
remote::TypeInfoProvider *ExternalTypeInfo) {
// See if we cached the layout already
auto ExternalTypeInfoId = ExternalTypeInfo ? ExternalTypeInfo->getId() : 0;
@@ -1002,7 +989,7 @@ public:
/// Return a description of the layout of a class instance with the given
/// metadata as its isa pointer.
const TypeInfo *
getInstanceTypeInfo(StoredPointer ObjectAddress,
getInstanceTypeInfo(RemoteAddress ObjectAddress,
remote::TypeInfoProvider *ExternalTypeInfo) {
auto MetadataAddress = readMetadataFromInstance(ObjectAddress);
if (!MetadataAddress)
@@ -1029,8 +1016,7 @@ public:
//
// Non-generic SIL boxes share metadata among types with compatible
// layout, but we need some way to get an outgoing pointer map for them.
auto CD = getBuilder().getCaptureDescriptor(
CDAddr->getResolvedAddress().getAddressData());
auto CD = getBuilder().getCaptureDescriptor(CDAddr->getResolvedAddress());
if (CD == nullptr)
return nullptr;
@@ -1045,8 +1031,9 @@ public:
if (auto Meta = readMetadata(*MetadataAddress)) {
if (auto *GenericHeapMeta = cast<TargetGenericBoxHeapMetadata<Runtime>>(
Meta.getLocalBuffer())) {
auto MetadataAddress = GenericHeapMeta->BoxedType;
auto TR = readTypeFromMetadata(MetadataAddress);
auto BoxedTypeAddress = RemoteAddress(
GenericHeapMeta->BoxedType, ObjectAddress.getAddressSpace());
auto TR = readTypeFromMetadata(BoxedTypeAddress);
return getTypeInfo(TR, ExternalTypeInfo);
}
}
@@ -1064,8 +1051,7 @@ public:
std::optional<std::pair<const TypeRef *, RemoteAddress>>
getDynamicTypeAndAddressClassExistential(RemoteAddress ExistentialAddress) {
auto PointerValue =
readResolvedPointerValue(ExistentialAddress.getAddressData());
auto PointerValue = readResolvedPointerValue(ExistentialAddress);
if (!PointerValue)
return {};
auto Result = readMetadataFromInstance(*PointerValue);
@@ -1074,7 +1060,7 @@ public:
auto TypeResult = readTypeFromMetadata(Result.value());
if (!TypeResult)
return {};
return {{std::move(TypeResult), RemoteAddress(*PointerValue)}};
return {{std::move(TypeResult), *PointerValue}};
}
std::optional<std::pair<const TypeRef *, RemoteAddress>>
@@ -1084,8 +1070,7 @@ public:
if (!Result)
return {};
auto TypeResult =
readTypeFromMetadata(Result->MetadataAddress.getAddressData());
auto TypeResult = readTypeFromMetadata(Result->MetadataAddress);
if (!TypeResult)
return {};
@@ -1101,8 +1086,7 @@ public:
if (!Result)
return {};
auto TypeResult =
readTypeFromMetadata(Result->MetadataAddress.getAddressData());
auto TypeResult = readTypeFromMetadata(Result->MetadataAddress);
if (!TypeResult)
return {};
return {{std::move(TypeResult), Result->PayloadAddress}};
@@ -1139,8 +1123,7 @@ public:
if (!OptMetaAndValue)
return false;
auto InstanceTR = readTypeFromMetadata(
OptMetaAndValue->MetadataAddress.getAddressData());
auto InstanceTR = readTypeFromMetadata(OptMetaAndValue->MetadataAddress);
if (!InstanceTR)
return false;
@@ -1156,8 +1139,7 @@ public:
// FIXME: Check third value, 'IsBridgedError'
auto InstanceTR = readTypeFromMetadata(
OptMetaAndValue->MetadataAddress.getAddressData());
auto InstanceTR = readTypeFromMetadata(OptMetaAndValue->MetadataAddress);
if (!InstanceTR)
return false;
@@ -1192,10 +1174,10 @@ public:
};
auto DereferenceAndSet = [&](RemoteAddress &Address) {
auto PointerValue = readResolvedPointerValue(Address.getAddressData());
auto PointerValue = readResolvedPointerValue(Address);
if (!PointerValue)
return false;
Address = RemoteAddress(*PointerValue);
Address = *PointerValue;
return true;
};
@@ -1332,7 +1314,7 @@ public:
return dyn_cast_or_null<const RecordTypeInfo>(TypeInfo);
}
bool metadataIsActor(StoredPointer MetadataAddress) {
bool metadataIsActor(RemoteAddress MetadataAddress) {
auto Metadata = readMetadata(MetadataAddress);
if (!Metadata)
return false;
@@ -1345,12 +1327,11 @@ public:
super::readAddressOfNominalTypeDescriptor(Metadata);
if (!DescriptorAddress)
return false;
if (!ownsAddress(RemoteAddress(DescriptorAddress), textRanges))
if (!ownsAddress(DescriptorAddress, textRanges))
return false;
auto DescriptorBytes =
getReader().readBytes(RemoteAddress(DescriptorAddress),
sizeof(TargetTypeContextDescriptor<Runtime>));
auto DescriptorBytes = getReader().readBytes(
DescriptorAddress, sizeof(TargetTypeContextDescriptor<Runtime>));
if (!DescriptorBytes)
return false;
auto Descriptor =
@@ -1361,12 +1342,13 @@ public:
/// Iterate the protocol conformance cache tree rooted at NodePtr, calling
/// Call with the type and protocol in each node.
void iterateConformanceTree(StoredPointer NodePtr,
std::function<void(StoredPointer Type, StoredPointer Proto)> Call) {
void iterateConformanceTree(
RemoteAddress NodePtr,
std::function<void(RemoteAddress Type, RemoteAddress Proto)> Call) {
if (!NodePtr)
return;
auto NodeBytes = getReader().readBytes(RemoteAddress(NodePtr),
sizeof(ConformanceNode<Runtime>));
auto NodeBytes =
getReader().readBytes(NodePtr, sizeof(ConformanceNode<Runtime>));
if (!NodeBytes)
return;
auto NodeData =
@@ -1378,8 +1360,8 @@ public:
void IterateConformanceTable(
RemoteAddress ConformancesPtr,
std::function<void(StoredPointer Type, StoredPointer Proto)> Call) {
auto MapBytes = getReader().readBytes(RemoteAddress(ConformancesPtr),
std::function<void(RemoteAddress Type, RemoteAddress Proto)> Call) {
auto MapBytes = getReader().readBytes(ConformancesPtr,
sizeof(ConcurrentHashMap<Runtime>));
if (!MapBytes)
return;
@@ -1389,8 +1371,9 @@ public:
auto Count = MapData->ElementCount;
auto Size = Count * sizeof(ConformanceCacheEntry<Runtime>) + sizeof(StoredPointer);
auto ElementsBytes =
getReader().readBytes(RemoteAddress(MapData->Elements), Size);
auto ElementsBytes = getReader().readBytes(
RemoteAddress(MapData->Elements, ConformancesPtr.getAddressSpace()),
Size);
if (!ElementsBytes)
return;
auto ElementsData =
@@ -1399,7 +1382,8 @@ public:
for (StoredSize i = 0; i < Count; i++) {
auto &Element = ElementsData[i];
Call(Element.Type, Element.Proto);
Call(RemoteAddress(Element.Type, ConformancesPtr.getAddressSpace()),
RemoteAddress(Element.Proto, ConformancesPtr.getAddressSpace()));
}
}
@@ -1407,7 +1391,7 @@ public:
/// with the type and protocol of each conformance. Returns None on success,
/// and a string describing the error on failure.
std::optional<std::string> iterateConformances(
std::function<void(StoredPointer Type, StoredPointer Proto)> Call) {
std::function<void(RemoteAddress Type, RemoteAddress Proto)> Call) {
std::string ConformancesPointerName =
"_swift_debug_protocolConformanceStatePointer";
auto ConformancesAddrAddr =
@@ -1429,15 +1413,15 @@ public:
StoredPointer allocationMetadataPointer(
MetadataAllocation<Runtime> Allocation) {
if (Allocation.Tag == GenericMetadataCacheTag) {
auto AllocationBytes =
getReader().readBytes(RemoteAddress(Allocation.Ptr),
Allocation.Size);
if (!AllocationBytes)
return 0;
auto Entry =
auto AllocationBytes = getReader().readBytes(
RemoteAddress(Allocation.Ptr, RemoteAddress::DefaultAddressSpace),
Allocation.Size);
if (!AllocationBytes)
return 0;
auto Entry =
reinterpret_cast<const GenericMetadataCacheEntry<StoredPointer> *>(
AllocationBytes.get());
return Entry->Value;
AllocationBytes.get());
return Entry->Value;
}
return 0;
}
@@ -1474,7 +1458,8 @@ public:
case ForeignMetadataCacheTag:
case GenericWitnessTableCacheTag: {
auto NodeBytes = getReader().readBytes(
RemoteAddress(Allocation.Ptr), sizeof(MetadataCacheNode<Runtime>));
RemoteAddress(Allocation.Ptr, RemoteAddress::DefaultAddressSpace),
sizeof(MetadataCacheNode<Runtime>));
if (!NodeBytes)
return std::nullopt;
auto Node =
@@ -1517,14 +1502,14 @@ public:
return "failed to read value of " + AllocationPoolPointerName;
struct PoolRange {
StoredPointer Begin;
RemoteAddress Begin;
StoredSize Remaining;
};
struct PoolTrailer {
StoredPointer PrevTrailer;
RemoteAddress PrevTrailer;
StoredSize PoolSize;
};
struct alignas(StoredPointer) AllocationHeader {
struct alignas(RemoteAddress) AllocationHeader {
uint16_t Size;
uint16_t Tag;
};
@@ -1544,14 +1529,13 @@ public:
auto TrailerPtr = Pool->Begin + Pool->Remaining;
while (TrailerPtr && LoopCount++ < LoopLimit) {
auto TrailerBytes = getReader()
.readBytes(RemoteAddress(TrailerPtr), sizeof(PoolTrailer));
auto TrailerBytes =
getReader().readBytes(TrailerPtr, sizeof(PoolTrailer));
if (!TrailerBytes)
break;
auto Trailer = reinterpret_cast<const PoolTrailer *>(TrailerBytes.get());
auto PoolStart = TrailerPtr - Trailer->PoolSize;
auto PoolBytes = getReader()
.readBytes(RemoteAddress(PoolStart), Trailer->PoolSize);
auto PoolBytes = getReader().readBytes(PoolStart, Trailer->PoolSize);
if (!PoolBytes)
break;
auto PoolPtr = (const char *)PoolBytes.get();
@@ -1565,7 +1549,10 @@ public:
auto RemoteAddr = PoolStart + Offset + sizeof(AllocationHeader);
MetadataAllocation<Runtime> Allocation;
Allocation.Tag = Header->Tag;
Allocation.Ptr = RemoteAddr;
if (RemoteAddr.getAddressSpace() != RemoteAddress::DefaultAddressSpace)
return "storing remote address from non-default address space.";
Allocation.Ptr = RemoteAddr.getRawAddress();
Allocation.Size = Header->Size;
Call(Allocation);
@@ -1601,15 +1588,15 @@ public:
auto BacktraceListNext = BacktraceListNextPtr->getResolvedAddress();
while (BacktraceListNext && LoopCount++ < LoopLimit) {
auto HeaderBytes = getReader().readBytes(
RemoteAddress(BacktraceListNext),
BacktraceListNext,
sizeof(MetadataAllocationBacktraceHeader<Runtime>));
if (!HeaderBytes) {
// FIXME: std::stringstream would be better, but LLVM's standard library
// introduces a vtable and we don't want that.
char result[128];
std::snprintf(result, sizeof(result),
"unable to read Next pointer %#" PRIx64,
BacktraceListNext.getAddressData());
"unable to read Next pointer %#" PRIx64,
BacktraceListNext.getRawAddress());
return std::string(result);
}
auto HeaderPtr =
@@ -1618,15 +1605,15 @@ public:
auto BacktraceAddrPtr =
BacktraceListNext +
sizeof(MetadataAllocationBacktraceHeader<Runtime>);
auto BacktraceBytes =
getReader().readBytes(RemoteAddress(BacktraceAddrPtr),
HeaderPtr->Count * sizeof(StoredPointer));
auto BacktraceBytes = getReader().readBytes(
BacktraceAddrPtr, HeaderPtr->Count * sizeof(StoredPointer));
auto BacktracePtr =
reinterpret_cast<const StoredPointer *>(BacktraceBytes.get());
Call(HeaderPtr->Allocation, HeaderPtr->Count, BacktracePtr);
BacktraceListNext = RemoteAddress(HeaderPtr->Next);
BacktraceListNext =
RemoteAddress(HeaderPtr->Next, RemoteAddress::DefaultAddressSpace);
}
return std::nullopt;
}
@@ -1635,7 +1622,8 @@ public:
asyncTaskSlabAllocations(StoredPointer SlabPtr) {
using StackAllocator = StackAllocator<Runtime>;
auto SlabBytes = getReader().readBytes(
RemoteAddress(SlabPtr), sizeof(typename StackAllocator::Slab));
RemoteAddress(SlabPtr, RemoteAddress::DefaultAddressSpace),
sizeof(typename StackAllocator::Slab));
auto Slab = reinterpret_cast<const typename StackAllocator::Slab *>(
SlabBytes.get());
if (!Slab)
@@ -1660,14 +1648,14 @@ public:
NextPtrChunk.Kind = AsyncTaskAllocationChunk::ChunkKind::RawPointer;
// Total slab size is the slab's capacity plus the header.
StoredPointer SlabSize = Slab->Capacity + HeaderSize;
auto SlabSize = Slab->Capacity + HeaderSize;
return {std::nullopt,
{Slab->Next, SlabSize, {NextPtrChunk, AllocatedSpaceChunk}}};
}
std::pair<std::optional<std::string>, AsyncTaskInfo>
asyncTaskInfo(StoredPointer AsyncTaskPtr, unsigned ChildTaskLimit,
asyncTaskInfo(RemoteAddress AsyncTaskPtr, unsigned ChildTaskLimit,
unsigned AsyncBacktraceLimit) {
loadTargetPointers();
@@ -1682,7 +1670,7 @@ public:
}
std::pair<std::optional<std::string>, ActorInfo>
actorInfo(StoredPointer ActorPtr) {
actorInfo(RemoteAddress ActorPtr) {
if (supportsPriorityEscalation)
return actorInfo<
DefaultActorImpl<Runtime, ActiveActorStatusWithEscalation<Runtime>>>(
@@ -1692,10 +1680,10 @@ public:
Runtime, ActiveActorStatusWithoutEscalation<Runtime>>>(ActorPtr);
}
StoredPointer nextJob(StoredPointer JobPtr) {
StoredPointer nextJob(RemoteAddress JobPtr) {
using Job = Job<Runtime>;
auto JobBytes = getReader().readBytes(RemoteAddress(JobPtr), sizeof(Job));
auto JobBytes = getReader().readBytes(JobPtr, sizeof(Job));
auto *JobObj = reinterpret_cast<const Job *>(JobBytes.get());
if (!JobObj)
return 0;
@@ -1770,7 +1758,7 @@ private:
template <typename AsyncTaskType>
std::pair<std::optional<std::string>, AsyncTaskInfo>
asyncTaskInfo(StoredPointer AsyncTaskPtr, unsigned ChildTaskLimit,
asyncTaskInfo(RemoteAddress AsyncTaskPtr, unsigned ChildTaskLimit,
unsigned AsyncBacktraceLimit) {
auto AsyncTaskObj = readObj<AsyncTaskType>(AsyncTaskPtr);
if (!AsyncTaskObj)
@@ -1805,7 +1793,8 @@ private:
// Find all child tasks.
unsigned ChildTaskLoopCount = 0;
auto RecordPtr = AsyncTaskObj->PrivateStorage.Status.Record;
auto RecordPtr = RemoteAddress(AsyncTaskObj->PrivateStorage.Status.Record,
RemoteAddress::DefaultAddressSpace);
while (RecordPtr && ChildTaskLoopCount++ < ChildTaskLimit) {
auto RecordObj = readObj<TaskStatusRecord<Runtime>>(RecordPtr);
if (!RecordObj)
@@ -1829,8 +1818,10 @@ private:
}
while (ChildTask && ChildTaskLoopCount++ < ChildTaskLimit) {
RemoteAddress ChildTaskAddress =
RemoteAddress(ChildTask, RemoteAddress::DefaultAddressSpace);
// Read the child task.
auto ChildTaskObj = readObj<AsyncTaskType>(ChildTask);
auto ChildTaskObj = readObj<AsyncTaskType>(ChildTaskAddress);
if (!ChildTaskObj)
return {std::string("found unreadable child task pointer"), Info};
@@ -1843,7 +1834,7 @@ private:
"iterate child tasks"),
Info};
StoredPointer ChildFragmentAddr = ChildTask + asyncTaskSize;
RemoteAddress ChildFragmentAddr = ChildTaskAddress + asyncTaskSize;
auto ChildFragmentObj =
readObj<ChildFragment<Runtime>>(ChildFragmentAddr);
if (ChildFragmentObj)
@@ -1856,7 +1847,8 @@ private:
}
}
RecordPtr = RecordObj->Parent;
RecordPtr =
RemoteAddress(RecordObj->Parent, RemoteAddress::DefaultAddressSpace);
}
const auto TaskResumeContext = AsyncTaskObj->ResumeContextAndReserved[0];
@@ -1867,12 +1859,14 @@ private:
auto ResumeContext = TaskResumeContext;
unsigned AsyncBacktraceLoopCount = 0;
while (ResumeContext && AsyncBacktraceLoopCount++ < AsyncBacktraceLimit) {
auto ResumeContextObj = readObj<AsyncContext<Runtime>>(ResumeContext);
auto ResumeContextObj = readObj<AsyncContext<Runtime>>(
RemoteAddress(ResumeContext, RemoteAddress::DefaultAddressSpace));
if (!ResumeContextObj)
break;
Info.AsyncBacktraceFrames.push_back(
stripSignedPointer(ResumeContextObj->ResumeParent));
ResumeContext = stripSignedPointer(ResumeContextObj->Parent);
stripSignedPointer(ResumeContextObj->ResumeParent).getRawAddress());
ResumeContext =
stripSignedPointer(ResumeContextObj->Parent).getRawAddress();
}
}
@@ -1881,7 +1875,7 @@ private:
template <typename ActorType>
std::pair<std::optional<std::string>, ActorInfo>
actorInfo(StoredPointer ActorPtr) {
actorInfo(RemoteAddress ActorPtr) {
auto ActorObj = readObj<ActorType>(ActorPtr);
if (!ActorObj)
return {std::string("failure reading actor"), {}};
@@ -1900,7 +1894,7 @@ private:
// Don't read FirstJob when idle.
if (Info.State != concurrency::ActorFlagConstants::Idle) {
// This is a JobRef which stores flags in the low bits.
Info.FirstJob = ActorObj->Status.FirstJob & ~StoredPointer(0x3);
Info.FirstJob = ActorObj->Status.FirstJob & ~0x3;
}
std::tie(Info.HasThreadPort, Info.ThreadPort) =
@@ -1913,27 +1907,29 @@ private:
// like AsyncTask::getResumeFunctionForLogging does.
template <typename AsyncTaskType>
StoredPointer getRunJob(const AsyncTaskType *AsyncTaskObj) {
auto Fptr = stripSignedPointer(AsyncTaskObj->RunJob);
auto Fptr = stripSignedPointer(AsyncTaskObj->RunJob).getRawAddress();
loadTargetPointers();
auto ResumeContextPtr = AsyncTaskObj->ResumeContextAndReserved[0];
if (target_non_future_adapter && Fptr == target_non_future_adapter) {
using Prefix = AsyncContextPrefix<Runtime>;
auto PrefixAddr = ResumeContextPtr - sizeof(Prefix);
auto PrefixBytes =
getReader().readBytes(RemoteAddress(PrefixAddr), sizeof(Prefix));
auto PrefixBytes = getReader().readBytes(
RemoteAddress(PrefixAddr, RemoteAddress::DefaultAddressSpace),
sizeof(Prefix));
if (PrefixBytes) {
auto PrefixPtr = reinterpret_cast<const Prefix *>(PrefixBytes.get());
return stripSignedPointer(PrefixPtr->AsyncEntryPoint);
return stripSignedPointer(PrefixPtr->AsyncEntryPoint).getRawAddress();
}
} else if (target_future_adapter && Fptr == target_future_adapter) {
using Prefix = FutureAsyncContextPrefix<Runtime>;
auto PrefixAddr = ResumeContextPtr - sizeof(Prefix);
auto PrefixBytes =
getReader().readBytes(RemoteAddress(PrefixAddr), sizeof(Prefix));
auto PrefixBytes = getReader().readBytes(
RemoteAddress(PrefixAddr, RemoteAddress::DefaultAddressSpace),
sizeof(Prefix));
if (PrefixBytes) {
auto PrefixPtr = reinterpret_cast<const Prefix *>(PrefixBytes.get());
return stripSignedPointer(PrefixPtr->AsyncEntryPoint);
return stripSignedPointer(PrefixPtr->AsyncEntryPoint).getRawAddress();
}
} else if ((target_task_wait_throwing_resume_adapter &&
Fptr == target_task_wait_throwing_resume_adapter) ||
@@ -1944,11 +1940,12 @@ private:
// and the pointers are potentially stale.
if (AsyncTaskObj->PrivateStorage.DependencyRecord) {
auto ContextBytes = getReader().readBytes(
RemoteAddress(ResumeContextPtr), sizeof(AsyncContext<Runtime>));
RemoteAddress(ResumeContextPtr, RemoteAddress::DefaultAddressSpace),
sizeof(AsyncContext<Runtime>));
if (ContextBytes) {
auto ContextPtr = reinterpret_cast<const AsyncContext<Runtime> *>(
ContextBytes.get());
return stripSignedPointer(ContextPtr->ResumeParent);
return stripSignedPointer(ContextPtr->ResumeParent).getRawAddress();
}
}
}
@@ -1967,7 +1964,7 @@ private:
auto Pointer = getReader().readPointer(Symbol, sizeof(StoredPointer));
if (!Pointer)
return 0;
return Pointer->getResolvedAddress().getAddressData();
return Pointer->getResolvedAddress().getRawAddress();
};
target_asyncTaskMetadata =
getPointer("_swift_concurrency_debug_asyncTaskMetadata");
@@ -1995,7 +1992,7 @@ private:
}
const TypeInfo *
getClosureContextInfo(StoredPointer Context, const ClosureContextInfo &Info,
getClosureContextInfo(RemoteAddress Context, const ClosureContextInfo &Info,
remote::TypeInfoProvider *ExternalTypeInfo) {
RecordTypeInfoBuilder Builder(getBuilder().getTypeConverter(),
RecordKind::ClosureContext);
@@ -2144,8 +2141,8 @@ private:
/// above.
///
/// \param Builder Used to obtain offsets of elements known so far.
std::optional<StoredPointer>
readMetadataSource(StoredPointer Context, const MetadataSource *MS,
std::optional<RemoteAddress>
readMetadataSource(RemoteAddress Context, const MetadataSource *MS,
const RecordTypeInfoBuilder &Builder) {
switch (MS->getKind()) {
case MetadataSourceKind::ClosureBinding: {
@@ -2161,9 +2158,9 @@ private:
unsigned Offset = getSizeOfHeapObject() +
sizeof(StoredPointer) * Index;
StoredPointer MetadataAddress;
if (!getReader().readInteger(RemoteAddress(Context + Offset),
&MetadataAddress))
RemoteAddress MetadataAddress;
if (!getReader().template readRemoteAddress<StoredPointer>(
Context + Offset, MetadataAddress))
break;
return MetadataAddress;
@@ -2175,9 +2172,9 @@ private:
// of this capture in the context.
unsigned CaptureOffset = Builder.getFieldOffset(Index);
StoredPointer CaptureAddress;
if (!getReader().readInteger(RemoteAddress(Context + CaptureOffset),
&CaptureAddress))
RemoteAddress CaptureAddress;
if (!getReader().template readRemoteAddress<StoredPointer>(
Context + CaptureOffset, CaptureAddress))
break;
// Read the requested capture's isa pointer.
@@ -2190,9 +2187,9 @@ private:
// of this capture in the context.
unsigned CaptureOffset = Builder.getFieldOffset(Index);
StoredPointer CaptureAddress;
if (!getReader().readInteger(RemoteAddress(Context + CaptureOffset),
&CaptureAddress))
RemoteAddress CaptureAddress;
if (!getReader().template readRemoteAddress<StoredPointer>(
Context + CaptureOffset, CaptureAddress))
break;
return CaptureAddress;
@@ -2219,8 +2216,8 @@ private:
}
template <typename T>
MemoryReader::ReadObjResult<T> readObj(StoredPointer Ptr) {
return getReader().template readObj<T>(RemoteAddress(Ptr));
MemoryReader::ReadObjResult<T> readObj(RemoteAddress Ptr) {
return getReader().template readObj<T>(Ptr);
}
};

View File

@@ -63,16 +63,17 @@ public:
size_t size() const { return Size; }
bool containsRemoteAddress(uint64_t remoteAddr, uint64_t size) const {
return Start.getAddressData() <= remoteAddr &&
remoteAddr + size <= Start.getAddressData() + Size;
bool containsRemoteAddress(remote::RemoteAddress remoteAddr,
uint64_t size) const {
return Start.getRemoteAddress() <= remoteAddr &&
remoteAddr + size <= Start.getRemoteAddress() + Size;
}
template <typename U>
RemoteRef<U> getRemoteRef(uint64_t remoteAddr) const {
RemoteRef<U> getRemoteRef(remote::RemoteAddress remoteAddr) const {
assert(containsRemoteAddress(remoteAddr, sizeof(U)));
auto localAddr = (uint64_t)(uintptr_t)Start.getLocalBuffer() +
(remoteAddr - Start.getAddressData());
(remoteAddr - Start.getRemoteAddress()).getRawAddress();
return RemoteRef<U>(remoteAddr, (const U *)localAddr);
}
@@ -124,7 +125,7 @@ public:
RemoteRef<Descriptor> operator*() const {
assert(Size > 0);
return RemoteRef<Descriptor>(Cur.getAddressData(),
return RemoteRef<Descriptor>(Cur.getRemoteAddress(),
(const Descriptor *)Cur.getLocalBuffer());
}
@@ -499,7 +500,8 @@ public:
/// Get the raw capture descriptor for a remote capture descriptor
/// address.
RemoteRef<CaptureDescriptor> getCaptureDescriptor(uint64_t RemoteAddress);
RemoteRef<CaptureDescriptor>
getCaptureDescriptor(remote::RemoteAddress RemoteAddress);
/// Get the unsubstituted capture types for a closure context.
ClosureContextInfo getClosureContextInfo(RemoteRef<CaptureDescriptor> CD);
@@ -512,11 +514,11 @@ public:
const std::string &Member,
StringRef Protocol);
RemoteRef<char> readTypeRef(uint64_t remoteAddr);
RemoteRef<char> readTypeRef(remote::RemoteAddress remoteAddr);
template <typename Record, typename Field>
RemoteRef<char> readTypeRef(RemoteRef<Record> record, const Field &field) {
uint64_t remoteAddr = record.resolveRelativeFieldData(field);
remote::RemoteAddress remoteAddr = record.resolveRelativeFieldData(field);
return readTypeRef(remoteAddr);
}
@@ -544,7 +546,8 @@ public:
StringRef searchName);
std::optional<std::reference_wrapper<const ReflectionInfo>>
findReflectionInfoWithTypeRefContainingAddress(uint64_t remoteAddr);
findReflectionInfoWithTypeRefContainingAddress(
remote::RemoteAddress remoteAddr);
std::vector<ReflectionInfo> ReflectionInfos;
@@ -555,8 +558,7 @@ public:
llvm::DenseSet<size_t> ProcessedReflectionInfoIndexes;
/// Cache for capture descriptor lookups.
std::unordered_map<uint64_t /* remote address*/,
RemoteRef<CaptureDescriptor>>
std::unordered_map<remote::RemoteAddress, RemoteRef<CaptureDescriptor>>
CaptureDescriptorsByAddress;
uint32_t CaptureDescriptorsByAddressLastReflectionInfoCache = 0;
@@ -565,7 +567,7 @@ public:
FieldTypeInfoCache;
/// Cache for normalized reflection name lookups.
std::unordered_map<uint64_t /* remote address */,
std::unordered_map<remote::RemoteAddress /* remote address */,
std::optional<std::string>>
NormalizedReflectionNameCache;
@@ -1107,8 +1109,12 @@ public:
// Try to resolve to the underlying type, if we can.
if (opaqueDescriptor->getKind() ==
Node::Kind::OpaqueTypeDescriptorSymbolicReference) {
auto underlyingTy =
OpaqueUnderlyingTypeReader(opaqueDescriptor->getIndex(), ordinal);
// FIXME: Node should carry a data structure that can fit a remote
// address. For now assume that this is a virtual address.
auto underlyingTy = OpaqueUnderlyingTypeReader(
remote::RemoteAddress(opaqueDescriptor->getIndex(),
remote::RemoteAddress::DefaultAddressSpace),
ordinal);
if (!underlyingTy)
return nullptr;
@@ -1457,7 +1463,7 @@ private:
llvm::DenseSet<size_t> ProcessedReflectionInfoIndexes;
public:
RemoteRef<char> readTypeRef(uint64_t remoteAddr) {
RemoteRef<char> readTypeRef(remote::RemoteAddress remoteAddr) {
return RDF.readTypeRef(remoteAddr);
}
template <typename Record, typename Field>
@@ -1471,7 +1477,7 @@ public:
private:
using RefDemangler = std::function<Demangle::Node *(RemoteRef<char>, bool)>;
using UnderlyingTypeReader =
std::function<const TypeRef *(uint64_t, unsigned)>;
std::function<const TypeRef *(remote::RemoteAddress, unsigned)>;
using ByteReader = std::function<remote::MemoryReader::ReadBytesResult(
remote::RemoteAddress, unsigned)>;
using StringReader =
@@ -1528,7 +1534,7 @@ public:
useOpaqueTypeSymbolicReferences);
}),
OpaqueUnderlyingTypeReader(
[&reader](uint64_t descriptorAddr,
[&reader](remote::RemoteAddress descriptorAddr,
unsigned ordinal) -> const TypeRef * {
return reader
.readUnderlyingTypeForOpaqueTypeDescriptor(descriptorAddr,
@@ -1616,7 +1622,8 @@ public:
/// Get the raw capture descriptor for a remote capture descriptor
/// address.
RemoteRef<CaptureDescriptor> getCaptureDescriptor(uint64_t RemoteAddress) {
RemoteRef<CaptureDescriptor>
getCaptureDescriptor(remote::RemoteAddress RemoteAddress) {
return RDF.getCaptureDescriptor(RemoteAddress);
}
@@ -1697,8 +1704,11 @@ public:
auto opaqueTypeChildDemangleTree = childDemangleTree->getFirstChild();
if (opaqueTypeChildDemangleTree->getKind() ==
Node::Kind::OpaqueTypeDescriptorSymbolicReference) {
// FIXME: Node should carry a data structure that can fit a remote
// address. For now assume that this is a process address.
extractOpaqueTypeProtocolRequirements<ObjCInteropKind, PointerSize>(
opaqueTypeChildDemangleTree->getIndex(),
remote::RemoteAddress(opaqueTypeChildDemangleTree->getIndex(),
remote::RemoteAddress::DefaultAddressSpace),
opaqueTypeConformanceRequirements, sameTypeRequirements);
}
}
@@ -1708,7 +1718,7 @@ public:
private:
struct ContextNameInfo {
std::string name;
uintptr_t descriptorAddress;
remote::RemoteAddress descriptorAddress;
bool isAnonymous;
~ContextNameInfo() {}
@@ -1731,10 +1741,10 @@ private:
OpaqueDynamicSymbolResolver(dynamicSymbolResolver) {}
std::optional<std::string> readProtocolNameFromProtocolDescriptor(
uintptr_t protocolDescriptorAddress) {
remote::RemoteAddress protocolDescriptorAddress) {
std::string protocolName;
auto protocolDescriptorBytes = OpaqueByteReader(
remote::RemoteAddress(protocolDescriptorAddress),
protocolDescriptorAddress,
sizeof(ExternalProtocolDescriptor<ObjCInteropKind, PointerSize>));
if (!protocolDescriptorBytes.get()) {
Error = "Error reading protocol descriptor.";
@@ -1747,11 +1757,11 @@ private:
// Compute the address of the protocol descriptor's name field and read
// the offset
auto protocolNameOffsetAddress = detail::applyRelativeOffset(
(const char *)protocolDescriptorAddress,
(int32_t)protocolDescriptor->getNameOffset());
auto protocolNameOffsetBytes = OpaqueByteReader(
remote::RemoteAddress(protocolNameOffsetAddress), sizeof(uint32_t));
auto protocolNameOffsetAddress =
protocolDescriptorAddress.applyRelativeOffset(
(int32_t)protocolDescriptor->getNameOffset());
auto protocolNameOffsetBytes =
OpaqueByteReader(protocolNameOffsetAddress, sizeof(uint32_t));
if (!protocolNameOffsetBytes.get()) {
Error = "Failed to read type name offset in a protocol descriptor.";
return std::nullopt;
@@ -1760,74 +1770,71 @@ private:
// Using the offset above, compute the address of the name field itsel
// and read it.
auto protocolNameAddress =
detail::applyRelativeOffset((const char *)protocolNameOffsetAddress,
(int32_t)*protocolNameOffset);
OpaqueStringReader(remote::RemoteAddress(protocolNameAddress),
protocolName);
auto protocolNameAddress = protocolNameOffsetAddress.applyRelativeOffset(
(int32_t)*protocolNameOffset);
OpaqueStringReader(protocolNameAddress, protocolName);
return protocolName;
}
std::optional<std::string> readTypeNameFromTypeDescriptor(
const ExternalTypeContextDescriptor<ObjCInteropKind, PointerSize>
*typeDescriptor,
uintptr_t typeDescriptorAddress) {
auto typeNameOffsetAddress =
detail::applyRelativeOffset((const char *)typeDescriptorAddress,
(int32_t)typeDescriptor->getNameOffset());
auto typeNameOffsetBytes = OpaqueByteReader(
remote::RemoteAddress(typeNameOffsetAddress), sizeof(uint32_t));
remote::RemoteAddress typeDescriptorAddress) {
auto typeNameOffsetAddress = typeDescriptorAddress.applyRelativeOffset(
(int32_t)typeDescriptor->getNameOffset());
auto typeNameOffsetBytes =
OpaqueByteReader(typeNameOffsetAddress, sizeof(uint32_t));
if (!typeNameOffsetBytes.get()) {
Error = "Failed to read type name offset in a type descriptor.";
return std::nullopt;
}
auto typeNameOffset = (const uint32_t *)typeNameOffsetBytes.get();
auto typeNameAddress = detail::applyRelativeOffset(
(const char *)typeNameOffsetAddress, (int32_t)*typeNameOffset);
auto typeNameAddress =
typeNameOffsetAddress.applyRelativeOffset((int32_t)*typeNameOffset);
std::string typeName;
OpaqueStringReader(remote::RemoteAddress(typeNameAddress), typeName);
OpaqueStringReader(typeNameAddress, typeName);
return typeName;
}
std::optional<std::string> readModuleNameFromModuleDescriptor(
const ExternalModuleContextDescriptor<ObjCInteropKind, PointerSize>
*moduleDescriptor,
uintptr_t moduleDescriptorAddress) {
auto parentNameOffsetAddress = detail::applyRelativeOffset(
(const char *)moduleDescriptorAddress,
(int32_t)moduleDescriptor->getNameOffset());
auto parentNameOffsetBytes = OpaqueByteReader(
remote::RemoteAddress(parentNameOffsetAddress), sizeof(uint32_t));
remote::RemoteAddress moduleDescriptorAddress) {
auto parentNameOffsetAddress =
moduleDescriptorAddress.applyRelativeOffset(
(int32_t)moduleDescriptor->getNameOffset());
auto parentNameOffsetBytes =
OpaqueByteReader(parentNameOffsetAddress, sizeof(uint32_t));
if (!parentNameOffsetBytes.get()) {
Error = "Failed to read parent name offset in a module descriptor.";
return std::nullopt;
}
auto parentNameOffset = (const uint32_t *)parentNameOffsetBytes.get();
auto parentNameAddress = detail::applyRelativeOffset(
(const char *)parentNameOffsetAddress, (int32_t)*parentNameOffset);
auto parentNameAddress = parentNameOffsetAddress.applyRelativeOffset(
(int32_t)*parentNameOffset);
std::string parentName;
OpaqueStringReader(remote::RemoteAddress(parentNameAddress), parentName);
OpaqueStringReader(parentNameAddress, parentName);
return parentName;
}
std::optional<std::string> readAnonymousNameFromAnonymousDescriptor(
const ExternalAnonymousContextDescriptor<ObjCInteropKind, PointerSize>
*anonymousDescriptor,
uintptr_t anonymousDescriptorAddress) {
remote::RemoteAddress anonymousDescriptorAddress) {
if (!anonymousDescriptor->hasMangledName()) {
std::stringstream stream;
stream << "(unknown context at $" << std::hex
<< anonymousDescriptorAddress << ")";
stream << "(unknown context at $"
<< anonymousDescriptorAddress.getDescription() << ")";
return stream.str();
}
return std::nullopt;
}
std::optional<std::string>
readFullyQualifiedTypeName(uintptr_t typeDescriptorTarget) {
readFullyQualifiedTypeName(remote::RemoteAddress typeDescriptorTarget) {
std::string typeName;
auto contextTypeDescriptorBytes = OpaqueByteReader(
remote::RemoteAddress(typeDescriptorTarget),
typeDescriptorTarget,
sizeof(ExternalContextDescriptor<ObjCInteropKind, PointerSize>));
if (!contextTypeDescriptorBytes.get()) {
Error = "Failed to read context descriptor.";
@@ -1861,16 +1868,15 @@ private:
return constructFullyQualifiedNameFromContextChain(contextNameChain);
}
std::optional<std::string>
readFullyQualifiedProtocolName(uintptr_t protocolDescriptorTarget) {
std::optional<std::string> readFullyQualifiedProtocolName(
remote::RemoteAddress protocolDescriptorTarget) {
std::optional<std::string> protocolName;
// Set low bit indicates that this is an indirect
// reference
if (protocolDescriptorTarget & 0x1) {
auto adjustedProtocolDescriptorTarget = protocolDescriptorTarget & ~0x1;
if (auto symbol = OpaquePointerReader(
remote::RemoteAddress(adjustedProtocolDescriptorTarget),
PointerSize)) {
if (auto symbol = OpaquePointerReader(adjustedProtocolDescriptorTarget,
PointerSize)) {
if (!symbol->getSymbol().empty() && symbol->getOffset() == 0) {
Demangle::Context Ctx;
auto demangledRoot =
@@ -1882,8 +1888,7 @@ private:
nodeToString(demangledRoot->getChild(0)->getChild(0));
} else {
// This is an absolute address of a protocol descriptor
auto protocolDescriptorAddress =
(uintptr_t)symbol->getResolvedAddress().getAddressData();
auto protocolDescriptorAddress = symbol->getResolvedAddress();
protocolName = readFullyQualifiedProtocolNameFromProtocolDescriptor(
protocolDescriptorAddress);
}
@@ -1903,13 +1908,13 @@ private:
private:
std::optional<std::string>
readFullyQualifiedProtocolNameFromProtocolDescriptor(
uintptr_t protocolDescriptorAddress) {
remote::RemoteAddress protocolDescriptorAddress) {
std::optional<std::string> protocolName =
readProtocolNameFromProtocolDescriptor(protocolDescriptorAddress);
// Read the protocol conformance descriptor itself
auto protocolContextDescriptorBytes = OpaqueByteReader(
remote::RemoteAddress(protocolDescriptorAddress),
protocolDescriptorAddress,
sizeof(ExternalContextDescriptor<ObjCInteropKind, PointerSize>));
if (!protocolContextDescriptorBytes.get()) {
return std::nullopt;
@@ -1927,23 +1932,22 @@ private:
return constructFullyQualifiedNameFromContextChain(contextNameChain);
}
uintptr_t getParentDescriptorAddress(
uintptr_t contextDescriptorAddress,
remote::RemoteAddress getParentDescriptorAddress(
remote::RemoteAddress contextDescriptorAddress,
const ExternalContextDescriptor<ObjCInteropKind, PointerSize>
*contextDescriptor) {
auto parentOffsetAddress = detail::applyRelativeOffset(
(const char *)contextDescriptorAddress,
auto parentOffsetAddress = contextDescriptorAddress.applyRelativeOffset(
(int32_t)contextDescriptor->getParentOffset());
auto parentOfsetBytes = OpaqueByteReader(
remote::RemoteAddress(parentOffsetAddress), sizeof(uint32_t));
auto parentOfsetBytes =
OpaqueByteReader(parentOffsetAddress, sizeof(uint32_t));
auto parentFieldOffset = (const int32_t *)parentOfsetBytes.get();
auto parentTargetAddress = detail::applyRelativeOffset(
(const char *)parentOffsetAddress, *parentFieldOffset);
auto parentTargetAddress =
parentOffsetAddress.applyRelativeOffset(*parentFieldOffset);
return parentTargetAddress;
}
std::optional<ContextNameInfo>
getContextName(uintptr_t contextDescriptorAddress,
getContextName(remote::RemoteAddress contextDescriptorAddress,
const ExternalContextDescriptor<ObjCInteropKind, PointerSize>
*contextDescriptor) {
if (auto moduleDescriptor = dyn_cast<
@@ -1989,7 +1993,7 @@ private:
}
void getParentContextChain(
uintptr_t contextDescriptorAddress,
remote::RemoteAddress contextDescriptorAddress,
const ExternalContextDescriptor<ObjCInteropKind, PointerSize>
*contextDescriptor,
std::vector<ContextNameInfo> &chain) {
@@ -1997,10 +2001,10 @@ private:
contextDescriptorAddress, contextDescriptor);
auto addParentNameAndRecurse =
[&](uintptr_t parentContextDescriptorAddress,
[&](remote::RemoteAddress parentContextDescriptorAddress,
std::vector<ContextNameInfo> &chain) -> void {
auto parentContextDescriptorBytes = OpaqueByteReader(
remote::RemoteAddress(parentContextDescriptorAddress),
parentContextDescriptorAddress,
sizeof(ExternalContextDescriptor<ObjCInteropKind, PointerSize>));
if (!parentContextDescriptorBytes.get()) {
Error = "Failed to read context descriptor.";
@@ -2024,9 +2028,8 @@ private:
// Set low bit indicates that this is an indirect reference
if (parentDescriptorAddress & 0x1) {
auto adjustedParentTargetAddress = parentDescriptorAddress & ~0x1;
if (auto symbol = OpaquePointerReader(
remote::RemoteAddress(adjustedParentTargetAddress),
PointerSize)) {
if (auto symbol =
OpaquePointerReader(adjustedParentTargetAddress, PointerSize)) {
if (!symbol->getSymbol().empty() && symbol->getOffset() == 0) {
Demangle::Context Ctx;
auto demangledRoot =
@@ -2072,8 +2075,9 @@ private:
lastContext ? false : contextNameChain[i + 1].isAnonymous;
if (nextContextIsAnonymous && !currentContextIsAnonymous) {
std::stringstream stream;
stream << "(" << contextNameInfo.name << " in $" << std::hex
<< contextNameChain[i + 1].descriptorAddress << ")";
stream << "(" << contextNameInfo.name << " in $"
<< contextNameChain[i + 1].descriptorAddress.getDescription()
<< ")";
reversedQualifiedTypeNameMembers.push_back(stream.str());
skipNext = true;
} else if (nextContextIsAnonymous && currentContextIsAnonymous) {
@@ -2104,11 +2108,11 @@ private:
template <template <typename Runtime> class ObjCInteropKind,
unsigned PointerSize>
void extractOpaqueTypeProtocolRequirements(
uintptr_t opaqueTypeDescriptorAddress,
remote::RemoteAddress opaqueTypeDescriptorAddress,
std::vector<std::string> &protocolRequirements,
std::vector<TypeAliasInfo> &sameTypeRequirements) {
auto opaqueTypeDescriptorBytes = OpaqueByteReader(
remote::RemoteAddress(opaqueTypeDescriptorAddress),
opaqueTypeDescriptorAddress,
sizeof(ExternalOpaqueTypeDescriptor<ObjCInteropKind, PointerSize>));
if (!opaqueTypeDescriptorBytes.get()) {
return;
@@ -2126,16 +2130,15 @@ private:
// is an offset to a TypeRef string, read it.
auto readRequirementTypeRefAddress =
[&](uintptr_t offsetFromOpaqueDescBase,
uintptr_t requirementAddress) -> uintptr_t {
uintptr_t requirementAddress) -> remote::RemoteAddress {
std::string typeRefString = "";
auto fieldOffsetOffset = requirementAddress + offsetFromOpaqueDescBase -
(uintptr_t)opaqueTypeDescriptor;
auto fieldOffsetAddress = opaqueTypeDescriptorAddress + fieldOffsetOffset;
auto fieldOffsetBytes = OpaqueByteReader(
remote::RemoteAddress(fieldOffsetAddress), sizeof(uint32_t));
auto fieldOffsetBytes =
OpaqueByteReader(fieldOffsetAddress, sizeof(uint32_t));
auto fieldOffset = (const int32_t *)fieldOffsetBytes.get();
auto fieldAddress = detail::applyRelativeOffset(
(const char *)fieldOffsetAddress, *fieldOffset);
auto fieldAddress = fieldOffsetAddress.applyRelativeOffset(*fieldOffset);
return fieldAddress;
};
@@ -2153,9 +2156,9 @@ private:
// Compute the address of the protocol descriptor by following the
// offset
auto protocolDescriptorAddress = detail::applyRelativeOffset(
(const char *)protocolDescriptorOffsetAddress,
protocolDescriptorOffsetValue);
auto protocolDescriptorAddress =
protocolDescriptorOffsetAddress.applyRelativeOffset(
protocolDescriptorOffsetValue);
auto nameReader =
QualifiedContextNameReader<ObjCInteropKind, PointerSize>(
@@ -2220,7 +2223,7 @@ private:
/// Extract conforming type's name from a Conformance Descriptor
/// Returns a pair of (mangledTypeName, fullyQualifiedTypeName)
std::optional<std::pair<std::string, std::string>> getConformingTypeName(
const uintptr_t conformanceDescriptorAddress,
const remote::RemoteAddress conformanceDescriptorAddress,
const ExternalProtocolConformanceDescriptor<
ObjCInteropKind, PointerSize> &conformanceDescriptor) {
std::string typeName;
@@ -2242,12 +2245,11 @@ private:
// descriptor
// - Address of the type descriptor is found at the (2) offset from the
// conformance descriptor address
auto contextDescriptorFieldAddress = detail::applyRelativeOffset(
(const char *)conformanceDescriptorAddress,
(int32_t)conformanceDescriptor.getTypeRefDescriptorOffset());
auto contextDescriptorFieldAddress =
conformanceDescriptorAddress.applyRelativeOffset(
(int32_t)conformanceDescriptor.getTypeRefDescriptorOffset());
auto contextDescriptorOffsetBytes =
OpaqueByteReader(remote::RemoteAddress(contextDescriptorFieldAddress),
sizeof(uint32_t));
OpaqueByteReader(contextDescriptorFieldAddress, sizeof(uint32_t));
if (!contextDescriptorOffsetBytes.get()) {
Error =
"Failed to read type descriptor field in conformance descriptor.";
@@ -2257,14 +2259,14 @@ private:
(const int32_t *)contextDescriptorOffsetBytes.get();
// Read the type descriptor itself using the address computed above
auto contextTypeDescriptorAddress = detail::applyRelativeOffset(
(const char *)contextDescriptorFieldAddress,
*contextDescriptorOffset);
auto contextTypeDescriptorAddress =
contextDescriptorFieldAddress.applyRelativeOffset(
*contextDescriptorOffset);
// Instead of a type descriptor this may just be a reference to an
// external, check that first
if (auto symbol = OpaqueDynamicSymbolResolver(
remote::RemoteAddress(contextTypeDescriptorAddress))) {
if (auto symbol =
OpaqueDynamicSymbolResolver(contextTypeDescriptorAddress)) {
if (!symbol->getSymbol().empty() && symbol->getOffset() == 0) {
Demangle::Context Ctx;
auto demangledRoot =
@@ -2287,8 +2289,7 @@ private:
} else if (symbol->getResolvedAddress()) {
// If symbol is empty and has an offset, this is the resolved remote
// address
contextTypeDescriptorAddress =
symbol->getResolvedAddress().getAddressData();
contextTypeDescriptorAddress = symbol->getResolvedAddress();
}
}
@@ -2302,17 +2303,17 @@ private:
/// Extract protocol name from a Conformance Descriptor
std::optional<std::string> getConformanceProtocolName(
const uintptr_t conformanceDescriptorAddress,
const remote::RemoteAddress conformanceDescriptorAddress,
const ExternalProtocolConformanceDescriptor<
ObjCInteropKind, PointerSize> &conformanceDescriptor) {
std::optional<std::string> protocolName;
auto protocolDescriptorFieldAddress = detail::applyRelativeOffset(
(const char *)conformanceDescriptorAddress,
(int32_t)conformanceDescriptor.getProtocolDescriptorOffset());
auto protocolDescriptorFieldAddress =
conformanceDescriptorAddress.applyRelativeOffset(
auto protocolDescriptorOffsetBytes = OpaqueByteReader(
remote::RemoteAddress(protocolDescriptorFieldAddress),
sizeof(uint32_t));
(int32_t)conformanceDescriptor.getProtocolDescriptorOffset());
auto protocolDescriptorOffsetBytes =
OpaqueByteReader(protocolDescriptorFieldAddress, sizeof(uint32_t));
if (!protocolDescriptorOffsetBytes.get()) {
Error = "Error reading protocol descriptor field in conformance "
"descriptor.";
@@ -2321,9 +2322,9 @@ private:
auto protocolDescriptorOffset =
(const uint32_t *)protocolDescriptorOffsetBytes.get();
auto protocolDescriptorTarget = detail::applyRelativeOffset(
(const char *)protocolDescriptorFieldAddress,
(int32_t)*protocolDescriptorOffset);
auto protocolDescriptorTarget =
protocolDescriptorFieldAddress.applyRelativeOffset(
(int32_t)*protocolDescriptorOffset);
return NameReader.readFullyQualifiedProtocolName(
protocolDescriptorTarget);
@@ -2340,11 +2341,11 @@ private:
*)conformanceRecordRef.getLocalBuffer();
// Read the Protocol Conformance Descriptor by getting its address from
// the conformance record.
auto conformanceDescriptorAddress = (uintptr_t)CD->getRelative(
(void *)conformanceRecordRef.getAddressData());
auto conformanceDescriptorAddress =
conformanceRecordRef.getRemoteAddress().getRelative(CD);
auto descriptorBytes = OpaqueByteReader(
remote::RemoteAddress(conformanceDescriptorAddress),
conformanceDescriptorAddress,
sizeof(ExternalProtocolConformanceDescriptor<ObjCInteropKind,
PointerSize>));
if (!descriptorBytes.get()) {

View File

@@ -88,14 +88,19 @@ class ObjectMemoryReader : public reflection::MemoryReader {
};
std::vector<ImageEntry> Images;
uint64_t PtrauthMask = 0;
std::pair<const Image *, uint64_t>
decodeImageIndexAndAddress(uint64_t Addr) const;
uint64_t encodeImageIndexAndAddress(const Image *image,
uint64_t imageAddr) const;
remote::RemoteAddress
encodeImageIndexAndAddress(const Image *image,
remote::RemoteAddress imageAddr) const;
StringRef getContentsAtAddress(uint64_t Addr, uint64_t Size);
uint64_t getPtrauthMask();
public:
explicit ObjectMemoryReader(
const std::vector<const llvm::object::ObjectFile *> &ObjectFiles);
@@ -110,7 +115,7 @@ public:
// TODO: We could consult the dynamic symbol tables of the images to
// implement this.
reflection::RemoteAddress getSymbolAddress(const std::string &name) override {
return reflection::RemoteAddress(nullptr);
return reflection::RemoteAddress();
}
ReadBytesResult readBytes(reflection::RemoteAddress Addr,

View File

@@ -35,5 +35,5 @@ RemoteAddress InProcessMemoryReader::getSymbolAddress(const std::string &name) {
#else
auto pointer = dlsym(RTLD_DEFAULT, name.c_str());
#endif
return RemoteAddress(pointer);
return RemoteAddress((uint64_t)pointer, RemoteAddress::DefaultAddressSpace);
}

View File

@@ -53,7 +53,7 @@ using irgen::Alignment;
using irgen::Size;
static inline RemoteAddress operator+(RemoteAddress address, Size offset) {
return RemoteAddress(address.getAddressData() + offset.getValue());
return address + offset.getValue();
}
namespace {
@@ -437,15 +437,14 @@ public:
Result<Type> getTypeForRemoteTypeMetadata(RemoteAddress metadata,
bool skipArtificial) override {
if (auto result = Reader.readTypeFromMetadata(metadata.getAddressData(),
skipArtificial))
if (auto result = Reader.readTypeFromMetadata(metadata, skipArtificial))
return result;
return getFailure<Type>();
}
Result<MetadataKind>
getKindForRemoteTypeMetadata(RemoteAddress metadata) override {
auto result = Reader.readKindFromMetadata(metadata.getAddressData());
auto result = Reader.readKindFromMetadata(metadata);
if (result)
return *result;
return getFailure<MetadataKind>();
@@ -453,8 +452,7 @@ public:
Result<NominalTypeDecl*>
getDeclForRemoteNominalTypeDescriptor(RemoteAddress descriptor) override {
if (auto result =
Reader.readNominalTypeFromDescriptor(descriptor.getAddressData()))
if (auto result = Reader.readNominalTypeFromDescriptor(descriptor))
return dyn_cast<NominalTypeDecl>((GenericTypeDecl *) result);
return getFailure<NominalTypeDecl*>();
}
@@ -468,8 +466,7 @@ public:
getOffsetOfTupleElementFromMetadata(RemoteAddress metadata,
unsigned index) override {
typename Runtime::StoredSize offset;
if (Reader.readTupleElementOffset(metadata.getAddressData(),
index, &offset))
if (Reader.readTupleElementOffset(metadata, index, &offset))
return uint64_t(offset);
return getFailure<uint64_t>();
}
@@ -484,17 +481,18 @@ public:
Result<RemoteAddress>
getHeapMetadataForObject(RemoteAddress object) override {
auto result = Reader.readMetadataFromInstance(object.getAddressData());
auto result = Reader.readMetadataFromInstance(object);
if (result) return RemoteAddress(*result);
return getFailure<RemoteAddress>();
}
Result<OpenedExistential>
getDynamicTypeAndAddressClassExistential(RemoteAddress object) {
auto pointerval = Reader.readResolvedPointerValue(object.getAddressData());
auto pointerval = Reader.readResolvedPointerValue(object);
if (!pointerval)
return getFailure<OpenedExistential>();
auto result = Reader.readMetadataFromInstance(*pointerval);
;
if (!result)
return getFailure<OpenedExistential>();
auto typeResult = Reader.readTypeFromMetadata(result.value());
@@ -508,7 +506,7 @@ public:
getDynamicTypeAndAddressErrorExistential(RemoteAddress object,
bool dereference=true) {
if (dereference) {
auto pointerval = Reader.readResolvedPointerValue(object.getAddressData());
auto pointerval = Reader.readResolvedPointerValue(object);
if (!pointerval)
return getFailure<OpenedExistential>();
object = RemoteAddress(*pointerval);
@@ -519,8 +517,7 @@ public:
if (!result)
return getFailure<OpenedExistential>();
auto typeResult =
Reader.readTypeFromMetadata(result->MetadataAddress.getAddressData());
auto typeResult = Reader.readTypeFromMetadata(result->MetadataAddress);
if (!typeResult)
return getFailure<OpenedExistential>();
@@ -531,8 +528,7 @@ public:
auto payloadAddress = result->PayloadAddress;
if (!result->IsBridgedError &&
typeResult->getClassOrBoundGenericClass()) {
auto pointerval = Reader.readResolvedPointerValue(
payloadAddress.getAddressData());
auto pointerval = Reader.readResolvedPointerValue(payloadAddress);
if (!pointerval)
return getFailure<OpenedExistential>();
@@ -549,8 +545,7 @@ public:
if (!result)
return getFailure<OpenedExistential>();
auto typeResult =
Reader.readTypeFromMetadata(result->MetadataAddress.getAddressData());
auto typeResult = Reader.readTypeFromMetadata(result->MetadataAddress);
if (!typeResult)
return getFailure<OpenedExistential>();
@@ -559,8 +554,7 @@ public:
// of the reference.
auto payloadAddress = result->PayloadAddress;
if (typeResult->getClassOrBoundGenericClass()) {
auto pointerval = Reader.readResolvedPointerValue(
payloadAddress.getAddressData());
auto pointerval = Reader.readResolvedPointerValue(payloadAddress);
if (!pointerval)
return getFailure<OpenedExistential>();
@@ -578,7 +572,7 @@ public:
// 1) Loading a pointer from the input address
// 2) Reading it as metadata and resolving the type
// 3) Wrapping the resolved type in an existential metatype.
auto pointerval = Reader.readResolvedPointerValue(object.getAddressData());
auto pointerval = Reader.readResolvedPointerValue(object);
if (!pointerval)
return getFailure<OpenedExistential>();
auto typeResult = Reader.readTypeFromMetadata(*pointerval);
@@ -634,7 +628,7 @@ public:
unsigned ordinal) override {
auto underlyingType = Reader
.readUnderlyingTypeForOpaqueTypeDescriptor(
opaqueDescriptor.getAddressData(), ordinal)
opaqueDescriptor, ordinal)
.getType();
if (!underlyingType)

View File

@@ -321,10 +321,11 @@ Image::resolvePointer(uint64_t Addr, uint64_t pointerValue) const {
// base address in the low 32 bits, and ptrauth discriminator info in the top
// 32 bits.
if (isMachOWithPtrAuth()) {
return remote::RemoteAbsolutePointer(
remote::RemoteAddress(HeaderAddress + (pointerValue & 0xffffffffull)));
return remote::RemoteAbsolutePointer(remote::RemoteAddress(
HeaderAddress + (pointerValue & 0xffffffffull), 0));
} else {
return remote::RemoteAbsolutePointer(remote::RemoteAddress(pointerValue));
return remote::RemoteAbsolutePointer(remote::RemoteAddress(
pointerValue, reflection::RemoteAddress::DefaultAddressSpace));
}
}
@@ -332,9 +333,8 @@ remote::RemoteAbsolutePointer Image::getDynamicSymbol(uint64_t Addr) const {
auto found = DynamicRelocations.find(Addr);
if (found == DynamicRelocations.end())
return nullptr;
return remote::RemoteAbsolutePointer(found->second.Symbol,
found->second.Offset,
remote::RemoteAddress((uint64_t)0));
return remote::RemoteAbsolutePointer(
found->second.Symbol, found->second.Offset, remote::RemoteAddress());
}
std::pair<const Image *, uint64_t>
@@ -348,9 +348,8 @@ ObjectMemoryReader::decodeImageIndexAndAddress(uint64_t Addr) const {
return {nullptr, 0};
}
uint64_t
ObjectMemoryReader::encodeImageIndexAndAddress(const Image *image,
uint64_t imageAddr) const {
remote::RemoteAddress ObjectMemoryReader::encodeImageIndexAndAddress(
const Image *image, remote::RemoteAddress imageAddr) const {
auto entry = (const ImageEntry *)image;
return imageAddr + entry->Slide;
}
@@ -482,19 +481,21 @@ ObjectMemoryReader::getImageStartAddress(unsigned i) const {
assert(i < Images.size());
return reflection::RemoteAddress(encodeImageIndexAndAddress(
&Images[i].TheImage, Images[i].TheImage.getStartAddress()));
&Images[i].TheImage,
remote::RemoteAddress(Images[i].TheImage.getStartAddress(),
reflection::RemoteAddress::DefaultAddressSpace)));
}
ReadBytesResult ObjectMemoryReader::readBytes(reflection::RemoteAddress Addr,
uint64_t Size) {
auto addrValue = Addr.getAddressData();
auto addrValue = Addr.getRawAddress();
auto resultBuffer = getContentsAtAddress(addrValue, Size);
return ReadBytesResult(resultBuffer.data(), no_op_destructor);
}
bool ObjectMemoryReader::readString(reflection::RemoteAddress Addr,
std::string &Dest) {
auto addrValue = Addr.getAddressData();
auto addrValue = Addr.getRawAddress();
auto resultBuffer = getContentsAtAddress(addrValue, 1);
if (resultBuffer.empty())
return false;
@@ -515,7 +516,7 @@ found_terminator:
remote::RemoteAbsolutePointer
ObjectMemoryReader::resolvePointer(reflection::RemoteAddress Addr,
uint64_t pointerValue) {
auto addrValue = Addr.getAddressData();
auto addrValue = Addr.getRawAddress();
const Image *image;
uint64_t imageAddr;
std::tie(image, imageAddr) = decodeImageIndexAndAddress(addrValue);
@@ -526,14 +527,13 @@ ObjectMemoryReader::resolvePointer(reflection::RemoteAddress Addr,
auto resolved = image->resolvePointer(imageAddr, pointerValue);
// Mix in the image index again to produce a remote address pointing into the
// same image.
return remote::RemoteAbsolutePointer(
remote::RemoteAddress(encodeImageIndexAndAddress(
image, resolved.getResolvedAddress().getAddressData())));
return remote::RemoteAbsolutePointer(remote::RemoteAddress(
encodeImageIndexAndAddress(image, resolved.getResolvedAddress())));
}
remote::RemoteAbsolutePointer
ObjectMemoryReader::getDynamicSymbol(reflection::RemoteAddress Addr) {
auto addrValue = Addr.getAddressData();
auto addrValue = Addr.getRawAddress();
const Image *image;
uint64_t imageAddr;
std::tie(image, imageAddr) = decodeImageIndexAndAddress(addrValue);
@@ -544,6 +544,31 @@ ObjectMemoryReader::getDynamicSymbol(reflection::RemoteAddress Addr) {
return image->getDynamicSymbol(imageAddr);
}
uint64_t ObjectMemoryReader::getPtrauthMask() {
auto initializePtrauthMask = [&]() -> uint64_t {
uint8_t pointerSize = 0;
if (!queryDataLayout(DataLayoutQueryType::DLQ_GetPointerSize, nullptr,
&pointerSize))
return ~0ull;
if (pointerSize == 4) {
uint32_t ptrauthMask32 = 0;
if (queryDataLayout(DataLayoutQueryType::DLQ_GetPtrAuthMask, nullptr,
&ptrauthMask32))
return (uint64_t)ptrauthMask32;
} else if (pointerSize == 8) {
uint64_t ptrauthMask64 = 0;
if (queryDataLayout(DataLayoutQueryType::DLQ_GetPtrAuthMask, nullptr,
&ptrauthMask64))
return ptrauthMask64;
}
return ~0ull;
};
if (!PtrauthMask)
PtrauthMask = initializePtrauthMask();
return PtrauthMask;
}
template <typename Runtime>
std::unique_ptr<ReflectionContextHolder> makeReflectionContextForMetadataReader(
std::shared_ptr<ObjectMemoryReader> reader, uint8_t pointerSize) {

View File

@@ -408,8 +408,7 @@ bool RecordTypeInfo::readExtraInhabitantIndex(remote::MemoryReader &reader,
[](const FieldInfo &lhs, const FieldInfo &rhs) {
return lhs.TI.getNumExtraInhabitants() < rhs.TI.getNumExtraInhabitants();
});
auto fieldAddress = remote::RemoteAddress(address.getAddressData()
+ mostCapaciousField->Offset);
auto fieldAddress = address + mostCapaciousField->Offset;
return mostCapaciousField->TI.readExtraInhabitantIndex(
reader, fieldAddress, extraInhabitantIndex);
}

View File

@@ -39,7 +39,8 @@ TypeRefBuilder::decodeMangledType(Node *node, bool forRequirement) {
std::optional<std::reference_wrapper<const ReflectionInfo>>
TypeRefBuilder::ReflectionTypeDescriptorFinder::
findReflectionInfoWithTypeRefContainingAddress(uint64_t remoteAddr) {
findReflectionInfoWithTypeRefContainingAddress(
remote::RemoteAddress remoteAddr) {
// Update ReflectionInfoIndexesSortedByTypeReferenceRange if necessary.
if (ReflectionInfoIndexesSortedByTypeReferenceRange.size() !=
ReflectionInfos.size()) {
@@ -54,12 +55,14 @@ TypeRefBuilder::ReflectionTypeDescriptorFinder::
ReflectionInfoIndexesSortedByTypeReferenceRange.begin(),
ReflectionInfoIndexesSortedByTypeReferenceRange.end(),
[&](uint32_t ReflectionInfoIndexA, uint32_t ReflectionInfoIndexB) {
uint64_t typeReferenceAStart = ReflectionInfos[ReflectionInfoIndexA]
.TypeReference.startAddress()
.getAddressData();
uint64_t typeReferenceBStart = ReflectionInfos[ReflectionInfoIndexB]
.TypeReference.startAddress()
.getAddressData();
remote::RemoteAddress typeReferenceAStart =
ReflectionInfos[ReflectionInfoIndexA]
.TypeReference.startAddress()
.getRemoteAddress();
remote::RemoteAddress typeReferenceBStart =
ReflectionInfos[ReflectionInfoIndexB]
.TypeReference.startAddress()
.getRemoteAddress();
return typeReferenceAStart < typeReferenceBStart;
});
@@ -71,10 +74,10 @@ TypeRefBuilder::ReflectionTypeDescriptorFinder::
const auto possiblyMatchingReflectionInfoIndex = std::lower_bound(
ReflectionInfoIndexesSortedByTypeReferenceRange.begin(),
ReflectionInfoIndexesSortedByTypeReferenceRange.end(), remoteAddr,
[&](uint32_t ReflectionInfoIndex, uint64_t remoteAddr) {
[&](uint32_t ReflectionInfoIndex, remote::RemoteAddress remoteAddr) {
return ReflectionInfos[ReflectionInfoIndex]
.TypeReference.endAddress()
.getAddressData() <= remoteAddr;
.getRemoteAddress() <= remoteAddr;
});
if (possiblyMatchingReflectionInfoIndex ==
@@ -97,7 +100,7 @@ TypeRefBuilder::ReflectionTypeDescriptorFinder::
}
RemoteRef<char> TypeRefBuilder::ReflectionTypeDescriptorFinder::readTypeRef(
uint64_t remoteAddr) {
remote::RemoteAddress remoteAddr) {
// The remote address should point into one of the TypeRef or
// ReflectionString references we already read out of the images.
RemoteRef<char> foundTypeRef;
@@ -129,7 +132,7 @@ found_type_ref:
// Make sure there's a valid mangled string within the bounds of the
// section.
for (auto i = foundTypeRef;
i.getAddressData() < limitAddress.getAddressData();) {
i.getRemoteAddress() < limitAddress.getRemoteAddress();) {
auto c = *i.getLocalBuffer();
if (c == '\0')
goto valid_type_ref;
@@ -160,7 +163,7 @@ valid_type_ref:
std::optional<std::string>
TypeRefBuilder::ReflectionTypeDescriptorFinder::normalizeReflectionName(
RemoteRef<char> reflectionName) {
const auto reflectionNameRemoteAddress = reflectionName.getAddressData();
const auto reflectionNameRemoteAddress = reflectionName.getRemoteAddress();
if (const auto found =
NormalizedReflectionNameCache.find(reflectionNameRemoteAddress);
@@ -353,13 +356,13 @@ TypeRefBuilder::ReflectionTypeDescriptorFinder::
return std::nullopt;
auto &Field = ReflectionInfos[Locator->InfoID].Field;
auto Addr = Field.startAddress().getAddressData() + Locator->Offset;
auto Addr = Field.startAddress().getRemoteAddress() + Locator->Offset;
// Validate that we've got the correct field descriptor offset by parsing
// the mangled name for that specific offset and making sure it's the one
// we're looking for.
for (auto FD : Field) {
if (FD.getAddressData() == Addr) {
if (FD.getRemoteAddress() == Addr) {
if (!FD->hasMangledTypeName())
break;
auto CandidateMangledName = readTypeRef(FD, FD->MangledTypeName);
@@ -749,7 +752,7 @@ TypeRefBuilder::getMultiPayloadEnumDescriptor(const TypeRef *TR) {
RemoteRef<CaptureDescriptor>
TypeRefBuilder::ReflectionTypeDescriptorFinder::getCaptureDescriptor(
uint64_t RemoteAddress) {
remote::RemoteAddress RemoteAddress) {
for (; CaptureDescriptorsByAddressLastReflectionInfoCache <
ReflectionInfos.size();
@@ -758,7 +761,7 @@ TypeRefBuilder::ReflectionTypeDescriptorFinder::getCaptureDescriptor(
ReflectionInfos[CaptureDescriptorsByAddressLastReflectionInfoCache]
.Capture) {
CaptureDescriptorsByAddress.emplace(
std::make_pair(CD.getAddressData(), CD));
std::make_pair(CD.getRemoteAddress(), CD));
}
}

View File

@@ -233,7 +233,9 @@ ReflectionSection<Iterator> sectionFromInfo(const swift_reflection_info_t &Info,
- Info.LocalStartAddress
+ Info.RemoteStartAddress;
auto Start = RemoteRef<void>(RemoteSectionStart, Section.section.Begin);
auto Start = RemoteRef<void>(
RemoteAddress(RemoteSectionStart, RemoteAddress::DefaultAddressSpace),
Section.section.Begin);
return ReflectionSection<Iterator>(Start,
(uintptr_t)Section.section.End - (uintptr_t)Section.section.Begin);
@@ -244,7 +246,9 @@ ReflectionSection<Iterator> reflectionSectionFromLocalAndRemote(
const swift_reflection_section_mapping_t &Section) {
auto RemoteSectionStart = (uint64_t)Section.remote_section.StartAddress;
auto Start = RemoteRef<void>(RemoteSectionStart, Section.local_section.Begin);
auto Start = RemoteRef<void>(
RemoteAddress(RemoteSectionStart, RemoteAddress::DefaultAddressSpace),
Section.local_section.Begin);
return ReflectionSection<Iterator>(Start,
(uintptr_t)Section.remote_section.Size);
@@ -309,7 +313,10 @@ int
swift_reflection_addImage(SwiftReflectionContextRef ContextRef,
swift_addr_t imageStart) {
return ContextRef->withContext<int>([&](auto *Context) {
return Context->addImage(RemoteAddress(imageStart)).has_value();
return Context
->addImage(
RemoteAddress(imageStart, RemoteAddress::DefaultAddressSpace))
.has_value();
});
}
@@ -331,7 +338,8 @@ swift_typeref_t
swift_reflection_typeRefForMetadata(SwiftReflectionContextRef ContextRef,
uintptr_t Metadata) {
return ContextRef->withContext<swift_typeref_t>([&](auto *Context) {
auto TR = Context->readTypeFromMetadata(Metadata);
auto TR = Context->readTypeFromMetadata(RemoteAddress(Metadata,
RemoteAddress::DefaultAddressSpace));
return reinterpret_cast<swift_typeref_t>(TR);
});
}
@@ -339,21 +347,24 @@ swift_reflection_typeRefForMetadata(SwiftReflectionContextRef ContextRef,
int
swift_reflection_ownsObject(SwiftReflectionContextRef ContextRef, uintptr_t Object) {
return ContextRef->withContext<int>([&](auto *Context) {
return Context->ownsObject(RemoteAddress(Object));
return Context->ownsObject(
RemoteAddress(Object, RemoteAddress::DefaultAddressSpace));
});
}
int
swift_reflection_ownsAddress(SwiftReflectionContextRef ContextRef, uintptr_t Address) {
return ContextRef->withContext<int>([&](auto *Context) {
return Context->ownsAddress(RemoteAddress(Address));
return Context->ownsAddress(
RemoteAddress(Address, RemoteAddress::DefaultAddressSpace));
});
}
int
swift_reflection_ownsAddressStrict(SwiftReflectionContextRef ContextRef, uintptr_t Address) {
return ContextRef->withContext<int>([&](auto *Context) {
return Context->ownsAddress(RemoteAddress(Address), false);
return Context->ownsAddress(
RemoteAddress(Address, RemoteAddress::DefaultAddressSpace), false);
});
}
@@ -361,10 +372,11 @@ uintptr_t
swift_reflection_metadataForObject(SwiftReflectionContextRef ContextRef,
uintptr_t Object) {
return ContextRef->withContext<uintptr_t>([&](auto *Context) -> uintptr_t {
auto MetadataAddress = Context->readMetadataFromInstance(Object);
auto MetadataAddress = Context->readMetadataFromInstance(
RemoteAddress(Object, RemoteAddress::DefaultAddressSpace));
if (!MetadataAddress)
return 0;
return *MetadataAddress;
return MetadataAddress->getRawAddress();
});
}
@@ -372,14 +384,19 @@ swift_reflection_ptr_t
swift_reflection_metadataNominalTypeDescriptor(SwiftReflectionContextRef ContextRef,
swift_reflection_ptr_t MetadataAddress) {
return ContextRef->withContext<swift_reflection_ptr_t>([&](auto *Context) {
return Context->nominalTypeDescriptorFromMetadata(MetadataAddress);
return Context
->nominalTypeDescriptorFromMetadata(
RemoteAddress(MetadataAddress, RemoteAddress::DefaultAddressSpace))
.getRawAddress();
});
}
int swift_reflection_metadataIsActor(SwiftReflectionContextRef ContextRef,
swift_reflection_ptr_t Metadata) {
return ContextRef->withContext<int>(
[&](auto *Context) { return Context->metadataIsActor(Metadata); });
return ContextRef->withContext<int>([&](auto *Context) {
return Context->metadataIsActor(
RemoteAddress(Metadata, RemoteAddress::DefaultAddressSpace));
});
}
swift_typeref_t
@@ -387,7 +404,8 @@ swift_reflection_typeRefForInstance(SwiftReflectionContextRef ContextRef,
uintptr_t Object) {
return ContextRef->withContext<swift_typeref_t>(
[&](auto *Context) -> swift_typeref_t {
auto MetadataAddress = Context->readMetadataFromInstance(Object);
auto MetadataAddress = Context->readMetadataFromInstance(
RemoteAddress(Object, RemoteAddress::DefaultAddressSpace));
if (!MetadataAddress)
return 0;
auto TR = Context->readTypeFromMetadata(*MetadataAddress);
@@ -443,7 +461,8 @@ swift_reflection_copyDemangledNameForProtocolDescriptor(
return ContextRef->withContext<char *>([&](auto *Context) {
Demangle::Demangler Dem;
auto Demangling = Context->readDemanglingForContextDescriptor(Proto, Dem);
auto Demangling = Context->readDemanglingForContextDescriptor(
RemoteAddress(Proto, RemoteAddress::DefaultAddressSpace), Dem);
auto Name = nodeToString(Demangling);
return strdup(Name.c_str());
});
@@ -649,7 +668,8 @@ swift_typeinfo_t
swift_reflection_infoForMetadata(SwiftReflectionContextRef ContextRef,
uintptr_t Metadata) {
return ContextRef->withContext<swift_typeinfo_t>([&](auto *Context) {
auto *TI = Context->getMetadataTypeInfo(Metadata, nullptr);
auto *TI = Context->getMetadataTypeInfo(
RemoteAddress(Metadata, RemoteAddress::DefaultAddressSpace), nullptr);
return convertTypeInfo(TI);
});
}
@@ -659,7 +679,8 @@ swift_reflection_childOfMetadata(SwiftReflectionContextRef ContextRef,
uintptr_t Metadata,
unsigned Index) {
return ContextRef->withContext<swift_childinfo_t>([&](auto *Context) {
auto *TI = Context->getMetadataTypeInfo(Metadata, nullptr);
auto *TI = Context->getMetadataTypeInfo(
RemoteAddress(Metadata, RemoteAddress::DefaultAddressSpace), nullptr);
return convertChild(TI, Index);
});
}
@@ -668,7 +689,8 @@ swift_typeinfo_t
swift_reflection_infoForInstance(SwiftReflectionContextRef ContextRef,
uintptr_t Object) {
return ContextRef->withContext<swift_typeinfo_t>([&](auto *Context) {
auto *TI = Context->getInstanceTypeInfo(Object, nullptr);
auto *TI = Context->getInstanceTypeInfo(
RemoteAddress(Object, RemoteAddress::DefaultAddressSpace), nullptr);
return convertTypeInfo(TI);
});
}
@@ -678,7 +700,8 @@ swift_reflection_childOfInstance(SwiftReflectionContextRef ContextRef,
uintptr_t Object,
unsigned Index) {
return ContextRef->withContext<swift_childinfo_t>([&](auto *Context) {
auto *TI = Context->getInstanceTypeInfo(Object, nullptr);
auto *TI = Context->getInstanceTypeInfo(
RemoteAddress(Object, RemoteAddress::DefaultAddressSpace), nullptr);
return convertChild(TI, Index);
});
}
@@ -690,16 +713,17 @@ int swift_reflection_projectExistential(SwiftReflectionContextRef ContextRef,
swift_addr_t *StartOfInstanceData) {
return ContextRef->withContext<int>([&](auto *Context) {
auto ExistentialTR = reinterpret_cast<const TypeRef *>(ExistentialTypeRef);
auto RemoteExistentialAddress = RemoteAddress(ExistentialAddress);
auto RemoteExistentialAddress =
RemoteAddress(ExistentialAddress, RemoteAddress::DefaultAddressSpace);
const TypeRef *InstanceTR = nullptr;
RemoteAddress RemoteStartOfInstanceData(nullptr);
RemoteAddress RemoteStartOfInstanceData;
auto Success = Context->projectExistential(
RemoteExistentialAddress, ExistentialTR, &InstanceTR,
&RemoteStartOfInstanceData, nullptr);
if (Success) {
*InstanceTypeRef = reinterpret_cast<swift_typeref_t>(InstanceTR);
*StartOfInstanceData = RemoteStartOfInstanceData.getAddressData();
*StartOfInstanceData = RemoteStartOfInstanceData.getRawAddress();
}
return Success;
@@ -713,14 +737,15 @@ int swift_reflection_projectExistentialAndUnwrapClass(SwiftReflectionContextRef
swift_addr_t *StartOfInstanceData) {
return ContextRef->withContext<int>([&](auto *Context) {
auto ExistentialTR = reinterpret_cast<const TypeRef *>(ExistentialTypeRef);
auto RemoteExistentialAddress = RemoteAddress(ExistentialAddress);
auto RemoteExistentialAddress =
RemoteAddress(ExistentialAddress, RemoteAddress::DefaultAddressSpace);
auto Pair = Context->projectExistentialAndUnwrapClass(
RemoteExistentialAddress, *ExistentialTR);
if (!Pair.has_value())
return false;
*InstanceTypeRef =
reinterpret_cast<swift_typeref_t>(std::get<const TypeRef *>(*Pair));
*StartOfInstanceData = std::get<RemoteAddress>(*Pair).getAddressData();
*StartOfInstanceData = std::get<RemoteAddress>(*Pair).getRawAddress();
return true;
});
@@ -732,7 +757,8 @@ int swift_reflection_projectEnumValue(SwiftReflectionContextRef ContextRef,
int *CaseIndex) {
return ContextRef->withContext<int>([&](auto *Context) {
auto EnumTR = reinterpret_cast<const TypeRef *>(EnumTypeRef);
auto RemoteEnumAddress = RemoteAddress(EnumAddress);
auto RemoteEnumAddress =
RemoteAddress(EnumAddress, RemoteAddress::DefaultAddressSpace);
if (!Context->projectEnumValue(RemoteEnumAddress, EnumTR, CaseIndex,
nullptr)) {
return false;
@@ -791,7 +817,8 @@ void swift_reflection_dumpInfoForTypeRef(SwiftReflectionContextRef ContextRef,
void swift_reflection_dumpInfoForMetadata(SwiftReflectionContextRef ContextRef,
uintptr_t Metadata) {
ContextRef->withContext<void>([&](auto *Context) {
auto TI = Context->getMetadataTypeInfo(Metadata, nullptr);
auto TI = Context->getMetadataTypeInfo(
RemoteAddress(Metadata, RemoteAddress::DefaultAddressSpace), nullptr);
if (TI == nullptr) {
std::cout << "<null type info>\n";
} else {
@@ -803,7 +830,8 @@ void swift_reflection_dumpInfoForMetadata(SwiftReflectionContextRef ContextRef,
void swift_reflection_dumpInfoForInstance(SwiftReflectionContextRef ContextRef,
uintptr_t Object) {
ContextRef->withContext<void>([&](auto *Context) {
auto TI = Context->getInstanceTypeInfo(Object, nullptr);
auto TI = Context->getInstanceTypeInfo(
RemoteAddress(Object, RemoteAddress::DefaultAddressSpace), nullptr);
if (TI == nullptr) {
std::cout << "<null type info>\n";
} else {
@@ -831,7 +859,7 @@ const char *swift_reflection_iterateConformanceCache(
void *ContextPtr) {
return ContextRef->withContext<const char *>([&](auto *Context) {
auto Error = Context->iterateConformances([&](auto Type, auto Proto) {
Call(Type, Proto, ContextPtr);
Call(Type.getRawAddress(), Proto.getRawAddress(), ContextPtr);
});
return returnableCString(ContextRef, Error);
});
@@ -939,7 +967,8 @@ swift_reflection_asyncTaskSlabPointer(SwiftReflectionContextRef ContextRef,
unsigned AsyncBacktraceLimit = 0;
auto [Error, TaskInfo] = Context->asyncTaskInfo(
AsyncTaskPtr, ChildTaskLimit, AsyncBacktraceLimit);
RemoteAddress(AsyncTaskPtr, RemoteAddress::DefaultAddressSpace),
ChildTaskLimit, AsyncBacktraceLimit);
swift_async_task_slab_return_t Result = {};
if (Error) {
@@ -999,7 +1028,8 @@ swift_reflection_asyncTaskInfo(SwiftReflectionContextRef ContextRef,
unsigned AsyncBacktraceLimit = 1000;
auto [Error, TaskInfo] = Context->asyncTaskInfo(
AsyncTaskPtr, ChildTaskLimit, AsyncBacktraceLimit);
RemoteAddress(AsyncTaskPtr, RemoteAddress::DefaultAddressSpace),
ChildTaskLimit, AsyncBacktraceLimit);
swift_async_task_info_t Result = {};
if (Error) {
@@ -1054,7 +1084,8 @@ swift_actor_info_t
swift_reflection_actorInfo(SwiftReflectionContextRef ContextRef,
swift_reflection_ptr_t ActorPtr) {
return ContextRef->withContext<swift_actor_info_t>([&](auto *Context) {
auto [Error, ActorInfo] = Context->actorInfo(ActorPtr);
auto [Error, ActorInfo] = Context->actorInfo(
RemoteAddress(ActorPtr, RemoteAddress::DefaultAddressSpace));
swift_actor_info_t Result = {};
Result.Error = returnableCString(ContextRef, Error);
@@ -1075,6 +1106,7 @@ swift_reflection_ptr_t
swift_reflection_nextJob(SwiftReflectionContextRef ContextRef,
swift_reflection_ptr_t JobPtr) {
return ContextRef->withContext<swift_reflection_ptr_t>([&](auto *Context) {
return Context->nextJob(JobPtr);
return Context->nextJob(
RemoteAddress(JobPtr, RemoteAddress::DefaultAddressSpace));
});
}

View File

@@ -120,20 +120,20 @@ public:
}
RemoteAddress getSymbolAddress(const std::string &name) override {
return RemoteAddress(nullptr);
return RemoteAddress();
}
bool isAddressValid(RemoteAddress addr, uint64_t size) const { return true; }
ReadBytesResult readBytes(RemoteAddress address, uint64_t size) override {
return ReadBytesResult((const void *)address.getAddressData(),
return ReadBytesResult((const void *)address.getRawAddress(),
[](const void *) {});
}
bool readString(RemoteAddress address, std::string &dest) override {
if (!isAddressValid(address, 1))
return false;
auto cString = StringRef((const char *)address.getAddressData());
auto cString = StringRef((const char *)address.getRawAddress());
dest.append(cString.begin(), cString.end());
return true;
}
@@ -142,7 +142,8 @@ public:
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
auto reader = std::make_shared<ObjectMemoryReader>();
NativeReflectionContext context(std::move(reader));
context.addImage(RemoteAddress(Data));
context.addImage(
RemoteAddress((uint64_t)Data, RemoteAddress::DefaultAddressSpace));
context.getBuilder().dumpAllSections<WithObjCInterop, sizeof(uintptr_t)>(std::cout);
return 0; // Non-zero return values are reserved for future use.
}

View File

@@ -77,8 +77,8 @@ printMetadataType(const Metadata *typeMetadata) {
auto &remoteAST = getRemoteASTContext();
auto &out = llvm::outs();
auto result =
remoteAST.getTypeForRemoteTypeMetadata(RemoteAddress(typeMetadata));
auto result = remoteAST.getTypeForRemoteTypeMetadata(RemoteAddress(
(uint64_t)typeMetadata, RemoteAddress::DefaultAddressSpace));
if (result) {
out << "found type: ";
result.getValue().print(out);
@@ -95,8 +95,8 @@ printHeapMetadataType(void *object) {
auto &remoteAST = getRemoteASTContext();
auto &out = llvm::outs();
auto metadataResult =
remoteAST.getHeapMetadataForObject(RemoteAddress(object));
auto metadataResult = remoteAST.getHeapMetadataForObject(
RemoteAddress((uint64_t)object, RemoteAddress::DefaultAddressSpace));
if (!metadataResult) {
out << metadataResult.getFailure().render() << '\n';
return;
@@ -120,8 +120,8 @@ static void printMemberOffset(const Metadata *typeMetadata,
auto &out = llvm::outs();
// The first thing we have to do is get the type.
auto typeResult =
remoteAST.getTypeForRemoteTypeMetadata(RemoteAddress(typeMetadata));
auto typeResult = remoteAST.getTypeForRemoteTypeMetadata(RemoteAddress(
(uint64_t)typeMetadata, RemoteAddress::DefaultAddressSpace));
if (!typeResult) {
out << "failed to find type: " << typeResult.getFailure().render() << '\n';
return;
@@ -130,7 +130,9 @@ static void printMemberOffset(const Metadata *typeMetadata,
Type type = typeResult.getValue();
RemoteAddress address =
(passMetadata ? RemoteAddress(typeMetadata) : RemoteAddress(nullptr));
(passMetadata ? RemoteAddress((uint64_t)typeMetadata,
RemoteAddress::DefaultAddressSpace)
: RemoteAddress());
auto offsetResult =
remoteAST.getOffsetOfMember(type, address, memberName);
@@ -170,8 +172,8 @@ printDynamicTypeAndAddressForExistential(void *object,
// First, retrieve the static type of the existential, so we can understand
// which kind of existential this is.
auto staticTypeResult =
remoteAST.getTypeForRemoteTypeMetadata(RemoteAddress(typeMetadata));
auto staticTypeResult = remoteAST.getTypeForRemoteTypeMetadata(RemoteAddress(
(uint64_t)typeMetadata, RemoteAddress::DefaultAddressSpace));
if (!staticTypeResult) {
out << "failed to resolve static type: "
<< staticTypeResult.getFailure().render() << '\n';
@@ -180,7 +182,8 @@ printDynamicTypeAndAddressForExistential(void *object,
// OK, we can reconstruct the dynamic type and the address now.
auto result = remoteAST.getDynamicTypeAndAddressForExistential(
RemoteAddress(object), staticTypeResult.getValue());
RemoteAddress((uint64_t)object, RemoteAddress::DefaultAddressSpace),
staticTypeResult.getValue());
if (result) {
out << "found type: ";
result.getValue().InstanceType.print(out);