From 520ed3a621f4fa9a67a66039996657ba5dc71180 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 27 Apr 2016 12:21:27 +0000 Subject: [PATCH] Create a .got when PPC64 uses a TOC. This simplifies the logic for computing the value of the toc base. llvm-svn: 267701 --- lld/ELF/Target.cpp | 11 +++---- lld/ELF/Writer.cpp | 2 +- lld/test/ELF/basic64be.s | 76 +++++++++++++++++++++++++++++++-------------- lld/test/ELF/ppc64-relocs.s | 4 +-- 4 files changed, 60 insertions(+), 33 deletions(-) diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index dbc164a..1d1bb35 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -823,14 +823,11 @@ PPC64TargetInfo::PPC64TargetInfo() { } uint64_t getPPC64TocBase() { - // The TOC consists of sections .got, .toc, .tocbss, .plt in that - // order. The TOC starts where the first of these sections starts. - - // FIXME: This obviously does not do the right thing when there is no .got - // section, but there is a .toc or .tocbss section. + // The TOC consists of sections .got, .toc, .tocbss, .plt in that order. The + // TOC starts where the first of these sections starts. We always create a + // .got when we see a relocation that uses it, so for us the start is always + // the .got. uint64_t TocVA = Out::Got->getVA(); - if (!TocVA) - TocVA = Out::Plt->getVA(); // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000 // thus permitting a full 64 Kbytes segment. Note that the glibc startup diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 553057f..a7d6719 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -538,7 +538,7 @@ void Writer::scanRelocs(InputSectionBase &C, ArrayRef Rels) { // This relocation does not require got entry, but it is relative to got and // needs it to be created. Here we request for that. - if (Expr == R_GOTONLY_PC || Expr == R_GOTREL) + if (Expr == R_GOTONLY_PC || Expr == R_GOTREL || Expr == R_PPC_TOC) HasGotOffRel = true; uintX_t Addend = getAddend(RI); diff --git a/lld/test/ELF/basic64be.s b/lld/test/ELF/basic64be.s index 32d8974..fb0bf7b 100644 --- a/lld/test/ELF/basic64be.s +++ b/lld/test/ELF/basic64be.s @@ -43,10 +43,10 @@ _start: # CHECK-NEXT: ] # CHECK-NEXT: HeaderSize: 64 # CHECK-NEXT: ProgramHeaderEntrySize: 56 -# CHECK-NEXT: ProgramHeaderCount: 5 +# CHECK-NEXT: ProgramHeaderCount: 6 # CHECK-NEXT: SectionHeaderEntrySize: 64 -# CHECK-NEXT: SectionHeaderCount: 8 -# CHECK-NEXT: StringTableSectionIndex: 6 +# CHECK-NEXT: SectionHeaderCount: 9 +# CHECK-NEXT: StringTableSectionIndex: 7 # CHECK-NEXT: } # CHECK-NEXT: Sections [ # CHECK-NEXT: Section { @@ -85,6 +85,24 @@ _start: # CHECK-NEXT: } # CHECK-NEXT: Section { # CHECK-NEXT: Index: 2 +# CHECK-NEXT: Name: .got +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x10020000 +# CHECK-NEXT: Offset: 0x20000 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 8 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: SectionData ( +# CHECK-NEXT: ) +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 3 # CHECK-NEXT: Name: .toc # CHECK-NEXT: Type: SHT_PROGBITS (0x1) # CHECK-NEXT: Flags [ (0x3) @@ -104,7 +122,7 @@ _start: # CHECK-NEXT: ) # CHECK-NEXT: } # CHECK-NEXT: Section { -# CHECK-NEXT: Index: 3 +# CHECK-NEXT: Index: 4 # CHECK-NEXT: Name: .toc1 # CHECK-NEXT: Type: SHT_PROGBITS (0x1) # CHECK-NEXT: Flags [ (0x3) @@ -124,7 +142,7 @@ _start: # CHECK-NEXT: ) # CHECK-NEXT: } # CHECK-NEXT: Section { -# CHECK-NEXT: Index: 4 +# CHECK-NEXT: Index: 5 # CHECK-NEXT: Name: .opd # CHECK-NEXT: Type: SHT_PROGBITS (0x1) # CHECK-NEXT: Flags [ (0x3) @@ -139,12 +157,12 @@ _start: # CHECK-NEXT: AddressAlignment: 1 # CHECK-NEXT: EntrySize: 0 # CHECK-NEXT: SectionData ( -# CHECK-NEXT: 0000: 00000000 10010000 00000000 00008000 |................| -# CHECK-NEXT: 0010: 00000000 00000000 |........| +# CHECK-NEXT: 0000: 00000000 10010000 00000000 10028000 |................| +# CHECK-NEXT: 0010: 00000000 00000000 |........| # CHECK-NEXT: ) # CHECK-NEXT: } # CHECK-NEXT: Section { -# CHECK-NEXT: Index: 5 +# CHECK-NEXT: Index: 6 # CHECK-NEXT: Name: .symtab # CHECK-NEXT: Type: SHT_SYMTAB (0x2) # CHECK-NEXT: Flags [ (0x0) @@ -152,7 +170,7 @@ _start: # CHECK-NEXT: Address: 0x0 # CHECK-NEXT: Offset: 0x20058 # CHECK-NEXT: Size: 48 -# CHECK-NEXT: Link: 7 +# CHECK-NEXT: Link: 8 # CHECK-NEXT: Info: 1 # CHECK-NEXT: AddressAlignment: 8 # CHECK-NEXT: EntrySize: 24 @@ -160,14 +178,14 @@ _start: # CHECK: ) # CHECK-NEXT: } # CHECK-NEXT: Section { -# CHECK-NEXT: Index: 6 +# CHECK-NEXT: Index: 7 # CHECK-NEXT: Name: .shstrtab -# CHECK-NEXT: Type: SHT_STRTAB (0x3) -# CHECK-NEXT: Flags [ (0x0) +# CHECK-NEXT: Type: SHT_STRTAB +# CHECK-NEXT: Flags [ # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 # CHECK-NEXT: Offset: 0x20088 -# CHECK-NEXT: Size: 49 +# CHECK-NEXT: Size: 54 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 # CHECK-NEXT: AddressAlignment: 1 @@ -176,13 +194,13 @@ _start: # CHECK: ) # CHECK-NEXT: } # CHECK-NEXT: Section { -# CHECK-NEXT: Index: 7 -# CHECK-NEXT: Name: .strtab (41) -# CHECK-NEXT: Type: SHT_STRTAB (0x3) +# CHECK-NEXT: Index: 8 +# CHECK-NEXT: Name: .strtab +# CHECK-NEXT: Type: SHT_STRTAB # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x200B9 +# CHECK-NEXT: Offset: 0x200BE # CHECK-NEXT: Size: 8 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 @@ -199,10 +217,10 @@ _start: # CHECK-NEXT: Offset: 0x40 # CHECK-NEXT: VirtualAddress: 0x10000040 # CHECK-NEXT: PhysicalAddress: 0x10000040 -# CHECK-NEXT: FileSize: 280 -# CHECK-NEXT: MemSize: 280 -# CHECK-NEXT: Flags [ (0x4) -# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: FileSize: 336 +# CHECK-NEXT: MemSize: 336 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R # CHECK-NEXT: ] # CHECK-NEXT: Alignment: 8 # CHECK-NEXT: } @@ -211,8 +229,8 @@ _start: # CHECK-NEXT: Offset: 0x0 # CHECK-NEXT: VirtualAddress: 0x10000000 # CHECK-NEXT: PhysicalAddress: 0x10000000 -# CHECK-NEXT: FileSize: 344 -# CHECK-NEXT: MemSize: 344 +# CHECK-NEXT: FileSize: 400 +# CHECK-NEXT: MemSize: 400 # CHECK-NEXT: Flags [ # CHECK-NEXT: PF_R # CHECK-NEXT: ] @@ -245,6 +263,18 @@ _start: # CHECK-NEXT: Alignment: 65536 # CHECK-NEXT: } # CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_GNU_RELRO +# CHECK-NEXT: Offset: 0x20000 +# CHECK-NEXT: VirtualAddress: 0x10020000 +# CHECK-NEXT: PhysicalAddress: 0x10020000 +# CHECK-NEXT: FileSize: 0 +# CHECK-NEXT: MemSize: 0 +# CHECK-NEXT: Flags [ (0x4) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 1 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { # CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551) # CHECK-NEXT: Offset: 0x0 # CHECK-NEXT: VirtualAddress: 0x0 diff --git a/lld/test/ELF/ppc64-relocs.s b/lld/test/ELF/ppc64-relocs.s index 61f9a1e..28902ae 100644 --- a/lld/test/ELF/ppc64-relocs.s +++ b/lld/test/ELF/ppc64-relocs.s @@ -43,7 +43,7 @@ _start: # CHECK: Disassembly of section .R_PPC64_TOC16_HI: # CHECK: .FR_PPC64_TOC16_HI: -# CHECK: 10010014: 3c 22 10 01 addis 1, 2, 4097 +# CHECK: 10010014: 3c 22 ff ff addis 1, 2, -1 .section .R_PPC64_TOC16_HA,"ax",@progbits .globl .FR_PPC64_TOC16_HA @@ -52,7 +52,7 @@ _start: # CHECK: Disassembly of section .R_PPC64_TOC16_HA: # CHECK: .FR_PPC64_TOC16_HA: -# CHECK: 10010018: 3c 22 10 02 addis 1, 2, 4098 +# CHECK: 10010018: 3c 22 00 00 addis 1, 2, 0 .section .R_PPC64_REL24,"ax",@progbits .globl .FR_PPC64_REL24 -- 2.7.4