diff options
Diffstat (limited to 'llvm/lib/MC/WasmObjectWriter.cpp')
-rw-r--r-- | llvm/lib/MC/WasmObjectWriter.cpp | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp index d16be49..b2c8c02 100644 --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -405,12 +405,17 @@ void WasmObjectWriter::writeHeader(const MCAssembler &Asm) { void WasmObjectWriter::executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) { - // As a stopgap measure until call_indirect instructions start explicitly - // referencing the indirect function table via TABLE_NUMBER relocs, ensure - // that the indirect function table import makes it to the output if anything - // in the compilation unit has caused it to be present. - if (auto *Sym = Asm.getContext().lookupSymbol("__indirect_function_table")) - Asm.registerSymbol(*Sym); + // Some compilation units require the indirect function table to be present + // but don't explicitly reference it. This is the case for call_indirect + // without the reference-types feature, and also function bitcasts in all + // cases. In those cases the __indirect_function_table has the + // WASM_SYMBOL_NO_STRIP attribute. Here we make sure this symbol makes it to + // the assembler, if needed. + if (auto *Sym = Asm.getContext().lookupSymbol("__indirect_function_table")) { + const auto *WasmSym = static_cast<const MCSymbolWasm *>(Sym); + if (WasmSym->isNoStrip()) + Asm.registerSymbol(*Sym); + } // Build a map of sections to the function that defines them, for use // in recordRelocation. @@ -509,21 +514,18 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm, Type == wasm::R_WASM_TABLE_INDEX_I32 || Type == wasm::R_WASM_TABLE_INDEX_I64) { // TABLE_INDEX relocs implicitly use the default indirect function table. + // We require the function table to have already been defined. 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"); + if (!Sym || !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(); + // Ensure that __indirect_function_table reaches the output. + Sym->setNoStrip(); + Asm.registerSymbol(*Sym); } - Sym->setUsedInReloc(); - Asm.registerSymbol(*Sym); } // Relocation other than R_WASM_TYPE_INDEX_LEB are required to be @@ -1211,6 +1213,9 @@ static bool isInSymtab(const MCSymbolWasm &Sym) { if (Sym.isSection()) return false; + if (Sym.omitFromLinkingSection()) + return false; + return true; } @@ -1674,10 +1679,6 @@ 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; |