[lld] r294464 - [ELF] - Added partial support for --emit-relocs (no --gc-section case, no /DISCARD/ support) #3

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 8 07:53:34 PST 2017


Author: grimar
Date: Wed Feb  8 09:53:33 2017
New Revision: 294464

URL: http://llvm.org/viewvc/llvm-project?rev=294464&view=rev
Log:
[ELF] - Added partial support for --emit-relocs (no --gc-section case, no /DISCARD/ support) #3

-q, --emit-relocs - Generate relocations in output

Simplest implementation: 
* no GC case, 
* no "/DISCARD/" linkerscript command support.

This patch is extracted from D28612 / D29636,

Relative to PR31579.

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

Added:
    lld/trunk/test/ELF/emit-relocs.s
Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/Options.td
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=294464&r1=294463&r2=294464&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Wed Feb  8 09:53:33 2017
@@ -102,6 +102,7 @@ struct Configuration {
   bool Demangle = true;
   bool DisableVerify;
   bool EhFrameHdr;
+  bool EmitRelocs;
   bool EnableNewDtags;
   bool ExportDynamic;
   bool FatalWarnings;
@@ -157,6 +158,7 @@ struct Configuration {
   unsigned LTOO;
   unsigned Optimize;
   unsigned ThinLTOJobs;
+  bool copyRelocs() { return Relocatable || EmitRelocs; };
 };
 
 // The only instance of Configuration struct.

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=294464&r1=294463&r2=294464&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Wed Feb  8 09:53:33 2017
@@ -519,6 +519,7 @@ void LinkerDriver::readConfigs(opt::Inpu
   Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions);
   Config->Demangle = getArg(Args, OPT_demangle, OPT_no_demangle, true);
   Config->DisableVerify = Args.hasArg(OPT_disable_verify);
+  Config->EmitRelocs = Args.hasArg(OPT_emit_relocs);
   Config->EhFrameHdr = Args.hasArg(OPT_eh_frame_hdr);
   Config->EnableNewDtags = !Args.hasArg(OPT_disable_new_dtags);
   Config->ExportDynamic =

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=294464&r1=294463&r2=294464&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Wed Feb  8 09:53:33 2017
@@ -399,6 +399,13 @@ elf::ObjectFile<ELFT>::createInputSectio
     }
     assert(isUInt<31>(NumRelocations));
     Target->NumRelocations = NumRelocations;
+
+    // Relocation sections processed by the linker are usually removed
+    // from the output, so returning `nullptr` for the normal case.
+    // However, if -emit-relocs is given, we need to leave them in the output.
+    // (Some post link analysis tools need this information.)
+    if (Config->EmitRelocs)
+      return make<InputSection<ELFT>>(this, &Sec, Name);
     return nullptr;
   }
   }

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=294464&r1=294463&r2=294464&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Wed Feb  8 09:53:33 2017
@@ -214,9 +214,9 @@ InputSectionBase<ELFT> *InputSection<ELF
   return Sections[this->Info];
 }
 
-// This is used for -r. We can't use memcpy to copy relocations because we need
-// to update symbol table offset and section index for each relocation. So we
-// copy relocations one by one.
+// This is used for -r and --emit-relocs. We can't use memcpy to copy
+// relocations because we need to update symbol table offset and section index
+// for each relocation. So we copy relocations one by one.
 template <class ELFT>
 template <class RelTy>
 void InputSection<ELFT>::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
@@ -235,7 +235,11 @@ void InputSection<ELFT>::copyRelocations
 
     if (Config->Rela)
       P->r_addend = getAddend<ELFT>(Rel);
-    P->r_offset = RelocatedSection->getOffset(Rel.r_offset);
+
+    // Output section VA is zero for -r, so r_offset is an offset within the
+    // section, but for --emit-relocs it is an virtual address.
+    P->r_offset = RelocatedSection->OutSec->Addr +
+                  RelocatedSection->getOffset(Rel.r_offset);
     P->setSymbolAndType(In<ELFT>::SymTab->getSymbolIndex(&Body), Type,
                         Config->Mips64EL);
   }
@@ -514,7 +518,8 @@ template <class ELFT> void InputSection<
     return;
   }
 
-  // If -r is given, then an InputSection may be a relocation section.
+  // If -r or --emit-relocs is given, then an InputSection
+  // may be a relocation section.
   if (this->Type == SHT_RELA) {
     copyRelocations(Buf + OutSecOff, this->template getDataAs<Elf_Rela>());
     return;

Modified: lld/trunk/ELF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=294464&r1=294463&r2=294464&view=diff
==============================================================================
--- lld/trunk/ELF/Options.td (original)
+++ lld/trunk/ELF/Options.td Wed Feb  8 09:53:33 2017
@@ -70,6 +70,8 @@ def dynamic_list: S<"dynamic-list">,
 def eh_frame_hdr: F<"eh-frame-hdr">,
   HelpText<"Request creation of .eh_frame_hdr section and PT_GNU_EH_FRAME segment header">;
 
+def emit_relocs: F<"emit-relocs">, HelpText<"Generate relocations in output">;
+
 def enable_new_dtags: F<"enable-new-dtags">,
   HelpText<"Enable new dynamic tags">;
 
@@ -283,6 +285,7 @@ def alias_define_common_dp: F<"dp">, Ali
 def alias_discard_all_x: Flag<["-"], "x">, Alias<discard_all>;
 def alias_discard_locals_X: Flag<["-"], "X">, Alias<discard_locals>;
 def alias_dynamic_list: J<"dynamic-list=">, Alias<dynamic_list>;
+def alias_emit_relocs: Flag<["-"], "q">, Alias<emit_relocs>;
 def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>;
 def alias_entry_entry: J<"entry=">, Alias<entry>;
 def alias_error_limit: J<"error-limit=">, Alias<error_limit>;

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=294464&r1=294463&r2=294464&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Wed Feb  8 09:53:33 2017
@@ -116,7 +116,7 @@ template <class ELFT> void OutputSection
   }
 
   uint32_t Type = this->Type;
