2828
2929namespace swift {
3030
31+ #ifndef NDEBUG
3132static swift::MetadataSections *registered = nullptr ;
3233
33- void record (swift::MetadataSections *sections) {
34+ static void record (swift::MetadataSections *sections) {
3435 if (registered == nullptr ) {
3536 registered = sections;
3637 sections->next = sections->prev = sections;
@@ -41,34 +42,70 @@ void record(swift::MetadataSections *sections) {
4142 registered->prev = sections;
4243 }
4344}
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+ }
4480}
4581
4682SWIFT_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
5485 record (sections);
86+ #endif
87+
88+ auto baseAddress = swift::getMetadataSectionBaseAddress (sections);
5589
5690 const auto &protocols_section = sections->swift5_protocols ;
5791 const void *protocols = reinterpret_cast <void *>(protocols_section.start );
5892 if (protocols_section.length )
59- swift::addImageProtocolsBlockCallback (protocols, protocols_section.length );
93+ swift::addImageProtocolsBlockCallback (baseAddress,
94+ protocols, protocols_section.length );
6095
6196 const auto &protocol_conformances = sections->swift5_protocol_conformances ;
6297 const void *conformances =
6398 reinterpret_cast <void *>(protocol_conformances.start );
6499 if (protocol_conformances.length )
65- swift::addImageProtocolConformanceBlockCallback (conformances,
100+ swift::addImageProtocolConformanceBlockCallback (baseAddress, conformances,
66101 protocol_conformances.length );
67102
68103 const auto &type_metadata = sections->swift5_type_metadata ;
69104 const void *metadata = reinterpret_cast <void *>(type_metadata.start );
70105 if (type_metadata.length )
71- swift::addImageTypeMetadataRecordBlockCallback (metadata, type_metadata.length );
106+ swift::addImageTypeMetadataRecordBlockCallback (baseAddress,
107+ metadata,
108+ type_metadata.length );
72109
73110 const auto &dynamic_replacements = sections->swift5_replace ;
74111 const auto *replacements =
@@ -77,7 +114,7 @@ void swift_addNewDSOImage(const void *addr) {
77114 const auto &dynamic_replacements_some = sections->swift5_replac2 ;
78115 const auto *replacements_some =
79116 reinterpret_cast <void *>(dynamic_replacements_some.start );
80- swift::addImageDynamicReplacementBlockCallback (
117+ swift::addImageDynamicReplacementBlockCallback (baseAddress,
81118 replacements, dynamic_replacements.length , replacements_some,
82119 dynamic_replacements_some.length );
83120 }
@@ -87,70 +124,22 @@ void swift_addNewDSOImage(const void *addr) {
87124 reinterpret_cast <void *>(accessible_funcs_section.start );
88125 if (accessible_funcs_section.length )
89126 swift::addImageAccessibleFunctionsBlockCallback (
90- functions, accessible_funcs_section.length );
127+ baseAddress, functions, accessible_funcs_section.length );
91128}
92129
93130void 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- }
106131}
107132
108133void 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- }
121134}
122135
123136void 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- }
136137}
137138
138139void swift::initializeDynamicReplacementLookup () {
139140}
140141
141142void 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- }
154143}
155144
156145#ifndef NDEBUG
@@ -173,16 +162,31 @@ const swift::MetadataSections *swift_getMetadataSection(size_t index) {
173162}
174163
175164SWIFT_RUNTIME_EXPORT
176- const char *swift_getMetadataSectionName (void *metadata_section) {
165+ const char *
166+ swift_getMetadataSectionName (const swift::MetadataSections *section) {
177167 swift::SymbolInfo info;
178- if (lookupSymbol (metadata_section , &info)) {
168+ if (lookupSymbol (section , &info)) {
179169 if (info.fileName ) {
180170 return info.fileName ;
181171 }
182172 }
183173 return " " ;
184174}
185175
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+
186190SWIFT_RUNTIME_EXPORT
187191size_t swift_getMetadataSectionCount () {
188192 if (swift::registered == nullptr )
0 commit comments