[RemoteInspection] Make MemoryReader::readRemoteAddress virtual

Allow subclasses to override the behavior of readRemoteAddress. LLDB in
particular needs this to correctly set the address space of the result
remote address.

rdar://148361743
This commit is contained in:
Augusto Noronha
2025-07-16 21:22:32 -07:00
parent 8dfff8c799
commit 45d6d45623
2 changed files with 39 additions and 7 deletions

View File

@@ -135,12 +135,10 @@ public:
/// Returns false if the operator failed. /// Returns false if the operator failed.
template <typename IntegerType> template <typename IntegerType>
bool readRemoteAddress(RemoteAddress address, RemoteAddress &out) { bool readRemoteAddress(RemoteAddress address, RemoteAddress &out) {
IntegerType buf; constexpr std::size_t integerSize = sizeof(IntegerType);
if (!readInteger(address, &buf)) static_assert((integerSize == 4 || integerSize == 8) &&
return false; "Only 32 or 64 bit architectures are supported!");
return readRemoteAddressImpl(address, out, integerSize);
out = RemoteAddress((uint64_t)buf, address.getAddressSpace());
return true;
} }
/// Attempts to read an integer from the given address in the remote /// Attempts to read an integer from the given address in the remote
@@ -338,6 +336,40 @@ public:
} }
virtual ~MemoryReader() = default; virtual ~MemoryReader() = default;
protected:
/// Implementation detail of remoteRemoteAddress. This exists because
/// templated functions cannot be virtual.
///
/// Attempts to read a remote address of a given size from the given address
/// in the remote process.
///
/// Returns false if the operator failed.
virtual bool readRemoteAddressImpl(RemoteAddress address, RemoteAddress &out,
std::size_t integerSize) {
assert((integerSize == 4 || integerSize == 8) &&
"Only 32 or 64 bit architectures are supported!");
auto Buf = std::malloc(integerSize);
if (!Buf)
return false;
// Free Buf when this function return.
ReadBytesResult Result(
Buf, [](const void *ptr) { free(const_cast<void *>(ptr)); });
if (!readBytes(address, reinterpret_cast<uint8_t *>(Buf), integerSize))
return false;
if (integerSize == 4)
out = RemoteAddress(*reinterpret_cast<uint32_t *>(Buf),
address.getAddressSpace());
else if (integerSize == 8)
out = RemoteAddress(*reinterpret_cast<uint64_t *>(Buf),
address.getAddressSpace());
else
return false;
return true;
}
}; };
} // end namespace remote } // end namespace remote

View File

@@ -56,7 +56,7 @@ public:
} }
bool inRange(const RemoteAddress &begin, const RemoteAddress &end) const { bool inRange(const RemoteAddress &begin, const RemoteAddress &end) const {
assert(begin.AddressSpace != end.AddressSpace && assert(begin.AddressSpace == end.AddressSpace &&
"Unexpected address spaces"); "Unexpected address spaces");
if (AddressSpace != begin.AddressSpace) if (AddressSpace != begin.AddressSpace)
return false; return false;