Skip to content

Compatibility50: Install objc_getClass hook only in main executable #30866

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions stdlib/toolchain/Compatibility50/Overrides.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include "../../public/runtime/CompatibilityOverride.h"

#include <dlfcn.h>
#include <mach-o/dyld.h>
#include <mach-o/getsect.h>

using namespace swift;

Expand Down Expand Up @@ -70,8 +72,29 @@ getObjCClassByMangledName_untrusted(const char * _Nonnull typeName,
return NO;
}

#if __POINTER_WIDTH__ == 64
using mach_header_platform = mach_header_64;
#else
using mach_header_platform = mach_header;
#endif

__attribute__((constructor))
static void installGetClassHook_untrusted() {
// swiftCompatibility* might be linked into multiple dynamic libraries because
// of build system reasons, but the copy in the main executable is the only
// one that should count. Bail early unless we're running out of the main
// executable.
//
// Newer versions of dyld add additional API that can determine this more
// efficiently, but we have to support back to OS X 10.9/iOS 7, so dladdr
// is the only API that reaches back that far.
Dl_info dlinfo;
if (dladdr((const void*)(uintptr_t)installGetClassHook_untrusted, &dlinfo) == 0)
return;
auto machHeader = (const mach_header_platform *)dlinfo.dli_fbase;
if (machHeader->filetype != MH_EXECUTE)
return;

// FIXME: delete this #if and dlsym once we don't
// need to build with older libobjc headers
#if !OBJC_GETCLASSHOOK_DEFINED
Expand Down