Skip to content

Commit

Permalink
[WebAssembly] Error on relocations against undefined data symbols.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
sbc100 committed Apr 22, 2019
1 parent 55043e2 commit 7cdec27
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 16 deletions.
6 changes: 4 additions & 2 deletions lld/test/wasm/undefined-data.ll
@@ -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"

Expand All @@ -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
46 changes: 32 additions & 14 deletions lld/wasm/InputFiles.cpp
Expand Up @@ -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:
Expand All @@ -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:
Expand Down
14 changes: 14 additions & 0 deletions lld/wasm/Writer.cpp
Expand Up @@ -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;
}
}

Expand Down

0 comments on commit 7cdec27

Please sign in to comment.