[lld] 53217ec - [lld][WebAssembly] Don't apply data relocations at static constructor time

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 27 15:50:30 PDT 2022


Author: Sam Clegg
Date: 2022-06-27T15:50:02-07:00
New Revision: 53217ecb882c25bb69e6065512a0627828d6e870

URL: https://github.com/llvm/llvm-project/commit/53217ecb882c25bb69e6065512a0627828d6e870
DIFF: https://github.com/llvm/llvm-project/commit/53217ecb882c25bb69e6065512a0627828d6e870.diff

LOG: [lld][WebAssembly] Don't apply data relocations at static constructor time

Instead, export `__wasm_apply_data_relocs` and `__wasm_call_ctors`
separately.

This is required since user code in a shared library (such as static
constructors) should not be run until relocations have been applied to
all loaded libraries.

See: https://github.com/emscripten-core/emscripten/issues/17295

Differential Revision: https://reviews.llvm.org/D128515

Added: 
    

Modified: 
    lld/test/wasm/data-segments.ll
    lld/test/wasm/pie.ll
    lld/test/wasm/shared-weak-symbols.s
    lld/test/wasm/shared.s
    lld/test/wasm/shared64.s
    lld/test/wasm/tls-export.s
    lld/test/wasm/tls-non-shared-memory.s
    lld/wasm/Driver.cpp
    lld/wasm/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/test/wasm/data-segments.ll b/lld/test/wasm/data-segments.ll
index 11fa97fd98e82..cc97698552e9f 100644
--- a/lld/test/wasm/data-segments.ll
+++ b/lld/test/wasm/data-segments.ll
@@ -30,12 +30,12 @@
 ; Also test in combination with PIC/pie
 ; RUN: wasm-ld --experimental-pic -pie -no-gc-sections --no-entry --shared-memory --max-memory=131072 %t.atomics.bulk-mem.pic.o -o %t.pic.wasm
 ; RUN: obj2yaml %t.pic.wasm | FileCheck %s --check-prefixes PASSIVE-PIC,PASSIVE32-PIC
-; RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_init_memory --no-show-raw-insn --no-leading-addr %t.pic.wasm | FileCheck %s --check-prefixes DIS,PIC-DIS -DPTR=i32
+; RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_apply_data_relocs,__wasm_init_memory --no-show-raw-insn --no-leading-addr %t.pic.wasm | FileCheck %s --check-prefixes DIS,PIC-DIS -DPTR=i32
 
 ; Also test in combination with PIC/pie + wasm64
 ; RUN: wasm-ld -mwasm64 --experimental-pic -pie -no-gc-sections --no-entry --shared-memory --max-memory=131072 %t.atomics.bulk-mem.pic-mem64.o -o %t.pic-mem64.wasm
 ; RUN: obj2yaml %t.pic-mem64.wasm | FileCheck %s --check-prefixes PASSIVE-PIC,PASSIVE64-PIC
-; RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_init_memory --no-show-raw-insn --no-leading-addr %t.pic-mem64.wasm | FileCheck %s --check-prefixes DIS,PIC-DIS -DPTR=i64
+; RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_apply_data_relocs,__wasm_init_memory --no-show-raw-insn --no-leading-addr %t.pic-mem64.wasm | FileCheck %s --check-prefixes DIS,PIC-DIS -DPTR=i64
 
 @a = hidden global [6 x i8] c"hello\00", align 1
 @b = hidden global [8 x i8] c"goodbye\00", align 1
@@ -113,26 +113,26 @@
 ; PASSIVE-NEXT:        Name:            __wasm_init_memory
 
 ;      PASSIVE-PIC:  - Type:            START
-; PASSIVE-PIC-NEXT:    StartFunction:   2
+; PASSIVE-PIC-NEXT:    StartFunction:   3
 ; PASSIVE-PIC-NEXT:  - Type:            DATACOUNT
 ; PASSIVE-PIC-NEXT:    Count:           3
 ; PASSIVE-PIC-NEXT:  - Type:            CODE
 ; PASSIVE-PIC-NEXT:    Functions:
 ; PASSIVE-PIC-NEXT:      - Index:           0
 ; PASSIVE-PIC-NEXT:        Locals:          []
