Skip to content

Commit 5ea5bb0

Browse files
committed
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.
1 parent 884155c commit 5ea5bb0

File tree

21 files changed

+299
-247
lines changed

21 files changed

+299
-247
lines changed

CMakeLists.txt

+6
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,12 @@ if(SWIFT_BUILD_TOOLS)
699699
endif()
700700
add_subdirectory(utils)
701701
add_subdirectory(stdlib)
702+
703+
if(SWIFT_BUILD_TOOLS)
704+
add_subdirectory(tools/swift-reflection-test)
705+
add_subdirectory(tools/swift-reflection-dump)
706+
endif()
707+
702708
if(SWIFT_BUILD_PERF_TESTSUITE AND "${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
703709
add_subdirectory(benchmark)
704710
endif()

cmake/modules/AddSwift.cmake

+5-1
Original file line numberDiff line numberDiff line change
@@ -1847,7 +1847,7 @@ endfunction()
18471847
function(add_swift_target_executable name)
18481848
# Parse the arguments we were given.
18491849
cmake_parse_arguments(SWIFTEXE_TARGET
1850-
"EXCLUDE_FROM_ALL;DONT_STRIP_NON_MAIN_SYMBOLS;DISABLE_ASLR"
1850+
"EXCLUDE_FROM_ALL;DONT_STRIP_NON_MAIN_SYMBOLS;DISABLE_ASLR;BUILD_WITH_STDLIB"
18511851
""
18521852
"DEPENDS;COMPONENT_DEPENDS;LINK_FAT_LIBRARIES"
18531853
${ARGN})
@@ -1887,6 +1887,10 @@ function(add_swift_target_executable name)
18871887
set(SWIFTEXE_TARGET_EXCLUDE_FROM_ALL_FLAG_CURRENT "EXCLUDE_FROM_ALL")
18881888
endif()
18891889

1890+
if(SWIFTEXE_TARGET_BUILD_WITH_STDLIB)
1891+
add_dependencies("swift-test-stdlib${VARIANT_SUFFIX}" ${VARIANT_NAME})
1892+
endif()
1893+
18901894
# Don't add the ${arch} to the suffix. We want to link against fat
18911895
# libraries.
18921896
_list_add_string_suffix(

include/swift/Reflection/Reader.h

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include <dlfcn.h>
2424
#include <cstdint>
25+
#include <cstring>
2526
#include <memory>
2627
#include <vector>
2728

lib/CMakeLists.txt

-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ add_subdirectory(Markup)
1212
add_subdirectory(Option)
1313
add_subdirectory(Parse)
1414
add_subdirectory(PrintAsObjC)
15-
add_subdirectory(Reflection)
1615
add_subdirectory(Sema)
1716
add_subdirectory(Serialization)
1817
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")

lib/Reflection/CMakeLists.txt

-3
This file was deleted.

stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,8 @@ internal func sendReflectionInfos() {
187187
for info in infos {
188188
debugLog("Sending info for \(info.imageName)")
189189
let imageNameBytes = Array(info.imageName.utf8)
190-
var imageNameLength = UInt64(imageNameBytes.count)
191-
fwrite(&imageNameLength, sizeof(UInt64.self), 1, stdout)
190+
var imageNameLength = UInt(imageNameBytes.count)
191+
fwrite(&imageNameLength, sizeof(UInt.self), 1, stdout)
192192
fflush(stdout)
193193
fwrite(imageNameBytes, 1, imageNameBytes.count, stdout)
194194
fflush(stdout)
@@ -235,7 +235,7 @@ internal func sendSymbolAddress() {
235235
name.withCString {
236236
let handle = unsafeBitCast(Int(-2), to: UnsafeMutablePointer<Void>.self)
237237
let symbol = dlsym(handle, $0)
238-
let symbolAddress = unsafeBitCast(symbol, to: UInt64.self)
238+
let symbolAddress = unsafeBitCast(symbol, to: UInt.self)
239239
sendValue(symbolAddress)
240240
}
241241
}

stdlib/public/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ if(SWIFT_BUILD_STDLIB)
3232
add_subdirectory(core)
3333
add_subdirectory(SwiftOnoneSupport)
3434
add_subdirectory(Platform)
35+
add_subdirectory(Reflection)
3536
endif()
3637

3738
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
add_swift_library(swiftReflection IS_STDLIB
2+
Demangle.cpp
3+
Remangle.cpp
4+
TypeRef.cpp
5+
INSTALL_IN_COMPONENT stdlib)

stdlib/public/Reflection/Demangle.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "../../../lib/Basic/Demangle.cpp"
2+
#include "../../../lib/Basic/Punycode.cpp"
3+
#include "../../../lib/Basic/PunycodeUTF8.cpp"

stdlib/public/Reflection/Remangle.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include "../../../lib/Basic/Remangle.cpp"

lib/Reflection/TypeRef.cpp renamed to stdlib/public/Reflection/TypeRef.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#include "swift/Basic/Demangle.h"
1919
#include "swift/Reflection/ReflectionContext.h"
2020
#include "swift/Reflection/TypeRef.h"
21-
#include "llvm/Support/ErrorHandling.h"
2221

2322
using namespace swift;
2423
using namespace reflection;
@@ -396,7 +395,7 @@ static unsigned _getDepth(TypeRef *TR) {
396395
break;
397396
}
398397
default:
399-
llvm_unreachable("Unexpected type ref kind asked for parent type");
398+
assert(false && "Asked for depth on non-nominal typeref");
400399
}
401400
}
402401

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// UNSUPPORTED: objc_interop
22
// RUN: rm -rf %t && mkdir -p %t
33
// 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
4-
// RUN: %target-swift-reflection-test -binary-filename %t/libTypesToReflect -dump-reflection-sections > %t/typeref_decoding.txt
4+
// RUN: %target-swift-reflection-dump -binary-filename %t/libTypesToReflect > %t/typeref_decoding.txt
55
// RUN: diff -u %S/typeref_decoding.result.txt %t/typeref_decoding.txt
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: rm -rf %t && mkdir -p %t
22
// 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
3-
// RUN: %target-swift-reflection-test -binary-filename %t/libTypesToReflect -dump-reflection-sections > %t/typeref_decoding.txt
3+
// RUN: %target-swift-reflection-dump -binary-filename %t/libTypesToReflect > %t/typeref_decoding.txt
44
// RUN: diff -u %S/typeref_decoding_objc.result.txt %t/typeref_decoding.txt
55
// REQUIRES: objc_interop

test/lit.cfg

+3-1
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ config.sil_extract = inferSwiftBinary('sil-extract')
272272
config.lldb_moduleimport_test = inferSwiftBinary('lldb-moduleimport-test')
273273
config.swift_ide_test = inferSwiftBinary('swift-ide-test')
274274
config.swift_reflection_test = inferSwiftBinary('swift-reflection-test')
275+
config.swift_reflection_dump = inferSwiftBinary('swift-reflection-dump')
275276
config.clang = inferSwiftBinary('clang')
276277
config.llvm_link = inferSwiftBinary('llvm-link')
277278
config.swift_llvm_opt = inferSwiftBinary('swift-llvm-opt')
@@ -840,7 +841,8 @@ config.substitutions.append(
840841
(subst_target_swift_ide_test_mock_sdk,
841842
subst_target_swift_ide_test_mock_sdk_after)))
842843
config.substitutions.append(('%target-swift-ide-test', config.target_swift_ide_test))
843-
config.substitutions.append(('%target-swift-reflection-test', '{} {} {}'.format(config.swift_reflection_test, '-arch', run_cpu)))
844+
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)))
845+
config.substitutions.append(('%target-swift-reflection-dump', '{} {} {}'.format(config.swift_reflection_dump, '-arch', run_cpu)))
844846
config.substitutions.append(('%target-swiftc_driver', config.target_swiftc_driver))
845847

