diff options
author | Roberto Oliveira <robertoguimaraes8@gmail.com> | 2017-08-24 20:49:50 +0000 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2017-08-24 22:53:52 +0000 |
commit | b1779fe77e90b5b5fb89c1959918b013eef06b33 (patch) | |
tree | 1d1fe0fcf156defaf001705b4bf21d9b7db17e43 /main/musl/0058-ppc64-fix-setjmp-longjmp-handling-of-TOC-pointer.patch | |
parent | 20412e4430bff12378f461a5b0b0bbe310440a97 (diff) | |
download | aports-b1779fe77e90b5b5fb89c1959918b013eef06b33.tar.bz2 aports-b1779fe77e90b5b5fb89c1959918b013eef06b33.tar.xz |
main/musl: backport ppc64 fix for setjmp/longjmp handling of TOC pointer
Diffstat (limited to 'main/musl/0058-ppc64-fix-setjmp-longjmp-handling-of-TOC-pointer.patch')
-rw-r--r-- | main/musl/0058-ppc64-fix-setjmp-longjmp-handling-of-TOC-pointer.patch | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/main/musl/0058-ppc64-fix-setjmp-longjmp-handling-of-TOC-pointer.patch b/main/musl/0058-ppc64-fix-setjmp-longjmp-handling-of-TOC-pointer.patch new file mode 100644 index 0000000000..37d188b77c --- /dev/null +++ b/main/musl/0058-ppc64-fix-setjmp-longjmp-handling-of-TOC-pointer.patch @@ -0,0 +1,178 @@ +From e31c8c2d796e8a9596503f079dc567c45f93c2ae Mon Sep 17 00:00:00 2001 +From: Bobby Bingham <koorogi@koorogi.info> +Date: Fri, 4 Aug 2017 00:12:32 -0500 +Subject: [PATCH] ppc64: fix setjmp/longjmp handling of TOC pointer + +The TOC pointer is constant within a single dso, but needs to be saved +and restored around cross-dso calls. The PLT stub saves it to the +caller's stack frame, and the linker adds code to the caller to restore +it. + +With a local call, as within a single dso or with static linking, this +doesn't happen and the TOC pointer is always in r2. Therefore, +setjmp/longjmp need to save/restore the TOC pointer from/to different +locations depending on whether the call to setjmp was a local or non-local +call. + +It is always safe for longjmp to restore to both r2 and the caller's stack. +If the call to setjmp was local, and only r2 matters and the stack location +will be ignored, but is required by the ABI to be reserved for the TOC +pointer. If the call was non-local, then only the stack location matters, +and whatever is restored into r2 will be clobbered anyway when the caller +reloads r2 from the stack. + +A little extra care is required for sigsetjmp, because it uses setjmp +internally. After the second return from this setjmp call, r2 will contain +the caller's TOC pointer instead of libc's TOC pointer. We need to save +and restore the correct libc pointer before we can tail call to +__sigsetjmp_tail. +--- + src/setjmp/powerpc64/longjmp.s | 14 +++++++++----- + src/setjmp/powerpc64/setjmp.s | 21 ++++++++++++++++----- + src/signal/powerpc64/sigsetjmp.s | 21 ++++++++++++++------- + 3 files changed, 39 insertions(+), 17 deletions(-) + +diff --git a/src/setjmp/powerpc64/longjmp.s b/src/setjmp/powerpc64/longjmp.s +index 7f241c2d..81d45ff6 100644 +--- a/src/setjmp/powerpc64/longjmp.s ++++ b/src/setjmp/powerpc64/longjmp.s +@@ -10,10 +10,14 @@ longjmp: + # 1) restore cr + ld 0, 1*8(3) + mtcr 0 +- # 2) restore r1-r2 (SP and TOC) ++ # 2) restore SP + ld 1, 2*8(3) ++ # 3) restore TOC into both r2 and the caller's stack. ++ # Which location is required depends on whether setjmp was called ++ # locally or non-locally, but it's always safe to restore to both. + ld 2, 3*8(3) +- # 3) restore r14-r31 ++ std 2, 24(1) ++ # 4) restore r14-r31 + ld 14, 4*8(3) + ld 15, 5*8(3) + ld 16, 6*8(3) +@@ -32,7 +36,7 @@ longjmp: + ld 29, 19*8(3) + ld 30, 20*8(3) + ld 31, 21*8(3) +- # 4) restore floating point registers f14-f31 ++ # 5) restore floating point registers f14-f31 + lfd 14, 22*8(3) + lfd 15, 23*8(3) + lfd 16, 24*8(3) +@@ -52,7 +56,7 @@ longjmp: + lfd 30, 38*8(3) + lfd 31, 39*8(3) + +- # 5) restore vector registers v20-v31 ++ # 6) restore vector registers v20-v31 + addi 3, 3, 40*8 + lvx 20, 0, 3 ; addi 3, 3, 16 + lvx 21, 0, 3 ; addi 3, 3, 16 +@@ -67,7 +71,7 @@ longjmp: + lvx 30, 0, 3 ; addi 3, 3, 16 + lvx 31, 0, 3 + +- # 6) return r4 ? r4 : 1 ++ # 7) return r4 ? r4 : 1 + mr 3, 4 + cmpwi cr7, 4, 0 + bne cr7, 1f +diff --git a/src/setjmp/powerpc64/setjmp.s b/src/setjmp/powerpc64/setjmp.s +index d16d4bae..37683fda 100644 +--- a/src/setjmp/powerpc64/setjmp.s ++++ b/src/setjmp/powerpc64/setjmp.s +@@ -1,24 +1,35 @@ +- .global ___setjmp +- .hidden ___setjmp + .global __setjmp + .global _setjmp + .global setjmp + .type __setjmp,@function + .type _setjmp,@function + .type setjmp,@function +-___setjmp: + __setjmp: + _setjmp: + setjmp: ++ ld 5, 24(1) # load from the TOC slot in the caller's stack frame ++ b __setjmp_toc ++ ++ .localentry __setjmp,.-__setjmp ++ .localentry _setjmp,.-_setjmp ++ .localentry setjmp,.-setjmp ++ mr 5, 2 ++ ++ .global __setjmp_toc ++ .hidden __setjmp_toc ++ # same as normal setjmp, except TOC pointer to save is provided in r5. ++ # r4 would normally be the 2nd parameter, but we're using r5 to simplify calling from sigsetjmp. ++ # solves the problem of knowing whether to save the TOC pointer from r2 or the caller's stack frame. ++__setjmp_toc: + # 0) store IP into 0, then into the jmpbuf pointed to by r3 (first arg) + mflr 0 + std 0, 0*8(3) + # 1) store cr + mfcr 0 + std 0, 1*8(3) +- # 2) store r1-r2 (SP and TOC) ++ # 2) store SP and TOC + std 1, 2*8(3) +- std 2, 3*8(3) ++ std 5, 3*8(3) + # 3) store r14-31 + std 14, 4*8(3) + std 15, 5*8(3) +diff --git a/src/signal/powerpc64/sigsetjmp.s b/src/signal/powerpc64/sigsetjmp.s +index 52ac1d03..410c2831 100644 +--- a/src/signal/powerpc64/sigsetjmp.s ++++ b/src/signal/powerpc64/sigsetjmp.s +@@ -2,29 +2,36 @@ + .global __sigsetjmp + .type sigsetjmp,%function + .type __sigsetjmp,%function +- .hidden ___setjmp ++ .hidden __setjmp_toc + sigsetjmp: + __sigsetjmp: + addis 2, 12, .TOC.-__sigsetjmp@ha + addi 2, 2, .TOC.-__sigsetjmp@l ++ ld 5, 24(1) # load from the TOC slot in the caller's stack frame ++ b 1f ++ + .localentry sigsetjmp,.-sigsetjmp + .localentry __sigsetjmp,.-__sigsetjmp ++ mr 5, 2 + ++1: + cmpwi cr7, 4, 0 +- beq- cr7, ___setjmp ++ beq- cr7, __setjmp_toc + +- mflr 5 +- std 5, 512(3) +- std 16, 512+8+8(3) ++ mflr 6 ++ std 6, 512(3) ++ std 2, 512+16(3) ++ std 16, 512+24(3) + mr 16, 3 + +- bl ___setjmp ++ bl __setjmp_toc + + mr 4, 3 + mr 3, 16 + ld 5, 512(3) + mtlr 5 +- ld 16, 512+8+8(3) ++ ld 2, 512+16(3) ++ ld 16, 512+24(3) + + .hidden __sigsetjmp_tail + b __sigsetjmp_tail +-- +2.13.1 + |