[lld] r262590 - [ELF] - add support for relocations against local symbols when producing relocatable output.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 2 23:49:35 PST 2016


Author: grimar
Date: Thu Mar  3 01:49:35 2016
New Revision: 262590

URL: http://llvm.org/viewvc/llvm-project?rev=262590&view=rev
Log:
[ELF] - add support for relocations against local symbols when producing relocatable output.

There was a known limitation for -r option:
relocations against local symbols were not supported. 
For example rel[a].eh_frame sections contained relocations against sections
and that was not supported for -r before. Patch fixes that.

Differential review: http://reviews.llvm.org/D17813

Added:
    lld/trunk/test/ELF/Inputs/relocatable-ehframe.s
    lld/trunk/test/ELF/relocatable-ehframe.s
Modified:
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=262590&r1=262589&r2=262590&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Thu Mar  3 01:49:35 2016
@@ -266,7 +266,9 @@ elf::ObjectFile<ELFT>::createInputSectio
     return MipsReginfo;
   }
 
-  if (Name == ".eh_frame")
+  // We dont need special handling of .eh_frame sections if relocatable
+  // output was choosen. Proccess them as usual input sections.
+  if (!Config->Relocatable && Name == ".eh_frame")
     return new (EHAlloc.Allocate()) EHInputSection<ELFT>(this, &Sec);
   if (shouldMerge<ELFT>(Sec))
     return new (MAlloc.Allocate()) MergeInputSection<ELFT>(this, &Sec);

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=262590&r1=262589&r2=262590&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Thu Mar  3 01:49:35 2016
@@ -132,11 +132,15 @@ void InputSection<ELFT>::copyRelocations
     RelType *P = reinterpret_cast<RelType *>(Buf);
     Buf += sizeof(RelType);
 
-    // Relocation for local symbol here means that it is probably
-    // rel[a].eh_frame section which has references to
-    // sections in r_info field. Also needs fix for addend.
-    if (SymIndex < SymTab->sh_info)
-      fatal("Relocation against local symbols is not supported yet");
+    // Relocation against local symbol here means that it is probably
+    // rel[a].eh_frame section which has references to sections in r_info field.
+    if (SymIndex < SymTab->sh_info) {
+      const Elf_Sym *Sym = this->File->getLocalSymbol(SymIndex);
+      uint32_t Idx = Out<ELFT>::SymTab->Locals[Sym];
+      P->r_offset = RelocatedSection->getOffset(Rel.r_offset);
+      P->setSymbolAndType(Idx, Type, Config->Mips64EL);
+      continue;
+    }
 
     SymbolBody *Body = this->File->getSymbolBody(SymIndex)->repl();
     P->r_offset = RelocatedSection->getOffset(Rel.r_offset);

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=262590&r1=262589&r2=262590&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Thu Mar  3 01:49:35 2016
@@ -241,6 +241,9 @@ public:
   unsigned NumLocals = 0;
   StringTableSection<ELFT> &StrTabSec;
 
+  // Local symbol -> ID, filled only when producing relocatable output.
+  llvm::DenseMap<const Elf_Sym *, uint32_t> Locals;
+
 private:
   void writeLocalSymbols(uint8_t *&Buf);
   void writeGlobalSymbols(uint8_t *Buf);

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=262590&r1=262589&r2=262590&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu Mar  3 01:49:35 2016
@@ -528,9 +528,13 @@ static void reportUndefined(SymbolTable<
 template <class ELFT>
 static bool shouldKeepInSymtab(const ObjectFile<ELFT> &File, StringRef SymName,
                                const typename ELFFile<ELFT>::Elf_Sym &Sym) {
-  if (Sym.getType() == STT_SECTION || Sym.getType() == STT_FILE)
+  if (Sym.getType() == STT_FILE)
     return false;
 
+  // We keep sections in symtab for relocatable output.
+  if (Sym.getType() == STT_SECTION)
+    return Config->Relocatable;
+
   InputSectionBase<ELFT> *Sec = File.getSection(Sym);
   // If sym references a section in a discarded group, don't keep it.
   if (Sec == InputSection<ELFT>::Discarded)
@@ -569,8 +573,13 @@ template <class ELFT> void Writer<ELFT>:
         InputSectionBase<ELFT> *Section = F->getSection(Sym);
         if (!Section->Live)
           continue;
+        // That can happen if creating relocatable output.
+        if (Sym.getType() == STT_SECTION)
+          SymName = Section->getSectionName();
       }
       ++Out<ELFT>::SymTab->NumLocals;
+      if (Config->Relocatable)
+        Out<ELFT>::SymTab->Locals[&Sym] = Out<ELFT>::SymTab->NumLocals;
       F->KeptLocalSyms.push_back(std::make_pair(
           &Sym, Out<ELFT>::SymTab->StrTabSec.addString(SymName)));
     }

Added: lld/trunk/test/ELF/Inputs/relocatable-ehframe.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/relocatable-ehframe.s?rev=262590&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/relocatable-ehframe.s (added)
+++ lld/trunk/test/ELF/Inputs/relocatable-ehframe.s Thu Mar  3 01:49:35 2016
@@ -0,0 +1,14 @@
+.section foo1,"ax", at progbits
+.cfi_startproc
+ nop
+.cfi_endproc
+
+.section bar1,"ax", at progbits
+.cfi_startproc
+ nop
+.cfi_endproc
+
+.section dah1,"ax", at progbits
+.cfi_startproc
+ nop
+.cfi_endproc

Added: lld/trunk/test/ELF/relocatable-ehframe.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/relocatable-ehframe.s?rev=262590&view=auto
==============================================================================
--- lld/trunk/test/ELF/relocatable-ehframe.s (added)
+++ lld/trunk/test/ELF/relocatable-ehframe.s Thu Mar  3 01:49:35 2016
@@ -0,0 +1,42 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/relocatable-ehframe.s -o %t2.o
+# RUN: ld.lld -r %t1.o %t2.o -o %t
+# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s
+# RUN: llvm-objdump -s -d %t | FileCheck -check-prefix=CHECKTEXT %s
+
+# CHECK:      Relocations [
+# CHECK-NEXT:   Section {{.*}} .rela.eh_frame {
+# CHECK-NEXT:     0x20 R_X86_64_PC32 foo 0x0
+# CHECK-NEXT:     0x34 R_X86_64_PC32 bar 0x0
+# CHECK-NEXT:     0x48 R_X86_64_PC32 dah 0x0
+# CHECK-NEXT:     0x78 R_X86_64_PC32 foo1 0x0
+# CHECK-NEXT:     0x8C R_X86_64_PC32 bar1 0x0
+# CHECK-NEXT:     0xA0 R_X86_64_PC32 dah1 0x0
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+# CHECKTEXT:      Contents of section .strtab:
+# CHECKTEXT-NEXT:  0000 00666f6f 00626172 00646168 00666f6f  .foo.bar.dah.foo
+# CHECKTEXT-NEXT:  0010 31006261 72310064 61683100 5f737461  1.bar1.dah1._sta
+# CHECKTEXT-NEXT:  0020 727400                               rt.
+ 
+.section foo,"ax", at progbits
+.cfi_startproc
+ nop
+.cfi_endproc
+
+.section bar,"ax", at progbits
+.cfi_startproc
+ nop
+.cfi_endproc
+
+.section dah,"ax", at progbits
+.cfi_startproc
+ nop
+.cfi_endproc
+
+.text
+.globl _start;
+_start:
+ nop




More information about the llvm-commits mailing list