diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp --- a/lld/ELF/Arch/PPC64.cpp +++ b/lld/ELF/Arch/PPC64.cpp @@ -582,6 +582,7 @@ tlsGotRel = R_PPC64_TPREL64; needsMoreStackNonSplit = false; + dynamicSectionOptFlags = 0; // We need 64K pages (at least under glibc/Linux, the loader won't // set different permissions on a finer granularity than that). diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -1531,6 +1531,11 @@ addInt(DT_PPC64_GLINK, in.plt->getVA() + target->pltHeaderSize - 32); } + // There may be multiple TOCs due to emitting thunks for some NOTOC relocs. + if (config->emachine == EM_PPC64 && + getPPC64TargetInfo()->dynamicSectionOptFlags != -1) + addInt(DT_LOPROC + 3, getPPC64TargetInfo()->dynamicSectionOptFlags); + addInt(DT_NULL, 0); return entries; } diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h --- a/lld/ELF/Target.h +++ b/lld/ELF/Target.h @@ -140,6 +140,12 @@ // On PPC ELF V2 abi, the first entry in the .got is the .TOC. unsigned gotHeaderEntriesNum = 0; + // On PPC ELF V2 abi, the dynamic section needs DT_PPC64_OPT (DT_LOPROC + 3) + // to be set to 0x2 if there can be multiple TOC's. Although we do not emit + // multiple TOC's, there can be a mix of TOC and NOTOC addressing which + // is functionally equivalent. + int dynamicSectionOptFlags = -1; + bool needsThunks = false; // A 4-byte field corresponding to one or more trap instructions, used to pad diff --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp --- a/lld/ELF/Thunks.cpp +++ b/lld/ELF/Thunks.cpp @@ -1367,6 +1367,12 @@ assert((type == R_PPC64_REL14 || type == R_PPC64_REL24 || type == R_PPC64_REL24_NOTOC) && "unexpected relocation type for thunk"); + + // If we are emitting stubs for NOTOC relocations, we need to tell + // the PLT resolver that there can be multiple TOCs. + if (type == R_PPC64_REL24_NOTOC) + getPPC64TargetInfo()->dynamicSectionOptFlags = 0x2; + if (s.isInPlt()) return type == R_PPC64_REL24_NOTOC ? (Thunk *)make(s, /*gotPlt=*/true) diff --git a/lld/test/ELF/basic-ppc64.s b/lld/test/ELF/basic-ppc64.s --- a/lld/test/ELF/basic-ppc64.s +++ b/lld/test/ELF/basic-ppc64.s @@ -35,7 +35,7 @@ // CHECK-NEXT: Version: 1 // CHECK-NEXT: Entry: 0x0 // CHECK-NEXT: ProgramHeaderOffset: 0x40 -// CHECK-NEXT: SectionHeaderOffset: 0x330 +// CHECK-NEXT: SectionHeaderOffset: 0x340 // CHECK-NEXT: Flags [ (0x2) // CHECK-NEXT: 0x2 // CHECK-NEXT: ] @@ -149,7 +149,7 @@ // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x20238 // CHECK-NEXT: Offset: 0x238 -// CHECK-NEXT: Size: 96 +// CHECK-NEXT: Size: 112 // CHECK-NEXT: Link: 3 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 8 @@ -160,13 +160,15 @@ // LE-NEXT: 0020: 05000000 00000000 28020000 00000000 | // LE-NEXT: 0030: 0A000000 00000000 01000000 00000000 | // LE-NEXT: 0040: 04000000 00000000 18020000 00000000 | -// LE-NEXT: 0050: 00000000 00000000 00000000 00000000 | +// LE-NEXT: 0050: 03000070 00000000 00000000 00000000 | +// LE-NEXT: 0060: 00000000 00000000 00000000 00000000 | // BE-NEXT: 0000: 00000000 00000006 00000000 00000200 | // BE-NEXT: 0010: 00000000 0000000B 00000000 00000018 | // BE-NEXT: 0020: 00000000 00000005 00000000 00000228 | // BE-NEXT: 0030: 00000000 0000000A 00000000 00000001 | // BE-NEXT: 0040: 00000000 00000004 00000000 00000218 | -// BE-NEXT: 0050: 00000000 00000000 00000000 00000000 | +// BE-NEXT: 0050: 00000000 70000003 00000000 00000000 | +// BE-NEXT: 0060: 00000000 00000000 00000000 00000000 | // CHECK-NEXT: ) // CHECK-NEXT: } // CHECK-NEXT: Section { @@ -177,8 +179,8 @@ // CHECK-NEXT: SHF_ALLOC (0x2) // CHECK-NEXT: SHF_WRITE (0x1) // CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x30298 -// CHECK-NEXT: Offset: 0x298 +// CHECK-NEXT: Address: 0x302A8 +// CHECK-NEXT: Offset: 0x2A8 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 @@ -194,7 +196,7 @@ // CHECK-NEXT: SHF_STRINGS (0x20) // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 -// CHECK-NEXT: Offset: 0x298 +// CHECK-NEXT: Offset: 0x2A8 // CHECK-NEXT: Size: 8 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 @@ -211,7 +213,7 @@ // CHECK-NEXT: Flags [ (0x0) // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 -// CHECK-NEXT: Offset: 0x2A0 +// CHECK-NEXT: Offset: 0x2B0 // CHECK-NEXT: Size: 48 // CHECK-NEXT: Link: 10 // CHECK-NEXT: Info: 2 @@ -233,7 +235,7 @@ // CHECK-NEXT: Flags [ (0x0) // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 -// CHECK-NEXT: Offset: 0x2D0 +// CHECK-NEXT: Offset: 0x2E0 // CHECK-NEXT: Size: 84 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 @@ -255,7 +257,7 @@ // CHECK-NEXT: Flags [ (0x0) // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 -// CHECK-NEXT: Offset: 0x324 +// CHECK-NEXT: Offset: 0x334 // CHECK-NEXT: Size: 10 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 @@ -309,8 +311,8 @@ // CHECK-NEXT: Offset: 0x238 // CHECK-NEXT: VirtualAddress: 0x20238 // CHECK-NEXT: PhysicalAddress: 0x20238 -// CHECK-NEXT: FileSize: 96 -// CHECK-NEXT: MemSize: 96 +// CHECK-NEXT: FileSize: 112 +// CHECK-NEXT: MemSize: 112 // CHECK-NEXT: Flags [ (0x6) // CHECK-NEXT: PF_R (0x4) // CHECK-NEXT: PF_W (0x2) @@ -322,8 +324,8 @@ // CHECK-NEXT: Offset: 0x238 // CHECK-NEXT: VirtualAddress: 0x20238 // CHECK-NEXT: PhysicalAddress: 0x20238 -// CHECK-NEXT: FileSize: 96 -// CHECK-NEXT: MemSize: 96 +// CHECK-NEXT: FileSize: 112 +// CHECK-NEXT: MemSize: 112 // CHECK-NEXT: Flags [ (0x6) // CHECK-NEXT: PF_R (0x4) // CHECK-NEXT: PF_W (0x2) @@ -335,7 +337,7 @@ // CHECK-NEXT: Offset: 0x238 // CHECK-NEXT: VirtualAddress: 0x20238 // CHECK-NEXT: PhysicalAddress: 0x20238 -// CHECK-NEXT: FileSize: 96 +// CHECK-NEXT: FileSize: 112 // CHECK-NEXT: MemSize: 3528 // CHECK-NEXT: Flags [ (0x4) // CHECK-NEXT: PF_R (0x4) diff --git a/lld/test/ELF/ppc-reloc-copy.s b/lld/test/ELF/ppc-reloc-copy.s --- a/lld/test/ELF/ppc-reloc-copy.s +++ b/lld/test/ELF/ppc-reloc-copy.s @@ -20,10 +20,10 @@ # NM32: 10030210 00000004 B x # REL64: .rela.dyn { -# REL64-NEXT: 0x10030350 R_PPC64_COPY x 0x0 +# REL64-NEXT: 0x10030360 R_PPC64_COPY x 0x0 # REL64-NEXT: } -# NM64: 0000000010030350 0000000000000004 B x +# NM64: 0000000010030360 0000000000000004 B x lis 3, x@ha lwz 3, x@l(3) diff --git a/lld/test/ELF/ppc64-abs64-dyn.s b/lld/test/ELF/ppc64-abs64-dyn.s --- a/lld/test/ELF/ppc64-abs64-dyn.s +++ b/lld/test/ELF/ppc64-abs64-dyn.s @@ -11,16 +11,16 @@ ## symbols and R_PPC64_TOC in writable sections. # CHECK: .rela.dyn { -# CHECK-NEXT: 0x303B8 R_PPC64_RELATIVE - 0x303B1 +# CHECK-NEXT: 0x303C8 R_PPC64_RELATIVE - 0x303C1 ## TOC base (0x283b0) + 0x8000 + 1 ---------^ -# CHECK-NEXT: 0x303C0 R_PPC64_RELATIVE - 0x303B9 -# CHECK-NEXT: 0x303C8 R_PPC64_ADDR64 external 0x1 -# CHECK-NEXT: 0x303D0 R_PPC64_ADDR64 global 0x1 +# CHECK-NEXT: 0x303D0 R_PPC64_RELATIVE - 0x303C9 +# CHECK-NEXT: 0x303D8 R_PPC64_ADDR64 external 0x1 +# CHECK-NEXT: 0x303E0 R_PPC64_ADDR64 global 0x1 # CHECK-NEXT: } # CHECK-LABEL: Symbols [ # CHECK: Symbol { # CHECK: Name: .TOC. ({{.+}}) -# CHECK-NEXT: Value: 0x283B0 +# CHECK-NEXT: Value: 0x283C0 .data .globl global diff --git a/lld/test/ELF/ppc64-bsymbolic-toc-restore.s b/lld/test/ELF/ppc64-bsymbolic-toc-restore.s --- a/lld/test/ELF/ppc64-bsymbolic-toc-restore.s +++ b/lld/test/ELF/ppc64-bsymbolic-toc-restore.s @@ -63,7 +63,7 @@ # CHECK-EMPTY: # CHECK-NEXT: : # CHECK-NEXT: addis 2, 12, 2 -# CHECK-NEXT: addi 2, 2, -32448 +# CHECK-NEXT: addi 2, 2, -32432 # CHECK-NEXT: [[DEF]]: li 3, 55 # CHECK-NEXT: blr # CHECK-NEXT: trap diff --git a/lld/test/ELF/ppc64-check-missing-tocbase.s b/lld/test/ELF/ppc64-check-missing-tocbase.s --- a/lld/test/ELF/ppc64-check-missing-tocbase.s +++ b/lld/test/ELF/ppc64-check-missing-tocbase.s @@ -22,10 +22,10 @@ # INPUT-ASM-NEXT: blr # SO-REL: Relocation section '.rela.dyn' -# SO-REL: 0000000000020390 0000000100000014 R_PPC64_GLOB_DAT 00000000000102d0 glob_int + 0 +# SO-REL: 00000000000203a0 0000000100000014 R_PPC64_GLOB_DAT 00000000000102d0 glob_int + 0 # SO-GOT: Hex dump of section '.got': -# SO-GOT: 0x00020388 88830200 00000000 00000000 00000000 +# SO-GOT: 0x00020398 98830200 00000000 00000000 00000000 # SO-SYM: Symbol table '.symtab' contains 4 entries: # SO-SYM: 3: 00000000000102d0 4 NOTYPE GLOBAL DEFAULT 6 glob_int diff --git a/lld/test/ELF/ppc64-dtprel.s b/lld/test/ELF/ppc64-dtprel.s --- a/lld/test/ELF/ppc64-dtprel.s +++ b/lld/test/ELF/ppc64-dtprel.s @@ -140,12 +140,12 @@ // The got entry for i is at .got+8*1 = 0x4209e0 // i@dtprel = 1024 - 0x8000 = -31744 = 0xffffffffffff8400 // HEX-LE: section '.got': -// HEX-LE-NEXT: 4209d0 d0894200 00000000 00000000 00000000 -// HEX-LE-NEXT: 4209e0 00000000 00000000 +// HEX-LE-NEXT: 4209e0 e0894200 00000000 00000000 00000000 +// HEX-LE-NEXT: 4209f0 00000000 00000000 // HEX-BE: section '.got': -// HEX-BE-NEXT: 4209d0 00000000 004289d0 00000000 00000000 -// HEX-BE-NEXT: 4209e0 00000000 00000000 +// HEX-BE-NEXT: 4209e0 00000000 004289e0 00000000 00000000 +// HEX-BE-NEXT: 4209f0 00000000 00000000 // Dis: : // Dis: addi 4, 3, -31744 diff --git a/lld/test/ELF/ppc64-local-dynamic.s b/lld/test/ELF/ppc64-local-dynamic.s --- a/lld/test/ELF/ppc64-local-dynamic.s +++ b/lld/test/ELF/ppc64-local-dynamic.s @@ -98,7 +98,7 @@ // Check that the got has 3 entries, 1 for the TOC and 1 structure of 2 entries // for the tls variables. Also verify the address so we can check the offsets // we calculate for each relocation type. -// CheckGot: got 00000018 0000000000020100 +// CheckGot: got 00000018 0000000000020110 // got starts at 0x20100 so .TOC. will be 0x28100, and the tls_index struct is // at 0x20108. diff --git a/lld/test/ELF/ppc64-long-branch-pi.s b/lld/test/ELF/ppc64-long-branch-pi.s --- a/lld/test/ELF/ppc64-long-branch-pi.s +++ b/lld/test/ELF/ppc64-long-branch-pi.s @@ -14,19 +14,19 @@ # RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck %s # SEC-PIE: Name Type Address Off Size ES Flg Lk Inf Al -# SEC-PIE: .got PROGBITS 0000000002002100 2012100 000008 00 WA 0 0 8 -# SEC-PIE: .branch_lt NOBITS 0000000002002110 2012110 000020 00 WA 0 0 8 +# SEC-PIE: .got PROGBITS 0000000002002110 2012110 000008 00 WA 0 0 8 +# SEC-PIE: .branch_lt NOBITS 0000000002002120 2012120 000020 00 WA 0 0 8 # SEC-SHARED: Name Type Address Off Size ES Flg Lk Inf Al -# SEC-SHARED: .got PROGBITS 00000000020020e0 20120e0 000008 00 WA 0 0 8 -# SEC-SHARED: .branch_lt NOBITS 00000000020020f0 20120f0 000020 00 WA 0 0 8 +# SEC-SHARED: .got PROGBITS 00000000020020f0 20120f0 000008 00 WA 0 0 8 +# SEC-SHARED: .branch_lt NOBITS 0000000002002100 2012100 000020 00 WA 0 0 8 # RELOC: .rela.dyn { -# RELOC-NEXT: 0x2002108 R_PPC64_RELATIVE - 0x2012100 -# RELOC-NEXT: 0x2002110 R_PPC64_RELATIVE - 0x2002000 -# RELOC-NEXT: 0x2002118 R_PPC64_RELATIVE - 0x2002008 -# RELOC-NEXT: 0x2002120 R_PPC64_RELATIVE - 0x200200C -# RELOC-NEXT: 0x2002128 R_PPC64_RELATIVE - 0x2000 +# RELOC-NEXT: 0x2002118 R_PPC64_RELATIVE - 0x2012110 +# RELOC-NEXT: 0x2002120 R_PPC64_RELATIVE - 0x2002000 +# RELOC-NEXT: 0x2002128 R_PPC64_RELATIVE - 0x2002008 +# RELOC-NEXT: 0x2002130 R_PPC64_RELATIVE - 0x200200C +# RELOC-NEXT: 0x2002138 R_PPC64_RELATIVE - 0x2000 # RELOC-NEXT: } # CHECK: <_start>: diff --git a/lld/test/ELF/ppc64-pcrel-call-to-extern.s b/lld/test/ELF/ppc64-pcrel-call-to-extern.s --- a/lld/test/ELF/ppc64-pcrel-call-to-extern.s +++ b/lld/test/ELF/ppc64-pcrel-call-to-extern.s @@ -72,31 +72,31 @@ # SYMBOL-NOP10-NEXT: 11: 0000000000000000 0 NOTYPE GLOBAL DEFAULT [] UND callee_global_TOC ## DT_PLTGOT points to .plt -# SEC: .plt NOBITS 0000000010030158 040158 000028 00 WA 0 0 8 -# SEC-OG: .plt NOBITS 0000000010030148 040148 000028 00 WA 0 0 8 -# SEC: 0x0000000000000003 (PLTGOT) 0x10030158 -# SEC-OG: 0x0000000000000003 (PLTGOT) 0x10030158 +# SEC: .plt NOBITS 0000000010030168 040168 000028 00 WA 0 0 8 +# SEC-OG: .plt NOBITS 0000000010030158 040158 000028 00 WA 0 0 8 +# SEC: 0x0000000000000003 (PLTGOT) 0x10030168 +# SEC-OG: 0x0000000000000003 (PLTGOT) 0x10030168 ## DT_PLTGOT points to .plt -# SEC-NOP10: .plt NOBITS 0000000010030158 040158 000028 00 WA 0 0 8 -# SEC-NOP10: 0x0000000000000003 (PLTGOT) 0x10030158 +# SEC-NOP10: .plt NOBITS 0000000010030168 040168 000028 00 WA 0 0 8 +# SEC-NOP10: 0x0000000000000003 (PLTGOT) 0x10030168 ## The first 2 entries in the .plt are reserved for the dynamic linkers ## usage. The JMP_SLOT relocations are stored at .plt[2], .plt[3], .plt[4]. ## Check that we emit 3 R_PPC64_JMP_SLOT in .rela.plt. # REL: .rela.plt { -# REL-NEXT: 0x10030168 R_PPC64_JMP_SLOT callee_global_stother0 0x0 -# REL-NEXT-OG: 0x10030158 R_PPC64_JMP_SLOT callee_global_stother0 0x0 -# REL-NEXT: 0x10030170 R_PPC64_JMP_SLOT callee_global_stother1 0x0 -# REL-NEXT-OG: 0x10030160 R_PPC64_JMP_SLOT callee_global_stother1 0x0 -# REL-NEXT: 0x10030178 R_PPC64_JMP_SLOT callee_global_TOC 0x0 -# REL-NEXT-OG: 0x10030168 R_PPC64_JMP_SLOT callee_global_TOC 0x0 +# REL-NEXT: 0x10030178 R_PPC64_JMP_SLOT callee_global_stother0 0x0 +# REL-NEXT-OG: 0x10030168 R_PPC64_JMP_SLOT callee_global_stother0 0x0 +# REL-NEXT: 0x10030180 R_PPC64_JMP_SLOT callee_global_stother1 0x0 +# REL-NEXT-OG: 0x10030170 R_PPC64_JMP_SLOT callee_global_stother1 0x0 +# REL-NEXT: 0x10030188 R_PPC64_JMP_SLOT callee_global_TOC 0x0 +# REL-NEXT-OG: 0x10030178 R_PPC64_JMP_SLOT callee_global_TOC 0x0 # REL-NEXT: } # REL-NOP10: .rela.plt { -# REL-NOP10-NEXT: 0x10030168 R_PPC64_JMP_SLOT callee_global_stother0 0x0 -# REL-NOP10-NEXT: 0x10030170 R_PPC64_JMP_SLOT callee_global_stother1 0x0 -# REL-NOP10-NEXT: 0x10030178 R_PPC64_JMP_SLOT callee_global_TOC 0x0 +# REL-NOP10-NEXT: 0x10030178 R_PPC64_JMP_SLOT callee_global_stother0 0x0 +# REL-NOP10-NEXT: 0x10030180 R_PPC64_JMP_SLOT callee_global_stother1 0x0 +# REL-NOP10-NEXT: 0x10030188 R_PPC64_JMP_SLOT callee_global_TOC 0x0 # REL-NOP10-NEXT: } # CHECK-LABEL: : @@ -107,9 +107,9 @@ # CHECK-NOP10: 10010000: bl 0x10010010 # CHECK-NOP10-NEXT: 10010004: blr -## .plt[2] - 0x10010010 = 0x10030168 - 0x10010010 = 0x20158 = 131416 +## .plt[2] - 0x10010010 = 0x10030178 - 0x10010010 = 0x20168 = 131432 # CHECK-LABEL: <__plt_pcrel_callee_global_stother0>: -# CHECK: 10010010: pld 12, 131416(0), 1 +# CHECK: 10010010: pld 12, 131432(0), 1 # CHECK-NEXT: 10010018: mtctr 12 # CHECK-NEXT: 1001001c: bctr @@ -120,7 +120,7 @@ # CHECK-NOP10-NEXT: 10010018: mflr 11 # CHECK-NOP10-NEXT: mtlr 12 # CHECK-NOP10-NEXT: addis 12, 11, 2 -# CHECK-NOP10-NEXT: ld 12, 336(12) +# CHECK-NOP10-NEXT: ld 12, 352(12) # CHECK-NOP10-NEXT: mtctr 12 # CHECK-NOP10-NEXT: bctr @@ -132,9 +132,9 @@ # CHECK-NOP10: 10020000: bl 0x10020010 # CHECK-NOP10-NEXT: 10020004: blr -## .plt[3] - 0x10020010 = 0x10030170 - 0x10020010 = 0x10160 = 65888 +## .plt[3] - 0x10020010 = 0x10030180 - 0x10020010 = 0x10170 = 65904 # CHECK-LABEL: <__plt_pcrel_callee_global_stother1>: -# CHECK: 10020010: pld 12, 65888(0), 1 +# CHECK: 10020010: pld 12, 65904(0), 1 # CHECK-NEXT: 10020018: mtctr 12 # CHECK-NEXT: 1002001c: bctr @@ -146,7 +146,7 @@ # CHECK-NOP10-NEXT: 10020018: mflr 11 # CHECK-NOP10-NEXT: mtlr 12 # CHECK-NOP10-NEXT: addis 12, 11, 1 -# CHECK-NOP10-NEXT: ld 12, 344(12) +# CHECK-NOP10-NEXT: ld 12, 360(12) # CHECK-NOP10-NEXT: mtctr 12 # CHECK-NOP10-NEXT: bctr @@ -158,9 +158,9 @@ # CHECK-NOP10: 10030000: bl 0x10030010 # CHECK-NOP10-NEXT: 10030004: blr -## .plt[4] - 0x10030010 = 0x10030178 - 0x10030010 = 0x168 = 360 +## .plt[4] - 0x10030010 = 0x10030188 - 0x10030010 = 0x178 = 376 # CHECK-LABEL: <__plt_pcrel_callee_global_TOC>: -# CHECK: 10030010: pld 12, 360(0), 1 +# CHECK: 10030010: pld 12, 376(0), 1 # CHECK-NEXT: 10030018: mtctr 12 # CHECK-NEXT: 1003001c: bctr @@ -172,7 +172,7 @@ # CHECK-NOP10-NEXT: 10030018: mflr 11 # CHECK-NOP10-NEXT: mtlr 12 # CHECK-NOP10-NEXT: addis 12, 11, 0 -# CHECK-NOP10-NEXT: ld 12, 352(12) +# CHECK-NOP10-NEXT: ld 12, 368(12) # CHECK-NOP10-NEXT: mtctr 12 # CHECK-NOP10-NEXT: bctr diff --git a/lld/test/ELF/ppc64-pcrel-long-branch.s b/lld/test/ELF/ppc64-pcrel-long-branch.s --- a/lld/test/ELF/ppc64-pcrel-long-branch.s +++ b/lld/test/ELF/ppc64-pcrel-long-branch.s @@ -19,6 +19,7 @@ # RUN: llvm-mc -filetype=obj -triple=ppc64 -defsym HIDDEN=1 %s -o %t.o # RUN: ld.lld -shared -T %t.script %t.o -o %t.so # RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck %s +# RUN: llvm-readelf --dynamic %t.so | FileCheck --check-prefix=READELF %s # CHECK-LABEL: <_start>: # CHECK-NEXT: 2000: bl 0x2010 @@ -35,6 +36,8 @@ # CHECK-LABEL: : # CHECK-NEXT: 2002000: blr +# READELF: (PPC64_OPT) 0x2 + .section .text_low, "ax", %progbits .globl _start _start: diff --git a/lld/test/ELF/ppc64-plt-stub-compatible.s b/lld/test/ELF/ppc64-plt-stub-compatible.s --- a/lld/test/ELF/ppc64-plt-stub-compatible.s +++ b/lld/test/ELF/ppc64-plt-stub-compatible.s @@ -29,9 +29,9 @@ # T2-LABEL: : # T2-NEXT: 10010300: addis 2, 12, 1 -# T2-NEXT: 10010304: addi 2, 2, -32368 +# T2-NEXT: 10010304: addi 2, 2, -32352 # T2-NEXT: 10010308: addis 4, 2, -1 -# T2-NEXT: 1001030c: lwa 3, 32412(4) +# T2-NEXT: 1001030c: lwa 3, 32396(4) # T2-NEXT: 10010310: bl 0x10010330 # T2-NEXT: 10010314: ld 2, 24(1) # T2-NEXT: 10010318: blr @@ -49,7 +49,7 @@ # T2-NEXT: 10010340: bctr # T2-LABEL: <__plt_pcrel_callee>: -# T2-NEXT: 10010350: pld 12, 344(0), 1 +# T2-NEXT: 10010350: pld 12, 360(0), 1 # T2-NEXT: 10010358: mtctr 12 # T2-NEXT: 1001035c: bctr .ifdef T2 @@ -83,15 +83,15 @@ # T3-LABEL: : # T3-NEXT: 10010310: addis 2, 12, 1 -# T3-NEXT: 10010314: addi 2, 2, -32392 +# T3-NEXT: 10010314: addi 2, 2, -32376 # T3-NEXT: 10010318: addis 4, 2, -1 -# T3-NEXT: 1001031c: lwa 3, 32420(4) +# T3-NEXT: 1001031c: lwa 3, 32404(4) # T3-NEXT: 10010320: bl 0x10010350 # T3-NEXT: 10010324: ld 2, 24(1) # T3-NEXT: 10010328: blr # T3-LABEL: <__plt_pcrel_callee>: -# T3-NEXT: 10010330: pld 12, 368(0), 1 +# T3-NEXT: 10010330: pld 12, 384(0), 1 # T3-NEXT: 10010338: mtctr 12 # T3-NEXT: 1001033c: bctr diff --git a/lld/test/ELF/ppc64-plt-stub.s b/lld/test/ELF/ppc64-plt-stub.s --- a/lld/test/ELF/ppc64-plt-stub.s +++ b/lld/test/ELF/ppc64-plt-stub.s @@ -15,9 +15,10 @@ # RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s ## DT_PLTGOT points to .plt -# SEC: .plt NOBITS 00000000100303f0 0003f0 000018 -# SEC: 0x0000000000000003 (PLTGOT) 0x100303f0 +# SEC: .plt NOBITS 0000000010030400 000400 000018 +# SEC: 0x0000000000000003 (PLTGOT) 0x10030400 # SEC: 0x0000000070000000 (PPC64_GLINK) 0x100102e0 +# SEC: 0x0000000070000003 (PPC64_OPT) 0x0 ## .plt[0] holds the address of _dl_runtime_resolve. ## .plt[1] holds the link map. 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,32 +19,32 @@ .text .section .text_low, "ax", %progbits # CHECK-LABEL: : -# CHECK-NEXT: pld 3, 458936(0), 1 +# CHECK-NEXT: pld 3, 458952(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: 100800b8 0000000100000014 R_PPC64_GLOB_DAT 0000000000000000 glob_int + 0 +# RELA: 100800c8 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, 458928(0), 1 +# CHECK-NEXT: pld 3, 458944(0), 1 # CHECK-NEXT: lwa 3, 8(3) # SYMBOL: 00000000 0 NOTYPE GLOBAL DEFAULT UND glob_int8 -# RELA: 100800c0 0000000200000014 R_PPC64_GLOB_DAT 0000000000000000 glob_int8 + 0 +# RELA: 100800d0 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, 200(0), 1 +# CHECK-NEXT: pld 3, 216(0), 1 # CHECK-NEXT: lwa 3, 64(3) # SYMBOL: 00000000 0 NOTYPE GLOBAL DEFAULT UND glob_int8_big -# RELA: 100800c8 0000000300000014 R_PPC64_GLOB_DAT 0000000000000000 glob_int8_big + 0 +# RELA: 100800d8 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 8 entries: 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,12 +16,12 @@ # RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=IE %s # GD-REL: .rela.dyn { -# 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: 0x20560 R_PPC64_DTPMOD64 a 0x0 +# GD-REL-NEXT: 0x20568 R_PPC64_DTPREL64 a 0x0 +# GD-REL-NEXT: 0x20570 R_PPC64_DTPMOD64 b 0x0 +# GD-REL-NEXT: 0x20578 R_PPC64_DTPREL64 b 0x0 +# GD-REL-NEXT: 0x20580 R_PPC64_DTPMOD64 c 0x0 +# GD-REL-NEXT: 0x20588 R_PPC64_DTPREL64 c 0x0 # GD-REL-NEXT: } ## Start with .got[1] as .got[0] is the .TOC. @@ -60,8 +60,8 @@ # LE-NEXT: addi 3, 3, -28656 # IE-REL: .rela.dyn { -# IE-REL-NEXT: 0x10020420 R_PPC64_TPREL64 b 0x0 -# IE-REL-NEXT: 0x10020428 R_PPC64_TPREL64 c 0x0 +# IE-REL-NEXT: 0x10020430 R_PPC64_TPREL64 b 0x0 +# IE-REL-NEXT: 0x10020438 R_PPC64_TPREL64 c 0x0 # IE-REL-NEXT: } ## a is relaxed to use LE. 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 @@ -24,10 +24,10 @@ # IE-REL: FLAGS STATIC_TLS # IE-REL: .rela.dyn { -# IE-REL-NEXT: 0x204B8 R_PPC64_TPREL64 c 0x0 -# IE-REL-NEXT: 0x204C0 R_PPC64_TPREL64 s 0x0 -# IE-REL-NEXT: 0x204C8 R_PPC64_TPREL64 i 0x0 -# IE-REL-NEXT: 0x204D0 R_PPC64_TPREL64 l 0x0 +# IE-REL-NEXT: 0x204C8 R_PPC64_TPREL64 c 0x0 +# IE-REL-NEXT: 0x204D0 R_PPC64_TPREL64 s 0x0 +# IE-REL-NEXT: 0x204D8 R_PPC64_TPREL64 i 0x0 +# IE-REL-NEXT: 0x204E0 R_PPC64_TPREL64 l 0x0 # IE-REL-NEXT: } # INPUT-REL: R_PPC64_GOT_TPREL16_HA c 0x0 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: 0000000001001178 0000000100000044 R_PPC64_DTPMOD64 0000000000000000 x + 0 -# GD-RELOC: 0000000001001180 000000010000004e R_PPC64_DTPREL64 0000000000000000 x + 0 -# GD-RELOC: 0000000001001188 0000000300000044 R_PPC64_DTPMOD64 0000000000000000 y + 0 -# GD-RELOC: 0000000001001190 000000030000004e R_PPC64_DTPREL64 0000000000000000 y + 0 +# GD-RELOC: 0000000001001188 0000000100000044 R_PPC64_DTPMOD64 0000000000000000 x + 0 +# GD-RELOC: 0000000001001190 000000010000004e R_PPC64_DTPREL64 0000000000000000 x + 0 +# GD-RELOC: 0000000001001198 0000000300000044 R_PPC64_DTPMOD64 0000000000000000 y + 0 +# GD-RELOC: 00000000010011a0 000000030000004e R_PPC64_DTPREL64 0000000000000000 y + 0 # GD-SYM: Symbol table '.dynsym' contains 4 entries: # GD-SYM: 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: 00000000010010e8 0000000100000049 R_PPC64_TPREL64 0000000000000000 x + 0 -# GDTOIE-RELOC: 00000000010010f0 0000000300000049 R_PPC64_TPREL64 0000000000000000 y + 0 +# GDTOIE-RELOC: 00000000010010f8 0000000100000049 R_PPC64_TPREL64 0000000000000000 x + 0 +# GDTOIE-RELOC: 0000000001001100 0000000300000049 R_PPC64_TPREL64 0000000000000000 y + 0 # GDTOIE-SYM: Symbol table '.dynsym' contains 4 entries: # GDTOIE-SYM: 0000000000000000 0 TLS GLOBAL DEFAULT UND x @@ -68,15 +68,15 @@ # GDTOLE-SYM: 0000000000000004 0 TLS GLOBAL DEFAULT 3 y # GD-LABEL: : -# GD-NEXT: paddi 3, 0, 376, 1 +# GD-NEXT: paddi 3, 0, 392, 1 # GD-NEXT: bl -# GD-NEXT: paddi 3, 0, 380, 1 +# GD-NEXT: paddi 3, 0, 396, 1 # GD-NEXT: bl # GD-NEXT: blr # GDTOIE-LABEL: : -# GDTOIE-NEXT: pld 3, 232(0), 1 +# GDTOIE-NEXT: pld 3, 248(0), 1 # GDTOIE-NEXT: add 3, 3, 13 -# GDTOIE-NEXT: pld 3, 228(0), 1 +# GDTOIE-NEXT: pld 3, 244(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,15 +42,15 @@ #--- asm # IE-RELOC: Relocation section '.rela.dyn' at offset 0x10090 contains 2 entries: -# IE-RELOC: 00000000010040e0 0000000100000049 R_PPC64_TPREL64 0000000000000000 x + 0 -# IE-RELOC: 00000000010040e8 0000000200000049 R_PPC64_TPREL64 0000000000000000 y + 0 +# IE-RELOC: 00000000010040f0 0000000100000049 R_PPC64_TPREL64 0000000000000000 x + 0 +# IE-RELOC: 00000000010040f8 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 # IE-SYM: 2: 0000000000000000 0 TLS GLOBAL DEFAULT UND y # IE-GOT: Hex dump of section '.got': -# IE-GOT-NEXT: 0x010040d8 d8c00001 00000000 00000000 00000000 +# IE-GOT-NEXT: 0x010040e8 e8c00001 00000000 00000000 00000000 # LE-RELOC: There are no relocations in this file. @@ -61,7 +61,7 @@ # LE-GOT: could not find section '.got' # IE-LABEL: : -# IE-NEXT: pld 3, 12512(0), 1 +# IE-NEXT: pld 3, 12528(0), 1 # IE-NEXT: add 3, 3, 13 # IE-NEXT: blr # LE-LABEL: : @@ -75,7 +75,7 @@ blr # IE-LABEL: : -# IE-NEXT: pld 3, 12496(0), 1 +# IE-NEXT: pld 3, 12512(0), 1 # IE-NEXT: add 4, 3, 13 # IE-NEXT: blr # LE-LABEL: : @@ -89,7 +89,7 @@ blr # IE-LABEL: : -# IE-NEXT: pld 3, 8416(0), 1 +# IE-NEXT: pld 3, 8432(0), 1 # IE-NEXT: lwzx 3, 3, 13 # IE-NEXT: blr # LE-LABEL: : @@ -103,8 +103,8 @@ blr # IE-LABEL: : -# IE-NEXT: pld 3, 4320(0), 1 -# IE-NEXT: pld 4, 4320(0), 1 +# IE-NEXT: pld 3, 4336(0), 1 +# IE-NEXT: pld 4, 4336(0), 1 # IE-NEXT: lwzx 3, 3, 13 # IE-NEXT: lwzx 4, 4, 13 # IE-NEXT: blr @@ -123,7 +123,7 @@ blr # IE-LABEL: : -# IE-NEXT: pld 4, 232(0), 1 +# IE-NEXT: pld 4, 248(0), 1 # IE-NEXT: lwzx 3, 4, 13 # IE-NEXT: stwx 3, 4, 13 # IE-NEXT: blr diff --git a/lld/test/ELF/ppc64-tls-pcrel-ld.s b/lld/test/ELF/ppc64-tls-pcrel-ld.s --- a/lld/test/ELF/ppc64-tls-pcrel-ld.s +++ b/lld/test/ELF/ppc64-tls-pcrel-ld.s @@ -19,15 +19,15 @@ ## LDTOLE - Local Dynamic relaxed to Local Exec # LD-RELOC: Relocation section '.rela.dyn' at offset 0x10080 contains 1 entries: -# LD-RELOC: 0000000001004168 0000000000000044 R_PPC64_DTPMOD64 0 +# LD-RELOC: 0000000001004178 0000000000000044 R_PPC64_DTPMOD64 0 # LD-SYM: Symbol table '.symtab' contains 11 entries: # LD-SYM: 0000000000000000 0 TLS LOCAL DEFAULT 13 x # LD-SYM: 0000000000000004 0 TLS LOCAL DEFAULT 13 y # LD-GOT: section '.got': -# LD-GOT-NEXT: 0x01004160 60c10001 00000000 00000000 00000000 -# LD-GOT-NEXT: 0x01004170 00000000 00000000 +# LD-GOT-NEXT: 0x01004170 70c10001 00000000 00000000 00000000 +# LD-GOT-NEXT: 0x01004180 00000000 00000000 # LDTOLE-RELOC: There are no relocations in this file. @@ -48,7 +48,7 @@ //--- asm # LD-LABEL: : -# LD: paddi 3, 0, 12644, 1 +# LD: paddi 3, 0, 12660, 1 # LD-NEXT: bl 0x1001020 # LD-NEXT: paddi 3, 3, -32768, 0 # LD-NEXT: blr @@ -69,7 +69,7 @@ blr # LD-LABEL: : -# LD: paddi 3, 0, 8552, 1 +# LD: paddi 3, 0, 8568, 1 # LD-NEXT: bl 0x1001020 # LD-NEXT: paddi 3, 3, -32768, 0 # LD-NEXT: lwz 3, 0(3) @@ -89,7 +89,7 @@ blr # LD-LABEL: : -# LD: paddi 3, 0, 4456, 1 +# LD: paddi 3, 0, 4472, 1 # LD-NEXT: bl 0x1001020 # LD-NEXT: paddi 3, 3, -32768, 0 # LD-NEXT: lwz 2, 0(3) @@ -115,7 +115,7 @@ blr # LD-LABEL: : -# LD: paddi 3, 0, 360, 1 +# LD: paddi 3, 0, 376, 1 # LD-NEXT: bl 0x1001020 # LD-NEXT: paddi 9, 3, -32764, 0 # LD-NEXT: lwz 4, 0(9) diff --git a/lld/test/ELF/ppc64-toc-relax-constants.s b/lld/test/ELF/ppc64-toc-relax-constants.s --- a/lld/test/ELF/ppc64-toc-relax-constants.s +++ b/lld/test/ELF/ppc64-toc-relax-constants.s @@ -23,10 +23,10 @@ # RELOCS-NEXT: 0x14 R_PPC64_TOC16_LO_DS .toc 0x10 # RELOCS-NEXT: } -# SECTIONS: .got PROGBITS 00000000100202f8 -# SECTIONS: .toc PROGBITS 00000000100202f8 +# SECTIONS: .got PROGBITS 0000000010020308 +# SECTIONS: .toc PROGBITS 0000000010020308 -# NM: 0000000010030310 D default +# NM: 0000000010030320 D default # .LCONST1 is .toc[0]. # .LCONST1 - (.got+0x8000) = 0x10020350 - (0x10020350+0x8000) = -32768 diff --git a/lld/test/ELF/ppc64-toc-relax.s b/lld/test/ELF/ppc64-toc-relax.s --- a/lld/test/ELF/ppc64-toc-relax.s +++ b/lld/test/ELF/ppc64-toc-relax.s @@ -52,12 +52,12 @@ # RELOCS-NEXT: 0x18 R_PPC64_ADDR64 default 0x0 # RELOCS-NEXT: } -# NM-DAG: 00000000100303a0 D default -# NM-DAG: 00000000100303a0 d hidden -# NM-DAG: 00000000100403a0 d hidden2 +# NM-DAG: 00000000100303b0 D default +# NM-DAG: 00000000100303b0 d hidden +# NM-DAG: 00000000100403b0 d hidden2 # 'hidden' is non-preemptable. It is relaxed. -# address(hidden) - (.got+0x8000) = 0x100303a0 - (0x10020380+0x8000) = (1<<16) - 32736 +# address(hidden) - (.got+0x8000) = 0x100303b0 - (0x10020390+0x8000) = (1<<16) - 32736 # COMMON: addis 3, 2, 1 # COMMON: addi 3, 3, -32736 # COMMON: lwa 3, 0(3) @@ -65,7 +65,7 @@ ld 3, .Lhidden@toc@l(3) lwa 3, 0(3) -# address(hidden2) - (.got+0x8000) = 0x100403a0 - (0x10020380+0x8000) = (2<<16) - 32736 +# address(hidden2) - (.got+0x8000) = 0x100403b0 - (0x10020390+0x8000) = (2<<16) - 32736 # COMMON: addis 3, 2, 2 # COMMON: addi 3, 3, -32736 # COMMON: lwa 3, 0(3) @@ -84,7 +84,7 @@ lwa 4, 0(4) # 'default' has default visibility. It is non-preemptable when producing an executable. -# address(default) - (.got+0x8000) = 0x100303a0 - (0x10020380+0x8000) = (1<<16) - 32736 +# address(default) - (.got+0x8000) = 0x100303b0 - (0x10020390+0x8000) = (1<<16) - 32736 # EXE: addis 5, 2, 1 # EXE: addi 5, 5, -32736 # EXE: lwa 5, 0(5) diff --git a/llvm/include/llvm/BinaryFormat/DynamicTags.def b/llvm/include/llvm/BinaryFormat/DynamicTags.def --- a/llvm/include/llvm/BinaryFormat/DynamicTags.def +++ b/llvm/include/llvm/BinaryFormat/DynamicTags.def @@ -223,6 +223,8 @@ // PPC64 specific dynamic table entries. PPC64_DYNAMIC_TAG(PPC64_GLINK, 0x70000000) // Address of 32 bytes before the // first glink lazy resolver stub. +PPC64_DYNAMIC_TAG(PPC64_OPT, 0x70000003) // Flags to control optimizations + // for TLS and multiple TOCs. // RISC-V specific dynamic array tags. RISCV_DYNAMIC_TAG(RISCV_VARIANT_CC, 0x70000001)