Skip to content

Commit 4341102

Browse files
committed
[Tools] Add a library to build specialized generic metadata out of process.
This library uses GenericMetadataBuilder with a ReaderWriter that can read data and resolve pointers from MachO files, and emit a JSON representation of a dylib containing the built metadata. We use LLVM's binary file readers to parse the MachO files and resolve fixups so we can follow pointers. This code is somewhat MachO specific, but could be generalized to other formats that LLVM supports. rdar://116592577
1 parent feae5f1 commit 4341102

39 files changed

+3876
-211
lines changed

CMakeLists.txt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,18 +215,22 @@ option(SWIFT_BUILD_REMOTE_MIRROR
215215
"Build the Swift Remote Mirror Library"
216216
TRUE)
217217

218+
option(SWIFT_BUILD_EXTERNAL_GENERIC_METADATA_BUILDER
219+
"Build the Swift External Generic Metadata Builder Library"
220+
TRUE)
221+
218222
option(SWIFT_BUILD_DYNAMIC_STDLIB
219223
"Build dynamic variants of the Swift standard library"
220224
TRUE)
221225

222226
option(SWIFT_BUILD_STATIC_STDLIB
223227
"Build static variants of the Swift standard library"
224228
FALSE)
225-
229+
226230
option(SWIFT_STDLIB_STATIC_PRINT
227231
"Build compile-time evaluated vprintf()"
228232
FALSE)
229-
233+
230234
option(SWIFT_STDLIB_ENABLE_UNICODE_DATA
231235
"Include Unicode data files in the standard library.
232236
NOTE: Disabling this will cause many String methods to crash."
@@ -1245,6 +1249,11 @@ if(SWIFT_BUILD_REMOTE_MIRROR)
12451249
message(STATUS "")
12461250
endif()
12471251

1252+
if(SWIFT_BUILD_EXTERNAL_GENERIC_METADATA_BUILDER)
1253+
message(STATUS "Building Swift External Generic Metadata Builder for SDKs: ${SWIFT_SDKS}")
1254+
message(STATUS "")
1255+
endif()
1256+
12481257
#
12491258
# Find required dependencies.
12501259
#

cmake/modules/SwiftComponents.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
# * llvm-toolchain-dev-tools -- install LLVM development tools useful in a shared toolchain
7171
# * dev -- headers and libraries required to use Swift compiler as a library.
7272
set(_SWIFT_DEFINED_COMPONENTS
73-
"autolink-driver;back-deployment;compiler;clang-builtin-headers;clang-resource-dir-symlink;clang-builtin-headers-in-clang-resource-dir;libexec;stdlib;stdlib-experimental;sdk-overlay;static-mirror-lib;swift-syntax-lib;editor-integration;tools;testsuite-tools;toolchain-tools;toolchain-dev-tools;llvm-toolchain-dev-tools;dev;license;sourcekit-xpc-service;sourcekit-inproc;swift-remote-mirror;swift-remote-mirror-headers")
73+
"autolink-driver;back-deployment;compiler;clang-builtin-headers;clang-resource-dir-symlink;clang-builtin-headers-in-clang-resource-dir;libexec;stdlib;stdlib-experimental;sdk-overlay;static-mirror-lib;swift-syntax-lib;editor-integration;tools;testsuite-tools;toolchain-tools;toolchain-dev-tools;llvm-toolchain-dev-tools;dev;license;sourcekit-xpc-service;sourcekit-inproc;swift-remote-mirror;swift-remote-mirror-headers;swift-external-generic-metadata-builder;swift-external-generic-metadata-builder-headers")
7474

7575
# The default install components include all of the defined components, except
7676
# for the following exceptions.

include/swift/ABI/Metadata.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ template <typename Runtime>
151151
struct TargetTypeMetadataHeaderBase {
152152
/// A pointer to the value-witnesses for this type. This is only
153153
/// present for type metadata.
154-
TargetPointer<Runtime, const ValueWitnessTable> ValueWitnesses;
154+
TargetPointer<Runtime, const TargetValueWitnessTable<Runtime>> ValueWitnesses;
155155
};
156156

157157
template <typename Runtime>
@@ -329,7 +329,7 @@ struct TargetMetadata {
329329
return asFullMetadata(this)->layoutString;
330330
}
331331

