[lld][WebAssembly] Create optional internal symbols only after LTO object as been added

This is important for the cases where new symbols can be introduced
during LTO.   Specifically this happens for during TLS-lowering where
references to `__tls_base` can be introduced.

Fixes: https://github.com/emscripten-core/emscripten/issues/12489

Differential Revision: https://reviews.llvm.org/D111171
This commit is contained in:
Sam Clegg 2021-09-28 11:43:47 -07:00
parent 0be9940ef2
commit 8fe128476e
3 changed files with 49 additions and 4 deletions

45
lld/test/wasm/lto/tls.ll Normal file
View File

@ -0,0 +1,45 @@
; Test that LTO objects build with TLS and threading support can be linked into
; a single threaded binary. Specifically the references to `__tls_base` that
; can be generated at LTO-time need to trigger the creation of the internal/fake
; `__tls_base` symbol in the linker.
; RUN: llvm-as %s -o %t1.o
; RUN: wasm-ld --export=tls_int --export=get_tls %t1.o -o %t
; RUN: obj2yaml %t | FileCheck %s
target datalayout = "e-m:e-p:32:32-i64:64-f128:64-n32:64-S128-ni:1:10:20"
target triple = "wasm32-unknown-emscripten"
@tls_int = dso_local thread_local global i32 99
define i32 @get_tls() #0 {
%val = load i32, i32* @tls_int
ret i32 %val
}
define void @_start() #0 {
ret void
}
attributes #0 = { noinline nounwind optnone "target-features"="+atomics,+bulk-memory,+mutable-globals,+sign-ext" }
; CHECK: - Type: GLOBAL
; CHECK-NEXT: Globals:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Type: I32
; CHECK-NEXT: Mutable: true
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 66576
; CHECK-NEXT: - Index: 1
; CHECK-NEXT: Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 1024
; CHECK: GlobalNames:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: __stack_pointer
; CHECK-NEXT: - Index: 1
; CHECK-NEXT: Name: __tls_base

View File

@ -947,8 +947,6 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
}
}
createOptionalSymbols();
if (errorCount())
return;
@ -976,6 +974,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
if (errorCount())
return;
createOptionalSymbols();
// Resolve any variant symbols that were created due to signature
// mismatchs.
symtab->handleSymbolVariants();

View File

@ -258,11 +258,11 @@ DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef name, uint32_t flags,
DefinedGlobal *SymbolTable::addOptionalGlobalSymbol(StringRef name,
InputGlobal *global) {
LLVM_DEBUG(dbgs() << "addOptionalGlobalSymbol: " << name << " -> " << global
<< "\n");
Symbol *s = find(name);
if (!s || s->isDefined())
return nullptr;
LLVM_DEBUG(dbgs() << "addOptionalGlobalSymbol: " << name << " -> " << global
<< "\n");
syntheticGlobals.emplace_back(global);
return replaceSymbol<DefinedGlobal>(s, name, WASM_SYMBOL_VISIBILITY_HIDDEN,
nullptr, global);