-
Notifications
You must be signed in to change notification settings - Fork 15.1k
release/19.x: [WebAssembly] Handle symbols in .init_array
sections (#119127)
#119533
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
Conversation
@llvm/pr-subscribers-mc Author: None (llvmbot) ChangesRequested by: @nikic Full diff: https://github.com/llvm/llvm-project/pull/119533.diff 3 Files Affected:
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index f25dc92fa235a2..85264692456767 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -1326,6 +1326,22 @@ static bool isInSymtab(const MCSymbolWasm &Sym) {
return true;
}
+static bool isSectionReferenced(MCAssembler &Asm, MCSectionWasm &Section) {
+ StringRef SectionName = Section.getName();
+
+ for (const MCSymbol &S : Asm.symbols()) {
+ const auto &WS = static_cast<const MCSymbolWasm &>(S);
+ if (WS.isData() && WS.isInSection()) {
+ auto &RefSection = static_cast<MCSectionWasm &>(WS.getSection());
+ if (RefSection.getName() == SectionName) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
void WasmObjectWriter::prepareImports(
SmallVectorImpl<wasm::WasmImport> &Imports, MCAssembler &Asm) {
// For now, always emit the memory import, since loads and stores are not
@@ -1482,8 +1498,10 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
LLVM_DEBUG(dbgs() << "Processing Section " << SectionName << " group "
<< Section.getGroup() << "\n";);
- // .init_array sections are handled specially elsewhere.
- if (SectionName.starts_with(".init_array"))
+ // .init_array sections are handled specially elsewhere, include them in
+ // data segments if and only if referenced by a symbol.
+ if (SectionName.starts_with(".init_array") &&
+ !isSectionReferenced(Asm, Section))
continue;
// Code is handled separately
@@ -1853,49 +1871,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-label.s b/llvm/test/MC/WebAssembly/init-array-label.s
new file mode 100644
index 00000000000000..0b4a5ea2da0b59
--- /dev/null
+++ b/llvm/test/MC/WebAssembly/init-array-label.s
@@ -0,0 +1,91 @@
+# 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.42,"",@
+ .p2align 2, 0x0
+ .int32 init1
+
+ .section .init_array,"",@
+ .globl p_init1
+ .p2align 2, 0x0
+p_init1:
+ .int32 init1
+ .size p_init1, 4
+
+ .section .init_array,"",@
+ .globl p_init2
+ .p2align 2, 0x0
+p_init2:
+ .int32 init1
+ .int32 init2
+ .size p_init2, 8
+
+# CHECK: - Type: FUNCTION
+# CHECK-NEXT: FunctionTypes: [ 0, 0 ]
+# CHECK-NEXT: - Type: DATACOUNT
+# CHECK-NEXT: Count: 1
+# 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: DATA
+# CHECK-NEXT: Segments:
+# CHECK-NEXT: - SectionOffset: 6
+# CHECK-NEXT: InitFlags: 0
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Opcode: I32_CONST
+# CHECK-NEXT: Value: 0
+# CHECK-NEXT: Content: '000000000000000000000000'
+# 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: - Index: 2
+# CHECK-NEXT: Kind: DATA
+# CHECK-NEXT: Name: p_init1
+# CHECK-NEXT: Flags: [ ]
+# CHECK-NEXT: Segment: 0
+# CHECK-NEXT: Size: 4
+# CHECK-NEXT: - Index: 3
+# CHECK-NEXT: Kind: DATA
+# CHECK-NEXT: Name: p_init2
+# CHECK-NEXT: Flags: [ ]
+# CHECK-NEXT: Segment: 0
+# CHECK-NEXT: Offset: 4
+# CHECK-NEXT: Size: 8
+# CHECK-NEXT: SegmentInfo:
+# CHECK-NEXT: - Index: 0
+# CHECK-NEXT: Name: .init_array
+# CHECK-NEXT: Alignment: 2
+# CHECK-NEXT: Flags: [ ]
+# CHECK-NEXT: InitFunctions:
+# CHECK-NEXT: - Priority: 42
+# CHECK-NEXT: Symbol: 0
+# CHECK-NEXT: - Priority: 65535
+# CHECK-NEXT: Symbol: 0
+# 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: ...
+#
|
@llvm/pr-subscribers-backend-webassembly Author: None (llvmbot) ChangesRequested by: @nikic Full diff: https://github.com/llvm/llvm-project/pull/119533.diff 3 Files Affected:
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index f25dc92fa235a2..85264692456767 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -1326,6 +1326,22 @@ static bool isInSymtab(const MCSymbolWasm &Sym) {
return true;
}
+static bool isSectionReferenced(MCAssembler &Asm, MCSectionWasm &Section) {
+ StringRef SectionName = Section.getName();
+
+ for (const MCSymbol &S : Asm.symbols()) {
+ const auto &WS = static_cast<const MCSymbolWasm &>(S);
+ if (WS.isData() && WS.isInSection()) {
+ auto &RefSection = static_cast<MCSectionWasm &>(WS.getSection());
+ if (RefSection.getName() == SectionName) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
void WasmObjectWriter::prepareImports(
SmallVectorImpl<wasm::WasmImport> &Imports, MCAssembler &Asm) {
// For now, always emit the memory import, since loads and stores are not
@@ -1482,8 +1498,10 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
LLVM_DEBUG(dbgs() << "Processing Section " << SectionName << " group "
<< Section.getGroup() << "\n";);
- // .init_array sections are handled specially elsewhere.
- if (SectionName.starts_with(".init_array"))
+ // .init_array sections are handled specially elsewhere, include them in
+ // data segments if and only if referenced by a symbol.
+ if (SectionName.starts_with(".init_array") &&
+ !isSectionReferenced(Asm, Section))
continue;
// Code is handled separately
@@ -1853,49 +1871,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-label.s b/llvm/test/MC/WebAssembly/init-array-label.s
new file mode 100644
index 00000000000000..0b4a5ea2da0b59
--- /dev/null
+++ b/llvm/test/MC/WebAssembly/init-array-label.s
@@ -0,0 +1,91 @@
+# 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.42,"",@
+ .p2align 2, 0x0
+ .int32 init1
+
+ .section .init_array,"",@
+ .globl p_init1
+ .p2align 2, 0x0
+p_init1:
+ .int32 init1
+ .size p_init1, 4
+
+ .section .init_array,"",@
+ .globl p_init2
+ .p2align 2, 0x0
+p_init2:
+ .int32 init1
+ .int32 init2
+ .size p_init2, 8
+
+# CHECK: - Type: FUNCTION
+# CHECK-NEXT: FunctionTypes: [ 0, 0 ]
+# CHECK-NEXT: - Type: DATACOUNT
+# CHECK-NEXT: Count: 1
+# 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: DATA
+# CHECK-NEXT: Segments:
+# CHECK-NEXT: - SectionOffset: 6
+# CHECK-NEXT: InitFlags: 0
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Opcode: I32_CONST
+# CHECK-NEXT: Value: 0
+# CHECK-NEXT: Content: '000000000000000000000000'
+# 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: - Index: 2
+# CHECK-NEXT: Kind: DATA
+# CHECK-NEXT: Name: p_init1
+# CHECK-NEXT: Flags: [ ]
+# CHECK-NEXT: Segment: 0
+# CHECK-NEXT: Size: 4
+# CHECK-NEXT: - Index: 3
+# CHECK-NEXT: Kind: DATA
+# CHECK-NEXT: Name: p_init2
+# CHECK-NEXT: Flags: [ ]
+# CHECK-NEXT: Segment: 0
+# CHECK-NEXT: Offset: 4
+# CHECK-NEXT: Size: 8
+# CHECK-NEXT: SegmentInfo:
+# CHECK-NEXT: - Index: 0
+# CHECK-NEXT: Name: .init_array
+# CHECK-NEXT: Alignment: 2
+# CHECK-NEXT: Flags: [ ]
+# CHECK-NEXT: InitFunctions:
+# CHECK-NEXT: - Priority: 42
+# CHECK-NEXT: Symbol: 0
+# CHECK-NEXT: - Priority: 65535
+# CHECK-NEXT: Symbol: 0
+# 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: ...
+#
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM if tests pass
…asm objects (llvm#111008) (cherry picked from commit ac5dd45)
Follow on from llvm#111008. (cherry picked from commit ed91843)
@nikic (or anyone else). If you would like to add a note about this fix in the release notes (completely optional). Please reply to this comment with a one or two sentence description of the fix. When you are done, please add the release:note label to this PR. |
Backport ac5dd45 ed91843
Requested by: @nikic