forked from OSchip/llvm-project
[lld][WebAssembly] Handle weakly referenced symbols when lazy (archive) version is see first
When a weak reference of a lazy symbol occurs we were not correctly updating the lazy symbol. We need to tag the existing lazy symbol as weak and, in the case of a function symbol, give it a signature. Without the signature we can't then create the dummy function which is needed when an weakly undefined function is called. We had tests for weakly referenced lazy symbols but we were only tests in the case where the reference was seen before the lazy symbol. See: https://github.com/WebAssembly/wasi-libc/pull/214 Differential Revision: https://reviews.llvm.org/D85567
This commit is contained in:
parent
9a368d2b00
commit
b34ec5969f
|
@ -1,4 +1,4 @@
|
|||
; Test that weak undefined symbols do not fetch members from archive files.
|
||||
;; Test that weak undefined symbols do not fetch members from archive files.
|
||||
; RUN: llc -filetype=obj %s -o %t.o
|
||||
; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/ret32.s -o %t.ret32.o
|
||||
; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/hello.s -o %t.hello.o
|
||||
|
@ -8,6 +8,10 @@
|
|||
; RUN: wasm-ld %t.o %t.a -o %t.wasm
|
||||
; RUN: obj2yaml %t.wasm | FileCheck %s
|
||||
|
||||
;; Also test with the library symbols being read first
|
||||
; RUN: wasm-ld %t.a %t.o -o %t2.wasm
|
||||
; RUN: obj2yaml %t2.wasm | FileCheck %s
|
||||
|
||||
; RUN: wasm-ld -u hello_str %t.o %t.a -o %t2.wasm
|
||||
; RUN: obj2yaml %t2.wasm | FileCheck %s -check-prefix=CHECK-DATA
|
||||
|
||||
|
|
|
@ -458,11 +458,16 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef name,
|
|||
file, sig, isCalledDirectly);
|
||||
};
|
||||
|
||||
if (wasInserted)
|
||||
if (wasInserted) {
|
||||
replaceSym();
|
||||
else if (auto *lazy = dyn_cast<LazySymbol>(s))
|
||||
lazy->fetch();
|
||||
else {
|
||||
} else if (auto *lazy = dyn_cast<LazySymbol>(s)) {
|
||||
if ((flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) {
|
||||
lazy->setWeak();
|
||||
lazy->signature = sig;
|
||||
} else {
|
||||
lazy->fetch();
|
||||
}
|
||||
} else {
|
||||
auto existingFunction = dyn_cast<FunctionSymbol>(s);
|
||||
if (!existingFunction) {
|
||||
reportTypeError(s, file, WASM_SYMBOL_TYPE_FUNCTION);
|
||||
|
@ -499,12 +504,16 @@ Symbol *SymbolTable::addUndefinedData(StringRef name, uint32_t flags,
|
|||
if (s->traced)
|
||||
printTraceSymbolUndefined(name, file);
|
||||
|
||||
if (wasInserted)
|
||||
if (wasInserted) {
|
||||
replaceSymbol<UndefinedData>(s, name, flags, file);
|
||||
else if (auto *lazy = dyn_cast<LazySymbol>(s))
|
||||
lazy->fetch();
|
||||
else if (s->isDefined())
|
||||
} else if (auto *lazy = dyn_cast<LazySymbol>(s)) {
|
||||
if ((flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK)
|
||||
lazy->setWeak();
|
||||
else
|
||||
lazy->fetch();
|
||||
} else if (s->isDefined()) {
|
||||
checkDataType(s, file);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
|
@ -339,6 +339,10 @@ const OutputSectionSymbol *SectionSymbol::getOutputSectionSymbol() const {
|
|||
|
||||
void LazySymbol::fetch() { cast<ArchiveFile>(file)->addMember(&archiveSymbol); }
|
||||
|
||||
void LazySymbol::setWeak() {
|
||||
flags |= (flags & ~WASM_SYMBOL_BINDING_MASK) | WASM_SYMBOL_BINDING_WEAK;
|
||||
}
|
||||
|
||||
MemoryBufferRef LazySymbol::getMemberBuffer() {
|
||||
Archive::Child c =
|
||||
CHECK(archiveSymbol.getMember(),
|
||||
|
|
|
@ -411,6 +411,7 @@ public:
|
|||
|
||||
static bool classof(const Symbol *s) { return s->kind() == LazyKind; }
|
||||
void fetch();
|
||||
void setWeak();
|
||||
MemoryBufferRef getMemberBuffer();
|
||||
|
||||
// Lazy symbols can have a signature because they can replace an
|
||||
|
|
Loading…
Reference in New Issue