Skip to content

Commit 5d32946

Browse files
committed
Use thread private key to avoid weak linkage
We use one bit of the third reserved swift private tls key. Also move the functionality into a separate static archive that is always linked dependent on deployment target.
1 parent da2d418 commit 5d32946

File tree

14 files changed

+66
-30
lines changed

14 files changed

+66
-30
lines changed

cmake/modules/SwiftSource.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ function(_compile_swift_files
269269
# into the new runtime.
270270
if (SWIFTFILE_IS_STDLIB OR SWIFTFILE_IS_SDK_OVERLAY)
271271
list(APPEND swift_flags "-runtime-compatibility-version" "none")
272+
list(APPEND swift_flags "-disable-autolinking-runtime-compatibility-dynamic-replacements")
272273
endif()
273274

274275
if (SWIFTFILE_IS_STDLIB_CORE OR SWIFTFILE_IS_SDK_OVERLAY)

include/swift/AST/IRGenOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ class IRGenOptions {
228228

229229
/// Pull in runtime compatibility shim libraries by autolinking.
230230
Optional<llvm::VersionTuple> AutolinkRuntimeCompatibilityLibraryVersion;
231+
Optional<llvm::VersionTuple> AutolinkRuntimeCompatibilityDynamicReplacementLibraryVersion;
231232

232233
IRGenOptions()
233234
: DWARFVersion(2), OutputKind(IRGenOutputKind::LLVMAssembly),

include/swift/Option/Options.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,4 +904,10 @@ def disable_autolinking_runtime_compatibility : Flag<["-"], "disable-autolinking
904904
Flags<[FrontendOption]>,
905905
HelpText<"Do not use autolinking for runtime compatibility libraries">;
906906

907+
def disable_autolinking_runtime_compatibility_dynamic_replacements
908+
: Flag<[ "-" ],
909+
"disable-autolinking-runtime-compatibility-dynamic-replacements">,
910+
Flags<[ FrontendOption ]>,
911+
HelpText<"Do not use autolinking for runtime compatibility libraries">;
912+
907913
include "FrontendOptions.td"

lib/Driver/ToolChains.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,12 @@ ToolChain::constructInvocation(const CompileJobAction &job,
446446
Arguments.push_back(arg->getValue());
447447
}
448448

449+
if (context.Args.hasArg(options::
450+
OPT_disable_autolinking_runtime_compatibility_dynamic_replacements)) {
451+
Arguments.push_back(
452+
"-disable-autolinking-runtime-compatibility-dynamic-replacements");
453+
}
454+
449455
return II;
450456
}
451457

lib/Frontend/CompilerInvocation.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,6 +1178,11 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
11781178
runtimeCompatibilityVersion;
11791179
}
11801180

1181+
if (!Args.hasArg(options::
1182+
OPT_disable_autolinking_runtime_compatibility_dynamic_replacements)) {
1183+
Opts.AutolinkRuntimeCompatibilityDynamicReplacementLibraryVersion =
1184+
getSwiftRuntimeCompatibilityVersionForTarget(Triple);
1185+
}
11811186
return false;
11821187
}
11831188

lib/IRGen/GenDecl.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,15 @@ void IRGenModule::emitSourceFile(SourceFile &SF) {
468468
/*forceLoad*/ true));
469469
}
470470
}
471+
472+
if (auto compatibilityVersion =
473+
IRGen.Opts.AutolinkRuntimeCompatibilityDynamicReplacementLibraryVersion) {
474+
if (*compatibilityVersion <= llvm::VersionTuple(5, 0)) {
475+
this->addLinkLibrary(LinkLibrary("swiftCompatibilityDynamicReplacements",
476+
LibraryKind::Library,
477+
/*forceLoad*/ true));
478+
}
479+
}
471480
}
472481
}
473482

stdlib/public/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ if(SWIFT_BUILD_STDLIB)
6262
add_subdirectory(core)
6363
add_subdirectory(SwiftOnoneSupport)
6464
add_subdirectory(Compatibility50)
65+
add_subdirectory(CompatibilityDynamicReplacements)
6566
endif()
6667

6768
if(SWIFT_BUILD_STDLIB OR SWIFT_BUILD_REMOTE_MIRROR)

stdlib/public/Compatibility50/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ set(swift_runtime_linker_flags ${SWIFT_RUNTIME_CORE_LINK_FLAGS})
33

