[lld] r254098 - [ELF] - Lazy relocations support for x86 target.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 25 13:37:59 PST 2015


Author: grimar
Date: Wed Nov 25 15:37:59 2015
New Revision: 254098

URL: http://llvm.org/viewvc/llvm-project?rev=254098&view=rev
Log:
[ELF] - Lazy relocations support for x86 target.

Patch implements lazy relocations for x86.
One of features of x86 is that executable files and shared object files have separate procedure linkage tables. So patch implements both cases.

Detailed information about instructions used can be found in http://docs.oracle.com/cd/E19620-01/805-3050/chapter6-1235/index.html (search: x86: Procedure Linkage Table).

Differential revision: http://reviews.llvm.org/D14955

Modified:
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/Target.cpp
    lld/trunk/ELF/Target.h
    lld/trunk/test/ELF/plt-i686.s
    lld/trunk/test/ELF/relocation-i686.s

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=254098&r1=254097&r2=254098&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Wed Nov 25 15:37:59 2015
@@ -150,18 +150,25 @@ template <class ELFT> void PltSection<EL
     Target->writePltZeroEntry(Buf, Out<ELFT>::GotPlt->getVA(), this->getVA());
     Off += Target->getPltZeroEntrySize();
   }
-  for (const SymbolBody *E : Entries) {
-    uint64_t Got = LazyReloc ? Out<ELFT>::GotPlt->getEntryAddr(*E)
-                             : Out<ELFT>::Got->getEntryAddr(*E);
+  for (std::pair<const SymbolBody *, size_t> &I : Entries) {
+    const SymbolBody *E = I.first;
+    unsigned RelOff = I.second;
+    uint64_t GotVA =
+        LazyReloc ? Out<ELFT>::GotPlt->getVA() : Out<ELFT>::Got->getVA();
+    uint64_t GotE = LazyReloc ? Out<ELFT>::GotPlt->getEntryAddr(*E)
+                              : Out<ELFT>::Got->getEntryAddr(*E);
     uint64_t Plt = this->getVA() + Off;
-    Target->writePltEntry(Buf + Off, Got, Plt, E->PltIndex);
+    Target->writePltEntry(Buf + Off, GotVA, GotE, Plt, E->PltIndex, RelOff);
     Off += Target->getPltEntrySize();
   }
 }
 
 template <class ELFT> void PltSection<ELFT>::addEntry(SymbolBody *Sym) {
   Sym->PltIndex = Entries.size();
-  Entries.push_back(Sym);
+  unsigned RelOff = Target->supportsLazyRelocations()
+                        ? Out<ELFT>::RelaPlt->getRelocOffset()
+                        : Out<ELFT>::RelaDyn->getRelocOffset();
+  Entries.push_back(std::make_pair(Sym, RelOff));
 }
 
 template <class ELFT>
@@ -281,6 +288,11 @@ template <class ELFT> void RelocationSec
   }
 }
 
+template <class ELFT> unsigned RelocationSection<ELFT>::getRelocOffset() {
+  const unsigned EntrySize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
+  return EntrySize * Relocs.size();
+}
+
 template <class ELFT> void RelocationSection<ELFT>::finalize() {
   this->Header.sh_link = Out<ELFT>::DynSymTab->SectionIndex;
   this->Header.sh_size = Relocs.size() * this->Header.sh_entsize;

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=254098&r1=254097&r2=254098&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Wed Nov 25 15:37:59 2015
@@ -166,7 +166,7 @@ public:
   uintX_t getEntryAddr(const SymbolBody &B) const;
 
 private:
-  std::vector<const SymbolBody *> Entries;
+  std::vector<std::pair<const SymbolBody *, unsigned>> Entries;
 };
 
 template <class ELFT> struct DynamicReloc {
@@ -216,6 +216,7 @@ class RelocationSection final : public O
 public:
   RelocationSection(StringRef Name, bool IsRela);
   void addReloc(const DynamicReloc<ELFT> &Reloc) { Relocs.push_back(Reloc); }
+  unsigned getRelocOffset();
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
   bool hasRelocs() const { return !Relocs.empty(); }

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=254098&r1=254097&r2=254098&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Wed Nov 25 15:37:59 2015
@@ -46,13 +46,15 @@ namespace {
 class X86TargetInfo final : public TargetInfo {
 public:
   X86TargetInfo();
+  void writeGotPltHeaderEntries(uint8_t *Buf) const override;
   unsigned getDynReloc(unsigned Type) const override;
   bool isTlsDynReloc(unsigned Type) const override;
   void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
   void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
                          uint64_t PltEntryAddr) const override;
-  void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
-                     uint64_t PltEntryAddr, int32_t Index) const override;
+  void writePltEntry(uint8_t *Buf, uint64_t GotAddr, uint64_t GotEntryAddr,
+                     uint64_t PltEntryAddr, int32_t Index,
+                     unsigned RelOff) const override;
   bool relocNeedsCopy(uint32_t Type, const SymbolBody &S) const override;
   bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
   bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
@@ -69,8 +71,9 @@ public:
   void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
   void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
                          uint64_t PltEntryAddr) const override;
