[lld] [llvm] [WebAssembly] Require tags for Wasm EH and Wasm SJLJ to be defined externally (PR #159143)
Sam Clegg via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 17 14:52:42 PDT 2025
https://github.com/sbc100 updated https://github.com/llvm/llvm-project/pull/159143
>From ae501eb8865488feac0a70a706781d5dcd99711b Mon Sep 17 00:00:00 2001
From: Sam Clegg <sbc at chromium.org>
Date: Mon, 15 Sep 2025 17:13:02 -0700
Subject: [PATCH] [WebAssembly] Require tags for Wasm EH and Wasm SJLJ to be
defined by compiler-rt
Rather then defining these tags in each object file that requires them
we can can declare them as undefined and require that they defined
externally in, for example, compiler-rt.
---
lld/test/wasm/Inputs/tags.s | 7 ++++++
lld/test/wasm/tag-section.ll | 16 +++++++------
llvm/lib/CodeGen/AsmPrinter/WasmException.cpp | 23 -------------------
llvm/lib/CodeGen/AsmPrinter/WasmException.h | 2 +-
.../WebAssembly/WebAssemblyAsmPrinter.cpp | 7 ------
.../CodeGen/WebAssembly/exception-legacy.ll | 3 ++-
llvm/test/CodeGen/WebAssembly/exception.ll | 3 ++-
7 files changed, 21 insertions(+), 40 deletions(-)
create mode 100644 lld/test/wasm/Inputs/tags.s
diff --git a/lld/test/wasm/Inputs/tags.s b/lld/test/wasm/Inputs/tags.s
new file mode 100644
index 0000000000000..e59b31b25626d
--- /dev/null
+++ b/lld/test/wasm/Inputs/tags.s
@@ -0,0 +1,7 @@
+.globl __cpp_exception
+.tagtype __cpp_exception i32
+__cpp_exception:
+
+.globl __c_longjmp
+.tagtype __c_longjmp i32
+__c_longjmp:
diff --git a/lld/test/wasm/tag-section.ll b/lld/test/wasm/tag-section.ll
index 20823c72c6511..45a578fb12f4f 100644
--- a/lld/test/wasm/tag-section.ll
+++ b/lld/test/wasm/tag-section.ll
@@ -1,18 +1,20 @@
-; Static code
+; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t_tags.o %p/Inputs/tags.s
+
+; Static code, with tags defined in tags.s
; RUN: llc -filetype=obj -wasm-enable-eh -exception-model=wasm -mattr=+exception-handling %p/Inputs/tag-section1.ll -o %t1.o
; RUN: llc -filetype=obj -wasm-enable-eh -exception-model=wasm -mattr=+exception-handling %p/Inputs/tag-section2.ll -o %t2.o
; RUN: llc -filetype=obj -wasm-enable-eh -exception-model=wasm -mattr=+exception-handling %s -o %t.o
-; RUN: wasm-ld -o %t.wasm %t.o %t1.o %t2.o
-; RUN: wasm-ld --export-all -o %t-export-all.wasm %t.o %t1.o %t2.o
+; RUN: wasm-ld -o %t.wasm %t.o %t1.o %t2.o %t_tags.o
+; RUN: wasm-ld --export-all -o %t-export-all.wasm %t.o %t1.o %t2.o %t_tags.o
; RUN: obj2yaml %t.wasm | FileCheck %s --check-prefix=NOPIC
; RUN: obj2yaml %t-export-all.wasm | FileCheck %s --check-prefix=NOPIC-EXPORT-ALL
-; PIC code
+; PIC code with tags imported
; RUN: llc -filetype=obj -wasm-enable-eh -exception-model=wasm -mattr=+exception-handling -relocation-model=pic %p/Inputs/tag-section1.ll -o %t1.o
; RUN: llc -filetype=obj -wasm-enable-eh -exception-model=wasm -mattr=+exception-handling -relocation-model=pic %p/Inputs/tag-section2.ll -o %t2.o
; RUN: llc -filetype=obj -wasm-enable-eh -exception-model=wasm -mattr=+exception-handling -relocation-model=pic %s -o %t.o
-; RUN: wasm-ld --import-undefined --experimental-pic --unresolved-symbols=import-dynamic -pie -o %t.wasm %t.o %t1.o %t2.o
-; RUN: obj2yaml %t.wasm | FileCheck %s --check-prefix=PIC
+; RUN: wasm-ld --import-undefined --experimental-pic --unresolved-symbols=import-dynamic -pie -o %t_pic.wasm %t.o %t1.o %t2.o
+; RUN: obj2yaml %t_pic.wasm | FileCheck %s --check-prefix=PIC
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-emscripten"
@@ -49,7 +51,7 @@ define void @_start() {
; NOPIC-EXPORT-ALL: Kind: TAG
; NOPIC-EXPORT-ALL: Index: 0
-; In PIC mode, tags are undefined and imported from JS.
+; In PIC mode, we leave the tags as undefined and they should be imported
; PIC: Sections:
; PIC: - Type: TYPE
; PIC-NEXT: Signatures:
diff --git a/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp b/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp
index bf65e525dde14..0309c65c7fb9d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp
@@ -19,29 +19,6 @@
#include "llvm/MC/MCStreamer.h"
using namespace llvm;
-void WasmException::endModule() {
- // These are symbols used to throw/catch C++ exceptions and C longjmps. These
- // symbols have to be emitted somewhere once in the module. Check if each of
- // the symbols has already been created, i.e., we have at least one 'throw' or
- // 'catch' instruction with the symbol in the module, and emit the symbol only
- // if so.
- //
- // But in dynamic linking, it is in general not possible to come up with a
- // module instantiating order in which tag-defining modules are loaded before
- // the importing modules. So we make them undefined symbols here, define tags
- // in the JS side, and feed them to each importing module.
- if (!Asm->isPositionIndependent()) {
- for (const char *SymName : {"__cpp_exception", "__c_longjmp"}) {
- SmallString<60> NameStr;
- Mangler::getNameWithPrefix(NameStr, SymName, Asm->getDataLayout());
- if (Asm->OutContext.lookupSymbol(NameStr)) {
- MCSymbol *ExceptionSym = Asm->GetExternalSymbolSymbol(SymName);
- Asm->OutStreamer->emitLabel(ExceptionSym);
- }
- }
- }
-}
-
void WasmException::endFunction(const MachineFunction *MF) {
bool ShouldEmitExceptionTable = false;
for (const LandingPadInfo &Info : MF->getLandingPads()) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/WasmException.h b/llvm/lib/CodeGen/AsmPrinter/WasmException.h
index 86cc37dfde079..9b545dfc98857 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WasmException.h
+++ b/llvm/lib/CodeGen/AsmPrinter/WasmException.h
@@ -26,7 +26,7 @@ class LLVM_LIBRARY_VISIBILITY WasmException : public EHStreamer {
public:
WasmException(AsmPrinter *A) : EHStreamer(A) {}
- void endModule() override;
+ void endModule() override {}
void beginFunction(const MachineFunction *MF) override {}
void endFunction(const MachineFunction *MF) override;
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
index db832bc91ddb5..6bb064a53eabd 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -249,13 +249,6 @@ MCSymbol *WebAssemblyAsmPrinter::getOrCreateWasmSymbol(StringRef Name) {
SmallVector<wasm::ValType, 4> Params;
if (Name == "__cpp_exception" || Name == "__c_longjmp") {
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_TAG);
- // In static linking we define tag symbols in WasmException::endModule().
- // But we may have multiple objects to be linked together, each of which
- // defines the tag symbols. To resolve them, we declare them as weak. In
- // dynamic linking we make tag symbols undefined in the backend, define it
- // in JS, and feed them to each importing module.
- if (!isPositionIndependent())
- WasmSym->setWeak(true);
WasmSym->setExternal(true);
// Currently both C++ exceptions and C longjmps have a single pointer type
diff --git a/llvm/test/CodeGen/WebAssembly/exception-legacy.ll b/llvm/test/CodeGen/WebAssembly/exception-legacy.ll
index 149e443903a88..b96a664166f42 100644
--- a/llvm/test/CodeGen/WebAssembly/exception-legacy.ll
+++ b/llvm/test/CodeGen/WebAssembly/exception-legacy.ll
@@ -573,4 +573,5 @@ attributes #0 = { nounwind }
attributes #1 = { noreturn }
attributes #2 = { noreturn nounwind }
-; CHECK: __cpp_exception:
+;; The exception tag should not be defined locally
+; CHECK-NOT: __cpp_exception:
diff --git a/llvm/test/CodeGen/WebAssembly/exception.ll b/llvm/test/CodeGen/WebAssembly/exception.ll
index fc42f050a687e..873386b3dcc6d 100644
--- a/llvm/test/CodeGen/WebAssembly/exception.ll
+++ b/llvm/test/CodeGen/WebAssembly/exception.ll
@@ -670,4 +670,5 @@ attributes #0 = { nounwind }
attributes #1 = { noreturn }
attributes #2 = { noreturn nounwind }
-; CHECK: __cpp_exception:
+;; The exception tag should not be defined locally
+; CHECK-NOT: __cpp_exception:
More information about the llvm-commits
mailing list