Skip to content

Commit 5cee6f3

Browse files
committed
Unify 'MetadataSections' data structure, as well as common ELF and COFF procedures
1 parent 79bdd43 commit 5cee6f3

File tree

10 files changed

+178
-309
lines changed

10 files changed

+178
-309
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -320,10 +320,8 @@ class ReflectionContext
320320

321321
// FIXME: This code needs to be cleaned up and updated
322322
// to make it work for 32 bit platforms.
323-
if (SectionName != ".sw5cptr" && SectionName != ".sw5bltn") {
324-
Begin = Begin.atByteOffset(8);
325-
Size -= 16;
326-
}
323+
Begin = Begin.atByteOffset(8);
324+
Size -= 16;
327325

328326
return {Begin, Size};
329327
}

stdlib/public/SwiftShims/MetadataSections.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,26 @@ namespace swift {
2929
extern "C" {
3030
#endif
3131

32+
/// Specifies the address range corresponding to a section.
3233
typedef struct MetadataSectionRange {
3334
__swift_uintptr_t start;
3435
__swift_size_t length;
3536
} MetadataSectionRange;
3637

38+
39+
/// Identifies the address space ranges for the Swift metadata required by the Swift runtime.
3740
struct MetadataSections {
3841
__swift_uintptr_t version;
3942
__swift_uintptr_t reserved;
4043

44+
/// `next` and `prev` are used by the runtime to construct a
45+
/// circularly doubly linked list to quickly iterate over the metadata
46+
/// from each image loaded into the address space. These are invasive
47+
/// to enable the runtime registration, which occurs at image load time, to
48+
/// be allocation-free as it is invoked from an image constructor function
49+
/// context where the system may not yet be ready to perform allocations.
50+
/// Additionally, avoiding the allocation enables a fast load operation, which
51+
/// directly impacts application load time.
4152
struct MetadataSections *next;
4253
struct MetadataSections *prev;
4354

stdlib/public/runtime/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ set(swift_runtime_sources
4545
Float16Support.cpp
4646
Heap.cpp
4747
HeapObject.cpp
48+
ImageInspectionCommon.cpp
4849
ImageInspectionMachO.cpp
4950
ImageInspectionELF.cpp
5051
ImageInspectionCOFF.cpp

stdlib/public/runtime/ImageInspectionCOFF.cpp

Lines changed: 0 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#if !defined(__ELF__) && !defined(__MACH__)
1414

1515
#include "ImageInspection.h"
16-
#include "ImageInspectionCOFF.h"
1716

1817
#if defined(__CYGWIN__)
1918
#include <dlfcn.h>
@@ -26,108 +25,6 @@
2625

2726
using namespace swift;
2827

29-
namespace {
30-
static const swift::MetadataSections *registered = nullptr;
31-
32-
void record(const swift::MetadataSections *sections) {
33-
if (registered == nullptr) {
34-
registered = sections;
35-
sections->next = sections->prev = sections;
36-
} else {
37-
registered->prev->next = sections;
38-
sections->next = registered;
39-
sections->prev = registered->prev;
40-
registered->prev = sections;
41-
}
42-
}
43-
}
44-
45-
void swift::initializeProtocolLookup() {
46-
const swift::MetadataSections *sections = registered;
47-
while (true) {
48-
const swift::MetadataSections::Range &protocols =
49-
sections->swift5_protocols;
50-
if (protocols.length)
51-
addImageProtocolsBlockCallbackUnsafe(
52-
reinterpret_cast<void *>(protocols.start), protocols.length);
53-
54-
if (sections->next == registered)
55-
break;
56-
sections = sections->next;
57-
}
58-
}
59-
60-
void swift::initializeProtocolConformanceLookup() {
61-
const swift::MetadataSections *sections = registered;
62-
while (true) {
63-
const swift::MetadataSections::Range &conformances =
64-
sections->swift5_protocol_conformances;
65-
if (conformances.length)
66-
addImageProtocolConformanceBlockCallbackUnsafe(
67-
reinterpret_cast<void *>(conformances.start), conformances.length);
68-
69-
if (sections->next == registered)
70-
break;
71-
sections = sections->next;
72-
}
73-
}
74-
75-
void swift::initializeTypeMetadataRecordLookup() {
76-
const swift::MetadataSections *sections = registered;
77-
while (true) {
78-
const swift::MetadataSections::Range &type_metadata =
79-
sections->swift5_type_metadata;
80-
if (type_metadata.length)
81-
addImageTypeMetadataRecordBlockCallbackUnsafe(
82-
reinterpret_cast<void *>(type_metadata.start), type_metadata.length);
83-
84-
if (sections->next == registered)
85-
break;
86-
sections = sections->next;
87-
}
88-
}
89-
90-
void swift::initializeDynamicReplacementLookup() {
91-
}
92-
93-
SWIFT_RUNTIME_EXPORT
94-
void swift_addNewDSOImage(const void *addr) {
95-
const swift::MetadataSections *sections =
96-
static_cast<const swift::MetadataSections *>(addr);
97-
98-
record(sections);
99-
100-
const auto &protocols_section = sections->swift5_protocols;
101-
const void *protocols =
102-
reinterpret_cast<void *>(protocols_section.start);
103-
if (protocols_section.length)
104-
addImageProtocolsBlockCallback(protocols, protocols_section.length);
105-
106-
const auto &protocol_conformances = sections->swift5_protocol_conformances;
107-
const void *conformances =
108-
reinterpret_cast<void *>(protocol_conformances.start);
109-
if (protocol_conformances.length)
110-
addImageProtocolConformanceBlockCallback(conformances,
111-
protocol_conformances.length);
112-
113-
const auto &type_metadata = sections->swift5_type_metadata;
114-
const void *metadata = reinterpret_cast<void *>(type_metadata.start);
115-
if (type_metadata.length)
116-
addImageTypeMetadataRecordBlockCallback(metadata, type_metadata.length);
117-
118-
const auto &dynamic_replacements = sections->swift5_repl;
119-
const auto *replacements =
120-
reinterpret_cast<void *>(dynamic_replacements.start);
121-
if (dynamic_replacements.length) {
122-
const auto &dynamic_replacements_some = sections->swift5_reps;
123-
const auto *replacements_some =
124-
reinterpret_cast<void *>(dynamic_replacements_some.start);
125-
addImageDynamicReplacementBlockCallback(
126-
replacements, dynamic_replacements.length, replacements_some,
127-
dynamic_replacements_some.length);
128-
}
129-
}
130-
13128
int swift::lookupSymbol(const void *address, SymbolInfo *info) {
13229
#if defined(__CYGWIN__)
13330
Dl_info dlinfo;
@@ -173,10 +70,4 @@ int swift::lookupSymbol(const void *address, SymbolInfo *info) {
17370
#endif // defined(__CYGWIN__) || defined(_WIN32)
17471
}
17572

176-
// This is only used for backward deployment hooks, which we currently only support for
177-
// MachO. Add a stub here to make sure it still compiles.
178-
void *swift::lookupSection(const char *segment, const char *section, size_t *outSize) {
179-
return nullptr;
180-
}
181-
18273
#endif // !defined(__ELF__) && !defined(__MACH__)

stdlib/public/runtime/ImageInspectionCOFF.h

Lines changed: 0 additions & 66 deletions
This file was deleted.
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
//===--- ImageInspectionCommon.cpp - Image inspection routines --*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
///
13+
/// \file
14+
///
15+
/// This file unifies common ELF and COFF image inspection routines
16+
///
17+
//===----------------------------------------------------------------------===//
18+
19+
#ifndef SWIFT_RUNTIME_IMAGEINSPECTIONCOMMON_H
20+
#define SWIFT_RUNTIME_IMAGEINSPECTIONCOMMON_H
21+
22+
#if !defined(__MACH__)
23+
24+
#include "../SwiftShims/Visibility.h"
25+
#include "../SwiftShims/MetadataSections.h"
26+
#include "ImageInspection.h"
27+
28+
29+
namespace swift {
30+
31+
static swift::MetadataSections *registered = nullptr;
32+
33+
void record(swift::MetadataSections *sections) {
34+
if (registered == nullptr) {
35+
registered = sections;
36+
sections->next = sections->prev = sections;
37+
} else {
38+
registered->prev->next = sections;
39+
sections->next = registered;
40+
sections->prev = registered->prev;
41+
registered->prev = sections;
42+
}
43+
}
44+
}
45+
46+
SWIFT_RUNTIME_EXPORT
47+
void swift_addNewDSOImage(const void *addr) {
48+
const swift::MetadataSections *sections =
49+
static_cast<const swift::MetadataSections *>(addr);
50+
51+
// We cast off the const in order to update the linked list
52+
// data structure. This is safe to do since we don't touch
53+
// any other fields.
54+
auto casted_sections = const_cast<swift::MetadataSections *>(sections);
55+
record(casted_sections);
56+
57+
const auto &protocols_section = sections->swift5_protocols;
58+
const void *protocols = reinterpret_cast<void *>(protocols_section.start);
59+
if (protocols_section.length)
60+
swift::addImageProtocolsBlockCallback(protocols, protocols_section.length);
61+
62+
const auto &protocol_conformances = sections->swift5_protocol_conformances;
63+
const void *conformances =
64+
reinterpret_cast<void *>(protocol_conformances.start);
65+
if (protocol_conformances.length)
66+
swift::addImageProtocolConformanceBlockCallback(conformances,
67+
protocol_conformances.length);
68+
69+
const auto &type_metadata = sections->swift5_type_metadata;
70+
const void *metadata = reinterpret_cast<void *>(type_metadata.start);
71+
if (type_metadata.length)
72+
swift::addImageTypeMetadataRecordBlockCallback(metadata, type_metadata.length);
73+
74+
const auto &dynamic_replacements = sections->swift5_replace;
75+
const auto *replacements =
76+
reinterpret_cast<void *>(dynamic_replacements.start);
77+
if (dynamic_replacements.length) {
78+
const auto &dynamic_replacements_some = sections->swift5_replac2;
79+
const auto *replacements_some =
80+
reinterpret_cast<void *>(dynamic_replacements_some.start);
81+
swift::addImageDynamicReplacementBlockCallback(
82+
replacements, dynamic_replacements.length, replacements_some,
83+
dynamic_replacements_some.length);
84+
}
85+
}
86+
87+
void swift::initializeProtocolLookup() {
88+
const swift::MetadataSections *sections = registered;
89+
while (true) {
90+
const swift::MetadataSectionRange &protocols =
91+
sections->swift5_protocols;
92+
if (protocols.length)
93+
addImageProtocolsBlockCallbackUnsafe(
94+
reinterpret_cast<void *>(protocols.start), protocols.length);
95+
96+
if (sections->next == registered)
97+
break;
98+
sections = sections->next;
99+
}
100+
}
101+
102+
void swift::initializeProtocolConformanceLookup() {
103+
const swift::MetadataSections *sections = registered;
104+
while (true) {
105+
const swift::MetadataSectionRange &conformances =
106+
sections->swift5_protocol_conformances;
107+
if (conformances.length)
108+
addImageProtocolConformanceBlockCallbackUnsafe(
109+
reinterpret_cast<void *>(conformances.start), conformances.length);
110+
111+
if (sections->next == registered)
112+
break;
113+
sections = sections->next;
114+
}
115+
}
116+
117+
void swift::initializeTypeMetadataRecordLookup() {
118+
const swift::MetadataSections *sections = registered;
119+
while (true) {
120+
const swift::MetadataSectionRange &type_metadata =
121+
sections->swift5_type_metadata;
122+
if (type_metadata.length)
123+
addImageTypeMetadataRecordBlockCallbackUnsafe(
124+
reinterpret_cast<void *>(type_metadata.start), type_metadata.length);
125+
126+
if (sections->next == registered)
127+
break;
128+
sections = sections->next;
129+
}
130+
}
131+
132+
void swift::initializeDynamicReplacementLookup() {
133+
}
134+
135+
// This is only used for backward deployment hooks, which we currently only support for
136+
// MachO. Add a stub here to make sure it still compiles.
137+
void *swift::lookupSection(const char *segment, const char *section, size_t *outSize) {
138+
return nullptr;
139+
}
140+
141+
#endif // !defined(__MACH__)
142+
143+
#endif // SWIFT_RUNTIME_IMAGEINSPECTIONCOMMON_H

0 commit comments

Comments
 (0)