[PATCH] D44259: [LLD][ELF] Use start of .got.plt as the location for _GLOBAL_OFFSET_TABLE_

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 9 10:02:56 PST 2018


LGTM

Peter Smith via Phabricator <reviews at reviews.llvm.org> writes:

> peter.smith updated this revision to Diff 137715.
> peter.smith added a comment.
>
> Thanks for the comment, and apologies for my misreading of the binutils source. I've updated the patch to keep Mips as it was previously.
>
>
> https://reviews.llvm.org/D44259
>
> Files:
>   ELF/Arch/Mips.cpp
>   ELF/Arch/PPC.cpp
>   ELF/Arch/X86.cpp
>   ELF/Arch/X86_64.cpp
>   ELF/SyntheticSections.cpp
>   ELF/SyntheticSections.h
>   ELF/Target.h
>   ELF/Writer.cpp
>   test/ELF/arm-got-relative.s
>   test/ELF/dynamic-got.s
>   test/ELF/global-offset-table-position-aarch64.s
>   test/ELF/global-offset-table-position-arm.s
>   test/ELF/global-offset-table-position-i386.s
>   test/ELF/global-offset-table-position.s
>   test/ELF/global_offset_table_shared.s
>   test/ELF/got32x-i386.s
>   test/ELF/i386-gotpc.s
>
> Index: test/ELF/i386-gotpc.s
> ===================================================================
> --- test/ELF/i386-gotpc.s
> +++ test/ELF/i386-gotpc.s
> @@ -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
> Index: test/ELF/got32x-i386.s
> ===================================================================
> --- test/ELF/got32x-i386.s
> +++ test/ELF/got32x-i386.s
> @@ -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
> Index: test/ELF/global_offset_table_shared.s
> ===================================================================
> --- test/ELF/global_offset_table_shared.s
> +++ test/ELF/global_offset_table_shared.s
> @@ -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
> Index: test/ELF/global-offset-table-position.s
> ===================================================================
> --- test/ELF/global-offset-table-position.s
> +++ test/ELF/global-offset-table-position.s
> @@ -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 @@
>  .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
> Index: test/ELF/global-offset-table-position-i386.s
> ===================================================================
> --- test/ELF/global-offset-table-position-i386.s
> +++ test/ELF/global-offset-table-position-i386.s
> @@ -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 @@
>  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
> Index: test/ELF/global-offset-table-position-arm.s
> ===================================================================
> --- test/ELF/global-offset-table-position-arm.s
> +++ test/ELF/global-offset-table-position-arm.s
> @@ -3,7 +3,8 @@
>  // RUN: llvm-readobj -t %t2 | FileCheck %s
>  // REQUIRES: arm
>  
> -// The ARM _GLOBAL_OFFSET_TABLE_ should be defined at the start of the .got
> +// The ARM _GLOBAL_OFFSET_TABLE_ should be defined at the start of the
> +// .got.plt section.
>  .globl  a
>  .type   a,%object
>  .comm   a,4,4
> @@ -25,11 +26,11 @@
>  .data
>  
>  // CHECK:     Name: _GLOBAL_OFFSET_TABLE_
> -// CHECK-NEXT:     Value: 0x3068
> +// 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
> Index: test/ELF/global-offset-table-position-aarch64.s
> ===================================================================
> --- test/ELF/global-offset-table-position-aarch64.s
> +++ test/ELF/global-offset-table-position-aarch64.s
> @@ -20,11 +20,11 @@
>  .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
> Index: test/ELF/dynamic-got.s
> ===================================================================
> --- test/ELF/dynamic-got.s
> +++ test/ELF/dynamic-got.s
> @@ -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:
> Index: test/ELF/arm-got-relative.s
> ===================================================================
> --- test/ELF/arm-got-relative.s
> +++ test/ELF/arm-got-relative.s
> @@ -28,26 +28,26 @@
>   bx lr
>  
>  // CHECK: Dynamic Relocations {
> -// CHECK-NEXT:  0x2048 R_ARM_GLOB_DAT function 0x0
> +// CHECK-NEXT:  0x3048 R_ARM_GLOB_DAT function 0x0
>  
>  // CHECK: Name: _GLOBAL_OFFSET_TABLE_
> -// CHECK-NEXT:    Value: 0x2048
> +// CHECK-NEXT:    Value: 0x2000
>  // CHECK-NEXT:    Size:
>  // CHECK-NEXT:    Binding: Local
>  // CHECK-NEXT:    Type: None
>  // CHECK-NEXT:    Other [
>  // CHECK-NEXT:      STV_HIDDEN
>  // CHECK-NEXT:    ]
> -// CHECK-NEXT:    Section: .got
> +// CHECK-NEXT:    Section: .got.plt
>  
>  // CODE: Disassembly of section .text:
>  // CODE-NEXT: _start:
>  // CODE-NEXT:    1000:        08 30 9f e5    ldr     r3, [pc, #8]
>  // CODE-NEXT:    1004:        08 20 9f e5    ldr     r2, [pc, #8]
>  // 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_ = 0x2048) - (0x1008 + 8) 0x1038
> -// CODE-NEXT:    1010:        38 10 00 00
> +// (_GLOBAL_OFFSET_TABLE_ = 0x2000) - (0x1008 + 8) = 0xff0
> +// CODE-NEXT:    1010:        f0 0f 00 00
>  // (Got(function) - GotBase = 0x0
>  // CODE-NEXT:    1014:        00 00 00 00
> Index: ELF/Writer.cpp
> ===================================================================
> --- ELF/Writer.cpp
> +++ ELF/Writer.cpp
> @@ -868,11 +868,12 @@
>  // 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;
>    }
>  
> Index: ELF/Target.h
> ===================================================================
> --- ELF/Target.h
> +++ ELF/Target.h
> @@ -71,9 +71,10 @@
>  
>    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.
> Index: ELF/SyntheticSections.h
> ===================================================================
> --- ELF/SyntheticSections.h
> +++ ELF/SyntheticSections.h
> @@ -269,7 +269,7 @@
>    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;
> Index: ELF/SyntheticSections.cpp
> ===================================================================
> --- ELF/SyntheticSections.cpp
> +++ ELF/SyntheticSections.cpp
> @@ -628,8 +628,9 @@
>  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) {
> @@ -900,6 +901,14 @@
>    }
>  }
>  
> +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: ELF/Arch/X86_64.cpp
> ===================================================================
> --- ELF/Arch/X86_64.cpp
> +++ ELF/Arch/X86_64.cpp
> @@ -51,7 +51,6 @@
>  } // 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: ELF/Arch/X86.cpp
> ===================================================================
> --- ELF/Arch/X86.cpp
> +++ ELF/Arch/X86.cpp
> @@ -46,7 +46,6 @@
>  } // namespace
>  
>  X86::X86() {
> -  GotBaseSymOff = -1;
>    CopyRel = R_386_COPY;
>    GotRel = R_386_GLOB_DAT;
>    PltRel = R_386_JUMP_SLOT;
> Index: ELF/Arch/PPC.cpp
> ===================================================================
> --- ELF/Arch/PPC.cpp
> +++ ELF/Arch/PPC.cpp
> @@ -21,13 +21,18 @@
>  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) {
> Index: ELF/Arch/Mips.cpp
> ===================================================================
> --- ELF/Arch/Mips.cpp
> +++ ELF/Arch/Mips.cpp
> @@ -50,6 +50,7 @@
>    DefaultMaxPageSize = 65536;
>    GotEntrySize = sizeof(typename ELFT::uint);
>    GotPltEntrySize = sizeof(typename ELFT::uint);
> +  GotBaseSymInGotPlt = false;
>    PltEntrySize = 16;
>    PltHeaderSize = 32;
>    CopyRel = R_MIPS_COPY;


More information about the llvm-commits mailing list