[lld] wasm-ld: Implement function pointer alignment (PR #105532)
Ethan O'Brien via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 21 20:14:24 PST 2025
https://github.com/ethanaobrien updated https://github.com/llvm/llvm-project/pull/105532
>From 4ce4fe223091fe461384a36f476fae48e7d854d1 Mon Sep 17 00:00:00 2001
From: Ethan O'Brien <ethan.a.obrien at gmail.com>
Date: Wed, 21 Aug 2024 08:56:25 -0500
Subject: [PATCH 1/4] Implement wip WebAssembly function alignment
---
lld/wasm/SyntheticSections.cpp | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp
index f02f55519a2512..13333a67378681 100644
--- a/lld/wasm/SyntheticSections.cpp
+++ b/lld/wasm/SyntheticSections.cpp
@@ -563,8 +563,24 @@ void ElemSection::addEntry(FunctionSymbol *sym) {
// They only exist so that the calls to missing functions can validate.
if (sym->hasTableIndex() || sym->isStub)
return;
+
+ uint32_t padding = 0;
+ uint64_t alignment = 1;
+
+ if (indirectFunctions.size() == 0 && padding > 0) {
+ for (uint32_t i=0; i<padding; i++) {
+ indirectFunctions.push_back(nullptr);
+ }
+ }
+
sym->setTableIndex(config->tableBase + indirectFunctions.size());
indirectFunctions.emplace_back(sym);
+
+ if (alignment > 1) {
+ for (uint32_t i=0; i<alignment-1; i++) {
+ indirectFunctions.push_back(nullptr);
+ }
+ }
}
void ElemSection::writeBody() {
@@ -602,6 +618,12 @@ void ElemSection::writeBody() {
writeUleb128(os, indirectFunctions.size(), "elem count");
uint32_t tableIndex = config->tableBase;
for (const FunctionSymbol *sym : indirectFunctions) {
+ if (sym == nullptr) {
+ (void) tableIndex;
+ writeUleb128(os, 0, "function index");
+ ++tableIndex;
+ continue;
+ }
assert(sym->getTableIndex() == tableIndex);
(void) tableIndex;
writeUleb128(os, sym->getFunctionIndex(), "function index");
>From d8df549f879794fa206080e97426e2937e71f1cb Mon Sep 17 00:00:00 2001
From: Ethan O'Brien <ethan.a.obrien at gmail.com>
Date: Mon, 30 Dec 2024 10:33:15 -0800
Subject: [PATCH 2/4] [wasm] Add function-pointer-alignment function
---
lld/wasm/Config.h | 1 +
lld/wasm/Driver.cpp | 1 +
lld/wasm/Options.td | 3 +++
lld/wasm/SyntheticSections.cpp | 13 ++-----------
4 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/lld/wasm/Config.h b/lld/wasm/Config.h
index 0c2ba3eebffc4f..970e9243dad3d3 100644
--- a/lld/wasm/Config.h
+++ b/lld/wasm/Config.h
@@ -93,6 +93,7 @@ struct Config {
// for shared libraries (since they always added to a dynamic offset at
// runtime).
uint64_t tableBase;
+ uint64_t functionPointerAlignment;
uint64_t zStackSize;
unsigned ltoPartitions;
unsigned ltoo;
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index 02471950fb5196..225785329f8f38 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -638,6 +638,7 @@ static void readConfigs(opt::InputArgList &args) {
LLVM_DEBUG(errorHandler().verbose = true);
config->tableBase = args::getInteger(args, OPT_table_base, 0);
+ config->functionPointerAlignment = args::getInteger(args, OPT_function_pointer_alignment, 0);
config->globalBase = args::getInteger(args, OPT_global_base, 0);
config->initialHeap = args::getInteger(args, OPT_initial_heap, 0);
config->initialMemory = args::getInteger(args, OPT_initial_memory, 0);
diff --git a/lld/wasm/Options.td b/lld/wasm/Options.td
index 1316dc5c70d936..b43ff513b89b65 100644
--- a/lld/wasm/Options.td
+++ b/lld/wasm/Options.td
@@ -251,6 +251,9 @@ def stack_first: FF<"stack-first">,
def table_base: JJ<"table-base=">,
HelpText<"Table offset at which to place address taken functions (Defaults to 1)">;
+def function_pointer_alignment: JJ<"function-pointer-alignment=">,
+ HelpText<"Align function pointers at a given value (Defaults to 1)">;
+
defm whole_archive: B<"whole-archive",
"Force load of all members in a static library",
"Do not force load of all members in a static library (default)">;
diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp
index 5292915d885a6b..a0c347651dbf82 100644
--- a/lld/wasm/SyntheticSections.cpp
+++ b/lld/wasm/SyntheticSections.cpp
@@ -567,20 +567,11 @@ void ElemSection::addEntry(FunctionSymbol *sym) {
if (sym->hasTableIndex() || sym->isStub)
return;
- uint32_t padding = 0;
- uint64_t alignment = 1;
-
- if (indirectFunctions.size() == 0 && padding > 0) {
- for (uint32_t i=0; i<padding; i++) {
- indirectFunctions.push_back(nullptr);
- }
- }
-
sym->setTableIndex(config->tableBase + indirectFunctions.size());
indirectFunctions.emplace_back(sym);
- if (alignment > 1) {
- for (uint32_t i=0; i<alignment-1; i++) {
+ if (config->functionPointerAlignment > 1) {
+ for (uint32_t i=0; i<config->functionPointerAlignment-1; i++) {
indirectFunctions.push_back(nullptr);
}
}
>From 983433dc9b196e8a0d42c74f04438df535401db8 Mon Sep 17 00:00:00 2001
From: Ethan O'Brien <ethan.a.obrien at gmail.com>
Date: Tue, 21 Jan 2025 22:10:04 -0600
Subject: [PATCH 3/4] Requested changes
---
lld/wasm/Driver.cpp | 3 ++-
lld/wasm/SyntheticSections.cpp | 13 +++++--------
2 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index d8fd2b7820d8bf..4a0e923868b25f 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -636,7 +636,8 @@ static void readConfigs(opt::InputArgList &args) {
LLVM_DEBUG(errorHandler().verbose = true);
ctx.arg.tableBase = args::getInteger(args, OPT_table_base, 0);
- ctx.arg.functionPointerAlignment = args::getInteger(args, OPT_function_pointer_alignment, 0);
+ ctx.arg.functionPointerAlignment =
+ args::getInteger(args, OPT_function_pointer_alignment, 0);
ctx.arg.globalBase = args::getInteger(args, OPT_global_base, 0);
ctx.arg.initialHeap = args::getInteger(args, OPT_initial_heap, 0);
ctx.arg.initialMemory = args::getInteger(args, OPT_initial_memory, 0);
diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp
index 3fcef7cb3db2c0..96126fe47c9f26 100644
--- a/lld/wasm/SyntheticSections.cpp
+++ b/lld/wasm/SyntheticSections.cpp
@@ -569,8 +569,9 @@ void ElemSection::addEntry(FunctionSymbol *sym) {
sym->setTableIndex(ctx.arg.tableBase + indirectFunctions.size());
indirectFunctions.emplace_back(sym);
+ // Pad with null function pointers if alignment is requesting.
if (ctx.arg.functionPointerAlignment > 1) {
- for (uint32_t i=0; i<ctx.arg.functionPointerAlignment-1; i++) {
+ while ((ctx.arg.tableBase + indirectFunctions.size()) % ctx.arg.functionPointerAlignment) {
indirectFunctions.push_back(nullptr);
}
}
@@ -610,15 +611,11 @@ void ElemSection::writeBody() {
writeUleb128(os, indirectFunctions.size(), "elem count");
uint32_t tableIndex = ctx.arg.tableBase;
for (const FunctionSymbol *sym : indirectFunctions) {
- if (sym == nullptr) {
- (void) tableIndex;
- writeUleb128(os, 0, "function index");
- ++tableIndex;
- continue;
+ if (sym != nullptr) {
+ assert(sym->getTableIndex() == tableIndex);
}
- assert(sym->getTableIndex() == tableIndex);
(void) tableIndex;
- writeUleb128(os, sym->getFunctionIndex(), "function index");
+ writeUleb128(os, sym ? sym->getFunctionIndex() : 0, "function index");
++tableIndex;
}
}
>From bbaf4e41080104004809c07cc14aecfe41bef0b5 Mon Sep 17 00:00:00 2001
From: Ethan O'Brien <77750390+ethanaobrien at users.noreply.github.com>
Date: Tue, 21 Jan 2025 22:14:15 -0600
Subject: [PATCH 4/4] Correct indentation
---
lld/wasm/SyntheticSections.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp
index 96126fe47c9f26..dd130cc455f7f3 100644
--- a/lld/wasm/SyntheticSections.cpp
+++ b/lld/wasm/SyntheticSections.cpp
@@ -612,7 +612,7 @@ void ElemSection::writeBody() {
uint32_t tableIndex = ctx.arg.tableBase;
for (const FunctionSymbol *sym : indirectFunctions) {
if (sym != nullptr) {
- assert(sym->getTableIndex() == tableIndex);
+ assert(sym->getTableIndex() == tableIndex);
}
(void) tableIndex;
writeUleb128(os, sym ? sym->getFunctionIndex() : 0, "function index");
More information about the llvm-commits
mailing list