summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/MC/WasmObjectWriter.cpp56
-rw-r--r--llvm/test/MC/WebAssembly/weak-alias.ll8
2 files changed, 29 insertions, 35 deletions
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index 4a824b2cae0..cac4aa17a5d 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -208,7 +208,7 @@ class WasmObjectWriter : public MCObjectWriter {
DenseMap<const MCSymbolWasm *, uint32_t> TypeIndices;
// Maps function symbols to the table element index space. Used
// for TABLE_INDEX relocation types (i.e. address taken functions).
- DenseMap<const MCSymbolWasm *, uint32_t> IndirectSymbolIndices;
+ DenseMap<const MCSymbolWasm *, uint32_t> TableIndices;
// Maps function/global symbols to the function/global index space.
DenseMap<const MCSymbolWasm *, uint32_t> SymbolIndices;
@@ -243,7 +243,7 @@ private:
DataRelocations.clear();
TypeIndices.clear();
SymbolIndices.clear();
- IndirectSymbolIndices.clear();
+ TableIndices.clear();
FunctionTypeIndices.clear();
FunctionTypes.clear();
Globals.clear();
@@ -493,24 +493,23 @@ static const MCSymbolWasm* ResolveSymbol(const MCSymbolWasm& Symbol) {
// useable.
uint32_t
WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry) {
-
switch (RelEntry.Type) {
case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
- case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
- // Provitional value is the indirect symbol index
- if (!IndirectSymbolIndices.count(RelEntry.Symbol))
- report_fatal_error("symbol not found in table index space: " +
- RelEntry.Symbol->getName());
- return IndirectSymbolIndices[RelEntry.Symbol];
+ case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32: {
+ // Provisional value is table address of the resolved symbol itself
+ const MCSymbolWasm *Sym = ResolveSymbol(*RelEntry.Symbol);
+ assert(Sym->isFunction());
+ return TableIndices[Sym];
+ }
case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
- // Provitional value is function/type/global index itself
+ // Provisional value is function/type/global index itself
return getRelocationIndexValue(RelEntry);
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: {
- // Provitional value is address of the global
+ // Provisional value is address of the global
const MCSymbolWasm *Sym = ResolveSymbol(*RelEntry.Symbol);
// For undefined symbols, use zero
if (!Sym->isDefined())
@@ -1274,26 +1273,21 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
{
auto HandleReloc = [&](const WasmRelocationEntry &Rel) {
- // Functions referenced by a relocation need to prepared to be called
- // indirectly.
- const MCSymbolWasm& WS = *Rel.Symbol;
- if (WS.isFunction() && IndirectSymbolIndices.count(&WS) == 0) {
- switch (Rel.Type) {
- case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
- case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
- case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
- case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: {
- uint32_t Index = SymbolIndices.find(&WS)->second;
- IndirectSymbolIndices[&WS] = TableElems.size() + kInitialTableOffset;
- DEBUG(dbgs() << " -> adding " << WS.getName()
- << " to table: " << TableElems.size() << "\n");
- TableElems.push_back(Index);
- registerFunctionType(WS);
- break;
- }
- default:
- break;
- }
+ // Functions referenced by a relocation need to put in the table. This is
+ // purely to make the object file's provisional values readable, and is
+ // ignored by the linker, which re-calculates the relocations itself.
+ if (Rel.Type != wasm::R_WEBASSEMBLY_TABLE_INDEX_I32 &&
+ Rel.Type != wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB)
+ return;
+ assert(Rel.Symbol->isFunction());
+ const MCSymbolWasm &WS = *ResolveSymbol(*Rel.Symbol);
+ uint32_t SymbolIndex = SymbolIndices.find(&WS)->second;
+ uint32_t TableIndex = TableElems.size() + kInitialTableOffset;
+ if (TableIndices.try_emplace(&WS, TableIndex).second) {
+ DEBUG(dbgs() << " -> adding " << WS.getName()
+ << " to table: " << TableIndex << "\n");
+ TableElems.push_back(SymbolIndex);
+ registerFunctionType(WS);
}
};
diff --git a/llvm/test/MC/WebAssembly/weak-alias.ll b/llvm/test/MC/WebAssembly/weak-alias.ll
index 2d2415991a0..7655211ec75 100644
--- a/llvm/test/MC/WebAssembly/weak-alias.ll
+++ b/llvm/test/MC/WebAssembly/weak-alias.ll
@@ -64,7 +64,7 @@ entry:
; CHECK-NEXT: Table:
; CHECK-NEXT: ElemType: ANYFUNC
; CHECK-NEXT: Limits:
-; CHECK-NEXT: Initial: 0x00000002
+; CHECK-NEXT: Initial: 0x00000001
; CHECK-NEXT: - Module: env
; CHECK-NEXT: Field: foo_alias
; CHECK-NEXT: Kind: FUNCTION
@@ -133,7 +133,7 @@ entry:
; CHECK-NEXT: - Offset:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 1
-; CHECK-NEXT: Functions: [ 1, 0 ]
+; CHECK-NEXT: Functions: [ 1 ]
; CHECK-NEXT: - Type: CODE
; CHECK-NEXT: Relocations:
; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
@@ -193,10 +193,10 @@ entry:
; CHECK-NEXT: Content: '01000000'
; CHECK-NEXT: - SectionOffset: 24
; CHECK-NEXT: MemoryIndex: 0
-; CHECK-NEXT: Offset:
+; CHECK-NEXT: Offset:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 16
-; CHECK-NEXT: Content: '02000000'
+; CHECK-NEXT: Content: '01000000'
; CHECK-NEXT: - Type: CUSTOM
; CHECK-NEXT: Name: linking
; CHECK-NEXT: DataSize: 20
OpenPOWER on IntegriCloud