diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -143,6 +143,10 @@ bool hasGotOffRel = false; protected: + // On Power PC we can have a delayed initialization for + // ElfSym::globalOffsetTable + void setupPPCDelayedInit(); + size_t numEntries = 0; uint32_t tlsIndexOff = -1; uint64_t size = 0; diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -654,6 +654,7 @@ } void GotSection::addEntry(Symbol &sym) { + setupPPCDelayedInit(); sym.gotIndex = numEntries; ++numEntries; } @@ -661,6 +662,8 @@ bool GotSection::addDynTlsEntry(Symbol &sym) { if (sym.globalDynIndex != -1U) return false; + setupPPCDelayedInit(); + sym.globalDynIndex = numEntries; // Global Dynamic TLS entries take two GOT slots. numEntries += 2; @@ -672,6 +675,7 @@ bool GotSection::addTlsIndex() { if (tlsIndexOff != uint32_t(-1)) return false; + setupPPCDelayedInit(); tlsIndexOff = numEntries * config->wordsize; numEntries += 2; return true; @@ -700,6 +704,19 @@ relocateAlloc(buf, buf + size); } +void GotSection::setupPPCDelayedInit() { + if (config->emachine != EM_PPC64 || ElfSym::globalOffsetTable) + return; + + // Add the size of the header. + numEntries += target->gotHeaderEntriesNum; + + symtab->addSymbol(Defined{/*file=*/nullptr, ".TOC.", STB_LOCAL, STV_HIDDEN, + STT_NOTYPE, 0x8000, /*size=*/0, Out::elfHeader}); + Symbol *s = symtab->find(".TOC."); + ElfSym::globalOffsetTable = cast(s); +} + static uint64_t getMipsPageAddr(uint64_t addr) { return (addr + 0x8000) & ~0xffff; } diff --git a/lld/test/ELF/ppc64-ld-got-dtprel.s b/lld/test/ELF/ppc64-ld-got-dtprel.s --- a/lld/test/ELF/ppc64-ld-got-dtprel.s +++ b/lld/test/ELF/ppc64-ld-got-dtprel.s @@ -22,14 +22,15 @@ # RELOCS-NEXT: R_PPC64_GOT_DTPREL16_DS j 0x0 # RELOCS-NEXT: } -## ha(i@got@dtprel) = (&.got[0] - (.got+0x8000) + 0x8000 >> 16) & 0xffff = 0 -## lo(i@got@dtprel) = &.got[0] - (.got+0x8000) & 0xffff = -32768 -## hi(j@got@dtprel) = (&.got[1] - (.got+0x8000) >> 16) & 0xffff = -1 -## j@got@dtprel = &.got[1] - (.got+0x8000) = -32760 +## Start with .got[1] as .got[0] is .TOC. +## ha(i@got@dtprel) = (&.got[1] - (.got+0x8000) >> 16) & 0xffff = 0 +## lo(i@got@dtprel) = &.got[1] - (.got+0x8000) & 0xffff = -32760 +## hi(j@got@dtprel) = (&.got[2] - (.got+0x8000) >> 16) & 0xffff = -1 +## j@got@dtprel = &.got[2] - (.got+0x8000) = -32752 # CHECK: addis 3, 2, 0 -# CHECK-NEXT: ld 3, -32768(3) +# CHECK-NEXT: ld 3, -32760(3) # CHECK-NEXT: addis 3, 2, -1 -# CHECK-NEXT: addi 3, 2, -32760 +# CHECK-NEXT: addi 3, 2, -32752 addis 3, 2, i@got@dtprel@ha ld 3, i@got@dtprel@l(3) diff --git a/lld/test/ELF/ppc64-reloc-got-pcrel34.s b/lld/test/ELF/ppc64-reloc-got-pcrel34.s --- a/lld/test/ELF/ppc64-reloc-got-pcrel34.s +++ b/lld/test/ELF/ppc64-reloc-got-pcrel34.s @@ -19,31 +19,36 @@ .text .section .text_low, "ax", %progbits # CHECK-LABEL: : -# CHECK-NEXT: pld 3, 458928(0), 1 +# CHECK-NEXT: pld 3, 458936(0), 1 # CHECK-NEXT: lwa 3, 0(3) + # SYMBOL: Symbol table '.dynsym' contains 4 entries: # SYMBOL: 00000000 0 NOTYPE GLOBAL DEFAULT UND glob_int -# RELA: 100800b0 0000000100000014 R_PPC64_GLOB_DAT 0000000000000000 glob_int + 0 +# RELA: 100800b8 0000000100000014 R_PPC64_GLOB_DAT 0000000000000000 glob_int + 0 GlobIntPCRel: pld 3, glob_int@got@PCREL(0), 1 lwa 3, 0(3) blr # CHECK-LABEL: : -# CHECK-NEXT: pld 3, 458920(0), 1 +# CHECK-NEXT: pld 3, 458928(0), 1 # CHECK-NEXT: lwa 3, 8(3) # SYMBOL: 00000000 0 NOTYPE GLOBAL DEFAULT UND glob_int8 -# RELA: 100800b8 0000000200000014 R_PPC64_GLOB_DAT 0000000000000000 glob_int8 + 0 +# RELA: 100800c0 0000000200000014 R_PPC64_GLOB_DAT 0000000000000000 glob_int8 + 0 GlobIntPCRelOffset: pld 3, glob_int8@got@PCREL(0), 1 lwa 3, 8(3) blr # CHECK-LABEL: : -# CHECK-NEXT: pld 3, 192(0), 1 +# CHECK-NEXT: pld 3, 200(0), 1 # CHECK-NEXT: lwa 3, 64(3) # SYMBOL: 00000000 0 NOTYPE GLOBAL DEFAULT UND glob_int8_big -# RELA: 100800c0 0000000300000014 R_PPC64_GLOB_DAT 0000000000000000 glob_int8_big + 0 +# RELA: 100800c8 0000000300000014 R_PPC64_GLOB_DAT 0000000000000000 glob_int8_big + 0 + +## Note that the first entry of the .got[0] should always be .TOC. +# SYMBOL: Symbol table '.symtab' contains 9 entries: +# SYMBOL: 5: 00000000100880b0 0 NOTYPE LOCAL DEFAULT 10 .TOC. .section .text_high, "ax", %progbits GlobIntPCRelBigOffset: pld 3, glob_int8_big@got@PCREL(0), 1 diff --git a/lld/test/ELF/ppc64-tls-gd.s b/lld/test/ELF/ppc64-tls-gd.s --- a/lld/test/ELF/ppc64-tls-gd.s +++ b/lld/test/ELF/ppc64-tls-gd.s @@ -16,28 +16,29 @@ # RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=IE %s # GD-REL: .rela.dyn { -# GD-REL-NEXT: 0x20548 R_PPC64_DTPMOD64 a 0x0 -# GD-REL-NEXT: 0x20550 R_PPC64_DTPREL64 a 0x0 -# GD-REL-NEXT: 0x20558 R_PPC64_DTPMOD64 b 0x0 -# GD-REL-NEXT: 0x20560 R_PPC64_DTPREL64 b 0x0 -# GD-REL-NEXT: 0x20568 R_PPC64_DTPMOD64 c 0x0 -# GD-REL-NEXT: 0x20570 R_PPC64_DTPREL64 c 0x0 +# GD-REL-NEXT: 0x20550 R_PPC64_DTPMOD64 a 0x0 +# GD-REL-NEXT: 0x20558 R_PPC64_DTPREL64 a 0x0 +# GD-REL-NEXT: 0x20560 R_PPC64_DTPMOD64 b 0x0 +# GD-REL-NEXT: 0x20568 R_PPC64_DTPREL64 b 0x0 +# GD-REL-NEXT: 0x20570 R_PPC64_DTPMOD64 c 0x0 +# GD-REL-NEXT: 0x20578 R_PPC64_DTPREL64 c 0x0 # GD-REL-NEXT: } -## &DTPMOD(a) - .TOC. = &.got[0] - (.got+0x8000) = -32768 +## Start with .got[1] as .got[0] is the .TOC. +## &DTPMOD(a) - .TOC. = &.got[1] - (.got+0x8000) = -32760 # GD: addis 3, 2, 0 -# GD-NEXT: addi 3, 3, -32768 +# GD-NEXT: addi 3, 3, -32760 # GD-NEXT: bl 0x10400 # GD-NEXT: ld 2, 24(1) -## &DTPMOD(b) - .TOC. = &.got[2] - (.got+0x8000) = -32752 +## &DTPMOD(b) - .TOC. = &.got[3] - (.got+0x8000) = -32744 # GD-NEXT: addis 3, 2, 0 -# GD-NEXT: addi 3, 3, -32752 +# GD-NEXT: addi 3, 3, -32744 # GD-NEXT: bl 0x10400 # GD-NEXT: ld 2, 24(1) -## &DTPMOD(b) - .TOC. = &.got[4] - (.got+0x8000) = -32736 -# GD-NEXT: li 3, -32736 +## &DTPMOD(b) - .TOC. = &.got[5] - (.got+0x8000) = -32728 +# GD-NEXT: li 3, -32728 # GD-NEXT: bl 0x10400 # GD-NEXT: ld 2, 24(1) @@ -59,8 +60,8 @@ # LE-NEXT: addi 3, 3, -28656 # IE-REL: .rela.dyn { -# IE-REL-NEXT: 0x10020418 R_PPC64_TPREL64 b 0x0 -# IE-REL-NEXT: 0x10020420 R_PPC64_TPREL64 c 0x0 +# IE-REL-NEXT: 0x10020420 R_PPC64_TPREL64 b 0x0 +# IE-REL-NEXT: 0x10020428 R_PPC64_TPREL64 c 0x0 # IE-REL-NEXT: } ## a is relaxed to use LE. @@ -69,15 +70,15 @@ # IE-NEXT: addis 3, 13, 0 # IE-NEXT: nop # IE-NEXT: addi 3, 3, -28664 -## &DTPMOD(b) - .TOC. = &.got[0] - (.got+0x8000) = -32768 +## &DTPMOD(b) - .TOC. = &.got[1] - (.got+0x8000) = -32760 # IE-NEXT: addis 3, 2, 0 -# IE-NEXT: ld 3, -32768(3) +# IE-NEXT: ld 3, -32760(3) # IE-NEXT: nop # IE-NEXT: add 3, 3, 13 -## &DTPMOD(c) - .TOC. = &.got[1] - (.got+0x8000) = -32760 +## &DTPMOD(c) - .TOC. = &.got[2] - (.got+0x8000) = -32752 ## r0 is wrong. R_PPC64_GOT_TLS16 cannot be relaxed to IE but the behavior is ## consistent with ld.bfd -# IE-NEXT: ld 3, -32760(0) +# IE-NEXT: ld 3, -32752(0) # IE-NEXT: nop # IE-NEXT: add 3, 3, 13 diff --git a/lld/test/ELF/ppc64-tls-ie.s b/lld/test/ELF/ppc64-tls-ie.s --- a/lld/test/ELF/ppc64-tls-ie.s +++ b/lld/test/ELF/ppc64-tls-ie.s @@ -23,19 +23,19 @@ # RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=LE %s # IE-REL: .rela.dyn { -# IE-REL-NEXT: 0x204A0 R_PPC64_TPREL64 c 0x0 -# IE-REL-NEXT: 0x204B0 R_PPC64_TPREL64 i 0x0 -# IE-REL-NEXT: 0x204B8 R_PPC64_TPREL64 l 0x0 -# IE-REL-NEXT: 0x204A8 R_PPC64_TPREL64 s 0x0 +# IE-REL-NEXT: 0x204A8 R_PPC64_TPREL64 c 0x0 +# IE-REL-NEXT: 0x204B8 R_PPC64_TPREL64 i 0x0 +# IE-REL-NEXT: 0x204C0 R_PPC64_TPREL64 l 0x0 +# IE-REL-NEXT: 0x204B0 R_PPC64_TPREL64 s 0x0 # IE-REL-NEXT: } # INPUT-REL: R_PPC64_GOT_TPREL16_HA c 0x0 # INPUT-REL: R_PPC64_GOT_TPREL16_LO_DS c 0x0 # INPUT-REL: R_PPC64_TLS c 0x0 -## &.got[0] - .TOC. = -32768 +## &.got[1] - .TOC. = -32760 # IE-LABEL: : # IE-NEXT: addis 3, 2, 0 -# IE-NEXT: ld 3, -32768(3) +# IE-NEXT: ld 3, -32760(3) # IE-NEXT: lbzx 3, 3, 13 # LE-LABEL: : # LE-NEXT: nop @@ -49,10 +49,10 @@ # INPUT-REL: R_PPC64_GOT_TPREL16_HA s 0x0 # INPUT-REL: R_PPC64_GOT_TPREL16_LO_DS s 0x0 # INPUT-REL: R_PPC64_TLS s 0x0 -## &.got[1] - .TOC. = -32760 +## &.got[2] - .TOC. = -32752 # IE-LABEL: : # IE-NEXT: addis 3, 2, 0 -# IE-NEXT: ld 3, -32760(3) +# IE-NEXT: ld 3, -32752(3) # IE-NEXT: lhzx 3, 3, 13 # LE-LABEL: : # LE-NEXT: nop @@ -66,10 +66,10 @@ # INPUT-REL: R_PPC64_GOT_TPREL16_HA i 0x0 # INPUT-REL: R_PPC64_GOT_TPREL16_LO_DS i 0x0 # INPUT-REL: R_PPC64_TLS i 0x0 -## &.got[2] - .TOC. = -32752 +## &.got[3] - .TOC. = -32744 # IE-LABEL: : # IE-NEXT: addis 3, 2, 0 -# IE-NEXT: ld 3, -32752(3) +# IE-NEXT: ld 3, -32744(3) # IE-NEXT: lwzx 3, 3, 13 # LE-LABEL: : # LE-NEXT: nop @@ -83,10 +83,10 @@ # INPUT-REL: R_PPC64_GOT_TPREL16_HA l 0x0 # INPUT-REL: R_PPC64_GOT_TPREL16_LO_DS l 0x0 # INPUT-REL: R_PPC64_TLS l 0x0 -## &.got[3] - .TOC. = -32744 +## &.got[4] - .TOC. = -32736 # IE-LABEL: : # IE-NEXT: addis 3, 2, 0 -# IE-NEXT: ld 3, -32744(3) +# IE-NEXT: ld 3, -32736(3) # IE-NEXT: ldx 3, 3, 13 # LE-LABEL: : # LE-NEXT: nop diff --git a/lld/test/ELF/ppc64-tls-pcrel-gd.s b/lld/test/ELF/ppc64-tls-pcrel-gd.s --- a/lld/test/ELF/ppc64-tls-pcrel-gd.s +++ b/lld/test/ELF/ppc64-tls-pcrel-gd.s @@ -42,10 +42,10 @@ #--- asm # GD-RELOC: Relocation section '.rela.dyn' at offset 0x100b8 contains 4 entries: -# GD-RELOC: 0000000001001160 0000000200000044 R_PPC64_DTPMOD64 0000000000000000 x + 0 -# GD-RELOC: 0000000001001168 000000020000004e R_PPC64_DTPREL64 0000000000000000 x + 0 -# GD-RELOC: 0000000001001170 0000000300000044 R_PPC64_DTPMOD64 0000000000000000 y + 0 -# GD-RELOC: 0000000001001178 000000030000004e R_PPC64_DTPREL64 0000000000000000 y + 0 +# GD-RELOC: 0000000001001168 0000000200000044 R_PPC64_DTPMOD64 0000000000000000 x + 0 +# GD-RELOC: 0000000001001170 000000020000004e R_PPC64_DTPREL64 0000000000000000 x + 0 +# GD-RELOC: 0000000001001178 0000000300000044 R_PPC64_DTPMOD64 0000000000000000 y + 0 +# GD-RELOC: 0000000001001180 000000030000004e R_PPC64_DTPREL64 0000000000000000 y + 0 # GD-SYM: Symbol table '.dynsym' contains 4 entries: # GD-SYM: 2: 0000000000000000 0 TLS GLOBAL DEFAULT UND x @@ -53,8 +53,8 @@ # GDTOIE-RELOC: Relocation section '.rela.dyn' at offset 0x{{.*}} contains 2 entries: -# GDTOIE-RELOC: 00000000010010e0 0000000200000049 R_PPC64_TPREL64 0000000000000000 x + 0 -# GDTOIE-RELOC: 00000000010010e8 0000000300000049 R_PPC64_TPREL64 0000000000000000 y + 0 +# GDTOIE-RELOC: 00000000010010e8 0000000200000049 R_PPC64_TPREL64 0000000000000000 x + 0 +# GDTOIE-RELOC: 00000000010010f0 0000000300000049 R_PPC64_TPREL64 0000000000000000 y + 0 # GDTOIE-SYM: Symbol table '.dynsym' contains 4 entries: # GDTOIE-SYM: 2: 0000000000000000 0 TLS GLOBAL DEFAULT UND x @@ -68,15 +68,15 @@ # GDTOLE-SYM: 4: 0000000000000004 0 TLS GLOBAL DEFAULT 3 y # GD-LABEL: : -# GD-NEXT: paddi 3, 0, 352, 1 +# GD-NEXT: paddi 3, 0, 360, 1 # GD-NEXT: bl -# GD-NEXT: paddi 3, 0, 356, 1 +# GD-NEXT: paddi 3, 0, 364, 1 # GD-NEXT: bl # GD-NEXT: blr # GDTOIE-LABEL: : -# GDTOIE-NEXT: pld 3, 224(0), 1 +# GDTOIE-NEXT: pld 3, 232(0), 1 # GDTOIE-NEXT: add 3, 3, 13 -# GDTOIE-NEXT: pld 3, 220(0), 1 +# GDTOIE-NEXT: pld 3, 228(0), 1 # GDTOIE-NEXT: add 3, 3, 13 # GDTOIE-NEXT: blr # GDTOLE-LABEL: : diff --git a/lld/test/ELF/ppc64-tls-pcrel-ie.s b/lld/test/ELF/ppc64-tls-pcrel-ie.s --- a/lld/test/ELF/ppc64-tls-pcrel-ie.s +++ b/lld/test/ELF/ppc64-tls-pcrel-ie.s @@ -42,8 +42,8 @@ #--- asm # IE-RELOC: Relocation section '.rela.dyn' at offset 0x10090 contains 2 entries: -# IE-RELOC: 00000000010040d8 0000000100000049 R_PPC64_TPREL64 0000000000000000 x + 0 -# IE-RELOC: 00000000010040e0 0000000200000049 R_PPC64_TPREL64 0000000000000000 y + 0 +# IE-RELOC: 00000000010040e0 0000000100000049 R_PPC64_TPREL64 0000000000000000 x + 0 +# IE-RELOC: 00000000010040e8 0000000200000049 R_PPC64_TPREL64 0000000000000000 y + 0 # IE-SYM: Symbol table '.dynsym' contains 3 entries: # IE-SYM: 1: 0000000000000000 0 TLS GLOBAL DEFAULT UND x @@ -61,7 +61,7 @@ # LE-GOT: could not find section '.got' # IE-LABEL: : -# IE-NEXT: pld 3, 12504(0), 1 +# IE-NEXT: pld 3, 12512(0), 1 # IE-NEXT: add 3, 3, 13 # IE-NEXT: blr # LE-LABEL: : @@ -75,7 +75,7 @@ blr # IE-LABEL: : -# IE-NEXT: pld 3, 8408(0), 1 +# IE-NEXT: pld 3, 8416(0), 1 # IE-NEXT: lwzx 3, 3, 13 # IE-NEXT: blr # LE-LABEL: : @@ -89,8 +89,8 @@ blr # IE-LABEL: : -# IE-NEXT: pld 3, 4312(0), 1 -# IE-NEXT: pld 4, 4312(0), 1 +# IE-NEXT: pld 3, 4320(0), 1 +# IE-NEXT: pld 4, 4320(0), 1 # IE-NEXT: lwzx 3, 3, 13 # IE-NEXT: lwzx 4, 4, 13 # IE-NEXT: blr @@ -109,7 +109,7 @@ blr # IE-LABEL: : -# IE-NEXT: pld 4, 224(0), 1 +# IE-NEXT: pld 4, 232(0), 1 # IE-NEXT: lwzx 3, 4, 13 # IE-NEXT: stwx 3, 4, 13 # IE-NEXT: blr