[lld] r331046 - [PPC64] Add offset to local entry point when calling functions without plt

Zaara Syeda via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 27 08:41:20 PDT 2018


Author: syzaara
Date: Fri Apr 27 08:41:19 2018
New Revision: 331046

URL: http://llvm.org/viewvc/llvm-project?rev=331046&view=rev
Log:
[PPC64] Add offset to local entry point when calling functions without plt

PPC64 V2 ABI describes two entry points to a function. The global entry point
sets up the TOC base pointer. When calling a local function, the call should
branch to the local entry point rather than the global entry point.
Section 3.4.1 describes using the 3 most significant bits of the st_other
field to find out how many instructions there are between the local and global
entry point. This patch adds the correct offset required to branch to the local
entry point of a function.

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

Added:
    lld/trunk/test/ELF/Inputs/ppc64-func-global-entry.s
    lld/trunk/test/ELF/Inputs/ppc64-func-local-entry.s
    lld/trunk/test/ELF/ppc64-func-entry-points.s
Modified:
    lld/trunk/ELF/InputSection.cpp

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=331046&r1=331045&r2=331046&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Fri Apr 27 08:41:19 2018
@@ -584,7 +584,18 @@ static uint64_t getRelocTargetVA(RelType
       if (InOpd)
         SymVA = read64be(&Out::OpdBuf[SymVA - OpdStart]);
     }
-    return SymVA - P;
+
+    // PPC64 V2 ABI describes two entry points to a function. The global entry
+    // point sets up the TOC base pointer. When calling a local function, the
+    // call should branch to the local entry point rather than the global entry
+    // point. Section 3.4.1 describes using the 3 most significant bits of the
+    // st_other field to find out how many instructions there are between the
+    // local and global entry point.
+    uint8_t StOther = (Sym.StOther >> 5) & 7;
+    if (StOther == 0 || StOther == 1)
+      return SymVA - P;
+
+    return SymVA - P + (1 << StOther);
   }
   case R_PPC_TOC:
     return getPPC64TocBase() + A;

Added: lld/trunk/test/ELF/Inputs/ppc64-func-global-entry.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/ppc64-func-global-entry.s?rev=331046&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/ppc64-func-global-entry.s (added)
+++ lld/trunk/test/ELF/Inputs/ppc64-func-global-entry.s Fri Apr 27 08:41:19 2018
@@ -0,0 +1,35 @@
+	.text
+	.abiversion 2
+	.globl	foo_external_diff       # -- Begin function foo_external_diff
+	.p2align	4
+	.type	foo_external_diff, at function
+foo_external_diff:                      # @foo_external_diff
+.Lfunc_begin0:
+.Lfunc_gep0:
+	addis 2, 12, .TOC.-.Lfunc_gep0 at ha
+	addi 2, 2, .TOC.-.Lfunc_gep0 at l
+.Lfunc_lep0:
+	.localentry	foo_external_diff, .Lfunc_lep0-.Lfunc_gep0
+# %bb.0:                                # %entry
+	addis 5, 2, .LC0 at toc@ha
+	add 3, 4, 3
+	ld 5, .LC0 at toc@l(5)
+	lwz 5, 0(5)
+	add 3, 3, 5
+	extsw 3, 3
+	blr
+	.long	0
+	.quad	0
+.Lfunc_end0:
+	.size	foo_external_diff, .Lfunc_end0-.Lfunc_begin0
+                                        # -- End function
+	.section	.toc,"aw", at progbits
+.LC0:
+	.tc glob2[TC],glob2
+	.type	glob2, at object           # @glob2
+	.data
+	.globl	glob2
+	.p2align	2
+glob2:
+	.long	10                      # 0xa
+	.size	glob2, 4

Added: lld/trunk/test/ELF/Inputs/ppc64-func-local-entry.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/ppc64-func-local-entry.s?rev=331046&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/ppc64-func-local-entry.s (added)
+++ lld/trunk/test/ELF/Inputs/ppc64-func-local-entry.s Fri Apr 27 08:41:19 2018
@@ -0,0 +1,16 @@
+	.text
+	.abiversion 2
+	.globl	foo_external_same       # -- Begin function foo_external_same
+	.p2align	4
+	.type	foo_external_same, at function
+foo_external_same:                      # @foo_external_same
+.Lfunc_begin0:
+# %bb.0:                                # %entry
+	add 3, 4, 3
+	extsw 3, 3
+	blr
+	.long	0
+	.quad	0
+.Lfunc_end0:
+	.size	foo_external_same, .Lfunc_end0-.Lfunc_begin0
+                                        # -- End function

Added: 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=331046&view=auto
==============================================================================
--- lld/trunk/test/ELF/ppc64-func-entry-points.s (added)
+++ lld/trunk/test/ELF/ppc64-func-entry-points.s Fri Apr 27 08:41:19 2018
@@ -0,0 +1,72 @@
+// REQUIRES: ppc
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-func-global-entry.s -o %t2.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-func-local-entry.s -o %t3.o
+// RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.o %t3.o -o %t
+// RUN: llvm-objdump -d %t | FileCheck %s
+	.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
+	mflr 0
+	std 0, 16(1)
+	stdu 1, -48(1)
+	li 3, 1
+	li 4, 1
+	std 30, 32(1)                   # 8-byte Folded Spill
+	bl foo_external_same
+	nop
+	mr 30, 3
+	li 3, 2
+	li 4, 2
+	bl foo_external_diff
+	nop
+	addis 4, 2, .LC0 at toc@ha
+	add 3, 3, 30
+	ld 30, 32(1)                    # 8-byte Folded Reload
+	ld 4, .LC0 at toc@l(4)
+	lwz 4, 0(4)
+	add 3, 3, 4
+	extsw 3, 3
+	addi 1, 1, 48
+	ld 0, 16(1)
+	li 0, 1
+	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	10                      # 0xa
+	.size	glob, 4
+
+# Check that foo_external_diff has a global entry point and we branch to
+# foo_external_diff+8. Also check that foo_external_same has no global entry
+# point and we branch to start of foo_external_same.
+
+// CHECK: _start:
+// CHECK: 10010020:       91 00 00 48     bl .+144
+// CHECK: 10010034:       55 00 00 48     bl .+84
+// CHECK: foo_external_diff:
+// CHECK-NEXT: 10010080:       02 00 4c 3c     addis 2, 12, 2
+// CHECK-NEXT: 10010084:       80 7f 42 38     addi 2, 2, 32640
+// CHECK-NEXT: 10010088:       ff ff a2 3c     addis 5, 2, -1
+// CHECK: foo_external_same:
+// CHECK-NEXT: 100100b0:       14 1a 64 7c     add 3, 4, 3




More information about the llvm-commits mailing list