[llvm] [AArch64][ELF] Section alignment of 4 for AArch64 instruction (PR #114031)

Sam Elliott via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 3 10:36:14 PST 2024


https://github.com/lenary updated https://github.com/llvm/llvm-project/pull/114031

>From f9e526c76673e3c4528d3b19eab81a91d2178593 Mon Sep 17 00:00:00 2001
From: Florin Popa <florin.popa at arm.com>
Date: Tue, 29 Oct 2024 10:43:25 +0000
Subject: [PATCH 1/5] [AArch64][ELF] Section alignment of 4 for AArch64
 instruction

The integrated assembler sets a minimum alignment for the .text section of 4. However user defined sections get an alignment of 1. Unlike the GNU assembler which raises the section alignment to 4 if an AArch64 instruction is used, the integrated assembler leaves the alignment at 1
---
 llvm/lib/MC/MCParser/ELFAsmParser.cpp         |  9 ++++++++
 .../directive-arch-section-alignment.s        | 22 +++++++++++++++++++
 2 files changed, 31 insertions(+)
 create mode 100644 llvm/test/MC/AArch64/directive-arch-section-alignment.s

diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
index c4536441665fa0..8e7256d6fae9cd 100644
--- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
@@ -697,6 +697,15 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
       getContext().getELFSection(SectionName, Type, Flags, Size, GroupName,
                                  IsComdat, UniqueID, LinkedToSym);
   getStreamer().switchSection(Section, Subsection);
+
+  // Section alignment of 4 if an AArch64 instruction is used when $x mapping
+  // symbol is added Match GNU Assembler
+  const Triple &TT = getContext().getTargetTriple();
+  if ((Section->getFlags() & ELF::SHF_EXECINSTR) && (TT.isAArch64())) {
+    if (Section->getAlign() < 4)
+      getStreamer().emitValueToAlignment(Align(4));
+  }
+
   // Check that flags are used consistently. However, the GNU assembler permits
   // to leave out in subsequent uses of the same sections; for compatibility,
   // do likewise.
diff --git a/llvm/test/MC/AArch64/directive-arch-section-alignment.s b/llvm/test/MC/AArch64/directive-arch-section-alignment.s
new file mode 100644
index 00000000000000..bf3881b9c288a7
--- /dev/null
+++ b/llvm/test/MC/AArch64/directive-arch-section-alignment.s
@@ -0,0 +1,22 @@
+// RUN: llvm-mc -triple aarch64-- -o - %s | FileCheck %s
+
+// CHECK: .section sec00
+// CHECK-NEXT: .p2align 2
+// CHECK-NEXT: nop
+.section sec00, "ax"
+nop
+nop
+// CHECK: .section sec01
+// CHECK-NEXT: .p2align 2
+// CHECK-NEXT: .p2align 2
+// CHECK-NEXT: nop
+.section sec01, "ax"
+.balign 4
+nop
+// CHECK: .section sec02
+// CHECK-NEXT: .p2align 2
+// CHECK-NEXT: .byte 1
+.section sec02, "ax"
+// CHECK-NEXT: nop
+.byte 1
+nop

>From beb10570240460c24f59cc3360afde67a61f5872 Mon Sep 17 00:00:00 2001
From: Florin Popa <florin.popa at arm.com>
Date: Tue, 29 Oct 2024 10:43:25 +0000
Subject: [PATCH 2/5] [AArch64][ELF] Section alignment of 4 for AArch64
 instruction

The integrated assembler sets a minimum alignment for the .text section of 4. However user defined sections get an alignment of 1. Unlike the GNU assembler which raises the section alignment to 4 if an AArch64 instruction is used, the integrated assembler leaves the alignment at 1
---
 llvm/lib/MC/MCParser/ELFAsmParser.cpp         |  8 ------
 .../MCTargetDesc/AArch64ELFStreamer.cpp       |  6 +++++
 .../directive-arch-section-alignment.s        | 27 +++++++++----------
 3 files changed, 19 insertions(+), 22 deletions(-)

diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
index 8e7256d6fae9cd..67b043b51c62c0 100644
--- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
@@ -698,14 +698,6 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
                                  IsComdat, UniqueID, LinkedToSym);
   getStreamer().switchSection(Section, Subsection);
 
