[lld] r330600 - [PPC64] Fix toc restore nops offset for V2 ABI
Zaara Syeda via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 23 08:01:24 PDT 2018
Author: syzaara
Date: Mon Apr 23 08:01:24 2018
New Revision: 330600
URL: http://llvm.org/viewvc/llvm-project?rev=330600&view=rev
Log:
[PPC64] Fix toc restore nops offset for V2 ABI
The PPC64 V2 ABI restores the toc base by loading from an offset of 24 from r1.
This patch fixes the offset and updates the testcases from V1 to V2. It also
issues an error when a nop is missing after a call to an external function.
Differential Revision: https://reviews.llvm.org/D45892
Added:
lld/trunk/test/ELF/Inputs/ppc64-func.s
lld/trunk/test/ELF/ppc64-error-toc-restore.s
lld/trunk/test/ELF/ppc64-error-toc-tail-call.s
Modified:
lld/trunk/ELF/InputSection.cpp
lld/trunk/test/ELF/ppc64-ifunc.s
lld/trunk/test/ELF/ppc64-toc-restore.s
lld/trunk/test/ELF/ppc64-weak-undef-call-shared.s
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=330600&r1=330599&r2=330600&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Mon Apr 23 08:01:24 2018
@@ -740,8 +740,12 @@ void InputSectionBase::relocateAlloc(uin
break;
case R_PPC_PLT_OPD:
// Patch a nop (0x60000000) to a ld.
- if (BufLoc + 8 <= BufEnd && read32be(BufLoc + 4) == 0x60000000)
- write32be(BufLoc + 4, 0xe8410028); // ld %r2, 40(%r1)
+ if (BufLoc + 8 <= BufEnd && read32(BufLoc + 4) == 0x60000000) {
+ write32(BufLoc + 4, 0xe8410018); // ld %r2, 24(%r1)
+ } else {
+ error(getErrorLocation(BufLoc) + "error: call lacks nop, can't restore toc.");
+ return;
+ }
LLVM_FALLTHROUGH;
default:
Target->relocateOne(BufLoc, Type, TargetVA);
Added: lld/trunk/test/ELF/Inputs/ppc64-func.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/ppc64-func.s?rev=330600&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/ppc64-func.s (added)
+++ lld/trunk/test/ELF/Inputs/ppc64-func.s Mon Apr 23 08:01:24 2018
@@ -0,0 +1,14 @@
+ .text
+ .abiversion 2
+ .globl foo_not_shared
+ .p2align 4
+ .type foo_not_shared, at function
+
+foo_not_shared:
+.Lfunc_begin0:
+ li 3, 55
+ blr
+ .long 0
+ .quad 0
+.Lfunc_end0:
+ .size foo_not_shared, .Lfunc_end0-.Lfunc_begin0
Added: lld/trunk/test/ELF/ppc64-error-toc-restore.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/ppc64-error-toc-restore.s?rev=330600&view=auto
==============================================================================
--- lld/trunk/test/ELF/ppc64-error-toc-restore.s (added)
+++ lld/trunk/test/ELF/ppc64-error-toc-restore.s Mon Apr 23 08:01:24 2018
@@ -0,0 +1,14 @@
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64le.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s
+// REQUIRES: ppc
+
+# Calling external function bar needs a nop
+// CHECK: error: call lacks nop, can't restore toc
+ .text
+ .abiversion 2
+
+.global _start
+_start:
+ bl foo
Added: lld/trunk/test/ELF/ppc64-error-toc-tail-call.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/ppc64-error-toc-tail-call.s?rev=330600&view=auto
==============================================================================
--- lld/trunk/test/ELF/ppc64-error-toc-tail-call.s (added)
+++ lld/trunk/test/ELF/ppc64-error-toc-tail-call.s Mon Apr 23 08:01:24 2018
@@ -0,0 +1,14 @@
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64le.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s
+// REQUIRES: ppc
+
+# A tail call to an external function without a nop should issue an error.
+// CHECK: error: call lacks nop, can't restore toc
+ .text
+ .abiversion 2
+
+.global _start
+_start:
+ b foo
Modified: lld/trunk/test/ELF/ppc64-ifunc.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/ppc64-ifunc.s?rev=330600&r1=330599&r2=330600&view=diff
==============================================================================
--- lld/trunk/test/ELF/ppc64-ifunc.s (original)
+++ lld/trunk/test/ELF/ppc64-ifunc.s Mon Apr 23 08:01:24 2018
@@ -1,34 +1,35 @@
# REQUIRES: ppc
-# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
-# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64le.s -o %t2.o
# RUN: ld.lld -shared %t2.o -o %t2.so
# RUN: ld.lld %t.o %t2.so -o %t
# RUN: llvm-objdump -d %t | FileCheck %s
# CHECK: _start:
-# CHECK-NEXT: 10010004: {{.*}} bl .+12
-# CHECK-NEXT: 10010008: {{.*}} bl .+40
+# CHECK-NEXT: 10010004: 1d 00 00 48 bl .+28
+# CHECK-NEXT: 10010008: 18 00 41 e8 ld 2, 24(1)
+# CHECK-NEXT: 1001000c: 35 00 00 48 bl .+52
+# CHECK-NEXT: 10010010: 18 00 41 e8 ld 2, 24(1)
-# 0x10010004 + 12 = 0x10010010 (PLT entry 0)
-# 0x10010008 + 40 = 0x10010030 (PLT entry 1)
+# 0x10010004 + 28 = 0x10010020 (PLT entry 0)
+# 0x1001000c + 52 = 0x10010040 (PLT entry 1)
# CHECK: Disassembly of section .plt:
-# CHECK: 10010010: {{.*}} std 2, 40(1)
-# CHECK-NEXT: 10010014: {{.*}} addis 11, 2, 4098
-# CHECK-NEXT: 10010018: {{.*}} ld 12, -32744(11)
-# CHECK-NEXT: 1001001c: {{.*}} ld 11, 0(12)
-# CHECK-NEXT: 10010020: {{.*}} mtctr 11
-# CHECK-NEXT: 10010024: {{.*}} ld 2, 8(12)
-# CHECK-NEXT: 10010028: {{.*}} ld 11, 16(12)
-# CHECK-NEXT: 1001002c: {{.*}} bctr
-# CHECK-NEXT: 10010030: {{.*}} std 2, 40(1)
-# CHECK-NEXT: 10010034: {{.*}} addis 11, 2, 4098
-# CHECK-NEXT: 10010038: {{.*}} ld 12, -32736(11)
-# CHECK-NEXT: 1001003c: {{.*}} ld 11, 0(12)
-# CHECK-NEXT: 10010040: {{.*}} mtctr 11
-# CHECK-NEXT: 10010044: {{.*}} ld 2, 8(12)
-# CHECK-NEXT: 10010048: {{.*}} ld 11, 16(12)
-# CHECK-NEXT: 1001004c: {{.*}} bctr
+# CHECK-NEXT: .plt:
+# CHECK-NEXT: 10010020: 18 00 41 f8 std 2, 24(1)
+# CHECK-NEXT: 10010024: 02 10 82 3d addis 12, 2, 4098
+# CHECK-NEXT: 10010028: 10 80 8c e9 ld 12, -32752(12)
+# CHECK-NEXT: 1001002c: a6 03 89 7d mtctr 12
+# CHECK-NEXT: 10010030: 20 04 80 4e bctr
+# CHECK-NEXT: 10010034: 08 00 e0 7f trap
+# CHECK-NEXT: 10010038: 08 00 e0 7f trap
+# CHECK-NEXT: 1001003c: 08 00 e0 7f trap
+# CHECK-NEXT: 10010040: 18 00 41 f8 std 2, 24(1)
+# CHECK-NEXT: 10010044: 02 10 82 3d addis 12, 2, 4098
+# CHECK-NEXT: 10010048: 18 80 8c e9 ld 12, -32744(12)
+# CHECK-NEXT: 1001004c: a6 03 89 7d mtctr 12
+ .text
+ .abiversion 2
.type ifunc STT_GNU_IFUNC
.globl ifunc
@@ -37,5 +38,7 @@ ifunc:
.global _start
_start:
- bl bar
+ bl foo
+ nop
bl ifunc
+ nop
Modified: lld/trunk/test/ELF/ppc64-toc-restore.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/ppc64-toc-restore.s?rev=330600&r1=330599&r2=330600&view=diff
==============================================================================
--- lld/trunk/test/ELF/ppc64-toc-restore.s (original)
+++ lld/trunk/test/ELF/ppc64-toc-restore.s Mon Apr 23 08:01:24 2018
@@ -1,62 +1,69 @@
-// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
-// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64le.s -o %t2.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-func.s -o %t3.o
// RUN: ld.lld -shared %t2.o -o %t2.so
-// RUN: ld.lld %t.o %t2.so -o %t
+// RUN: ld.lld %t.o %t2.so %t3.o -o %t
// RUN: llvm-objdump -d %t | FileCheck %s
// REQUIRES: ppc
+ .text
+ .abiversion 2
+.global bar_local
+bar_local:
+ li 3, 2
+ blr
+# Calling external function foo in a shared object needs a nop.
+# Calling local function bar_local doe snot need a nop.
// CHECK: Disassembly of section .text:
-
.global _start
_start:
- bl bar
+ bl foo
nop
+ bl bar_local
// CHECK: _start:
-// CHECK: 10010000: 48 00 00 21 bl .+32
-// CHECK-NOT: 10010004: 60 00 00 00 nop
-// CHECK: 10010004: e8 41 00 28 ld 2, 40(1)
-
-.global noret
-noret:
- bl bar
- li 5, 7
-
-// CHECK: noret:
-// CHECK: 10010008: 48 00 00 19 bl .+24
-// CHECK: 1001000c: 38 a0 00 07 li 5, 7
-
-.global noretend
-noretend:
- bl bar
-
-// CHECK: noretend:
-// CHECK: 10010010: 48 00 00 11 bl .+16
-
-.global noretb
-noretb:
- b bar
+// CHECK: 10010008: 49 00 00 48 bl .+72
+// CHECK-NOT: 1001000c: 00 00 00 60 nop
+// CHECK: 1001000c: 18 00 41 e8 ld 2, 24(1)
+// CHECK: 10010010: f1 ff ff 4b bl .+67108848
+// CHECK-NOT: 10010014: 00 00 00 60 nop
+// CHECK-NOT: 10010014: 18 00 41 e8 ld 2, 24(1)
+
+# Calling a function in another object file which will have same
+# TOC base does not need a nop. If nop present, do not rewrite to
+# a toc restore
+.global diff_object
+_diff_object:
+ bl foo_not_shared
+ bl foo_not_shared
+ nop
-// CHECK: noretb:
-// CHECK: 10010014: 48 00 00 0c b .+12
+// CHECK: _diff_object:
+// CHECK-NEXT: 10010014: 1d 00 00 48 bl .+28
+// CHECK-NEXT: 10010018: 19 00 00 48 bl .+24
+// CHECK-NEXT: 1001001c: 00 00 00 60 nop
+
+# Branching to a local function does not need a nop
+.global noretbranch
+noretbranch:
+ b bar_local
+// CHECK: noretbranch:
+// CHECK: 10010020: e0 ff ff 4b b .+67108832
+// CHECK-NOT: 10010024: 00 00 00 60 nop
+// CHECK-NOT: 10010024: 18 00 41 e8 ld 2, 24(1)
// This should come last to check the end-of-buffer condition.
.global last
last:
- bl bar
+ bl foo
nop
-
// CHECK: last:
-// CHECK: 10010018: 48 00 00 09 bl .+8
-// CHECK: 1001001c: e8 41 00 28 ld 2, 40(1)
+// CHECK: 10010024: 2d 00 00 48 bl .+44
+// CHECK-NEXT: 10010028: 18 00 41 e8 ld 2, 24(1)
// CHECK: Disassembly of section .plt:
// CHECK: .plt:
-// CHECK: 10010020: f8 41 00 28 std 2, 40(1)
-// CHECK: 10010024: 3d 62 10 02 addis 11, 2, 4098
-// CHECK: 10010028: e9 8b 80 18 ld 12, -32744(11)
-// CHECK: 1001002c: e9 6c 00 00 ld 11, 0(12)
-// CHECK: 10010030: 7d 69 03 a6 mtctr 11
-// CHECK: 10010034: e8 4c 00 08 ld 2, 8(12)
-// CHECK: 10010038: e9 6c 00 10 ld 11, 16(12)
-// CHECK: 1001003c: 4e 80 04 20 bctr
+// CHECK-NEXT: 10010050: 18 00 41 f8 std 2, 24(1)
+// CHECK-NEXT: 10010054: 02 10 82 3d addis 12, 2, 4098
+// CHECK-NEXT: 10010058: 10 80 8c e9 ld 12, -32752(12)
+// CHECK-NEXT: 1001005c: a6 03 89 7d mtctr 12
Modified: lld/trunk/test/ELF/ppc64-weak-undef-call-shared.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/ppc64-weak-undef-call-shared.s?rev=330600&r1=330599&r2=330600&view=diff
==============================================================================
--- lld/trunk/test/ELF/ppc64-weak-undef-call-shared.s (original)
+++ lld/trunk/test/ELF/ppc64-weak-undef-call-shared.s Mon Apr 23 08:01:24 2018
@@ -10,7 +10,7 @@
.text
.Lfoo:
bl weakfunc
+ nop
// CHECK-NOT: R_PPC64_REL24
.weak weakfunc
-
More information about the llvm-commits
mailing list