[lld] r327823 - [ELF] Recommit 327248 with Arm using the .got for _GLOBAL_OFFSET_TABLE_

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Sun Mar 18 23:52:52 PDT 2018


Author: psmith
Date: Sun Mar 18 23:52:51 2018
New Revision: 327823

URL: http://llvm.org/viewvc/llvm-project?rev=327823&view=rev
Log:
[ELF] Recommit 327248 with Arm using the .got for _GLOBAL_OFFSET_TABLE_

This is the same as 327248 except Arm defining _GLOBAL_OFFSET_TABLE_ to
be the base of the .got section as some existing code is relying upon it.

For most Targets the _GLOBAL_OFFSET_TABLE_ symbol is expected to be at
the start of the .got.plt section so that _GLOBAL_OFFSET_TABLE_[0] =
reserved value that is by convention the address of the dynamic section.
Previously we had defined _GLOBAL_OFFSET_TABLE_ as either the start or end
of the .got section with the intention that the .got.plt section would
follow the .got. However this does not always hold with the current
default section ordering so _GLOBAL_OFFSET_TABLE_[0] may not be consistent
with the reserved first entry of the .got.plt.

X86, X86_64 and AArch64 will use the .got.plt. Arm, Mips and Power use .got

Fixes PR36555

Differential Revision: https://reviews.llvm.org/D44259


Modified:
    lld/trunk/ELF/Arch/ARM.cpp
    lld/trunk/ELF/Arch/Mips.cpp
    lld/trunk/ELF/Arch/PPC.cpp
    lld/trunk/ELF/Arch/X86.cpp
    lld/trunk/ELF/Arch/X86_64.cpp
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/SyntheticSections.h
    lld/trunk/ELF/Target.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/dynamic-got.s
    lld/trunk/test/ELF/global-offset-table-position-aarch64.s
    lld/trunk/test/ELF/global-offset-table-position-i386.s
    lld/trunk/test/ELF/global-offset-table-position.s
    lld/trunk/test/ELF/global_offset_table_shared.s
    lld/trunk/test/ELF/got32x-i386.s
    lld/trunk/test/ELF/i386-gotpc.s

