[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:
Sam Clegg 2018-01-31 19:28:47 +00:00
parent f9a9e9a251
commit f9edbe95db
2 changed files with 29 additions and 35 deletions

View File

@ -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);
}
};

View File

@ -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