[lld] [lld][WebAssembly]: Restore non-pie dynamic-linking executable (PR #108146)
YAMAMOTO Takashi via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 11 20:28:44 PDT 2024
https://github.com/yamt updated https://github.com/llvm/llvm-project/pull/108146
>From 85f918172fc200804e1dd7f654c14e2fd10c6ffe Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Wed, 11 Sep 2024 15:04:01 +0900
Subject: [PATCH 1/2] [lld][WebAssembly]: Restore non-pie dynamic-linking
executable
Fixes https://github.com/llvm/llvm-project/issues/107387
---
lld/wasm/Driver.cpp | 3 ++-
lld/wasm/InputChunks.cpp | 2 +-
lld/wasm/Relocations.cpp | 3 ++-
3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index 2de7dcaeb43d47..a6e1d2ded5ca15 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -919,7 +919,8 @@ static void createSyntheticSymbols() {
}
if (ctx.isPic ||
- config->unresolvedSymbols == UnresolvedPolicy::ImportDynamic) {
+ config->unresolvedSymbols == UnresolvedPolicy::ImportDynamic ||
+ !config->isStatic) {
// 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.
diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp
index 975225974aff6e..dbf800422e45b5 100644
--- a/lld/wasm/InputChunks.cpp
+++ b/lld/wasm/InputChunks.cpp
@@ -378,7 +378,7 @@ void InputChunk::generateRelocationCode(raw_ostream &os) const {
uint64_t offset = getVA(rel.Offset) - getInputSectionOffset();
Symbol *sym = file->getSymbol(rel);
- if (!ctx.isPic && sym->isDefined())
+ if (!ctx.isPic && sym->isDefined() && !sym->hasGOTIndex())
continue;
LLVM_DEBUG(dbgs() << "gen reloc: type=" << relocTypeToString(rel.Type)
diff --git a/lld/wasm/Relocations.cpp b/lld/wasm/Relocations.cpp
index 6f33a4f28a9d09..70229179afdcfc 100644
--- a/lld/wasm/Relocations.cpp
+++ b/lld/wasm/Relocations.cpp
@@ -146,7 +146,8 @@ void scanRelocations(InputChunk *chunk) {
if (ctx.isPic ||
(sym->isUndefined() &&
- config->unresolvedSymbols == UnresolvedPolicy::ImportDynamic)) {
+ config->unresolvedSymbols == UnresolvedPolicy::ImportDynamic) ||
+ sym->isShared()) {
switch (reloc.Type) {
case R_WASM_TABLE_INDEX_SLEB:
case R_WASM_TABLE_INDEX_SLEB64:
>From 9513512579197f0dbbbaa5813370a21ee219a705 Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Thu, 12 Sep 2024 11:25:47 +0900
Subject: [PATCH 2/2] [lld][WebAssembly]: Defer __wasm_apply_data_relocs
decision to writer phase
At the time of createSyntheticSymbols, it isn't obvious if we
need these relocations.
Note: this has a side effect to stop emitting empty
__wasm_apply_data_relocs. It isn't a problem because the export
is optional in the spec (DynamicLinking.md) and all implementations
I'm aware of implement it that way. (emscripten, toywasm, wasm-tools)
---
lld/wasm/Driver.cpp | 12 ------------
lld/wasm/Symbols.cpp | 1 -
lld/wasm/Symbols.h | 8 ++------
lld/wasm/Writer.cpp | 20 +++++++++++++++++---
4 files changed, 19 insertions(+), 22 deletions(-)
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index a6e1d2ded5ca15..289c1217ff5ead 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -917,18 +917,6 @@ static void createSyntheticSymbols() {
is64 ? i64ArgSignature : i32ArgSignature,
"__wasm_init_tls"));
}
-
- if (ctx.isPic ||
- config->unresolvedSymbols == UnresolvedPolicy::ImportDynamic ||
- !config->isStatic) {
- // 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/Symbols.cpp b/lld/wasm/Symbols.cpp
index f74699d0763fd9..b2bbd11c53ef23 100644
--- a/lld/wasm/Symbols.cpp
+++ b/lld/wasm/Symbols.cpp
@@ -80,7 +80,6 @@ namespace wasm {
DefinedFunction *WasmSym::callCtors;
DefinedFunction *WasmSym::callDtors;
DefinedFunction *WasmSym::initMemory;
-DefinedFunction *WasmSym::applyDataRelocs;
DefinedFunction *WasmSym::applyGlobalRelocs;
DefinedFunction *WasmSym::applyTLSRelocs;
DefinedFunction *WasmSym::applyGlobalTLSRelocs;
diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h
index 2ba575fddc8796..5ce3ecbc4ab194 100644
--- a/lld/wasm/Symbols.h
+++ b/lld/wasm/Symbols.h
@@ -591,18 +591,14 @@ struct WasmSym {
// Function that calls the libc/etc. cleanup function.
static DefinedFunction *callDtors;
- // __wasm_apply_data_relocs
- // Function that applies relocations to data segment post-instantiation.
- static DefinedFunction *applyDataRelocs;
-
// __wasm_apply_global_relocs
// Function that applies relocations to wasm globals post-instantiation.
// Unlike __wasm_apply_data_relocs this needs to run on every thread.
static DefinedFunction *applyGlobalRelocs;
// __wasm_apply_tls_relocs
- // Like applyDataRelocs but for TLS section. These must be delayed until
- // __wasm_init_tls.
+ // Like __wasm_apply_data_relocs but for TLS section. These must be
+ // delayed until __wasm_init_tls.
static DefinedFunction *applyTLSRelocs;
// __wasm_apply_global_tls_relocs
diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index 6beef81d39a381..21d4578ba9de17 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -1145,6 +1145,8 @@ void Writer::createSyntheticInitFunctions() {
static WasmSignature nullSignature = {{}, {}};
+ createApplyDataRelocationsFunction();
+
// Passive segments are used to avoid memory being reinitialized on each
// thread's instantiation. These passive segments are initialized and
// dropped in __wasm_init_memory, which is registered as the start function
@@ -1467,15 +1469,29 @@ void Writer::createApplyDataRelocationsFunction() {
{
raw_string_ostream os(bodyContent);
writeUleb128(os, 0, "num locals");
+ uint64_t off = os.tell();
for (const OutputSegment *seg : segments)
if (!config->sharedMemory || !seg->isTLS())
for (const InputChunk *inSeg : seg->inputSegments)
inSeg->generateRelocationCode(os);
+ if (off == os.tell()) {
+ LLVM_DEBUG(dbgs() << "skipping empty __wasm_apply_data_relocs\n");
+ return;
+ }
writeU8(os, WASM_OPCODE_END, "END");
}
- createFunction(WasmSym::applyDataRelocs, bodyContent);
+ // __wasm_apply_data_relocs
+ // Function that applies relocations to data segment post-instantiation.
+ static WasmSignature nullSignature = {{}, {}};
+ auto def = symtab->addSyntheticFunction(
+ "__wasm_apply_data_relocs",
+ WASM_SYMBOL_VISIBILITY_DEFAULT | WASM_SYMBOL_EXPORTED,
+ make<SyntheticFunction>(nullSignature, "__wasm_apply_data_relocs"));
+ def->markLive();
+
+ createFunction(def, bodyContent);
}
void Writer::createApplyTLSRelocationsFunction() {
@@ -1771,8 +1787,6 @@ void Writer::run() {
if (!config->relocatable) {
// Create linker synthesized functions
- if (WasmSym::applyDataRelocs)
- createApplyDataRelocationsFunction();
if (WasmSym::applyGlobalRelocs)
createApplyGlobalRelocationsFunction();
if (WasmSym::applyTLSRelocs)
More information about the llvm-commits
mailing list