[WebAssembly] Use GeneralDynamic TLS for exception handling builtins.
These global TLS symbols are shared across all shared libraries and therefor should not be assumed to be local to the current module. Also add new error in the linker when TLS relocations are used against undefined symbols. TLS relocations are offsets into the current modules tls data segment, and don't make sense for undefined symbols which are modeled as global imports. Fixes: https://github.com/emscripten-core/emscripten/issues/13398 Differential Revision: https://reviews.llvm.org/D119630
This commit is contained in:
parent
9dcb006165
commit
37f422f4ac
|
@ -6,6 +6,8 @@ _start:
|
|||
.functype _start () -> ()
|
||||
i32.const foo@TLSREL
|
||||
i32.const bar@TLSREL
|
||||
i32.const baz@TLSREL
|
||||
drop
|
||||
drop
|
||||
drop
|
||||
end_function
|
||||
|
@ -24,3 +26,4 @@ bar:
|
|||
|
||||
# CHECK: relocation R_WASM_MEMORY_ADDR_TLS_SLEB cannot be used against `foo` in non-TLS section: .data
|
||||
# CHECK: relocation R_WASM_MEMORY_ADDR_TLS_SLEB cannot be used against `bar` in non-TLS section: .bss
|
||||
# CHECK: relocation R_WASM_MEMORY_ADDR_TLS_SLEB cannot be used against an undefined symbol `baz`
|
||||
|
|
|
@ -112,6 +112,11 @@ void scanRelocations(InputChunk *chunk) {
|
|||
break;
|
||||
case R_WASM_MEMORY_ADDR_TLS_SLEB:
|
||||
case R_WASM_MEMORY_ADDR_TLS_SLEB64:
|
||||
if (!sym->isDefined()) {
|
||||
error(toString(file) + ": relocation " + relocTypeToString(reloc.Type) +
|
||||
" cannot be used against an undefined symbol `" + toString(*sym) +
|
||||
"`");
|
||||
}
|
||||
// In single-threaded builds TLS is lowered away and TLS data can be
|
||||
// merged with normal data and allowing TLS relocation in non-TLS
|
||||
// segments.
|
||||
|
|
|
@ -422,7 +422,7 @@ static GlobalVariable *getGlobalVariable(Module &M, Type *Ty,
|
|||
// shared-memory module, which we don't want to be responsible for.
|
||||
auto *Subtarget = TM.getSubtargetImpl();
|
||||
auto TLS = Subtarget->hasAtomics() && Subtarget->hasBulkMemory()
|
||||
? GlobalValue::LocalExecTLSModel
|
||||
? GlobalValue::GeneralDynamicTLSModel
|
||||
: GlobalValue::NotThreadLocal;
|
||||
GV->setThreadLocalMode(TLS);
|
||||
return GV;
|
||||
|
|
|
@ -9,8 +9,8 @@ target triple = "wasm32-unknown-unknown"
|
|||
@_ZTIc = external constant i8*
|
||||
; NO-TLS-DAG: __THREW__ = external global [[PTR]]
|
||||
; NO-TLS-DAG: __threwValue = external global i32
|
||||
; TLS-DAG: __THREW__ = external thread_local(localexec) global [[PTR]]
|
||||
; TLS-DAG: __threwValue = external thread_local(localexec) global i32
|
||||
; TLS-DAG: __THREW__ = external thread_local global [[PTR]]
|
||||
; TLS-DAG: __threwValue = external thread_local global i32
|
||||
|
||||
; Test invoke instruction with clauses (try-catch block)
|
||||
define void @clause() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
|
||||
|
|
|
@ -10,8 +10,8 @@ target triple = "wasm32-unknown-unknown"
|
|||
@global_var = global i32 0, align 4
|
||||
; NO-TLS-DAG: __THREW__ = external global [[PTR]]
|
||||
; NO-TLS-DAG: __threwValue = external global [[PTR]]
|
||||
; TLS-DAG: __THREW__ = external thread_local(localexec) global i32
|
||||
; TLS-DAG: __threwValue = external thread_local(localexec) global i32
|
||||
; TLS-DAG: __THREW__ = external thread_local global i32
|
||||
; TLS-DAG: __threwValue = external thread_local global i32
|
||||
@global_longjmp_ptr = global void (%struct.__jmp_buf_tag*, i32)* @longjmp, align 4
|
||||
; CHECK-DAG: @global_longjmp_ptr = global void (%struct.__jmp_buf_tag*, i32)* bitcast (void ([[PTR]], i32)* @emscripten_longjmp to void (%struct.__jmp_buf_tag*, i32)*)
|
||||
|
||||
|
|
Loading…
Reference in a new issue