Skip to content

Commit 2ac0ab0

Browse files
committed
[Runtime] Use objc_addLoadImageFunc when available to find out about newly loaded images.
rdar://problem/49742015
1 parent 7696a76 commit 2ac0ab0

File tree

2 files changed

+38
-6
lines changed

2 files changed

+38
-6
lines changed

stdlib/public/runtime/ImageInspectionMachO.cpp

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "ImageInspection.h"
2424
#include <mach-o/dyld.h>
2525
#include <mach-o/getsect.h>
26+
#include <objc/runtime.h>
2627
#include <assert.h>
2728
#include <dlfcn.h>
2829

@@ -55,7 +56,7 @@ extern "C" void *_NSGetMachExecuteHeader();
5556

5657
template <const char *SEGMENT_NAME, const char *SECTION_NAME,
5758
void CONSUME_BLOCK(const void *start, uintptr_t size)>
58-
void addImageCallback(const mach_header *mh, intptr_t vmaddr_slide) {
59+
void addImageCallback(const mach_header *mh) {
5960
#if __POINTER_WIDTH__ == 64
6061
assert(mh->magic == MH_MAGIC_64 && "loaded non-64-bit image?!");
6162
#endif
@@ -72,12 +73,17 @@ void addImageCallback(const mach_header *mh, intptr_t vmaddr_slide) {
7273

7374
CONSUME_BLOCK(section, size);
7475
}
76+
template <const char *SEGMENT_NAME, const char *SECTION_NAME,
77+
void CONSUME_BLOCK(const void *start, uintptr_t size)>
78+
void addImageCallback(const mach_header *mh, intptr_t vmaddr_slide) {
79+
addImageCallback<SEGMENT_NAME, SECTION_NAME, CONSUME_BLOCK>(mh);
80+
}
7581

7682
template <const char *SEGMENT_NAME, const char *SECTION_NAME,
7783
const char *SEGMENT_NAME2, const char *SECTION_NAME2,
7884
void CONSUME_BLOCK(const void *start, uintptr_t size,
7985
const void *start2, uintptr_t size2)>
80-
void addImageCallback2Sections(const mach_header *mh, intptr_t vmaddr_slide) {
86+
void addImageCallback2Sections(const mach_header *mh) {
8187
#if __POINTER_WIDTH__ == 64
8288
assert(mh->magic == MH_MAGIC_64 && "loaded non-64-bit image?!");
8389
#endif
@@ -103,27 +109,48 @@ void addImageCallback2Sections(const mach_header *mh, intptr_t vmaddr_slide) {
103109

104110
CONSUME_BLOCK(section, size, section2, size2);
105111
}
112+
template <const char *SEGMENT_NAME, const char *SECTION_NAME,
113+
const char *SEGMENT_NAME2, const char *SECTION_NAME2,
114+
void CONSUME_BLOCK(const void *start, uintptr_t size,
115+
const void *start2, uintptr_t size2)>
116+
void addImageCallback2Sections(const mach_header *mh, intptr_t vmaddr_slide) {
117+
addImageCallback2Sections<SEGMENT_NAME, SECTION_NAME,
118+
SEGMENT_NAME2, SECTION_NAME2,
119+
CONSUME_BLOCK>(mh);
120+
}
121+
106122
} // end anonymous namespace
107123

124+
#if OBJC_ADDLOADIMAGEFUNC_DEFINED
125+
#define REGISTER_FUNC(...) \
126+
if (__builtin_available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)) { \
127+
objc_addLoadImageFunc(__VA_ARGS__); \
128+
} else { \
129+
_dyld_register_func_for_add_image(__VA_ARGS__); \
130+
}
131+
#else
132+
#define REGISTER_FUNC(...) _dyld_register_func_for_add_image(__VA_ARGS__)
133+
#endif
134+
108135
void swift::initializeProtocolLookup() {
109-
_dyld_register_func_for_add_image(
136+
REGISTER_FUNC(
110137
addImageCallback<TextSegment, ProtocolsSection,
111138
addImageProtocolsBlockCallback>);
112139
}
113140

114141
void swift::initializeProtocolConformanceLookup() {
115-
_dyld_register_func_for_add_image(
142+
REGISTER_FUNC(
116143
addImageCallback<TextSegment, ProtocolConformancesSection,
117144
addImageProtocolConformanceBlockCallback>);
118145
}
119146
void swift::initializeTypeMetadataRecordLookup() {
120-
_dyld_register_func_for_add_image(
147+
REGISTER_FUNC(
121148
addImageCallback<TextSegment, TypeMetadataRecordSection,
122149
addImageTypeMetadataRecordBlockCallback>);
123150
}
124151

125152
void swift::initializeDynamicReplacementLookup() {
126-
_dyld_register_func_for_add_image(
153+
REGISTER_FUNC(
127154
addImageCallback2Sections<TextSegment, DynamicReplacementSection,
128155
TextSegment, DynamicReplacementSomeSection,
129156
addImageDynamicReplacementBlockCallback>);

test/stdlib/dlopen_race.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ func register_func_for_add_image(_ f: add_image_callback) {
3030
// for them to be used. rdar://problem/49742015
3131
var add_image_count = 0
3232
DlopenRaceTests.test("race") {
33+
// This test is expected to fail unless the ObjC notification is supported.
34+
let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: -2)
35+
let objc_addLoadImageFunc = dlsym(RTLD_DEFAULT, "objc_addLoadImageFunc");
36+
if objc_addLoadImageFunc == nil { return }
37+
3338
register_func_for_add_image({ header, slide in
3439
// The protocol conformance check in the print call is enough to trigger
3540
// ObjC class initialization in the newly opened image if Swift has

0 commit comments

Comments
 (0)