mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
139 lines
4.6 KiB
Objective-C
139 lines
4.6 KiB
Objective-C
//===--- test.m - SwiftRemoteMirrorLegacyInterop test program. ------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2018 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 is a test program that exercises the SwiftRemoteMirrorLegacyInterop header.
|
|
///
|
|
//===----------------------------------------------------------------------------===//
|
|
|
|
#import <dlfcn.h>
|
|
#import <Foundation/Foundation.h>
|
|
#import <mach/mach.h>
|
|
#import <mach-o/dyld.h>
|
|
|
|
#import "SwiftRemoteMirrorLegacyInterop.h"
|
|
|
|
|
|
void *Load(char *path) {
|
|
void *Handle = dlopen(path, RTLD_LOCAL);
|
|
if (Handle == NULL) {
|
|
fprintf(stderr, "loading %s: %s\n", path, dlerror());
|
|
exit(1);
|
|
}
|
|
return Handle;
|
|
}
|
|
|
|
void Free(void *reader_context, const void *bytes, void *context) {
|
|
assert(reader_context == (void *)0xdeadbeef);
|
|
assert(context == (void *)0xfeedface);
|
|
free((void *)bytes);
|
|
}
|
|
|
|
const void *ReadBytes(void *context, swift_addr_t address, uint64_t size,
|
|
void **outFreeContext) {
|
|
assert(context == (void *)0xdeadbeef);
|
|
*outFreeContext = (void *)0xfeedface;
|
|
|
|
void *Buffer = malloc(size);
|
|
vm_size_t InOutSize = size;
|
|
kern_return_t result = vm_read_overwrite(mach_task_self(), address, size, (vm_address_t)Buffer, &InOutSize);
|
|
if (result != KERN_SUCCESS) abort();
|
|
if (InOutSize != size) abort();
|
|
return Buffer;
|
|
}
|
|
|
|
uint64_t GetStringLength(void *context, swift_addr_t address) {
|
|
assert(context == (void *)0xdeadbeef);
|
|
return strlen((char *)address);
|
|
}
|
|
|
|
swift_addr_t GetSymbolAddress(void *context, const char *name, uint64_t name_length) {
|
|
assert(context == (void *)0xdeadbeef);
|
|
return (swift_addr_t)dlsym(RTLD_DEFAULT, name);
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
if (argc != 4) {
|
|
fprintf(stderr, "usage: %s <libtestswift.dylib> <libswiftRemoteMirror4.dylib> "
|
|
"<libswiftRemoteMirror5.dylib>\n",
|
|
argv[0]);
|
|
exit(1);
|
|
}
|
|
|
|
char *TestLibPath = argv[1];
|
|
char *Mirror4Path = argv[2];
|
|
char *Mirror5Path = argv[3];
|
|
|
|
void *TestHandle = Load(TestLibPath);
|
|
intptr_t (*Test)(void) = dlsym(TestHandle, "test");
|
|
|
|
uintptr_t Obj = Test();
|
|
|
|
void *Mirror4Handle = Mirror4Path[0] == '-' ? NULL : Load(Mirror4Path);
|
|
void *Mirror5Handle = Mirror5Path[0] == '-' ? NULL : Load(Mirror5Path);
|
|
SwiftReflectionInteropContextRef Context =
|
|
swift_reflection_interop_createReflectionContext(
|
|
(void *)0xdeadbeef,
|
|
Mirror5Handle,
|
|
Mirror4Handle,
|
|
sizeof(void *),
|
|
Free,
|
|
ReadBytes,
|
|
GetStringLength,
|
|
GetSymbolAddress);
|
|
if (Context == NULL) {
|
|
fprintf(stderr, "Unable to create a reflection context!\n");
|
|
exit(1);
|
|
}
|
|
|
|
uint32_t ImageCount = _dyld_image_count();
|
|
for (uint32_t i = 0; i < ImageCount; i++) {
|
|
swift_addr_t Image = (swift_addr_t)_dyld_get_image_header(i);
|
|
swift_reflection_interop_addImage(Context, Image);
|
|
}
|
|
|
|
swift_typeref_interop_t Type = swift_reflection_interop_typeRefForInstance(Context, Obj);
|
|
if (Type.Typeref != 0) {
|
|
swift_typeinfo_t TypeInfo = swift_reflection_interop_infoForTypeRef(Context, Type);
|
|
printf("Kind:%u Size:%u Alignment:%u Stride:%u NumFields:%u\n",
|
|
TypeInfo.Kind, TypeInfo.Size, TypeInfo.Alignment, TypeInfo.Stride,
|
|
TypeInfo.NumFields);
|
|
} else {
|
|
printf("Unknown typeref!\n");
|
|
}
|
|
|
|
uintptr_t Metadata = *(uintptr_t *)Obj;
|
|
swift_metadata_interop_t LookedUp =
|
|
swift_reflection_interop_lookupMetadata(Context, Metadata);
|
|
printf("Original metadata: %p\n", (void *)Metadata);
|
|
printf("Looked up metadata: Metadata=%p Library=%d\n",
|
|
(void *)LookedUp.Metadata, LookedUp.Library);
|
|
|
|
swift_typeinfo_t TypeInfo = swift_reflection_interop_infoForInstance(Context, Obj);
|
|
if (TypeInfo.Kind != SWIFT_UNKNOWN) {
|
|
printf("Kind:%u Size:%u Alignment:%u Stride:%u NumFields:%u\n",
|
|
TypeInfo.Kind, TypeInfo.Size, TypeInfo.Alignment, TypeInfo.Stride,
|
|
TypeInfo.NumFields);
|
|
|
|
for (unsigned i = 0; i < TypeInfo.NumFields; ++i) {
|
|
swift_childinfo_interop_t ChildInfo = swift_reflection_interop_childOfInstance(
|
|
Context, Obj, i);
|
|
printf(" [%u]: %s Offset:%u Kind:%u\n", i,
|
|
ChildInfo.Name, ChildInfo.Offset, ChildInfo.Kind);
|
|
}
|
|
} else {
|
|
printf("Unknown typeinfo!\n");
|
|
}
|
|
|
|
swift_reflection_interop_destroyReflectionContext(Context);
|
|
}
|