-; PASSIVE-PIC-NEXT:        Body:            10030B
+; PASSIVE-PIC-NEXT:        Body:            0B
 ; PASSIVE-PIC-NEXT:      - Index:           1
 ; PASSIVE-PIC-NEXT:        Locals:          []
 ; PASSIVE-PIC-NEXT:        Body:            {{.*}}
 ; PASSIVE-PIC-NEXT:      - Index:           2
+; PASSIVE-PIC-NEXT:        Locals:          []
+; PASSIVE-PIC-NEXT:        Body:            0B
+; PASSIVE-PIC-NEXT:      - Index:           3
 ; PASSIVE-PIC-NEXT:        Locals:
 ; PASSIVE32-PIC-NEXT:          - Type:            I32
 ; PASSIVE64-PIC-NEXT:          - Type:            I64
 ; PASSIVE-PIC-NEXT:              Count:           2
 ; PASSIVE-PIC-NEXT:        Body:            {{.*}}
-; PASSIVE-PIC-NEXT:      - Index:           3
-; PASSIVE-PIC-NEXT:        Locals:          []
-; PASSIVE-PIC-NEXT:        Body:            0B
 ; PASSIVE-PIC-NEXT:  - Type:            DATA
 ; PASSIVE-PIC-NEXT:    Segments:
 ; PASSIVE-PIC-NEXT:      - SectionOffset:   3
@@ -152,18 +152,19 @@
 ; PASSIVE-PIC-NEXT:      - Index:           1
 ; PASSIVE-PIC-NEXT:        Name:            __wasm_init_tls
 ; PASSIVE-PIC-NEXT:      - Index:           2
-; PASSIVE-PIC-NEXT:        Name:            __wasm_init_memory
-; PASSIVE-PIC-NEXT:      - Index:           3
 ; PASSIVE-PIC-NEXT:        Name:            __wasm_apply_data_relocs
+; PASSIVE-PIC-NEXT:      - Index:           3
+; PASSIVE-PIC-NEXT:        Name:            __wasm_init_memory
 
-; In PIC mode __wasm_call_ctors contains a call to __wasm_apply_data_relocs
-; In non-PIC mode __wasm_call_ctors is an emtpy function since there are
 ; no data relocations.
 ; DIS-LABEL:       <__wasm_call_ctors>:
 ; DIS-EMPTY:
-; PIC-DIS-NEXT:    call 3
 ; DIS-NEXT:        end
 
+; In PIC mode __wasm_apply_data_relocs is export seperatly to __wasm_call_ctors
+; PIC-DIS:     <__wasm_apply_data_relocs>:
+; PIC-DIS-EMPTY:
+
 ; DIS-LABEL:       <__wasm_init_memory>:
 
 ; PIC-DIS:           .local [[PTR]]

diff  --git a/lld/test/wasm/pie.ll b/lld/test/wasm/pie.ll
index c781611569944..467cb5d5fc2e2 100644
--- a/lld/test/wasm/pie.ll
+++ b/lld/test/wasm/pie.ll
@@ -1,7 +1,7 @@
 ; RUN: llc -relocation-model=pic -mattr=+mutable-globals -filetype=obj %s -o %t.o
 ; RUN: wasm-ld --no-gc-sections --experimental-pic -pie -o %t.wasm %t.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
-; RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors --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 --no-show-raw-insn --no-leading-addr %t.wasm | FileCheck %s --check-prefixes DISASSEM
 
 target triple = "wasm32-unknown-emscripten"
 
@@ -91,11 +91,13 @@ declare void @external_func()
 ; CHECK-NEXT:         Name:            _start
 ; CHECK-NEXT:     GlobalNames:
 
-; DISASSEM:       <__wasm_call_ctors>:
+; DISASSEM-LABEL:  <__wasm_call_ctors>:
 ; DISASSEM-EMPTY:
-; DISASSEM-NEXT:   call 2
 ; DISASSEM-NEXT:   end
 
+; DISASSEM-LABEL:  <__wasm_apply_data_relocs>:
+; 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
@@ -153,10 +155,10 @@ declare void @external_func()
 ; SHMEM:         - Type:            START
 ; SHMEM-NEXT:      StartFunction:   6
 
-; DISASSEM-SHMEM:       <__wasm_start>:
+; DISASSEM-SHMEM-LABEL:  <__wasm_start>:
 ; DISASSEM-SHMEM-EMPTY:
 ; DISASSEM-SHMEM-NEXT:   call 5
