[lld] r304886 - [ELF] - Do not merge relocation sections by name when using --emit-relocs.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 7 02:20:36 PDT 2017


Author: grimar
Date: Wed Jun  7 04:20:35 2017
New Revision: 304886

URL: http://llvm.org/viewvc/llvm-project?rev=304886&view=rev
Log:
[ELF] - Do not merge relocation sections by name when using --emit-relocs.

Previously we would merge relocation sections by name.
That did not work in some cases, like testcase shows.

Patch implements logic to merge relocation sections if their target
sections were merged into the same output section.

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

Added:
    lld/trunk/test/ELF/linkerscript/emit-relocs-multiple.s
Modified:
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/emit-relocs-merge.s

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=304886&r1=304885&r2=304886&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Wed Jun  7 04:20:35 2017
@@ -283,6 +283,20 @@ void OutputSectionFactory::addInputSec(I
     return;
   }
 
+  // Imagine .zed : { *(.foo) *(.bar) } script. Both foo and bar may have
+  // relocation sections .rela.foo and .rela.bar for example. Most tools do
+  // not allow multiple REL[A] sections for output section. Hence we
+  // should combine these relocation sections into single output.
+  // We skip synthetic sections because it can be .rela.dyn/.rela.plt or any
+  // other REL[A] sections created by linker itself.
+  if (!isa<SyntheticSection>(IS) &&
+      (IS->Type == SHT_REL || IS->Type == SHT_RELA)) {
+    auto *Sec = cast<InputSection>(IS);
+    OutputSection *Out = Sec->getRelocatedSection()->getOutputSection();
+    addInputSec(IS, OutsecName, Out->RelocationSection);
+    return;
+  }
+
   SectionKey Key = createKey(IS, OutsecName);
   OutputSection *&Sec = Map[Key];
   return addInputSec(IS, OutsecName, Sec);

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=304886&r1=304885&r2=304886&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Wed Jun  7 04:20:35 2017
@@ -67,6 +67,11 @@ public:
   // formula: Off = Off_first + VA - VA_first.
   OutputSection *FirstInPtLoad = nullptr;
 
+  // Pointer to a relocation section for this section. Usually nullptr because
+  // we consume relocations, but if --emit-relocs is specified (which is rare),
+  // it may have a non-null value.
+  OutputSection *RelocationSection = nullptr;
+
   // The following fields correspond to Elf_Shdr members.
   uint64_t Size = 0;
   uint64_t Offset = 0;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=304886&r1=304885&r2=304886&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Jun  7 04:20:35 2017
@@ -101,18 +101,6 @@ StringRef elf::getOutputSectionName(Stri
   if (Config->Relocatable)
     return Name;
 
-  // If -emit-relocs is given (which is rare), we need to copy
-  // relocation sections to the output. If input section .foo is
-  // output as .bar, we want to rename .rel.foo .rel.bar as well.
-  if (Config->EmitRelocs) {
-    for (StringRef V : {".rel.", ".rela."}) {
-      if (Name.startswith(V)) {
-        StringRef Inner = getOutputSectionName(Name.substr(V.size() - 1));
-        return Saver.save(V.drop_back() + Inner);
-      }
-    }
-  }
-
   for (StringRef V :
        {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.",
         ".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.",

Modified: lld/trunk/test/ELF/emit-relocs-merge.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/emit-relocs-merge.s?rev=304886&r1=304885&r2=304886&view=diff
==============================================================================
--- lld/trunk/test/ELF/emit-relocs-merge.s (original)
+++ lld/trunk/test/ELF/emit-relocs-merge.s Wed Jun  7 04:20:35 2017
@@ -8,7 +8,7 @@
 # CHECK-NEXT:     0x1000 R_X86_64_64 zed 0x0
 # CHECK-NEXT:     0x1008 R_X86_64_64 zed 0x0
 # CHECK-NEXT:   }
-# CHECK-NEXT:   Section ({{.*}}) .rela.data {
+# CHECK-NEXT:   Section ({{.*}}) .rela.data.foo {
 # CHECK-NEXT:     0x1000 R_X86_64_64 zed 0x0
 # CHECK-NEXT:     0x1008 R_X86_64_64 zed 0x0
 # CHECK-NEXT:   }

Added: lld/trunk/test/ELF/linkerscript/emit-relocs-multiple.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/emit-relocs-multiple.s?rev=304886&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/emit-relocs-multiple.s (added)
+++ lld/trunk/test/ELF/linkerscript/emit-relocs-multiple.s Wed Jun  7 04:20:35 2017
@@ -0,0 +1,20 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "SECTIONS { .zed : { *(.foo) *(.bar) } }" > %t.script
+# RUN: ld.lld --emit-relocs --script %t.script %t.o -o %t1
+# RUN: llvm-readobj -r %t1 | FileCheck %s
+
+# CHECK:      Relocations [
+# CHECK-NEXT:   Section {{.*}} .rela.foo {
+# CHECK-NEXT:     0x1 R_X86_64_32 .zed 0x0
+# CHECK-NEXT:     0x6 R_X86_64_32 .zed 0x5
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+.section .foo,"ax", at progbits
+aaa:
+  movl $aaa, %edx
+
+.section .bar,"ax", at progbits
+bbb:
+  movl $bbb, %edx




More information about the llvm-commits mailing list