diff options
author | Bobby Bingham <koorogi@koorogi.info> | 2017-08-04 00:12:32 -0500 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2017-08-11 20:31:33 -0400 |
commit | e31c8c2d796e8a9596503f079dc567c45f93c2ae (patch) | |
tree | 11d78ae147d030b5ead0e005cd470d8841b0c8fa /src/signal | |
parent | 52cf5c18f4ad3a7a59fb7113cf115c6fc05c7494 (diff) | |
download | musl-e31c8c2d796e8a9596503f079dc567c45f93c2ae.tar.gz musl-e31c8c2d796e8a9596503f079dc567c45f93c2ae.tar.bz2 musl-e31c8c2d796e8a9596503f079dc567c45f93c2ae.tar.xz musl-e31c8c2d796e8a9596503f079dc567c45f93c2ae.zip |
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.
Diffstat (limited to 'src/signal')
-rw-r--r-- | src/signal/powerpc64/sigsetjmp.s | 21 |
1 files changed, 14 insertions, 7 deletions
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 |