-; DISASSEM-SHMEM-NEXT:   call 3
+; DISASSEM-SHMEM-NEXT:   call 4
 ; DISASSEM-SHMEM-NEXT:   end
 
 ; SHMEM:         FunctionNames:
@@ -167,9 +169,9 @@ declare void @external_func()
 ; SHMEM-NEXT:      - Index:           2
 ; SHMEM-NEXT:        Name:            __wasm_init_tls
 ; SHMEM-NEXT:      - Index:           3
-; SHMEM-NEXT:        Name:            __wasm_init_memory
-; SHMEM-NEXT:      - Index:           4
 ; SHMEM-NEXT:        Name:            __wasm_apply_data_relocs
+; SHMEM-NEXT:      - Index:           4
+; SHMEM-NEXT:        Name:            __wasm_init_memory
 ; SHMEM-NEXT:      - Index:           5
 ; SHMEM-NEXT:        Name:            __wasm_apply_global_relocs
 ; SHMEM-NEXT:      - Index:           6

diff  --git a/lld/test/wasm/shared-weak-symbols.s b/lld/test/wasm/shared-weak-symbols.s
index c74d599602949..90de006353b3d 100644
--- a/lld/test/wasm/shared-weak-symbols.s
+++ b/lld/test/wasm/shared-weak-symbols.s
@@ -62,6 +62,9 @@ call_weak:
 # CHECK-NEXT:       - Name:            __wasm_call_ctors
 # CHECK-NEXT:         Kind:            FUNCTION
 # CHECK-NEXT:         Index:           1
+# CHECK-NEXT:       - Name:            __wasm_apply_data_relocs
+# CHECK-NEXT:         Kind:            FUNCTION
+# CHECK-NEXT:         Index:           2
 # CHECK-NEXT:       - Name:            weak_func
 # CHECK-NEXT:         Kind:            FUNCTION
 # CHECK-NEXT:         Index:           3

diff  --git a/lld/test/wasm/shared.s b/lld/test/wasm/shared.s
index 086f228308de9..e53af32ee546f 100644
--- a/lld/test/wasm/shared.s
+++ b/lld/test/wasm/shared.s
@@ -209,7 +209,6 @@ get_local_func_address:
 
 # DIS:      <__wasm_call_ctors>:
 # DIS-EMPTY:
-# DIS-NEXT:                 call    1
 # DIS-NEXT:                 end
 
 # DIS:      <__wasm_apply_data_relocs>:

diff  --git a/lld/test/wasm/shared64.s b/lld/test/wasm/shared64.s
index c5a813ea98f34..9847aa72fe7eb 100644
--- a/lld/test/wasm/shared64.s
+++ b/lld/test/wasm/shared64.s
@@ -216,7 +216,6 @@ get_local_func_address:
 
 # DIS:      <__wasm_call_ctors>:
 # DIS-EMPTY:
-# DIS-NEXT:                 call    1
 # DIS-NEXT:                 end
 
 # DIS:      <__wasm_apply_data_relocs>:

diff  --git a/lld/test/wasm/tls-export.s b/lld/test/wasm/tls-export.s
index 619f9d2df312a..1f64be607abb2 100644
--- a/lld/test/wasm/tls-export.s
+++ b/lld/test/wasm/tls-export.s
@@ -40,6 +40,9 @@ tls1:
 # CHECK-NEXT:      - Name:            __wasm_call_ctors
 # CHECK-NEXT:        Kind:            FUNCTION
 # CHECK-NEXT:        Index:           0
+# CHECK-NEXT:      - Name:            __wasm_apply_data_relocs
+# CHECK-NEXT:        Kind:            FUNCTION
+# CHECK-NEXT:        Index:           1
 # CHECK-NEXT:      - Name:            tls1
 # CHECK-NEXT:        Kind:            GLOBAL
 # CHECK-NEXT:        Index:           2

diff  --git a/lld/test/wasm/tls-non-shared-memory.s b/lld/test/wasm/tls-non-shared-memory.s
index 1754fd6254bb8..a2e2257cc9392 100644
--- a/lld/test/wasm/tls-non-shared-memory.s
+++ b/lld/test/wasm/tls-non-shared-memory.s
@@ -127,6 +127,9 @@ tls1:
 # PIE-NEXT:       - Name:            memory
 # PIE-NEXT:         Kind:            MEMORY
 # PIE-NEXT:         Index:           0
