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

Rafael Ávila de Espíndola via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 9 10:03:07 PST 2018


rafael added a comment.

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 @@
>   1. 73728 == 0x12000 == ADDR(.got)
>   2. CHECK:       _start:
>   3. CHECK-NEXT:   11001: 8b 05 {{.*}} movl 73728, %eax
>   4. CHECK-NEXT:   11007: 8b 1d {{.*}} movl 73728, %ebx +# CHECK-NEXT:   11001: 8b 05 {{.*}} movl 77824, %eax +# CHECK-NEXT:   11007: 8b 1d {{.*}} movl 77824, %ebx
>   5. CHECK-NEXT:   1100d: 8b 80 {{.*}} movl -4(%eax), %eax
>   6. CHECK-NEXT:   11013: 8b 83 {{.*}} movl -4(%ebx), %eax
>   7. CHECK: Sections:
>   8. CHECK:  Name Size     Address
>   9. CHECK:  .got 00000004 0000000000012000 +# CHECK:  .got 00000004 0000000000013000
>   10. RUN: not ld.lld %S/Inputs/i386-got32x-baseless.elf -o %t1 -pie 2>&1 | \
>   11. 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;


https://reviews.llvm.org/D44259





More information about the llvm-commits mailing list