Skip to content

Commit e303c22

Browse files
committed
[Runtime] Use dyld SPI for getting macho sections when available.
When available, use objc_addLoadImageFunc2 and _dyld_register_func_for_add_image to look up mach-o sections instead of using getsectiondata. When not available, we fall back to objc_addLoadImageFunc or _dyld_register_func_for_add_image and getsectiondata as before. rdar://51760462
1 parent 3bf7805 commit e303c22

File tree

1 file changed

+95
-16
lines changed

1 file changed

+95
-16
lines changed

stdlib/public/runtime/ImageInspectionMachO.cpp

Lines changed: 95 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,31 @@
3030
#include <assert.h>
3131
#include <dlfcn.h>
3232

33+
#if __has_include(<objc/objc-internal.h>) && __has_include(<mach-o/dyld_priv.h>)
34+
#include <mach-o/dyld_priv.h>
35+
#include <objc/objc-internal.h>
36+
#else
37+
38+
// Bring our own definition of enum _dyld_section_location_kind and some of its
39+
// values. They'll be unused when we can't include dyld_priv.h, but the code
40+
// needs them in order to compile.
41+
enum _dyld_section_location_kind {
42+
_dyld_section_location_text_swift5_protos,
43+
_dyld_section_location_text_swift5_proto,
44+
_dyld_section_location_text_swift5_types,
45+
_dyld_section_location_text_swift5_replace,
46+
_dyld_section_location_text_swift5_replace2,
47+
_dyld_section_location_text_swift5_ac_funcs,
48+
};
49+
50+
#endif
51+
52+
#if !OBJC_ADDLOADIMAGEFUNC2_DEFINED
53+
// If we don't have objc_addLoadImageFunc2, fall back to objc_addLoadImageFunc.
54+
// Use a #define so we don't have to conditionalize the calling code below.
55+
#define objc_addLoadImageFunc2 objc_addLoadImageFunc
56+
#endif
57+
3358
using namespace swift;
3459

3560
namespace {
@@ -54,34 +79,51 @@ using mach_header_platform = mach_header;
5479
#endif
5580

5681
template <const char *SEGMENT_NAME, const char *SECTION_NAME,
57-
void CONSUME_BLOCK(const void *baseAddress,
58-
const void *start, uintptr_t size)>
82+
enum _dyld_section_location_kind SECTION_KIND,
83+
void CONSUME_BLOCK(const void *baseAddress, const void *start,
84+
uintptr_t size)>
5985
void addImageCallback(const mach_header *mh) {
6086
#if __POINTER_WIDTH__ == 64
6187
assert(mh->magic == MH_MAGIC_64 && "loaded non-64-bit image?!");
6288
#endif
63-
64-
// Look for a __swift5_proto section.
89+
6590
unsigned long size;
6691
const uint8_t *section =
6792
getsectiondata(reinterpret_cast<const mach_header_platform *>(mh),
6893
SEGMENT_NAME, SECTION_NAME,
6994
&size);
70-
95+
7196
if (!section)
7297
return;
73-
98+
7499
CONSUME_BLOCK(mh, section, size);
75100
}
76101
template <const char *SEGMENT_NAME, const char *SECTION_NAME,
77-
void CONSUME_BLOCK(const void *baseAddress,
78-
const void *start, uintptr_t size)>
102+
enum _dyld_section_location_kind SECTION_KIND,
103+
void CONSUME_BLOCK(const void *baseAddress, const void *start,
104+
uintptr_t size)>
105+
void addImageCallback(const mach_header *mh,
106+
struct _dyld_section_location_info_s *dyldInfo) {
107+
#if __POINTER_WIDTH__ == 64
108+
assert(mh->magic == MH_MAGIC_64 && "loaded non-64-bit image?!");
109+
#endif
110+
111+
auto result = _dyld_lookup_section_info(mh, dyldInfo, SECTION_KIND);
112+
if (result.buffer)
113+
CONSUME_BLOCK(mh, result.buffer, result.bufferSize);
114+
}
115+
template <const char *SEGMENT_NAME, const char *SECTION_NAME,
116+
enum _dyld_section_location_kind SECTION_KIND,
117+
void CONSUME_BLOCK(const void *baseAddress, const void *start,
118+
uintptr_t size)>
79119
void addImageCallback(const mach_header *mh, intptr_t vmaddr_slide) {
80-
addImageCallback<SEGMENT_NAME, SECTION_NAME, CONSUME_BLOCK>(mh);
120+
addImageCallback<SEGMENT_NAME, SECTION_NAME, SECTION_KIND, CONSUME_BLOCK>(mh);
81121
}
82122

83123
template <const char *SEGMENT_NAME, const char *SECTION_NAME,
84124
const char *SEGMENT_NAME2, const char *SECTION_NAME2,
125+
enum _dyld_section_location_kind SECTION_KIND,
126+
enum _dyld_section_location_kind SECTION_KIND2,
85127
void CONSUME_BLOCK(const void *baseAddress,
86128
const void *start, uintptr_t size,
87129
const void *start2, uintptr_t size2)>
@@ -113,23 +155,54 @@ void addImageCallback2Sections(const mach_header *mh) {
113155
}
114156
template <const char *SEGMENT_NAME, const char *SECTION_NAME,
115157
const char *SEGMENT_NAME2, const char *SECTION_NAME2,
158+
enum _dyld_section_location_kind SECTION_KIND,
159+
enum _dyld_section_location_kind SECTION_KIND2,
116160
void CONSUME_BLOCK(const void *baseAddress,
117161
const void *start, uintptr_t size,
118162
const void *start2, uintptr_t size2)>
163+
void addImageCallback2Sections(const mach_header *mh,
164+
struct _dyld_section_location_info_s *dyldInfo) {
165+
#if __POINTER_WIDTH__ == 64
166+
assert(mh->magic == MH_MAGIC_64 && "loaded non-64-bit image?!");
167+
#endif
168+
169+
// Look for a section.
170+
auto result = _dyld_lookup_section_info(mh, dyldInfo, SECTION_KIND);
171+
if (!result.buffer)
172+
return;
173+
174+
auto result2 = _dyld_lookup_section_info(mh, dyldInfo, SECTION_KIND2);
175+
// No NULL check here, we allow this one not to be present. dyld gives us
176+
// a NULL pointer and 0 size when the section isn't in the dylib so we don't
177+
// need to zero anything out.
178+
179+
CONSUME_BLOCK(mh, result.buffer, result.bufferSize, result2.buffer,
180+
result2.bufferSize);
181+
}
182+
template <const char *SEGMENT_NAME, const char *SECTION_NAME,
183+
const char *SEGMENT_NAME2, const char *SECTION_NAME2,
184+
enum _dyld_section_location_kind SECTION_KIND,
185+
enum _dyld_section_location_kind SECTION_KIND2,
186+
void CONSUME_BLOCK(const void *baseAddress, const void *start,
187+
uintptr_t size, const void *start2,
188+
uintptr_t size2)>
119189
void addImageCallback2Sections(const mach_header *mh, intptr_t vmaddr_slide) {
120-
addImageCallback2Sections<SEGMENT_NAME, SECTION_NAME,
121-
SEGMENT_NAME2, SECTION_NAME2,
190+
addImageCallback2Sections<SEGMENT_NAME, SECTION_NAME, SEGMENT_NAME2,
191+
SECTION_NAME2, SECTION_KIND, SECTION_KIND2,
122192
CONSUME_BLOCK>(mh);
123193
}
124194

125195
} // end anonymous namespace
126196

