[llvm] [WebAssembly] Define `__funcref_call_table` in generated asm and objects (PR #180900)

Demetrius Kanios via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 10 12:00:30 PDT 2026


================
@@ -392,6 +392,22 @@ void WebAssemblyAsmPrinter::emitEndOfAsmFile(Module &M) {
   // emitDecls() is not called until now.
   emitDecls(M);
 
+  {
+    StringRef Name = "__funcref_call_table";
+    auto *Sym = static_cast<MCSymbolWasm *>(OutContext.lookupSymbol(Name));
+    if (Sym) {
+      if (!Sym->isFunctionTable())
+        OutContext.reportError(SMLoc(), "symbol is not a wasm funcref table");
+
+      if (Sym->isWeak()) {
+        OutStreamer->emitSymbolAttribute(Sym, MCSA_Weak);
+      }
+      if (!Sym->isDefined()) {
+        OutStreamer->emitLabel(Sym);
----------------
QuantumSegfault wrote:

Perhaps there's some confusion? I'm trying to fix `__funcref_call_table`...not `__indirect_function_table`.

Ever since it's inception `__funcref_call_table` was declared like this.
```c++
MCSymbolWasm *WebAssembly::getOrCreateFuncrefCallTableSymbol(
    MCContext &Ctx, const WebAssemblySubtarget *Subtarget) {
  StringRef Name = "__funcref_call_table";
  auto *Sym = static_cast<MCSymbolWasm *>(Ctx.lookupSymbol(Name));
  if (Sym) {
    if (!Sym->isFunctionTable())
      Ctx.reportError(SMLoc(), "symbol is not a wasm funcref table");
  } else {
    Sym = static_cast<MCSymbolWasm *>(Ctx.getOrCreateSymbol(Name));

    // Setting Weak ensure only one table is left after linking when multiple
    // modules define the table.
    Sym->setWeak(true);

    wasm::WasmLimits Limits = {0, 1, 1, 0};
    wasm::WasmTableType TableType = {wasm::ValType::FUNCREF, Limits};
    Sym->setType(wasm::WASM_SYMBOL_TYPE_TABLE);
    Sym->setTableType(TableType);
  }
  // MVP object files can't have symtab entries for tables.
  if (!(Subtarget && Subtarget->hasCallIndirectOverlong()))
    Sym->setOmitFromLinkingSection();
  return Sym;
}
```

If any exist, they can all be merged into the same. However when outputting `-filetype=obj` directly from `llc`, it would just error out with `LLVM ERROR: undefined table symbol cannot be weak`. It never worked.

I do want to set "weak" + "defined", but my approach was the only one I found. `emitLabel` IS what defines the MCSymbol, strangely enough. Do you know another way to define an MCSymbol?

https://github.com/llvm/llvm-project/pull/180900


More information about the llvm-commits mailing list