aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/WasmObjectWriter.cpp
diff options
context:
space:
mode:
authorAndy Wingo <wingo@igalia.com>2020-11-25 08:31:05 -0800
committerSam Clegg <sbc@chromium.org>2020-11-25 08:38:43 -0800
commitfeac819e50b2b62eeafdf1a7e6ecaa725d7bf08d (patch)
tree9dea0e43c4e5ae68636f4da37a8e0ef1ceab876f /llvm/lib/MC/WasmObjectWriter.cpp
parenta8d74517dcff42d3300aa144820b2772c1560a96 (diff)
downloadllvm-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.cpp64
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;