332-
const ValueWitnessTable *getValueWitnesses() const {
332+
const TargetValueWitnessTable<Runtime> *getValueWitnesses() const {
333333
return asFullMetadata(this)->ValueWitnesses;
334334
}
335335

@@ -2979,7 +2979,7 @@ template <typename Runtime>
29792979
struct swift_ptrauth_struct_context_descriptor(ModuleContextDescriptor)
29802980
TargetModuleContextDescriptor final : TargetContextDescriptor<Runtime> {
29812981
/// The module name.
2982-
RelativeDirectPointer<const char, /*nullable*/ false> Name;
2982+
TargetRelativeDirectPointer<Runtime, const char, /*nullable*/ false> Name;
29832983

29842984
/// Is this module a special C-imported module?
29852985
bool isCImportedContext() const {
@@ -3036,7 +3036,7 @@ struct swift_ptrauth_struct_context_descriptor(ExtensionContextDescriptor)
30363036
///
30373037
/// Note that the Parent of the extension will be the module context the
30383038
/// extension is declared inside.
3039-
RelativeDirectPointer<const char> ExtendedContext;
3039+
TargetRelativeDirectPointer<Runtime, const char> ExtendedContext;
30403040

30413041
using TrailingGenericContextObjects::getGenericContext;
30423042

@@ -3527,10 +3527,10 @@ struct TargetGenericValueMetadataPattern final :
35273527

35283528
/// The value-witness table. Indirectable so that we can re-use tables
35293529
/// from other libraries if that seems wise.
3530-
TargetRelativeIndirectablePointer<Runtime, const ValueWitnessTable>
3530+
TargetRelativeIndirectablePointer<Runtime, const TargetValueWitnessTable<Runtime>>
35313531
ValueWitnesses;
35323532

3533-
const ValueWitnessTable *getValueWitnessesPattern() const {
3533+
const TargetValueWitnessTable<Runtime> *getValueWitnessesPattern() const {
35343534
return ValueWitnesses.get();
35353535
}
35363536

@@ -3825,9 +3825,11 @@ class swift_ptrauth_struct_context_descriptor(TypeContextDescriptor)
38253825
/*Nullable*/ true> AccessFunctionPtr;
38263826

38273827
/// A pointer to the field descriptor for the type, if any.
3828-
TargetRelativeDirectPointer<Runtime, const reflection::FieldDescriptor,
3829-
/*nullable*/ true> Fields;
3830-
3828+
TargetRelativeDirectPointer<Runtime,
3829+
const reflection::TargetFieldDescriptor<Runtime>,
3830+
/*nullable*/ true>
3831+
Fields;
3832+
38313833
bool isReflectable() const { return (bool)Fields; }
38323834

38333835
MetadataAccessFunction getAccessFunction() const {

include/swift/ABI/TargetLayout.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ struct RuntimeTarget<8> {
6363
};
6464

6565
namespace reflection {
66-
class FieldDescriptor;
66+
template <typename Runtime>
67+
class TargetFieldDescriptor;
6768
}
6869

6970
/// In-process native runtime target.

include/swift/Basic/RelativePointer.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,8 +590,12 @@ class RelativeDirectPointerIntPairImpl {
590590
using ValueTy = PointeeTy;
591591
using PointerTy = PointeeTy*;
592592

593+
Offset getOffset() const & {
594+
return RelativeOffsetPlusInt & ~getMask();
595+
}
596+
593597
PointerTy getPointer() const & {
594-
Offset offset = (RelativeOffsetPlusInt & ~getMask());
598+
Offset offset = getOffset();
595599

596600
// Check for null.
597601
if (Nullable && offset == 0)
@@ -624,6 +628,7 @@ class RelativeDirectPointerIntPair<PointeeTy, IntTy, Nullable, Offset,
624628
{
625629
using super = RelativeDirectPointerIntPairImpl<PointeeTy, IntTy, Nullable, Offset>;
626630
public:
631+
using super::getOffset;
627632
using super::getPointer;
628633
using super::getInt;
629634
using super::getOpaqueValue;

include/swift/Demangling/Demangle.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,8 @@ class Node {
264264
// Only to be used by the demangler parsers.
265265
void removeChildAt(unsigned Pos);
266266

267+
void replaceChild(unsigned Pos, NodePointer Child);
268+
267269
// Reverses the order of children.
268270
void reverseChildren(size_t StartingAt = 0);
269271

include/swift/RemoteInspection/Records.h

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#ifndef SWIFT_REFLECTION_RECORDS_H
1818
#define SWIFT_REFLECTION_RECORDS_H
1919

20-
#include "swift/Basic/RelativePointer.h"
20+
#include "swift/ABI/TargetLayout.h"
2121
#include "swift/Demangling/Demangle.h"
2222
#include "llvm/ADT/ArrayRef.h"
2323

@@ -82,14 +82,15 @@ class FieldRecordFlags {
8282
}
8383
};
8484

85-
class FieldRecord {
85+
template <typename Runtime>
86+
class TargetFieldRecord {
8687
const FieldRecordFlags Flags;
8788

8889
public:
89-
const RelativeDirectPointer<const char> MangledTypeName;
90-
const RelativeDirectPointer<const char> FieldName;
90+
const TargetRelativeDirectPointer<Runtime, const char> MangledTypeName;
91+
const TargetRelativeDirectPointer<Runtime, const char> FieldName;
9192

92-
FieldRecord() = delete;
93+
TargetFieldRecord() = delete;
9394

9495
bool hasMangledTypeName() const {
9596
return MangledTypeName;
@@ -111,36 +112,37 @@ class FieldRecord {
111112
return Flags.isVar();
112113
}
113114
};
115+
using FieldRecord = TargetFieldRecord<InProcess>;
114116

115-
struct FieldRecordIterator {
116-
const FieldRecord *Cur;
117-
const FieldRecord * const End;
117+
template <typename Runtime>
118+
struct TargetFieldRecordIterator {
119+
const TargetFieldRecord<Runtime> *Cur;
120+
const TargetFieldRecord<Runtime> *const End;
118121

119-
FieldRecordIterator(const FieldRecord *Cur, const FieldRecord * const End)
120-
: Cur(Cur), End(End) {}
122+
TargetFieldRecordIterator(const TargetFieldRecord<Runtime> *Cur,
123+
const TargetFieldRecord<Runtime> *const End)
124+
: Cur(Cur), End(End) {}
121125

122-
const FieldRecord &operator*() const {
123-
return *Cur;
124-
}
126+
const TargetFieldRecord<Runtime> &operator*() const { return *Cur; }
125127

126-
const FieldRecord *operator->() const {
127-
return Cur;
128-
}
128+
const TargetFieldRecord<Runtime> *operator->() const { return Cur; }
129129

130-
FieldRecordIterator &operator++() {
130+
TargetFieldRecordIterator &operator++() {
131131
++Cur;
132132
return *this;
133133
}
134134

135-
bool operator==(const FieldRecordIterator &other) const {
135+
bool operator==(const TargetFieldRecordIterator &other) const {
136136
return Cur == other.Cur && End == other.End;
137137
}
138138

139-
bool operator!=(const FieldRecordIterator &other) const {
139+
bool operator!=(const TargetFieldRecordIterator &other) const {
140140
return !(*this == other);
141141
}
142142
};
143143

144+
using FieldRecordIterator = TargetFieldRecordIterator<InProcess>;
145+
144146
enum class FieldDescriptorKind : uint16_t {
145147
// Swift nominal types.
146148
Struct,
@@ -173,16 +175,17 @@ enum class FieldDescriptorKind : uint16_t {
173175

174176
// Field descriptors contain a collection of field records for a single
175177
// class, struct or enum declaration.
176-
class FieldDescriptor {
177-
const FieldRecord *getFieldRecordBuffer() const {
178-
return reinterpret_cast<const FieldRecord *>(this + 1);
178+
template <typename Runtime>
179+
class TargetFieldDescriptor {
180+
const TargetFieldRecord<Runtime> *getFieldRecordBuffer() const {
181+
return reinterpret_cast<const TargetFieldRecord<Runtime> *>(this + 1);
179182
}
180183

181184
public:
182-
const RelativeDirectPointer<const char> MangledTypeName;
183-
const RelativeDirectPointer<const char> Superclass;
185+
const TargetRelativeDirectPointer<Runtime, const char> MangledTypeName;
186+
const TargetRelativeDirectPointer<Runtime, const char> Superclass;
184187

185-
FieldDescriptor() = delete;
188+
TargetFieldDescriptor() = delete;
186189

187190
const FieldDescriptorKind Kind;
188191
const uint16_t FieldRecordSize;
@@ -222,7 +225,7 @@ class FieldDescriptor {
222225
return const_iterator { End, End };
223226
}
224227

225-
llvm::ArrayRef<FieldRecord> getFields() const {
228+
llvm::ArrayRef<TargetFieldRecord<Runtime>> getFields() const {
226229
return {getFieldRecordBuffer(), NumFields};
227230
}
228231

@@ -242,6 +245,7 @@ class FieldDescriptor {
242245
return Demangle::makeSymbolicMangledNameStringRef(Superclass.get());
243246
}
244247
};
248+
using FieldDescriptor = TargetFieldDescriptor<InProcess>;
245249

246250
// Associated type records describe the mapping from an associated
247251
// type to the type witness of a conformance.

include/swift/Runtime/Enum.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include "swift/Runtime/Config.h"
2121

2222
namespace swift {
23-
23+
2424
struct OpaqueValue;
2525
struct InProcess;
2626

@@ -139,7 +139,7 @@ void swift_initEnumMetadataMultiPayloadWithLayoutString(EnumMetadata *enumType,
139139
SWIFT_RUNTIME_EXPORT
140140
unsigned swift_getEnumCaseMultiPayload(const OpaqueValue *value,
141141
const EnumMetadata *enumType);
142-
142+
143143
/// Store the tag value for the given case into a multi-payload enum,
144144
/// whose associated payload (if any) has already been initialized.
145145
SWIFT_RUNTIME_EXPORT

include/swift/Runtime/EnvironmentVariables.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//===----------------------------------------------------------------------===//
1616

1717
#include "swift/Threading/Once.h"
18+
#include "swift/shims/Visibility.h"
1819

1920
namespace swift {
2021
namespace runtime {
@@ -54,4 +55,4 @@ SWIFT_RUNTIME_STDLIB_SPI bool concurrencyValidateUncheckedContinuations();
5455

5556
} // end namespace environment
5657
} // end namespace runtime
57-
} // end namespace Swift
58+
} // end namespace swift

0 commit comments

Comments
 (0)