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,67 @@ 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
+ #if defined(__ELF__)
64
+ // If the base address was set but the image is an ELF image, it is going to
65
+ // be __dso_handle which is not the value we expect (Dl_info::dli_fbase), so
66
+ // we need to fix it up.
67
+ if (auto baseAddress = sections->baseAddress ) {
68
+ swift::SymbolInfo symbolInfo;
69
+ if (lookupSymbol (baseAddress, &symbolInfo) && symbolInfo.baseAddress ) {
70
+ sections->baseAddress = symbolInfo.baseAddress ;
71
+ }
72
+ }
73
+ #endif
74
+
75
+ return sections->baseAddress ;
76
+ }
44
77
}
45
78
46
79
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
-
80
+ void swift_addNewDSOImage (swift::MetadataSections *sections) {
81
+ #ifndef NDEBUG
54
82
record (sections);
83
+ #endif
84
+
85
+ auto baseAddress = swift::getMetadataSectionBaseAddress (sections);
55
86
56
87
const auto &protocols_section = sections->swift5_protocols ;
57
88
const void *protocols = reinterpret_cast <void *>(protocols_section.start );
58
89
if (protocols_section.length )
59
- swift::addImageProtocolsBlockCallback (protocols, protocols_section.length );
90
+ swift::addImageProtocolsBlockCallback (baseAddress,
91
+ protocols, protocols_section.length );
60
92
61
93
const auto &protocol_conformances = sections->swift5_protocol_conformances ;
62
94
const void *conformances =
63
95
reinterpret_cast <void *>(protocol_conformances.start );
64
96
if (protocol_conformances.length )
65
- swift::addImageProtocolConformanceBlockCallback (conformances,
97
+ swift::addImageProtocolConformanceBlockCallback (baseAddress, conformances,
66
98
protocol_conformances.length );
67
99
68
100
const auto &type_metadata = sections->swift5_type_metadata ;
69
101
const void *metadata = reinterpret_cast <void *>(type_metadata.start );
70
102
if (type_metadata.length )
71
- swift::addImageTypeMetadataRecordBlockCallback (metadata, type_metadata.length );
103
+ swift::addImageTypeMetadataRecordBlockCallback (baseAddress,
104
+ metadata,
105
+ type_metadata.length );
72
106
73
107
const auto &dynamic_replacements = sections->swift5_replace ;
74
108
const auto *replacements =
@@ -77,7 +111,7 @@ void swift_addNewDSOImage(const void *addr) {
77
111
const auto &dynamic_replacements_some = sections->swift5_replac2 ;
78
112
const auto *replacements_some =
79
113
reinterpret_cast <void *>(dynamic_replacements_some.start );
80
- swift::addImageDynamicReplacementBlockCallback (
114
+ swift::addImageDynamicReplacementBlockCallback (baseAddress,
81
115
replacements, dynamic_replacements.length , replacements_some,
82
116
dynamic_replacements_some.length );
83
117
}
@@ -87,70 +121,22 @@ void swift_addNewDSOImage(const void *addr) {
87
121
reinterpret_cast <void *>(accessible_funcs_section.start );
88
122
if (accessible_funcs_section.length )
89
123
swift::addImageAccessibleFunctionsBlockCallback (
90
- functions, accessible_funcs_section.length );
124
+ baseAddress, functions, accessible_funcs_section.length );
91
125
}
92
126
93
127
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
128
}
107
129
108
130
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
131
}
122
132
123
133
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
134
}
137
135
138
136
void swift::initializeDynamicReplacementLookup () {
139
137
}
140
138
141
139
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
140
}
155
141
156
142
#ifndef NDEBUG
@@ -173,16 +159,35 @@ const swift::MetadataSections *swift_getMetadataSection(size_t index) {
173
159
}
174
160
175
161
SWIFT_RUNTIME_EXPORT
176
- const char *swift_getMetadataSectionName (void *metadata_section) {
162
+ const char *
163
+ swift_getMetadataSectionName (const swift::MetadataSections *section) {
177
164
swift::SymbolInfo info;
178
- if (lookupSymbol (metadata_section , &info)) {
165
+ if (lookupSymbol (section , &info)) {
179
166
if (info.fileName ) {
180
167
return info.fileName ;
181
168
}
182
169
}
183
170
return " " ;
184
171
}
185
172
173
+ SWIFT_RUNTIME_EXPORT
174
+ void swift_getMetadataSectionBaseAddress (const swift::MetadataSections *section,
175
+ void const **out_actual,
176
+ void const **out_expected) {
177
+ *out_actual = nullptr ;
178
+ *out_expected = section->baseAddress ;
179
+
180
+ swift::SymbolInfo info;
181
+ if (lookupSymbol (section, &info)) {
182
+ *out_actual = info.baseAddress ;
183
+ if (info.fileName ) {
184
+ return info.fileName ;
185
+ }
186
+ }
187
+ return " " ;
188
+
189
+ }
190
+
186
191
SWIFT_RUNTIME_EXPORT
187
192
size_t swift_getMetadataSectionCount () {
188
193
if (swift::registered == nullptr )
0 commit comments