Split swift-refleciton-test into host and target test targets

swift-reflection-test is now the test that forks a swift executable
and performs remote reflection, making it runnable on other targets,
such as the iOS simulator.

swift-reflection-dump is now a host-side tool that dumps the remote
reflection sections for any platform binary and will continue to
link in LLVM object file support.

This necessitates finally moving lib/Refleciton into stdlib/public,
since we're linking target-specific versions of the test tool and
we would eventually like to adopt some of this functionality in
the runtime anyway.
This commit is contained in:
David Farler
2016-03-28 12:24:41 -07:00
parent 884155c09c
commit 5ea5bb06a3
21 changed files with 300 additions and 248 deletions

View File

@@ -699,6 +699,12 @@ if(SWIFT_BUILD_TOOLS)
endif()
add_subdirectory(utils)
add_subdirectory(stdlib)
if(SWIFT_BUILD_TOOLS)
add_subdirectory(tools/swift-reflection-test)
add_subdirectory(tools/swift-reflection-dump)
endif()
if(SWIFT_BUILD_PERF_TESTSUITE AND "${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
add_subdirectory(benchmark)
endif()

View File

@@ -1847,7 +1847,7 @@ endfunction()
function(add_swift_target_executable name)
# Parse the arguments we were given.
cmake_parse_arguments(SWIFTEXE_TARGET
"EXCLUDE_FROM_ALL;DONT_STRIP_NON_MAIN_SYMBOLS;DISABLE_ASLR"
"EXCLUDE_FROM_ALL;DONT_STRIP_NON_MAIN_SYMBOLS;DISABLE_ASLR;BUILD_WITH_STDLIB"
""
"DEPENDS;COMPONENT_DEPENDS;LINK_FAT_LIBRARIES"
${ARGN})
@@ -1887,6 +1887,10 @@ function(add_swift_target_executable name)
set(SWIFTEXE_TARGET_EXCLUDE_FROM_ALL_FLAG_CURRENT "EXCLUDE_FROM_ALL")
endif()
if(SWIFTEXE_TARGET_BUILD_WITH_STDLIB)
add_dependencies("swift-test-stdlib${VARIANT_SUFFIX}" ${VARIANT_NAME})
endif()
# Don't add the ${arch} to the suffix. We want to link against fat
# libraries.
_list_add_string_suffix(

View File

@@ -22,6 +22,7 @@
#include <dlfcn.h>
#include <cstdint>
#include <cstring>
#include <memory>
#include <vector>

View File

@@ -12,7 +12,6 @@ add_subdirectory(Markup)
add_subdirectory(Option)
add_subdirectory(Parse)
add_subdirectory(PrintAsObjC)
add_subdirectory(Reflection)
add_subdirectory(Sema)
add_subdirectory(Serialization)
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")

View File

@@ -1,3 +0,0 @@
add_swift_library(swiftReflection
TypeRef.cpp
LINK_LIBRARIES swiftBasic)

View File

@@ -187,8 +187,8 @@ internal func sendReflectionInfos() {
for info in infos {
debugLog("Sending info for \(info.imageName)")
let imageNameBytes = Array(info.imageName.utf8)
var imageNameLength = UInt64(imageNameBytes.count)
fwrite(&imageNameLength, sizeof(UInt64.self), 1, stdout)
var imageNameLength = UInt(imageNameBytes.count)
fwrite(&imageNameLength, sizeof(UInt.self), 1, stdout)
fflush(stdout)
fwrite(imageNameBytes, 1, imageNameBytes.count, stdout)
fflush(stdout)
@@ -235,7 +235,7 @@ internal func sendSymbolAddress() {
name.withCString {
let handle = unsafeBitCast(Int(-2), to: UnsafeMutablePointer<Void>.self)
let symbol = dlsym(handle, $0)
let symbolAddress = unsafeBitCast(symbol, to: UInt64.self)
let symbolAddress = unsafeBitCast(symbol, to: UInt.self)
sendValue(symbolAddress)
}
}

View File

@@ -32,6 +32,7 @@ if(SWIFT_BUILD_STDLIB)
add_subdirectory(core)
add_subdirectory(SwiftOnoneSupport)
add_subdirectory(Platform)
add_subdirectory(Reflection)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")

View File

@@ -0,0 +1,5 @@
add_swift_library(swiftReflection IS_STDLIB
Demangle.cpp
Remangle.cpp
TypeRef.cpp
INSTALL_IN_COMPONENT stdlib)

View File

@@ -0,0 +1,3 @@
#include "../../../lib/Basic/Demangle.cpp"
#include "../../../lib/Basic/Punycode.cpp"
#include "../../../lib/Basic/PunycodeUTF8.cpp"

View File

@@ -0,0 +1 @@
#include "../../../lib/Basic/Remangle.cpp"

View File

@@ -18,7 +18,6 @@
#include "swift/Basic/Demangle.h"
#include "swift/Reflection/ReflectionContext.h"
#include "swift/Reflection/TypeRef.h"
#include "llvm/Support/ErrorHandling.h"
using namespace swift;
using namespace reflection;
@@ -396,7 +395,7 @@ static unsigned _getDepth(TypeRef *TR) {
break;
}
default:
llvm_unreachable("Unexpected type ref kind asked for parent type");
assert(false && "Asked for depth on non-nominal typeref");
}
}

View File

@@ -1,5 +1,5 @@
// UNSUPPORTED: objc_interop
// RUN: rm -rf %t && mkdir -p %t
// RUN: %target-swiftc_driver %S/Inputs/ConcreteTypes.swift %S/Inputs/GenericTypes.swift %S/Inputs/Protocols.swift -emit-module -emit-library -module-name TypesToReflect -Xfrontend -enable-reflection-metadata -o %t/libTypesToReflect
// RUN: %target-swift-reflection-test -binary-filename %t/libTypesToReflect -dump-reflection-sections > %t/typeref_decoding.txt
// RUN: %target-swift-reflection-dump -binary-filename %t/libTypesToReflect > %t/typeref_decoding.txt
// RUN: diff -u %S/typeref_decoding.result.txt %t/typeref_decoding.txt

View File

@@ -1,5 +1,5 @@
// RUN: rm -rf %t && mkdir -p %t
// RUN: %target-swiftc_driver %S/Inputs/ConcreteTypes.swift %S/Inputs/GenericTypes.swift %S/Inputs/Protocols.swift -emit-module -emit-library -module-name TypesToReflect -Xfrontend -enable-reflection-metadata -o %t/libTypesToReflect
// RUN: %target-swift-reflection-test -binary-filename %t/libTypesToReflect -dump-reflection-sections > %t/typeref_decoding.txt
// RUN: %target-swift-reflection-dump -binary-filename %t/libTypesToReflect > %t/typeref_decoding.txt
// RUN: diff -u %S/typeref_decoding_objc.result.txt %t/typeref_decoding.txt
// REQUIRES: objc_interop

View File

@@ -272,6 +272,7 @@ config.sil_extract = inferSwiftBinary('sil-extract')
config.lldb_moduleimport_test = inferSwiftBinary('lldb-moduleimport-test')
config.swift_ide_test = inferSwiftBinary('swift-ide-test')
config.swift_reflection_test = inferSwiftBinary('swift-reflection-test')
config.swift_reflection_dump = inferSwiftBinary('swift-reflection-dump')
config.clang = inferSwiftBinary('clang')
config.llvm_link = inferSwiftBinary('llvm-link')
config.swift_llvm_opt = inferSwiftBinary('swift-llvm-opt')
@@ -840,7 +841,8 @@ config.substitutions.append(
(subst_target_swift_ide_test_mock_sdk,
subst_target_swift_ide_test_mock_sdk_after)))
config.substitutions.append(('%target-swift-ide-test', config.target_swift_ide_test))
config.substitutions.append(('%target-swift-reflection-test', '{} {} {}'.format(config.swift_reflection_test, '-arch', run_cpu)))
config.substitutions.append(('%target-swift-reflection-test', '{test_runner}{variant_suffix} {arch}'.format(test_runner=config.swift_reflection_test, variant_suffix=config.variant_suffix, arch=run_cpu)))
config.substitutions.append(('%target-swift-reflection-dump', '{} {} {}'.format(config.swift_reflection_dump, '-arch', run_cpu)))
config.substitutions.append(('%target-swiftc_driver', config.target_swiftc_driver))
if hasattr(config, 'target_swift_autolink_extract'):

View File

@@ -15,6 +15,7 @@ config.target_triple = "@TARGET_TRIPLE@"
config.targets_to_build = "@TARGETS_TO_BUILD@"
config.variant_triple = "@VARIANT_TRIPLE@"
config.variant_sdk = "@VARIANT_SDK@"
config.variant_suffix = "@VARIANT_SUFFIX@"
config.swiftlib_dir = "@LIT_SWIFTLIB_DIR@"
config.darwin_xcrun_toolchain = "@SWIFT_DARWIN_XCRUN_TOOLCHAIN@"

View File

@@ -5,7 +5,6 @@ add_subdirectory(swift-demangle)
add_subdirectory(lldb-moduleimport-test)
add_subdirectory(sil-extract)
add_subdirectory(swift-llvm-opt)
add_subdirectory(swift-reflection-test)
if(SWIFT_BUILD_SOURCEKIT)
add_subdirectory(SourceKit)

View File

@@ -0,0 +1,11 @@
add_swift_executable(swift-reflection-dump
swift-reflection-dump.cpp
LINK_FAT_LIBRARIES
swiftReflection
COMPONENT_DEPENDS object support
)
swift_install_in_component(tools
TARGETS swift-reflection-dump
RUNTIME DESTINATION bin)

View File

@@ -0,0 +1,202 @@
//===--- swift-reflection-test.cpp - Reflection testing application -------===//
//
// 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 is a host-side tool to dump remote reflection sections in swift
// binaries.
//===----------------------------------------------------------------------===//
#include "swift/ABI/MetadataValues.h"
#include "swift/Basic/Demangle.h"
#include "swift/Basic/LLVMInitialize.h"
#include "swift/Reflection/ReflectionContext.h"
#include "swift/Reflection/TypeRef.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/CommandLine.h"
#include <unistd.h>
#include <algorithm>
#include <iostream>
#include <csignal>
using llvm::dyn_cast;
using llvm::StringRef;
using llvm::ArrayRef;
using namespace llvm::object;
using namespace swift;
using namespace reflection;
using namespace Demangle;
enum class ActionType {
None,
DumpReflectionSections,
DumpHeapInstance
};
namespace options {
static llvm::cl::opt<ActionType>
Action(llvm::cl::desc("Mode:"),
llvm::cl::values(
clEnumValN(ActionType::DumpReflectionSections,
"dump-reflection-sections",
"Dump the field reflection section"),
clEnumValN(ActionType::DumpHeapInstance,
"dump-heap-instance",
"Dump the field layout for a heap instance by running "
"a Swift executable"),
clEnumValEnd));
static llvm::cl::opt<std::string>
BinaryFilename("binary-filename", llvm::cl::desc("Filename of the binary file"),
llvm::cl::Required);
static llvm::cl::opt<std::string>
Architecture("arch", llvm::cl::desc("Architecture to inspect in the binary"),
llvm::cl::Required);
} // end namespace options
static void guardError(std::error_code error) {
if (!error) return;
std::cerr << "swift-reflection-test error: " << error.message() << "\n";
exit(EXIT_FAILURE);
}
static llvm::object::SectionRef
getSectionRef(const ObjectFile *objectFile,
ArrayRef<StringRef> anySectionNames) {
for (auto section : objectFile->sections()) {
StringRef sectionName;
section.getName(sectionName);
for (auto desiredName : anySectionNames) {
if (sectionName.equals(desiredName)) {
return section;
}
}
}
return llvm::object::SectionRef();
}
static llvm::object::SectionRef
getSectionRef(const Binary *binaryFile, StringRef arch,
ArrayRef<StringRef> anySectionNames) {
if (auto objectFile = dyn_cast<ObjectFile>(binaryFile))
return getSectionRef(objectFile, anySectionNames);
if (auto machoUniversal = dyn_cast<MachOUniversalBinary>(binaryFile)) {
const auto objectOrError = machoUniversal->getObjectForArch(arch);
guardError(objectOrError.getError());
return getSectionRef(objectOrError.get().get(), anySectionNames);
}
return SectionRef();
}
static int doDumpReflectionSections(std::string BinaryFilename,
StringRef arch) {
auto binaryOrError = llvm::object::createBinary(BinaryFilename);
guardError(binaryOrError.getError());
const auto binary = binaryOrError.get().getBinary();
auto FieldSectionRef = getSectionRef(binary, arch, {
"__swift3_fieldmd", ".swift3_fieldmd"
});
if (FieldSectionRef.getObject() == nullptr) {
std::cerr << BinaryFilename;
std::cerr << " doesn't have a field reflection section!\n";
return EXIT_FAILURE;
}
auto AssociatedTypeSectionRef = getSectionRef(binary, arch, {
"__swift3_assocty", ".swift3_assocty"
});
if (AssociatedTypeSectionRef.getObject() == nullptr) {
std::cerr << BinaryFilename;
std::cerr << " doesn't have an associated type reflection section!\n";
return EXIT_FAILURE;
}
auto ReflectionStringsSectionRef = getSectionRef(binary, arch, {
"__swift3_reflstr", ".swift3_reflstr"
});
if (ReflectionStringsSectionRef.getObject() == nullptr) {
std::cerr << BinaryFilename;
std::cerr << " doesn't have an associated reflection strings section!\n";
return EXIT_FAILURE;
}
auto TypeRefSectionRef = getSectionRef(binary, arch, {
"__swift3_typeref", ".swift3_typeref"
});
if (TypeRefSectionRef.getObject() == nullptr) {
std::cerr << BinaryFilename;
std::cerr << " doesn't have an associated typeref section!\n";
return EXIT_FAILURE;
}
StringRef FieldSectionContents;
FieldSectionRef.getContents(FieldSectionContents);
const FieldSection fieldSection {
reinterpret_cast<const void *>(FieldSectionContents.begin()),
reinterpret_cast<const void *>(FieldSectionContents.end())
};
StringRef AssociatedTypeSectionContents;
AssociatedTypeSectionRef.getContents(AssociatedTypeSectionContents);
const AssociatedTypeSection associatedTypeSection {
reinterpret_cast<const void *>(AssociatedTypeSectionContents.begin()),
reinterpret_cast<const void *>(AssociatedTypeSectionContents.end())
};
StringRef ReflectionStringsSectionContents;
ReflectionStringsSectionRef.getContents(ReflectionStringsSectionContents);
const GenericSection ReflectionStringsSection {
reinterpret_cast<const void *>(ReflectionStringsSectionContents.begin()),
reinterpret_cast<const void *>(ReflectionStringsSectionContents.end())
};
StringRef TypeRefSectionContents;
AssociatedTypeSectionRef.getContents(TypeRefSectionContents);
const GenericSection TypeRefSection {
reinterpret_cast<const void *>(TypeRefSectionContents.begin()),
reinterpret_cast<const void *>(TypeRefSectionContents.end())
};
InProcessMemoryReader Reader;
ReflectionContext<External<RuntimeTarget<8>>> RC(Reader);
RC.addReflectionInfo({
BinaryFilename,
fieldSection,
associatedTypeSection,
ReflectionStringsSection,
TypeRefSection,
});
RC.dumpAllSections(std::cout);
return EXIT_SUCCESS;
}
int main(int argc, char *argv[]) {
llvm::cl::ParseCommandLineOptions(argc, argv, "Swift Reflection Dump\n");
return doDumpReflectionSections(options::BinaryFilename,
options::Architecture);
}

View File

@@ -1,13 +1,5 @@
add_swift_executable(swift-reflection-test
add_swift_target_executable(swift-reflection-test BUILD_WITH_STDLIB
swift-reflection-test.cpp
LINK_LIBRARIES
swiftBasic
swiftReflection
COMPONENT_DEPENDS object support
)
swift_install_in_component(tools
TARGETS swift-reflection-test
RUNTIME DESTINATION bin)
LINK_FAT_LIBRARIES
swiftReflection)

View File

@@ -1,4 +1,4 @@
//===--- swift-reflection-test.cpp - Reflection testing application -------===//
//===--- swift-reflection-dump.cpp - Reflection testing application -------===//
//
// This source file is part of the Swift.org open source project
//
@@ -9,200 +9,26 @@
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
// This file supports performing target-specific remote reflection tests
// on live swift executables.
//===----------------------------------------------------------------------===//
#include "swift/ABI/MetadataValues.h"
#include "swift/Basic/Demangle.h"
#include "swift/Basic/LLVMInitialize.h"
#include "swift/Reflection/ReflectionContext.h"
#include "swift/Reflection/TypeRef.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/ADT/Optional.h"
#include "messages.h"
#include <unistd.h>
#include <algorithm>
#include <iostream>
#include <csignal>
using llvm::dyn_cast;
using llvm::StringRef;
using llvm::ArrayRef;
using namespace llvm::object;
using namespace swift;
using namespace reflection;
using namespace Demangle;
namespace {
enum class ActionType {
None,
DumpReflectionSections,
DumpHeapInstance
};
} // end anonymous namespace
namespace options {
static llvm::cl::opt<ActionType>
Action(llvm::cl::desc("Mode:"),
llvm::cl::values(
clEnumValN(ActionType::DumpReflectionSections,
"dump-reflection-sections",
"Dump the field reflection section"),
clEnumValN(ActionType::DumpHeapInstance,
"dump-heap-instance",
"Dump the field layout for a heap instance by running "
"a Swift executable"),
clEnumValEnd));
static llvm::cl::opt<std::string>
BinaryFilename("binary-filename", llvm::cl::desc("Filename of the binary file"),
llvm::cl::Required);
static llvm::cl::opt<std::string>
Architecture("arch", llvm::cl::desc("Architecture to inspect in the binary"),
llvm::cl::Required);
} // end namespace options
static void guardError(std::error_code error) {
if (!error) return;
std::cerr << "swift-reflection-test error: " << error.message() << "\n";
exit(EXIT_FAILURE);
}
static void errorAndExit(const std::string &message) {
std::cerr << message << ": " << strerror(errno) << std::endl;
exit(EXIT_FAILURE);
}
static llvm::object::SectionRef
getSectionRef(const ObjectFile *objectFile,
ArrayRef<StringRef> anySectionNames) {
for (auto section : objectFile->sections()) {
StringRef sectionName;
section.getName(sectionName);
for (auto desiredName : anySectionNames) {
if (sectionName.equals(desiredName)) {
return section;
}
}
}
return llvm::object::SectionRef();
}
static llvm::object::SectionRef
getSectionRef(const Binary *binaryFile, StringRef arch,
ArrayRef<StringRef> anySectionNames) {
if (auto objectFile = dyn_cast<ObjectFile>(binaryFile))
return getSectionRef(objectFile, anySectionNames);
if (auto machoUniversal = dyn_cast<MachOUniversalBinary>(binaryFile)) {
const auto objectOrError = machoUniversal->getObjectForArch(arch);
guardError(objectOrError.getError());
return getSectionRef(objectOrError.get().get(), anySectionNames);
}
return SectionRef();
}
static int doDumpReflectionSections(std::string BinaryFilename,
StringRef arch) {
auto binaryOrError = llvm::object::createBinary(BinaryFilename);
guardError(binaryOrError.getError());
const auto binary = binaryOrError.get().getBinary();
auto FieldSectionRef = getSectionRef(binary, arch, {
"__swift3_fieldmd", ".swift3_fieldmd"
});
if (FieldSectionRef.getObject() == nullptr) {
std::cerr << BinaryFilename;
std::cerr << " doesn't have a field reflection section!\n";
return EXIT_FAILURE;
}
auto AssociatedTypeSectionRef = getSectionRef(binary, arch, {
"__swift3_assocty", ".swift3_assocty"
});
if (AssociatedTypeSectionRef.getObject() == nullptr) {
std::cerr << BinaryFilename;
std::cerr << " doesn't have an associated type reflection section!\n";
return EXIT_FAILURE;
}
auto ReflectionStringsSectionRef = getSectionRef(binary, arch, {
"__swift3_reflstr", ".swift3_reflstr"
});
if (ReflectionStringsSectionRef.getObject() == nullptr) {
std::cerr << BinaryFilename;
std::cerr << " doesn't have an associated reflection strings section!\n";
return EXIT_FAILURE;
}
auto TypeRefSectionRef = getSectionRef(binary, arch, {
"__swift3_typeref", ".swift3_typeref"
});
if (TypeRefSectionRef.getObject() == nullptr) {
std::cerr << BinaryFilename;
std::cerr << " doesn't have an associated typeref section!\n";
return EXIT_FAILURE;
}
StringRef FieldSectionContents;
FieldSectionRef.getContents(FieldSectionContents);
const FieldSection fieldSection {
reinterpret_cast<const void *>(FieldSectionContents.begin()),
reinterpret_cast<const void *>(FieldSectionContents.end())
};
StringRef AssociatedTypeSectionContents;
AssociatedTypeSectionRef.getContents(AssociatedTypeSectionContents);
const AssociatedTypeSection associatedTypeSection {
reinterpret_cast<const void *>(AssociatedTypeSectionContents.begin()),
reinterpret_cast<const void *>(AssociatedTypeSectionContents.end())
};
StringRef ReflectionStringsSectionContents;
ReflectionStringsSectionRef.getContents(ReflectionStringsSectionContents);
const GenericSection ReflectionStringsSection {
reinterpret_cast<const void *>(ReflectionStringsSectionContents.begin()),
reinterpret_cast<const void *>(ReflectionStringsSectionContents.end())
};
StringRef TypeRefSectionContents;
AssociatedTypeSectionRef.getContents(TypeRefSectionContents);
const GenericSection TypeRefSection {
reinterpret_cast<const void *>(TypeRefSectionContents.begin()),
reinterpret_cast<const void *>(TypeRefSectionContents.end())
};
InProcessMemoryReader Reader;
ReflectionContext<External<RuntimeTarget<8>>> RC(Reader);
RC.addReflectionInfo({
BinaryFilename,
fieldSection,
associatedTypeSection,
ReflectionStringsSection,
TypeRefSection,
});
RC.dumpAllSections(std::cout);
return EXIT_SUCCESS;
}
namespace {
template <typename Runtime>
struct Section {
@@ -255,9 +81,11 @@ struct RemoteReflectionInfo {
};
}
template <typename Runtime>
class PipeMemoryReader : public MemoryReader {
using StoredPointer = typename Runtime::StoredPointer;
using StoredSize = typename Runtime::StoredSize;
static constexpr size_t ReadEnd = 0;
static constexpr size_t WriteEnd = 1;
@@ -318,7 +146,7 @@ public:
StoredPointer TargetAddress = (StoredPointer)Address;
write(getParentWriteFD(), REQUEST_READ_BYTES, 2);
write(getParentWriteFD(), &TargetAddress, sizeof(TargetAddress));
write(getParentWriteFD(), &Size, sizeof(Size));
write(getParentWriteFD(), &Size, sizeof(StoredSize));
collectBytesFromPipe(Dest, Size);
return true;
}
@@ -360,16 +188,16 @@ public:
std::vector<ReflectionInfo> receiveReflectionInfo() {
write(getParentWriteFD(), REQUEST_REFLECTION_INFO, 2);
uint64_t NumReflectionInfos = 0;
StoredSize NumReflectionInfos = 0;
collectBytesFromPipe(&NumReflectionInfos, sizeof(NumReflectionInfos));
std::vector<RemoteReflectionInfo<Runtime>> RemoteInfos;
for (uint64_t i = 0; i < NumReflectionInfos; ++i) {
uint64_t ImageNameLength;
for (StoredSize i = 0; i < NumReflectionInfos; ++i) {
StoredSize ImageNameLength;
collectBytesFromPipe(&ImageNameLength, sizeof(ImageNameLength));
char c;
std::string ImageName;
for (uint64_t i = 0; i < ImageNameLength; ++i) {
for (StoredSize i = 0; i < ImageNameLength; ++i) {
collectBytesFromPipe(&c, 1);
ImageName.push_back(c);
}
@@ -456,6 +284,7 @@ public:
}
};
template <typename Runtime>
static int doDumpHeapInstance(std::string BinaryFilename) {
using StoredPointer = typename Runtime::StoredPointer;
@@ -487,8 +316,8 @@ static int doDumpHeapInstance(std::string BinaryFilename) {
StoredPointer instance = Pipe.receiveInstanceAddress();
assert(instance);
std::cerr << "Parent: instance pointer in child address space: 0x";
std::cerr << std::hex << instance << std::endl;
std::cout << "Parent: instance pointer in child address space: 0x";
std::cout << std::hex << instance << std::endl;
StoredPointer isa;
if (!Pipe.readInteger(instance, &isa))
@@ -497,17 +326,17 @@ static int doDumpHeapInstance(std::string BinaryFilename) {
for (auto &Info : Pipe.receiveReflectionInfo())
RC.addReflectionInfo(Info);
std::cerr << "Parent: metadata pointer in child address space: 0x";
std::cerr << std::hex << isa << std::endl;
std::cout << "Parent: metadata pointer in child address space: 0x";
std::cout << std::hex << isa << std::endl;
std::cerr << "Decoding type reference ..." << std::endl;
std::cout << "Decoding type reference ..." << std::endl;
auto TR = RC.getTypeRef(isa);
TR->dump();
TR->dump(std::cout, 0);
auto Fields = RC.getFieldTypeRefs(isa);
for (auto &Field : Fields) {
std::cout << Field.first << ":\n";
Field.second->dump();
Field.second->dump(std::cout , 0);
// TODO: Print field layout here.
std::cout << std::endl;
}
@@ -519,14 +348,19 @@ static int doDumpHeapInstance(std::string BinaryFilename) {
return EXIT_SUCCESS;
}
void printUsageAndExit() {
std::cerr << "swift-reflection-test <arch> <binary filename>" << std::endl;
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[]) {
llvm::cl::ParseCommandLineOptions(argc, argv, "Swift Reflection Test\n");
switch (options::Action) {
case ActionType::DumpReflectionSections:
return doDumpReflectionSections(options::BinaryFilename,
options::Architecture);
case ActionType::DumpHeapInstance: {
StringRef arch = options::Architecture;
if (argc != 3)
printUsageAndExit();
std::string arch(argv[1]);
std::string BinaryFilename(argv[2]);
unsigned PointerSize = 0;
if (arch == "x86_64")
PointerSize = 8;
@@ -542,13 +376,7 @@ int main(int argc, char *argv[]) {
errorAndExit("Unsupported architecture");
if (PointerSize == 4)
return doDumpHeapInstance<External<RuntimeTarget<4>>>(options::BinaryFilename);
return doDumpHeapInstance<External<RuntimeTarget<4>>>(BinaryFilename);
else
return doDumpHeapInstance<External<RuntimeTarget<8>>>(options::BinaryFilename);
}
case ActionType::None:
llvm::cl::PrintHelpMessage();
return EXIT_FAILURE;
break;
}
return doDumpHeapInstance<External<RuntimeTarget<8>>>(BinaryFilename);
}

View File

@@ -13,6 +13,7 @@ config.swift_obj_root = "@SWIFT_BINARY_DIR@"
config.target_triple = "@TARGET_TRIPLE@"
config.targets_to_build = "@TARGETS_TO_BUILD@"
config.variant_triple = "@VARIANT_TRIPLE@"
config.variant_suffix = "@VARIANT_SUFFIX@"
config.variant_sdk = "@VARIANT_SDK@"
config.darwin_xcrun_toolchain = "@SWIFT_DARWIN_XCRUN_TOOLCHAIN@"