uint32_t ObjFile::calcExpectedValue(const WasmRelocation &reloc) const {
switch (reloc.Type) {
case R_WASM_TABLE_INDEX_I32:
- case R_WASM_TABLE_INDEX_SLEB:
- case R_WASM_TABLE_INDEX_REL_SLEB: {
+ case R_WASM_TABLE_INDEX_SLEB: {
const WasmSymbol &sym = wasmObj->syms()[reloc.Index];
return tableEntries[sym.Info.ElementIndex];
}
+ case R_WASM_TABLE_INDEX_REL_SLEB: {
+ const WasmSymbol &sym = wasmObj->syms()[reloc.Index];
+ return tableEntriesRel[sym.Info.ElementIndex];
+ }
case R_WASM_MEMORY_ADDR_SLEB:
case R_WASM_MEMORY_ADDR_I32:
case R_WASM_MEMORY_ADDR_LEB:
// verifying the existing table index relocations
uint32_t totalFunctions =
wasmObj->getNumImportedFunctions() + wasmObj->functions().size();
+ tableEntriesRel.resize(totalFunctions);
tableEntries.resize(totalFunctions);
for (const WasmElemSegment &seg : wasmObj->elements()) {
if (seg.Offset.Opcode != WASM_OPCODE_I32_CONST)
for (uint32_t index = 0; index < seg.Functions.size(); index++) {
uint32_t functionIndex = seg.Functions[index];
+ tableEntriesRel[functionIndex] = index;
tableEntries[functionIndex] = offset + index;
}
}
std::vector<bool> typeIsUsed;
// Maps function indices to table indices
std::vector<uint32_t> tableEntries;
+ std::vector<uint32_t> tableEntriesRel;
std::vector<bool> keptComdats;
std::vector<InputSegment *> segments;
std::vector<InputFunction *> functions;
// Provisional value is table address of the resolved symbol itself
const MCSymbolWasm *Sym = resolveSymbol(*RelEntry.Symbol);
assert(Sym->isFunction());
- return TableIndices[Sym];
+ if (RelEntry.Type == wasm::R_WASM_TABLE_INDEX_REL_SLEB)
+ return TableIndices[Sym] - InitialTableOffset;
+ else
+ return TableIndices[Sym];
}
case wasm::R_WASM_TYPE_INDEX_LEB:
// Provisional value is same as the index
// 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_WASM_TABLE_INDEX_I32 &&
- Rel.Type != wasm::R_WASM_TABLE_INDEX_SLEB)
+ Rel.Type != wasm::R_WASM_TABLE_INDEX_SLEB &&
+ Rel.Type != wasm::R_WASM_TABLE_INDEX_REL_SLEB)
return;
assert(Rel.Symbol->isFunction());
const MCSymbolWasm &WS = *resolveSymbol(*Rel.Symbol);
# CHECK-NEXT: Table:
# CHECK-NEXT: ElemType: FUNCREF
# CHECK-NEXT: Limits:
-# CHECK-NEXT: Initial: 0x00000000
+# CHECK-NEXT: Initial: 0x00000001
# CHECK-NEXT: - Module: env
# CHECK-NEXT: Field: default_func
# CHECK-NEXT: Kind: FUNCTION
# CHECK-NEXT: GlobalMutable: true
# CHECK-NEXT: - Type: FUNCTION
# CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0 ]
+# CHECK-NEXT: - Type: ELEM
+# CHECK-NEXT: Segments:
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Opcode: I32_CONST
+# CHECK-NEXT: Value: 1
+# CHECK-NEXT: Functions: [ 5 ]
# CHECK-NEXT: - Type: DATACOUNT
# CHECK-NEXT: Count: 1
# CHECK-NEXT: - Type: CODE