diff options
author | Andy Wingo <wingo@igalia.com> | 2020-11-25 08:31:05 -0800 |
---|---|---|
committer | Sam Clegg <sbc@chromium.org> | 2020-11-25 08:38:43 -0800 |
commit | feac819e50b2b62eeafdf1a7e6ecaa725d7bf08d (patch) | |
tree | 9dea0e43c4e5ae68636f4da37a8e0ef1ceab876f /llvm/lib/MC/WasmObjectWriter.cpp | |
parent | a8d74517dcff42d3300aa144820b2772c1560a96 (diff) | |
download | llvm-feac819e50b2b62eeafdf1a7e6ecaa725d7bf08d.zip llvm-feac819e50b2b62eeafdf1a7e6ecaa725d7bf08d.tar.gz llvm-feac819e50b2b62eeafdf1a7e6ecaa725d7bf08d.tar.bz2 |
[MC][WebAssembly] Only emit indirect function table import if needed
The indirect function table, synthesized by the linker, is needed if and
only if there are TABLE_INDEX relocs.
Differential Revision: https://reviews.llvm.org/D91637
Diffstat (limited to 'llvm/lib/MC/WasmObjectWriter.cpp')
-rw-r--r-- | llvm/lib/MC/WasmObjectWriter.cpp | 64 |
1 files changed, 48 insertions, 16 deletions
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp index 029b776..a05d4c9 100644 --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -40,8 +40,8 @@ using namespace llvm; namespace { -// Went we ceate the indirect function table we start at 1, so that there is -// and emtpy slot at 0 and therefore calling a null function pointer will trap. +// When we create the indirect function table we start at 1, so that there is +// and empty slot at 0 and therefore calling a null function pointer will trap. static const uint32_t InitialTableOffset = 1; // For patching purposes, we need to remember where each section starts, both @@ -218,9 +218,7 @@ class WasmObjectWriter : public MCObjectWriter { SmallVector<WasmDataSegment, 4> DataSegments; unsigned NumFunctionImports = 0; unsigned NumGlobalImports = 0; - // NumTableImports is initialized to 1 to account for the hardcoded import of - // __indirect_function_table - unsigned NumTableImports = 1; + unsigned NumTableImports = 0; unsigned NumEventImports = 0; uint32_t SectionCount = 0; @@ -270,7 +268,7 @@ private: SectionFunctions.clear(); NumFunctionImports = 0; NumGlobalImports = 0; - NumTableImports = 1; + NumTableImports = 0; MCObjectWriter::reset(); } @@ -497,6 +495,29 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm, SymA = cast<MCSymbolWasm>(SectionSymbol); } + if (Type == wasm::R_WASM_TABLE_INDEX_REL_SLEB || + Type == wasm::R_WASM_TABLE_INDEX_SLEB || + Type == wasm::R_WASM_TABLE_INDEX_SLEB64 || + Type == wasm::R_WASM_TABLE_INDEX_I32 || + Type == wasm::R_WASM_TABLE_INDEX_I64) { + // TABLE_INDEX relocs implicitly use the default indirect function table. + auto TableName = "__indirect_function_table"; + MCSymbolWasm *Sym = cast_or_null<MCSymbolWasm>(Ctx.lookupSymbol(TableName)); + if (Sym) { + if (!Sym->isFunctionTable()) + Ctx.reportError( + Fixup.getLoc(), + "symbol '__indirect_function_table' is not a function table"); + } else { + Sym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(TableName)); + Sym->setFunctionTable(); + // The default function table is synthesized by the linker. + Sym->setUndefined(); + } + Sym->setUsedInReloc(); + Asm.registerSymbol(*Sym); + } + // Relocation other than R_WASM_TYPE_INDEX_LEB are required to be // against a named symbol. if (Type != wasm::R_WASM_TYPE_INDEX_LEB) { @@ -1201,16 +1222,6 @@ void WasmObjectWriter::prepareImports( : wasm::WASM_LIMITS_FLAG_NONE; Imports.push_back(MemImport); - // For now, always emit the table section, since indirect calls are not - // valid without it. In the future, we could perhaps be more clever and omit - // it if there are no indirect calls. - wasm::WasmImport TableImport; - TableImport.Module = "env"; - TableImport.Field = "__indirect_function_table"; - TableImport.Kind = wasm::WASM_EXTERNAL_TABLE; - TableImport.Table.ElemType = wasm::WASM_TYPE_FUNCREF; - Imports.push_back(TableImport); - // Populate SignatureIndices, and Imports and WasmIndices for undefined // symbols. This must be done before populating WasmIndices for defined // symbols. @@ -1269,6 +1280,23 @@ void WasmObjectWriter::prepareImports( Imports.push_back(Import); assert(WasmIndices.count(&WS) == 0); WasmIndices[&WS] = NumEventImports++; + } else if (WS.isTable()) { + if (WS.isWeak()) + report_fatal_error("undefined table symbol cannot be weak"); + + wasm::WasmImport Import; + Import.Module = WS.getImportModule(); + Import.Field = WS.getImportName(); + Import.Kind = wasm::WASM_EXTERNAL_TABLE; + wasm::ValType ElemType = WS.getTableType(); + Import.Table.ElemType = uint8_t(ElemType); + // FIXME: Extend table type to include limits? For now we don't specify + // a min or max which does not place any restrictions on the size of the + // imported table. + Import.Table.Limits = {wasm::WASM_LIMITS_FLAG_NONE, 0, 0}; + Imports.push_back(Import); + assert(WasmIndices.count(&WS) == 0); + WasmIndices[&WS] = NumTableImports++; } } } @@ -1618,6 +1646,10 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm, WS.setIndex(InvalidIndex); continue; } + if (WS.isTable() && WS.getName() == "__indirect_function_table") { + // For the moment, don't emit table symbols -- wasm-ld can't handle them. + continue; + } LLVM_DEBUG(dbgs() << "adding to symtab: " << WS << "\n"); uint32_t Flags = 0; |