846848
if hasattr(config, 'target_swift_autolink_extract'):

test/lit.site.cfg.in

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ config.target_triple = "@TARGET_TRIPLE@"
1515
config.targets_to_build = "@TARGETS_TO_BUILD@"
1616
config.variant_triple = "@VARIANT_TRIPLE@"
1717
config.variant_sdk = "@VARIANT_SDK@"
18+
config.variant_suffix = "@VARIANT_SUFFIX@"
1819
config.swiftlib_dir = "@LIT_SWIFTLIB_DIR@"
1920
config.darwin_xcrun_toolchain = "@SWIFT_DARWIN_XCRUN_TOOLCHAIN@"
2021

tools/CMakeLists.txt

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ add_subdirectory(swift-demangle)
55
add_subdirectory(lldb-moduleimport-test)
66
add_subdirectory(sil-extract)
77
add_subdirectory(swift-llvm-opt)
8-
add_subdirectory(swift-reflection-test)
98

109
if(SWIFT_BUILD_SOURCEKIT)
1110
add_subdirectory(SourceKit)
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
add_swift_executable(swift-reflection-dump
2+
swift-reflection-dump.cpp
3+
LINK_FAT_LIBRARIES
4+
swiftReflection
5+
COMPONENT_DEPENDS object support
6+
)
7+
8+
swift_install_in_component(tools
9+
TARGETS swift-reflection-dump
10+
RUNTIME DESTINATION bin)
11+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
//===--- swift-reflection-test.cpp - Reflection testing application -------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
// This is a host-side tool to dump remote reflection sections in swift
13+
// binaries.
14+
//===----------------------------------------------------------------------===//
15+
16+
#include "swift/ABI/MetadataValues.h"
17+
#include "swift/Basic/Demangle.h"
18+
#include "swift/Basic/LLVMInitialize.h"
19+
#include "swift/Reflection/ReflectionContext.h"
20+
#include "swift/Reflection/TypeRef.h"
21+
#include "llvm/Object/Archive.h"
22+
#include "llvm/Object/MachO.h"
23+
#include "llvm/Object/MachOUniversal.h"
24+
#include "llvm/Object/ELF.h"
25+
#include "llvm/Support/CommandLine.h"
26+
27+
#include <unistd.h>
28+
29+
#include <algorithm>
30+
#include <iostream>
31+
#include <csignal>
32+
33+
using llvm::dyn_cast;
34+
using llvm::StringRef;
35+
using llvm::ArrayRef;
36+
using namespace llvm::object;
37+
38+
using namespace swift;
39+
using namespace reflection;
40+
using namespace Demangle;
41+
42+
enum class ActionType {
43+
None,
44+
DumpReflectionSections,
45+
DumpHeapInstance
46+
};
47+
48+
namespace options {
49+
static llvm::cl::opt<ActionType>
50+
Action(llvm::cl::desc("Mode:"),
51+
llvm::cl::values(
52+
clEnumValN(ActionType::DumpReflectionSections,
53+
"dump-reflection-sections",
54+
"Dump the field reflection section"),
55+
clEnumValN(ActionType::DumpHeapInstance,
56+
"dump-heap-instance",
57+
"Dump the field layout for a heap instance by running "
58+
"a Swift executable"),
59+
clEnumValEnd));
60+
61+
static llvm::cl::opt<std::string>
62+
BinaryFilename("binary-filename", llvm::cl::desc("Filename of the binary file"),
63+
llvm::cl::Required);
64+
65+
static llvm::cl::opt<std::string>
66+
Architecture("arch", llvm::cl::desc("Architecture to inspect in the binary"),
67+
llvm::cl::Required);
68+
} // end namespace options
69+
70+
static void guardError(std::error_code error) {
71+
if (!error) return;
72+
std::cerr << "swift-reflection-test error: " << error.message() << "\n";
73+
exit(EXIT_FAILURE);
74+
}
75+
76+
static llvm::object::SectionRef
77+
getSectionRef(const ObjectFile *objectFile,
78+
ArrayRef<StringRef> anySectionNames) {
79+
for (auto section : objectFile->sections()) {
80+
StringRef sectionName;
81+
section.getName(sectionName);
82+
for (auto desiredName : anySectionNames) {
83+
if (sectionName.equals(desiredName)) {
84+
return section;
85+
}
86+
}
87+
}
88+
return llvm::object::SectionRef();
89+
}
90+
91+
static llvm::object::SectionRef
92+
getSectionRef(const Binary *binaryFile, StringRef arch,
93+
ArrayRef<StringRef> anySectionNames) {
94+
if (auto objectFile = dyn_cast<ObjectFile>(binaryFile))
95+
return getSectionRef(objectFile, anySectionNames);
96+
if (auto machoUniversal = dyn_cast<MachOUniversalBinary>(binaryFile)) {
97+
const auto objectOrError = machoUniversal->getObjectForArch(arch);
98+
guardError(objectOrError.getError());
99+
return getSectionRef(objectOrError.get().get(), anySectionNames);
100+
}
101+
return SectionRef();
102+
}
103+
104+
static int doDumpReflectionSections(std::string BinaryFilename,
105+
StringRef arch) {
106+
auto binaryOrError = llvm::object::createBinary(BinaryFilename);
107+
guardError(binaryOrError.getError());
108+
109+
const auto binary = binaryOrError.get().getBinary();
110+
111+
auto FieldSectionRef = getSectionRef(binary, arch, {
112+
"__swift3_fieldmd", ".swift3_fieldmd"
113+
});
114+
115+
if (FieldSectionRef.getObject() == nullptr) {
116+
std::cerr << BinaryFilename;
117+
std::cerr << " doesn't have a field reflection section!\n";
118+
return EXIT_FAILURE;
119+
}
120+
121+
auto AssociatedTypeSectionRef = getSectionRef(binary, arch, {
122+
"__swift3_assocty", ".swift3_assocty"
123+
});
124+
125+
if (AssociatedTypeSectionRef.getObject() == nullptr) {
126+
std::cerr << BinaryFilename;
127+
std::cerr << " doesn't have an associated type reflection section!\n";
128+
return EXIT_FAILURE;
129+
}
130+
131+
auto ReflectionStringsSectionRef = getSectionRef(binary, arch, {
132+
"__swift3_reflstr", ".swift3_reflstr"
133+
});
134+
135+
if (ReflectionStringsSectionRef.getObject() == nullptr) {
136+
std::cerr << BinaryFilename;
137+
std::cerr << " doesn't have an associated reflection strings section!\n";
138+
return EXIT_FAILURE;
139+
}
140+
141+
auto TypeRefSectionRef = getSectionRef(binary, arch, {
142+
"__swift3_typeref", ".swift3_typeref"
143+
});
144+
145+
if (TypeRefSectionRef.getObject() == nullptr) {
146+
std::cerr << BinaryFilename;
147+
std::cerr << " doesn't have an associated typeref section!\n";
148+
return EXIT_FAILURE;
149+
}
150+
151+
StringRef FieldSectionContents;
152+
FieldSectionRef.getContents(FieldSectionContents);
153+
154+
const FieldSection fieldSection {
155+
reinterpret_cast<const void *>(FieldSectionContents.begin()),
156+
reinterpret_cast<const void *>(FieldSectionContents.end())
157+
};
158+
159+
StringRef AssociatedTypeSectionContents;
160+
AssociatedTypeSectionRef.getContents(AssociatedTypeSectionContents);
161+
162+
const AssociatedTypeSection associatedTypeSection {
163+
reinterpret_cast<const void *>(AssociatedTypeSectionContents.begin()),
164+
reinterpret_cast<const void *>(AssociatedTypeSectionContents.end())
165+
};
166+
167+
StringRef ReflectionStringsSectionContents;
168+
ReflectionStringsSectionRef.getContents(ReflectionStringsSectionContents);
169+
170+
const GenericSection ReflectionStringsSection {
171+
reinterpret_cast<const void *>(ReflectionStringsSectionContents.begin()),
172+
reinterpret_cast<const void *>(ReflectionStringsSectionContents.end())
173+
};
174+
175+
StringRef TypeRefSectionContents;
176+
AssociatedTypeSectionRef.getContents(TypeRefSectionContents);
177+
178+
const GenericSection TypeRefSection {
179+
reinterpret_cast<const void *>(TypeRefSectionContents.begin()),
180+
reinterpret_cast<const void *>(TypeRefSectionContents.end())
181+
};
182+
183+
InProcessMemoryReader Reader;
184+
ReflectionContext<External<RuntimeTarget<8>>> RC(Reader);
185+
RC.addReflectionInfo({
186+
BinaryFilename,
187+
fieldSection,
188+
associatedTypeSection,
189+
ReflectionStringsSection,
190+
TypeRefSection,
191+
});
192+
RC.dumpAllSections(std::cout);
193+
194+
return EXIT_SUCCESS;
195+
}
196+
197+
int main(int argc, char *argv[]) {
198+
llvm::cl::ParseCommandLineOptions(argc, argv, "Swift Reflection Dump\n");
199+
return doDumpReflectionSections(options::BinaryFilename,
200+
options::Architecture);
201+
}
202+
+3-11
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
1-
add_swift_executable(swift-reflection-test
1+
add_swift_target_executable(swift-reflection-test BUILD_WITH_STDLIB
22
swift-reflection-test.cpp
3-
LINK_LIBRARIES
4-
swiftBasic
5-
swiftReflection
6-
7-
COMPONENT_DEPENDS object support
8-
)
9-
10-
swift_install_in_component(tools
11-
TARGETS swift-reflection-test
12-
RUNTIME DESTINATION bin)
3+
LINK_FAT_LIBRARIES
4+
swiftReflection)
135

0 commit comments

Comments
 (0)