Skip to content

Commit a347f89

Browse files
committed
Refactor code duplication in inspecting dylibs
MetadataLookup.cpp and ProtocolConformance.cpp has same part for inspecting dynamic libraries. The common code exist in one file and other uses it. This uses the argument passing to callback in Linux/Cygwin and not applied to OS X.
1 parent f86f9f0 commit a347f89

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
@@ -224,8 +224,18 @@ namespace {
224224
}
225225

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

230240
struct ConformanceState {
231241
ConcurrentMap<ConformanceCacheEntry> Cache;
@@ -235,7 +245,13 @@ struct ConformanceState {
235245
ConformanceState() {
236246
SectionsToScan.reserve(16);
237247
pthread_mutex_init(&SectionsToScanLock, nullptr);
248+
#if defined(__APPLE__) && defined(__MACH__)
238249
_initializeCallbacksToInspectDylib();
250+
#else
251+
_swift_initializeCallbacksToInspectDylib(
252+
_addImageProtocolConformancesBlock,
253+
SWIFT_PROTOCOL_CONFORMANCES_SECTION);
254+
#endif
239255
}
240256

241257
void cacheSuccess(const void *type, const ProtocolDescriptor *proto,
@@ -295,6 +311,14 @@ static void _addImageProtocolConformancesBlock(const uint8_t *conformances,
295311
recordsBegin, recordsEnd);
296312
}
297313

314+
#if !defined(__APPLE__) || !defined(__MACH__)
315+
// Common Structure
316+
struct InspectArgs {
317+
void (*fnAddImageBlock)(const uint8_t *, size_t);
318+
const char *sectionName;
319+
};
320+
#endif
321+
298322
#if defined(__APPLE__) && defined(__MACH__)
299323
static void _addImageProtocolConformances(const mach_header *mh,
300324
intptr_t vmaddr_slide) {
@@ -317,16 +341,27 @@ static void _addImageProtocolConformances(const mach_header *mh,
317341

318342
_addImageProtocolConformancesBlock(conformances, conformancesSize);
319343
}
344+
345+
static void _initializeCallbacksToInspectDylib() {
346+
// Install our dyld callback.
347+
// Dyld will invoke this on our behalf for all images that have already
348+
// been loaded.
349+
_dyld_register_func_for_add_image(_addImageProtocolConformances);
350+
}
351+
320352
#elif defined(__ELF__)
321353
static int _addImageProtocolConformances(struct dl_phdr_info *info,
322-
size_t size, void * /*data*/) {
354+
size_t size, void *data) {
355+
// inspectArgs contains addImage*Block function and the section name
356+
InspectArgs *inspectArgs = reinterpret_cast<InspectArgs *>(data);
357+
323358
void *handle;
324359
if (!info->dlpi_name || info->dlpi_name[0] == '\0') {
325360
handle = dlopen(nullptr, RTLD_LAZY);
326361
} else
327362
handle = dlopen(info->dlpi_name, RTLD_LAZY | RTLD_NOLOAD);
328363
auto conformances = reinterpret_cast<const uint8_t*>(
329-
dlsym(handle, SWIFT_PROTOCOL_CONFORMANCES_SECTION));
364+
dlsym(handle, inspectArgs->sectionName));
330365

331366
if (!conformances) {
332367
// if there are no conformances, don't hold this handle open.
@@ -338,14 +373,29 @@ static int _addImageProtocolConformances(struct dl_phdr_info *info,
338373
auto conformancesSize = *reinterpret_cast<const uint64_t*>(conformances);
339374
conformances += sizeof(conformancesSize);
340375

341-
_addImageProtocolConformancesBlock(conformances, conformancesSize);
376+
inspectArgs->fnAddImageBlock(conformances, conformancesSize);
342377

343378
dlclose(handle);
344379
return 0;
345380
}
381+
382+
void swift::_swift_initializeCallbacksToInspectDylib(
383+
void (*fnAddImageBlock)(const uint8_t *, size_t),
384+
const char *sectionName) {
385+
InspectArgs inspectArgs = {fnAddImageBlock, sectionName};
386+
387+
// Search the loaded dls. Unlike the above, this only searches the already
388+
// loaded ones.
389+
// FIXME: Find a way to have this continue to happen after.
390+
// rdar://problem/19045112
391+
dl_iterate_phdr(_addImageProtocolConformances, &inspectArgs);
392+
}
346393
#elif defined(__CYGWIN__)
347394
static int _addImageProtocolConformances(struct dl_phdr_info *info,
348-
size_t size, void * /*data*/) {
395+
size_t size, void *data) {
396+
InspectArgs *inspectArgs = (InspectArgs *)data;
397+
// inspectArgs contains addImage*Block function and the section name
398+
349399
void *handle;
350400
if (!info->dlpi_name || info->dlpi_name[0] == '\0') {
351401
handle = dlopen(nullptr, RTLD_LAZY);
@@ -354,40 +404,26 @@ static int _addImageProtocolConformances(struct dl_phdr_info *info,
354404

355405
unsigned long conformancesSize;
356406
const uint8_t *conformances =
357-
_swift_getSectionDataPE(handle, SWIFT_PROTOCOL_CONFORMANCES_SECTION,
407+
_swift_getSectionDataPE(handle, inspectArgs->sectionName,
358408
&conformancesSize);
359409

360-
if (!conformances) {
361-
// if there are no conformances, don't hold this handle open.
362-
dlclose(handle);
363-
return 0;
364-
}
365-
366-
_addImageProtocolConformancesBlock(conformances, conformancesSize);
410+
if (conformances)
411+
inspectArgs->fnAddImageBlock(conformances, conformancesSize);
367412

368413
dlclose(handle);
369414
return 0;
370415
}
371-
#endif
372416

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

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

0 commit comments

Comments
 (0)