-  void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
-                     uint64_t PltEntryAddr, int32_t Index) const override;
+  void writePltEntry(uint8_t *Buf, uint64_t GotAddr, uint64_t GotEntryAddr,
+                     uint64_t PltEntryAddr, int32_t Index,
+                     unsigned RelOff) const override;
   bool relocNeedsCopy(uint32_t Type, const SymbolBody &S) const override;
   bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
   bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
@@ -88,8 +91,9 @@ public:
   void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
   void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
                          uint64_t PltEntryAddr) const override;
-  void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
-                     uint64_t PltEntryAddr, int32_t Index) const override;
+  void writePltEntry(uint8_t *Buf, uint64_t GotAddr, uint64_t GotEntryAddr,
+                     uint64_t PltEntryAddr, int32_t Index,
+                     unsigned RelOff) const override;
   bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
   bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
   void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
@@ -105,8 +109,9 @@ public:
   void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
   void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
                          uint64_t PltEntryAddr) const override;
-  void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
-                     uint64_t PltEntryAddr, int32_t Index) const override;
+  void writePltEntry(uint8_t *Buf, uint64_t GotAddr, uint64_t GotEntryAddr,
+                     uint64_t PltEntryAddr, int32_t Index,
+                     unsigned RelOff) const override;
   bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
   bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
   void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
@@ -121,8 +126,9 @@ public:
   void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
   void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
                          uint64_t PltEntryAddr) const override;
-  void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
-                     uint64_t PltEntryAddr, int32_t Index) const override;
+  void writePltEntry(uint8_t *Buf, uint64_t GotAddr, uint64_t GotEntryAddr,
+                     uint64_t PltEntryAddr, int32_t Index,
+                     unsigned RelOff) const override;
   bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
   bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
   void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
