Index: llvm/trunk/lib/MC/WasmObjectWriter.cpp =================================================================== --- llvm/trunk/lib/MC/WasmObjectWriter.cpp +++ llvm/trunk/lib/MC/WasmObjectWriter.cpp @@ -499,25 +499,44 @@ } // Compute a value to write into the code at the location covered -// by RelEntry. This value isn't used by the static linker, since -// we have addends; it just serves to make the code more readable -// and to make standalone wasm modules directly usable. +// by RelEntry. This value isn't used by the static linker; it just serves +// to make the object format more readable and more likely to be directly +// useable. uint32_t WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry) { - const MCSymbolWasm *Sym = ResolveSymbol(*RelEntry.Symbol); - // For undefined symbols, use zero - if (!Sym->isDefined()) - return 0; - - uint32_t GlobalIndex = SymbolIndices[Sym]; - const WasmGlobal& Global = Globals[GlobalIndex - NumGlobalImports]; - uint64_t Address = Global.InitialValue + RelEntry.Addend; - - // Ignore overflow. LLVM allows address arithmetic to silently wrap. - uint32_t Value = Address; + 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_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 + 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 + const MCSymbolWasm *Sym = ResolveSymbol(*RelEntry.Symbol); + // For undefined symbols, use zero + if (!Sym->isDefined()) + return 0; + + uint32_t GlobalIndex = SymbolIndices[Sym]; + const WasmGlobal& Global = Globals[GlobalIndex - NumGlobalImports]; + uint64_t Address = Global.InitialValue + RelEntry.Addend; - return Value; + // Ignore overflow. LLVM allows address arithmetic to silently wrap. + return Address; + } + default: + llvm_unreachable("invalid relocation type"); + } } static void addData(SmallVectorImpl &DataBytes, @@ -564,32 +583,19 @@ DEBUG(dbgs() << "addData -> " << DataBytes.size() << "\n"); } -uint32_t WasmObjectWriter::getRelocationIndexValue( - const WasmRelocationEntry &RelEntry) { - switch (RelEntry.Type) { - case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB: - case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32: - 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_FUNCTION_INDEX_LEB: - case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB: - case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB: - case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: - case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32: - if (!SymbolIndices.count(RelEntry.Symbol)) - report_fatal_error("symbol not found in function/global index space: " + - RelEntry.Symbol->getName()); - return SymbolIndices[RelEntry.Symbol]; - case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB: +uint32_t +WasmObjectWriter::getRelocationIndexValue(const WasmRelocationEntry &RelEntry) { + if (RelEntry.Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB) { if (!TypeIndices.count(RelEntry.Symbol)) report_fatal_error("symbol not found in type index space: " + RelEntry.Symbol->getName()); return TypeIndices[RelEntry.Symbol]; - default: - llvm_unreachable("invalid relocation type"); } + + if (!SymbolIndices.count(RelEntry.Symbol)) + report_fatal_error("symbol not found in function/global index space: " + + RelEntry.Symbol->getName()); + return SymbolIndices[RelEntry.Symbol]; } // Apply the portions of the relocation records that we can handle ourselves @@ -603,35 +609,23 @@ RelEntry.Offset; DEBUG(dbgs() << "applyRelocation: " << RelEntry << "\n"); + uint32_t Value = getProvisionalValue(RelEntry); + switch (RelEntry.Type) { - case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB: case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB: case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB: - case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB: { - uint32_t Index = getRelocationIndexValue(RelEntry); - WritePatchableSLEB(Stream, Index, Offset); - break; - } - case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32: { - uint32_t Index = getRelocationIndexValue(RelEntry); - WriteI32(Stream, Index, Offset); - break; - } - case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: { - uint32_t Value = getProvisionalValue(RelEntry); - WritePatchableSLEB(Stream, Value, Offset); - break; - } - case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB: { - uint32_t Value = getProvisionalValue(RelEntry); + case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB: + case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB: WritePatchableLEB(Stream, Value, Offset); break; - } - case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32: { - uint32_t Value = getProvisionalValue(RelEntry); + case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32: + case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32: WriteI32(Stream, Value, Offset); break; - } + case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB: + case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: + WritePatchableSLEB(Stream, Value, Offset); + break; default: llvm_unreachable("invalid relocation type"); } Index: llvm/trunk/test/MC/WebAssembly/external-func-address.ll =================================================================== --- llvm/trunk/test/MC/WebAssembly/external-func-address.ll +++ llvm/trunk/test/MC/WebAssembly/external-func-address.ll @@ -34,5 +34,5 @@ ; CHECK: - Type: DATA ; CHECK-NEXT: Relocations: ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32 -; CHECK-NEXT: Index: 1 +; CHECK-NEXT: Index: 0 ; CHECK-NEXT: Offset: 0x00000006 Index: llvm/trunk/test/MC/WebAssembly/func-address.ll =================================================================== --- llvm/trunk/test/MC/WebAssembly/func-address.ll +++ llvm/trunk/test/MC/WebAssembly/func-address.ll @@ -42,6 +42,6 @@ ; CHECK: Relocation { ; CHECK: Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB (1) ; CHECK: Offset: 0x1E -; CHECK: Index: 0x1 +; CHECK: Index: 0x2 ; CHECK: } ; CHECK: } Index: llvm/trunk/test/MC/WebAssembly/global-ctor-dtor.ll =================================================================== --- llvm/trunk/test/MC/WebAssembly/global-ctor-dtor.ll +++ llvm/trunk/test/MC/WebAssembly/global-ctor-dtor.ll @@ -95,7 +95,7 @@ ; CHECK-NEXT: Index: 0 ; CHECK-NEXT: Offset: 0x00000004 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB -; CHECK-NEXT: Index: 1 +; CHECK-NEXT: Index: 5 ; CHECK-NEXT: Offset: 0x0000000F ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB ; CHECK-NEXT: Index: 0 @@ -107,7 +107,7 @@ ; CHECK-NEXT: Index: 2 ; CHECK-NEXT: Offset: 0x0000002C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB -; CHECK-NEXT: Index: 2 +; CHECK-NEXT: Index: 7 ; CHECK-NEXT: Offset: 0x00000037 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB ; CHECK-NEXT: Index: 0 Index: llvm/trunk/test/MC/WebAssembly/weak-alias.ll =================================================================== --- llvm/trunk/test/MC/WebAssembly/weak-alias.ll +++ llvm/trunk/test/MC/WebAssembly/weak-alias.ll @@ -174,7 +174,7 @@ ; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000000F ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32 -; CHECK-NEXT: Index: 2 +; CHECK-NEXT: Index: 0 ; CHECK-NEXT: Offset: 0x00000018 ; CHECK-NEXT: Segments: ; CHECK-NEXT: - SectionOffset: 6