[lld] r249340 - Create R_X86_64_RELATIVE when needed.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 5 12:30:12 PDT 2015


Author: rafael
Date: Mon Oct  5 14:30:12 2015
New Revision: 249340

URL: http://llvm.org/viewvc/llvm-project?rev=249340&view=rev
Log:
Create R_X86_64_RELATIVE when needed.

The dynamic relocation code needs refactoring, but it is probably better
to do it with this test passing.

Added:
    lld/trunk/test/elf2/relative-dynamic-reloc.s
Modified:
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/Target.cpp
    lld/trunk/ELF/Target.h
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=249340&r1=249339&r2=249340&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Mon Oct  5 14:30:12 2015
@@ -104,16 +104,23 @@ template <class ELFT> void RelocationSec
     uint32_t SymIndex = RI.getSymbol(IsMips64EL);
     const SymbolBody *Body = C.getFile()->getSymbolBody(SymIndex);
     uint32_t Type = RI.getType(IsMips64EL);
-    if (Target->relocNeedsGot(Type, *Body)) {
+    if (Body && Target->relocNeedsGot(Type, *Body)) {
       P->r_offset = GotSec.getEntryAddr(*Body);
       P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
                           Target->getGotReloc(), IsMips64EL);
     } else {
       P->r_offset = RI.r_offset + C.getOutputSectionOff() + Out->getVA();
-      P->setSymbolAndType(Body->getDynamicSymbolTableIndex(), Type, IsMips64EL);
-      if (IsRela)
-        static_cast<Elf_Rela *>(P)->r_addend =
-            static_cast<const Elf_Rela &>(RI).r_addend;
+      if (Body && Body->isShared()) {
+        P->setSymbolAndType(Body->getDynamicSymbolTableIndex(), Type,
+                            IsMips64EL);
+        if (IsRela)
+          static_cast<Elf_Rela *>(P)->r_addend =
+              static_cast<const Elf_Rela &>(RI).r_addend;
+      } else {
+        P->setSymbolAndType(0, Target->getRelativeReloc(), IsMips64EL);
+        if (IsRela)
+          static_cast<Elf_Rela *>(P)->r_addend = P->r_offset;
+      }
     }
   }
 }

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=249340&r1=249339&r2=249340&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Mon Oct  5 14:30:12 2015
@@ -30,6 +30,8 @@ TargetInfo::~TargetInfo() {}
 
 bool TargetInfo::relocPointsToGot(uint32_t Type) const { return false; }
 
+bool TargetInfo::isRelRelative(uint32_t Type) const { return true; }
+
 X86TargetInfo::X86TargetInfo() {
   PCRelReloc = R_386_PC32;
   GotReloc = R_386_GLOB_DAT;
@@ -87,6 +89,7 @@ X86_64TargetInfo::X86_64TargetInfo() {
   PCRelReloc = R_X86_64_PC32;
   GotReloc = R_X86_64_GLOB_DAT;
   GotRefReloc = R_X86_64_PC32;
+  RelativeReloc = R_X86_64_RELATIVE;
 }
 
 void X86_64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
@@ -139,6 +142,18 @@ bool X86_64TargetInfo::relocNeedsPlt(uin
     return true;
   }
 }
+
+bool X86_64TargetInfo::isRelRelative(uint32_t Type) const {
+  switch (Type) {
+  default:
+    return false;
+  case R_X86_64_PC64:
+  case R_X86_64_PC32:
+  case R_X86_64_PC16:
+  case R_X86_64_PC8:
+    return true;
+  }
+}
 
 void X86_64TargetInfo::relocateOne(uint8_t *Buf, const void *RelP,
                                    uint32_t Type, uint64_t BaseAddr,

Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=249340&r1=249339&r2=249340&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Mon Oct  5 14:30:12 2015
@@ -23,9 +23,11 @@ public:
   llvm::StringRef getDefaultEntry() const { return DefaultEntry; }
   unsigned getPCRelReloc() const { return PCRelReloc; }
   unsigned getGotReloc() const { return GotReloc; }
-  unsigned getGotRefReloc() const { return GotRefReloc; };
+  unsigned getGotRefReloc() const { return GotRefReloc; }
+  unsigned getRelativeReloc() const { return RelativeReloc; }
   virtual void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
                              uint64_t PltEntryAddr) const = 0;