@@ -184,6 +190,18 @@ X86TargetInfo::X86TargetInfo() {
   GotReloc = R_386_GLOB_DAT;
   GotRefReloc = R_386_GOT32;
   PltReloc = R_386_JUMP_SLOT;
+  LazyRelocations = true;
+  PltEntrySize = 16;
+  PltZeroEntrySize = 16;
+}
+
+void X86TargetInfo::writeGotPltHeaderEntries(uint8_t *Buf) const {
+  write32le(Buf, Out<ELF32LE>::Dynamic->getVA());
+}
+
+void X86TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {
+  // Skip 6 bytes of "pushl (GOT+4)"
+  write32le(Buf, Plt + 6);
 }
 
 unsigned X86TargetInfo::getDynReloc(unsigned Type) const {
@@ -200,17 +218,44 @@ bool X86TargetInfo::isTlsDynReloc(unsign
   return false;
 }
 
-void X86TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {}
 void X86TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
-                                      uint64_t PltEntryAddr) const {}
+                                      uint64_t PltEntryAddr) const {
+  // Executable files and shared object files have
+  // separate procedure linkage tables.
+  if (Config->Shared) {
+    const uint8_t V[] = {
+        0xff, 0xb3, 0x04, 0x00, 0x00, 0x00, // pushl 4(%ebx
+        0xff, 0xa3, 0x08, 0x00, 0x00, 0x00, // jmp *8(%ebx)
+        0x90, 0x90, 0x90, 0x90              // nop;nop;nop;nop
+    };
+    memcpy(Buf, V, sizeof(V));
+    return;
+  }
 
-void X86TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
-                                  uint64_t PltEntryAddr, int32_t Index) const {
-  // jmpl *val; nop; nop
-  const uint8_t Inst[] = {0xff, 0x25, 0, 0, 0, 0, 0x90, 0x90};
+  const uint8_t PltData[] = {
+      0xff, 0x35, 0x00, 0x00, 0x00, 0x00, // pushl (GOT+4)
+      0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *(GOT+8)
+      0x90, 0x90, 0x90, 0x90              // nop;nop;nop;nop
+  };
+  memcpy(Buf, PltData, sizeof(PltData));
+  write32le(Buf + 2, GotEntryAddr + 4); // GOT+4
+  write32le(Buf + 8, GotEntryAddr + 8); // GOT+8
+}
+
+void X86TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotAddr,
+                                  uint64_t GotEntryAddr, uint64_t PltEntryAddr,
+                                  int32_t Index, unsigned RelOff) const {
+  const uint8_t Inst[] = {
+      0xff, 0x00, 0x00, 0x00, 0x00, 0x00, // jmp *foo_in_GOT|*foo at GOT(%ebx)
+      0x68, 0x00, 0x00, 0x00, 0x00,       // pushl $reloc_offset
+      0xe9, 0x00, 0x00, 0x00, 0x00        // jmp .PLT0 at PC
+  };
   memcpy(Buf, Inst, sizeof(Inst));
-  assert(isUInt<32>(GotEntryAddr));
-  write32le(Buf + 2, GotEntryAddr);
+  // jmp *foo at GOT(%ebx) or jmp *foo_in_GOT
+  Buf[1] = Config->Shared ? 0xa3 : 0x25;
+  write32le(Buf + 2, Config->Shared ? (GotEntryAddr - GotAddr) : GotEntryAddr);
+  write32le(Buf + 7, RelOff);
+  write32le(Buf + 12, -Index * PltEntrySize - PltZeroEntrySize - 16);
 }
 
 bool X86TargetInfo::relocNeedsCopy(uint32_t Type, const SymbolBody &S) const {
@@ -292,9 +337,10 @@ void X86_64TargetInfo::writePltZeroEntry
   write32le(Buf + 8, GotEntryAddr - PltEntryAddr + 4); // GOT+16
 }
 
-void X86_64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
-                                     uint64_t PltEntryAddr,
-                                     int32_t Index) const {
+void X86_64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotAddr,
+                                     uint64_t GotEntryAddr,
+                                     uint64_t PltEntryAddr, int32_t Index,
+                                     unsigned RelOff) const {
   const uint8_t Inst[] = {
       0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmpq *got(%rip)
       0x68, 0x00, 0x00, 0x00, 0x00,       // pushq <relocation index>
@@ -522,8 +568,10 @@ uint64_t getPPC64TocBase() {
 void PPC64TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {}
 void PPC64TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
                                         uint64_t PltEntryAddr) const {}
-void PPC64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
-                                    uint64_t PltEntryAddr, int32_t Index) const {
+void PPC64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotAddr,
+                                    uint64_t GotEntryAddr,
+                                    uint64_t PltEntryAddr, int32_t Index,
+                                    unsigned RelOff) const {
   uint64_t Off = GotEntryAddr - getPPC64TocBase();
 
   // FIXME: What we should do, in theory, is get the offset of the function
@@ -734,9 +782,10 @@ void AArch64TargetInfo::writePltZeroEntr
               GotEntryAddr + 16);
 }
 
-void AArch64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
-                                      uint64_t PltEntryAddr,
-                                      int32_t Index) const {
+void AArch64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotAddr,
+                                      uint64_t GotEntryAddr,
+                                      uint64_t PltEntryAddr, int32_t Index,
+                                      unsigned RelOff) const {
   const uint8_t Inst[] = {
       0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[n]))
       0x11, 0x02, 0x40, 0xf9, // ldr  x17, [x16, Offset(&(.plt.got[n]))]
@@ -895,8 +944,10 @@ template <class ELFT>
 void MipsTargetInfo<ELFT>::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
                                        uint64_t PltEntryAddr) const {}
 template <class ELFT>
