Index: lib/MC/WasmObjectWriter.cpp =================================================================== --- lib/MC/WasmObjectWriter.cpp +++ lib/MC/WasmObjectWriter.cpp @@ -211,11 +211,11 @@ // Index values to use for fixing up call_indirect type indices. // Maps function symbols to the index of the type of the function DenseMap TypeIndices; - // Maps function symbols to the table element index space. Used - // for TABLE_INDEX relocation types (i.e. address taken functions). - DenseMap IndirectSymbolIndices; // Maps function/global symbols to the function/global index space. DenseMap SymbolIndices; + // Maps function symbol indices to the table element index space. Used + // for TABLE_INDEX relocation types (i.e. address taken functions). + SmallVector TableIndices; DenseMap FunctionTypeIndices; @@ -223,6 +223,7 @@ SmallVector Globals; unsigned NumFunctionImports = 0; unsigned NumGlobalImports = 0; + unsigned InitialTableOffset = 1; // TargetObjectWriter wrappers. bool is64Bit() const { return TargetObjectWriter->is64Bit(); } @@ -248,7 +249,7 @@ DataRelocations.clear(); TypeIndices.clear(); SymbolIndices.clear(); - IndirectSymbolIndices.clear(); + TableIndices.clear(); FunctionTypeIndices.clear(); FunctionTypes.clear(); Globals.clear(); @@ -516,14 +517,23 @@ return Value; } -// Get a provisional table index. This isn't used by the linker at all; -// for now we'll write out the same value that we always have. TODO make neater +// Get a provisional table index. For table relocations, the relocation +// entry contains the actual function symbol index, and that's all that's +// used by the linker. However, as a nice touch so that the object files +// "work", we create provisional table and table indexes just for show. uint32_t WasmObjectWriter::getProvisionalTableIndex( - const WasmRelocationEntry &RelEntry) { - if (!IndirectSymbolIndices.count(RelEntry.Symbol)) - report_fatal_error("symbol not found in table index space: " + + const WasmRelocationEntry &RelEntry) { + const MCSymbolWasm *Sym = ResolveSymbol(*RelEntry.Symbol); + assert(Sym->isFunction()); + if (!SymbolIndices.count(Sym)) + report_fatal_error("symbol not found in function/global index space: " + RelEntry.Symbol->getName()); - return IndirectSymbolIndices[RelEntry.Symbol]; + uint32_t SymbolIndex = SymbolIndices[Sym]; + int32_t TableIndex = TableIndices[SymbolIndex]; + if (TableIndex < 0) + report_fatal_error("symbol not found in table index space: " + + Sym->getName()); + return TableIndex; } static void addData(SmallVectorImpl &DataBytes, @@ -790,7 +800,7 @@ // init expr for starting offset write8(wasm::WASM_OPCODE_I32_CONST); - encodeSLEB128(0, getStream()); + encodeSLEB128(InitialTableOffset, getStream()); write8(wasm::WASM_OPCODE_END); encodeULEB128(TableElems.size(), getStream()); @@ -1307,26 +1317,21 @@ } { + TableIndices.resize(NumFunctionImports + Functions.size(), -1); 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(); - DEBUG(dbgs() << " -> adding 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[WS]; + if (TableIndices[SymbolIndex] == -1) { + TableIndices[SymbolIndex] = TableElems.size() + InitialTableOffset; + DEBUG(dbgs() << " -> adding to table: " << TableElems.size() << "\n"); + TableElems.push_back(SymbolIndex); } }; Index: test/MC/WebAssembly/external-func-address.ll =================================================================== --- test/MC/WebAssembly/external-func-address.ll +++ test/MC/WebAssembly/external-func-address.ll @@ -29,7 +29,7 @@ ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: ; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 0 +; CHECK-NEXT: Value: 1 ; CHECK-NEXT: Functions: [ 0 ] ; CHECK: - Type: DATA ; CHECK-NEXT: Relocations: Index: test/MC/WebAssembly/global-ctor-dtor.ll =================================================================== --- test/MC/WebAssembly/global-ctor-dtor.ll +++ test/MC/WebAssembly/global-ctor-dtor.ll @@ -87,7 +87,7 @@ ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: ; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 0 +; CHECK-NEXT: Value: 1 ; CHECK-NEXT: Functions: [ 5, 7 ] ; CHECK-NEXT: - Type: CODE ; CHECK-NEXT: Relocations: @@ -121,13 +121,13 @@ ; CHECK-NEXT: Body: 1080808080000B ; CHECK-NEXT: - Index: 6 ; CHECK-NEXT: Locals: -; CHECK-NEXT: Body: 024041808080800041004180808080001081808080000D000F0B00000B +; CHECK-NEXT: Body: 024041818080800041004180808080001081808080000D000F0B00000B ; CHECK-NEXT: - Index: 7 ; CHECK-NEXT: Locals: ; CHECK-NEXT: Body: 1082808080000B ; CHECK-NEXT: - Index: 8 ; CHECK-NEXT: Locals: -; CHECK-NEXT: Body: 024041818080800041004180808080001081808080000D000F0B00000B +; CHECK-NEXT: Body: 024041828080800041004180808080001081808080000D000F0B00000B ; CHECK-NEXT: - Type: DATA ; CHECK-NEXT: Segments: ; CHECK-NEXT: - SectionOffset: 6 Index: test/MC/WebAssembly/weak-alias.ll =================================================================== --- test/MC/WebAssembly/weak-alias.ll +++ test/MC/WebAssembly/weak-alias.ll @@ -62,7 +62,7 @@ ; 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 @@ -130,8 +130,8 @@ ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: ; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 0 -; CHECK-NEXT: Functions: [ 1, 0 ] +; CHECK-NEXT: Value: 1 +; CHECK-NEXT: Functions: [ 1 ] ; CHECK-NEXT: - Type: CODE ; CHECK-NEXT: Relocations: ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB @@ -188,9 +188,14 @@ ; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 8 -; CHECK-NEXT: Content: '00000000' - -; CHECK: - Type: CUSTOM +; CHECK-NEXT: Content: '01000000' +; CHECK-NEXT: - SectionOffset: 24 +; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: Offset: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 16 +; CHECK-NEXT: Content: '01000000' +; CHECK-NEXT: - Type: CUSTOM ; CHECK-NEXT: Name: name ; CHECK-NEXT: FunctionNames: ; CHECK-NEXT: - Index: 1