[lld] r249496 - Create simpler dynamic relocations for local symbols in got.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 6 17:58:20 PDT 2015


Author: rafael
Date: Tue Oct  6 19:58:20 2015
New Revision: 249496

URL: http://llvm.org/viewvc/llvm-project?rev=249496&view=rev
Log:
Create simpler dynamic relocations for local symbols in got.

If the symbol is not preemptable, we can use a R_X86_64_RELATIVE.

Added:
    lld/trunk/test/elf2/local-got-shared.s
Modified:
    lld/trunk/ELF/OutputSections.cpp

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=249496&r1=249495&r2=249496&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Tue Oct  6 19:58:20 2015
@@ -104,12 +104,6 @@ RelocationSection<ELFT>::RelocationSecti
   this->Header.sh_addralign = ELFT::Is64Bits ? 8 : 4;
 }
 
-static bool isLocalDefinition(const SymbolBody *Body) {
-  if (!Body)
-    return true;
-  return !Body->isShared() && !Body->isUndefined();
-}
-
 template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
   const unsigned EntrySize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
   bool IsMips64EL = Relocs[0].C.getFile()->getObj().isMips64EL();
@@ -126,32 +120,36 @@ template <class ELFT> void RelocationSec
     const ELFFile<ELFT> &Obj = File.getObj();
 
     uint32_t Type = RI.getType(IsMips64EL);
+
+    bool CanBePreempted = canBePreempted(Body);
+    uintX_t Addend = 0;
+    if (!CanBePreempted) {
+      if (IsRela) {
+        if (Body)
+          Addend += getSymVA(cast<ELFSymbolBody<ELFT>>(*Body), BssSec);
+        else
+          Addend += getLocalSymVA(
+              Obj.getRelocationSymbol(&RI, File.getSymbolTable()), File);
+      }
+      P->setSymbolAndType(0, Target->getRelativeReloc(), IsMips64EL);
+    }
+
     if (Body && Target->relocNeedsGot(Type, *Body)) {
       P->r_offset = GotSec.getEntryAddr(*Body);
-      P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
-                          Target->getGotReloc(), IsMips64EL);
+      if (CanBePreempted)
+        P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
+                            Target->getGotReloc(), IsMips64EL);
     } else {
-      P->r_offset = RI.r_offset + C.getOutputSectionOff() + Out->getVA();
-      uintX_t Addend = 0;
       if (IsRela)
-        Addend = static_cast<const Elf_Rela &>(RI).r_addend;
-
-      if (!isLocalDefinition(Body)) {
+        Addend += static_cast<const Elf_Rela &>(RI).r_addend;
+      P->r_offset = RI.r_offset + C.getOutputSectionOff() + Out->getVA();
+      if (CanBePreempted)
         P->setSymbolAndType(Body->getDynamicSymbolTableIndex(), Type,
                             IsMips64EL);
-      } else {
-        P->setSymbolAndType(0, Target->getRelativeReloc(), IsMips64EL);
-        if (IsRela) {
-          if (Body)
-            Addend += getSymVA(cast<ELFSymbolBody<ELFT>>(*Body), BssSec);
-          else
-            Addend += getLocalSymVA(
-                Obj.getRelocationSymbol(&RI, File.getSymbolTable()), File);
-        }
-      }
-      if (IsRela)
-        static_cast<Elf_Rela *>(P)->r_addend = Addend;
     }
+
+    if (IsRela)
+      static_cast<Elf_Rela *>(P)->r_addend = Addend;
   }
 }
 
@@ -418,7 +416,7 @@ bool lld::elf2::canBePreempted(const Sym
     return true;
   if (!Config->Shared)
     return false;
-  return true;
+  return Body->getMostConstrainingVisibility() == STV_DEFAULT;
 }
 
 template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) {

Added: lld/trunk/test/elf2/local-got-shared.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/local-got-shared.s?rev=249496&view=auto
==============================================================================
--- lld/trunk/test/elf2/local-got-shared.s (added)
+++ lld/trunk/test/elf2/local-got-shared.s Tue Oct  6 19:58:20 2015
@@ -0,0 +1,35 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+// RUN: ld.lld2 %t.o -o %t -shared
+// RUN: llvm-readobj -s -r %t | FileCheck %s
+// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
+
+bar:
+	call foo at gotpcrel
+
+        .hidden foo
+        .global foo
+foo:
+        nop
+
+// 0x3090 - 0x2000 - 5 = 4235
+// DISASM:      bar:
+// DISASM-NEXT:   2000: {{.*}} callq 4235
+
+// DISASM:      foo:
+// DISASM-NEXT:   2005: {{.*}} nop
+
+// CHECK:      Name: .got
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT:   SHF_ALLOC
+// CHECK-NEXT:   SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x3090
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 8
+
+// CHECK:      Relocations [
+// CHECK-NEXT:   Section ({{.*}}) .rela.dyn {
+// CHECK-NEXT:     0x3090 R_X86_64_RELATIVE - 0x2005
+// CHECK-NEXT:   }
+// CHECK-NEXT: ]




More information about the llvm-commits mailing list