[lld] r249485 - Don't create dynamic relocations when its known what the got points to.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 6 16:56:53 PDT 2015


Author: rafael
Date: Tue Oct  6 18:56:53 2015
New Revision: 249485

URL: http://llvm.org/viewvc/llvm-project?rev=249485&view=rev
Log:
Don't create dynamic relocations when its known what the got points to.

Added:
    lld/trunk/test/elf2/local-got.s
Modified:
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.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=249485&r1=249484&r2=249485&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Tue Oct  6 18:56:53 2015
@@ -14,6 +14,7 @@
 
 using namespace llvm;
 using namespace llvm::object;
+using namespace llvm::support::endian;
 using namespace llvm::ELF;
 
 using namespace lld;
@@ -29,10 +30,11 @@ OutputSectionBase<Is64Bits>::OutputSecti
 }
 
 template <class ELFT>
-GotSection<ELFT>::GotSection()
+GotSection<ELFT>::GotSection(const OutputSection<ELFT> &BssSec)
     : OutputSectionBase<ELFT::Is64Bits>(".got", llvm::ELF::SHT_PROGBITS,
                                         llvm::ELF::SHF_ALLOC |
-                                            llvm::ELF::SHF_WRITE) {
+                                            llvm::ELF::SHF_WRITE),
+      BssSec(BssSec) {
   this->Header.sh_addralign = this->getAddrSize();
 }
 
@@ -47,6 +49,16 @@ GotSection<ELFT>::getEntryAddr(const Sym
   return this->getVA() + B.getGotIndex() * this->getAddrSize();
 }
 
+template <class ELFT> void GotSection<ELFT>::writeTo(uint8_t *Buf) {
+  for (const SymbolBody *B : Entries) {
+    if (canBePreempted(B))
+      continue; // The dynamic linker will take care of it.
+    uintX_t VA = getSymVA(*B, BssSec);
+    write<uintX_t, ELFT::TargetEndianness, sizeof(uintX_t)>(Buf, VA);
+    Buf += sizeof(uintX_t);
+  }
+}
+
 template <class ELFT>
 PltSection<ELFT>::PltSection(const GotSection<ELFT> &GotSec)
     : OutputSectionBase<ELFT::Is64Bits>(".plt", llvm::ELF::SHT_PROGBITS,
@@ -399,6 +411,16 @@ lld::elf2::getLocalSymVA(const typename
   return Out->getVA() + Section->getOutputSectionOff() + Sym->st_value;
 }
 
+bool lld::elf2::canBePreempted(const SymbolBody *Body) {
+  if (!Body)
+    return false;
+  if (Body->isShared() || Body->isUndefined())
+    return true;
+  if (!Config->Shared)
+    return false;
+  return true;
+}
+
 template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) {
   for (InputSection<ELFT> *C : Sections)
     C->writeTo(Buf, BssSec, PltSec, GotSec);

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=249485&r1=249484&r2=249485&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Tue Oct  6 18:56:53 2015
@@ -40,7 +40,7 @@ template <class ELFT>
 typename llvm::object::ELFFile<ELFT>::uintX_t
 getLocalSymVA(const typename llvm::object::ELFFile<ELFT>::Elf_Sym *Sym,
               const ObjectFile<ELFT> &File);
-
+bool canBePreempted(const SymbolBody *Body);
 template <class ELFT> bool includeInSymtab(const SymbolBody &B);
 
 bool includeInDynamicSymtab(const SymbolBody &B);
@@ -103,17 +103,18 @@ class GotSection final : public OutputSe
   typedef typename Base::uintX_t uintX_t;
 
 public:
-  GotSection();
+  GotSection(const OutputSection<ELFT> &BssSec);
   void finalize() override {
     this->Header.sh_size = Entries.size() * this->getAddrSize();
   }
-  void writeTo(uint8_t *Buf) override {}
+  void writeTo(uint8_t *Buf) override;
   void addEntry(SymbolBody *Sym);
   bool empty() const { return Entries.empty(); }
   uintX_t getEntryAddr(const SymbolBody &B) const;
 
 private:
   std::vector<const SymbolBody *> Entries;
+  const OutputSection<ELFT> &BssSec;
 };
 
 template <class ELFT>

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=249485&r1=249484&r2=249485&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Oct  6 18:56:53 2015
@@ -85,7 +85,7 @@ public:
   Writer(SymbolTable *T)
       : SymTabSec(*T, StrTabSec, BssSec), DynSymSec(*T, DynStrSec, BssSec),
         RelaDynSec(DynSymSec, GotSec, BssSec, T->shouldUseRela()),
-        PltSec(GotSec), HashSec(DynSymSec),
+        GotSec(BssSec), PltSec(GotSec), HashSec(DynSymSec),
         DynamicSec(*T, HashSec, RelaDynSec, BssSec),
         BssSec(PltSec, GotSec, BssSec, ".bss", SHT_NOBITS,
                SHF_ALLOC | SHF_WRITE) {}
@@ -230,18 +230,14 @@ void Writer<ELFT>::scanRelocs(
         if (Body->isInGot())
           continue;
         GotSec.addEntry(Body);
-        Body->setUsedInDynamicReloc();
-        RelaDynSec.addReloc({C, RI});
-        continue;
-      }
-      if (Body->isShared()) {
-        Body->setUsedInDynamicReloc();
-        RelaDynSec.addReloc({C, RI});
-        continue;
       }
     }
-    if (Config->Shared && !Target->isRelRelative(Type))
+    if (canBePreempted(Body)) {
+      Body->setUsedInDynamicReloc();
+      RelaDynSec.addReloc({C, RI});
+    } else if (Config->Shared && !Target->isRelRelative(Type)) {
       RelaDynSec.addReloc({C, RI});
+    }
   }
 }
 

Added: lld/trunk/test/elf2/local-got.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/local-got.s?rev=249485&view=auto
==============================================================================
--- lld/trunk/test/elf2/local-got.s (added)
+++ lld/trunk/test/elf2/local-got.s Tue Oct  6 18:56:53 2015
@@ -0,0 +1,40 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+// RUN: lld -flavor gnu2 %t.o -o %t
+// RUN: llvm-readobj -s -r -section-data %t | FileCheck %s
+// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
+
+        .globl _start
+_start:
+	call foo at gotpcrel
+
+        .global foo
+foo:
+        nop
+
+// 0x12000 - 0x11000 - 5 = 4091
+// DISASM:      _start:
+// DISASM-NEXT:   11000: {{.*}} callq 4091
+
+// DISASM:      foo:
+// DISASM-NEXT:   11005: {{.*}} 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: 0x12000
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 8
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 8
+// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: SectionData (
+// 0x11005 in little endian
+// CHECK-NEXT:   0000: 05100100 00000000                    |........|
+// CHECK-NEXT: )
+
+// CHECK:      Relocations [
+// CHECK-NEXT: ]




More information about the llvm-commits mailing list