mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-28 10:46:11 +00:00
[WebAssembly] MC: Resolve aliases when creating provisional table entries
This change is useful for the upcoming addition of the symbol table (D41954) since in that world aliases for given function all share the same function index. This change does not effect lld because it essentially ignores the wasm "table". The table exists only to the wasm objects will validate and disassembly meaningfully. Patch by Nicholas Wilson! Differential Revision: https://reviews.llvm.org/D42095 llvm-svn: 323900
This commit is contained in:
parent
f9a9e9a251
commit
f9edbe95db
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user