Modified: lld/trunk/ELF/Arch/ARM.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/ARM.cpp?rev=327823&r1=327822&r2=327823&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/ARM.cpp (original)
+++ lld/trunk/ELF/Arch/ARM.cpp Sun Mar 18 23:52:51 2018
@@ -55,6 +55,7 @@ ARM::ARM() {
   TlsGotRel = R_ARM_TLS_TPOFF32;
   TlsModuleIndexRel = R_ARM_TLS_DTPMOD32;
   TlsOffsetRel = R_ARM_TLS_DTPOFF32;
+  GotBaseSymInGotPlt = false;
   GotEntrySize = 4;
   GotPltEntrySize = 4;
   PltEntrySize = 16;

Modified: lld/trunk/ELF/Arch/Mips.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/Mips.cpp?rev=327823&r1=327822&r2=327823&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/Mips.cpp (original)
+++ lld/trunk/ELF/Arch/Mips.cpp Sun Mar 18 23:52:51 2018
@@ -50,6 +50,7 @@ template <class ELFT> MIPS<ELFT>::MIPS()
   DefaultMaxPageSize = 65536;
   GotEntrySize = sizeof(typename ELFT::uint);
   GotPltEntrySize = sizeof(typename ELFT::uint);
+  GotBaseSymInGotPlt = false;
   PltEntrySize = 16;
   PltHeaderSize = 32;
   CopyRel = R_MIPS_COPY;

Modified: lld/trunk/ELF/Arch/PPC.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/PPC.cpp?rev=327823&r1=327822&r2=327823&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/PPC.cpp (original)
+++ lld/trunk/ELF/Arch/PPC.cpp Sun Mar 18 23:52:51 2018
@@ -21,13 +21,18 @@ using namespace lld::elf;
 namespace {
 class PPC final : public TargetInfo {
 public:
-  PPC() { GotBaseSymOff = 0x8000; }
+  PPC();
   void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
   RelExpr getRelExpr(RelType Type, const Symbol &S,
                      const uint8_t *Loc) const override;
 };
 } // namespace
 
+PPC::PPC() {
+  GotBaseSymOff = 0x8000;
+  GotBaseSymInGotPlt = false;
+}
+
 RelExpr PPC::getRelExpr(RelType Type, const Symbol &S,
                         const uint8_t *Loc) const {
   switch (Type) {

Modified: lld/trunk/ELF/Arch/X86.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/X86.cpp?rev=327823&r1=327822&r2=327823&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/X86.cpp (original)
+++ lld/trunk/ELF/Arch/X86.cpp Sun Mar 18 23:52:51 2018
@@ -46,7 +46,6 @@ public:
 } // namespace
 
 X86::X86() {
-  GotBaseSymOff = -1;
   CopyRel = R_386_COPY;
   GotRel = R_386_GLOB_DAT;
   PltRel = R_386_JUMP_SLOT;

Modified: lld/trunk/ELF/Arch/X86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/X86_64.cpp?rev=327823&r1=327822&r2=327823&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/X86_64.cpp (original)
+++ lld/trunk/ELF/Arch/X86_64.cpp Sun Mar 18 23:52:51 2018
@@ -51,7 +51,6 @@ private:
 } // namespace
 
 template <class ELFT> X86_64<ELFT>::X86_64() {
-  GotBaseSymOff = -1;
   CopyRel = R_X86_64_COPY;
   GotRel = R_X86_64_GLOB_DAT;
   PltRel = R_X86_64_JUMP_SLOT;

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=327823&r1=327822&r2=327823&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Sun Mar 18 23:52:51 2018
@@ -626,8 +626,9 @@ void GotSection::finalizeContents() { Si
 bool GotSection::empty() const {
   // We need to emit a GOT even if it's empty if there's a relocation that is
   // relative to GOT(such as GOTOFFREL) or there's a symbol that points to a GOT
-  // (i.e. _GLOBAL_OFFSET_TABLE_).
-  return NumEntries == 0 && !HasGotOffRel && !ElfSym::GlobalOffsetTable;
+  // (i.e. _GLOBAL_OFFSET_TABLE_) that the target defines relative to the .got.
+  return NumEntries == 0 && !HasGotOffRel &&
+         !(ElfSym::GlobalOffsetTable && !Target->GotBaseSymInGotPlt);
 }
 
 void GotSection::writeTo(uint8_t *Buf) {
@@ -898,6 +899,14 @@ void GotPltSection::writeTo(uint8_t *Buf
   }
 }
 
+bool GotPltSection::empty() const {
+  // We need to emit a GOT.PLT even if it's empty if there's a symbol that
+  // references the _GLOBAL_OFFSET_TABLE_ and the Target defines the symbol
+  // relative to the .got.plt section.
+  return Entries.empty() &&
+         !(ElfSym::GlobalOffsetTable && Target->GotBaseSymInGotPlt);
+}
+
 // On ARM the IgotPltSection is part of the GotSection, on other Targets it is
 // part of the .got.plt
 IgotPltSection::IgotPltSection()

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=327823&r1=327822&r2=327823&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Sun Mar 18 23:52:51 2018
@@ -270,7 +270,7 @@ public:
   void addEntry(Symbol &Sym);
   size_t getSize() const override;
   void writeTo(uint8_t *Buf) override;
-  bool empty() const override { return Entries.empty(); }
+  bool empty() const override;
 
 private:
   std::vector<const Symbol *> Entries;

Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=327823&r1=327822&r2=327823&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Sun Mar 18 23:52:51 2018
@@ -75,9 +75,10 @@ public:
 
   uint64_t getImageBase();
 
-  // Offset of _GLOBAL_OFFSET_TABLE_ from base of .got section. Use -1 for
-  // end of .got
+  // Offset of _GLOBAL_OFFSET_TABLE_ from base of .got or .got.plt section.
   uint64_t GotBaseSymOff = 0;
+  // True if _GLOBAL_OFFSET_TABLE_ is relative to .got.plt, false if .got.
+  bool GotBaseSymInGotPlt = true;
 
   // On systems with range extensions we place collections of Thunks at
   // regular spacings that enable the majority of branches reach the Thunks.

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=327823&r1=327822&r2=327823&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Sun Mar 18 23:52:51 2018
@@ -869,11 +869,12 @@ void Writer<ELFT>::forEachRelSec(std::fu
 // defining these symbols explicitly in the linker script.
 template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
   if (ElfSym::GlobalOffsetTable) {
-    // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
-    // be at some offset from the base of the .got section, usually 0 or the end
-    // of the .got
-    InputSection *GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot)
-                                            : cast<InputSection>(InX::Got);
+    // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention usually
+    // to the start of the .got or .got.plt section.
+    InputSection *GotSection = InX::GotPlt;
+    if (!Target->GotBaseSymInGotPlt)
+      GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot)
+                                : cast<InputSection>(InX::Got);
     ElfSym::GlobalOffsetTable->Section = GotSection;
   }
 

Modified: lld/trunk/test/ELF/dynamic-got.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/dynamic-got.s?rev=327823&r1=327822&r2=327823&view=diff
==============================================================================
--- lld/trunk/test/ELF/dynamic-got.s (original)
+++ lld/trunk/test/ELF/dynamic-got.s Sun Mar 18 23:52:51 2018
@@ -3,6 +3,23 @@
 // RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared
 // RUN: llvm-readobj -s -l -section-data -r %t.so | FileCheck %s
 
+// 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:
+// CHECK-NEXT:     Offset:
+// CHECK-NEXT:     Size:
+// CHECK-NEXT:     Link:
+// CHECK-NEXT:     Info:
+// CHECK-NEXT:     AddressAlignment:
+// CHECK-NEXT:     EntrySize:
+// CHECK-NEXT:     SectionData (
+// CHECK-NEXT:       0000: 00300000 00000000 00000000
+// CHECK-NEXT:     )
+
 // CHECK:      Name: .got
 // CHECK-NEXT: Type: SHT_PROGBITS
 // CHECK-NEXT: Flags [
@@ -17,19 +34,19 @@
 // CHECK-NEXT: AddressAlignment:
 // CHECK-NEXT: EntrySize:
 // CHECK-NEXT: SectionData (
-// CHECK-NEXT:   0000: 00200000                |
+// CHECK-NEXT:   0000: 00300000
 // CHECK-NEXT: )
 
 // CHECK:      Relocations [
 // CHECK-NEXT:   Section ({{.*}}) .rel.dyn {
-// CHECK-NEXT:     0x2050 R_386_RELATIVE - 0x0
+// CHECK-NEXT:     0x3050 R_386_RELATIVE - 0x0
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]
 
 // CHECK:      Type: PT_DYNAMIC
-// CHECK-NEXT: Offset: 0x2000
-// CHECK-NEXT: VirtualAddress: 0x2000
-// CHECK-NEXT: PhysicalAddress: 0x2000
+// CHECK-NEXT: Offset: 0x3000
+// CHECK-NEXT: VirtualAddress: 0x3000
+// CHECK-NEXT: PhysicalAddress: 0x3000
 
         calll   .L0$pb
 .L0$pb:

Modified: lld/trunk/test/ELF/global-offset-table-position-aarch64.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/global-offset-table-position-aarch64.s?rev=327823&r1=327822&r2=327823&view=diff
==============================================================================
--- lld/trunk/test/ELF/global-offset-table-position-aarch64.s (original)
+++ lld/trunk/test/ELF/global-offset-table-position-aarch64.s Sun Mar 18 23:52:51 2018
@@ -20,11 +20,11 @@ _start:
 .long _GLOBAL_OFFSET_TABLE_ - .
 
 // CHECK: Name: _GLOBAL_OFFSET_TABLE_ (11)
-// CHECK-NEXT:     Value: 0x30090
+// CHECK-NEXT:     Value: 0x20008
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Local (0x0)
 // CHECK-NEXT:     Type: None (0x0)
 // CHECK-NEXT:     Other [ (0x2)
 // CHECK-NEXT:       STV_HIDDEN (0x2)
 // CHECK-NEXT:     ]
-// CHECK-NEXT:     Section: .got
+// CHECK-NEXT:     Section: .got.plt

Modified: lld/trunk/test/ELF/global-offset-table-position-i386.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/global-offset-table-position-i386.s?rev=327823&r1=327822&r2=327823&view=diff
==============================================================================
--- lld/trunk/test/ELF/global-offset-table-position-i386.s (original)
+++ lld/trunk/test/ELF/global-offset-table-position-i386.s Sun Mar 18 23:52:51 2018
@@ -3,7 +3,8 @@
 // RUN: llvm-readobj -t %t2 | FileCheck %s
 // REQUIRES: x86
 
-// The X86 _GLOBAL_OFFSET_TABLE_ is defined at the end of the .got section.
+// The X86 _GLOBAL_OFFSET_TABLE_ is defined at the start of the .got.plt
+// section.
 .globl  a
 .type   a, at object
 .comm   a,4,4
@@ -21,11 +22,11 @@ addl    $_GLOBAL_OFFSET_TABLE_, %eax
 calll   f at PLT
 
 // CHECK:     Name: _GLOBAL_OFFSET_TABLE_ (1)
-// CHECK-NEXT:     Value: 0x306C
+// CHECK-NEXT:     Value: 0x2000
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Local (0x0)
 // CHECK-NEXT:     Type: None (0x0)
 // CHECK-NEXT:     Other [ (0x2)
 // CHECK-NEXT:       STV_HIDDEN (0x2)
 // CHECK-NEXT:     ]
-// CHECK-NEXT:     Section: .got (0xA)
+// CHECK-NEXT:     Section: .got.plt

Modified: lld/trunk/test/ELF/global-offset-table-position.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/global-offset-table-position.s?rev=327823&r1=327822&r2=327823&view=diff
==============================================================================
--- lld/trunk/test/ELF/global-offset-table-position.s (original)
+++ lld/trunk/test/ELF/global-offset-table-position.s Sun Mar 18 23:52:51 2018
@@ -3,7 +3,8 @@
 // RUN: llvm-readobj -t %t2 | FileCheck %s
 // REQUIRES: x86
 
-// The X86_64 _GLOBAL_OFFSET_TABLE_ is defined at the end of the .got section.
+// The X86_64 _GLOBAL_OFFSET_TABLE_ is defined at the start of the .got.plt
+// section.
 .globl  a
 .type   a, at object
 .comm   a,4,4
@@ -21,11 +22,11 @@ callq	f at PLT
 .long _GLOBAL_OFFSET_TABLE_ - .
 
 // CHECK:     Name: _GLOBAL_OFFSET_TABLE_
-// CHECK-NEXT:     Value: 0x30D8
+// CHECK-NEXT:     Value: 0x2008
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Local
 // CHECK-NEXT:     Type: None (0x0)
 // CHECK-NEXT:     Other [
 // CHECK-NEXT:       STV_HIDDEN
 // CHECK-NEXT:     ]
-// CHECK-NEXT:     Section: .got
+// CHECK-NEXT:     Section: .got.plt

Modified: lld/trunk/test/ELF/global_offset_table_shared.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/global_offset_table_shared.s?rev=327823&r1=327822&r2=327823&view=diff
==============================================================================
--- lld/trunk/test/ELF/global_offset_table_shared.s (original)
+++ lld/trunk/test/ELF/global_offset_table_shared.s Sun Mar 18 23:52:51 2018
@@ -4,11 +4,11 @@
 .long _GLOBAL_OFFSET_TABLE_ - .
 
 // CHECK:      Name: _GLOBAL_OFFSET_TABLE_
-// CHECK-NEXT: Value: 0x2060
+// CHECK-NEXT: Value: 0x2000
 // CHECK-NEXT: Size: 0
 // CHECK-NEXT: Binding: Local
 // CHECK-NEXT: Type: None
 // CHECK-NEXT: Other [ (0x2)
 // CHECK-NEXT: STV_HIDDEN (0x2)
 // CHECK-NEXT:    ]
-// CHECK-NEXT: Section: .got
+// CHECK-NEXT: Section: .got.plt

Modified: lld/trunk/test/ELF/got32x-i386.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/got32x-i386.s?rev=327823&r1=327822&r2=327823&view=diff
==============================================================================
--- lld/trunk/test/ELF/got32x-i386.s (original)
+++ lld/trunk/test/ELF/got32x-i386.s Sun Mar 18 23:52:51 2018
@@ -33,13 +33,13 @@
 
 ## 73728 == 0x12000 == ADDR(.got)
 # CHECK:       _start:
-# CHECK-NEXT:   11001: 8b 05 {{.*}} movl 73728, %eax
-# CHECK-NEXT:   11007: 8b 1d {{.*}} movl 73728, %ebx
+# CHECK-NEXT:   11001: 8b 05 {{.*}} movl 77824, %eax
+# CHECK-NEXT:   11007: 8b 1d {{.*}} movl 77824, %ebx
 # CHECK-NEXT:   1100d: 8b 80 {{.*}} movl -4(%eax), %eax
 # CHECK-NEXT:   11013: 8b 83 {{.*}} movl -4(%ebx), %eax
 # CHECK: Sections:
 # CHECK:  Name Size     Address
-# CHECK:  .got 00000004 0000000000012000
+# CHECK:  .got 00000004 0000000000013000
 
 # RUN: not ld.lld %S/Inputs/i386-got32x-baseless.elf -o %t1 -pie 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=ERR

Modified: lld/trunk/test/ELF/i386-gotpc.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/i386-gotpc.s?rev=327823&r1=327822&r2=327823&view=diff
==============================================================================
--- lld/trunk/test/ELF/i386-gotpc.s (original)
+++ lld/trunk/test/ELF/i386-gotpc.s Sun Mar 18 23:52:51 2018
@@ -6,15 +6,23 @@
 
 movl $_GLOBAL_OFFSET_TABLE_, %eax
 
+// 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: 0x2000
+
 // CHECK:      Name: .got
 // CHECK-NEXT: Type: SHT_PROGBITS
 // CHECK-NEXT: Flags [
 // CHECK-NEXT:   SHF_ALLOC
 // CHECK-NEXT:   SHF_WRITE
 // CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x2030
+// CHECK-NEXT: Address: 0x3030
 
 // DISASM:      Disassembly of section .text:
 // DISASM-NEXT: .text:
-// DISASM-NEXT:    1000: {{.*}}         movl    $4144, %eax
-//                                              0x2030 - 0x1000 = 4144
+// DISASM-NEXT:    1000: {{.*}}         movl    $8240, %eax
+//                                              0x3030 - 0x1000 = 0x2030




More information about the llvm-commits mailing list