+# PIE-NEXT:       - Name:            __wasm_apply_data_relocs
+# PIE-NEXT:         Kind:            FUNCTION
+# PIE-NEXT:         Index:           1
 # PIE-NEXT:   - Type:
 
 # .tdata and .data are combined into single segment in PIC mode.

diff  --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index 32bd1ef3344e3..0a0f0c8a05bd7 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -656,6 +656,17 @@ static void createSyntheticSymbols() {
             is64 ? i64ArgSignature : i32ArgSignature,
             "__wasm_init_tls"));
   }
+
+  if (config->isPic ||
+      config->unresolvedSymbols == UnresolvedPolicy::ImportDynamic) {
+    // For PIC code, or when dynamically importing addresses, we create
+    // synthetic functions that apply relocations.  These get called from
+    // __wasm_call_ctors before the user-level constructors.
+    WasmSym::applyDataRelocs = symtab->addSyntheticFunction(
+        "__wasm_apply_data_relocs",
+        WASM_SYMBOL_VISIBILITY_DEFAULT | WASM_SYMBOL_EXPORTED,
+        make<SyntheticFunction>(nullSignature, "__wasm_apply_data_relocs"));
+  }
 }
 
 static void createOptionalSymbols() {

diff  --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index fa9802d477d55..8eed209ba2172 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -1018,17 +1018,6 @@ void Writer::createSyntheticInitFunctions() {
     WasmSym::tlsBase->markLive();
   }
 
-  if (config->isPic ||
-      config->unresolvedSymbols == UnresolvedPolicy::ImportDynamic) {
-    // For PIC code, or when dynamically importing addresses, we create
-    // synthetic functions that apply relocations.  These get called from
-    // __wasm_call_ctors before the user-level constructors.
-    WasmSym::applyDataRelocs = symtab->addSyntheticFunction(
-        "__wasm_apply_data_relocs", WASM_SYMBOL_VISIBILITY_HIDDEN,
-        make<SyntheticFunction>(nullSignature, "__wasm_apply_data_relocs"));
-    WasmSym::applyDataRelocs->markLive();
-  }
-
   if (config->isPic && out.globalSec->needsRelocations()) {
     WasmSym::applyGlobalRelocs = symtab->addSyntheticFunction(
         "__wasm_apply_global_relocs", WASM_SYMBOL_VISIBILITY_HIDDEN,
@@ -1298,8 +1287,8 @@ void Writer::createStartFunction() {
 
 // For -shared (PIC) output, we create create a synthetic function which will
 // apply any relocations to the data segments on startup.  This function is
-// called `__wasm_apply_data_relocs` and is added at the beginning of
-// `__wasm_call_ctors` before any of the constructors run.
+// called `__wasm_apply_data_relocs` and is expected to be called before
+// any user code (i.e. before `__wasm_call_ctors`).
 void Writer::createApplyDataRelocationsFunction() {
   LLVM_DEBUG(dbgs() << "createApplyDataRelocationsFunction\n");
   // First write the body's contents to a string.
@@ -1352,11 +1341,9 @@ void Writer::createApplyGlobalTLSRelocationsFunction() {
 // Create synthetic "__wasm_call_ctors" function based on ctor functions
 // in input object.
 void Writer::createCallCtorsFunction() {
-  // If __wasm_call_ctors isn't referenced, there aren't any ctors, and we
-  // aren't calling `__wasm_apply_data_relocs` for Emscripten-style PIC, don't
+  // If __wasm_call_ctors isn't referenced, there aren't any ctors, don't
   // define the `__wasm_call_ctors` function.
-  if (!WasmSym::callCtors->isLive() && !WasmSym::applyDataRelocs &&
-      initFunctions.empty())
+  if (!WasmSym::callCtors->isLive() && initFunctions.empty())
     return;
 
   // First write the body's contents to a string.
@@ -1365,12 +1352,6 @@ void Writer::createCallCtorsFunction() {
     raw_string_ostream os(bodyContent);
     writeUleb128(os, 0, "num locals");
 
-    if (WasmSym::applyDataRelocs) {
-      writeU8(os, WASM_OPCODE_CALL, "CALL");
-      writeUleb128(os, WasmSym::applyDataRelocs->getFunctionIndex(),
-                   "function index");
-    }
-
     // Call constructors
     for (const WasmInitEntry &f : initFunctions) {
       writeU8(os, WASM_OPCODE_CALL, "CALL");


        


More information about the llvm-commits mailing list