Skip to content

Commit 235cf66

Browse files
Merge pull request #40656 from apple/revert-40611-jgrynspan/coff-elf-double-registration-fix
Revert "Fix an issue on COFF/ELF targets where the runtime would register each loaded image twice (at least early on.)"
2 parents 4902ff5 + cf39513 commit 235cf66

12 files changed

+101
-223
lines changed

stdlib/public/SwiftShims/MetadataSections.h

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,25 +39,7 @@ typedef struct MetadataSectionRange {
3939
/// Identifies the address space ranges for the Swift metadata required by the Swift runtime.
4040
struct MetadataSections {
4141
__swift_uintptr_t version;
42-
43-
/// The base address of the image where this metadata section was defined, as
44-
/// reported when the section was registered with the Swift runtime.
45-
///
46-
/// The value of this field is equivalent to the value of
47-
/// \c SymbolInfo::baseAddress as returned from \c lookupSymbol() for a symbol
48-
/// in the image that contains these sections.
49-
///
50-
/// For Mach-O images, set this field to \c __dso_handle (i.e. the Mach header
51-
/// for the image.) For ELF images, set it to \c __dso_handle (the runtime
52-
/// will adjust it to the start of the ELF image when the image is loaded.)
53-
/// For COFF images, set this field to \c __ImageBase.
54-
///
55-
/// For platforms that have a single statically-linked image or no dynamic
56-
/// loader (i.e. no equivalent of \c __dso_handle or \c __ImageBase), this
57-
/// field is ignored and should be set to \c nullptr.
58-
///
59-
/// \sa swift_addNewDSOImage()
60-
const void *baseAddress;
42+
__swift_uintptr_t reserved;
6143

6244
/// `next` and `prev` are used by the runtime to construct a
6345
/// circularly doubly linked list to quickly iterate over the metadata

stdlib/public/runtime/AccessibleFunction.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ static void _registerAccessibleFunctions(AccessibleFunctionsState &C,
9898
C.SectionsToScan.push_back(section);
9999
}
100100

101-
void swift::addImageAccessibleFunctionsBlockCallbackUnsafe(
102-
const void *baseAddress, const void *functions, uintptr_t size) {
101+
void swift::addImageAccessibleFunctionsBlockCallbackUnsafe(const void *functions,
102+
uintptr_t size) {
103103
assert(
104104
size % sizeof(AccessibleFunctionRecord) == 0 &&
105105
"accessible function section not a multiple of AccessibleFunctionRecord");
@@ -108,10 +108,10 @@ void swift::addImageAccessibleFunctionsBlockCallbackUnsafe(
108108
_registerAccessibleFunctions(C, AccessibleFunctionsSection{functions, size});
109109
}
110110

111-
void swift::addImageAccessibleFunctionsBlockCallback(
112-
const void *baseAddress, const void *functions, uintptr_t size) {
111+
void swift::addImageAccessibleFunctionsBlockCallback(const void *functions,
112+
uintptr_t size) {
113113
Functions.get();
114-
addImageAccessibleFunctionsBlockCallbackUnsafe(baseAddress, functions, size);
114+
addImageAccessibleFunctionsBlockCallbackUnsafe(functions, size);
115115
}
116116

117117
static const AccessibleFunctionRecord *

stdlib/public/runtime/ImageInspection.h

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -77,31 +77,22 @@ void initializeDynamicReplacementLookup();
7777
void initializeAccessibleFunctionsLookup();
7878

7979
// Callbacks to register metadata from an image to the runtime.
80-
void addImageProtocolsBlockCallback(const void *baseAddress,
81-
const void *start, uintptr_t size);
82-
void addImageProtocolsBlockCallbackUnsafe(const void *baseAddress,
83-
const void *start, uintptr_t size);
84-
void addImageProtocolConformanceBlockCallback(const void *baseAddress,
85-
const void *start,
80+
void addImageProtocolsBlockCallback(const void *start, uintptr_t size);
81+
void addImageProtocolsBlockCallbackUnsafe(const void *start, uintptr_t size);
82+
void addImageProtocolConformanceBlockCallback(const void *start,
8683
uintptr_t size);
87-
void addImageProtocolConformanceBlockCallbackUnsafe(const void *baseAddress,
88-
const void *start,
84+
void addImageProtocolConformanceBlockCallbackUnsafe(const void *start,
8985
uintptr_t size);
90-
void addImageTypeMetadataRecordBlockCallback(const void *baseAddress,
91-
const void *start,
86+
void addImageTypeMetadataRecordBlockCallback(const void *start,
9287
uintptr_t size);
93-
void addImageTypeMetadataRecordBlockCallbackUnsafe(const void *baseAddress,
94-
const void *start,
88+
void addImageTypeMetadataRecordBlockCallbackUnsafe(const void *start,
9589
uintptr_t size);
96-
void addImageDynamicReplacementBlockCallback(const void *baseAddress,
97-
const void *start, uintptr_t size,
90+
void addImageDynamicReplacementBlockCallback(const void *start, uintptr_t size,
9891
const void *start2,
9992
uintptr_t size2);
100-
void addImageAccessibleFunctionsBlockCallback(const void *baseAddress,
101-
const void *start,
93+
void addImageAccessibleFunctionsBlockCallback(const void *start,
10294
uintptr_t size);
103-
void addImageAccessibleFunctionsBlockCallbackUnsafe(const void *baseAddress,
104-
const void *start,
95+
void addImageAccessibleFunctionsBlockCallbackUnsafe(const void *start,
10596
uintptr_t size);
10697

10798
int lookupSymbol(const void *address, SymbolInfo *info);

stdlib/public/runtime/ImageInspectionCommon.cpp

Lines changed: 63 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,9 @@
2828

2929
namespace swift {
3030

31-
#ifndef NDEBUG
3231
static swift::MetadataSections *registered = nullptr;
3332

34-
static void record(swift::MetadataSections *sections) {
33+
void record(swift::MetadataSections *sections) {
3534
if (registered == nullptr) {
3635
registered = sections;
3736
sections->next = sections->prev = sections;
@@ -42,67 +41,34 @@ static void record(swift::MetadataSections *sections) {
4241
registered->prev = sections;
4342
}
4443
}
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-
}
7744
}
7845

7946
SWIFT_RUNTIME_EXPORT
80-
void swift_addNewDSOImage(swift::MetadataSections *sections) {
81-
#ifndef NDEBUG
82-
record(sections);
83-
#endif
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));
8453

85-
auto baseAddress = swift::getMetadataSectionBaseAddress(sections);
54+
record(sections);
8655

8756
const auto &protocols_section = sections->swift5_protocols;
8857
const void *protocols = reinterpret_cast<void *>(protocols_section.start);
8958
if (protocols_section.length)
90-
swift::addImageProtocolsBlockCallback(baseAddress,
91-
protocols, protocols_section.length);
59+
swift::addImageProtocolsBlockCallback(protocols, protocols_section.length);
9260

9361
const auto &protocol_conformances = sections->swift5_protocol_conformances;
9462
const void *conformances =
9563
reinterpret_cast<void *>(protocol_conformances.start);
9664
if (protocol_conformances.length)
97-
swift::addImageProtocolConformanceBlockCallback(baseAddress, conformances,
65+
swift::addImageProtocolConformanceBlockCallback(conformances,
9866
protocol_conformances.length);
9967

10068
const auto &type_metadata = sections->swift5_type_metadata;
10169
const void *metadata = reinterpret_cast<void *>(type_metadata.start);
10270
if (type_metadata.length)
103-
swift::addImageTypeMetadataRecordBlockCallback(baseAddress,
104-
metadata,
105-
type_metadata.length);
71+
swift::addImageTypeMetadataRecordBlockCallback(metadata, type_metadata.length);
10672

10773
const auto &dynamic_replacements = sections->swift5_replace;
10874
const auto *replacements =
@@ -111,7 +77,7 @@ void swift_addNewDSOImage(swift::MetadataSections *sections) {
11177
const auto &dynamic_replacements_some = sections->swift5_replac2;
11278
const auto *replacements_some =
11379
reinterpret_cast<void *>(dynamic_replacements_some.start);
114-
swift::addImageDynamicReplacementBlockCallback(baseAddress,
80+
swift::addImageDynamicReplacementBlockCallback(
11581
replacements, dynamic_replacements.length, replacements_some,
11682
dynamic_replacements_some.length);
11783
}
@@ -121,22 +87,70 @@ void swift_addNewDSOImage(swift::MetadataSections *sections) {
12187
reinterpret_cast<void *>(accessible_funcs_section.start);
12288
if (accessible_funcs_section.length)
12389
swift::addImageAccessibleFunctionsBlockCallback(
124-
baseAddress, functions, accessible_funcs_section.length);
90+
functions, accessible_funcs_section.length);
12591
}
12692

12793
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+
}
128106
}
129107

130108
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+
}
131121
}
132122

133123
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+
}
134136
}
135137

136138
void swift::initializeDynamicReplacementLookup() {
137139
}
138140

139141
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+
}
140154
}
141155

142156
#ifndef NDEBUG
@@ -159,35 +173,16 @@ const swift::MetadataSections *swift_getMetadataSection(size_t index) {
159173
}
160174

161175
SWIFT_RUNTIME_EXPORT
162-
const char *
163-
swift_getMetadataSectionName(const swift::MetadataSections *section) {
176+
const char *swift_getMetadataSectionName(void *metadata_section) {
164177
swift::SymbolInfo info;
165-
if (lookupSymbol(section, &info)) {
178+
if (lookupSymbol(metadata_section, &info)) {
166179
if (info.fileName) {
167180
return info.fileName;
168181
}
169182
}
170183
return "";
171184
}
172185

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-
191186
SWIFT_RUNTIME_EXPORT
192187
size_t swift_getMetadataSectionCount() {
193188
if (swift::registered == nullptr)

stdlib/public/runtime/ImageInspectionCommon.h

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,35 +52,22 @@
5252

5353
namespace swift {
5454
struct MetadataSections;
55-
static constexpr const uintptr_t CurrentSectionMetadataVersion = 2;
55+
static constexpr const uintptr_t CurrentSectionMetadataVersion = 1;
5656
}
5757

5858
struct SectionInfo {
5959
uint64_t size;
6060
const char *data;
6161
};
6262

63-
/// Called by injected constructors when a dynamic library is loaded.
64-
///
65-
/// \param sections A structure describing the metadata sections in the
66-
/// newly-loaded image.
67-
///
68-
/// \warning The runtime keeps a reference to \a sections and may mutate it, so
69-
/// it \em must be mutable and long-lived (that is, statically or dynamically
70-
/// allocated.) The effect of passing a pointer to a local value is undefined.
63+
// Called by injected constructors when a dynamic library is loaded.
7164
SWIFT_RUNTIME_EXPORT
72-
void swift_addNewDSOImage(struct swift::MetadataSections *sections);
65+
void swift_addNewDSOImage(const void *addr);
7366

7467
#ifndef NDEBUG
7568

7669
SWIFT_RUNTIME_EXPORT
77-
const char *
78-
swift_getMetadataSectionName(const struct swift::MetadataSections *section);
79-
80-
SWIFT_RUNTIME_EXPORT
81-
void swift_getMetadataSectionBaseAddress(
82-
const struct swift::MetadataSections *section,
83-
void const **out_actual, void const **out_expected);
70+
const char *swift_getMetadataSectionName(void *metadata_section);
8471

8572
SWIFT_RUNTIME_EXPORT
8673
size_t swift_getMetadataSectionCount();

stdlib/public/runtime/ImageInspectionMachO.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ using mach_header_platform = mach_header;
5454
#endif
5555

5656
template <const char *SEGMENT_NAME, const char *SECTION_NAME,
57-
void CONSUME_BLOCK(const void *baseAddress,
58-
const void *start, uintptr_t size)>
57+
void CONSUME_BLOCK(const void *start, uintptr_t size)>
5958
void addImageCallback(const mach_header *mh) {
6059
#if __POINTER_WIDTH__ == 64
6160
assert(mh->magic == MH_MAGIC_64 && "loaded non-64-bit image?!");
@@ -71,19 +70,17 @@ void addImageCallback(const mach_header *mh) {
7170
if (!section)
7271
return;
7372

74-
CONSUME_BLOCK(mh, section, size);
73+
CONSUME_BLOCK(section, size);
7574
}
7675
template <const char *SEGMENT_NAME, const char *SECTION_NAME,
77-
void CONSUME_BLOCK(const void *baseAddress,
78-
const void *start, uintptr_t size)>
76+
void CONSUME_BLOCK(const void *start, uintptr_t size)>
7977
void addImageCallback(const mach_header *mh, intptr_t vmaddr_slide) {
8078
addImageCallback<SEGMENT_NAME, SECTION_NAME, CONSUME_BLOCK>(mh);
8179
}
8280

8381
template <const char *SEGMENT_NAME, const char *SECTION_NAME,
8482
const char *SEGMENT_NAME2, const char *SECTION_NAME2,
85-
void CONSUME_BLOCK(const void *baseAddress,
86-
const void *start, uintptr_t size,
83+
void CONSUME_BLOCK(const void *start, uintptr_t size,
8784
const void *start2, uintptr_t size2)>
8885
void addImageCallback2Sections(const mach_header *mh) {
8986
#if __POINTER_WIDTH__ == 64
@@ -109,12 +106,11 @@ void addImageCallback2Sections(const mach_header *mh) {
109106
if (!section2)
110107
size2 = 0;
111108

112-
CONSUME_BLOCK(mh, section, size, section2, size2);
109+
CONSUME_BLOCK(section, size, section2, size2);
113110
}
114111
template <const char *SEGMENT_NAME, const char *SECTION_NAME,
115112
const char *SEGMENT_NAME2, const char *SECTION_NAME2,
116-
void CONSUME_BLOCK(const void *baseAddress,
117-
const void *start, uintptr_t size,
113+
void CONSUME_BLOCK(const void *start, uintptr_t size,
118114
const void *start2, uintptr_t size2)>
119115
void addImageCallback2Sections(const mach_header *mh, intptr_t vmaddr_slide) {
120116
addImageCallback2Sections<SEGMENT_NAME, SECTION_NAME,

0 commit comments

Comments
 (0)