28
28
29
29
namespace swift {
30
30
31
+ #ifndef NDEBUG
31
32
static swift::MetadataSections *registered = nullptr ;
32
33
33
- void record (swift::MetadataSections *sections) {
34
+ static void record (swift::MetadataSections *sections) {
34
35
if (registered == nullptr ) {
35
36
registered = sections;
36
37
sections->next = sections->prev = sections;
@@ -41,34 +42,70 @@ void record(swift::MetadataSections *sections) {
41
42
registered->prev = sections;
42
43
}
43
44
}
45
+ #endif
46
+
47
+ static const void *
48
+ getMetadataSectionBaseAddress (swift::MetadataSections *sections) {
49
+ // If the base address was not set by the caller of swift_addNewDSOImage()
50
+ // then we can assume that the caller was built against an older version of
51
+ // the runtime that did not capture a value for this field. Currently nothing
52
+ // is actively using the image's base address outside of tests that are built
53
+ // with the runtime/stdlib, so there's no need to try to fix up the value. If
54
+ // something in the runtime starts using it, we will want to either:
55
+ // 1. Resolve the address from a known-good address like swift5_protocols when
56
+ // the image is first loaded (in this function);
57
+ // 1. Resolve the address from a known-good address like swift5_protocols when
58
+ // the address is first used (and atomically swap the address back so we
59
+ // don't incur the cost of lookupSymbol() each time we need it; or
60
+ // 3. Introduce an ABI-breaking change so that all binaries are rebuilt and
61
+ // start supplying a value for this field.
62
+
63
+ #ifndef NDEBUG
64
+ #if defined(__ELF__)
65
+ // If the base address was set but the image is an ELF image, it is going to
66
+ // be __dso_handle which is not the value we expect (Dl_info::dli_fbase), so
67
+ // we need to fix it up. Since the base address is currently unused by the
68
+ // runtime outside tests, we don't normally do this work.
69
+ if (auto baseAddress = sections->baseAddress ) {
70
+ swift::SymbolInfo symbolInfo;
71
+ if (lookupSymbol (baseAddress, &symbolInfo) && symbolInfo.baseAddress ) {
72
+ sections->baseAddress = symbolInfo.baseAddress ;
73
+ }
74
+ }
75
+ #endif
76
+ #endif
77
+
78
+ return sections->baseAddress ;
79
+ }
44
80
}
45
81
46
82
SWIFT_RUNTIME_EXPORT
47
- void swift_addNewDSOImage (const void *addr) {
48
- // We cast off the const in order to update the linked list
49
- // data structure. This is safe to do since we don't touch
50
- // any other fields.
51
- swift::MetadataSections *sections =
52
- static_cast <swift::MetadataSections *>(const_cast <void *>(addr));
53
-
83
+ void swift_addNewDSOImage (swift::MetadataSections *sections) {
84
+ #ifndef NDEBUG
54
85
record (sections);
86
+ #endif
87
+
88
+ auto baseAddress = swift::getMetadataSectionBaseAddress (sections);
55
89
56
90
const auto &protocols_section = sections->swift5_protocols ;
57
91
const void *protocols = reinterpret_cast <void *>(protocols_section.start );
58
92
if (protocols_section.length )
59
- swift::addImageProtocolsBlockCallback (protocols, protocols_section.length );
93
+ swift::addImageProtocolsBlockCallback (baseAddress,
94
+ protocols, protocols_section.length );
60
95
61
96
const auto &protocol_conformances = sections->swift5_protocol_conformances ;
62
97
const void *conformances =
63
98
reinterpret_cast <void *>(protocol_conformances.start );
64
99
if (protocol_conformances.length )
65
- swift::addImageProtocolConformanceBlockCallback (conformances,
100
+ swift::addImageProtocolConformanceBlockCallback (baseAddress, conformances,
66
101
protocol_conformances.length );
67
102
68
103
const auto &type_metadata = sections->swift5_type_metadata ;
69
104
const void *metadata = reinterpret_cast <void *>(type_metadata.start );
70
105
if (type_metadata.length )
71
- swift::addImageTypeMetadataRecordBlockCallback (metadata, type_metadata.length );
106
+ swift::addImageTypeMetadataRecordBlockCallback (baseAddress,
107
+ metadata,
108
+ type_metadata.length );
72
109
73
110
const auto &dynamic_replacements = sections->swift5_replace ;
74
111
const auto *replacements =
@@ -77,7 +114,7 @@ void swift_addNewDSOImage(const void *addr) {
77
114
const auto &dynamic_replacements_some = sections->swift5_replac2 ;
78
115
const auto *replacements_some =
79
116
reinterpret_cast <void *>(dynamic_replacements_some.start );
80
- swift::addImageDynamicReplacementBlockCallback (
117
+ swift::addImageDynamicReplacementBlockCallback (baseAddress,
81
118
replacements, dynamic_replacements.length , replacements_some,
82
119
dynamic_replacements_some.length );
83
120
}
@@ -87,70 +124,22 @@ void swift_addNewDSOImage(const void *addr) {
87
124
reinterpret_cast <void *>(accessible_funcs_section.start );
88
125
if (accessible_funcs_section.length )
89
126
swift::addImageAccessibleFunctionsBlockCallback (
90
- functions, accessible_funcs_section.length );
127
+ baseAddress, functions, accessible_funcs_section.length );
91
128
}
92
129
93
130
void swift::initializeProtocolLookup () {
94
- const swift::MetadataSections *sections = registered;
95
- while (true ) {
96
- const swift::MetadataSectionRange &protocols =
97
- sections->swift5_protocols ;
98
- if (protocols.length )
99
- addImageProtocolsBlockCallbackUnsafe (
100
- reinterpret_cast <void *>(protocols.start ), protocols.length );
101
-
102
- if (sections->next == registered)
103
- break ;
104
- sections = sections->next ;
105
- }
106
131
}
107
132
108
133
void swift::initializeProtocolConformanceLookup () {
109
- const swift::MetadataSections *sections = registered;
110
- while (true ) {
111
- const swift::MetadataSectionRange &conformances =
112
- sections->swift5_protocol_conformances ;
113
- if (conformances.length )
114
- addImageProtocolConformanceBlockCallbackUnsafe (
115
- reinterpret_cast <void *>(conformances.start ), conformances.length );
116
-
117
- if (sections->next == registered)
118
- break ;
119
- sections = sections->next ;
120
- }
121
134
}
122
135
123
136
void swift::initializeTypeMetadataRecordLookup () {
124
- const swift::MetadataSections *sections = registered;
125
- while (true ) {
126
- const swift::MetadataSectionRange &type_metadata =
127
- sections->swift5_type_metadata ;
128
- if (type_metadata.length )
129
- addImageTypeMetadataRecordBlockCallbackUnsafe (
130
- reinterpret_cast <void *>(type_metadata.start ), type_metadata.length );
131
-
132
- if (sections->next == registered)
133
- break ;
134
- sections = sections->next ;
135
- }
136
137
}
137
138
138
139
void swift::initializeDynamicReplacementLookup () {
139
140
}
140
141
141
142
void swift::initializeAccessibleFunctionsLookup () {
142
- const swift::MetadataSections *sections = registered;
143
- while (true ) {
144
- const swift::MetadataSectionRange &functions =
145
- sections->swift5_accessible_functions ;
146
- if (functions.length )
147
- addImageAccessibleFunctionsBlockCallbackUnsafe (
148
- reinterpret_cast <void *>(functions.start ), functions.length );
149
-
150
- if (sections->next == registered)
151
- break ;
152
- sections = sections->next ;
153
- }
154
143
}
155
144
156
145
#ifndef NDEBUG
@@ -173,16 +162,31 @@ const swift::MetadataSections *swift_getMetadataSection(size_t index) {
173
162
}
174
163
175
164
SWIFT_RUNTIME_EXPORT
176
- const char *swift_getMetadataSectionName (void *metadata_section) {
165
+ const char *
166
+ swift_getMetadataSectionName (const swift::MetadataSections *section) {
177
167
swift::SymbolInfo info;
178
- if (lookupSymbol (metadata_section , &info)) {
168
+ if (lookupSymbol (section , &info)) {
179
169
if (info.fileName ) {
180
170
return info.fileName ;
181
171
}
182
172
}
183
173
return " " ;
184
174
}
185
175
176
+ SWIFT_RUNTIME_EXPORT
177
+ void swift_getMetadataSectionBaseAddress (const swift::MetadataSections *section,
178
+ void const **out_actual,
179
+ void const **out_expected) {
180
+ swift::SymbolInfo info;
181
+ if (lookupSymbol (section, &info)) {
182
+ *out_actual = info.baseAddress ;
183
+ } else {
184
+ *out_actual = nullptr ;
185
+ }
186
+
187
+ *out_expected = section->baseAddress ;
188
+ }
189
+
186
190
SWIFT_RUNTIME_EXPORT
187
191
size_t swift_getMetadataSectionCount () {
188
192
if (swift::registered == nullptr )
0 commit comments