-  // Section alignment of 4 if an AArch64 instruction is used when $x mapping
-  // symbol is added Match GNU Assembler
-  const Triple &TT = getContext().getTargetTriple();
-  if ((Section->getFlags() & ELF::SHF_EXECINSTR) && (TT.isAArch64())) {
-    if (Section->getAlign() < 4)
-      getStreamer().emitValueToAlignment(Align(4));
-  }
-
   // Check that flags are used consistently. However, the GNU assembler permits
   // to leave out in subsequent uses of the same sections; for compatibility,
   // do likewise.
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
index 490efb650d5038..e15a9237cda1d4 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
@@ -202,6 +202,12 @@ class AArch64ELFStreamer : public MCELFStreamer {
       LastEMS = EMS_None;
 
     MCELFStreamer::changeSection(Section, Subsection);
+
+    // Section alignment of 4 to match GNU Assembler
+    if (Section->getAlign() < 4) {
+      Section->setAlignment(Align(4));
+      emitValueToAlignment(Align(4), 0, 1, 0);
+    }
   }
 
   // Reset state between object emissions
diff --git a/llvm/test/MC/AArch64/directive-arch-section-alignment.s b/llvm/test/MC/AArch64/directive-arch-section-alignment.s
index bf3881b9c288a7..0c483a8817b20b 100644
--- a/llvm/test/MC/AArch64/directive-arch-section-alignment.s
+++ b/llvm/test/MC/AArch64/directive-arch-section-alignment.s
@@ -1,22 +1,21 @@
-// RUN: llvm-mc -triple aarch64-- -o - %s | FileCheck %s
+// RUN: llvm-mc -triple aarch64-windows -filetype obj -o %t.obj %s
+// RUN: llvm-objdump -d -r %t.obj | FileCheck %s
 
-// CHECK: .section sec00
-// CHECK-NEXT: .p2align 2
-// CHECK-NEXT: nop
 .section sec00, "ax"
 nop
 nop
-// CHECK: .section sec01
-// CHECK-NEXT: .p2align 2
-// CHECK-NEXT: .p2align 2
-// CHECK-NEXT: nop
+nop
 .section sec01, "ax"
 .balign 4
 nop
-// CHECK: .section sec02
-// CHECK-NEXT: .p2align 2
-// CHECK-NEXT: .byte 1
-.section sec02, "ax"
-// CHECK-NEXT: nop
-.byte 1
 nop
+nop
+
+// CHECK: 0000000000000000 <sec00>:
+// CHECK-NEXT: 0: d503201f      nop
+// CHECK-NEXT: 4: d503201f      nop
+// CHECK-NEXT: 8: d503201f      nop
+// CHECK: 0000000000000000 <sec01>:
+// CHECK-NEXT: 0: d503201f      nop
+// CHECK-NEXT: 4: d503201f      nop
+// CHECK-NEXT: 8: d503201f      nop

>From 5f7eb072ba8270334453d480d72a424bac568f6c Mon Sep 17 00:00:00 2001
From: Florin Popa <florin.popa at arm.com>
Date: Tue, 29 Oct 2024 10:43:25 +0000
Subject: [PATCH 3/5] [AArch64][ELF] Section alignment of 4 for AArch64
 instruction

The integrated assembler sets a minimum alignment for the .text section of 4. However user defined sections get an alignment of 1. Unlike the GNU assembler which raises the section alignment to 4 if an AArch64 instruction is used, the integrated assembler leaves the alignment at 1
---
 llvm/lib/MC/MCParser/ELFAsmParser.cpp         |  1 -
 .../MCTargetDesc/AArch64ELFStreamer.cpp       |  2 +-
 .../directive-arch-section-alignment.s        | 47 ++++++++++++++-----
 3 files changed, 36 insertions(+), 14 deletions(-)

diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
index 67b043b51c62c0..c4536441665fa0 100644
--- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
@@ -697,7 +697,6 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
       getContext().getELFSection(SectionName, Type, Flags, Size, GroupName,
                                  IsComdat, UniqueID, LinkedToSym);
   getStreamer().switchSection(Section, Subsection);