44
add_swift_target_library(swiftCompatibility50 TARGET_LIBRARY STATIC INSTALL_WITH_SHARED
55
ProtocolConformance.cpp
6-
DynamicReplaceable.cpp
76
Overrides.cpp
87
C_COMPILE_FLAGS ${swift_runtime_library_compile_flags}
98
LINK_FLAGS ${swift_runtime_linker_flags}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
set(swift_runtime_compile_flags ${SWIFT_RUNTIME_CORE_CXX_FLAGS})
2+
set(swift_runtime_linker_flags ${SWIFT_RUNTIME_CORE_LINK_FLAGS})
3+
4+
add_swift_target_library(swiftCompatibilityDynamicReplacements TARGET_LIBRARY STATIC INSTALL_WITH_SHARED
5+
DynamicReplaceable.cpp
6+
C_COMPILE_FLAGS ${swift_runtime_library_compile_flags}
7+
LINK_FLAGS ${swift_runtime_linker_flags}
8+
TARGET_SDKS ${SWIFT_APPLE_PLATFORMS}
9+
INSTALL_IN_COMPONENT compiler)
10+
11+

stdlib/public/Compatibility50/DynamicReplaceable.cpp renamed to stdlib/public/CompatibilityDynamicReplacements/DynamicReplaceable.cpp

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,12 @@
1717
//
1818
//===----------------------------------------------------------------------===//
1919

20-
#include "Overrides.h"
2120
#include "swift/Runtime/Once.h"
2221
#include "swift/Runtime/Exclusivity.h"
2322
#include "../runtime/ThreadLocalStorage.h"
2423

2524
using namespace swift;
2625

27-
// The thread-local key must be weak so that it is shared between different
28-
// binaries (e.g. shared libraries).
29-
__attribute__((weak)) __swift_thread_key_t _swift_dr_key;
30-
__attribute__((weak)) swift_once_t _swift_dr_Predicate;
31-
32-
static void createSwiftThreadKey(void *) {
33-
int result = SWIFT_THREAD_KEY_CREATE(&_swift_dr_key, nullptr);
34-
if (result != 0)
35-
abort();
36-
}
37-
38-
static __swift_thread_key_t &getTLSKey() {
39-
swift_once(&_swift_dr_Predicate, createSwiftThreadKey, nullptr);
40-
return _swift_dr_key;
41-
}
42-
4326
__attribute__((visibility("hidden"), weak))
4427
extern "C" char *swift_getFunctionReplacement50(char **ReplFnPtr, char *CurrFn) {
4528
// Call the current implementation if it is available.
@@ -52,9 +35,11 @@ extern "C" char *swift_getFunctionReplacement50(char **ReplFnPtr, char *CurrFn)
5235
if (RawReplFn == CurrFn)
5336
return nullptr;
5437

55-
__swift_thread_key_t key = getTLSKey();
56-
if ((intptr_t)SWIFT_THREAD_GETSPECIFIC(key) != 0) {
57-
SWIFT_THREAD_SETSPECIFIC(key, (void *)0);
38+
auto origKey = (uintptr_t)SWIFT_THREAD_GETSPECIFIC(SWIFT_RUNTIME2_TLS_KEY);
39+
if ((origKey & 0x1) != 0) {
40+
auto mask = ((uintptr_t)-1) < 1;
41+
auto resetKey = origKey & mask;
42+
SWIFT_THREAD_SETSPECIFIC(SWIFT_RUNTIME2_TLS_KEY, (void *)resetKey);
5843
return nullptr;
5944
}
6045
return ReplFn;
@@ -67,6 +52,13 @@ extern "C" char *swift_getOrigOfReplaceable50(char **OrigFnPtr) {
6752
return swift_getOrigOfReplaceable(OrigFnPtr);
6853

6954
char *OrigFn = *OrigFnPtr;
70-
SWIFT_THREAD_SETSPECIFIC(getTLSKey(), (void *)-1);
55+
auto origKey = (uintptr_t)SWIFT_THREAD_GETSPECIFIC(SWIFT_RUNTIME2_TLS_KEY);
56+
auto newKey = origKey | 0x1;
57+
SWIFT_THREAD_SETSPECIFIC(SWIFT_RUNTIME2_TLS_KEY, (void *)newKey);
7158
return OrigFn;
7259
}
60+
61+
// Allow this library to get force-loaded by autolinking
62+
__attribute__((weak, visibility("hidden")))
63+
extern "C"
64+
char _swift_FORCE_LOAD_$_swiftCompatibilityDynamicReplacements = 0;

stdlib/public/runtime/ThreadLocalStorage.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,14 @@ extern "C" int pthread_key_init_np(int key, void (*destructor)(void *));
5353
# ifndef __PTK_FRAMEWORK_SWIFT_KEY1
5454
# define __PTK_FRAMEWORK_SWIFT_KEY1 101
5555
# endif
56+
# ifndef __PTK_FRAMEWORK_SWIFT_KEY2
57+
# define __PTK_FRAMEWORK_SWIFT_KEY2 102
58+
# endif
59+
5660

5761
# define SWIFT_RUNTIME_TLS_KEY __PTK_FRAMEWORK_SWIFT_KEY0
5862
# define SWIFT_STDLIB_TLS_KEY __PTK_FRAMEWORK_SWIFT_KEY1
63+
# define SWIFT_RUNTIME2_TLS_KEY __PTK_FRAMEWORK_SWIFT_KEY2
5964

6065
#endif
6166

test/IRGen/autolink-runtime-compatibility.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
// REQUIRES: OS=macosx
22

33
// Doesn't autolink compatibility library because autolinking is disabled
4-
// RUN: %target-swift-frontend -target x86_64-apple-macosx10.9 -disable-autolinking-runtime-compatibility -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=NO-FORCE-LOAD %s
5-
// RUN: %target-swift-frontend -runtime-compatibility-version 5.0 -disable-autolinking-runtime-compatibility -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=NO-FORCE-LOAD %s
4+
// RUN: %target-swift-frontend -disable-autolinking-runtime-compatibility-dynamic-replacements -target x86_64-apple-macosx10.9 -disable-autolinking-runtime-compatibility -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=NO-FORCE-LOAD %s
5+
// RUN: %target-swift-frontend -disable-autolinking-runtime-compatibility-dynamic-replacements -runtime-compatibility-version 5.0 -disable-autolinking-runtime-compatibility -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=NO-FORCE-LOAD %s
66

77
// Doesn't autolink compatibility library because runtime compatibility library is disabled
8-
// RUN: %target-swift-frontend -runtime-compatibility-version none -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=NO-FORCE-LOAD %s
8+
// RUN: %target-swift-frontend -disable-autolinking-runtime-compatibility-dynamic-replacements -runtime-compatibility-version none -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=NO-FORCE-LOAD %s
99

1010
// Doesn't autolink compatibility library because target OS doesn't need it
11-
// RUN: %target-swift-frontend -target x86_64-apple-macosx10.24 -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=NO-FORCE-LOAD %s
11+
// RUN: %target-swift-frontend -disable-autolinking-runtime-compatibility-dynamic-replacements -target x86_64-apple-macosx10.24 -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=NO-FORCE-LOAD %s
1212

1313
// Autolinks because compatibility library was explicitly asked for
1414
// RUN: %target-swift-frontend -runtime-compatibility-version 5.0 -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=FORCE-LOAD %s

test/IRGen/unused.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -runtime-compatibility-version none -primary-file %s -emit-ir | %FileCheck -check-prefix CHECK -check-prefix NEGATIVE -check-prefix CHECK-%target-object-format %s
1+
// RUN: %target-swift-frontend -disable-autolinking-runtime-compatibility-dynamic-replacements -runtime-compatibility-version none -primary-file %s -emit-ir | %FileCheck -check-prefix CHECK -check-prefix NEGATIVE -check-prefix CHECK-%target-object-format %s
22

33
// REQUIRES: CPU=x86_64
44

test/Serialization/autolinking.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %target-swift-frontend -emit-module -parse-stdlib -o %t -module-name someModule -module-link-name module %S/../Inputs/empty.swift
3-
// RUN: %target-swift-frontend -runtime-compatibility-version none -emit-ir -lmagic %s -I %t > %t/out.txt
3+
// RUN: %target-swift-frontend -disable-autolinking-runtime-compatibility-dynamic-replacements -runtime-compatibility-version none -emit-ir -lmagic %s -I %t > %t/out.txt
44
// RUN: %FileCheck %s < %t/out.txt
55
// RUN: %FileCheck -check-prefix=NO-FORCE-LOAD %s < %t/out.txt
66

77
// RUN: %empty-directory(%t/someModule.framework/Modules/someModule.swiftmodule)
88
// RUN: mv %t/someModule.swiftmodule %t/someModule.framework/Modules/someModule.swiftmodule/%target-swiftmodule-name
9-
// RUN: %target-swift-frontend -runtime-compatibility-version none -emit-ir -lmagic %s -F %t > %t/framework.txt
9+
// RUN: %target-swift-frontend -disable-autolinking-runtime-compatibility-dynamic-replacements -runtime-compatibility-version none -emit-ir -lmagic %s -F %t > %t/framework.txt
1010
// RUN: %FileCheck -check-prefix=FRAMEWORK %s < %t/framework.txt
1111
// RUN: %FileCheck -check-prefix=NO-FORCE-LOAD %s < %t/framework.txt
1212

@@ -15,7 +15,7 @@
1515
// RUN: %FileCheck %s < %t/force-load.txt
1616
// RUN: %FileCheck -check-prefix FORCE-LOAD-CLIENT -check-prefix FORCE-LOAD-CLIENT-%target-object-format %s < %t/force-load.txt
1717

18-
// RUN: %target-swift-frontend -runtime-compatibility-version none -emit-ir -parse-stdlib -module-name someModule -module-link-name module %S/../Inputs/empty.swift | %FileCheck --check-prefix=NO-FORCE-LOAD %s
18+
// RUN: %target-swift-frontend -disable-autolinking-runtime-compatibility-dynamic-replacements -runtime-compatibility-version none -emit-ir -parse-stdlib -module-name someModule -module-link-name module %S/../Inputs/empty.swift | %FileCheck --check-prefix=NO-FORCE-LOAD %s
1919
// RUN: %target-swift-frontend -runtime-compatibility-version none -emit-ir -parse-stdlib -module-name someModule -module-link-name module %S/../Inputs/empty.swift -autolink-force-load | %FileCheck --check-prefix=FORCE-LOAD %s
2020
// RUN: %target-swift-frontend -runtime-compatibility-version none -emit-ir -parse-stdlib -module-name someModule -module-link-name 0module %S/../Inputs/empty.swift -autolink-force-load | %FileCheck --check-prefix=FORCE-LOAD-HEX %s
2121

0 commit comments

Comments
 (0)