-  if (!Config->Relocatable || (Type != SHT_RELA && Type != SHT_REL))
+  if (!Config->copyRelocs() || (Type != SHT_RELA && Type != SHT_REL))
     return;
 
   this->Link = In<ELFT>::SymTab->OutSec->SectionIndex;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=294464&r1=294463&r2=294464&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Feb  8 09:53:33 2017
@@ -449,9 +449,9 @@ static bool shouldKeepInSymtab(InputSect
   if (B.isFile())
     return false;
 
-  // We keep sections in symtab for relocatable output.
+  // We keep sections in symtab for relocatable output and --emit-reloc.
   if (B.isSection())
-    return Config->Relocatable;
+    return Config->copyRelocs();
 
   // If sym references a section in a discarded group, don't keep it.
   if (Sec == &InputSection<ELFT>::Discarded)

Added: lld/trunk/test/ELF/emit-relocs.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/emit-relocs.s?rev=294464&view=auto
==============================================================================
--- lld/trunk/test/ELF/emit-relocs.s (added)
+++ lld/trunk/test/ELF/emit-relocs.s Wed Feb  8 09:53:33 2017
@@ -0,0 +1,108 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+# RUN: ld.lld --emit-relocs %t1.o -o %t
+# RUN: llvm-readobj -t -r %t1 | FileCheck %s
+
+## Check single dash form.
+# RUN: ld.lld -emit-relocs %t1.o -o %t1
+# RUN: llvm-readobj -t -r %t1 | FileCheck %s
+
+## Check alias.
+# RUN: ld.lld -q %t1.o -o %t2
+# RUN: llvm-readobj -t -r %t2 | FileCheck %s
+
+# CHECK:      Relocations [
+# CHECK-NEXT:   Section ({{.*}}) .rela.text {
+# CHECK-NEXT:     0x201002 R_X86_64_32 .text 0x1
+# CHECK-NEXT:     0x201007 R_X86_64_PLT32 fn 0xFFFFFFFFFFFFFFFC
+# CHECK-NEXT:     0x20100E R_X86_64_32 .text 0x1
+# CHECK-NEXT:     0x201013 R_X86_64_PLT32 fn2 0xFFFFFFFFFFFFFFFC
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+# CHECK-NEXT: Symbols [
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name:
+# CHECK-NEXT:     Value: 0x0
+# CHECK-NEXT:     Size: 0
+# CHECK-NEXT:     Binding: Local
+# CHECK-NEXT:     Type: None
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: Undefined
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: bar
+# CHECK-NEXT:     Value: 0x201001
+# CHECK-NEXT:     Size: 0
+# CHECK-NEXT:     Binding: Local
+# CHECK-NEXT:     Type: None
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: .text
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: foo
+# CHECK-NEXT:     Value: 0x20100D
+# CHECK-NEXT:     Size: 0
+# CHECK-NEXT:     Binding: Local
+# CHECK-NEXT:     Type: None
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: .text
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name:
+# CHECK-NEXT:     Value: 0x201000
+# CHECK-NEXT:     Size: 0
+# CHECK-NEXT:     Binding: Local
+# CHECK-NEXT:     Type: Section
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: .text
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name:
+# CHECK-NEXT:     Value: 0x20100C
+# CHECK-NEXT:     Size: 0
+# CHECK-NEXT:     Binding: Local
+# CHECK-NEXT:     Type: Section
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: .text
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: fn
+# CHECK-NEXT:     Value: 0x201000
+# CHECK-NEXT:     Size: 0
+# CHECK-NEXT:     Binding: Global
+# CHECK-NEXT:     Type: Function
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: .text
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: fn2
+# CHECK-NEXT:     Value: 0x20100C
+# CHECK-NEXT:     Size: 0
+# CHECK-NEXT:     Binding: Global
+# CHECK-NEXT:     Type: Function
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: .text
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+.section .text,"ax", at progbits,unique,0
+.globl fn
+.type fn, at function
+fn:
+ nop
+
+bar:
+  movl $bar, %edx
+  callq fn at PLT
+  nop
+
+.section .text,"ax", at progbits,unique,1
+.globl fn2
+.type fn2, at function
+fn2:
+ nop
+
+foo:
+  movl $foo, %edx
+  callq fn2 at PLT
+  nop




More information about the llvm-commits mailing list