Index: lld/ELF/Writer.cpp =================================================================== --- lld/ELF/Writer.cpp +++ lld/ELF/Writer.cpp @@ -663,6 +663,9 @@ if (InX::Got && Sec == InX::Got->getParent()) return true; + if (Sec->Name.equals(".toc")) + return true; + // .got.plt contains pointers to external function symbols. They are // by default resolved lazily, so we usually cannot put it into RELRO. // However, if "-z now" is given, the lazy symbol resolution is @@ -707,8 +710,9 @@ RF_BSS = 1 << 8, RF_NOTE = 1 << 7, RF_PPC_NOT_TOCBSS = 1 << 6, - RF_PPC_TOCL = 1 << 4, - RF_PPC_TOC = 1 << 3, + RF_PPC_TOCL = 1 << 5, + RF_PPC_TOC = 1 << 4, + RF_PPC_GOT = 1 << 3, RF_PPC_BRANCH_LT = 1 << 2, RF_MIPS_GPREL = 1 << 1, RF_MIPS_NOT_GOT = 1 << 0 @@ -827,6 +831,9 @@ if (Name == ".toc") Rank |= RF_PPC_TOC; + if (Name == ".got") + Rank |= RF_PPC_GOT; + if (Name == ".branch_lt") Rank |= RF_PPC_BRANCH_LT; } Index: lld/test/ELF/ppc64-func-entry-points.s =================================================================== --- lld/test/ELF/ppc64-func-entry-points.s +++ lld/test/ELF/ppc64-func-entry-points.s @@ -75,6 +75,6 @@ // CHECK: foo_external_diff: // CHECK-NEXT: 10010080: {{.*}} addis 2, 12, 2 // CHECK-NEXT: 10010084: {{.*}} addi 2, 2, 32640 -// CHECK-NEXT: 10010088: {{.*}} addis 5, 2, -1 +// CHECK-NEXT: 10010088: {{.*}} addis 5, 2, 0 // CHECK: foo_external_same: // CHECK-NEXT: 100100b0: {{.*}} add 3, 4, 3 Index: lld/test/ELF/ppc64-got-indirect.s =================================================================== --- /dev/null +++ lld/test/ELF/ppc64-got-indirect.s @@ -0,0 +1,115 @@ +# REQUIRES: ppc + +# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o +# RUN: llvm-readobj -relocations %t.o | FileCheck -check-prefix=RELOCS-LE %s +# RUN: ld.lld %t.o -o %t2 +# RUN: llvm-objdump -D %t2 | FileCheck %s --check-prefix=CHECK-LE +# RUN: llvm-objdump -D %t2 | FileCheck %s + +# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o +# RUN: llvm-readobj -relocations %t.o | FileCheck -check-prefix=RELOCS-BE %s +# RUN: ld.lld %t.o -o %t2 +# RUN: llvm-objdump -D %t2 | FileCheck %s --check-prefix=CHECK-BE +# RUN: llvm-objdump -D %t2 | FileCheck %s + +# Make sure we calculate the offset correctly for a got-indirect access to a +# global variable as described by the PPC64 ELF V2 abi. + .text + .abiversion 2 + .globl _start # -- Begin function _start + .p2align 4 + .type _start,@function +_start: # @_start +.Lfunc_begin0: +.Lfunc_gep0: + addis 2, 12, .TOC.-.Lfunc_gep0@ha + addi 2, 2, .TOC.-.Lfunc_gep0@l +.Lfunc_lep0: + .localentry _start, .Lfunc_lep0-.Lfunc_gep0 +# %bb.0: # %entry + addis 3, 2, .LC0@toc@ha + ld 3, .LC0@toc@l(3) + li 4, 0 + stw 4, -12(1) + li 0,1 + lwa 3, 0(3) + sc + .long 0 + .quad 0 +.Lfunc_end0: + .size _start, .Lfunc_end0-.Lfunc_begin0 + # -- End function + .section .toc,"aw",@progbits +.LC0: + .tc glob[TC],glob + .type glob,@object # @glob + .data + .globl glob + .p2align 2 +glob: + .long 55 # 0x37 + .size glob, 4 + +# Verify the relocations emitted for glob are through the .toc + +# RELOCS-LE: Relocations [ +# RELOCS-LE: .rela.text { +# RELOCS-LE: 0x0 R_PPC64_REL16_HA .TOC. 0x0 +# RELOCS-LE: 0x4 R_PPC64_REL16_LO .TOC. 0x4 +# RELOCS-LE: 0x8 R_PPC64_TOC16_HA .toc 0x0 +# RELOCS-LE: 0xC R_PPC64_TOC16_LO_DS .toc 0x0 +# RELOCS-LE: } +# RELOCS-LE: .rela.toc { +# RELOCS-LE: 0x0 R_PPC64_ADDR64 glob 0x0 +# RELOCS-LE: } + +# RELOCS-BE: Relocations [ +# RELOCS-BE: .rela.text { +# RELOCS-BE: 0x2 R_PPC64_REL16_HA .TOC. 0x2 +# RELOCS-BE: 0x6 R_PPC64_REL16_LO .TOC. 0x6 +# RELOCS-BE: 0xA R_PPC64_TOC16_HA .toc 0x0 +# RELOCS-BE: 0xE R_PPC64_TOC16_LO_DS .toc 0x0 +# RELOCS-BE: } +# RELOCS-BE: .rela.toc { +# RELOCS-BE: 0x0 R_PPC64_ADDR64 glob 0x0 +# RELOCS-BE: } +# RELOCS-BE:] + +# Verify that the global variable access is done through the correct +# toc entry: +# r2 = .TOC. = 0x10038000. +# r3 = r2 - 32760 = 0x10030008 -> .toc entry for glob. + +# CHECK: _start: +# CHECK-NEXT: 10010000: {{.*}} addis 2, 12, 3 +# CHECK-NEXT: 10010004: {{.*}} addi 2, 2, -32768 +# CHECK-NEXT: 10010008: {{.*}} addis 3, 2, 0 +# CHECK-NEXT: 1001000c: {{.*}} ld 3, -32760(3) +# CHECK: 1001001c: {{.*}} lwa 3, 0(3) + +# CHECK-LE: Disassembly of section .data: +# CHECK-LE-NEXT: glob: +# CHECK-LE-NEXT: 10020000: 37 00 00 00 + +# CHECK-LE: Disassembly of section .got: +# CHECK-LE-NEXT: .got: +# CHECK-LE-NEXT: 10030000: 00 80 03 10 +# CHECK-LE-NEXT: 10030004: 00 00 00 00 + +# Verify that .toc comes right after .got +# CHECK-LE: Disassembly of section .toc: +# CHECK-LE: 10030008: 00 00 02 10 + +# CHECK-BE: Disassembly of section .data: +# CHECK-BE-NEXT: glob: +# CHECK-BE-NEXT: 10020000: 00 00 00 37 + +# CHECK-BE: Disassembly of section .got: +# CHECK-BE-NEXT: .got: +# CHECK-BE-NEXT: 10030000: 00 00 00 00 +# CHECK-BE-NEXT: 10030004: 10 03 80 00 + +# Verify that .toc comes right after .got +# CHECK-BE: Disassembly of section .toc: +# CHECK-BE: 10030008: 00 00 00 00 +# CHECK-BE: 1003000c: 10 02 00 00 Index: lld/test/ELF/ppc64-relocs.s =================================================================== --- lld/test/ELF/ppc64-relocs.s +++ lld/test/ELF/ppc64-relocs.s @@ -54,7 +54,7 @@ # CHECK: Disassembly of section .R_PPC64_TOC16_HI: # CHECK: .FR_PPC64_TOC16_HI: -# CHECK: 10010014: {{.*}} addis 1, 2, -2 +# CHECK: 10010014: {{.*}} addis 1, 2, -1 .section .R_PPC64_TOC16_HA,"ax",@progbits .globl .FR_PPC64_TOC16_HA @@ -63,7 +63,7 @@ # CHECK: Disassembly of section .R_PPC64_TOC16_HA: # CHECK: .FR_PPC64_TOC16_HA: -# CHECK: 10010018: {{.*}} addis 1, 2, -1 +# CHECK: 10010018: {{.*}} addis 1, 2, 0 .section .R_PPC64_REL24,"ax",@progbits .globl .FR_PPC64_REL24 @@ -160,7 +160,7 @@ # 0x10000190 + 0xfeb4 = 0x10010044 # CHECK: Disassembly of section .R_PPC64_REL32: # CHECK: .FR_PPC64_REL32: -# CHECK: 1001003c: {{.*}} addis 5, 2, -1 +# CHECK: 1001003c: {{.*}} addis 5, 2, 0 # CHECK: 10010040: {{.*}} ld 5, -32736(5) # CHECK: 10010044: {{.*}} add 3, 3, 4