Skip to content

Commit 2ded9fe

Browse files
committed
Merge pull request #1466 from tinysun212/pr-common-inspect-dylib
Refactor code duplication in inspecting dylibs
2 parents c27d22d + a347f89 commit 2ded9fe

File tree

2 files changed

+83
-88
lines changed

2 files changed

+83
-88
lines changed

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 18 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,18 @@ namespace {
9191
};
9292
}
9393

94+
#if defined(__APPLE__) && defined(__MACH__)
9495
static void _initializeCallbacksToInspectDylib();
96+
#else
97+
namespace swift {
98+
void _swift_initializeCallbacksToInspectDylib(
99+
void (*fnAddImageBlock)(const uint8_t *, size_t),
100+
const char *sectionName);
101+
}
102+
103+
static void _addImageTypeMetadataRecordsBlock(const uint8_t *records,
104+
size_t recordsSize);
105+
#endif
95106

96107
struct TypeMetadataState {
97108
ConcurrentMap<TypeMetadataCacheEntry> Cache;
@@ -101,7 +112,13 @@ struct TypeMetadataState {
101112
TypeMetadataState() {
102113
SectionsToScan.reserve(16);
103114
pthread_mutex_init(&SectionsToScanLock, nullptr);
115+
#if defined(__APPLE__) && defined(__MACH__)
104116
_initializeCallbacksToInspectDylib();
117+
#else
118+
_swift_initializeCallbacksToInspectDylib(
119+
_addImageTypeMetadataRecordsBlock,
120+
SWIFT_TYPE_METADATA_SECTION);
121+
#endif
105122
}
106123
};
107124

@@ -155,72 +172,14 @@ static void _addImageTypeMetadataRecords(const mach_header *mh,
155172

156173
_addImageTypeMetadataRecordsBlock(records, recordsSize);
157174
}
158-
#elif defined(__ELF__)
159-
static int _addImageTypeMetadataRecords(struct dl_phdr_info *info,
160-
size_t size, void * /*data*/) {
161-
void *handle;
162-
if (!info->dlpi_name || info->dlpi_name[0] == '\0') {
163-
handle = dlopen(nullptr, RTLD_LAZY);
164-
} else
165-
handle = dlopen(info->dlpi_name, RTLD_LAZY | RTLD_NOLOAD);
166-
auto records = reinterpret_cast<const uint8_t*>(
167-
dlsym(handle, SWIFT_TYPE_METADATA_SECTION));
168-
169-
if (!records) {
170-
// if there are no type metadata records, don't hold this handle open.
171-
dlclose(handle);
172-
return 0;
173-
}
174-
175-
// Extract the size of the type metadata block from the head of the section
176-
auto recordsSize = *reinterpret_cast<const uint64_t*>(records);
177-
records += sizeof(recordsSize);
178-
179-
_addImageTypeMetadataRecordsBlock(records, recordsSize);
180-
181-
dlclose(handle);
182-
return 0;
183-
}
184-
#elif defined(__CYGWIN__)
185-
static int _addImageTypeMetadataRecords(struct dl_phdr_info *info,
186-
size_t size, void * /*data*/) {
187-
void *handle;
188-
if (!info->dlpi_name || info->dlpi_name[0] == '\0') {
189-
handle = dlopen(nullptr, RTLD_LAZY);
190-
} else
191-
handle = dlopen(info->dlpi_name, RTLD_LAZY | RTLD_NOLOAD);
192-
193-
unsigned long recordsSize;
194-
const uint8_t *records =
195-
_swift_getSectionDataPE(handle, SWIFT_TYPE_METADATA_SECTION,
196-
&recordsSize);
197-
198-
if (records) {
199-
_addImageTypeMetadataRecordsBlock(records, recordsSize);
200-
}
201-
dlclose(handle);
202-
return 0;
203-
}
204-
#endif
205175

206176
static void _initializeCallbacksToInspectDylib() {
207-
#if defined(__APPLE__) && defined(__MACH__)
208177
// Install our dyld callback.
209178
// Dyld will invoke this on our behalf for all images that have already
210179
// been loaded.
211180
_dyld_register_func_for_add_image(_addImageTypeMetadataRecords);
212-
#elif defined(__ELF__)
213-
// Search the loaded dls. Unlike the above, this only searches the already
214-
// loaded ones.
215-
// FIXME: Find a way to have this continue to happen after.
216-
// rdar://problem/19045112
217-
dl_iterate_phdr(_addImageTypeMetadataRecords, nullptr);
218-
#elif defined(__CYGWIN__)
219-
_swift_dl_iterate_phdr(_addImageTypeMetadataRecords, nullptr);
220-
#else
221-
# error No known mechanism to inspect dynamic libraries on this platform.
222-
#endif
223181
}
182+
#endif
224183

225184
void
226185
swift::swift_registerTypeMetadataRecords(const TypeMetadataRecord *begin,

stdlib/public/runtime/ProtocolConformance.cpp

Lines changed: 65 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,18 @@ namespace {
226226
}
227227

228228
// Conformance Cache.
229-
229+
#if defined(__APPLE__) && defined(__MACH__)
230230
static void _initializeCallbacksToInspectDylib();
231+
#else
232+
namespace swift {
233+
void _swift_initializeCallbacksToInspectDylib(
234+
void (*fnAddImageBlock)(const uint8_t *, size_t),
235+
const char *sectionName);
236+
}
237+
238+
static void _addImageProtocolConformancesBlock(const uint8_t *conformances,
239+
size_t conformancesSize);
240+
#endif
231241

232242
struct ConformanceState {
233243
ConcurrentMap<ConformanceCacheEntry> Cache;
@@ -237,7 +247,13 @@ struct ConformanceState {
237247
ConformanceState() {
238248
SectionsToScan.reserve(16);
239249
pthread_mutex_init(&SectionsToScanLock, nullptr);
250+
#if defined(__APPLE__) && defined(__MACH__)
240251
_initializeCallbacksToInspectDylib();
252+
#else
253+
_swift_initializeCallbacksToInspectDylib(
254+
_addImageProtocolConformancesBlock,
255+
SWIFT_PROTOCOL_CONFORMANCES_SECTION);
256+
#endif
241257
}
242258

243259
void cacheSuccess(const void *type, const ProtocolDescriptor *proto,
@@ -297,6 +313,14 @@ static void _addImageProtocolConformancesBlock(const uint8_t *conformances,
297313
recordsBegin, recordsEnd);
298314
}
299315

316+
#if !defined(__APPLE__) || !defined(__MACH__)
317+
// Common Structure
318+
struct InspectArgs {
319+
void (*fnAddImageBlock)(const uint8_t *, size_t);
320+
const char *sectionName;
321+
};
322+
#endif
323+
300324
#if defined(__APPLE__) && defined(__MACH__)
301325
static void _addImageProtocolConformances(const mach_header *mh,
302326
intptr_t vmaddr_slide) {
@@ -319,16 +343,27 @@ static void _addImageProtocolConformances(const mach_header *mh,
319343

320344
_addImageProtocolConformancesBlock(conformances, conformancesSize);
321345
}
346+
347+
static void _initializeCallbacksToInspectDylib() {
348+
// Install our dyld callback.
349+
// Dyld will invoke this on our behalf for all images that have already
350+
// been loaded.
351+
_dyld_register_func_for_add_image(_addImageProtocolConformances);
352+
}
353+
322354
#elif defined(__ELF__)
323355
static int _addImageProtocolConformances(struct dl_phdr_info *info,
324-
size_t size, void * /*data*/) {
356+
size_t size, void *data) {
357+
// inspectArgs contains addImage*Block function and the section name
358+
InspectArgs *inspectArgs = reinterpret_cast<InspectArgs *>(data);
359+
325360
void *handle;
326361
if (!info->dlpi_name || info->dlpi_name[0] == '\0') {
327362
handle = dlopen(nullptr, RTLD_LAZY);
328363
} else
329364
handle = dlopen(info->dlpi_name, RTLD_LAZY | RTLD_NOLOAD);
330365
auto conformances = reinterpret_cast<const uint8_t*>(
331-
dlsym(handle, SWIFT_PROTOCOL_CONFORMANCES_SECTION));
366+
dlsym(handle, inspectArgs->sectionName));
332367

333368
if (!conformances) {
334369
// if there are no conformances, don't hold this handle open.
@@ -340,14 +375,29 @@ static int _addImageProtocolConformances(struct dl_phdr_info *info,
340375
auto conformancesSize = *reinterpret_cast<const uint64_t*>(conformances);
341376
conformances += sizeof(conformancesSize);
342377

343-
_addImageProtocolConformancesBlock(conformances, conformancesSize);
378+
inspectArgs->fnAddImageBlock(conformances, conformancesSize);
344379

345380
dlclose(handle);
346381
return 0;
347382
}
383+
384+
void swift::_swift_initializeCallbacksToInspectDylib(
385+
void (*fnAddImageBlock)(const uint8_t *, size_t),
386+
const char *sectionName) {
387+
InspectArgs inspectArgs = {fnAddImageBlock, sectionName};
388+
389+
// Search the loaded dls. Unlike the above, this only searches the already
390+
// loaded ones.
391+
// FIXME: Find a way to have this continue to happen after.
392+
// rdar://problem/19045112
393+
dl_iterate_phdr(_addImageProtocolConformances, &inspectArgs);
394+
}
348395
#elif defined(__CYGWIN__)
349396
static int _addImageProtocolConformances(struct dl_phdr_info *info,
350-
size_t size, void * /*data*/) {
397+
size_t size, void *data) {
398+
InspectArgs *inspectArgs = (InspectArgs *)data;
399+
// inspectArgs contains addImage*Block function and the section name
400+
351401
void *handle;
352402
if (!info->dlpi_name || info->dlpi_name[0] == '\0') {
353403
handle = dlopen(nullptr, RTLD_LAZY);
@@ -356,40 +406,26 @@ static int _addImageProtocolConformances(struct dl_phdr_info *info,
356406

357407
unsigned long conformancesSize;
358408
const uint8_t *conformances =
359-
_swift_getSectionDataPE(handle, SWIFT_PROTOCOL_CONFORMANCES_SECTION,
409+
_swift_getSectionDataPE(handle, inspectArgs->sectionName,
360410
&conformancesSize);
361411

362-
if (!conformances) {
363-
// if there are no conformances, don't hold this handle open.
364-
dlclose(handle);
365-
return 0;
366-
}
367-
368-
_addImageProtocolConformancesBlock(conformances, conformancesSize);
412+
if (conformances)
413+
inspectArgs->fnAddImageBlock(conformances, conformancesSize);
369414

370415
dlclose(handle);
371416
return 0;
372417
}
373-
#endif
374418

375-
static void _initializeCallbacksToInspectDylib() {
376-
#if defined(__APPLE__) && defined(__MACH__)
377-
// Install our dyld callback.
378-
// Dyld will invoke this on our behalf for all images that have already
379-
// been loaded.
380-
_dyld_register_func_for_add_image(_addImageProtocolConformances);
381-
#elif defined(__ELF__)
382-
// Search the loaded dls. Unlike the above, this only searches the already
383-
// loaded ones.
384-
// FIXME: Find a way to have this continue to happen after.
385-
// rdar://problem/19045112
386-
dl_iterate_phdr(_addImageProtocolConformances, nullptr);
387-
#elif defined(__CYGWIN__)
388-
_swift_dl_iterate_phdr(_addImageProtocolConformances, nullptr);
419+
void swift::_swift_initializeCallbacksToInspectDylib(
420+
void (*fnAddImageBlock)(const uint8_t *, size_t),
421+
const char *sectionName) {
422+
InspectArgs inspectArgs = {fnAddImageBlock, sectionName};
423+
424+
_swift_dl_iterate_phdr(_addImageProtocolConformances, &inspectArgs);
425+
}
389426
#else
390427
# error No known mechanism to inspect dynamic libraries on this platform.
391428
#endif
392-
}
393429

394430
// This variable is used to signal when a cache was generated and
395431
// it is correct to avoid a new scan.

0 commit comments

Comments
 (0)