forked from OSchip/llvm-project
[WebAssembly] Error on relocations against undefined data symbols.
We can't (currently) meaningfully resolve certain types of relocations against undefined data symbols. Previously when `--allow-undefined` was used we were treating such relocation much like weak data symbols and simply inserting zeros. This change turns such use cases in to an error. This means that `--allow-undefined` is no longer effective for data symbols. Fixes https://bugs.llvm.org/show_bug.cgi?id=40364 Differential Revision: https://reviews.llvm.org/D60882 llvm-svn: 358899
This commit is contained in:
parent
55043e2336
commit
7cdec273dd
|
@ -1,6 +1,7 @@
|
|||
; RUN: llc -filetype=obj %s -o %t.o
|
||||
; RUN: not wasm-ld -o %t.wasm %t.o 2>&1 | FileCheck %s -check-prefix=UNDEF
|
||||
; RUN: not wasm-ld --shared -o %t.wasm %t.o 2>&1 | FileCheck %s -check-prefix=BADRELOC
|
||||
; RUN: not wasm-ld --allow-undefined -o %t.wasm %t.o 2>&1 | FileCheck %s -check-prefix=ALLOW
|
||||
; RUN: not wasm-ld --shared -o %t.wasm %t.o 2>&1 | FileCheck %s -check-prefix=SHARED
|
||||
|
||||
target triple = "wasm32-unknown-unknown"
|
||||
|
||||
|
@ -13,4 +14,5 @@ entry:
|
|||
}
|
||||
|
||||
; UNDEF: undefined symbol: data_external
|
||||
; BADRELOC: undefined-data.ll.tmp.o: relocation R_WASM_MEMORY_ADDR_LEB cannot be used againt symbol data_external; recompile with -fPIC
|
||||
; ALLOW: undefined-data.ll.tmp.o: cannot resolve relocation of type R_WASM_MEMORY_ADDR_LEB against undefined (non-weak) data symbol: data_external
|
||||
; SHARED: undefined-data.ll.tmp.o: relocation R_WASM_MEMORY_ADDR_LEB cannot be used againt symbol data_external; recompile with -fPIC
|
||||
|
|
|
@ -141,6 +141,30 @@ uint32_t ObjFile::calcExpectedValue(const WasmRelocation &Reloc) const {
|
|||
|
||||
// Translate from the relocation's index into the final linked output value.
|
||||
uint32_t ObjFile::calcNewValue(const WasmRelocation &Reloc) const {
|
||||
const Symbol* Sym = nullptr;
|
||||
if (Reloc.Type != R_WASM_TYPE_INDEX_LEB) {
|
||||
Sym = Symbols[Reloc.Index];
|
||||
|
||||
// We can end up with relocations against non-live symbols. For example
|
||||
// in debug sections.
|
||||
if ((isa<FunctionSymbol>(Sym) || isa<DataSymbol>(Sym)) && !Sym->isLive())
|
||||
return 0;
|
||||
|
||||
// Special handling for undefined data symbols. Most relocations against
|
||||
// such symbols cannot be resolved.
|
||||
if (isa<DataSymbol>(Sym) && Sym->isUndefined()) {
|
||||
if (Sym->isWeak() || Config->Relocatable)
|
||||
return 0;
|
||||
if (Config->Shared && Reloc.Type == R_WASM_MEMORY_ADDR_I32)
|
||||
return 0;
|
||||
if (Reloc.Type != R_WASM_GLOBAL_INDEX_LEB) {
|
||||
llvm_unreachable(
|
||||
("invalid relocation against undefined data symbol: " + toString(*Sym))
|
||||
.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (Reloc.Type) {
|
||||
case R_WASM_TABLE_INDEX_I32:
|
||||
case R_WASM_TABLE_INDEX_SLEB:
|
||||
|
@ -150,28 +174,22 @@ uint32_t ObjFile::calcNewValue(const WasmRelocation &Reloc) const {
|
|||
case R_WASM_MEMORY_ADDR_I32:
|
||||
case R_WASM_MEMORY_ADDR_LEB:
|
||||
case R_WASM_MEMORY_ADDR_REL_SLEB:
|
||||
if (auto *Sym = dyn_cast<DefinedData>(getDataSymbol(Reloc.Index)))
|
||||
if (Sym->isLive())
|
||||
return Sym->getVirtualAddress() + Reloc.Addend;
|
||||
return 0;
|
||||
return cast<DefinedData>(Sym)->getVirtualAddress() + Reloc.Addend;
|
||||
case R_WASM_TYPE_INDEX_LEB:
|
||||
return TypeMap[Reloc.Index];
|
||||
case R_WASM_FUNCTION_INDEX_LEB:
|
||||
return getFunctionSymbol(Reloc.Index)->getFunctionIndex();
|
||||
case R_WASM_GLOBAL_INDEX_LEB: {
|
||||
const Symbol* Sym = Symbols[Reloc.Index];
|
||||
case R_WASM_GLOBAL_INDEX_LEB:
|
||||
if (auto GS = dyn_cast<GlobalSymbol>(Sym))
|
||||
return GS->getGlobalIndex();
|
||||
return Sym->getGOTIndex();
|
||||
} case R_WASM_EVENT_INDEX_LEB:
|
||||
case R_WASM_EVENT_INDEX_LEB:
|
||||
return getEventSymbol(Reloc.Index)->getEventIndex();
|
||||
case R_WASM_FUNCTION_OFFSET_I32:
|
||||
if (auto *Sym = dyn_cast<DefinedFunction>(getFunctionSymbol(Reloc.Index))) {
|
||||
if (Sym->isLive())
|
||||
return Sym->Function->OutputOffset +
|
||||
Sym->Function->getFunctionCodeOffset() + Reloc.Addend;
|
||||
}
|
||||
return 0;
|
||||
case R_WASM_FUNCTION_OFFSET_I32: {
|
||||
auto *F = cast<DefinedFunction>(Sym);
|
||||
return F->Function->OutputOffset + F->Function->getFunctionCodeOffset() +
|
||||
Reloc.Addend;
|
||||
}
|
||||
case R_WASM_SECTION_OFFSET_I32:
|
||||
return getSectionSymbol(Reloc.Index)->Section->OutputOffset + Reloc.Addend;
|
||||
default:
|
||||
|
|
|
@ -1170,6 +1170,20 @@ void Writer::processRelocations(InputChunk *Chunk) {
|
|||
Sym->setGOTIndex(NumImportedGlobals++);
|
||||
GOTSymbols.push_back(Sym);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R_WASM_MEMORY_ADDR_SLEB:
|
||||
case R_WASM_MEMORY_ADDR_LEB:
|
||||
case R_WASM_MEMORY_ADDR_REL_SLEB: {
|
||||
if (!Config->Relocatable) {
|
||||
auto* Sym = File->getSymbols()[Reloc.Index];
|
||||
if (Sym->isUndefined() && !Sym->isWeak()) {
|
||||
error(toString(File) + ": cannot resolve relocation of type " +
|
||||
relocTypeToString(Reloc.Type) +
|
||||
" against undefined (non-weak) data symbol: " + toString(*Sym));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue