From 0ec49dab6794166d67fae4764ce7fdea42ea6103 Mon Sep 17 00:00:00 2001
From: Rich Felker <dalias@aerifal.cx>
Date: Wed, 29 Aug 2018 12:48:42 -0400
Subject: fix async thread cancellation on powerpc64

entering the local entry point for __cancel from __cp_cancel is valid
if __cp_cancel was reached from __syscall_cp, since both are in libc
and share the same TOC pointer, but it is not valid if __cp_cancel was
reached when cancel_handler rewrote the program counter for
asynchronous cancellation of code outside libc.

to ensure __cancel is entered with a valid TOC pointer, recompute the
correct value in a PC-relative manner before jumping.
---
 src/thread/powerpc64/syscall_cp.s | 7 +++++++
 1 file changed, 7 insertions(+)

(limited to 'src')

diff --git a/src/thread/powerpc64/syscall_cp.s b/src/thread/powerpc64/syscall_cp.s
index d420dbde..ef50ed00 100644
--- a/src/thread/powerpc64/syscall_cp.s
+++ b/src/thread/powerpc64/syscall_cp.s
@@ -34,4 +34,11 @@ __cp_end:
 	blr
 
 __cp_cancel:
+	mflr 0
+	bl 1f
+	.long .TOC.-.
+1:	mflr 3
+	lwa 2, 0(3)
+	add 2, 2, 3
+	mtlr 0
 	b __cancel
-- 
cgit v1.2.3-70-g09d2