[lld][WebAssembly] Fix handling of mixed strong and weak references
When adding a undefined symbols to the symbol table, if the existing reference is weak replace the symbol flags with (potentially) non-weak binding. Fixes: https://github.com/llvm/llvm-project/issues/60829 Differential Revision: https://reviews.llvm.org/D144747
This commit is contained in:
parent
45391e1394
commit
d65ed8cde0
5
lld/test/wasm/Inputs/strong-refs.s
Normal file
5
lld/test/wasm/Inputs/strong-refs.s
Normal file
@ -0,0 +1,5 @@
|
||||
.globl f2
|
||||
f2:
|
||||
.functype f2 () -> (i32)
|
||||
i32.const global_var
|
||||
end_function
|
@ -1,9 +1,18 @@
|
||||
# Test that undefined weak externals (global_var) and (foo) don't cause
|
||||
# link failures and resolve to zero.
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
|
||||
# RUN: wasm-ld -strip-all %t.o -o %t.wasm
|
||||
# RUN: obj2yaml %t.wasm | FileCheck %s
|
||||
|
||||
# Test that undefined weak externals (global_var) and (foo) don't cause
|
||||
# link failures and resolve to zero.
|
||||
# Also verify test that strong references in another file do cause link
|
||||
# failure (See https://github.com/llvm/llvm-project/issues/60806)
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/strong-refs.s -o %t-strong.o
|
||||
# RUN: not wasm-ld -strip-all %t.o %t-strong.o -o %t.wasm 2>&1 | FileCheck --check-prefix=ERROR %s
|
||||
# RUN: not wasm-ld -strip-all %t-strong.o %t.o -o %t.wasm 2>&1 | FileCheck --check-prefix=ERROR %s
|
||||
|
||||
# ERROR: undefined symbol: global_var
|
||||
|
||||
.functype foo () -> (i32)
|
||||
|
||||
@ -33,7 +42,6 @@ _start:
|
||||
.weak foo
|
||||
.weak global_var
|
||||
|
||||
|
||||
# CHECK: --- !WASM
|
||||
# CHECK-NEXT: FileHeader:
|
||||
# CHECK-NEXT: Version: 0x1
|
||||
|
@ -548,6 +548,8 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef name,
|
||||
file);
|
||||
if (isCalledDirectly)
|
||||
existingUndefined->isCalledDirectly = true;
|
||||
if (s->isWeak())
|
||||
s->flags = flags;
|
||||
}
|
||||
}
|
||||
|
||||
@ -574,6 +576,8 @@ Symbol *SymbolTable::addUndefinedData(StringRef name, uint32_t flags,
|
||||
lazy->fetch();
|
||||
} else if (s->isDefined()) {
|
||||
checkDataType(s, file);
|
||||
} else if (s->isWeak()) {
|
||||
s->flags = flags;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
@ -599,6 +603,8 @@ Symbol *SymbolTable::addUndefinedGlobal(StringRef name,
|
||||
lazy->fetch();
|
||||
else if (s->isDefined())
|
||||
checkGlobalType(s, file, type);
|
||||
else if (s->isWeak())
|
||||
s->flags = flags;
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -623,6 +629,8 @@ Symbol *SymbolTable::addUndefinedTable(StringRef name,
|
||||
lazy->fetch();
|
||||
else if (s->isDefined())
|
||||
checkTableType(s, file, type);
|
||||
else if (s->isWeak())
|
||||
s->flags = flags;
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -647,6 +655,8 @@ Symbol *SymbolTable::addUndefinedTag(StringRef name,
|
||||
lazy->fetch();
|
||||
else if (s->isDefined())
|
||||
checkTagType(s, file, sig);
|
||||
else if (s->isWeak())
|
||||
s->flags = flags;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,18 @@ using namespace object;
|
||||
void WasmSymbol::print(raw_ostream &Out) const {
|
||||
Out << "Name=" << Info.Name
|
||||
<< ", Kind=" << toString(wasm::WasmSymbolType(Info.Kind)) << ", Flags=0x"
|
||||
<< Twine::utohexstr(Info.Flags);
|
||||
<< Twine::utohexstr(Info.Flags) << " [";
|
||||
switch (getBinding()) {
|
||||
case wasm::WASM_SYMBOL_BINDING_GLOBAL: Out << "global"; break;
|
||||
case wasm::WASM_SYMBOL_BINDING_LOCAL: Out << "local"; break;
|
||||
case wasm::WASM_SYMBOL_BINDING_WEAK: Out << "weak"; break;
|
||||
}
|
||||
if (isHidden()) {
|
||||
Out << ", hidden";
|
||||
} else {
|
||||
Out << ", default";
|
||||
}
|
||||
Out << "]";
|
||||
if (!isTypeData()) {
|
||||
Out << ", ElemIndex=" << Info.ElementIndex;
|
||||
} else if (isDefined()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user