[llvm-objcopy] Add --set-section-alignment

Fixes PR43181. This option was recently added to GNU objcopy (binutils
PR24942).

`llvm-objcopy -I binary -O elf64-x86-64 --set-section-alignment .data=8` can set the alignment of .data.

Reviewed By: grimar, jhenderson, rupprecht

Differential Revision: https://reviews.llvm.org/D67656

llvm-svn: 373461
diff --git a/llvm/test/tools/llvm-objcopy/ELF/binary-input.test b/llvm/test/tools/llvm-objcopy/ELF/binary-input.test
index 8eef7f7..f232296 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/binary-input.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/binary-input.test
@@ -110,3 +110,11 @@
 # CHECK-NEXT:     Section: Absolute
 # CHECK-NEXT:   }
 # CHECK-NEXT: ]
+
+## The alignment can be changed by --set-section-alignment.
+# RUN: llvm-objcopy -I binary -O elf64-x86-64 --set-section-alignment .data=8 %t.x-txt %t2.o
+# RUN: llvm-readobj --sections %t2.o | FileCheck --check-prefix=ALIGN %s
+
+# ALIGN:      Name: .data
+# ALIGN:      AddressAlignment:
+# ALIGN-SAME:                   8{{$}}
diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-section-alignment.test b/llvm/test/tools/llvm-objcopy/ELF/set-section-alignment.test
new file mode 100644
index 0000000..79c7edd
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-section-alignment.test
@@ -0,0 +1,54 @@
+# RUN: yaml2obj %s -o %t
+
+# RUN: llvm-objcopy --set-section-alignment .foo=4 --set-section-alignment .bar=0x5 \
+# RUN:   --set-section-alignment .baz=0 %t %t.2
+# RUN: llvm-readobj --sections %t.2 | FileCheck --check-prefix=CHECK %s
+
+# CHECK:      Name: .foo
+# CHECK:      AddressAlignment:
+# CHECK-SAME:                   4{{$}}
+# CHECK:      Name: .bar
+# CHECK:      AddressAlignment:
+# CHECK-SAME:                   5{{$}}
+# CHECK:      Name: .baz
+# CHECK:      AddressAlignment:
+# CHECK-SAME:                   0{{$}}
+
+## If a section is specified multiple times, the last wins.
+# RUN: llvm-objcopy --set-section-alignment .foo=4 --set-section-alignment=.foo=7 %t %t.3
+# RUN: llvm-readobj --sections %t.3 | FileCheck --check-prefix=MULTI %s
+
+# MULTI:      Name: .foo
+# MULTI:      AddressAlignment:
+# MULTI-SAME:                   7{{$}}
+
+## Ignore the option if the section does not exist.
+# RUN: llvm-objcopy --set-section-alignment .not_exist=4 %t.3 %t.4
+# RUN: cmp %t.3 %t.4
+
+# RUN: not llvm-objcopy --set-section-alignment=.foo %t /dev/null 2>&1 | \
+# RUN:   FileCheck --check-prefix=MISSING-EQUAL %s
+# MISSING-EQUAL:   error: bad format for --set-section-alignment: missing '='
+
+# RUN: not llvm-objcopy --set-section-alignment==4 %t /dev/null 2>&1 | \
+# RUN:   FileCheck --check-prefix=MISSING-SECTION %s
+# MISSING-SECTION: error: bad format for --set-section-alignment: missing section name
+
+# RUN: not llvm-objcopy --set-section-alignment=.foo=bar %t /dev/null 2>&1 | \
+# RUN:   FileCheck --check-prefix=INVALID-ALIGN %s
+# INVALID-ALIGN:   error: invalid alignment for --set-section-alignment: 'bar'
+
+!ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name:         .foo
+    Type:         SHT_PROGBITS
+  - Name:         .bar
+    Type:         SHT_NOBITS
+  - Name:         .baz
+    Type:         SHT_NOTE
+    AddressAlign: 4