[ELF] - Don't emit broken relocations for SHF_MERGE sections when --emit-relocs is...
authorGeorge Rimar <grimar@accesssoftek.com>
Thu, 16 Nov 2017 12:33:36 +0000 (12:33 +0000)
committerGeorge Rimar <grimar@accesssoftek.com>
Thu, 16 Nov 2017 12:33:36 +0000 (12:33 +0000)
Previously our relocations we rewrote were broken for that case.
We emited incorrect addend and broken relocation info field
because did not produce section symbol for mergeable synthetic sections.

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

llvm-svn: 318394

lld/ELF/InputSection.cpp
lld/ELF/Writer.cpp
lld/test/ELF/emit-relocs-mergeable-i386.s [new file with mode: 0644]
lld/test/ELF/emit-relocs-mergeable.s [new file with mode: 0644]
lld/test/ELF/emit-relocs.s

index 9fe31e0..67eba3c 100644 (file)
@@ -411,7 +411,8 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
       }
 
       if (Config->IsRela) {
-        P->r_addend += Sym.getVA() - Section->getOutputSection()->Addr;
+        P->r_addend =
+            Sym.getVA(getAddend<ELFT>(Rel)) - Section->getOutputSection()->Addr;
       } else if (Config->Relocatable) {
         const uint8_t *BufLoc = Sec->Data.begin() + Rel.r_offset;
         Sec->Relocations.push_back({R_ABS, Type, Rel.r_offset,
index c3475b3..9592169 100644 (file)
@@ -473,8 +473,10 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
 }
 
 template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
-  // Create one STT_SECTION symbol for each output section we might
-  // have a relocation with.
+  // Create a section symbol for each output section so that we can represent
+  // relocations that point to the section. If we know that no relocation is
+  // referring to a section (that happens if the section is a synthetic one), we
+  // don't create a section symbol for that section.
   for (BaseCommand *Base : Script->SectionCommands) {
     auto *Sec = dyn_cast<OutputSection>(Base);
     if (!Sec)
@@ -487,8 +489,15 @@ template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
     if (I == Sec->SectionCommands.end())
       continue;
     InputSection *IS = cast<InputSectionDescription>(*I)->Sections[0];
-    if (isa<SyntheticSection>(IS) || IS->Type == SHT_REL ||
-        IS->Type == SHT_RELA)
+
+    // Relocations are not using REL[A] section symbols.
+    if (IS->Type == SHT_REL || IS->Type == SHT_RELA)
+      continue;
+
+    // Unlike other synthetic sections, mergeable output sections contain data
+    // copied from input sections, and there may be a relocation pointing to its
+    // contents if -emit-reloc is given.
+    if (isa<SyntheticSection>(IS) && !(IS->Flags & SHF_MERGE))
       continue;
 
     auto *Sym = make<Defined>("", /*IsLocal=*/true, /*StOther=*/0, STT_SECTION,
diff --git a/lld/test/ELF/emit-relocs-mergeable-i386.s b/lld/test/ELF/emit-relocs-mergeable-i386.s
new file mode 100644 (file)
index 0000000..945af98
--- /dev/null
@@ -0,0 +1,66 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t1
+# RUN: ld.lld --emit-relocs %t1 -o %t2
+# RUN: llvm-readobj -sections -section-data %t2 | FileCheck %s
+
+## Check lf we produce proper relocations when doing merging of SHF_MERGE sections.
+
+## Check addends of relocations are: 0x0, 0x8, 0x8, 0x4
+# CHECK:      Section {
+# CHECK:        Index:
+# CHECK:        Name: .foo
+# CHECK-NEXT:   Type: SHT_PROGBITS
+# CHECK-NEXT:   Flags [
+# CHECK-NEXT:     SHF_ALLOC
+# CHECK-NEXT:     SHF_EXECINSTR
+# CHECK-NEXT:   ]
+# CHECK-NEXT:   Address:
+# CHECK-NEXT:   Offset:
+# CHECK-NEXT:   Size:
+# CHECK-NEXT:   Link:
+# CHECK-NEXT:   Info:
+# CHECK-NEXT:   AddressAlignment:
+# CHECK-NEXT:   EntrySize:
+# CHECK-NEXT:   SectionData (
+# CHECK-NEXT:     0000: 00000000 08000000 08000000 04000000
+# CHECK-NEXT:   )
+# CHECK-NEXT: }
+
+## Check that offsets for AAA is 0x0, for BBB is 0x8 and CCC has offset 0x4.
+# CHECK:      Section {
+# CHECK:        Index:
+# CHECK:        Name: .strings
+# CHECK-NEXT:   Type: SHT_PROGBITS
+# CHECK-NEXT:   Flags [
+# CHECK-NEXT:     SHF_MERGE
+# CHECK-NEXT:     SHF_STRINGS
+# CHECK-NEXT:   ]
+# CHECK-NEXT:   Address:
+# CHECK-NEXT:   Offset:
+# CHECK-NEXT:   Size:
+# CHECK-NEXT:   Link:
+# CHECK-NEXT:   Info:
+# CHECK-NEXT:   AddressAlignment:
+# CHECK-NEXT:   EntrySize:
+# CHECK-NEXT:   SectionData (
+# CHECK-NEXT:     |AAA.CCC.BBB.|
+# CHECK-NEXT:   )
+# CHECK-NEXT: } 
+
+.section .strings,"MS",@progbits,1,unique,10
+.Linfo_string0:
+  .asciz "AAA"
+.Linfo_string1:
+  .asciz "BBB"
+
+.section .strings,"MS",@progbits,1,unique,20
+.Linfo_string2:
+  .asciz "BBB"
+.Linfo_string3:
+  .asciz "CCC"
+
+.section .foo,"ax",@progbits
+.long .Linfo_string0
+.long .Linfo_string1
+.long .Linfo_string2
+.long .Linfo_string3
diff --git a/lld/test/ELF/emit-relocs-mergeable.s b/lld/test/ELF/emit-relocs-mergeable.s
new file mode 100644 (file)
index 0000000..9b6ec1d
--- /dev/null
@@ -0,0 +1,53 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
+# RUN: ld.lld --emit-relocs %t1 -o %t2
+# RUN: llvm-readobj -sections -section-data -r %t2 | FileCheck %s
+
+## Check if we produce proper relocations when doing merging of SHF_MERGE sections.
+
+# CHECK:      Section {
+# CHECK:        Index:
+# CHECK:        Name: .strings
+# CHECK-NEXT:   Type: SHT_PROGBITS
+# CHECK-NEXT:   Flags [ 
+# CHECK-NEXT:     SHF_MERGE
+# CHECK-NEXT:     SHF_STRINGS
+# CHECK-NEXT:   ]
+# CHECK-NEXT:   Address:
+# CHECK-NEXT:   Offset:
+# CHECK-NEXT:   Size: 12
+# CHECK-NEXT:   Link:
+# CHECK-NEXT:   Info:
+# CHECK-NEXT:   AddressAlignment:
+# CHECK-NEXT:   EntrySize:
+# CHECK-NEXT:   SectionData (
+# CHECK-NEXT:     0000: 41414100 43434300 42424200 |AAA.CCC.BBB.|
+# CHECK-NEXT:   )
+# CHECK-NEXT: }
+
+# CHECK:      Relocations [
+# CHECK-NEXT:   Section {{.*}} .rela.foo {
+# CHECK-NEXT:     0x201000 R_X86_64_64 .strings 0x0
+# CHECK-NEXT:     0x201008 R_X86_64_64 .strings 0x8
+# CHECK-NEXT:     0x201010 R_X86_64_64 .strings 0x8
+# CHECK-NEXT:     0x201018 R_X86_64_64 .strings 0x4
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+.section .strings,"MS",@progbits,1,unique,10
+.Linfo_string0:
+  .asciz "AAA"
+.Linfo_string1:
+  .asciz "BBB"
+
+.section .strings,"MS",@progbits,1,unique,20
+.Linfo_string2:
+  .asciz "BBB"
+.Linfo_string3:
+  .asciz "CCC"
+
+.section .foo,"ax",@progbits
+.quad .Linfo_string0
+.quad .Linfo_string1
+.quad .Linfo_string2
+.quad .Linfo_string3
index 4f87ba6..95e70d8 100644 (file)
 # CHECK-NEXT:     Section: .text
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name:
+# CHECK-NEXT:     Value: 0x0
+# CHECK-NEXT:     Size: 0
+# CHECK-NEXT:     Binding: Local
+# CHECK-NEXT:     Type: Section
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: .comment
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Name: fn
 # CHECK-NEXT:     Value: 0x201000
 # CHECK-NEXT:     Size: 0