[LLD] Emit DT_PPC64_OPT into the dynamic section
authorStefan Pintilie <stefanp@ca.ibm.com>
Fri, 2 Jun 2023 18:46:25 +0000 (14:46 -0400)
committerStefan Pintilie <stefanp@ca.ibm.com>
Mon, 5 Jun 2023 16:18:29 +0000 (12:18 -0400)
As per section 4.2.2 of the PowerPC ELFv2 ABI, this value tells the dynamic linker which optimizations it is allowed to do.
Specifically, the higher order bit of the two tells the dynamic linker that there may be multiple TOC pointers in the binary.

When we resolve any NOTOC relocations during linking, we need to set this value because we may be calling
TOC functions from NOTOC functions when the NOTOC function already clobbered the TOC pointer.

In practice, this ensures that the PLT resolver always resolves the call to the GEP (global entry point) of
the TOC function (which will set up the TOC for the TOC function).

Original patch by nemanjai

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D150631

24 files changed:
lld/ELF/SyntheticSections.cpp
lld/ELF/Target.h
lld/ELF/Thunks.cpp
lld/test/ELF/basic-ppc64.s
lld/test/ELF/ppc-reloc-copy.s
lld/test/ELF/ppc64-abs64-dyn.s
lld/test/ELF/ppc64-bsymbolic-toc-restore.s
lld/test/ELF/ppc64-check-missing-tocbase.s
lld/test/ELF/ppc64-dtprel.s
lld/test/ELF/ppc64-local-dynamic.s
lld/test/ELF/ppc64-long-branch-pi.s
lld/test/ELF/ppc64-pcrel-call-to-extern.s
lld/test/ELF/ppc64-pcrel-long-branch.s
lld/test/ELF/ppc64-plt-stub-compatible.s
lld/test/ELF/ppc64-plt-stub.s
lld/test/ELF/ppc64-reloc-got-pcrel34.s
lld/test/ELF/ppc64-tls-gd.s
lld/test/ELF/ppc64-tls-ie.s
lld/test/ELF/ppc64-tls-pcrel-gd.s
lld/test/ELF/ppc64-tls-pcrel-ie.s
lld/test/ELF/ppc64-tls-pcrel-ld.s
lld/test/ELF/ppc64-toc-relax-constants.s
lld/test/ELF/ppc64-toc-relax.s
llvm/include/llvm/BinaryFormat/DynamicTags.def

index 2dc263d..88534d2 100644 (file)
@@ -1531,6 +1531,9 @@ DynamicSection<ELFT>::computeContents() {
     addInt(DT_PPC64_GLINK, in.plt->getVA() + target->pltHeaderSize - 32);
   }
 
+  if (config->emachine == EM_PPC64)
+    addInt(DT_PPC64_OPT, getPPC64TargetInfo()->ppc64DynamicSectionOpt);
+
   addInt(DT_NULL, 0);
   return entries;
 }
index e6a7816..59534ab 100644 (file)
@@ -140,6 +140,12 @@ public:
   // 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 ppc64DynamicSectionOpt = 0;
+
   bool needsThunks = false;
 
   // A 4-byte field corresponding to one or more trap instructions, used to pad
index 26f3041..331e28e 100644 (file)
@@ -1367,6 +1367,12 @@ static Thunk *addThunkPPC64(RelType type, Symbol &s, int64_t a) {
   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()->ppc64DynamicSectionOpt = 0x2;
+
   if (s.isInPlt())
     return type == R_PPC64_REL24_NOTOC
                ? (Thunk *)make<PPC64R12SetupStub>(s, /*gotPlt=*/true)
index 4032cec..3bf0541 100644 (file)
@@ -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:  ]
 // 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
 // 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 {
 // 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
 // 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
 // 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
 // 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
 // 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
 // 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)
 // 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)
 // 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)
index 1f169e4..7e10706 100644 (file)
 # 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)
index 48818c1..a674a3e 100644 (file)
 ## 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
