[lld] Reapply "[lld][WebAssembly] Do not relocate ABSOLUTE symbols" (#154371) (PR #154494)

YAMAMOTO Takashi via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 20 02:21:44 PDT 2025


https://github.com/yamt created https://github.com/llvm/llvm-project/pull/154494

This reverts commit 28f2fb24e1668943172cfd7a381c4262d51615b4.

The previous attempt was breaking things like __start_ symbols.

This time, use a separate flag instead of abusing ABOSULUTE.

>From 576af7e810dbde174308ebdd6bc5484a98a53575 Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Wed, 20 Aug 2025 17:57:48 +0900
Subject: [PATCH] Reapply "[lld][WebAssembly] Do not relocate ABSOLUTE symbols"
 (#154371)

This reverts commit 28f2fb24e1668943172cfd7a381c4262d51615b4.

The previous attempt was breaking things like __start_ symbols.

This time, use a separate flag instead of abusing ABOSULUTE.
---
 lld/test/wasm/pie.s            | 27 ++++++++++++++++++++++++---
 lld/wasm/Driver.cpp            |  4 +++-
 lld/wasm/Symbols.h             |  5 ++++-
 lld/wasm/SyntheticSections.cpp |  4 +++-
 4 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/lld/test/wasm/pie.s b/lld/test/wasm/pie.s
index 21eac79207318..78d6c85097b10 100644
--- a/lld/test/wasm/pie.s
+++ b/lld/test/wasm/pie.s
@@ -2,7 +2,7 @@
 # RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten %S/Inputs/internal_func.s -o %t.internal_func.o
 # RUN: wasm-ld --no-gc-sections --experimental-pic -pie --unresolved-symbols=import-dynamic -o %t.wasm %t.o %t.internal_func.o
 # RUN: obj2yaml %t.wasm | FileCheck %s
-# RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_apply_data_relocs --no-show-raw-insn --no-leading-addr %t.wasm | FileCheck %s --check-prefixes DISASSEM
+# RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_apply_data_relocs,__wasm_apply_global_relocs --no-show-raw-insn --no-leading-addr %t.wasm | FileCheck %s --check-prefixes DISASSEM
 
 .functype external_func () -> ()
 .functype internal_func1 () -> (i32)
@@ -41,6 +41,9 @@ foo:
   drop
 
   global.get __stack_pointer
+  drop
+
+  global.get __wasm_first_page_end at GOT
   end_function
 
 get_data_address:
@@ -145,6 +148,18 @@ _start:
 # DISASSEM-LABEL:  <__wasm_apply_data_relocs>:
 # DISASSEM:        end
 
+# global 6 is __wasm_first_page_end, which is noReloc and
+# thus should not be relocated.
+#
+# DISASSEM-LABEL:  <__wasm_apply_global_relocs>:
+# DISASSEM:        global.set      4
+# DISASSEM:        global.set      5
+# DISASSEM-NOT:    global.set      6
+# DISASSEM:        global.set      7
+# DISASSEM:        global.set      8
+# DISASSEM:        global.set      9
+# DISASSEM:        end
+
 # Run the same test with extended-const support.  When this is available
 # we don't need __wasm_apply_global_relocs and instead rely on the add
 # instruction in the InitExpr.  We also, therefore, do not need these globals
@@ -173,17 +188,23 @@ _start:
 # EXTENDED-CONST-NEXT:        Type:            I32
 # EXTENDED-CONST-NEXT:        Mutable:         false
 # EXTENDED-CONST-NEXT:        InitExpr:
+# EXTENDED-CONST-NEXT:          Opcode:        I32_CONST
+# EXTENDED-CONST-NEXT:          Value:         65536
+# EXTENDED-CONST-NEXT:      - Index:           7
+# EXTENDED-CONST-NEXT:        Type:            I32
+# EXTENDED-CONST-NEXT:        Mutable:         false
+# EXTENDED-CONST-NEXT:        InitExpr:
 # EXTENDED-CONST-NEXT:          Extended:        true
 # This instruction sequence decodes to:
 # (global.get[0x23] 0x1 i32.const[0x41] 0x0C i32.add[0x6A] end[0x0b])
 # EXTENDED-CONST-NEXT:          Body:            2301410C6A0B
-# EXTENDED-CONST-NEXT:      - Index:           7
+# EXTENDED-CONST-NEXT:      - Index:           8
 # EXTENDED-CONST-NEXT:        Type:            I32
 # EXTENDED-CONST-NEXT:        Mutable:         false
 # EXTENDED-CONST-NEXT:        InitExpr:
 # EXTENDED-CONST-NEXT:          Opcode:        GLOBAL_GET
 # EXTENDED-CONST-NEXT:          Index:         2
-# EXTENDED-CONST-NEXT:      - Index:           8
+# EXTENDED-CONST-NEXT:      - Index:           9
 # EXTENDED-CONST-NEXT:        Type:            I32
 # EXTENDED-CONST-NEXT:        Mutable:         false
 # EXTENDED-CONST-NEXT:        InitExpr:
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index 1c5d21c06f5af..5ad8c1bde289d 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -999,8 +999,10 @@ static void createOptionalSymbols() {
   }
 
   ctx.sym.firstPageEnd = symtab->addOptionalDataSymbol("__wasm_first_page_end");
-  if (ctx.sym.firstPageEnd)
+  if (ctx.sym.firstPageEnd) {
     ctx.sym.firstPageEnd->setVA(ctx.arg.pageSize);
+    ctx.sym.firstPageEnd->noReloc = true;
+  }
 
   // For non-shared memory programs we still need to define __tls_base since we
   // allow object files built with TLS to be linked into single threaded
diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h
index 55ee21939ce07..caee04865545d 100644
--- a/lld/wasm/Symbols.h
+++ b/lld/wasm/Symbols.h
@@ -142,7 +142,7 @@ class Symbol {
       : name(name), file(f), symbolKind(k), referenced(!ctx.arg.gcSections),
         requiresGOT(false), isUsedInRegularObj(false), forceExport(false),
         forceImport(false), canInline(false), traced(false), isStub(false),
-        flags(flags) {}
+        noReloc(false), flags(flags) {}
 
   StringRef name;
   InputFile *file;
@@ -185,6 +185,9 @@ class Symbol {
   // the null function pointer).
   bool isStub : 1;
 
+  // True if this symbol is not relative to __memory_base.
+  bool noReloc : 1;
+
   uint32_t flags;
 
   std::optional<StringRef> importName;
diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp
index e1192706ea913..4d0c5abf799db 100644
--- a/lld/wasm/SyntheticSections.cpp
+++ b/lld/wasm/SyntheticSections.cpp
@@ -440,6 +440,8 @@ void GlobalSection::generateRelocationCode(raw_ostream &os, bool TLS) const {
                                  : WASM_OPCODE_I32_ADD;
 
   for (const Symbol *sym : internalGotSymbols) {
+    if (sym->noReloc)
+      continue;
     if (TLS != sym->isTLS())
       continue;
 
@@ -503,7 +505,7 @@ void GlobalSection::writeBody() {
     bool useExtendedConst = false;
     uint32_t globalIdx;
     int64_t offset;
-    if (ctx.arg.extendedConst && ctx.isPic) {
+    if (ctx.arg.extendedConst && ctx.isPic && !sym->noReloc) {
       if (auto *d = dyn_cast<DefinedData>(sym)) {
         if (!sym->isTLS()) {
           globalIdx = ctx.sym.memoryBase->getGlobalIndex();



More information about the llvm-commits mailing list