mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Reflection] Implement swift_reflection_addImage which takes care of looking up reflection info on behalf of the client.
rdar://problem/37538580
This commit is contained in:
@@ -54,10 +54,18 @@ swift_reflection_createReflectionContext(
|
||||
void
|
||||
swift_reflection_destroyReflectionContext(SwiftReflectionContextRef Context);
|
||||
|
||||
/// Add reflection information from a loaded Swift image.
|
||||
/// Add reflection sections for a loaded Swift image.
|
||||
void
|
||||
swift_reflection_addImage(SwiftReflectionContextRef ContextRef, swift_addr_t imageStart);
|
||||
swift_reflection_addReflectionInfo(SwiftReflectionContextRef ContextRef,
|
||||
swift_reflection_info_t Info);
|
||||
|
||||
#ifdef __APPLE__
|
||||
/// Add reflection information from a loaded Swift image.
|
||||
/// Returns true on success, false if the image's memory couldn't be read.
|
||||
int
|
||||
swift_reflection_addImage(SwiftReflectionContextRef ContextRef,
|
||||
swift_addr_t imageStart, uint64_t imageLength);
|
||||
#endif
|
||||
|
||||
/// Returns a boolean indicating if the isa mask was successfully
|
||||
/// read, in which case it is stored in the isaMask out parameter.
|
||||
|
||||
@@ -26,6 +26,50 @@ extern "C" {
|
||||
|
||||
typedef uintptr_t swift_typeref_t;
|
||||
|
||||
/// \brief Represents one of the Swift reflection sections of an image.
|
||||
typedef struct swift_reflection_section {
|
||||
void *Begin;
|
||||
void *End;
|
||||
} swift_reflection_section_t;
|
||||
|
||||
/// \brief Represents the set of Swift reflection sections of an image.
|
||||
/// Not all sections may be present.
|
||||
typedef struct swift_reflection_info {
|
||||
struct {
|
||||
swift_reflection_section_t section;
|
||||
uintptr_t offset;
|
||||
} field;
|
||||
|
||||
struct {
|
||||
swift_reflection_section_t section;
|
||||
uintptr_t offset;
|
||||
} associated_types;
|
||||
|
||||
struct {
|
||||
swift_reflection_section_t section;
|
||||
uintptr_t offset;
|
||||
} builtin_types;
|
||||
|
||||
struct {
|
||||
swift_reflection_section_t section;
|
||||
uintptr_t offset;
|
||||
} capture;
|
||||
|
||||
struct {
|
||||
swift_reflection_section_t section;
|
||||
uintptr_t offset;
|
||||
} type_references;
|
||||
|
||||
struct {
|
||||
swift_reflection_section_t section;
|
||||
uintptr_t offset;
|
||||
} reflection_strings;
|
||||
|
||||
// Start address in local and remote address spaces.
|
||||
uintptr_t LocalStartAddress;
|
||||
uintptr_t RemoteStartAddress;
|
||||
} swift_reflection_info_t;
|
||||
|
||||
/// The layout kind of a Swift type.
|
||||
typedef enum swift_layout_kind {
|
||||
// Nothing is known about the size or contents of this value.
|
||||
|
||||
@@ -45,96 +45,25 @@ public enum InstanceKind : UInt8 {
|
||||
case Closure
|
||||
}
|
||||
|
||||
/// Represents a section in a loaded image in this process.
|
||||
internal struct Section {
|
||||
/// The absolute start address of the section's data in this address space.
|
||||
let startAddress: UnsafeRawPointer
|
||||
|
||||
/// The size of the section in bytes.
|
||||
let size: UInt
|
||||
}
|
||||
|
||||
/// Holds the addresses and sizes of sections related to reflection
|
||||
internal struct ReflectionInfo : Sequence {
|
||||
/// The name of the loaded image
|
||||
internal let imageName: String
|
||||
|
||||
/// Reflection metadata sections
|
||||
internal let fieldmd: Section?
|
||||
internal let assocty: Section?
|
||||
internal let builtin: Section?
|
||||
internal let capture: Section?
|
||||
internal let typeref: Section?
|
||||
internal let reflstr: Section?
|
||||
|
||||
internal func makeIterator() -> AnyIterator<Section?> {
|
||||
return AnyIterator([
|
||||
fieldmd,
|
||||
assocty,
|
||||
builtin,
|
||||
capture,
|
||||
typeref,
|
||||
reflstr
|
||||
].makeIterator())
|
||||
}
|
||||
}
|
||||
|
||||
#if arch(x86_64) || arch(arm64)
|
||||
typealias MachHeader = mach_header_64
|
||||
#else
|
||||
typealias MachHeader = mach_header
|
||||
#endif
|
||||
|
||||
/// Get the location and size of a section in a binary.
|
||||
///
|
||||
/// - Parameter name: The name of the section
|
||||
/// - Parameter imageHeader: A pointer to the Mach header describing the
|
||||
/// image.
|
||||
/// - Returns: A `Section` containing the address and size, or `nil` if there
|
||||
/// is no section by the given name.
|
||||
internal func getSectionInfo(_ name: String,
|
||||
_ imageHeader: UnsafePointer<MachHeader>) -> Section? {
|
||||
debugLog("BEGIN \(#function)"); defer { debugLog("END \(#function)") }
|
||||
var size: UInt = 0
|
||||
let address = getsectiondata(imageHeader, "__TEXT", name, &size)
|
||||
guard let nonNullAddress = address else { return nil }
|
||||
guard size != 0 else { return nil }
|
||||
return Section(startAddress: nonNullAddress, size: size)
|
||||
}
|
||||
|
||||
/// Get the Swift Reflection section locations for a loaded image.
|
||||
///
|
||||
/// An image of interest must have the following sections in the __DATA
|
||||
/// segment:
|
||||
/// - __swift5_fieldmd
|
||||
/// - __swift5_assocty
|
||||
/// - __swift5_builtin
|
||||
/// - __swift5_capture
|
||||
/// - __swift5_typeref
|
||||
/// - __swift5_reflstr (optional, may have been stripped out)
|
||||
/// Get the TEXT segment location and size for a loaded image.
|
||||
///
|
||||
/// - Parameter i: The index of the loaded image as reported by Dyld.
|
||||
/// - Returns: A `ReflectionInfo` containing the locations of all of the
|
||||
/// needed sections, or `nil` if the image doesn't contain all of them.
|
||||
internal func getReflectionInfoForImage(atIndex i: UInt32) -> ReflectionInfo? {
|
||||
/// - Returns: The image name, address, and size.
|
||||
internal func getAddressInfoForImage(atIndex i: UInt32) ->
|
||||
(name: String, address: UnsafeMutablePointer<UInt8>?, size: UInt) {
|
||||
debugLog("BEGIN \(#function)"); defer { debugLog("END \(#function)") }
|
||||
let header = unsafeBitCast(_dyld_get_image_header(i),
|
||||
to: UnsafePointer<MachHeader>.self)
|
||||
|
||||
let imageName = _dyld_get_image_name(i)!
|
||||
let fieldmd = getSectionInfo("__swift5_fieldmd", header)
|
||||
let assocty = getSectionInfo("__swift5_assocty", header)
|
||||
let builtin = getSectionInfo("__swift5_builtin", header)
|
||||
let capture = getSectionInfo("__swift5_capture", header)
|
||||
let typeref = getSectionInfo("__swift5_typeref", header)
|
||||
let reflstr = getSectionInfo("__swift5_reflstr", header)
|
||||
return ReflectionInfo(imageName: String(validatingUTF8: imageName)!,
|
||||
fieldmd: fieldmd,
|
||||
assocty: assocty,
|
||||
builtin: builtin,
|
||||
capture: capture,
|
||||
typeref: typeref,
|
||||
reflstr: reflstr)
|
||||
let name = String(validatingUTF8: _dyld_get_image_name(i)!)!
|
||||
var size: UInt = 0
|
||||
let address = getsegmentdata(header, "__TEXT", &size)
|
||||
return (name, address, size)
|
||||
}
|
||||
|
||||
internal func sendBytes<T>(from address: UnsafePointer<T>, count: Int) {
|
||||
@@ -179,18 +108,15 @@ internal func readUInt() -> UInt {
|
||||
/// process.
|
||||
internal func sendReflectionInfos() {
|
||||
debugLog("BEGIN \(#function)"); defer { debugLog("END \(#function)") }
|
||||
let infos = (0..<_dyld_image_count()).compactMap(getReflectionInfoForImage)
|
||||
let infos = (0..<_dyld_image_count()).map(getAddressInfoForImage)
|
||||
|
||||
var numInfos = infos.count
|
||||
debugLog("\(numInfos) reflection info bundles.")
|
||||
precondition(numInfos >= 1)
|
||||
sendBytes(from: &numInfos, count: MemoryLayout<UInt>.size)
|
||||
for info in infos {
|
||||
debugLog("Sending info for \(info.imageName)")
|
||||
for section in info {
|
||||
sendValue(section?.startAddress)
|
||||
sendValue(section?.size ?? 0)
|
||||
}
|
||||
debugLog("\(infos.count) reflection info bundles.")
|
||||
precondition(infos.count >= 1)
|
||||
sendValue(infos.count)
|
||||
for (name, address, size) in infos {
|
||||
debugLog("Sending info for \(name)")
|
||||
sendValue(address)
|
||||
sendValue(size)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,8 +182,7 @@ internal func sendPointerSize() {
|
||||
/// This is the main "run loop" of the test harness.
|
||||
///
|
||||
/// The parent will necessarily need to:
|
||||
/// - Get the addresses of all of the reflection sections for any swift dylibs
|
||||
/// that are loaded, where applicable.
|
||||
/// - Get the addresses of any swift dylibs that are loaded, where applicable.
|
||||
/// - Get the address of the `instance`
|
||||
/// - Get the pointer size of this process, which affects assumptions about the
|
||||
/// the layout of runtime structures with pointer-sized fields.
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
#include "swift/Runtime/Unreachable.h"
|
||||
#include "swift/SwiftRemoteMirror/SwiftRemoteMirror.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <mach-o/getsect.h>
|
||||
#endif
|
||||
|
||||
using namespace swift;
|
||||
using namespace swift::reflection;
|
||||
using namespace swift::remote;
|
||||
@@ -23,6 +27,20 @@ using namespace swift::remote;
|
||||
using NativeReflectionContext
|
||||
= ReflectionContext<External<RuntimeTarget<sizeof(uintptr_t)>>>;
|
||||
|
||||
struct SwiftReflectionContext {
|
||||
NativeReflectionContext *nativeContext;
|
||||
|
||||
SwiftReflectionContext(MemoryReaderImpl impl) {
|
||||
auto Reader = std::make_shared<CMemoryReader>(impl);
|
||||
nativeContext = new NativeReflectionContext(Reader);
|
||||
}
|
||||
|
||||
~SwiftReflectionContext() {
|
||||
delete nativeContext;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
uint16_t
|
||||
swift_reflection_getSupportedMetadataVersion() {
|
||||
return SWIFT_REFLECTION_METADATA_VERSION;
|
||||
@@ -44,28 +62,90 @@ swift_reflection_createReflectionContext(void *ReaderContext,
|
||||
getSymbolAddress
|
||||
};
|
||||
|
||||
auto Reader = std::make_shared<CMemoryReader>(ReaderImpl);
|
||||
auto Context
|
||||
= new swift::reflection::ReflectionContext<External<RuntimeTarget<sizeof(uintptr_t)>>>(Reader);
|
||||
return reinterpret_cast<SwiftReflectionContextRef>(Context);
|
||||
return new SwiftReflectionContext(ReaderImpl);
|
||||
}
|
||||
|
||||
void swift_reflection_destroyReflectionContext(SwiftReflectionContextRef ContextRef) {
|
||||
auto Context = reinterpret_cast<swift::reflection::ReflectionContext<InProcess> *>(ContextRef);
|
||||
delete Context;
|
||||
delete ContextRef;
|
||||
}
|
||||
|
||||
void
|
||||
swift_reflection_addReflectionInfo(SwiftReflectionContextRef ContextRef,
|
||||
swift_reflection_info_t Info) {
|
||||
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
||||
auto Context = ContextRef->nativeContext;
|
||||
|
||||
Context->addReflectionInfo(*reinterpret_cast<ReflectionInfo *>(&Info));
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
#ifndef __LP64__
|
||||
typedef const struct mach_header MachHeader;
|
||||
#else
|
||||
typedef const struct mach_header_64 MachHeader;
|
||||
#endif
|
||||
|
||||
template <typename Section>
|
||||
static bool findSection(MachHeader *Header, const char *Name,
|
||||
Section &Sect) {
|
||||
unsigned long Size;
|
||||
auto Address = getsectiondata(Header, "__TEXT", Name, &Size);
|
||||
if (!Address)
|
||||
return false;
|
||||
|
||||
Sect.section.Begin = Address;
|
||||
auto End = reinterpret_cast<uintptr_t>(Address) + Size;
|
||||
Sect.section.End = reinterpret_cast<void *>(End);
|
||||
Sect.offset = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
swift_reflection_addImage(SwiftReflectionContextRef ContextRef,
|
||||
swift_addr_t imageStart, uint64_t imageLength) {
|
||||
auto Context = ContextRef->nativeContext;
|
||||
|
||||
if (imageLength < sizeof(MachHeader)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto Buf = malloc(imageLength);
|
||||
Context->getReader().readBytes(RemoteAddress(imageStart),
|
||||
reinterpret_cast<uint8_t *>(Buf),
|
||||
imageLength);
|
||||
|
||||
auto Header = reinterpret_cast<MachHeader *>(Buf);
|
||||
if (Header->magic != MH_MAGIC && Header->magic != MH_MAGIC_64) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
swift_reflection_info_t info = {};
|
||||
|
||||
// The docs say "not all sections may be present." We'll succeed if ANY of them are
|
||||
// present. Not sure if that's the right thing to do.
|
||||
bool success = false;
|
||||
success = findSection(Header, "__swift5_fieldmd", info.field) || success;
|
||||
success = findSection(Header, "__swift5_assocty", info.associated_types) || success;
|
||||
success = findSection(Header, "__swift5_builtin", info.builtin_types) || success;
|
||||
success = findSection(Header, "__swift5_capture", info.capture) || success;
|
||||
success = findSection(Header, "__swift5_typeref", info.type_references) || success;
|
||||
success = findSection(Header, "__swift5_reflstr", info.reflection_strings) || success;
|
||||
|
||||
if (success) {
|
||||
info.LocalStartAddress = reinterpret_cast<uintptr_t>(Buf);
|
||||
info.RemoteStartAddress = imageStart;
|
||||
swift_reflection_addReflectionInfo(ContextRef, info);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
swift_reflection_readIsaMask(SwiftReflectionContextRef ContextRef,
|
||||
uintptr_t *outIsaMask) {
|
||||
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
||||
auto Context = ContextRef->nativeContext;
|
||||
auto isaMask = Context->readIsaMask();
|
||||
if (isaMask) {
|
||||
*outIsaMask = *isaMask;
|
||||
@@ -78,7 +158,7 @@ swift_reflection_readIsaMask(SwiftReflectionContextRef ContextRef,
|
||||
swift_typeref_t
|
||||
swift_reflection_typeRefForMetadata(SwiftReflectionContextRef ContextRef,
|
||||
uintptr_t Metadata) {
|
||||
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
||||
auto Context = ContextRef->nativeContext;
|
||||
auto TR = Context->readTypeFromMetadata(Metadata);
|
||||
return reinterpret_cast<swift_typeref_t>(TR);
|
||||
}
|
||||
@@ -86,7 +166,7 @@ swift_reflection_typeRefForMetadata(SwiftReflectionContextRef ContextRef,
|
||||
swift_typeref_t
|
||||
swift_reflection_typeRefForInstance(SwiftReflectionContextRef ContextRef,
|
||||
uintptr_t Object) {
|
||||
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
||||
auto Context = ContextRef->nativeContext;
|
||||
auto MetadataAddress = Context->readMetadataFromInstance(Object);
|
||||
if (!MetadataAddress)
|
||||
return 0;
|
||||
@@ -98,7 +178,7 @@ swift_typeref_t
|
||||
swift_reflection_typeRefForMangledTypeName(SwiftReflectionContextRef ContextRef,
|
||||
const char *MangledTypeName,
|
||||
uint64_t Length) {
|
||||
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
||||
auto Context = ContextRef->nativeContext;
|
||||
auto TR = Context->readTypeFromMangledName(MangledTypeName, Length);
|
||||
return reinterpret_cast<swift_typeref_t>(TR);
|
||||
}
|
||||
@@ -223,7 +303,7 @@ static swift_childinfo_t convertChild(const TypeInfo *TI, unsigned Index) {
|
||||
swift_typeinfo_t
|
||||
swift_reflection_infoForTypeRef(SwiftReflectionContextRef ContextRef,
|
||||
swift_typeref_t OpaqueTypeRef) {
|
||||
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
||||
auto Context = ContextRef->nativeContext;
|
||||
auto TR = reinterpret_cast<const TypeRef *>(OpaqueTypeRef);
|
||||
auto TI = Context->getTypeInfo(TR);
|
||||
return convertTypeInfo(TI);
|
||||
@@ -233,7 +313,7 @@ swift_childinfo_t
|
||||
swift_reflection_childOfTypeRef(SwiftReflectionContextRef ContextRef,
|
||||
swift_typeref_t OpaqueTypeRef,
|
||||
unsigned Index) {
|
||||
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
||||
auto Context = ContextRef->nativeContext;
|
||||
auto TR = reinterpret_cast<const TypeRef *>(OpaqueTypeRef);
|
||||
auto *TI = Context->getTypeInfo(TR);
|
||||
return convertChild(TI, Index);
|
||||
@@ -242,7 +322,7 @@ swift_reflection_childOfTypeRef(SwiftReflectionContextRef ContextRef,
|
||||
swift_typeinfo_t
|
||||
swift_reflection_infoForMetadata(SwiftReflectionContextRef ContextRef,
|
||||
uintptr_t Metadata) {
|
||||
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
||||
auto Context = ContextRef->nativeContext;
|
||||
auto *TI = Context->getMetadataTypeInfo(Metadata);
|
||||
return convertTypeInfo(TI);
|
||||
}
|
||||
@@ -251,7 +331,7 @@ swift_childinfo_t
|
||||
swift_reflection_childOfMetadata(SwiftReflectionContextRef ContextRef,
|
||||
uintptr_t Metadata,
|
||||
unsigned Index) {
|
||||
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
||||
auto Context = ContextRef->nativeContext;
|
||||
auto *TI = Context->getMetadataTypeInfo(Metadata);
|
||||
return convertChild(TI, Index);
|
||||
}
|
||||
@@ -259,7 +339,7 @@ swift_reflection_childOfMetadata(SwiftReflectionContextRef ContextRef,
|
||||
swift_typeinfo_t
|
||||
swift_reflection_infoForInstance(SwiftReflectionContextRef ContextRef,
|
||||
uintptr_t Object) {
|
||||
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
||||
auto Context = ContextRef->nativeContext;
|
||||
auto *TI = Context->getInstanceTypeInfo(Object);
|
||||
return convertTypeInfo(TI);
|
||||
}
|
||||
@@ -268,7 +348,7 @@ swift_childinfo_t
|
||||
swift_reflection_childOfInstance(SwiftReflectionContextRef ContextRef,
|
||||
uintptr_t Object,
|
||||
unsigned Index) {
|
||||
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
||||
auto Context = ContextRef->nativeContext;
|
||||
auto *TI = Context->getInstanceTypeInfo(Object);
|
||||
return convertChild(TI, Index);
|
||||
}
|
||||
@@ -278,7 +358,7 @@ int swift_reflection_projectExistential(SwiftReflectionContextRef ContextRef,
|
||||
swift_typeref_t ExistentialTypeRef,
|
||||
swift_typeref_t *InstanceTypeRef,
|
||||
swift_addr_t *StartOfInstanceData) {
|
||||
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
||||
auto Context = ContextRef->nativeContext;
|
||||
auto ExistentialTR = reinterpret_cast<const TypeRef *>(ExistentialTypeRef);
|
||||
auto RemoteExistentialAddress = RemoteAddress(ExistentialAddress);
|
||||
const TypeRef *InstanceTR = nullptr;
|
||||
@@ -307,7 +387,7 @@ void swift_reflection_dumpTypeRef(swift_typeref_t OpaqueTypeRef) {
|
||||
|
||||
void swift_reflection_dumpInfoForTypeRef(SwiftReflectionContextRef ContextRef,
|
||||
swift_typeref_t OpaqueTypeRef) {
|
||||
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
||||
auto Context = ContextRef->nativeContext;
|
||||
auto TR = reinterpret_cast<const TypeRef *>(OpaqueTypeRef);
|
||||
auto TI = Context->getTypeInfo(TR);
|
||||
if (TI == nullptr) {
|
||||
@@ -319,7 +399,7 @@ void swift_reflection_dumpInfoForTypeRef(SwiftReflectionContextRef ContextRef,
|
||||
|
||||
void swift_reflection_dumpInfoForMetadata(SwiftReflectionContextRef ContextRef,
|
||||
uintptr_t Metadata) {
|
||||
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
||||
auto Context = ContextRef->nativeContext;
|
||||
auto TI = Context->getMetadataTypeInfo(Metadata);
|
||||
if (TI == nullptr) {
|
||||
std::cout << "<null type info>\n";
|
||||
@@ -330,7 +410,7 @@ void swift_reflection_dumpInfoForMetadata(SwiftReflectionContextRef ContextRef,
|
||||
|
||||
void swift_reflection_dumpInfoForInstance(SwiftReflectionContextRef ContextRef,
|
||||
uintptr_t Object) {
|
||||
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
||||
auto Context = ContextRef->nativeContext;
|
||||
auto TI = Context->getInstanceTypeInfo(Object);
|
||||
if (TI == nullptr) {
|
||||
std::cout << "<null type info>\n";
|
||||
|
||||
@@ -29,28 +29,11 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
typedef struct RemoteSection {
|
||||
uintptr_t StartAddress;
|
||||
uintptr_t Size;
|
||||
uintptr_t EndAddress;
|
||||
} RemoteSection;
|
||||
|
||||
typedef struct PipeMemoryReader {
|
||||
int to_child[2];
|
||||
int from_child[2];
|
||||
} PipeMemoryReader;
|
||||
|
||||
typedef struct RemoteReflectionInfo {
|
||||
RemoteSection fieldmd;
|
||||
RemoteSection assocty;
|
||||
RemoteSection builtin;
|
||||
RemoteSection capture;
|
||||
RemoteSection typeref;
|
||||
RemoteSection reflstr;
|
||||
uintptr_t StartAddress;
|
||||
size_t TotalSize;
|
||||
} RemoteReflectionInfo;
|
||||
|
||||
static void errorAndExit(const char *message) {
|
||||
fprintf(stderr, "%s\n", message);
|
||||
abort();
|
||||
@@ -61,77 +44,6 @@ static void errnoAndExit(const char *message) {
|
||||
abort();
|
||||
}
|
||||
|
||||
static swift_reflection_section_t
|
||||
makeLocalSection(void *Buffer, RemoteSection Section,
|
||||
RemoteReflectionInfo Info) {
|
||||
if (Section.Size == 0) {
|
||||
swift_reflection_section_t LS = {NULL, NULL};
|
||||
return LS;
|
||||
}
|
||||
|
||||
uintptr_t Base
|
||||
= (uintptr_t)Buffer + Section.StartAddress - Info.StartAddress;
|
||||
swift_reflection_section_t LS = {
|
||||
(void *)Base,
|
||||
(void *)(Base + Section.Size)
|
||||
};
|
||||
return LS;
|
||||
}
|
||||
|
||||
static
|
||||
uintptr_t getStartAddress(const RemoteSection Sections[], size_t Count) {
|
||||
uintptr_t Start = 0;
|
||||
for (size_t i = 0; i < Count; ++i) {
|
||||
if (Sections[i].StartAddress != 0) {
|
||||
if (Start != 0)
|
||||
Start = MIN(Start, Sections[i].StartAddress);
|
||||
else
|
||||
Start = Sections[i].StartAddress;
|
||||
}
|
||||
}
|
||||
return Start;
|
||||
}
|
||||
|
||||
static
|
||||
uintptr_t getEndAddress(const RemoteSection Sections[], size_t Count) {
|
||||
uintptr_t End = 0;
|
||||
for (size_t i = 0; i < Count; ++i) {
|
||||
if (Sections[i].StartAddress != 0)
|
||||
End = MAX(End, Sections[i].EndAddress);
|
||||
}
|
||||
return End;
|
||||
}
|
||||
|
||||
static
|
||||
RemoteReflectionInfo makeRemoteReflectionInfo(RemoteSection fieldmd,
|
||||
RemoteSection assocty,
|
||||
RemoteSection builtin,
|
||||
RemoteSection capture,
|
||||
RemoteSection typeref,
|
||||
RemoteSection reflstr) {
|
||||
RemoteReflectionInfo Info = {
|
||||
fieldmd,
|
||||
assocty,
|
||||
builtin,
|
||||
capture,
|
||||
typeref,
|
||||
reflstr,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
const RemoteSection Sections[6] = {
|
||||
fieldmd, assocty, builtin, capture, typeref, reflstr
|
||||
};
|
||||
|
||||
Info.StartAddress = getStartAddress(Sections, 6);
|
||||
|
||||
uintptr_t EndAddress = getEndAddress(Sections, 6);
|
||||
Info.TotalSize = EndAddress - Info.StartAddress;
|
||||
|
||||
return Info;
|
||||
}
|
||||
|
||||
static const size_t ReadEnd = 0;
|
||||
static const size_t WriteEnd = 1;
|
||||
|
||||
@@ -247,18 +159,6 @@ PipeMemoryReader createPipeMemoryReader() {
|
||||
return Reader;
|
||||
}
|
||||
|
||||
static
|
||||
RemoteSection makeRemoteSection(const PipeMemoryReader *Reader) {
|
||||
uintptr_t Start;
|
||||
size_t Size;
|
||||
|
||||
PipeMemoryReader_collectBytesFromPipe(Reader, &Start, sizeof(Start));
|
||||
PipeMemoryReader_collectBytesFromPipe(Reader, &Size, sizeof(Size));
|
||||
|
||||
RemoteSection RS = {Start, Size, Start + Size};
|
||||
return RS;
|
||||
}
|
||||
|
||||
static void
|
||||
PipeMemoryReader_receiveReflectionInfo(SwiftReflectionContextRef RC,
|
||||
const PipeMemoryReader *Reader) {
|
||||
@@ -270,50 +170,17 @@ PipeMemoryReader_receiveReflectionInfo(SwiftReflectionContextRef RC,
|
||||
|
||||
if (NumReflectionInfos == 0)
|
||||
return;
|
||||
|
||||
RemoteReflectionInfo *RemoteInfos = calloc(NumReflectionInfos,
|
||||
sizeof(RemoteReflectionInfo));
|
||||
if (RemoteInfos == NULL)
|
||||
errnoAndExit("malloc failed");
|
||||
|
||||
|
||||
struct { uintptr_t Start, Size; } *Images;
|
||||
Images = calloc(NumReflectionInfos, sizeof(*Images));
|
||||
PipeMemoryReader_collectBytesFromPipe(Reader, Images,
|
||||
NumReflectionInfos * sizeof(*Images));
|
||||
|
||||
for (size_t i = 0; i < NumReflectionInfos; ++i) {
|
||||
RemoteInfos[i] = makeRemoteReflectionInfo(
|
||||
makeRemoteSection(Reader),
|
||||
makeRemoteSection(Reader),
|
||||
makeRemoteSection(Reader),
|
||||
makeRemoteSection(Reader),
|
||||
makeRemoteSection(Reader),
|
||||
makeRemoteSection(Reader));
|
||||
swift_reflection_addImage(RC, Images[i].Start, Images[i].Size);
|
||||
}
|
||||
|
||||
// Now pull in the remote sections into our address space.
|
||||
|
||||
for (size_t i = 0; i < NumReflectionInfos; ++i) {
|
||||
RemoteReflectionInfo RemoteInfo = RemoteInfos[i];
|
||||
|
||||
void *Buffer = malloc(RemoteInfo.TotalSize);
|
||||
|
||||
int Success = PipeMemoryReader_readBytes((void *)Reader,
|
||||
RemoteInfo.StartAddress,
|
||||
Buffer,
|
||||
RemoteInfo.TotalSize);
|
||||
if (!Success)
|
||||
errorAndExit("Couldn't read reflection information");
|
||||
|
||||
swift_reflection_info_t Info = {
|
||||
{makeLocalSection(Buffer, RemoteInfo.fieldmd, RemoteInfo), 0},
|
||||
{makeLocalSection(Buffer, RemoteInfo.assocty, RemoteInfo), 0},
|
||||
{makeLocalSection(Buffer, RemoteInfo.builtin, RemoteInfo), 0},
|
||||
{makeLocalSection(Buffer, RemoteInfo.capture, RemoteInfo), 0},
|
||||
{makeLocalSection(Buffer, RemoteInfo.typeref, RemoteInfo), 0},
|
||||
{makeLocalSection(Buffer, RemoteInfo.reflstr, RemoteInfo), 0},
|
||||
/*LocalStartAddress*/ (uintptr_t) Buffer,
|
||||
/*RemoteStartAddress*/ RemoteInfo.StartAddress,
|
||||
};
|
||||
swift_reflection_addReflectionInfo(RC, Info);
|
||||
}
|
||||
|
||||
free(RemoteInfos);
|
||||
|
||||
free(Images);
|
||||
}
|
||||
|
||||
uint64_t PipeMemoryReader_getStringLength(void *Context, swift_addr_t Address) {
|
||||
|
||||
Reference in New Issue
Block a user