Skip to content

Commit 5a3d2a9

Browse files
authored
Merge pull request #30866 from jckarter/objc_getClass_compat_hook_main_only
Compatibility50: Install objc_getClass hook only in main executable
2 parents 0d10132 + 4c92234 commit 5a3d2a9

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

stdlib/toolchain/Compatibility50/Overrides.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "../../public/runtime/CompatibilityOverride.h"
1919

2020
#include <dlfcn.h>
21+
#include <mach-o/dyld.h>
22+
#include <mach-o/getsect.h>
2123

2224
using namespace swift;
2325

@@ -70,8 +72,29 @@ getObjCClassByMangledName_untrusted(const char * _Nonnull typeName,
7072
return NO;
7173
}
7274

75+
#if __POINTER_WIDTH__ == 64
76+
using mach_header_platform = mach_header_64;
77+
#else
78+
using mach_header_platform = mach_header;
79+
#endif
80+
7381
__attribute__((constructor))
7482
static void installGetClassHook_untrusted() {
83+
// swiftCompatibility* might be linked into multiple dynamic libraries because
84+
// of build system reasons, but the copy in the main executable is the only
85+
// one that should count. Bail early unless we're running out of the main
86+
// executable.
87+
//
88+
// Newer versions of dyld add additional API that can determine this more
89+
// efficiently, but we have to support back to OS X 10.9/iOS 7, so dladdr
90+
// is the only API that reaches back that far.
91+
Dl_info dlinfo;
92+
if (dladdr((const void*)(uintptr_t)installGetClassHook_untrusted, &dlinfo) == 0)
93+
return;
94+
auto machHeader = (const mach_header_platform *)dlinfo.dli_fbase;
95+
if (machHeader->filetype != MH_EXECUTE)
96+
return;
97+
7598
// FIXME: delete this #if and dlsym once we don't
7699
// need to build with older libobjc headers
77100
#if !OBJC_GETCLASSHOOK_DEFINED

0 commit comments

Comments
 (0)