Recommit r356738 "[llvm-objcopy] - Implement replaceSectionReferences for GroupSection class."

Fix: r356853 + set AddressAlign to 4 in 
Inputs/compress-debug-sections.yaml for the new group section introduced.

Original commit message:

Currently, llvm-objcopy incorrectly handles compression and decompression of the
sections from COMDAT groups, because we do not implement the
replaceSectionReferences for this type of the sections.

The patch does that.

Differential revision: https://reviews.llvm.org/D59638


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@356856 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/tools/llvm-objcopy/ELF/Inputs/compress-debug-sections.yaml b/test/tools/llvm-objcopy/ELF/Inputs/compress-debug-sections.yaml
index a3c607c..8da77b3 100644
--- a/test/tools/llvm-objcopy/ELF/Inputs/compress-debug-sections.yaml
+++ b/test/tools/llvm-objcopy/ELF/Inputs/compress-debug-sections.yaml
@@ -25,6 +25,24 @@
   - Name:            .debug_bar
     Type:            SHT_PROGBITS
     Content:         0000000000000000
+  - Name:            .group
+    Type:            SHT_GROUP
+    Link:            .symtab
+    AddressAlign:    4
+    EntSize:         0x0000000000000004
+    Info:            groupname
+    Members:
+      - SectionOrType:   GRP_COMDAT
+      - SectionOrType:   .text.in.group
+      - SectionOrType:   .debug_in_group
+  - Name:            .text.in.group
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+    Content:         '00'
+  - Name:            .debug_in_group
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_GROUP ]
+    Content:         '00'
 Symbols:
   Global:
     - Name:    .debug_foo
@@ -35,4 +53,6 @@
       Section: .notdebug_foo
     - Name:    .Linfo_string0
       Section: .debug_bar
+    - Name:    groupname
+      Section: .group
 ...
diff --git a/test/tools/llvm-objcopy/ELF/compress-debug-sections-groups.test b/test/tools/llvm-objcopy/ELF/compress-debug-sections-groups.test
new file mode 100644
index 0000000..a72ecbf
--- /dev/null
+++ b/test/tools/llvm-objcopy/ELF/compress-debug-sections-groups.test
@@ -0,0 +1,53 @@
+# REQUIRES: zlib
+
+## In this test, we check how llvm-objcopy handles compression/decompression
+## of debug sections included in a COMDAT group.
+
+# RUN: yaml2obj %p/Inputs/compress-debug-sections.yaml -o %t.o
+
+## Check compression of debug sections.
+# RUN: llvm-objcopy --compress-debug-sections %t.o %t-compressed.o
+# RUN: llvm-readobj -s -elf-section-groups %t-compressed.o | \
+# RUN:   FileCheck %s --check-prefixes=CHECK,COMPRESS
+
+## Check zlib-gnu compression of debug sections.
+# RUN: llvm-objcopy --compress-debug-sections=zlib-gnu %t.o %t-compressed-gnu.o
+# RUN: llvm-readobj -s -elf-section-groups %t-compressed-gnu.o | \
+# RUN:   FileCheck %s --check-prefixes=CHECK,COMPRESSZLIB
+
+## Check decompression of debug sections.
+# RUN: llvm-objcopy --decompress-debug-sections %t-compressed.o %t-decompressed.o
+# RUN: llvm-readobj -elf-section-groups %t-decompressed.o | \
+# RUN:   FileCheck %s --check-prefixes=CHECK,DECOMPRESS
+
+## Check decompression of zlib-gnu debug sections.
+# RUN: llvm-objcopy --decompress-debug-sections %t-compressed-gnu.o %t-decompressed-gnu.o
+# RUN: llvm-readobj -elf-section-groups %t-decompressed-gnu.o | \
+# RUN:   FileCheck %s --check-prefixes=CHECK,DECOMPRESS
+
+# COMPRESSZLIB:      Name: .zdebug_in_group
+# COMPRESSZLIB-NEXT: Type: SHT_PROGBITS
+# COMPRESSZLIB-NEXT: Flags [
+# COMPRESSZLIB-NEXT:   SHF_GROUP
+# COMPRESSZLIB-NEXT: ]
+
+# COMPRESS:      Name: .debug_in_group
+# COMPRESS-NEXT: Type: SHT_PROGBITS
+# COMPRESS-NEXT: Flags [
+# COMPRESS-NEXT:   SHF_COMPRESSED
+# COMPRESS-NEXT:   SHF_GROUP
+# COMPRESS-NEXT: ]
+
+# CHECK:           Group {
+# CHECK-NEXT:        Name: .group
+# CHECK-NEXT:        Index:
+# CHECK-NEXT:        Link:
+# CHECK-NEXT:        Info:
+# CHECK-NEXT:        Type: COMDAT
+# CHECK-NEXT:        Signature: groupname
+# CHECK-NEXT:        Section(s) in group [
+# CHECK-NEXT:          .text.in.group
+# COMPRESSZLIB-NEXT:   .zdebug_in_group
+# COMPRESS-NEXT:       .debug_in_group
+# DECOMPRESS-NEXT:     .debug_in_group
+# CHECK-NEXT:        ]
diff --git a/tools/llvm-objcopy/ELF/Object.cpp b/tools/llvm-objcopy/ELF/Object.cpp
index 39bee85..4639d90 100644
--- a/tools/llvm-objcopy/ELF/Object.cpp
+++ b/tools/llvm-objcopy/ELF/Object.cpp
@@ -689,6 +689,13 @@
     Sym->Referenced = true;
 }
 
+void GroupSection::replaceSectionReferences(
+    const DenseMap<SectionBase *, SectionBase *> &FromTo) {
+  for (SectionBase *&Sec : GroupMembers)
+    if (SectionBase *To = FromTo.lookup(Sec))
+      Sec = To;
+}
+
 void Section::initialize(SectionTableRef SecTable) {
   if (Link != ELF::SHN_UNDEF) {
     LinkSection =
diff --git a/tools/llvm-objcopy/ELF/Object.h b/tools/llvm-objcopy/ELF/Object.h
index 732ff89..e892d06 100644
--- a/tools/llvm-objcopy/ELF/Object.h
+++ b/tools/llvm-objcopy/ELF/Object.h
@@ -633,6 +633,8 @@
   void finalize() override;
   Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
   void markSymbols() override;
+  void replaceSectionReferences(
+      const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
 
   static bool classof(const SectionBase *S) {
     return S->Type == ELF::SHT_GROUP;