[lld] r248196 - [ELF2] Support relocs for local symbols

Davide Italiano via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 21 12:30:12 PDT 2015


Author: davide
Date: Mon Sep 21 14:30:11 2015
New Revision: 248196

URL: http://llvm.org/viewvc/llvm-project?rev=248196&view=rev
Log:
[ELF2] Support relocs for local symbols

Differential Revision:	 http://reviews.llvm.org/D12978

Added:
    lld/trunk/test/elf2/relocation-local.s
Modified:
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=248196&r1=248195&r2=248196&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Sep 21 14:30:11 2015
@@ -263,6 +263,7 @@ class lld::elf2::OutputSection final
 public:
   typedef typename OutputSectionBase<ELFT::Is64Bits>::uintX_t uintX_t;
   typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
+  typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
   typedef typename ELFFile<ELFT>::Elf_Rel Elf_Rel;
   typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela;
   OutputSection(const PltSection<ELFT> &PltSec, const GotSection<ELFT> &GotSec,
@@ -734,6 +735,21 @@ getSymVA(const DefinedRegular<ELFT> *DR)
 }
 
 template <class ELFT>
+static typename ELFFile<ELFT>::uintX_t
+getLocalSymVA(const typename ELFFile<ELFT>::Elf_Sym *Sym,
+              const ObjectFile<ELFT> &File) {
+  uint32_t SecIndex = Sym->st_shndx;
+
+  if (SecIndex == SHN_XINDEX)
+    SecIndex = File.getObj()->getExtendedSymbolTableIndex(
+        Sym, File.getSymbolTable(), File.getSymbolTableShndx());
+  ArrayRef<InputSection<ELFT> *> Chunks = File.getChunks();
+  InputSection<ELFT> *Section = Chunks[SecIndex];
+  OutputSection<ELFT> *Out = Section->getOutputSection();
+  return Out->getVA() + Section->getOutputSectionOff() + Sym->st_value;
+}
+
+template <class ELFT>
 void OutputSection<ELFT>::relocateOne(uint8_t *Buf, const Elf_Rel &Rel,
                                       uint32_t Type, uintX_t BaseAddr,
                                       uintX_t SymVA) {
@@ -789,42 +805,51 @@ void OutputSection<ELFT>::relocate(
   bool IsMips64EL = File.getObj()->isMips64EL();
   for (const RelType &RI : Rels) {
     uint32_t SymIndex = RI.getSymbol(IsMips64EL);
-    const SymbolBody *Body = File.getSymbolBody(SymIndex);
-    if (!Body)
-      continue;
-
     uint32_t Type = RI.getType(IsMips64EL);
     uintX_t SymVA;
 
-    switch (Body->kind()) {
-    case SymbolBody::DefinedRegularKind:
-      SymVA = getSymVA<ELFT>(cast<DefinedRegular<ELFT>>(Body));
-      break;
-    case SymbolBody::DefinedAbsoluteKind:
-      SymVA = cast<DefinedAbsolute<ELFT>>(Body)->Sym.st_value;
-      break;
-    case SymbolBody::DefinedCommonKind: {
-      auto *DC = cast<DefinedCommon<ELFT>>(Body);
-      SymVA = DC->OutputSec->getVA() + DC->OffsetInBSS;
-      break;
-    }
-    case SymbolBody::SharedKind:
-      if (relocNeedsPLT(Type)) {
-        SymVA = PltSec.getEntryAddr(*Body);
-        Type = R_X86_64_PC32;
-      } else if (relocNeedsGOT(Type)) {
-        SymVA = GotSec.getEntryAddr(*Body);
-        Type = R_X86_64_PC32;
-      } else {
+    // Handle relocations for local symbols -- they never get
+    // resolved so we don't allocate a SymbolBody.
+    const Elf_Shdr *SymTab = File.getSymbolTable();
+    if (SymIndex < SymTab->sh_info) {
+      const Elf_Sym *Sym = File.getObj()->getRelocationSymbol(&RI, SymTab);
+      if (!Sym)
         continue;
+      SymVA = getLocalSymVA(Sym, File);
+    } else {
+      const SymbolBody *Body = File.getSymbolBody(SymIndex);
+      if (!Body)
+        continue;
+      switch (Body->kind()) {
+      case SymbolBody::DefinedRegularKind:
+        SymVA = getSymVA<ELFT>(cast<DefinedRegular<ELFT>>(Body));
+        break;
+      case SymbolBody::DefinedAbsoluteKind:
+        SymVA = cast<DefinedAbsolute<ELFT>>(Body)->Sym.st_value;
+        break;
+      case SymbolBody::DefinedCommonKind: {
+        auto *DC = cast<DefinedCommon<ELFT>>(Body);
+        SymVA = DC->OutputSec->getVA() + DC->OffsetInBSS;
+        break;
+      }
+      case SymbolBody::SharedKind:
+        if (relocNeedsPLT(Type)) {
+          SymVA = PltSec.getEntryAddr(*Body);
+          Type = R_X86_64_PC32;
+        } else if (relocNeedsGOT(Type)) {
+          SymVA = GotSec.getEntryAddr(*Body);
+          Type = R_X86_64_PC32;
+        } else {
+          continue;
+        }
+        break;
+      case SymbolBody::UndefinedKind:
+        assert(Body->isWeak() && "Undefined symbol reached writer");
+        SymVA = 0;
+        break;
+      case SymbolBody::LazyKind:
+        llvm_unreachable("Lazy symbol reached writer");
       }
-      break;
-    case SymbolBody::UndefinedKind:
-      assert(Body->isWeak() && "Undefined symbol reached writer");
-      SymVA = 0;
-      break;
-    case SymbolBody::LazyKind:
-      llvm_unreachable("Lazy symbol reached writer");
     }
 
     relocateOne(Buf, RI, Type, BaseAddr, SymVA);

Added: lld/trunk/test/elf2/relocation-local.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/relocation-local.s?rev=248196&view=auto
==============================================================================
--- lld/trunk/test/elf2/relocation-local.s (added)
+++ lld/trunk/test/elf2/relocation-local.s Mon Sep 21 14:30:11 2015
@@ -0,0 +1,38 @@
+// Test that relocation of local symbols is working.
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
+// RUN: lld -flavor gnu2 %t -o %t2
+// RUN: llvm-objdump -s -d %t2 | FileCheck %s
+// REQUIRES: x86
+
+
+.global _start
+_start:
+  call lulz
+
+.zero 4
+lulz:
+
+.section       .text2,"ax", at progbits
+R_X86_64_32:
+  movl $R_X86_64_32, %edx
+
+// FIXME: this would be far more self evident if llvm-objdump printed
+// constants in hex.
+// CHECK: Disassembly of section .text2:
+// CHECK-NEXT: R_X86_64_32:
+// CHECK-NEXT:  1100c: {{.*}} movl $69644, %edx
+
+.section .R_X86_64_32S,"ax", at progbits
+R_X86_64_32S:
+  movq lulz - 0x100000, %rdx
+
+// CHECK: Disassembly of section .R_X86_64_32S:
+// CHECK-NEXT: R_X86_64_32S:
+// CHECK-NEXT:  {{.*}}: {{.*}} movq -978935, %rdx
+
+.section .R_X86_64_64,"a", at progbits
+R_X86_64_64:
+ .quad R_X86_64_64
+
+// CHECK:      Contents of section .R_X86_64_64:
+// CHECK-NEXT:   12000 00200100 00000000




More information about the llvm-commits mailing list