127197
#if OBJC_ADDLOADIMAGEFUNC_DEFINED && SWIFT_OBJC_INTEROP
128-
#define REGISTER_FUNC(...) \
129-
if (__builtin_available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)) { \
130-
objc_addLoadImageFunc(__VA_ARGS__); \
131-
} else { \
132-
_dyld_register_func_for_add_image(__VA_ARGS__); \
198+
#define REGISTER_FUNC(...) \
199+
if (SWIFT_RUNTIME_WEAK_CHECK(objc_addLoadImageFunc2)) { \
200+
SWIFT_RUNTIME_WEAK_USE(objc_addLoadImageFunc2(__VA_ARGS__)); \
201+
} else if (__builtin_available(macOS 10.15, iOS 13, tvOS 13, \
202+
watchOS 6, *)) { \
203+
objc_addLoadImageFunc(__VA_ARGS__); \
204+
} else { \
205+
_dyld_register_func_for_add_image(__VA_ARGS__); \
133206
}
134207
#else
135208
#define REGISTER_FUNC(...) _dyld_register_func_for_add_image(__VA_ARGS__)
@@ -144,30 +217,36 @@ void addImageCallback2Sections(const mach_header *mh, intptr_t vmaddr_slide) {
144217

145218
void swift::initializeProtocolLookup() {
146219
REGISTER_FUNC(addImageCallback<TextSegment, ProtocolsSection,
220+
_dyld_section_location_text_swift5_protos,
147221
addImageProtocolsBlockCallbackUnsafe>);
148222
}
149223

150224
void swift::initializeProtocolConformanceLookup() {
151225
REGISTER_FUNC(
152226
addImageCallback<TextSegment, ProtocolConformancesSection,
227+
_dyld_section_location_text_swift5_proto,
153228
addImageProtocolConformanceBlockCallbackUnsafe>);
154229
}
155230
void swift::initializeTypeMetadataRecordLookup() {
156231
REGISTER_FUNC(
157232
addImageCallback<TextSegment, TypeMetadataRecordSection,
233+
_dyld_section_location_text_swift5_types,
158234
addImageTypeMetadataRecordBlockCallbackUnsafe>);
159235
}
160236

161237
void swift::initializeDynamicReplacementLookup() {
162238
REGISTER_FUNC(
163239
addImageCallback2Sections<TextSegment, DynamicReplacementSection,
164240
TextSegment, DynamicReplacementSomeSection,
241+
_dyld_section_location_text_swift5_replace,
242+
_dyld_section_location_text_swift5_replace2,
165243
addImageDynamicReplacementBlockCallback>);
166244
}
167245

168246
void swift::initializeAccessibleFunctionsLookup() {
169247
REGISTER_FUNC(
170248
addImageCallback<TextSegment, AccessibleFunctionsSection,
249+
_dyld_section_location_text_swift5_ac_funcs,
171250
addImageAccessibleFunctionsBlockCallbackUnsafe>);
172251
}
173252

0 commit comments

Comments
 (0)