[ELF] - Linkerscript: implemented SUBALIGN() command.
You can force input section alignment within an output section by using SUBALIGN. The
value specified overrides any alignment given by input sections, whether larger or smaller.
SUBALIGN is used in many projects in the wild.
Differential revision: https://reviews.llvm.org/D23063
llvm-svn: 279256
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 35a1a61..6b037a0 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -283,9 +283,14 @@
std::tie(OutSec, IsNew) = Factory.create(Head, Cmd->Name);
if (IsNew)
OutputSections->push_back(OutSec);
- for (InputSectionBase<ELFT> *Sec : V)
+
+ uint32_t Subalign = Cmd->SubalignExpr ? Cmd->SubalignExpr(0) : 0;
+ for (InputSectionBase<ELFT> *Sec : V) {
+ if (Subalign)
+ Sec->Alignment = Subalign;
if (!Sec->OutSec)
OutSec->addSection(Sec);
+ }
}
}
@@ -937,6 +942,8 @@
Cmd->LmaExpr = readParenExpr();
if (skip("ALIGN"))
Cmd->AlignExpr = readParenExpr();
+ if (skip("SUBALIGN"))
+ Cmd->SubalignExpr = readParenExpr();
// Parse constraints.
if (skip("ONLY_IF_RO"))
diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index b236fe0..d93023f 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -81,6 +81,7 @@
Expr AddrExpr;
Expr AlignExpr;
Expr LmaExpr;
+ Expr SubalignExpr;
std::vector<std::unique_ptr<BaseCommand>> Commands;
std::vector<StringRef> Phdrs;
std::vector<uint8_t> Filler;
diff --git a/lld/test/ELF/linkerscript/linkerscript-subalign.s b/lld/test/ELF/linkerscript/linkerscript-subalign.s
new file mode 100644
index 0000000..8b441d4
--- /dev/null
+++ b/lld/test/ELF/linkerscript/linkerscript-subalign.s
@@ -0,0 +1,43 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+
+# RUN: echo "SECTIONS { .aaa : { *(.aaa.*) } }" > %t1.script
+# RUN: ld.lld -o %t1 --script %t1.script %t1.o
+# RUN: llvm-objdump -s %t1 | FileCheck -check-prefix=NOALIGN %s
+# NOALIGN: Contents of section .aaa:
+# NOALIGN-NEXT: 01000000 00000000 00000000 00000000
+# NOALIGN-NEXT: 00000000 00000000 00000000 00000000
+# NOALIGN-NEXT: 02000000 00000000 00000000 00000000
+# NOALIGN-NEXT: 00000000 00000000 00000000 00000000
+# NOALIGN-NEXT: 03000000 00000000 00000000 00000000
+# NOALIGN-NEXT: 00000000 00000000 00000000 00000000
+# NOALIGN-NEXT: 00000000 00000000 00000000 00000000
+# NOALIGN-NEXT: 00000000 00000000 00000000 00000000
+# NOALIGN-NEXT: 04000000 00000000
+
+# RUN: echo "SECTIONS { .aaa : SUBALIGN(1) { *(.aaa.*) } }" > %t2.script
+# RUN: ld.lld -o %t2 --script %t2.script %t1.o
+# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=SUBALIGN %s
+# SUBALIGN: Contents of section .aaa:
+# SUBALIGN: 01000000 00000000 02000000 00000000
+# SUBALIGN: 03000000 00000000 04000000 00000000
+
+.global _start
+_start:
+ nop
+
+.section .aaa.1, "a"
+.align 16
+.quad 1
+
+.section .aaa.2, "a"
+.align 32
+.quad 2
+
+.section .aaa.3, "a"
+.align 64
+.quad 3
+
+.section .aaa.4, "a"
+.align 128
+.quad 4