[llvm] [WebAssembly] Support multiple `.init_array` fragments when writing Wasm objects (PR #111008)
George Stagg via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 6 06:14:46 PST 2024
https://github.com/georgestagg updated https://github.com/llvm/llvm-project/pull/111008
>From 8266ca5900fe1b2013f108784fbdf94b001fd5cd Mon Sep 17 00:00:00 2001
From: George Stagg <george.stagg at posit.co>
Date: Thu, 3 Oct 2024 15:25:43 +0100
Subject: [PATCH 1/3] WasmObjectWriter: Support multiple .init_array section
fragments
---
llvm/lib/MC/WasmObjectWriter.cpp | 94 ++++++++++++++------------
llvm/test/MC/WebAssembly/init-array.ll | 56 +++++++++++++++
2 files changed, 108 insertions(+), 42 deletions(-)
create mode 100644 llvm/test/MC/WebAssembly/init-array.ll
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index f25dc92fa235a2..034e058690744a 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -1769,6 +1769,11 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
WS.setIndex(InvalidIndex);
continue;
}
+ // Contents of .init_array sections are handled elsewhere.
+ if (WS.isDefined() &&
+ WS.getSection().getName().starts_with(".init_array")) {
+ continue;
+ }
LLVM_DEBUG(dbgs() << "adding to symtab: " << WS << "\n");
uint32_t Flags = 0;
@@ -1853,49 +1858,54 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
if (EmptyFrag.getKind() != MCFragment::FT_Data)
report_fatal_error(".init_array section should be aligned");
- const MCFragment &AlignFrag = *EmptyFrag.getNext();
- if (AlignFrag.getKind() != MCFragment::FT_Align)
- report_fatal_error(".init_array section should be aligned");
- if (cast<MCAlignFragment>(AlignFrag).getAlignment() !=
- Align(is64Bit() ? 8 : 4))
- report_fatal_error(".init_array section should be aligned for pointers");
-
- const MCFragment &Frag = *AlignFrag.getNext();
- if (Frag.hasInstructions() || Frag.getKind() != MCFragment::FT_Data)
- report_fatal_error("only data supported in .init_array section");
-
- uint16_t Priority = UINT16_MAX;
- unsigned PrefixLength = strlen(".init_array");
- if (WS.getName().size() > PrefixLength) {
- if (WS.getName()[PrefixLength] != '.')
+ const MCFragment *nextFrag = EmptyFrag.getNext();
+ while (nextFrag != nullptr) {
+ const MCFragment &AlignFrag = *nextFrag;
+ if (AlignFrag.getKind() != MCFragment::FT_Align)
+ report_fatal_error(".init_array section should be aligned");
+ if (cast<MCAlignFragment>(AlignFrag).getAlignment() !=
+ Align(is64Bit() ? 8 : 4))
report_fatal_error(
- ".init_array section priority should start with '.'");
- if (WS.getName().substr(PrefixLength + 1).getAsInteger(10, Priority))
- report_fatal_error("invalid .init_array section priority");
- }
- const auto &DataFrag = cast<MCDataFragment>(Frag);
- const SmallVectorImpl<char> &Contents = DataFrag.getContents();
- for (const uint8_t *
- P = (const uint8_t *)Contents.data(),
- *End = (const uint8_t *)Contents.data() + Contents.size();
- P != End; ++P) {
- if (*P != 0)
- report_fatal_error("non-symbolic data in .init_array section");
- }
- for (const MCFixup &Fixup : DataFrag.getFixups()) {
- assert(Fixup.getKind() ==
- MCFixup::getKindForSize(is64Bit() ? 8 : 4, false));
- const MCExpr *Expr = Fixup.getValue();
- auto *SymRef = dyn_cast<MCSymbolRefExpr>(Expr);
- if (!SymRef)
- report_fatal_error("fixups in .init_array should be symbol references");
- const auto &TargetSym = cast<const MCSymbolWasm>(SymRef->getSymbol());
- if (TargetSym.getIndex() == InvalidIndex)
- report_fatal_error("symbols in .init_array should exist in symtab");
- if (!TargetSym.isFunction())
- report_fatal_error("symbols in .init_array should be for functions");
- InitFuncs.push_back(
- std::make_pair(Priority, TargetSym.getIndex()));
+ ".init_array section should be aligned for pointers");
+
+ const MCFragment &Frag = *AlignFrag.getNext();
+ nextFrag = Frag.getNext();
+ if (Frag.hasInstructions() || Frag.getKind() != MCFragment::FT_Data)
+ report_fatal_error("only data supported in .init_array section");
+
+ uint16_t Priority = UINT16_MAX;
+ unsigned PrefixLength = strlen(".init_array");
+ if (WS.getName().size() > PrefixLength) {
+ if (WS.getName()[PrefixLength] != '.')
+ report_fatal_error(
+ ".init_array section priority should start with '.'");
+ if (WS.getName().substr(PrefixLength + 1).getAsInteger(10, Priority))
+ report_fatal_error("invalid .init_array section priority");
+ }
+ const auto &DataFrag = cast<MCDataFragment>(Frag);
+ const SmallVectorImpl<char> &Contents = DataFrag.getContents();
+ for (const uint8_t *
+ P = (const uint8_t *)Contents.data(),
+ *End = (const uint8_t *)Contents.data() + Contents.size();
+ P != End; ++P) {
+ if (*P != 0)
+ report_fatal_error("non-symbolic data in .init_array section");
+ }
+ for (const MCFixup &Fixup : DataFrag.getFixups()) {
+ assert(Fixup.getKind() ==
+ MCFixup::getKindForSize(is64Bit() ? 8 : 4, false));
+ const MCExpr *Expr = Fixup.getValue();
+ auto *SymRef = dyn_cast<MCSymbolRefExpr>(Expr);
+ if (!SymRef)
+ report_fatal_error(
+ "fixups in .init_array should be symbol references");
+ const auto &TargetSym = cast<const MCSymbolWasm>(SymRef->getSymbol());
+ if (TargetSym.getIndex() == InvalidIndex)
+ report_fatal_error("symbols in .init_array should exist in symtab");
+ if (!TargetSym.isFunction())
+ report_fatal_error("symbols in .init_array should be for functions");
+ InitFuncs.push_back(std::make_pair(Priority, TargetSym.getIndex()));
+ }
}
}
diff --git a/llvm/test/MC/WebAssembly/init-array.ll b/llvm/test/MC/WebAssembly/init-array.ll
new file mode 100644
index 00000000000000..d19ddcf10d5d9c
--- /dev/null
+++ b/llvm/test/MC/WebAssembly/init-array.ll
@@ -0,0 +1,56 @@
+; RUN: llc -mcpu=mvp -filetype=obj %s -o - | obj2yaml | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+ at p_init1 = hidden global ptr @init1, section ".init_array", align 4
+ at p_init2 = hidden global ptr @init2, section ".init_array", align 4
+
+define hidden void @init1() #0 { ret void }
+define hidden void @init2() #0 { ret void }
+
+
+; CHECK: - Type: IMPORT
+; CHECK-NEXT: Imports:
+; CHECK-NEXT: - Module: env
+; CHECK-NEXT: Field: __linear_memory
+; CHECK-NEXT: Kind: MEMORY
+; CHECK-NEXT: Memory:
+; CHECK-NEXT: Minimum: 0x0
+; CHECK-NEXT: - Module: env
+; CHECK-NEXT: Field: __indirect_function_table
+; CHECK-NEXT: Kind: TABLE
+; CHECK-NEXT: Table:
+; CHECK-NEXT: Index: 0
+; CHECK-NEXT: ElemType: FUNCREF
+; CHECK-NEXT: Limits:
+; CHECK-NEXT: Minimum: 0x0
+; CHECK-NEXT: - Type: FUNCTION
+; CHECK-NEXT: FunctionTypes: [ 0, 0 ]
+; CHECK-NEXT: - Type: CODE
+; CHECK-NEXT: Functions:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Locals: []
+; CHECK-NEXT: Body: 0B
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: Locals: []
+; CHECK-NEXT: Body: 0B
+; CHECK-NEXT: - Type: CUSTOM
+; CHECK-NEXT: Name: linking
+; CHECK-NEXT: Version: 2
+; CHECK-NEXT: SymbolTable:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: init1
+; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
+; CHECK-NEXT: Function: 0
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: init2
+; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
+; CHECK-NEXT: Function: 1
+; CHECK-NEXT: InitFunctions:
+; CHECK-NEXT: - Priority: 65535
+; CHECK-NEXT: Symbol: 0
+; CHECK-NEXT: - Priority: 65535
+; CHECK-NEXT: Symbol: 1
+; CHECK-NEXT: ...
>From ffbc5e1bdfe7186ff4f64d436a8536bee494e26f Mon Sep 17 00:00:00 2001
From: George Stagg <george.stagg at posit.co>
Date: Wed, 6 Nov 2024 10:02:15 +0000
Subject: [PATCH 2/3] Switch init-array test to assembly format
---
llvm/test/MC/WebAssembly/init-array.ll | 56 --------------------------
llvm/test/MC/WebAssembly/init-array.s | 49 ++++++++++++++++++++++
2 files changed, 49 insertions(+), 56 deletions(-)
delete mode 100644 llvm/test/MC/WebAssembly/init-array.ll
create mode 100644 llvm/test/MC/WebAssembly/init-array.s
diff --git a/llvm/test/MC/WebAssembly/init-array.ll b/llvm/test/MC/WebAssembly/init-array.ll
deleted file mode 100644
index d19ddcf10d5d9c..00000000000000
--- a/llvm/test/MC/WebAssembly/init-array.ll
+++ /dev/null
@@ -1,56 +0,0 @@
-; RUN: llc -mcpu=mvp -filetype=obj %s -o - | obj2yaml | FileCheck %s
-
-target triple = "wasm32-unknown-unknown"
-
- at p_init1 = hidden global ptr @init1, section ".init_array", align 4
- at p_init2 = hidden global ptr @init2, section ".init_array", align 4
-
-define hidden void @init1() #0 { ret void }
-define hidden void @init2() #0 { ret void }
-
-
-; CHECK: - Type: IMPORT
-; CHECK-NEXT: Imports:
-; CHECK-NEXT: - Module: env
-; CHECK-NEXT: Field: __linear_memory
-; CHECK-NEXT: Kind: MEMORY
-; CHECK-NEXT: Memory:
-; CHECK-NEXT: Minimum: 0x0
-; CHECK-NEXT: - Module: env
-; CHECK-NEXT: Field: __indirect_function_table
-; CHECK-NEXT: Kind: TABLE
-; CHECK-NEXT: Table:
-; CHECK-NEXT: Index: 0
-; CHECK-NEXT: ElemType: FUNCREF
-; CHECK-NEXT: Limits:
-; CHECK-NEXT: Minimum: 0x0
-; CHECK-NEXT: - Type: FUNCTION
-; CHECK-NEXT: FunctionTypes: [ 0, 0 ]
-; CHECK-NEXT: - Type: CODE
-; CHECK-NEXT: Functions:
-; CHECK-NEXT: - Index: 0
-; CHECK-NEXT: Locals: []
-; CHECK-NEXT: Body: 0B
-; CHECK-NEXT: - Index: 1
-; CHECK-NEXT: Locals: []
-; CHECK-NEXT: Body: 0B
-; CHECK-NEXT: - Type: CUSTOM
-; CHECK-NEXT: Name: linking
-; CHECK-NEXT: Version: 2
-; CHECK-NEXT: SymbolTable:
-; CHECK-NEXT: - Index: 0
-; CHECK-NEXT: Kind: FUNCTION
-; CHECK-NEXT: Name: init1
-; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
-; CHECK-NEXT: Function: 0
-; CHECK-NEXT: - Index: 1
-; CHECK-NEXT: Kind: FUNCTION
-; CHECK-NEXT: Name: init2
-; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
-; CHECK-NEXT: Function: 1
-; CHECK-NEXT: InitFunctions:
-; CHECK-NEXT: - Priority: 65535
-; CHECK-NEXT: Symbol: 0
-; CHECK-NEXT: - Priority: 65535
-; CHECK-NEXT: Symbol: 1
-; CHECK-NEXT: ...
diff --git a/llvm/test/MC/WebAssembly/init-array.s b/llvm/test/MC/WebAssembly/init-array.s
new file mode 100644
index 00000000000000..e79fb453ec12a3
--- /dev/null
+++ b/llvm/test/MC/WebAssembly/init-array.s
@@ -0,0 +1,49 @@
+# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj < %s | obj2yaml | FileCheck %s
+
+init1:
+ .functype init1 () -> ()
+ end_function
+
+init2:
+ .functype init2 () -> ()
+ end_function
+
+ .section .init_array,"",@
+ .p2align 2, 0
+ .int32 init1
+
+ .section .init_array,"",@
+ .p2align 2
+ .int32 init2
+
+# CHECK: - Type: FUNCTION
+# CHECK-NEXT: FunctionTypes: [ 0, 0 ]
+# CHECK-NEXT: - Type: CODE
+# CHECK-NEXT: Functions:
+# CHECK-NEXT: - Index: 0
+# CHECK-NEXT: Locals: []
+# CHECK-NEXT: Body: 0B
+# CHECK-NEXT: - Index: 1
+# CHECK-NEXT: Locals: []
+# CHECK-NEXT: Body: 0B
+# CHECK-NEXT: - Type: CUSTOM
+# CHECK-NEXT: Name: linking
+# CHECK-NEXT: Version: 2
+# CHECK-NEXT: SymbolTable:
+# CHECK-NEXT: - Index: 0
+# CHECK-NEXT: Kind: FUNCTION
+# CHECK-NEXT: Name: init1
+# CHECK-NEXT: Flags: [ BINDING_LOCAL ]
+# CHECK-NEXT: Function: 0
+# CHECK-NEXT: - Index: 1
+# CHECK-NEXT: Kind: FUNCTION
+# CHECK-NEXT: Name: init2
+# CHECK-NEXT: Flags: [ BINDING_LOCAL ]
+# CHECK-NEXT: Function: 1
+# CHECK-NEXT: InitFunctions:
+# CHECK-NEXT: - Priority: 65535
+# CHECK-NEXT: Symbol: 0
+# CHECK-NEXT: - Priority: 65535
+# CHECK-NEXT: Symbol: 1
+# CHECK-NEXT: ...
+#
>From 783024ec224acf7bfb39fc373406865f29ff1cb1 Mon Sep 17 00:00:00 2001
From: George Stagg <george.stagg at posit.co>
Date: Wed, 6 Nov 2024 13:59:49 +0000
Subject: [PATCH 3/3] Skip only data symbols in .init_array
---
llvm/lib/MC/WasmObjectWriter.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index 034e058690744a..ee7ffffaf7781f 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -1770,7 +1770,7 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
continue;
}
// Contents of .init_array sections are handled elsewhere.
- if (WS.isDefined() &&
+ if (WS.isDefined() && WS.isData() &&
WS.getSection().getName().starts_with(".init_array")) {
continue;
}
More information about the llvm-commits
mailing list