index a55d79e..052d15f 100644 (file)
@@ -63,7 +63,7 @@ caller:
 # CHECK-EMPTY:
 # CHECK-NEXT:  <def>:
 # 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
index e7a34ee..5a4c0ad 100644 (file)
 # 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
index 4871b78..d3b065f 100644 (file)
@@ -140,12 +140,12 @@ k:
 // 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:     <test>:
 // Dis:      addi 4, 3, -31744
index 0113116..393901e 100644 (file)
@@ -98,7 +98,7 @@ k:
 // 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.
index 6cc596b..43919be 100644 (file)
 # 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>:
index a929cb3..e5846e8 100644 (file)
 # SYMBOL-NOP10-NEXT: 11: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT [<other: 0x60>] 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: <caller1>:
 # 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
 
 # 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
 
 # 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
 
 # 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
 
 # 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
 
 # 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
 
index 4c8e3b2..d7ca9f5 100644 (file)
@@ -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: <high>:
 # CHECK-NEXT:    2002000: blr
 
+# READELF: (PPC64_OPT) 0x2
+
 .section .text_low, "ax", %progbits
 .globl _start
 _start:
index 11c5389..9561918 100644 (file)
@@ -29,9 +29,9 @@ callee:
 
 # T2-LABEL: <p9codegen>:
 # 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 @@ callee:
 # 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 @@ Global:
 
 # T3-LABEL: <p9codegen>:
 # 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
 
index 76d12d4..6e0206f 100644 (file)
 # 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.
index e5a3643..24265aa 100644 (file)
 .text
 .section .text_low, "ax", %progbits
 # CHECK-LABEL: <GlobIntPCRel>:
-# 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: <GlobIntPCRelOffset>:
-# 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: <GlobIntPCRelBigOffset>:
-# 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:
index 9a1e6fc..a3a0630 100644 (file)
 # 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.
index 8c03ba2..8da808b 100644 (file)
 
 # 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
index e2ec15c..2ffaad0 100644 (file)
@@ -42,10 +42,10 @@ y:
 #--- 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 @@ y:
 
 
 # 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 @@ y:
 # GDTOLE-SYM: 0000000000000004     0 TLS     GLOBAL DEFAULT     3 y
 
 # GD-LABEL: <GDTwoVal>:
-# 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: <GDTwoVal>:
-# 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: <GDTwoVal>:
index 7eca204..f7a828d 100644 (file)
@@ -42,15 +42,15 @@ y:
 
 #--- 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 @@ y:
 # LE-GOT: could not find section '.got'
 
 # IE-LABEL: <IEAddr>:
-# 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: <IEAddr>:
@@ -75,7 +75,7 @@ IEAddr:
        blr
 
 # IE-LABEL: <IEAddrCopy>:
-# 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: <IEAddrCopy>:
@@ -89,7 +89,7 @@ IEAddrCopy:
        blr
 
 # IE-LABEL: <IEVal>:
-# 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: <IEVal>:
@@ -103,8 +103,8 @@ IEVal:
        blr
 
 # IE-LABEL: <IETwoVal>:
-# 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 @@ IETwoVal:
        blr
 
 # IE-LABEL: <IEIncrementVal>:
-# 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
index a7f244d..7c225dc 100644 (file)
 ## 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 @@ SECTIONS {
 
 //--- asm
 # LD-LABEL: <LDAddr>:
-# 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 @@ LDAddr:
   blr
 
 # LD-LABEL: <LDVal>:
-# 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 @@ LDVal:
   blr
 
 # LD-LABEL: <LDTwoVal>:
-# 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 @@ LDTwoVal:
   blr
 
 # LD-LABEL: <LDIncrementVal>:
-# 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)
index 6a0adc2..b7c446c 100644 (file)
 # 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
index 3f14deb..59aed15 100644 (file)
 # 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)
index 7bb248c..f393b82 100644 (file)
@@ -223,6 +223,8 @@ PPC_DYNAMIC_TAG(PPC_OPT, 0x70000001) // Has TLS optimization.
 // 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)