-void MipsTargetInfo<ELFT>::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
-                                         uint64_t PltEntryAddr, int32_t Index) const {}
+void MipsTargetInfo<ELFT>::writePltEntry(uint8_t *Buf, uint64_t GotAddr,
+                                         uint64_t GotEntryAddr,
+                                         uint64_t PltEntryAddr, int32_t Index,
+                                         unsigned RelOff) const {}
 
 template <class ELFT>
 bool MipsTargetInfo<ELFT>::relocNeedsGot(uint32_t Type,

Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=254098&r1=254097&r2=254098&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Wed Nov 25 15:37:59 2015
@@ -50,8 +50,9 @@ public:
   virtual void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const = 0;
   virtual void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
                                  uint64_t PltEntryAddr) const = 0;
-  virtual void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
-                             uint64_t PltEntryAddr, int32_t Index) const = 0;
+  virtual void writePltEntry(uint8_t *Buf, uint64_t GotAddr,
+                             uint64_t GotEntryAddr, uint64_t PltEntryAddr,
+                             int32_t Index, unsigned RelOff) const = 0;
   virtual bool isRelRelative(uint32_t Type) const;
   virtual bool relocNeedsCopy(uint32_t Type, const SymbolBody &S) const;
   virtual bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const = 0;

Modified: lld/trunk/test/ELF/plt-i686.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/plt-i686.s?rev=254098&r1=254097&r2=254098&view=diff
==============================================================================
--- lld/trunk/test/ELF/plt-i686.s (original)
+++ lld/trunk/test/ELF/plt-i686.s Wed Nov 25 15:37:59 2015
@@ -2,8 +2,12 @@
 // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o
 // RUN: ld.lld -shared %t2.o -o %t2.so
 // RUN: ld.lld %t.o %t2.so -o %t
-// RUN: llvm-readobj -s -r %t | FileCheck %s
+// RUN: llvm-readobj -s -r %t | FileCheck --check-prefix=CHECK %s
 // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
+// RUN: ld.lld -shared %t.o %t2.so -o %t
+// RUN: llvm-readobj -s -r %t | FileCheck --check-prefix=CHECKSHARED %s
+// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASMSHARED %s
+
 // REQUIRES: x86
 
 // CHECK:      Name: .plt
@@ -14,41 +18,124 @@
 // CHECK-NEXT: ]
 // CHECK-NEXT: Address: 0x11010
 // CHECK-NEXT: Offset:
-// CHECK-NEXT: Size: 16
+// CHECK-NEXT: Size: 48
 // CHECK-NEXT: Link: 0
 // CHECK-NEXT: Info: 0
 // CHECK-NEXT: AddressAlignment: 16
 
+// CHECK:      Name: .got.plt
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT:   SHF_ALLOC
+// CHECK-NEXT:   SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x12058
+// CHECK-NEXT: Offset: 0x2058
+// CHECK-NEXT: Size: 20
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 4
+// CHECK-NEXT: EntrySize: 0
+
+// 0x12058 + got.plt.reserved(12) = 0x12064
+// 0x12058 + got.plt.reserved(12) + 4 = 0x12068
 // CHECK:      Relocations [
-// CHECK-NEXT:   Section ({{.*}}) .rel.dyn {
-// CHECK-NEXT:     0x12050 R_386_GLOB_DAT bar 0x0
-// CHECK-NEXT:     0x12054 R_386_GLOB_DAT zed 0x0
+// CHECK-NEXT:   Section ({{.*}}) .rel.plt {
+// CHECK-NEXT:     0x12064 R_386_JUMP_SLOT bar 0x0
+// CHECK-NEXT:     0x12068 R_386_JUMP_SLOT zed 0x0
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]
 
 // Unfortunately FileCheck can't do math, so we have to check for explicit
 // values:
 
-// 0x11010 - (0x11000 + 1) - 4 = 11
-// 0x11010 - (0x11005 + 1) - 4 = 2
-// 0x11018 - (0x1100a + 1) - 4 = 9
+// 16 is the size of PLT[0]
+// (0x11010 + 16) - (0x11000 + 1) - 4 = 27
+// (0x11010 + 16) - (0x11005 + 1) - 4 = 22
+// (0x11020 + 16) - (0x1100a + 1) - 4 = 33
 
 // DISASM:      _start:
-// DISASM-NEXT:   11000:  e9 0b 00 00 00  jmp  11
-// DISASM-NEXT:   11005:  e9 06 00 00 00  jmp  6
-// DISASM-NEXT:   1100a:  e9 09 00 00 00  jmp  9
-
-// 0x12050 = 73808
-// 0x12054 = 73812
-
+// DISASM-NEXT:   11000:  e9 1b 00 00 00  jmp  27
+// DISASM-NEXT:   11005:  e9 16 00 00 00  jmp  22
+// DISASM-NEXT:   1100a:  e9 21 00 00 00  jmp  33
+
+// 0x11010 - 0x1102b - 5 = -32
+// 0x11010 - 0x1103b - 5 = -48
+// 73820 = 0x1205C = .got.plt (0x12058) + 4
+// 73824 = 0x12060 = .got.plt (0x12058) + 8
+// 73828 = 0x12064 = .got.plt (0x12058) + got.plt.reserved(12)
+// 73832 = 0x12068 = .got.plt (0x12058) + got.plt.reserved(12) + 4
 // DISASM:      Disassembly of section .plt:
 // DISASM-NEXT: .plt:
-// DISASM-NEXT:   11010:  ff 25 {{.*}}       jmpl *73808
-// DISASM-NEXT:   11016:  90                 nop
-// DISASM-NEXT:   11017:  90                 nop
-// DISASM-NEXT:   11018:  ff 25 {{.*}}       jmpl *73812
-// DISASM-NEXT:   1101e:  90                 nop
-// DISASM-NEXT:   1101f:  90                 nop
+// DISASM-NEXT:    11010: ff 35 5c 20 01 00 pushl 73820
+// DISASM-NEXT:    11016: ff 25 60 20 01 00 jmpl *73824
+// DISASM-NEXT:    1101c: 90 nop
+// DISASM-NEXT:    1101d: 90 nop
+// DISASM-NEXT:    1101e: 90 nop
+// DISASM-NEXT:    1101f: 90 nop
+// DISASM-NEXT:    11020: ff 25 64 20 01 00 jmpl *73828
+// DISASM-NEXT:    11026: 68 00 00 00 00 pushl $0
+// DISASM-NEXT:    1102b: e9 e0 ff ff ff jmp -32 <.plt>
+// DISASM-NEXT:    11030: ff 25 68 20 01 00 jmpl *73832
+// DISASM-NEXT:    11036: 68 08 00 00 00 pushl $8
+// DISASM-NEXT:    1103b: e9 d0 ff ff ff jmp -48 <.plt>
+
+// CHECKSHARED:        Name: .plt
+// CHECKSHARED-NEXT:   Type: SHT_PROGBITS
+// CHECKSHARED-NEXT:   Flags [
+// CHECKSHARED-NEXT:     SHF_ALLOC
+// CHECKSHARED-NEXT:     SHF_EXECINSTR
+// CHECKSHARED-NEXT:   ]
+// CHECKSHARED-NEXT:   Address: 0x1010
+// CHECKSHARED-NEXT:   Offset: 0x1010
+// CHECKSHARED-NEXT:   Size: 48
+// CHECKSHARED-NEXT:   Link: 0
+// CHECKSHARED-NEXT:   Info: 0
+// CHECKSHARED-NEXT:   AddressAlignment: 16
+// CHECKSHARED-NEXT:   EntrySize: 0
+// CHECKSHARED-NEXT:   }
+// CHECKSHARED:        Name: .got.plt
+// CHECKSHARED-NEXT:   Type: SHT_PROGBITS
+// CHECKSHARED-NEXT:   Flags [
+// CHECKSHARED-NEXT:     SHF_ALLOC
+// CHECKSHARED-NEXT:     SHF_WRITE
+// CHECKSHARED-NEXT:   ]
+// CHECKSHARED-NEXT:   Address: 0x2058
+// CHECKSHARED-NEXT:   Offset: 0x2058
+// CHECKSHARED-NEXT:   Size: 20
+// CHECKSHARED-NEXT:   Link: 0
+// CHECKSHARED-NEXT:   Info: 0
+// CHECKSHARED-NEXT:   AddressAlignment: 4
+// CHECKSHARED-NEXT:   EntrySize: 0
+// CHECKSHARED-NEXT:   }
+
+// 0x2058 + got.plt.reserved(12) = 0x2064
+// 0x2058 + got.plt.reserved(12) + 4 = 0x2068
+// CHECKSHARED:        Relocations [
+// CHECKSHARED-NEXT:     Section ({{.*}}) .rel.plt {
+// CHECKSHARED-NEXT:       0x2064 R_386_JUMP_SLOT bar 0x0
+// CHECKSHARED-NEXT:       0x2068 R_386_JUMP_SLOT zed 0x0
+// CHECKSHARED-NEXT:     }
+// CHECKSHARED-NEXT:   ]
+
+// DISASMSHARED:       _start:
+// DISASMSHARED-NEXT:  1000: e9 1b 00 00 00 jmp 27
+// DISASMSHARED-NEXT:  1005: e9 16 00 00 00 jmp 22
+// DISASMSHARED-NEXT:  100a: e9 21 00 00 00 jmp 33
+// DISASMSHARED-NEXT:  Disassembly of section .plt:
+// DISASMSHARED-NEXT:  .plt:
+// DISASMSHARED-NEXT:  1010: ff b3 04 00 00 00  pushl 4(%ebx)
+// DISASMSHARED-NEXT:  1016: ff a3 08 00 00 00  jmpl *8(%ebx)
+// DISASMSHARED-NEXT:  101c: 90 nop
+// DISASMSHARED-NEXT:  101d: 90 nop
+// DISASMSHARED-NEXT:  101e: 90 nop
+// DISASMSHARED-NEXT:  101f: 90 nop
+// DISASMSHARED-NEXT:  1020: ff a3 0c 00 00 00  jmpl *12(%ebx)
+// DISASMSHARED-NEXT:  1026: 68 00 00 00 00     pushl $0
+// DISASMSHARED-NEXT:  102b: e9 e0 ff ff ff     jmp -32 <.plt>
+// DISASMSHARED-NEXT:  1030: ff a3 10 00 00 00  jmpl *16(%ebx)
+// DISASMSHARED: 1036: 68 08 00 00 00     pushl $8
+// DISASMSHARED: 103b: e9 d0 ff ff ff     jmp -48 <.plt>
 
 .global _start
 _start:

Modified: lld/trunk/test/ELF/relocation-i686.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/relocation-i686.s?rev=254098&r1=254097&r2=254098&view=diff
==============================================================================
--- lld/trunk/test/ELF/relocation-i686.s (original)
+++ lld/trunk/test/ELF/relocation-i686.s Wed Nov 25 15:37:59 2015
@@ -47,7 +47,7 @@ movl bar at GOT, %eax
 // ADDR-NEXT: ]
 // ADDR-NEXT: Address: 0x11030
 // ADDR-NEXT: Offset: 0x1030
-// ADDR-NEXT: Size: 8
+// ADDR-NEXT: Size: 32
 
 // ADDR:      Name: .got
 // ADDR-NEXT: Type: SHT_PROGBITS
@@ -55,7 +55,7 @@ movl bar at GOT, %eax
 // ADDR-NEXT:   SHF_ALLOC
 // ADDR-NEXT:   SHF_WRITE
 // ADDR-NEXT: ]
-// ADDR-NEXT: Address: 0x12050
+// ADDR-NEXT: Address: 0x12070
 
 .section .R_386_GOTPC,"ax", at progbits
 R_386_GOTPC:
@@ -65,14 +65,14 @@ R_386_GOTPC:
 
 // CHECK:      Disassembly of section .R_386_GOTPC:
 // CHECK-NEXT: R_386_GOTPC:
-// CHECK-NEXT:   11014:  {{.*}} movl  $4156, %eax
+// CHECK-NEXT:   11014:  {{.*}} movl  $4188, %eax
 
 .section .dynamic_reloc, "ax", at progbits
  call bar
 // 0x11030 - (0x11019 + 5) = 18
 // CHECK:      Disassembly of section .dynamic_reloc:
 // CHECK-NEXT: .dynamic_reloc:
-// CHECK-NEXT:   11019:  e8 12 00 00 00 calll 18
+// CHECK-NEXT:   11019:  e8 22 00 00 00 calll 34
 
 .section .R_386_GOT32,"ax", at progbits
 .global R_386_GOT32




More information about the llvm-commits mailing list