Revert r327248, "For most Targets the _GLOBAL_OFFSET_TABLE_ symbol is expected to...
authorPeter Collingbourne <peter@pcc.me.uk>
Fri, 16 Mar 2018 01:01:44 +0000 (01:01 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Fri, 16 Mar 2018 01:01:44 +0000 (01:01 +0000)
This change broke ARM code that expects to be able to add
_GLOBAL_OFFSET_TABLE_ to the result of an R_ARM_REL32.

I will provide a reproducer on llvm-commits.

llvm-svn: 327688

17 files changed:
lld/ELF/Arch/Mips.cpp
lld/ELF/Arch/PPC.cpp
lld/ELF/Arch/X86.cpp
lld/ELF/Arch/X86_64.cpp
lld/ELF/SyntheticSections.cpp
lld/ELF/SyntheticSections.h
lld/ELF/Target.h
lld/ELF/Writer.cpp
lld/test/ELF/arm-got-relative.s
lld/test/ELF/dynamic-got.s
lld/test/ELF/global-offset-table-position-aarch64.s
lld/test/ELF/global-offset-table-position-arm.s
lld/test/ELF/global-offset-table-position-i386.s
lld/test/ELF/global-offset-table-position.s
lld/test/ELF/global_offset_table_shared.s
lld/test/ELF/got32x-i386.s
lld/test/ELF/i386-gotpc.s

index d8631b5..fcf5aff 100644 (file)
@@ -50,7 +50,6 @@ 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;
index 20cae0e..6af0df3 100644 (file)
@@ -21,18 +21,13 @@ using namespace lld::elf;
 namespace {
 class PPC final : public TargetInfo {
 public:
-  PPC();
+  PPC() { GotBaseSymOff = 0x8000; }
   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) {
index e638feb..bbaa341 100644 (file)
@@ -46,6 +46,7 @@ public:
 } // namespace
 
 X86::X86() {
+  GotBaseSymOff = -1;
   CopyRel = R_386_COPY;
   GotRel = R_386_GLOB_DAT;
   PltRel = R_386_JUMP_SLOT;
index 512b1ff..f6f5038 100644 (file)
@@ -51,6 +51,7 @@ 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;
index ef7944c..f5fa073 100644 (file)
@@ -626,9 +626,8 @@ void GotSection::finalizeContents() { Size = NumEntries * Config->Wordsize; }
 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_) that the target defines relative to the .got.
-  return NumEntries == 0 && !HasGotOffRel &&
-         !(ElfSym::GlobalOffsetTable && !Target->GotBaseSymInGotPlt);
+  // (i.e. _GLOBAL_OFFSET_TABLE_).
+  return NumEntries == 0 && !HasGotOffRel && !ElfSym::GlobalOffsetTable;
 }
 
 void GotSection::writeTo(uint8_t *Buf) {
@@ -899,14 +898,6 @@ 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()
index 23deb03..7f23d82 100644 (file)
@@ -270,7 +270,7 @@ public:
   void addEntry(Symbol &Sym);
   size_t getSize() const override;
   void writeTo(uint8_t *Buf) override;
-  bool empty() const override;
+  bool empty() const override { return Entries.empty(); }
 
 private:
   std::vector<const Symbol *> Entries;
index b097009..e29c9f4 100644 (file)
@@ -75,10 +75,9 @@ public:
 
   uint64_t getImageBase();
 
-  // Offset of _GLOBAL_OFFSET_TABLE_ from base of .got or .got.plt section.
+  // Offset of _GLOBAL_OFFSET_TABLE_ from base of .got section. Use -1 for
+  // end of .got
   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.
index 2490d1d..a088cc5 100644 (file)
@@ -869,12 +869,11 @@ void Writer<ELFT>::forEachRelSec(std::function<void(InputSectionBase &)> Fn) {
 // 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 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);
+    // 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);
     ElfSym::GlobalOffsetTable->Section = GotSection;
   }
 
index c64969d..cf8b0a6 100644 (file)
@@ -28,17 +28,17 @@ function:
  bx lr
 
 // CHECK: Dynamic Relocations {
-// CHECK-NEXT:  0x3048 R_ARM_GLOB_DAT function 0x0
+// CHECK-NEXT:  0x2048 R_ARM_GLOB_DAT function 0x0
 
 // CHECK: Name: _GLOBAL_OFFSET_TABLE_
-// CHECK-NEXT:    Value: 0x2000
+// CHECK-NEXT:    Value: 0x2048
 // CHECK-NEXT:    Size:
 // CHECK-NEXT:    Binding: Local
 // CHECK-NEXT:    Type: None
 // CHECK-NEXT:    Other [
 // CHECK-NEXT:      STV_HIDDEN
 // CHECK-NEXT:    ]
-// CHECK-NEXT:    Section: .got.plt
+// CHECK-NEXT:    Section: .got
 
 // CODE: Disassembly of section .text:
 // CODE-NEXT: _start:
@@ -47,7 +47,7 @@ function:
 // CODE-NEXT:    1008:        03 00 8f e0    add     r0, pc, r3
 // CODE-NEXT:    100c:        1e ff 2f e1    bx      lr
 // CODE:$d.1:
-// (_GLOBAL_OFFSET_TABLE_ = 0x2000) - (0x1008 + 8) = 0xff0
-// CODE-NEXT:    1010:        f0 0f 00 00
+// (_GLOBAL_OFFSET_TABLE_ = 0x2048) - (0x1008 + 8) 0x1038
+// CODE-NEXT:    1010:        38 10 00 00
 // (Got(function) - GotBase = 0x0
 // CODE-NEXT:    1014:        00 00 00 00
index 844e4f4..385394b 100644 (file)
@@ -3,23 +3,6 @@
 // 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 [
 // CHECK-NEXT: AddressAlignment:
 // CHECK-NEXT: EntrySize:
 // CHECK-NEXT: SectionData (
-// CHECK-NEXT:   0000: 00300000
+// CHECK-NEXT:   0000: 00200000                |
 // CHECK-NEXT: )
 
 // CHECK:      Relocations [
 // CHECK-NEXT:   Section ({{.*}}) .rel.dyn {
-// CHECK-NEXT:     0x3050 R_386_RELATIVE - 0x0
+// CHECK-NEXT:     0x2050 R_386_RELATIVE - 0x0
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]
 
 // CHECK:      Type: PT_DYNAMIC
-// CHECK-NEXT: Offset: 0x3000
-// CHECK-NEXT: VirtualAddress: 0x3000
-// CHECK-NEXT: PhysicalAddress: 0x3000
+// CHECK-NEXT: Offset: 0x2000
+// CHECK-NEXT: VirtualAddress: 0x2000
+// CHECK-NEXT: PhysicalAddress: 0x2000
 
         calll   .L0$pb
 .L0$pb:
index 8e26913..68bc4a4 100644 (file)
@@ -20,11 +20,11 @@ _start:
 .long _GLOBAL_OFFSET_TABLE_ - .
 
 // CHECK: Name: _GLOBAL_OFFSET_TABLE_ (11)
-// CHECK-NEXT:     Value: 0x20008
+// CHECK-NEXT:     Value: 0x30090
 // 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.plt
+// CHECK-NEXT:     Section: .got
index 0538129..19619b2 100644 (file)
@@ -3,8 +3,7 @@
 // RUN: llvm-readobj -t %t2 | FileCheck %s
 // REQUIRES: arm
 
-// The ARM _GLOBAL_OFFSET_TABLE_ should be defined at the start of the
-// .got.plt section.
+// The ARM _GLOBAL_OFFSET_TABLE_ should be defined at the start of the .got
 .globl  a
 .type   a,%object
 .comm   a,4,4
@@ -26,11 +25,11 @@ _start:
 .data
 
 // CHECK:     Name: _GLOBAL_OFFSET_TABLE_
-// CHECK-NEXT:     Value: 0x2000
+// CHECK-NEXT:     Value: 0x3068
 // 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.plt
+// CHECK-NEXT:     Section: .got
index 8d50b49..9f778e1 100644 (file)
@@ -3,8 +3,7 @@
 // RUN: llvm-readobj -t %t2 | FileCheck %s
 // REQUIRES: x86
 
-// The X86 _GLOBAL_OFFSET_TABLE_ is defined at the start of the .got.plt
-// section.
+// The X86 _GLOBAL_OFFSET_TABLE_ is defined at the end of the .got section.
 .globl  a
 .type   a,@object
 .comm   a,4,4
@@ -22,11 +21,11 @@ addl    $_GLOBAL_OFFSET_TABLE_, %eax
 calll   f@PLT
 
 // CHECK:     Name: _GLOBAL_OFFSET_TABLE_ (1)
-// CHECK-NEXT:     Value: 0x2000
+// CHECK-NEXT:     Value: 0x306C
 // 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.plt
+// CHECK-NEXT:     Section: .got (0xA)
index 57fe6c8..f1195b2 100644 (file)
@@ -3,8 +3,7 @@
 // RUN: llvm-readobj -t %t2 | FileCheck %s
 // REQUIRES: x86
 
-// The X86_64 _GLOBAL_OFFSET_TABLE_ is defined at the start of the .got.plt
-// section.
+// The X86_64 _GLOBAL_OFFSET_TABLE_ is defined at the end of the .got section.
 .globl  a
 .type   a,@object
 .comm   a,4,4
@@ -22,11 +21,11 @@ callq       f@PLT
 .long _GLOBAL_OFFSET_TABLE_ - .
 
 // CHECK:     Name: _GLOBAL_OFFSET_TABLE_
-// CHECK-NEXT:     Value: 0x2008
+// CHECK-NEXT:     Value: 0x30D8
 // 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.plt
+// CHECK-NEXT:     Section: .got
index 06bd7b3..03af02e 100644 (file)
@@ -4,11 +4,11 @@
 .long _GLOBAL_OFFSET_TABLE_ - .
 
 // CHECK:      Name: _GLOBAL_OFFSET_TABLE_
-// CHECK-NEXT: Value: 0x2000
+// CHECK-NEXT: Value: 0x2060
 // 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.plt
+// CHECK-NEXT: Section: .got
index 610051e..dd0b895 100644 (file)
 
 ## 73728 == 0x12000 == ADDR(.got)
 # CHECK:       _start:
-# CHECK-NEXT:   11001: 8b 05 {{.*}} movl 77824, %eax
-# CHECK-NEXT:   11007: 8b 1d {{.*}} movl 77824, %ebx
+# CHECK-NEXT:   11001: 8b 05 {{.*}} movl 73728, %eax
+# CHECK-NEXT:   11007: 8b 1d {{.*}} movl 73728, %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 0000000000013000
+# CHECK:  .got 00000004 0000000000012000
 
 # RUN: not ld.lld %S/Inputs/i386-got32x-baseless.elf -o %t1 -pie 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=ERR
index af8380b..d2c5ef3 100644 (file)
@@ -6,23 +6,15 @@
 
 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: 0x3030
+// CHECK-NEXT: Address: 0x2030
 
 // DISASM:      Disassembly of section .text:
 // DISASM-NEXT: .text:
-// DISASM-NEXT:    1000: {{.*}}         movl    $8240, %eax
-//                                              0x3030 - 0x1000 = 0x2030
+// DISASM-NEXT:    1000: {{.*}}         movl    $4144, %eax
+//                                              0x2030 - 0x1000 = 4144