[lld] r333199 - [PPC64] Add .toc section after .got section

Zaara Syeda via llvm-commits llvm-commits at lists.llvm.org
Thu May 24 08:59:41 PDT 2018


Author: syzaara
Date: Thu May 24 08:59:41 2018
New Revision: 333199

URL: http://llvm.org/viewvc/llvm-project?rev=333199&view=rev
Log:
[PPC64] Add .toc section after .got section

PPC64 maintains a compiler managed got in the .toc section. When accessing a
global variable through got-indirect access, a .toc entry is created for the
variable. The relocation for the got-indirect access will refer to the .toc
section rather than the symbol that is actually accessed. The .toc entry
contains the address of the global variable. We evaluate the offset from
r2 (which is the TOC base) to the address of the toc entry for the global
variable. Currently, the .toc is not near the .got. This causes errors because
the offset from r2 to the toc section is too large. The linker needs to add
all the .toc input sections to the .got output section, merging the compiler
managed got with the linker got. This ensures that the offsets from the TOC
base to the toc entries are not too large.

This patch puts the .toc section right after the .got section.

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

Added:
    lld/trunk/test/ELF/ppc64-got-indirect.s
Modified:
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/ppc64-func-entry-points.s
    lld/trunk/test/ELF/ppc64-relocs.s

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=333199&r1=333198&r2=333199&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu May 24 08:59:41 2018
@@ -663,6 +663,9 @@ static bool isRelroSection(const OutputS
   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 @@ enum RankFlags {
   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 @@ static unsigned getSectionRank(const Out
     if (Name == ".toc")
       Rank |= RF_PPC_TOC;
 
+    if (Name == ".got")
+      Rank |= RF_PPC_GOT;
+
     if (Name == ".branch_lt")
       Rank |= RF_PPC_BRANCH_LT;
   }

Modified: lld/trunk/test/ELF/ppc64-func-entry-points.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/ppc64-func-entry-points.s?rev=333199&r1=333198&r2=333199&view=diff
==============================================================================
--- lld/trunk/test/ELF/ppc64-func-entry-points.s (original)
+++ lld/trunk/test/ELF/ppc64-func-entry-points.s Thu May 24 08:59:41 2018
@@ -75,6 +75,6 @@ glob:
 // 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

Added: lld/trunk/test/ELF/ppc64-got-indirect.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/ppc64-got-indirect.s?rev=333199&view=auto
==============================================================================
--- lld/trunk/test/ELF/ppc64-got-indirect.s (added)
+++ lld/trunk/test/ELF/ppc64-got-indirect.s Thu May 24 08:59:41 2018
@@ -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, at function
+_start:                                   # @_start
+.Lfunc_begin0:
+.Lfunc_gep0:
+  addis 2, 12, .TOC.-.Lfunc_gep0 at ha
+  addi 2, 2, .TOC.-.Lfunc_gep0 at l
+.Lfunc_lep0:
+  .localentry  _start, .Lfunc_lep0-.Lfunc_gep0
+# %bb.0:                                # %entry
+  addis 3, 2, .LC0 at toc@ha
+  ld 3, .LC0 at 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", at progbits
+.LC0:
+  .tc glob[TC],glob
+  .type  glob, at 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

Modified: lld/trunk/test/ELF/ppc64-relocs.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/ppc64-relocs.s?rev=333199&r1=333198&r2=333199&view=diff
==============================================================================
--- lld/trunk/test/ELF/ppc64-relocs.s (original)
+++ lld/trunk/test/ELF/ppc64-relocs.s Thu May 24 08:59:41 2018
@@ -54,7 +54,7 @@ _start:
 
 # 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", at progbits
 .globl .FR_PPC64_TOC16_HA
@@ -63,7 +63,7 @@ _start:
 
 # 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", at progbits
 .globl .FR_PPC64_REL24
@@ -160,7 +160,7 @@ _start:
 # 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
 




More information about the llvm-commits mailing list