+  virtual bool isRelRelative(uint32_t Type) const;
   virtual bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const = 0;
   virtual bool relocPointsToGot(uint32_t Type) const;
   virtual bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const = 0;
@@ -39,6 +41,7 @@ protected:
   unsigned PCRelReloc;
   unsigned GotRefReloc;
   unsigned GotReloc;
+  unsigned RelativeReloc;
   llvm::StringRef DefaultEntry = "_start";
 };
 
@@ -65,6 +68,7 @@ public:
   void relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type,
                    uint64_t BaseAddr, uint64_t SymVA,
                    uint64_t GotVA) const override;
+  bool isRelRelative(uint32_t Type) const override;
 };
 
 class PPC64TargetInfo final : public TargetInfo {

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=249340&r1=249339&r2=249340&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Oct  5 14:30:12 2015
@@ -217,22 +217,29 @@ void Writer<ELFT>::scanRelocs(
   for (const RelType &RI : Rels) {
     uint32_t SymIndex = RI.getSymbol(IsMips64EL);
     SymbolBody *Body = File.getSymbolBody(SymIndex);
-    if (!Body)
-      continue;
     uint32_t Type = RI.getType(IsMips64EL);
-    if (Target->relocNeedsPlt(Type, *Body)) {
-      if (Body->isInPlt())
+    if (Body) {
+      if (Target->relocNeedsPlt(Type, *Body)) {
+        if (Body->isInPlt())
+          continue;
+        PltSec.addEntry(Body);
+      }
+      if (Target->relocNeedsGot(Type, *Body)) {
+        if (Body->isInGot())
+          continue;
+        GotSec.addEntry(Body);
+        Body->setUsedInDynamicReloc();
+        RelaDynSec.addReloc({C, RI});
         continue;
-      PltSec.addEntry(Body);
-    }
-    if (Target->relocNeedsGot(Type, *Body)) {
-      if (Body->isInGot())
+      }
+      if (Body->isShared()) {
+        Body->setUsedInDynamicReloc();
+        RelaDynSec.addReloc({C, RI});
         continue;
-      GotSec.addEntry(Body);
-    } else if (!isa<SharedSymbol<ELFT>>(Body))
-      continue;
-    Body->setUsedInDynamicReloc();
-    RelaDynSec.addReloc({C, RI});
+      }
+    }
+    if (Config->Shared && !Target->isRelRelative(Type))
+      RelaDynSec.addReloc({C, RI});
   }
 }
 

Added: lld/trunk/test/elf2/relative-dynamic-reloc.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/relative-dynamic-reloc.s?rev=249340&view=auto
==============================================================================
--- lld/trunk/test/elf2/relative-dynamic-reloc.s (added)
+++ lld/trunk/test/elf2/relative-dynamic-reloc.s Mon Oct  5 14:30:12 2015
@@ -0,0 +1,40 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+// RUN: ld.lld2 -shared %t.o -o %t.so
+// RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
+
+// Test that we create R_X86_64_RELATIVE relocations but don't put any
+// symbols in the dynamic symbol table.
+
+// CHECK:      Relocations [
+// CHECK-NEXT:   Section ({{.*}}) .rela.dyn {
+// CHECK-NEXT:     [[FOO_ADDR:.*]] R_X86_64_RELATIVE - [[FOO_ADDR]]
+// CHECK-NEXT:     [[BAR_ADDR:.*]] R_X86_64_RELATIVE - [[BAR_ADDR]]
+// CHECK-NEXT:   }
+// CHECK-NEXT: ]
+
+// CHECK:      Symbols [
+// CHECK:        Name: foo
+// CHECK-NEXT:   Value: [[FOO_ADDR]]
+// CHECK:        Name: bar
+// CHECK-NEXT:   Value: [[BAR_ADDR]]
+// CHECK:      ]
+
+// CHECK:      DynamicSymbols [
+// CHECK-NEXT:   Symbol {
+// CHECK-NEXT:     Name: @ (0)
+// 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: ]
+
+foo:
+        .quad foo
+
+        .hidden bar
+        .global bar
+bar:
+        .quad bar




More information about the llvm-commits mailing list