-
   // Check that flags are used consistently. However, the GNU assembler permits
   // to leave out in subsequent uses of the same sections; for compatibility,
   // do likewise.
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
index e15a9237cda1d4..0e4fb27718d46e 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
@@ -204,7 +204,7 @@ class AArch64ELFStreamer : public MCELFStreamer {
     MCELFStreamer::changeSection(Section, Subsection);
 
     // Section alignment of 4 to match GNU Assembler
-    if (Section->getAlign() < 4) {
+    if ((Section->getAlign() < 4) && Section->isText()) {
       Section->setAlignment(Align(4));
       emitValueToAlignment(Align(4), 0, 1, 0);
     }
diff --git a/llvm/test/MC/AArch64/directive-arch-section-alignment.s b/llvm/test/MC/AArch64/directive-arch-section-alignment.s
index 0c483a8817b20b..4c83d65db86294 100644
--- a/llvm/test/MC/AArch64/directive-arch-section-alignment.s
+++ b/llvm/test/MC/AArch64/directive-arch-section-alignment.s
@@ -1,21 +1,44 @@
-// RUN: llvm-mc -triple aarch64-windows -filetype obj -o %t.obj %s
-// RUN: llvm-objdump -d -r %t.obj | FileCheck %s
+// RUN: llvm-mc -triple=aarch64-none-linux-gnu -filetype=obj -o %t.obj %s
+// RUN: llvm-readobj -S --sd %t.obj | FileCheck %s  --check-prefix=CHECK-OBJ
+// RUN: llvm-readelf -s  %t.obj | FileCheck %s --check-prefix=CHECK-ELF
 
 .section sec00, "ax"
+.byte 1
+.section sec01, "ax"
 nop
 nop
-nop
-.section sec01, "ax"
+.section sec02, "ax"
 .balign 4
 nop
 nop
+.section sec03, "ax"
+.byte 0
+.section sec04, "aw"
 nop
+nop
+
+// CHECK-OBJ: Name: sec00
+// CHECK-OBJ-NEXT: Type: SHT_PROGBITS (0x1)
+// CHECK-OBJ-NEXT: Flags [ (0x6)
+// CHECK-OBJ: AddressAlignment: 4
+// CHECK-OBJ: Name: sec01
+// CHECK-OBJ-NEXT: Type: SHT_PROGBITS (0x1)
+// CHECK-OBJ-NEXT: Flags [ (0x6)
+// CHECK-OBJ: AddressAlignment: 4
+// CHECK-OBJ: Name: sec02
+// CHECK-OBJ-NEXT: Type: SHT_PROGBITS (0x1)
+// CHECK-OBJ-NEXT: Flags [ (0x6)
+// CHECK-OBJ: Name: sec03
+// CHECK-OBJ-NEXT: Type: SHT_PROGBITS (0x1)
+// CHECK-OBJ-NEXT: Flags [ (0x6)
+// CHECK-OBJ: AddressAlignment: 4
+// CHECK-OBJ: Name: sec04
+// CHECK-OBJ-NEXT: Type: SHT_PROGBITS (0x1)
+// CHECK-OBJ-NEXT: Flags [ (0x3)
+// CHECK-OBJ: AddressAlignment: 1
 
-// CHECK: 0000000000000000 <sec00>:
-// CHECK-NEXT: 0: d503201f      nop
-// CHECK-NEXT: 4: d503201f      nop
-// CHECK-NEXT: 8: d503201f      nop
-// CHECK: 0000000000000000 <sec01>:
-// CHECK-NEXT: 0: d503201f      nop
-// CHECK-NEXT: 4: d503201f      nop
-// CHECK-NEXT: 8: d503201f      nop
+//CHECK-ELF: sec00             PROGBITS        0000000000000000 000040 000001 00  AX  0   0  4
+//CHECK-ELF-NEXT: sec01             PROGBITS        0000000000000000 000044 000008 00  AX  0   0  4
+//CHECK-ELF-NEXT: sec02             PROGBITS        0000000000000000 00004c 000008 00  AX  0   0  4
+//CHECK-ELF-NEXT: sec03             PROGBITS        0000000000000000 000054 000001 00  AX  0   0  4
+//CHECK-ELF-NEXT: sec04             PROGBITS        0000000000000000 000055 000008 00  WA  0   0  1

>From 46b0b4e970e70d6d881ba0f919ac30c51bf98e8a Mon Sep 17 00:00:00 2001
From: Florin Popa <florin.popa at arm.com>
Date: Tue, 29 Oct 2024 10:43:25 +0000
Subject: [PATCH 4/5] [AArch64][ELF] Section alignment of 4 for AArch64
 instruction

The integrated assembler sets a minimum alignment for the .text section of 4. However user defined sections get an alignment of 1. Unlike the GNU assembler which raises the section alignment to 4 if an AArch64 instruction is used, the integrated assembler leaves the alignment at 1
---
 llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
index 0e4fb27718d46e..29de1a11600d04 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
@@ -206,7 +206,6 @@ class AArch64ELFStreamer : public MCELFStreamer {
     // Section alignment of 4 to match GNU Assembler
     if ((Section->getAlign() < 4) && Section->isText()) {
       Section->setAlignment(Align(4));
-      emitValueToAlignment(Align(4), 0, 1, 0);
     }
   }
 

>From 0a7346fea454e31e3d8d887555c28e23e3cfecea Mon Sep 17 00:00:00 2001
From: Florin Popa <florin.popa at arm.com>
Date: Tue, 29 Oct 2024 10:43:25 +0000
Subject: [PATCH 5/5] [AArch64][ELF] Section alignment of 4 for AArch64
 instruction

The integrated assembler sets a minimum alignment for the .text section of 4. However user defined sections get an alignment of 1. Unlike the GNU assembler which raises the section alignment to 4 if an AArch64 instruction is used, the integrated assembler leaves the alignment at 1
---
 .../MCTargetDesc/AArch64ELFStreamer.cpp       |  3 +-
 .../directive-arch-section-alignment.s        | 38 ++++++-------------
 2 files changed, 12 insertions(+), 29 deletions(-)

diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
index 29de1a11600d04..0dc091e42755b3 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
@@ -204,9 +204,8 @@ class AArch64ELFStreamer : public MCELFStreamer {
     MCELFStreamer::changeSection(Section, Subsection);
 
     // Section alignment of 4 to match GNU Assembler
-    if ((Section->getAlign() < 4) && Section->isText()) {
+    if ((Section->getAlign() < 4) && Section->isText())
       Section->setAlignment(Align(4));
-    }
   }
 
   // Reset state between object emissions
diff --git a/llvm/test/MC/AArch64/directive-arch-section-alignment.s b/llvm/test/MC/AArch64/directive-arch-section-alignment.s
index 4c83d65db86294..8b3be4e322cc12 100644
--- a/llvm/test/MC/AArch64/directive-arch-section-alignment.s
+++ b/llvm/test/MC/AArch64/directive-arch-section-alignment.s
@@ -1,6 +1,5 @@
 // RUN: llvm-mc -triple=aarch64-none-linux-gnu -filetype=obj -o %t.obj %s
-// RUN: llvm-readobj -S --sd %t.obj | FileCheck %s  --check-prefix=CHECK-OBJ
-// RUN: llvm-readelf -s  %t.obj | FileCheck %s --check-prefix=CHECK-ELF
+// RUN: llvm-readobj -S --sd %t.obj | FileCheck %s
 
 .section sec00, "ax"
 .byte 1
@@ -17,28 +16,13 @@ nop
 nop
 nop
 
-// CHECK-OBJ: Name: sec00
-// CHECK-OBJ-NEXT: Type: SHT_PROGBITS (0x1)
-// CHECK-OBJ-NEXT: Flags [ (0x6)
-// CHECK-OBJ: AddressAlignment: 4
-// CHECK-OBJ: Name: sec01
-// CHECK-OBJ-NEXT: Type: SHT_PROGBITS (0x1)
-// CHECK-OBJ-NEXT: Flags [ (0x6)
-// CHECK-OBJ: AddressAlignment: 4
-// CHECK-OBJ: Name: sec02
-// CHECK-OBJ-NEXT: Type: SHT_PROGBITS (0x1)
-// CHECK-OBJ-NEXT: Flags [ (0x6)
-// CHECK-OBJ: Name: sec03
-// CHECK-OBJ-NEXT: Type: SHT_PROGBITS (0x1)
-// CHECK-OBJ-NEXT: Flags [ (0x6)
-// CHECK-OBJ: AddressAlignment: 4
-// CHECK-OBJ: Name: sec04
-// CHECK-OBJ-NEXT: Type: SHT_PROGBITS (0x1)
-// CHECK-OBJ-NEXT: Flags [ (0x3)
-// CHECK-OBJ: AddressAlignment: 1
-
-//CHECK-ELF: sec00             PROGBITS        0000000000000000 000040 000001 00  AX  0   0  4
-//CHECK-ELF-NEXT: sec01             PROGBITS        0000000000000000 000044 000008 00  AX  0   0  4
-//CHECK-ELF-NEXT: sec02             PROGBITS        0000000000000000 00004c 000008 00  AX  0   0  4
-//CHECK-ELF-NEXT: sec03             PROGBITS        0000000000000000 000054 000001 00  AX  0   0  4
-//CHECK-ELF-NEXT: sec04             PROGBITS        0000000000000000 000055 000008 00  WA  0   0  1
+// CHECK: Name: sec00
+// CHECK: AddressAlignment: 4
+// CHECK: Name: sec01
+// CHECK: AddressAlignment: 4
+// CHECK: Name: sec02
+// CHECK: AddressAlignment: 4
+// CHECK: Name: sec03
+// CHECK: AddressAlignment: 4
+// CHECK: Name: sec04
+// CHECK: AddressAlignment: 1
\ No newline at end of file



More information about the llvm-commits mailing list