mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Teach RemoteMirror how to project enum values
This adds two new functions to the SwiftRemoteMirror
facility that support inspecting enum values.
Currently, these support non-payload enums and
single-payload enums, including nested enums and
payloads with struct, tuple, and reference payloads.
In particular, it handles nested `Optional` types.
TODO: Multi-payload enums use different strategies for
encoding the cases that aren't yet supported by this
code.
Note: This relies on information from dataLayoutQuery
to correctly decode invalid pointer values that are used
to encode enums. Existing clients will need to augment
their DLQ functions before using these new APIs.
Resolves rdar://59961527
```
/// Projects the value of an enum.
///
/// Takes the address and typeref for an enum and determines the
/// index of the currently-selected case within the enum.
///
/// Returns true iff the enum case could be successfully determined.
/// In particular, note that this code may fail for valid in-memory data
/// if the compiler is using a strategy we do not yet understand.
SWIFT_REMOTE_MIRROR_LINKAGE
int swift_reflection_projectEnumValue(SwiftReflectionContextRef ContextRef,
swift_addr_t EnumAddress,
swift_typeref_t EnumTypeRef,
uint64_t *CaseIndex);
/// Finds information about a particular enum case.
///
/// Given an enum typeref and index of a case, returns:
/// * Typeref of the associated payload or zero if there is no payload
/// * Name of the case if known.
///
/// The Name points to a freshly-allocated C string on the heap. You
/// are responsible for freeing the string (via `free()`) when you are finished.
SWIFT_REMOTE_MIRROR_LINKAGE
int swift_reflection_getEnumCaseTypeRef(SwiftReflectionContextRef ContextRef,
swift_typeref_t EnumTypeRef,
unsigned CaseIndex,
char **CaseName,
swift_typeref_t *PayloadTypeRef);
```
Co-authored-by: Mike Ash <mikeash@apple.com>
1145 lines
41 KiB
C++
1145 lines
41 KiB
C++
//===--- SwiftRemoteMirrorLegacyInterop.h - Interop with legacy libs. -*- C++ -*-===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------------===//
|
|
///
|
|
/// \file
|
|
/// This header provides an interface for using multiple versions of the Swift remote
|
|
/// mirror library to inspect processes built with different versions of Swift, or
|
|
/// processes where different libraries are built with different versions of Swift.
|
|
///
|
|
//===----------------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_REMOTE_MIRROR_LEGACY_INTEROP_H
|
|
#define SWIFT_REMOTE_MIRROR_LEGACY_INTEROP_H
|
|
|
|
#if defined(__APPLE__) && defined(__MACH__)
|
|
|
|
#include "SwiftRemoteMirrorLegacyInteropTypes.h"
|
|
#include "SwiftRemoteMirror.h"
|
|
|
|
#include <string.h>
|
|
#include <dlfcn.h>
|
|
#include <mach-o/getsect.h>
|
|
|
|
#include <CoreFoundation/CFDictionary.h>
|
|
#include <TargetConditionals.h>
|
|
|
|
/// The "public" interface follows. All of these functions are the same
|
|
/// as the corresponding swift_reflection_* functions, except for taking
|
|
/// or returning _interop data types in some circumstances.
|
|
|
|
static inline SwiftReflectionInteropContextRef
|
|
swift_reflection_interop_createReflectionContext(
|
|
void *ReaderContext,
|
|
uint8_t PointerSize,
|
|
FreeBytesFunction FreeBytes,
|
|
ReadBytesFunction ReadBytes,
|
|
GetStringLengthFunction GetStringLength,
|
|
GetSymbolAddressFunction GetSymbolAddress);
|
|
|
|
static inline SwiftReflectionInteropContextRef
|
|
swift_reflection_interop_createReflectionContextWithDataLayout(
|
|
void *ReaderContext,
|
|
QueryDataLayoutFunction DataLayout,
|
|
FreeBytesFunction FreeBytes,
|
|
ReadBytesFunction ReadBytes,
|
|
GetStringLengthFunction GetStringLength,
|
|
GetSymbolAddressFunction GetSymbolAddress);
|
|
|
|
/// Add a library handle to the interop context. Returns 1 if the
|
|
/// library was added successfully, 0 if a symbol couldn't be looked up
|
|
/// or the reported metadata version is too old.
|
|
static inline int
|
|
swift_reflection_interop_addLibrary(
|
|
SwiftReflectionInteropContextRef ContextRef, void *LibraryHandle);
|
|
|
|
static inline void
|
|
swift_reflection_interop_destroyReflectionContext(
|
|
SwiftReflectionInteropContextRef ContextRef);
|
|
|
|
/// Set the is-Swift mask for the stable ABI on the current system.
|
|
/// NOTE: must be called after interop_addLibrary is used to add the
|
|
/// stable ABI remote mirror library in order to take effect.
|
|
static inline void
|
|
swift_reflection_interop_setClassIsSwiftMask(
|
|
SwiftReflectionInteropContextRef ContextRef, uint64_t mask);
|
|
|
|
static inline int
|
|
swift_reflection_interop_addImage(SwiftReflectionInteropContextRef ContextRef,
|
|
swift_addr_t imageStart);
|
|
|
|
static inline int
|
|
swift_reflection_interop_readIsaMask(SwiftReflectionInteropContextRef ContextRef,
|
|
uintptr_t *outIsaMask);
|
|
|
|
/// Look up a metadata pointer and return an interop structure that can
|
|
/// be passed to other calls. Returns { 0, 0 } if the metadata pointer
|
|
/// was not recognized.
|
|
static inline swift_metadata_interop_t
|
|
swift_reflection_interop_lookupMetadata(SwiftReflectionInteropContextRef ContextRef,
|
|
uintptr_t RemoteTyperef);
|
|
|
|
static inline swift_typeref_interop_t
|
|
swift_reflection_interop_typeRefForMetadata(SwiftReflectionInteropContextRef ContextRef,
|
|
swift_metadata_interop_t Metadata);
|
|
|
|
static inline swift_typeref_interop_t
|
|
swift_reflection_interop_typeRefForInstance(SwiftReflectionInteropContextRef ContextRef,
|
|
uintptr_t Object);
|
|
|
|
static inline swift_typeref_interop_t
|
|
swift_reflection_interop_typeRefForMangledTypeName(
|
|
SwiftReflectionInteropContextRef ContextRef,
|
|
const char *MangledName,
|
|
uint64_t Length);
|
|
|
|
static inline swift_typeinfo_t
|
|
swift_reflection_interop_infoForTypeRef(SwiftReflectionInteropContextRef ContextRef,
|
|
swift_typeref_interop_t OpaqueTypeRef);
|
|
|
|
static inline swift_childinfo_interop_t
|
|
swift_reflection_interop_childOfTypeRef(SwiftReflectionInteropContextRef ContextRef,
|
|
swift_typeref_interop_t OpaqueTypeRef,
|
|
unsigned Index);
|
|
|
|
static inline swift_typeinfo_interop_t
|
|
swift_reflection_interop_infoForMetadata(SwiftReflectionInteropContextRef ContextRef,
|
|
swift_metadata_interop_t Metadata);
|
|
|
|
static inline swift_childinfo_interop_t
|
|
swift_reflection_interop_childOfMetadata(SwiftReflectionInteropContextRef ContextRef,
|
|
swift_metadata_interop_t Metadata,
|
|
unsigned Index);
|
|
|
|
static inline swift_typeinfo_interop_t
|
|
swift_reflection_interop_infoForInstance(SwiftReflectionInteropContextRef ContextRef,
|
|
uintptr_t Object);
|
|
|
|
static inline swift_childinfo_interop_t
|
|
swift_reflection_interop_childOfInstance(SwiftReflectionInteropContextRef ContextRef,
|
|
uintptr_t Object,
|
|
unsigned Index);
|
|
|
|
static inline unsigned
|
|
swift_reflection_interop_genericArgumentCountOfTypeRef(
|
|
SwiftReflectionInteropContextRef ContextRef, swift_typeref_interop_t OpaqueTypeRef);
|
|
|
|
static inline swift_typeref_interop_t
|
|
swift_reflection_interop_genericArgumentOfTypeRef(
|
|
SwiftReflectionInteropContextRef ContextRef, swift_typeref_interop_t OpaqueTypeRef,
|
|
unsigned Index);
|
|
|
|
static inline int
|
|
swift_reflection_interop_projectExistential(SwiftReflectionInteropContextRef ContextRef,
|
|
swift_addr_t ExistentialAddress,
|
|
swift_typeref_interop_t ExistentialTypeRef,
|
|
swift_typeref_interop_t *OutInstanceTypeRef,
|
|
swift_addr_t *OutStartOfInstanceData);
|
|
|
|
static inline void
|
|
swift_reflection_interop_dumpTypeRef(SwiftReflectionInteropContextRef ContextRef,
|
|
swift_typeref_interop_t OpaqueTypeRef);
|
|
|
|
static inline void
|
|
swift_reflection_interop_dumpInfoForTypeRef(SwiftReflectionInteropContextRef ContextRef,
|
|
swift_typeref_interop_t OpaqueTypeRef);
|
|
|
|
static inline void
|
|
swift_reflection_interop_dumpInfoForMetadata(SwiftReflectionInteropContextRef ContextRef,
|
|
swift_metadata_interop_t Metadata);
|
|
|
|
static inline void
|
|
swift_reflection_interop_dumpInfoForInstance(SwiftReflectionInteropContextRef ContextRef,
|
|
uintptr_t Object);
|
|
|
|
static inline size_t
|
|
swift_reflection_interop_demangle(SwiftReflectionInteropContextRef ContextRef,
|
|
const char *MangledName,
|
|
size_t Length,
|
|
char *OutDemangledName,
|
|
size_t MaxLength);
|
|
|
|
|
|
|
|
/// \name Internal implementation details, clients don't need to use these.
|
|
/// @{
|
|
|
|
/// The minimum supported metadata version for the legacy library.
|
|
#define SWIFT_LEGACY_METADATA_MIN_VERSION 3
|
|
|
|
/// The legacy reflection info struct.
|
|
typedef struct swift_reflection_legacy_info {
|
|
swift_reflection_section_t fieldmd;
|
|
swift_reflection_section_t assocty;
|
|
swift_reflection_section_t builtin;
|
|
swift_reflection_section_t capture;
|
|
swift_reflection_section_t typeref;
|
|
swift_reflection_section_t reflstr;
|
|
uintptr_t LocalStartAddress;
|
|
uintptr_t RemoteStartAddress;
|
|
} swift_reflection_legacy_info_t;
|
|
|
|
/// The signature of the legacy ReadBytesFunction.
|
|
typedef int (*ReadBytesFunctionLegacy)(void *reader_context, swift_addr_t address,
|
|
void *dest, uint64_t size);
|
|
|
|
struct SwiftReflectionFunctions {
|
|
unsigned long long *classIsSwiftMaskPtr;
|
|
|
|
uint16_t (*getSupportedMetadataVersion)(void);
|
|
|
|
SwiftReflectionContextRef (*createReflectionContext)(
|
|
void *ReaderContext,
|
|
uint8_t PointerSize,
|
|
FreeBytesFunction FreeBytes,
|
|
ReadBytesFunction ReadBytes,
|
|
GetStringLengthFunction GetStringLength,
|
|
GetSymbolAddressFunction GetSymbolAddress);
|
|
|
|
// Optional creation function that takes a data layout query function.
|
|
SwiftReflectionContextRef (*createReflectionContextWithDataLayout)(
|
|
void *ReaderContext,
|
|
QueryDataLayoutFunction DataLayout,
|
|
FreeBytesFunction FreeBytes,
|
|
ReadBytesFunction ReadBytes,
|
|
GetStringLengthFunction GetStringLength,
|
|
GetSymbolAddressFunction GetSymbolAddress);
|
|
|
|
SwiftReflectionContextRef (*createReflectionContextLegacy)(
|
|
void *ReaderContext,
|
|
PointerSizeFunction getPointerSize,
|
|
SizeSizeFunction getSizeSize,
|
|
ReadBytesFunctionLegacy readBytes,
|
|
GetStringLengthFunction getStringLength,
|
|
GetSymbolAddressFunction getSymbolAddress);
|
|
|
|
void (*destroyReflectionContext)(SwiftReflectionContextRef Context);
|
|
|
|
void (*addReflectionInfo)(SwiftReflectionContextRef Context,
|
|
swift_reflection_info_t Info);
|
|
|
|
void (*addReflectionInfoLegacy)(SwiftReflectionContextRef Context,
|
|
swift_reflection_legacy_info_t Info);
|
|
|
|
int (*addImage)(SwiftReflectionContextRef ContextRef,
|
|
swift_addr_t imageStart);
|
|
|
|
int (*readIsaMask)(SwiftReflectionContextRef ContextRef, uintptr_t *outIsaMask);
|
|
|
|
swift_typeref_t (*typeRefForMetadata)(SwiftReflectionContextRef ContextRef,
|
|
uintptr_t Metadata);
|
|
|
|
int (*ownsObject)(SwiftReflectionContextRef ContextRef, uintptr_t Object);
|
|
|
|
int (*ownsAddress)(SwiftReflectionContextRef ContextRef, uintptr_t Address);
|
|
|
|
uintptr_t (*metadataForObject)(SwiftReflectionContextRef ContextRef, uintptr_t Object);
|
|
|
|
swift_typeref_t (*typeRefForInstance)(SwiftReflectionContextRef ContextRef,
|
|
uintptr_t Object);
|
|
|
|
swift_typeref_t (*typeRefForMangledTypeName)(SwiftReflectionContextRef ContextRef,
|
|
const char *MangledName,
|
|
uint64_t Length);
|
|
|
|
swift_typeinfo_t (*infoForTypeRef)(SwiftReflectionContextRef ContextRef,
|
|
swift_typeref_t OpaqueTypeRef);
|
|
|
|
swift_childinfo_t (*childOfTypeRef)(SwiftReflectionContextRef ContextRef,
|
|
swift_typeref_t OpaqueTypeRef,
|
|
unsigned Index);
|
|
|
|
swift_typeinfo_t (*infoForMetadata)(SwiftReflectionContextRef ContextRef,
|
|
uintptr_t Metadata);
|
|
|
|
swift_childinfo_t (*childOfMetadata)(SwiftReflectionContextRef ContextRef,
|
|
uintptr_t Metadata,
|
|
unsigned Index);
|
|
swift_typeinfo_t (*infoForInstance)(SwiftReflectionContextRef ContextRef,
|
|
uintptr_t Object);
|
|
|
|
swift_childinfo_t (*childOfInstance)(SwiftReflectionContextRef ContextRef,
|
|
uintptr_t Object,
|
|
unsigned Index);
|
|
|
|
unsigned (*genericArgumentCountOfTypeRef)(swift_typeref_t OpaqueTypeRef);
|
|
|
|
swift_typeref_t (*genericArgumentOfTypeRef)(swift_typeref_t OpaqueTypeRef,
|
|
unsigned Index);
|
|
|
|
int (*projectExistential)(SwiftReflectionContextRef ContextRef,
|
|
swift_addr_t ExistentialAddress,
|
|
swift_typeref_t ExistentialTypeRef,
|
|
swift_typeref_t *OutInstanceTypeRef,
|
|
swift_addr_t *OutStartOfInstanceData);
|
|
|
|
void (*dumpTypeRef)(swift_typeref_t OpaqueTypeRef);
|
|
|
|
void (*dumpInfoForTypeRef)(SwiftReflectionContextRef ContextRef,
|
|
swift_typeref_t OpaqueTypeRef);
|
|
|
|
void (*dumpInfoForMetadata)(SwiftReflectionContextRef ContextRef,
|
|
uintptr_t Metadata);
|
|
|
|
void (*dumpInfoForInstance)(SwiftReflectionContextRef ContextRef,
|
|
uintptr_t Object);
|
|
|
|
size_t (*demangle)(const char *MangledName,
|
|
size_t Length,
|
|
char *OutDemangledName,
|
|
size_t MaxLength);
|
|
};
|
|
|
|
struct SwiftReflectionInteropContextLibrary {
|
|
SwiftReflectionContextRef Context;
|
|
struct SwiftReflectionFunctions Functions;
|
|
int IsLegacy;
|
|
};
|
|
|
|
struct SwiftReflectionInteropContextFreeList {
|
|
struct SwiftReflectionInteropContextFreeList *Next;
|
|
const void *Pointer;
|
|
void *Context;
|
|
};
|
|
|
|
struct SwiftReflectionInteropContextLegacyImageRangeList {
|
|
struct SwiftReflectionInteropContextLegacyImageRangeList *Next;
|
|
swift_addr_t Start, End;
|
|
};
|
|
|
|
struct SwiftReflectionInteropContext {
|
|
void *ReaderContext;
|
|
QueryDataLayoutFunction DataLayout;
|
|
FreeBytesFunction FreeBytes;
|
|
ReadBytesFunction ReadBytes;
|
|
uint64_t (*GetStringLength)(void *reader_context,
|
|
swift_addr_t address);
|
|
swift_addr_t (*GetSymbolAddress)(void *reader_context,
|
|
const char *name,
|
|
uint64_t name_length);
|
|
|
|
struct SwiftReflectionInteropContextLibrary *Libraries;
|
|
int LibraryCount;
|
|
|
|
struct SwiftReflectionInteropContextFreeList *FreeList;
|
|
struct SwiftReflectionInteropContextLegacyImageRangeList *LegacyImageRangeList;
|
|
|
|
CFMutableDictionaryRef AddressToLibraryCache;
|
|
};
|
|
|
|
#define FOREACH_LIBRARY \
|
|
for (struct SwiftReflectionInteropContextLibrary *Library = &ContextRef->Libraries[0]; \
|
|
Library < &ContextRef->Libraries[ContextRef->LibraryCount]; \
|
|
++Library)
|
|
#define LIBRARY_INDEX (Library - ContextRef->Libraries)
|
|
#define DECLARE_LIBRARY(index) \
|
|
struct SwiftReflectionInteropContextLibrary *Library = &ContextRef->Libraries[index]
|
|
|
|
static inline int
|
|
swift_reflection_interop_libraryOwnsAddress(
|
|
struct SwiftReflectionInteropContext *ContextRef,
|
|
struct SwiftReflectionInteropContextLibrary *Library,
|
|
uintptr_t Address) {
|
|
if (!Library->IsLegacy)
|
|
return Library->Functions.ownsAddress(Library->Context, Address);
|
|
|
|
// Search the images list to see if the address is in one of them.
|
|
struct SwiftReflectionInteropContextLegacyImageRangeList *Node =
|
|
ContextRef->LegacyImageRangeList;
|
|
while (Node != nullptr) {
|
|
if (Node->Start <= Address && Address < Node->End)
|
|
return 1;
|
|
Node = Node->Next;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static inline struct SwiftReflectionInteropContextLibrary *
|
|
swift_reflection_interop_libraryForAddress(
|
|
struct SwiftReflectionInteropContext *ContextRef,
|
|
uintptr_t Address) {
|
|
uintptr_t cachedIndex;
|
|
if (CFDictionaryGetValueIfPresent(ContextRef->AddressToLibraryCache,
|
|
(void *)Address,
|
|
(const void **)&cachedIndex)) {
|
|
return &ContextRef->Libraries[cachedIndex];
|
|
}
|
|
|
|
FOREACH_LIBRARY {
|
|
if (swift_reflection_interop_libraryOwnsAddress(ContextRef, Library, Address)) {
|
|
CFDictionarySetValue(ContextRef->AddressToLibraryCache,
|
|
(void *)Address,
|
|
(void *)LIBRARY_INDEX);
|
|
return Library;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
static inline uintptr_t
|
|
swift_reflection_interop_metadataForObject(
|
|
struct SwiftReflectionInteropContext *ContextRef,
|
|
uintptr_t Object) {
|
|
FOREACH_LIBRARY {
|
|
if (Library->IsLegacy)
|
|
continue;
|
|
uintptr_t Metadata = Library->Functions.metadataForObject(Library->Context, Object);
|
|
if (Metadata != 0)
|
|
return Metadata;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static inline struct SwiftReflectionInteropContextLibrary *
|
|
swift_reflection_interop_libraryForObject(
|
|
struct SwiftReflectionInteropContext *ContextRef,
|
|
uintptr_t Object) {
|
|
uintptr_t Metadata = swift_reflection_interop_metadataForObject(ContextRef, Object);
|
|
if (Metadata == 0) {
|
|
// If we couldn't retrieve metadata, assume it belongs to a legacy library.
|
|
FOREACH_LIBRARY {
|
|
if (Library->IsLegacy)
|
|
return Library;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
return swift_reflection_interop_libraryForAddress(ContextRef, Metadata);
|
|
}
|
|
|
|
static inline int
|
|
swift_reflection_interop_loadFunctions(struct SwiftReflectionInteropContext *Context,
|
|
void *Handle) {
|
|
if (Handle == nullptr)
|
|
return 0;
|
|
|
|
struct SwiftReflectionInteropContextLibrary *Library = &Context
|
|
->Libraries[Context->LibraryCount];
|
|
struct SwiftReflectionFunctions *Functions = &Library->Functions;
|
|
|
|
#ifndef __cplusplus
|
|
#define decltype(x) void *
|
|
#endif
|
|
#define LOAD_NAMED(field, symbol, required) do { \
|
|
Functions->field = (decltype(Functions->field))dlsym(Handle, symbol); \
|
|
if (required && Functions->field == nullptr) return 0; \
|
|
} while (0)
|
|
#define LOAD(name) LOAD_NAMED(name, "swift_reflection_" #name, 1)
|
|
#define LOAD_OPT(name) LOAD_NAMED(name, "swift_reflection_" #name, 0)
|
|
|
|
Functions->classIsSwiftMaskPtr =
|
|
(unsigned long long *)dlsym(Handle, "swift_reflection_classIsSwiftMask");
|
|
LOAD(getSupportedMetadataVersion);
|
|
uint16_t version = Functions->getSupportedMetadataVersion();
|
|
if (version < SWIFT_LEGACY_METADATA_MIN_VERSION)
|
|
return 0;
|
|
|
|
int IsLegacy = dlsym(Handle, "swift_reflection_addImage") == nullptr;
|
|
|
|
if (IsLegacy) {
|
|
LOAD_NAMED(createReflectionContextLegacy, "swift_reflection_createReflectionContext", 1);
|
|
LOAD_NAMED(addReflectionInfoLegacy, "swift_reflection_addReflectionInfo", 1);
|
|
} else {
|
|
LOAD(createReflectionContext);
|
|
LOAD(addReflectionInfo);
|
|
LOAD(addImage);
|
|
LOAD(ownsObject);
|
|
LOAD(ownsAddress);
|
|
LOAD(metadataForObject);
|
|
|
|
// Optional creation function.
|
|
LOAD_OPT(createReflectionContextWithDataLayout);
|
|
}
|
|
|
|
LOAD(destroyReflectionContext);
|
|
LOAD(readIsaMask);
|
|
LOAD(typeRefForMetadata);
|
|
LOAD(typeRefForInstance);
|
|
LOAD(typeRefForMangledTypeName);
|
|
LOAD(infoForTypeRef);
|
|
LOAD(childOfTypeRef);
|
|
LOAD(infoForMetadata);
|
|
LOAD(childOfMetadata);
|
|
LOAD(infoForInstance);
|
|
LOAD(childOfInstance);
|
|
LOAD(genericArgumentCountOfTypeRef);
|
|
LOAD(genericArgumentOfTypeRef);
|
|
LOAD(projectExistential);
|
|
LOAD(dumpTypeRef);
|
|
LOAD(dumpInfoForTypeRef);
|
|
|
|
Library->IsLegacy = IsLegacy;
|
|
Context->LibraryCount++;
|
|
|
|
return 1;
|
|
|
|
#undef LOAD
|
|
#undef LOAD_NAMED
|
|
#ifndef __cplusplus
|
|
#undef decltype
|
|
#endif
|
|
}
|
|
|
|
static inline int
|
|
swift_reflection_interop_readBytesAdapter(void *reader_context,
|
|
swift_addr_t address,
|
|
void *dest,
|
|
uint64_t size) {
|
|
SwiftReflectionInteropContextRef Context =
|
|
(SwiftReflectionInteropContextRef)reader_context;
|
|
|
|
void *FreeContext;
|
|
const void *ptr = Context->ReadBytes(Context->ReaderContext, address, size,
|
|
&FreeContext);
|
|
if (ptr == nullptr)
|
|
return 0;
|
|
|
|
memcpy(dest, ptr, size);
|
|
if (Context->FreeBytes != nullptr)
|
|
Context->FreeBytes(Context->ReaderContext, ptr, FreeContext);
|
|
return 1;
|
|
}
|
|
|
|
static inline uint8_t
|
|
swift_reflection_interop_getSizeAdapter(void *reader_context) {
|
|
// Legacy library doesn't pay attention to these anyway.
|
|
(void)reader_context;
|
|
return sizeof(void *);
|
|
}
|
|
|
|
static inline uint64_t
|
|
swift_reflection_interop_GetStringLengthAdapter(
|
|
void *reader_context, swift_addr_t address) {
|
|
SwiftReflectionInteropContextRef Context =
|
|
(SwiftReflectionInteropContextRef)reader_context;
|
|
return Context->GetStringLength(Context->ReaderContext, address);
|
|
}
|
|
|
|
static inline swift_addr_t
|
|
swift_reflection_interop_GetSymbolAddressAdapter(
|
|
void *reader_context, const char *name, uint64_t name_length) {
|
|
SwiftReflectionInteropContextRef Context =
|
|
(SwiftReflectionInteropContextRef)reader_context;
|
|
return Context->GetSymbolAddress(Context->ReaderContext, name, name_length);
|
|
}
|
|
|
|
static inline int
|
|
swift_reflection_interop_minimalDataLayoutQueryFunction4(
|
|
void *ReaderContext,
|
|
DataLayoutQueryType type,
|
|
void *inBuffer, void *outBuffer) {
|
|
switch (type) {
|
|
case DLQ_GetPointerSize:
|
|
case DLQ_GetSizeSize: {
|
|
uint8_t *result = (uint8_t *)outBuffer;
|
|
*result = 4;
|
|
return 1;
|
|
}
|
|
case DLQ_GetObjCReservedLowBits: {
|
|
uint8_t *result = (uint8_t *)outBuffer;
|
|
// Swift assumes this for all 32-bit platforms, including Darwin
|
|
*result = 0;
|
|
return 1;
|
|
}
|
|
case DLQ_GetLeastValidPointerValue: {
|
|
uint64_t *result = (uint64_t *)outBuffer;
|
|
// Swift assumes this for all 32-bit platforms, including Darwin
|
|
*result = 0x1000;
|
|
return 1;
|
|
}
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
static inline int
|
|
swift_reflection_interop_minimalDataLayoutQueryFunction8(
|
|
void *ReaderContext,
|
|
DataLayoutQueryType type,
|
|
void *inBuffer, void *outBuffer) {
|
|
// Caveat: This assumes the process being examined is
|
|
// running in the same kind of environment as this host code.
|
|
#if defined(__APPLE__) && __APPLE__
|
|
auto applePlatform = true;
|
|
#else
|
|
auto applePlatform = false;
|
|
#endif
|
|
#if defined(__APPLE__) && __APPLE__ && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_IOS) && TARGET_OS_WATCH) || (defined(TARGET_OS_TV) && TARGET_OS_TV))
|
|
auto iosDerivedPlatform = true;
|
|
#else
|
|
auto iosDerivedPlatform = false;
|
|
#endif
|
|
|
|
switch (type) {
|
|
case DLQ_GetPointerSize:
|
|
case DLQ_GetSizeSize: {
|
|
uint8_t *result = (uint8_t *)outBuffer;
|
|
*result = 8;
|
|
return 1;
|
|
}
|
|
case DLQ_GetObjCReservedLowBits: {
|
|
uint8_t *result = (uint8_t *)outBuffer;
|
|
if (applePlatform && !iosDerivedPlatform) {
|
|
*result = 1;
|
|
} else {
|
|
*result = 0;
|
|
}
|
|
return 1;
|
|
}
|
|
case DLQ_GetLeastValidPointerValue: {
|
|
uint64_t *result = (uint64_t *)outBuffer;
|
|
if (applePlatform) {
|
|
// On 64-bit Apple platforms, Swift reserves the first 4GiB
|
|
*result = 0x100000000;
|
|
} else {
|
|
// Swift reserves the first 4KiB everywhere else.
|
|
*result = 0x1000;
|
|
}
|
|
return 1;
|
|
}
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
static inline SwiftReflectionInteropContextRef
|
|
swift_reflection_interop_createReflectionContext(
|
|
void *ReaderContext,
|
|
uint8_t PointerSize,
|
|
FreeBytesFunction FreeBytes,
|
|
ReadBytesFunction ReadBytes,
|
|
GetStringLengthFunction GetStringLength,
|
|
GetSymbolAddressFunction GetSymbolAddress) {
|
|
QueryDataLayoutFunction DataLayout;
|
|
if (PointerSize == 4)
|
|
DataLayout = swift_reflection_interop_minimalDataLayoutQueryFunction4;
|
|
else if (PointerSize == 8)
|
|
DataLayout = swift_reflection_interop_minimalDataLayoutQueryFunction8;
|
|
else
|
|
abort(); // Can't handle sizes other than 4 and 8.
|
|
|
|
return swift_reflection_interop_createReflectionContextWithDataLayout(
|
|
ReaderContext,
|
|
nullptr,
|
|
FreeBytes,
|
|
ReadBytes,
|
|
GetStringLength,
|
|
GetSymbolAddress);
|
|
}
|
|
|
|
static inline SwiftReflectionInteropContextRef
|
|
swift_reflection_interop_createReflectionContextWithDataLayout(
|
|
void *ReaderContext,
|
|
QueryDataLayoutFunction DataLayout,
|
|
FreeBytesFunction FreeBytes,
|
|
ReadBytesFunction ReadBytes,
|
|
GetStringLengthFunction GetStringLength,
|
|
GetSymbolAddressFunction GetSymbolAddress) {
|
|
|
|
SwiftReflectionInteropContextRef ContextRef =
|
|
(SwiftReflectionInteropContextRef)calloc(sizeof(*ContextRef), 1);
|
|
|
|
ContextRef->ReaderContext = ReaderContext;
|
|
ContextRef->DataLayout = DataLayout;
|
|
ContextRef->FreeBytes = FreeBytes;
|
|
ContextRef->ReadBytes = ReadBytes;
|
|
ContextRef->GetStringLength = GetStringLength;
|
|
ContextRef->GetSymbolAddress = GetSymbolAddress;
|
|
|
|
ContextRef->AddressToLibraryCache = CFDictionaryCreateMutable(nullptr, 0, nullptr, nullptr);
|
|
|
|
return ContextRef;
|
|
}
|
|
|
|
static inline int
|
|
swift_reflection_interop_addLibrary(
|
|
SwiftReflectionInteropContextRef ContextRef, void *LibraryHandle) {
|
|
size_t NewSize = (ContextRef->LibraryCount + 1) * sizeof(*ContextRef->Libraries);
|
|
ContextRef->Libraries = realloc(ContextRef->Libraries, NewSize);
|
|
int Success = swift_reflection_interop_loadFunctions(ContextRef, LibraryHandle);
|
|
if (Success) {
|
|
struct SwiftReflectionInteropContextLibrary *Library =
|
|
&ContextRef->Libraries[ContextRef->LibraryCount - 1];
|
|
if (Library->IsLegacy) {
|
|
Library->Context = Library->Functions.createReflectionContextLegacy(
|
|
ContextRef,
|
|
swift_reflection_interop_getSizeAdapter, swift_reflection_interop_getSizeAdapter,
|
|
swift_reflection_interop_readBytesAdapter,
|
|
swift_reflection_interop_GetStringLengthAdapter,
|
|
swift_reflection_interop_GetSymbolAddressAdapter);
|
|
} else if (Library->Functions.createReflectionContextWithDataLayout) {
|
|
Library->Context =
|
|
Library->Functions.createReflectionContextWithDataLayout(
|
|
ContextRef->ReaderContext,
|
|
ContextRef->DataLayout,
|
|
ContextRef->FreeBytes,
|
|
ContextRef->ReadBytes,
|
|
ContextRef->GetStringLength,
|
|
ContextRef->GetSymbolAddress);
|
|
} else {
|
|
uint8_t PointerSize;
|
|
int result = ContextRef->DataLayout(
|
|
ContextRef->ReaderContext, DLQ_GetPointerSize, nullptr, &PointerSize);
|
|
if (!result)
|
|
abort(); // We need the pointer size, can't proceed without it.
|
|
|
|
Library->Context = Library->Functions.createReflectionContext(
|
|
ContextRef->ReaderContext,
|
|
PointerSize,
|
|
ContextRef->FreeBytes,
|
|
ContextRef->ReadBytes,
|
|
ContextRef->GetStringLength,
|
|
ContextRef->GetSymbolAddress);
|
|
}
|
|
}
|
|
return Success;
|
|
}
|
|
|
|
static inline void
|
|
swift_reflection_interop_destroyReflectionContext(
|
|
SwiftReflectionInteropContextRef ContextRef) {
|
|
FOREACH_LIBRARY {
|
|
Library->Functions.destroyReflectionContext(Library->Context);
|
|
}
|
|
free(ContextRef->Libraries);
|
|
struct SwiftReflectionInteropContextLegacyImageRangeList *LegacyImageRangeList
|
|
= ContextRef->LegacyImageRangeList;
|
|
while (LegacyImageRangeList != nullptr) {
|
|
struct SwiftReflectionInteropContextLegacyImageRangeList *Next
|
|
= LegacyImageRangeList->Next;
|
|
free(LegacyImageRangeList);
|
|
LegacyImageRangeList = Next;
|
|
}
|
|
struct SwiftReflectionInteropContextFreeList *FreeList = ContextRef->FreeList;
|
|
while (FreeList != nullptr) {
|
|
ContextRef->FreeBytes(ContextRef->ReaderContext,
|
|
FreeList->Pointer, FreeList->Context);
|
|
struct SwiftReflectionInteropContextFreeList *Next = FreeList->Next;
|
|
free(FreeList);
|
|
FreeList = Next;
|
|
}
|
|
|
|
CFRelease(ContextRef->AddressToLibraryCache);
|
|
|
|
free(ContextRef);
|
|
}
|
|
|
|
static inline void
|
|
swift_reflection_interop_setClassIsSwiftMask(
|
|
SwiftReflectionInteropContextRef ContextRef, uint64_t mask) {
|
|
FOREACH_LIBRARY {
|
|
if (Library->Functions.classIsSwiftMaskPtr)
|
|
*Library->Functions.classIsSwiftMaskPtr = mask;
|
|
}
|
|
}
|
|
|
|
#ifndef __LP64__
|
|
typedef const struct mach_header MachHeader;
|
|
#else
|
|
typedef const struct mach_header_64 MachHeader;
|
|
#endif
|
|
|
|
static inline int
|
|
swift_reflection_interop_findSection(MachHeader *Header, const char *Name,
|
|
swift_reflection_section_t *Sect) {
|
|
unsigned long Size;
|
|
void *Address = getsectiondata(Header, "__TEXT", Name, &Size);
|
|
if (!Address)
|
|
return 0;
|
|
|
|
Sect->Begin = Address;
|
|
Sect->End = (void *)((uintptr_t)Address + Size);
|
|
return 1;
|
|
}
|
|
|
|
static inline int
|
|
swift_reflection_interop_addImageLegacy(
|
|
SwiftReflectionInteropContextRef ContextRef,
|
|
struct SwiftReflectionInteropContextLibrary *Library,
|
|
swift_addr_t ImageStart) {
|
|
void *FreeContext;
|
|
const void *Buf;
|
|
Buf = ContextRef->ReadBytes(ContextRef->ReaderContext,
|
|
ImageStart,
|
|
sizeof(MachHeader),
|
|
&FreeContext);
|
|
if (Buf == nullptr)
|
|
return 0;
|
|
|
|
MachHeader *Header = (MachHeader *)Buf;
|
|
|
|
if (Header->magic != MH_MAGIC && Header->magic != MH_MAGIC_64) {
|
|
if (ContextRef->FreeBytes != nullptr)
|
|
ContextRef->FreeBytes(ContextRef->ReaderContext, Buf, FreeContext);
|
|
return 0;
|
|
}
|
|
|
|
// Read the commands.
|
|
uint32_t Length = Header->sizeofcmds;
|
|
if (ContextRef->FreeBytes != nullptr)
|
|
ContextRef->FreeBytes(ContextRef->ReaderContext, Buf, FreeContext);
|
|
|
|
Buf = ContextRef->ReadBytes(ContextRef->ReaderContext,
|
|
ImageStart,
|
|
Length,
|
|
&FreeContext);
|
|
if (Buf == nullptr)
|
|
return 0;
|
|
Header = (MachHeader *)Buf;
|
|
|
|
// Find the TEXT segment and figure out where the end is.
|
|
unsigned long TextSize;
|
|
uint8_t *TextSegment = getsegmentdata(Header, "__TEXT", &TextSize);
|
|
if (ContextRef->FreeBytes != nullptr)
|
|
ContextRef->FreeBytes(ContextRef->ReaderContext, Buf, FreeContext);
|
|
|
|
if (TextSegment == nullptr) {
|
|
return 0;
|
|
}
|
|
unsigned long TextEnd = TextSegment - (uint8_t *)Buf + TextSize;
|
|
|
|
// Read everything including the TEXT segment.
|
|
Buf = ContextRef->ReadBytes(ContextRef->ReaderContext,
|
|
ImageStart,
|
|
TextEnd,
|
|
&FreeContext);
|
|
if (Buf == nullptr)
|
|
return 0;
|
|
Header = (MachHeader *)Buf;
|
|
|
|
// Find all the sections and fill out the reflection info.
|
|
swift_reflection_legacy_info_t info = {};
|
|
|
|
int success = 0;
|
|
success = swift_reflection_interop_findSection(Header,
|
|
"__swift3_fieldmd",
|
|
&info.fieldmd) || success;
|
|
success = swift_reflection_interop_findSection(Header,
|
|
"__swift3_assocty",
|
|
&info.assocty) || success;
|
|
success = swift_reflection_interop_findSection(Header,
|
|
"__swift3_builtin",
|
|
&info.builtin) || success;
|
|
success = swift_reflection_interop_findSection(Header,
|
|
"__swift3_capture",
|
|
&info.capture) || success;
|
|
success = swift_reflection_interop_findSection(Header,
|
|
"__swift3_typeref",
|
|
&info.typeref) || success;
|
|
success = swift_reflection_interop_findSection(Header,
|
|
"__swift3_reflstr",
|
|
&info.reflstr) || success;
|
|
|
|
if (!success) {
|
|
if (ContextRef->FreeBytes != nullptr)
|
|
ContextRef->FreeBytes(ContextRef->ReaderContext, Buf, FreeContext);
|
|
return 0;
|
|
}
|
|
|
|
info.LocalStartAddress = (uintptr_t)Buf;
|
|
info.RemoteStartAddress = (uintptr_t)ImageStart;
|
|
|
|
Library->Functions.addReflectionInfoLegacy(Library->Context, info);
|
|
|
|
// Find the data segment and add it to our list.
|
|
unsigned long DataSize;
|
|
const uint8_t *DataSegment = getsegmentdata(Header, "__DATA", &DataSize);
|
|
uintptr_t DataSegmentStart = (uintptr_t)(DataSegment - (const uint8_t *)Buf + ImageStart);
|
|
|
|
struct SwiftReflectionInteropContextLegacyImageRangeList *Node =
|
|
(struct SwiftReflectionInteropContextLegacyImageRangeList *)malloc(sizeof(*Node));
|
|
Node->Next = ContextRef->LegacyImageRangeList;
|
|
Node->Start = ImageStart;
|
|
Node->End = DataSegmentStart + DataSize;
|
|
ContextRef->LegacyImageRangeList = Node;
|
|
|
|
// If the buffer needs to be freed, save buffer and free context to free it when the
|
|
// reflection context is destroyed.
|
|
if (ContextRef->FreeBytes != nullptr) {
|
|
struct SwiftReflectionInteropContextFreeList *FreeListNode =
|
|
(struct SwiftReflectionInteropContextFreeList *)malloc(sizeof(*FreeListNode));
|
|
FreeListNode->Next = ContextRef->FreeList;
|
|
FreeListNode->Pointer = Buf;
|
|
FreeListNode->Context = FreeContext;
|
|
ContextRef->FreeList = FreeListNode;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static inline int
|
|
swift_reflection_interop_addImage(SwiftReflectionInteropContextRef ContextRef,
|
|
swift_addr_t imageStart) {
|
|
FOREACH_LIBRARY {
|
|
int Success;
|
|
if (Library->IsLegacy) {
|
|
Success = swift_reflection_interop_addImageLegacy(ContextRef,
|
|
Library,
|
|
imageStart);
|
|
} else {
|
|
Success = Library->Functions.addImage(Library->Context, imageStart);
|
|
}
|
|
if (Success) {
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static inline int
|
|
swift_reflection_interop_readIsaMask(SwiftReflectionInteropContextRef ContextRef,
|
|
uintptr_t *outIsaMask) {
|
|
FOREACH_LIBRARY {
|
|
int Success = Library->Functions.readIsaMask(Library->Context, outIsaMask);
|
|
if (Success)
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static inline swift_metadata_interop_t
|
|
swift_reflection_interop_lookupMetadata(SwiftReflectionInteropContextRef ContextRef,
|
|
uintptr_t Metadata) {
|
|
swift_metadata_interop_t Result = {};
|
|
struct SwiftReflectionInteropContextLibrary *Library =
|
|
swift_reflection_interop_libraryForAddress(ContextRef, Metadata);
|
|
if (Library != nullptr) {
|
|
Result.Metadata = Metadata;
|
|
Result.Library = (int)LIBRARY_INDEX;
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
static inline swift_typeref_interop_t
|
|
swift_reflection_interop_typeRefForMetadata(SwiftReflectionInteropContextRef ContextRef,
|
|
swift_metadata_interop_t Metadata) {
|
|
DECLARE_LIBRARY(Metadata.Library);
|
|
swift_typeref_interop_t Result;
|
|
Result.Typeref = Library->Functions.
|
|
typeRefForMetadata(Library->Context, Metadata.Metadata);
|
|
Result.Library = Metadata.Library;
|
|
return Result;
|
|
}
|
|
|
|
static inline swift_typeref_interop_t
|
|
swift_reflection_interop_typeRefForInstance(SwiftReflectionInteropContextRef ContextRef,
|
|
uintptr_t Object) {
|
|
swift_typeref_interop_t Result = {};
|
|
struct SwiftReflectionInteropContextLibrary *Library
|
|
= swift_reflection_interop_libraryForObject(ContextRef, Object);
|
|
if (Library != nullptr) {
|
|
swift_typeref_t Typeref = Library->Functions.typeRefForInstance(Library->Context,
|
|
Object);
|
|
Result.Typeref = Typeref;
|
|
Result.Library = (int)LIBRARY_INDEX;
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
static inline swift_typeref_interop_t
|
|
swift_reflection_interop_typeRefForMangledTypeName(
|
|
SwiftReflectionInteropContextRef ContextRef,
|
|
const char *MangledName,
|
|
uint64_t Length) {
|
|
swift_typeref_interop_t Result;
|
|
FOREACH_LIBRARY {
|
|
swift_typeref_t Typeref = Library->Functions.typeRefForMangledTypeName(
|
|
Library->Context, MangledName, Length);
|
|
if (Typeref == 0)
|
|
continue;
|
|
|
|
Result.Typeref = Typeref;
|
|
Result.Library = (int)LIBRARY_INDEX;
|
|
return Result;
|
|
}
|
|
|
|
Result.Typeref = 0;
|
|
Result.Library = 0;
|
|
return Result;
|
|
}
|
|
|
|
static inline swift_typeinfo_t
|
|
swift_reflection_interop_infoForTypeRef(SwiftReflectionInteropContextRef ContextRef,
|
|
swift_typeref_interop_t OpaqueTypeRef) {
|
|
DECLARE_LIBRARY(OpaqueTypeRef.Library);
|
|
return Library->Functions.infoForTypeRef(Library->Context, OpaqueTypeRef.Typeref);
|
|
}
|
|
|
|
static inline swift_childinfo_interop_t
|
|
swift_reflection_interop_childOfTypeRef(SwiftReflectionInteropContextRef ContextRef,
|
|
swift_typeref_interop_t OpaqueTypeRef,
|
|
unsigned Index) {
|
|
DECLARE_LIBRARY(OpaqueTypeRef.Library);
|
|
swift_childinfo_t LibResult = Library->Functions.childOfTypeRef(Library->Context,
|
|
OpaqueTypeRef.Typeref,
|
|
Index);
|
|
swift_childinfo_interop_t Result;
|
|
Result.Name = LibResult.Name;
|
|
Result.Offset = LibResult.Offset;
|
|
Result.Kind = LibResult.Kind;
|
|
Result.TR.Typeref = LibResult.TR;
|
|
Result.TR.Library = OpaqueTypeRef.Library;
|
|
return Result;
|
|
}
|
|
|
|
static inline swift_typeinfo_interop_t
|
|
swift_reflection_interop_infoForMetadata(SwiftReflectionInteropContextRef ContextRef,
|
|
swift_metadata_interop_t Metadata) {
|
|
DECLARE_LIBRARY(Metadata.Library);
|
|
return Library->Functions.infoForMetadata(Library->Context, Metadata.Metadata);
|
|
}
|
|
|
|
static inline swift_childinfo_interop_t
|
|
swift_reflection_interop_childOfMetadata(SwiftReflectionInteropContextRef ContextRef,
|
|
swift_metadata_interop_t Metadata,
|
|
unsigned Index) {
|
|
DECLARE_LIBRARY(Metadata.Library);
|
|
swift_childinfo_t LibResult = Library->Functions.childOfMetadata(Library->Context,
|
|
Metadata.Metadata,
|
|
Index);
|
|
swift_childinfo_interop_t Result;
|
|
Result.Name = LibResult.Name;
|
|
Result.Offset = LibResult.Offset;
|
|
Result.Kind = LibResult.Kind;
|
|
Result.TR.Typeref = LibResult.TR;
|
|
Result.TR.Library = Metadata.Library;
|
|
return Result;
|
|
}
|
|
|
|
static inline swift_typeinfo_interop_t
|
|
swift_reflection_interop_infoForInstance(SwiftReflectionInteropContextRef ContextRef,
|
|
uintptr_t Object) {
|
|
swift_typeinfo_t Result = {};
|
|
struct SwiftReflectionInteropContextLibrary *Library
|
|
= swift_reflection_interop_libraryForObject(ContextRef, Object);
|
|
|
|
if (Library != nullptr) {
|
|
Result = Library->Functions.infoForInstance(Library->Context, Object);
|
|
} else {
|
|
Result.Kind = SWIFT_UNKNOWN;
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
static inline swift_childinfo_interop_t
|
|
swift_reflection_interop_childOfInstance(SwiftReflectionInteropContextRef ContextRef,
|
|
uintptr_t Object,
|
|
unsigned Index) {
|
|
swift_childinfo_interop_t Result = {};
|
|
struct SwiftReflectionInteropContextLibrary *Library
|
|
= swift_reflection_interop_libraryForObject(ContextRef, Object);
|
|
if (Library != nullptr) {
|
|
swift_childinfo_t LibResult = Library->Functions.childOfInstance(Library->Context,
|
|
Object, Index);
|
|
Result.Name = LibResult.Name;
|
|
Result.Offset = LibResult.Offset;
|
|
Result.Kind = LibResult.Kind;
|
|
Result.TR.Typeref = LibResult.TR;
|
|
Result.TR.Library = (int)LIBRARY_INDEX;
|
|
} else {
|
|
Result.Kind = SWIFT_UNKNOWN;
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
static inline unsigned
|
|
swift_reflection_interop_genericArgumentCountOfTypeRef(
|
|
SwiftReflectionInteropContextRef ContextRef, swift_typeref_interop_t OpaqueTypeRef) {
|
|
DECLARE_LIBRARY(OpaqueTypeRef.Library);
|
|
return Library->Functions.genericArgumentCountOfTypeRef(OpaqueTypeRef.Typeref);
|
|
}
|
|
|
|
static inline swift_typeref_interop_t
|
|
swift_reflection_interop_genericArgumentOfTypeRef(
|
|
SwiftReflectionInteropContextRef ContextRef, swift_typeref_interop_t OpaqueTypeRef,
|
|
unsigned Index) {
|
|
DECLARE_LIBRARY(OpaqueTypeRef.Library);
|
|
swift_typeref_interop_t Result;
|
|
Result.Typeref = Library->Functions.genericArgumentOfTypeRef(OpaqueTypeRef.Typeref,
|
|
Index);
|
|
Result.Library = OpaqueTypeRef.Library;
|
|
return Result;
|
|
}
|
|
|
|
static inline int
|
|
swift_reflection_interop_projectExistential(SwiftReflectionInteropContextRef ContextRef,
|
|
swift_addr_t ExistentialAddress,
|
|
swift_typeref_interop_t ExistentialTypeRef,
|
|
swift_typeref_interop_t *OutInstanceTypeRef,
|
|
swift_addr_t *OutStartOfInstanceData) {
|
|
DECLARE_LIBRARY(ExistentialTypeRef.Library);
|
|
int Success = Library->Functions.projectExistential(Library->Context,
|
|
ExistentialAddress,
|
|
ExistentialTypeRef.Typeref,
|
|
&OutInstanceTypeRef->Typeref,
|
|
OutStartOfInstanceData);
|
|
if (!Success)
|
|
return 0;
|
|
|
|
OutInstanceTypeRef->Library = ExistentialTypeRef.Library;
|
|
return 1;
|
|
}
|
|
|
|
static inline void
|
|
swift_reflection_interop_dumpTypeRef(SwiftReflectionInteropContextRef ContextRef,
|
|
swift_typeref_interop_t OpaqueTypeRef) {
|
|
DECLARE_LIBRARY(OpaqueTypeRef.Library);
|
|
Library->Functions.dumpTypeRef(OpaqueTypeRef.Typeref);
|
|
}
|
|
|
|
static inline void
|
|
swift_reflection_interop_dumpInfoForTypeRef(SwiftReflectionInteropContextRef ContextRef,
|
|
swift_typeref_interop_t OpaqueTypeRef) {
|
|
DECLARE_LIBRARY(OpaqueTypeRef.Library);
|
|
Library->Functions.dumpInfoForTypeRef(Library->Context, OpaqueTypeRef.Typeref);
|
|
}
|
|
|
|
static inline void
|
|
swift_reflection_interop_dumpInfoForMetadata(SwiftReflectionInteropContextRef ContextRef,
|
|
swift_metadata_interop_t Metadata) {
|
|
DECLARE_LIBRARY(Metadata.Library);
|
|
Library->Functions.dumpInfoForMetadata(Library->Context, Metadata.Metadata);
|
|
}
|
|
|
|
static inline void
|
|
swift_reflection_interop_dumpInfoForInstance(SwiftReflectionInteropContextRef ContextRef,
|
|
uintptr_t Object) {
|
|
struct SwiftReflectionInteropContextLibrary *Library
|
|
= swift_reflection_interop_libraryForObject(ContextRef, Object);
|
|
if (Library != nullptr) {
|
|
Library->Functions.dumpInfoForInstance(Library->Context, Object);
|
|
}
|
|
}
|
|
|
|
static inline size_t
|
|
swift_reflection_interop_demangle(SwiftReflectionInteropContextRef ContextRef,
|
|
const char *MangledName,
|
|
size_t Length,
|
|
char *OutDemangledName,
|
|
size_t MaxLength) {
|
|
FOREACH_LIBRARY {
|
|
return Library->Functions.demangle(MangledName, Length, OutDemangledName, MaxLength);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#undef FOREACH_LIBRARY
|
|
#undef LIBRARY_INDEX
|
|
#undef DECLARE_LIBRARY
|
|
|
|
/// @}
|
|
|
|
#endif // defined(__APPLE__) && defined(__MACH__)
|
|
|
|
#endif // SWIFT_REMOTE_MIRROR_LEGACY_INTEROP_H
|
|
|