[lld] [WIP] wasm-ld: Implement function pointer alignment (PR #105532)

Ethan O'Brien via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 30 10:34:13 PST 2024


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/2] 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/2] [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);
     }
   }



More information about the llvm-commits mailing list