mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Organize the MemoryReader interface headers to better support
multiple clients.
This commit is contained in:
@@ -1,153 +0,0 @@
|
||||
//===--- Reader.h - Swift Type Reflection Memory Reader ---------*- C++ -*-===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See http://swift.org/LICENSE.txt for license information
|
||||
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Implements reading memory from the current or external process
|
||||
// for reflection.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SWIFT_REFLECTION_READER_H
|
||||
#define SWIFT_REFLECTION_READER_H
|
||||
|
||||
#include "swift/SwiftRemoteMirror/MemoryReaderInterface.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace swift {
|
||||
namespace reflection {
|
||||
|
||||
template <typename Iterator>
|
||||
class ReflectionSection {
|
||||
using const_iterator = Iterator;
|
||||
const void * const Begin;
|
||||
const void * const End;
|
||||
|
||||
public:
|
||||
ReflectionSection(const void * const Begin,
|
||||
const void * const End)
|
||||
: Begin(Begin), End(End) {}
|
||||
|
||||
ReflectionSection(uint64_t Begin, uint64_t End)
|
||||
: Begin(reinterpret_cast<const void * const>(Begin)),
|
||||
End(reinterpret_cast<const void * const>(End)) {}
|
||||
|
||||
void *startAddress() {
|
||||
return const_cast<void *>(Begin);
|
||||
}
|
||||
|
||||
const_iterator begin() const {
|
||||
return const_iterator(Begin, End);
|
||||
}
|
||||
|
||||
const_iterator end() const {
|
||||
return const_iterator(End, End);
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return (char *)End - (char *)Begin;
|
||||
}
|
||||
};
|
||||
|
||||
class MemoryReader {
|
||||
public:
|
||||
virtual uint8_t getPointerSize() = 0;
|
||||
virtual uint8_t getSizeSize() = 0;
|
||||
virtual addr_t getSymbolAddress(const std::string &Name) = 0;
|
||||
virtual std::string readString(addr_t Address) = 0;
|
||||
virtual bool readBytes(addr_t Address, uint8_t *Dest, uint64_t Size) = 0;
|
||||
|
||||
template <typename IntegerType>
|
||||
bool readInteger(addr_t Address, IntegerType *Dest) {
|
||||
return readBytes(Address, (uint8_t*)Dest, sizeof(IntegerType));
|
||||
}
|
||||
|
||||
virtual ~MemoryReader() = default;
|
||||
};
|
||||
|
||||
class InProcessMemoryReader final : public MemoryReader {
|
||||
uint8_t getPointerSize() override {
|
||||
return sizeof(uintptr_t);
|
||||
}
|
||||
|
||||
uint8_t getSizeSize() override {
|
||||
return sizeof(size_t);
|
||||
}
|
||||
|
||||
addr_t getSymbolAddress(const std::string &Name) override {
|
||||
auto Symbol = dlsym(RTLD_DEFAULT, Name.c_str());
|
||||
auto Pointer = reinterpret_cast<uintptr_t>(Symbol);
|
||||
return static_cast<addr_t>(Pointer);
|
||||
}
|
||||
|
||||
std::string readString(addr_t Address) override {
|
||||
return std::string((char *)Address);
|
||||
}
|
||||
|
||||
bool readBytes(addr_t Address, uint8_t *Dest, uint64_t Size) override {
|
||||
return memmove(Dest, reinterpret_cast<const void *>(Address), Size);
|
||||
}
|
||||
};
|
||||
|
||||
class CMemoryReader final : public MemoryReader {
|
||||
MemoryReaderImpl Impl;
|
||||
|
||||
public:
|
||||
CMemoryReader(MemoryReaderImpl Impl)
|
||||
: Impl(Impl) {
|
||||
assert(this->Impl.getPointerSize && "No getPointerSize implementation");
|
||||
assert(this->Impl.getStringLength && "No stringLength implementation");
|
||||
assert(this->Impl.readBytes && "No readBytes implementation");
|
||||
assert(this->Impl.getPointerSize() != 0 && "Invalid target pointer size");
|
||||
}
|
||||
|
||||
uint8_t getPointerSize() override {
|
||||
return Impl.getPointerSize();
|
||||
}
|
||||
|
||||
uint8_t getSizeSize() override {
|
||||
return Impl.getSizeSize();
|
||||
}
|
||||
|
||||
addr_t getSymbolAddress(const std::string &Name) override {
|
||||
auto Address = Impl.getSymbolAddress(Name.c_str(), Name.size());
|
||||
return static_cast<addr_t>(Address);
|
||||
}
|
||||
|
||||
uint64_t getStringLength(addr_t Address) {
|
||||
return Impl.getStringLength(Address);
|
||||
}
|
||||
|
||||
std::string readString(addr_t Address) override {
|
||||
auto NameSize = getStringLength(Address);
|
||||
if (!NameSize)
|
||||
return "";
|
||||
|
||||
auto NameBuffer = std::unique_ptr<uint8_t>(new uint8_t[NameSize + 1]);
|
||||
if (!readBytes(Address, NameBuffer.get(), NameSize + 1))
|
||||
return "";
|
||||
return std::string(reinterpret_cast<const char *>(NameBuffer.get()));
|
||||
}
|
||||
|
||||
bool readBytes(addr_t Address, uint8_t *Dest, uint64_t Size) override {
|
||||
return Impl.readBytes(Address, Dest, Size);
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace reflection
|
||||
} // end namespace swift
|
||||
|
||||
#endif // SWIFT_REFLECTION_READER_H
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#define SWIFT_REFLECTION_REFLECTIONCONTEXT_H
|
||||
|
||||
#include "swift/Runtime/Metadata.h"
|
||||
#include "swift/Reflection/Reader.h"
|
||||
#include "swift/Remote/MemoryReader.h"
|
||||
#include "swift/Reflection/Records.h"
|
||||
#include "swift/Reflection/TypeRef.h"
|
||||
#include "swift/SwiftRemoteMirror/SwiftRemoteMirrorTypes.h"
|
||||
@@ -33,6 +33,41 @@ class NodePointer;
|
||||
namespace swift {
|
||||
namespace reflection {
|
||||
|
||||
using swift::remote::MemoryReader;
|
||||
using swift::remote::RemoteAddress;
|
||||
|
||||
template <typename Iterator>
|
||||
class ReflectionSection {
|
||||
using const_iterator = Iterator;
|
||||
const void * const Begin;
|
||||
const void * const End;
|
||||
|
||||
public:
|
||||
ReflectionSection(const void * const Begin,
|
||||
const void * const End)
|
||||
: Begin(Begin), End(End) {}
|
||||
|
||||
ReflectionSection(uint64_t Begin, uint64_t End)
|
||||
: Begin(reinterpret_cast<const void * const>(Begin)),
|
||||
End(reinterpret_cast<const void * const>(End)) {}
|
||||
|
||||
void *startAddress() {
|
||||
return const_cast<void *>(Begin);
|
||||
}
|
||||
|
||||
const_iterator begin() const {
|
||||
return const_iterator(Begin, End);
|
||||
}
|
||||
|
||||
const_iterator end() const {
|
||||
return const_iterator(End, End);
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return (char *)End - (char *)Begin;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Runtime>
|
||||
using SharedTargetMetadataRef = std::shared_ptr<TargetMetadata<Runtime>>;
|
||||
|
||||
@@ -87,7 +122,7 @@ class ReflectionContext {
|
||||
SharedTargetMetadataRef<Runtime> _readMetadata(StoredPointer Address,
|
||||
size_t Size = sizeof(M)) {
|
||||
uint8_t *Buffer = (uint8_t *)malloc(Size);
|
||||
if (!Reader->readBytes(Address, Buffer, Size)) {
|
||||
if (!Reader->readBytes(RemoteAddress(Address), Buffer, Size)) {
|
||||
free(Buffer);
|
||||
return nullptr;
|
||||
}
|
||||
@@ -202,7 +237,7 @@ public:
|
||||
return Cached->second;
|
||||
|
||||
StoredPointer KindValue = 0;
|
||||
if (!Reader->readInteger(Address, &KindValue))
|
||||
if (!Reader->readInteger(RemoteAddress(Address), &KindValue))
|
||||
return nullptr;
|
||||
|
||||
auto Kind = static_cast<MetadataKind>(KindValue);
|
||||
@@ -219,7 +254,8 @@ public:
|
||||
StoredPointer NumProtocolsAddress = Address +
|
||||
TargetExistentialTypeMetadata<Runtime>::OffsetToNumProtocols;
|
||||
StoredPointer NumProtocols;
|
||||
if (!Reader->readInteger(NumProtocolsAddress, &NumProtocols))
|
||||
if (!Reader->readInteger(RemoteAddress(NumProtocolsAddress),
|
||||
&NumProtocols))
|
||||
return nullptr;
|
||||
|
||||
auto TotalSize = sizeof(TargetExistentialTypeMetadata<Runtime>) +
|
||||
@@ -254,7 +290,8 @@ public:
|
||||
auto NumElementsAddress = Address +
|
||||
TargetTupleTypeMetadata<Runtime>::OffsetToNumElements;
|
||||
StoredSize NumElements;
|
||||
if (!Reader->readInteger(NumElementsAddress, &NumElements))
|
||||
if (!Reader->readInteger(RemoteAddress(NumElementsAddress),
|
||||
&NumElements))
|
||||
return nullptr;
|
||||
auto TotalSize = sizeof(TargetTupleTypeMetadata<Runtime>) +
|
||||
NumElements * sizeof(StoredPointer);
|
||||
@@ -270,7 +307,7 @@ public:
|
||||
template<typename Offset>
|
||||
StoredPointer resolveRelativeOffset(StoredPointer targetAddress) {
|
||||
Offset relative;
|
||||
if (!Reader->readInteger(targetAddress, &relative))
|
||||
if (!Reader->readInteger(RemoteAddress(targetAddress), &relative))
|
||||
return 0;
|
||||
using SignedOffset = typename std::make_signed<Offset>::type;
|
||||
using SignedPointer = typename std::make_signed<StoredPointer>::type;
|
||||
@@ -316,7 +353,7 @@ public:
|
||||
|
||||
auto Size = sizeof(TargetNominalTypeDescriptor<Runtime>);
|
||||
auto Buffer = (uint8_t *)malloc(Size);
|
||||
if (!Reader->readBytes(DescriptorAddress, Buffer, Size)) {
|
||||
if (!Reader->readBytes(RemoteAddress(DescriptorAddress), Buffer, Size)) {
|
||||
free(Buffer);
|
||||
return {nullptr, 0};
|
||||
}
|
||||
@@ -340,7 +377,7 @@ public:
|
||||
readProtocolDescriptor(StoredPointer Address) {
|
||||
auto Size = sizeof(TargetProtocolDescriptor<Runtime>);
|
||||
auto Buffer = (uint8_t *)malloc(Size);
|
||||
if (!Reader->readBytes(Address, Buffer, Size)) {
|
||||
if (!Reader->readBytes(RemoteAddress(Address), Buffer, Size)) {
|
||||
free(Buffer);
|
||||
return nullptr;
|
||||
}
|
||||
@@ -356,7 +393,8 @@ public:
|
||||
auto AddressOfParentAddress
|
||||
= resolveRelativeOffset<StoredPointer>(MetadataAddress +
|
||||
ValueMeta->offsetToParentOffset());
|
||||
if (!Reader->readInteger(AddressOfParentAddress, &ParentAddress))
|
||||
if (!Reader->readInteger(RemoteAddress(AddressOfParentAddress),
|
||||
&ParentAddress))
|
||||
return 0;
|
||||
} else if (auto Class = dyn_cast<TargetClassMetadata<Runtime>>(Meta.get())){
|
||||
StoredPointer DescriptorAddress;
|
||||
@@ -366,7 +404,8 @@ public:
|
||||
TypeRefVector Substitutions;
|
||||
auto OffsetToParent
|
||||
= sizeof(StoredPointer) * (Descriptor->GenericParams.Offset - 1);
|
||||
if (!Reader->readInteger(MetadataAddress + OffsetToParent, &ParentAddress))
|
||||
if (!Reader->readInteger(RemoteAddress(MetadataAddress + OffsetToParent),
|
||||
&ParentAddress))
|
||||
return 0;
|
||||
}
|
||||
return ParentAddress;
|
||||
@@ -393,7 +432,7 @@ public:
|
||||
for (ArgIndex i = 0; i < NumGenericParams; ++i,
|
||||
AddressOfGenericArgAddress += sizeof(StoredPointer)) {
|
||||
StoredPointer GenericArgAddress;
|
||||
if (!Reader->readInteger(AddressOfGenericArgAddress,
|
||||
if (!Reader->readInteger(RemoteAddress(AddressOfGenericArgAddress),
|
||||
&GenericArgAddress))
|
||||
return {};
|
||||
if (auto GenericArg = getTypeRef(GenericArgAddress))
|
||||
@@ -418,8 +457,8 @@ public:
|
||||
auto NameAddress
|
||||
= resolveRelativeOffset<int32_t>(DescriptorAddress +
|
||||
Descriptor->offsetToNameOffset());
|
||||
auto MangledName = Reader->readString(NameAddress);
|
||||
if (MangledName.empty())
|
||||
std::string MangledName;
|
||||
if (!Reader->readString(RemoteAddress(NameAddress), MangledName))
|
||||
return nullptr;
|
||||
|
||||
auto DemangleNode = Demangle::demangleTypeAsNode(MangledName);
|
||||
@@ -471,7 +510,8 @@ public:
|
||||
for (StoredPointer i = 0; i < TupleMeta->NumElements; ++i,
|
||||
ElementAddress += sizeof(Element)) {
|
||||
Element E;
|
||||
if (!Reader->readBytes(ElementAddress, (uint8_t*)&E, sizeof(Element)))
|
||||
if (!Reader->readBytes(RemoteAddress(ElementAddress),
|
||||
(uint8_t*)&E, sizeof(Element)))
|
||||
return nullptr;
|
||||
|
||||
if (auto ElementTypeRef = getTypeRef(E.Type))
|
||||
@@ -486,7 +526,8 @@ public:
|
||||
StoredPointer FlagsAddress = MetadataAddress +
|
||||
TargetFunctionTypeMetadata<Runtime>::OffsetToFlags;
|
||||
TargetFunctionTypeFlags<Runtime> Flags;
|
||||
if (!Reader->readBytes(FlagsAddress, (uint8_t*)&Flags, sizeof(Flags)))
|
||||
if (!Reader->readBytes(RemoteAddress(FlagsAddress),
|
||||
(uint8_t*)&Flags, sizeof(Flags)))
|
||||
return nullptr;
|
||||
TypeRefVector Arguments;
|
||||
StoredPointer ArgumentAddress = MetadataAddress +
|
||||
@@ -494,7 +535,8 @@ public:
|
||||
for (StoredPointer i = 0; i < Function->getNumArguments(); ++i,
|
||||
ArgumentAddress += sizeof(StoredPointer)) {
|
||||
StoredPointer FlaggedArgumentAddress;
|
||||
if (!Reader->readInteger(ArgumentAddress, &FlaggedArgumentAddress))
|
||||
if (!Reader->readInteger(RemoteAddress(ArgumentAddress),
|
||||
&FlaggedArgumentAddress))
|
||||
return nullptr;
|
||||
// TODO: Use target-agnostic FlaggedPointer to mask this!
|
||||
FlaggedArgumentAddress &= ~((StoredPointer)1);
|
||||
@@ -517,8 +559,10 @@ public:
|
||||
auto ProtocolDescriptor = readProtocolDescriptor(ProtocolAddress);
|
||||
if (!ProtocolDescriptor)
|
||||
return nullptr;
|
||||
auto MangledName = Reader->readString(ProtocolDescriptor->Name);
|
||||
if (MangledName.empty())
|
||||
|
||||
std::string MangledName;
|
||||
if (!Reader->readString(RemoteAddress(ProtocolDescriptor->Name),
|
||||
MangledName))
|
||||
return nullptr;
|
||||
auto Demangled = Demangle::demangleSymbolAsNode(MangledName);
|
||||
auto Protocol = TypeRef::fromDemangleNode(Demangled);
|
||||
@@ -607,8 +651,8 @@ public:
|
||||
auto NameAddress
|
||||
= resolveRelativeOffset<int32_t>(DescriptorAddress +
|
||||
Descriptor->offsetToNameOffset());
|
||||
auto MangledName = Reader->readString(NameAddress);
|
||||
if (MangledName.empty())
|
||||
std::string MangledName;
|
||||
if (!Reader->readString(RemoteAddress(NameAddress), MangledName))
|
||||
return {};
|
||||
|
||||
auto TR = getTypeRef(MetadataAddress);
|
||||
|
||||
78
include/swift/Remote/CMemoryReader.h
Normal file
78
include/swift/Remote/CMemoryReader.h
Normal file
@@ -0,0 +1,78 @@
|
||||
//===- CMemoryReader.h - MemoryReader wrapper for C impls -------*- C++ -*-===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See http://swift.org/LICENSE.txt for license information
|
||||
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares an implementation of MemoryReader that wraps the
|
||||
// C interface provided by SwiftRemoteMirror.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SWIFT_REMOTE_CMEMORYREADER_H
|
||||
#define SWIFT_REMOTE_CMEMORYREADER_H
|
||||
|
||||
#include "swift/SwiftRemoteMirror/MemoryReaderInterface.h"
|
||||
#include "swift/Remote/MemoryReader.h"
|
||||
|
||||
namespace swift {
|
||||
namespace remote {
|
||||
|
||||
/// An implementation of MemoryReader which wraps the C interface offered
|
||||
/// by SwiftRemoteMirror.
|
||||
class CMemoryReader final : public MemoryReader {
|
||||
MemoryReaderImpl Impl;
|
||||
|
||||
public:
|
||||
CMemoryReader(MemoryReaderImpl Impl) : Impl(Impl) {
|
||||
assert(this->Impl.getPointerSize && "No getPointerSize implementation");
|
||||
assert(this->Impl.getStringLength && "No stringLength implementation");
|
||||
assert(this->Impl.readBytes && "No readBytes implementation");
|
||||
assert(this->Impl.getPointerSize() != 0 && "Invalid target pointer size");
|
||||
}
|
||||
|
||||
uint8_t getPointerSize() override {
|
||||
return Impl.getPointerSize();
|
||||
}
|
||||
|
||||
uint8_t getSizeSize() override {
|
||||
return Impl.getSizeSize();
|
||||
}
|
||||
|
||||
RemoteAddress getSymbolAddress(const std::string &name) override {
|
||||
auto addressData = Impl.getSymbolAddress(name.c_str(), name.size());
|
||||
return RemoteAddress(addressData);
|
||||
}
|
||||
|
||||
uint64_t getStringLength(RemoteAddress address) {
|
||||
return Impl.getStringLength(address.getAddressData());
|
||||
}
|
||||
|
||||
bool readString(RemoteAddress address, std::string &dest) override {
|
||||
auto length = getStringLength(address);
|
||||
if (!length)
|
||||
return false;
|
||||
|
||||
auto buffer = std::unique_ptr<uint8_t>(new uint8_t[length + 1]);
|
||||
if (!readBytes(address, buffer.get(), length + 1))
|
||||
return false;
|
||||
|
||||
dest = std::string(reinterpret_cast<const char *>(buffer.get()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readBytes(RemoteAddress address, uint8_t *dest, uint64_t size) override {
|
||||
return Impl.readBytes(address.getAddressData(), dest, size);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
58
include/swift/Remote/InProcessMemoryReader.h
Normal file
58
include/swift/Remote/InProcessMemoryReader.h
Normal file
@@ -0,0 +1,58 @@
|
||||
//===- InProcessMemoryReader.h - Access to local memory ---------*- C++ -*-===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See http://swift.org/LICENSE.txt for license information
|
||||
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares an abstract interface for working with remote memory.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SWIFT_REMOTE_INPROCESSMEMORYREADER_H
|
||||
#define SWIFT_REMOTE_INPROCESSMEMORYREADER_H
|
||||
|
||||
#include "swift/Remote/MemoryReader.h"
|
||||
|
||||
#include <memory>
|
||||
#include <dlfcn.h>
|
||||
|
||||
namespace swift {
|
||||
namespace remote {
|
||||
|
||||
/// An implementation of MemoryReader which simply reads from the current
|
||||
/// address space.
|
||||
class InProcessMemoryReader final : public MemoryReader {
|
||||
uint8_t getPointerSize() override {
|
||||
return sizeof(uintptr_t);
|
||||
}
|
||||
|
||||
uint8_t getSizeSize() override {
|
||||
return sizeof(size_t);
|
||||
}
|
||||
|
||||
RemoteAddress getSymbolAddress(const std::string &name) override {
|
||||
auto pointer = dlsym(RTLD_DEFAULT, name.c_str());
|
||||
return RemoteAddress(pointer);
|
||||
}
|
||||
|
||||
bool readString(RemoteAddress address, std::string &dest) override {
|
||||
dest = address.getLocalPointer<char>();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readBytes(RemoteAddress address, uint8_t *dest, uint64_t size) override {
|
||||
std::memcpy(dest, address.getLocalPointer<void>(), (size_t) size);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
95
include/swift/Remote/MemoryReader.h
Normal file
95
include/swift/Remote/MemoryReader.h
Normal file
@@ -0,0 +1,95 @@
|
||||
//===- MemoryReader.h - Abstract access to remote memory --------*- C++ -*-===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See http://swift.org/LICENSE.txt for license information
|
||||
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares an abstract interface for working with the memory
|
||||
// of a remote process.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SWIFT_REMOTE_MEMORYREADER_H
|
||||
#define SWIFT_REMOTE_MEMORYREADER_H
|
||||
|
||||
#include <cstdint>
|
||||
#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)) {}
|
||||
|
||||
explicit RemoteAddress(uint64_t addressData) : Data(addressData) {}
|
||||
|
||||
explicit operator bool() const {
|
||||
return Data != 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T *getLocalPointer() const {
|
||||
return reinterpret_cast<const T*>(static_cast<uintptr_t>(Data));
|
||||
}
|
||||
|
||||
uint64_t getAddressData() const {
|
||||
return Data;
|
||||
}
|
||||
};
|
||||
|
||||
/// An abstract interface for reading memory.
|
||||
///
|
||||
/// This abstraction presents memory as if it were a read-only
|
||||
/// representation of the address space of a remote process.
|
||||
class MemoryReader {
|
||||
public:
|
||||
/// Return the size of an ordinary pointer in the remote process, in bytes.
|
||||
virtual uint8_t getPointerSize() = 0;
|
||||
|
||||
/// Return the size of size_t in the remote process, in bytes.
|
||||
virtual uint8_t getSizeSize() = 0;
|
||||
|
||||
/// Look up the given public symbol name in the remote process.
|
||||
virtual RemoteAddress getSymbolAddress(const std::string &name) = 0;
|
||||
|
||||
/// Attempts to read 'size' bytes from the given address in the
|
||||
/// remote process.
|
||||
///
|
||||
/// Returns false if the operation failed.
|
||||
virtual bool readBytes(RemoteAddress address, uint8_t *dest,
|
||||
uint64_t size) = 0;
|
||||
|
||||
/// Attempts to read a C string from the given address in the remote
|
||||
/// process.
|
||||
///
|
||||
/// Returns false if the operation failed.
|
||||
virtual bool readString(RemoteAddress address, std::string &dest) = 0;
|
||||
|
||||
/// 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) {
|
||||
return readBytes(address, reinterpret_cast<uint8_t*>(dest),
|
||||
sizeof(IntegerType));
|
||||
}
|
||||
|
||||
virtual ~MemoryReader() = default;
|
||||
};
|
||||
|
||||
} // end namespace reflection
|
||||
} // end namespace swift
|
||||
|
||||
#endif // SWIFT_REFLECTION_READER_H
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#include "swift/Reflection/ReflectionContext.h"
|
||||
#include "swift/Remote/CMemoryReader.h"
|
||||
#include "swift/SwiftRemoteMirror/SwiftRemoteMirror.h"
|
||||
|
||||
using namespace swift;
|
||||
using namespace reflection;
|
||||
using namespace swift::reflection;
|
||||
using namespace swift::remote;
|
||||
|
||||
using NativeReflectionContext
|
||||
= ReflectionContext<External<RuntimeTarget<sizeof(uintptr_t)>>>;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "swift/Basic/Demangle.h"
|
||||
#include "swift/Basic/LLVMInitialize.h"
|
||||
#include "swift/Reflection/ReflectionContext.h"
|
||||
#include "swift/Remote/InProcessMemoryReader.h"
|
||||
#include "swift/Reflection/TypeRef.h"
|
||||
#include "llvm/Object/Archive.h"
|
||||
#include "llvm/Object/MachO.h"
|
||||
@@ -36,7 +37,8 @@ using llvm::ArrayRef;
|
||||
using namespace llvm::object;
|
||||
|
||||
using namespace swift;
|
||||
using namespace reflection;
|
||||
using namespace swift::reflection;
|
||||
using namespace swift::remote;
|
||||
using namespace Demangle;
|
||||
|
||||
enum class ActionType {
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace swift;
|
||||
using namespace reflection;
|
||||
using namespace swift::reflection;
|
||||
using namespace swift::remote;
|
||||
using namespace Demangle;
|
||||
|
||||
static void errorAndExit(const std::string &message) {
|
||||
@@ -142,9 +143,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool readBytes(addr_t Address, uint8_t *Dest, uint64_t Size) override {
|
||||
bool readBytes(RemoteAddress Address, uint8_t *Dest, uint64_t Size) override {
|
||||
|
||||
StoredPointer TargetAddress = (StoredPointer)Address;
|
||||
StoredPointer TargetAddress = (StoredPointer)Address.getAddressData();
|
||||
write(getParentWriteFD(), REQUEST_READ_BYTES, 2);
|
||||
write(getParentWriteFD(), &TargetAddress, sizeof(TargetAddress));
|
||||
write(getParentWriteFD(), &Size, sizeof(StoredSize));
|
||||
@@ -160,13 +161,13 @@ public:
|
||||
return static_cast<uint64_t>(Length);
|
||||
}
|
||||
|
||||
addr_t getSymbolAddress(const std::string &SymbolName) override {
|
||||
RemoteAddress getSymbolAddress(const std::string &SymbolName) override {
|
||||
StoredPointer Address = 0;
|
||||
write(getParentWriteFD(), REQUEST_SYMBOL_ADDRESS, 2);
|
||||
write(getParentWriteFD(), SymbolName.c_str(), SymbolName.size());
|
||||
write(getParentWriteFD(), "\n", 1);
|
||||
collectBytesFromPipe(&Address, sizeof(Address));
|
||||
return static_cast<StoredPointer>(Address);
|
||||
return RemoteAddress(static_cast<StoredPointer>(Address));
|
||||
}
|
||||
|
||||
StoredPointer receiveInstanceAddress() {
|
||||
@@ -237,7 +238,8 @@ public:
|
||||
|
||||
auto buffer = (uint8_t *)malloc(RemoteInfo.TotalSize);
|
||||
|
||||
if (!readBytes(RemoteInfo.StartAddress, buffer, RemoteInfo.TotalSize))
|
||||
if (!readBytes(RemoteAddress(RemoteInfo.StartAddress), buffer,
|
||||
RemoteInfo.TotalSize))
|
||||
errorAndExit("Couldn't read reflection information");
|
||||
|
||||
auto fieldmd_base
|
||||
@@ -265,23 +267,26 @@ public:
|
||||
return Infos;
|
||||
}
|
||||
|
||||
uint64_t getStringLength(StoredPointer Address) {
|
||||
uint64_t getStringLength(RemoteAddress addr) {
|
||||
write(getParentWriteFD(), REQUEST_STRING_LENGTH, 2);
|
||||
StoredPointer Length;
|
||||
StoredPointer Address = addr.getAddressData();
|
||||
write(getParentWriteFD(), &Address, sizeof(Address));
|
||||
StoredPointer Length;
|
||||
collectBytesFromPipe(&Length, sizeof(Length));
|
||||
return static_cast<uint64_t>(Length);
|
||||
}
|
||||
|
||||
std::string readString(addr_t Address) override {
|
||||
bool readString(RemoteAddress Address, std::string &Dest) override {
|
||||
auto NameSize = getStringLength(Address);
|
||||
if (!NameSize)
|
||||
return "";
|
||||
return false;
|
||||
|
||||
auto NameBuffer = std::unique_ptr<uint8_t>(new uint8_t[NameSize + 1]);
|
||||
if (!readBytes(Address, NameBuffer.get(), NameSize + 1))
|
||||
return "";
|
||||
return std::string(reinterpret_cast<const char *>(NameBuffer.get()));
|
||||
return false;
|
||||
|
||||
Dest = reinterpret_cast<const char *>(NameBuffer.get());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -321,7 +326,7 @@ static int doDumpHeapInstance(std::string BinaryFilename) {
|
||||
std::cout << std::hex << instance << std::endl;
|
||||
|
||||
StoredPointer isa;
|
||||
if (!Pipe->readInteger(instance, &isa))
|
||||
if (!Pipe->readInteger(RemoteAddress(instance), &isa))
|
||||
errorAndExit("Couldn't get heap object's metadata address");
|
||||
|
||||
for (auto &Info : Pipe->receiveReflectionInfo())
|
||||
|
||||
Reference in New Issue
Block a user