Skip to content

[lld][WebAssembly] Avoid emitting empty __wasm_apply_data_relocs function #109249

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions lld/test/wasm/data-segments.ll
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
; PASSIVE-NEXT: Name: __wasm_init_memory

; PASSIVE-PIC: - Type: START
; PASSIVE-PIC-NEXT: StartFunction: 3
; PASSIVE-PIC-NEXT: StartFunction: 2
; PASSIVE-PIC-NEXT: - Type: DATACOUNT
; PASSIVE-PIC-NEXT: Count: 3
; PASSIVE-PIC-NEXT: - Type: CODE
Expand All @@ -125,9 +125,6 @@
; 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
Expand All @@ -152,17 +149,13 @@
; PASSIVE-PIC-NEXT: - Index: 1
; PASSIVE-PIC-NEXT: Name: __wasm_init_tls
; PASSIVE-PIC-NEXT: - Index: 2
; PASSIVE-PIC-NEXT: Name: __wasm_apply_data_relocs
; PASSIVE-PIC-NEXT: - Index: 3
; PASSIVE-PIC-NEXT: Name: __wasm_init_memory

; no data relocations.
; DIS-LABEL: <__wasm_call_ctors>:
; DIS-EMPTY:
; DIS-NEXT: end

; In PIC mode __wasm_apply_data_relocs is export separatly to __wasm_call_ctors
; PIC-DIS: <__wasm_apply_data_relocs>:
; PIC-DIS-EMPTY:

; DIS-LABEL: <__wasm_init_memory>:
Expand Down
15 changes: 5 additions & 10 deletions lld/test/wasm/shared-weak-symbols.s
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ call_weak:
# ASM: 10 80 80 80 80 00 call 0
drop
call hidden_weak_func
# ASM: 10 84 80 80 80 00 call 4
# ASM: 10 83 80 80 80 00 call 3
end_function
# ASM-NEXT: 0b end

Expand Down Expand Up @@ -62,15 +62,12 @@ 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
# CHECK-NEXT: Index: 2
# CHECK-NEXT: - Name: call_weak
# CHECK-NEXT: Kind: FUNCTION
# CHECK-NEXT: Index: 5
# CHECK-NEXT: Index: 4
# CHECK-NEXT: - Type: CODE

# CHECK: - Type: CUSTOM
Expand All @@ -81,10 +78,8 @@ call_weak:
# CHECK-NEXT: - Index: 1
# CHECK-NEXT: Name: __wasm_call_ctors
# CHECK-NEXT: - Index: 2
# CHECK-NEXT: Name: __wasm_apply_data_relocs
# CHECK-NEXT: - Index: 3
# CHECK-NEXT: Name: weak_func
# CHECK-NEXT: - Index: 4
# CHECK-NEXT: - Index: 3
# CHECK-NEXT: Name: hidden_weak_func
# CHECK-NEXT: - Index: 5
# CHECK-NEXT: - Index: 4
# CHECK-NEXT: Name: call_weak
3 changes: 0 additions & 3 deletions lld/test/wasm/tls-export.s
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ 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
3 changes: 0 additions & 3 deletions lld/test/wasm/tls-non-shared-memory.s
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,6 @@ 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.
Expand Down
2 changes: 1 addition & 1 deletion lld/test/wasm/tls-relocations.s
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ tls_sym:
# ASM-NEXT: i32.const 16
# ASM-NEXT: memory.init 0, 0
# call to __wasm_apply_tls_relocs
# ASM-NEXT: call 4
# ASM-NEXT: call 3
# ASM-NEXT: end

# ASM: <__wasm_apply_tls_relocs>:
Expand Down
11 changes: 0 additions & 11 deletions lld/wasm/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -917,17 +917,6 @@ static void createSyntheticSymbols() {
is64 ? i64ArgSignature : i32ArgSignature,
"__wasm_init_tls"));
}

if (ctx.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() {
Expand Down
10 changes: 8 additions & 2 deletions lld/wasm/InputChunks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,11 +361,12 @@ uint64_t InputChunk::getVA(uint64_t offset) const {
// Generate code to apply relocations to the data section at runtime.
// This is only called when generating shared libraries (PIC) where address are
// not known at static link time.
void InputChunk::generateRelocationCode(raw_ostream &os) const {
bool InputChunk::generateRelocationCode(raw_ostream &os) const {
LLVM_DEBUG(dbgs() << "generating runtime relocations: " << name
<< " count=" << relocations.size() << "\n");

bool is64 = config->is64.value_or(false);
bool generated = false;
unsigned opcode_ptr_const = is64 ? WASM_OPCODE_I64_CONST
: WASM_OPCODE_I32_CONST;
unsigned opcode_ptr_add = is64 ? WASM_OPCODE_I64_ADD
Expand All @@ -378,7 +379,10 @@ void InputChunk::generateRelocationCode(raw_ostream &os) const {
uint64_t offset = getVA(rel.Offset) - getInputSectionOffset();

Symbol *sym = file->getSymbol(rel);
if (!ctx.isPic && sym->isDefined())
// Runtime relocations are needed when we don't know the address of
// a symbol statically.
bool requiresRuntimeReloc = ctx.isPic || sym->hasGOTIndex();
if (!requiresRuntimeReloc)
continue;

LLVM_DEBUG(dbgs() << "gen reloc: type=" << relocTypeToString(rel.Type)
Expand Down Expand Up @@ -435,7 +439,9 @@ void InputChunk::generateRelocationCode(raw_ostream &os) const {
writeU8(os, opcode_reloc_store, "I32_STORE");
writeUleb128(os, 2, "align");
writeUleb128(os, 0, "offset");
generated = true;
}
return generated;
}

// Split WASM_SEG_FLAG_STRINGS section. Such a section is a sequence of
Expand Down
2 changes: 1 addition & 1 deletion lld/wasm/InputChunks.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class InputChunk {

size_t getNumRelocations() const { return relocations.size(); }
void writeRelocations(llvm::raw_ostream &os) const;
void generateRelocationCode(raw_ostream &os) const;
bool generateRelocationCode(raw_ostream &os) const;

bool isTLS() const { return flags & llvm::wasm::WASM_SEG_FLAG_TLS; }
bool isRetained() const { return flags & llvm::wasm::WASM_SEG_FLAG_RETAIN; }
Expand Down
1 change: 0 additions & 1 deletion lld/wasm/Symbols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 2 additions & 6 deletions lld/wasm/Symbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 18 additions & 4 deletions lld/wasm/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1467,15 +1469,29 @@ void Writer::createApplyDataRelocationsFunction() {
{
raw_string_ostream os(bodyContent);
writeUleb128(os, 0, "num locals");
bool generated = false;
for (const OutputSegment *seg : segments)
if (!config->sharedMemory || !seg->isTLS())
for (const InputChunk *inSeg : seg->inputSegments)
inSeg->generateRelocationCode(os);
generated |= inSeg->generateRelocationCode(os);

if (!generated) {
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() {
Expand Down Expand Up @@ -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)
Expand Down
Loading