summaryrefslogtreecommitdiff
path: root/src/thread
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2018-08-29 12:48:42 -0400
committerRich Felker <dalias@aerifal.cx>2018-08-29 12:48:42 -0400
commit0ec49dab6794166d67fae4764ce7fdea42ea6103 (patch)
treeb2904c92d52d5a884c7e3203b6906b446403702d /src/thread
parent9cdaf1a86bf7790c8dec749118392ee78101ee37 (diff)
downloadmusl-0ec49dab6794166d67fae4764ce7fdea42ea6103.tar.gz
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.
Diffstat (limited to 'src/thread')
-rw-r--r--src/thread/powerpc64/syscall_cp.s7
1 files changed, 7 insertions, 0 deletions
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