123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- #include "tsan_ppc_regs.h"
- .section .text
- .hidden __tsan_setjmp
- .globl _setjmp
- .type _setjmp, @function
- .align 4
- #if _CALL_ELF == 2
- _setjmp:
- #else
- .section ".opd","aw"
- .align 3
- _setjmp:
- .quad .L._setjmp,.TOC.@tocbase,0
- .previous
- #endif
- .L._setjmp:
- mflr r0
- stdu r1,-48(r1)
- std r2,24(r1)
- std r3,32(r1)
- std r0,40(r1)
- // r3 is the original stack pointer.
- addi r3,r1,48
- // r4 is the mangled stack pointer (see glibc)
- ld r4,-28696(r13)
- xor r4,r3,r4
- // Materialize a TOC in case we were called from libc.
- // For big-endian, we load the TOC from the OPD. For little-
- // endian, we use the .TOC. symbol to find it.
- nop
- bcl 20,31,0f
- 0:
- mflr r2
- #if _CALL_ELF == 2
- addis r2,r2,.TOC.-0b@ha
- addi r2,r2,.TOC.-0b@l
- #else
- addis r2,r2,_setjmp-0b@ha
- addi r2,r2,_setjmp-0b@l
- ld r2,8(r2)
- #endif
- // Call the interceptor.
- bl __tsan_setjmp
- nop
- // Restore regs needed for setjmp.
- ld r3,32(r1)
- ld r0,40(r1)
- // Emulate the real setjmp function. We do this because we can't
- // perform a sibcall: The real setjmp function trashes the TOC
- // pointer, and with a sibcall we have no way to restore it.
- // This way we can make sure our caller's stack pointer and
- // link register are saved correctly in the jmpbuf.
- ld r6,-28696(r13)
- addi r5,r1,48 // original stack ptr of caller
- xor r5,r6,r5
- std r5,0(r3) // mangled stack ptr of caller
- ld r5,24(r1)
- std r5,8(r3) // caller's saved TOC pointer
- xor r0,r6,r0
- std r0,16(r3) // caller's mangled return address
- mfcr r0
- // Nonvolatiles.
- std r14,24(r3)
- stfd f14,176(r3)
- stw r0,172(r3) // CR
- std r15,32(r3)
- stfd f15,184(r3)
- std r16,40(r3)
- stfd f16,192(r3)
- std r17,48(r3)
- stfd f17,200(r3)
- std r18,56(r3)
- stfd f18,208(r3)
- std r19,64(r3)
- stfd f19,216(r3)
- std r20,72(r3)
- stfd f20,224(r3)
- std r21,80(r3)
- stfd f21,232(r3)
- std r22,88(r3)
- stfd f22,240(r3)
- std r23,96(r3)
- stfd f23,248(r3)
- std r24,104(r3)
- stfd f24,256(r3)
- std r25,112(r3)
- stfd f25,264(r3)
- std r26,120(r3)
- stfd f26,272(r3)
- std r27,128(r3)
- stfd f27,280(r3)
- std r28,136(r3)
- stfd f28,288(r3)
- std r29,144(r3)
- stfd f29,296(r3)
- std r30,152(r3)
- stfd f30,304(r3)
- std r31,160(r3)
- stfd f31,312(r3)
- addi r5,r3,320
- mfspr r0,256
- stw r0,168(r3) // VRSAVE
- addi r6,r5,16
- stvx v20,0,r5
- addi r5,r5,32
- stvx v21,0,r6
- addi r6,r6,32
- stvx v22,0,r5
- addi r5,r5,32
- stvx v23,0,r6
- addi r6,r6,32
- stvx v24,0,r5
- addi r5,r5,32
- stvx v25,0,r6
- addi r6,r6,32
- stvx v26,0,r5
- addi r5,r5,32
- stvx v27,0,r6
- addi r6,r6,32
- stvx v28,0,r5
- addi r5,r5,32
- stvx v29,0,r6
- addi r6,r6,32
- stvx v30,0,r5
- stvx v31,0,r6
- // Clear the "mask-saved" slot.
- li r4,0
- stw r4,512(r3)
- // Restore TOC, LR, and stack and return to caller.
- ld r2,24(r1)
- ld r0,40(r1)
- addi r1,r1,48
- li r3,0 // This is the setjmp return path
- mtlr r0
- blr
- .size _setjmp, .-.L._setjmp
- .globl setjmp
- .type setjmp, @function
- .align 4
- setjmp:
- b _setjmp
- .size setjmp, .-setjmp
- // sigsetjmp is like setjmp, except that the mask in r4 needs
- // to be saved at offset 512 of the jump buffer.
- .globl __sigsetjmp
- .type __sigsetjmp, @function
- .align 4
- #if _CALL_ELF == 2
- __sigsetjmp:
- #else
- .section ".opd","aw"
- .align 3
- __sigsetjmp:
- .quad .L.__sigsetjmp,.TOC.@tocbase,0
- .previous
- #endif
- .L.__sigsetjmp:
- mflr r0
- stdu r1,-64(r1)
- std r2,24(r1)
- std r3,32(r1)
- std r4,40(r1)
- std r0,48(r1)
- // r3 is the original stack pointer.
- addi r3,r1,64
- // r4 is the mangled stack pointer (see glibc)
- ld r4,-28696(r13)
- xor r4,r3,r4
- // Materialize a TOC in case we were called from libc.
- // For big-endian, we load the TOC from the OPD. For little-
- // endian, we use the .TOC. symbol to find it.
- nop
- bcl 20,31,1f
- 1:
- mflr r2
- #if _CALL_ELF == 2
- addis r2,r2,.TOC.-1b@ha
- addi r2,r2,.TOC.-1b@l
- #else
- addis r2,r2,_setjmp-1b@ha
- addi r2,r2,_setjmp-1b@l
- ld r2,8(r2)
- #endif
- // Call the interceptor.
- bl __tsan_setjmp
- nop
- // Restore regs needed for __sigsetjmp.
- ld r3,32(r1)
- ld r4,40(r1)
- ld r0,48(r1)
- // Emulate the real sigsetjmp function. We do this because we can't
- // perform a sibcall: The real sigsetjmp function trashes the TOC
- // pointer, and with a sibcall we have no way to restore it.
- // This way we can make sure our caller's stack pointer and
- // link register are saved correctly in the jmpbuf.
- ld r6,-28696(r13)
- addi r5,r1,64 // original stack ptr of caller
- xor r5,r6,r5
- std r5,0(r3) // mangled stack ptr of caller
- ld r5,24(r1)
- std r5,8(r3) // caller's saved TOC pointer
- xor r0,r6,r0
- std r0,16(r3) // caller's mangled return address
- mfcr r0
- // Nonvolatiles.
- std r14,24(r3)
- stfd f14,176(r3)
- stw r0,172(r3) // CR
- std r15,32(r3)
- stfd f15,184(r3)
- std r16,40(r3)
- stfd f16,192(r3)
- std r17,48(r3)
- stfd f17,200(r3)
- std r18,56(r3)
- stfd f18,208(r3)
- std r19,64(r3)
- stfd f19,216(r3)
- std r20,72(r3)
- stfd f20,224(r3)
- std r21,80(r3)
- stfd f21,232(r3)
- std r22,88(r3)
- stfd f22,240(r3)
- std r23,96(r3)
- stfd f23,248(r3)
- std r24,104(r3)
- stfd f24,256(r3)
- std r25,112(r3)
- stfd f25,264(r3)
- std r26,120(r3)
- stfd f26,272(r3)
- std r27,128(r3)
- stfd f27,280(r3)
- std r28,136(r3)
- stfd f28,288(r3)
- std r29,144(r3)
- stfd f29,296(r3)
- std r30,152(r3)
- stfd f30,304(r3)
- std r31,160(r3)
- stfd f31,312(r3)
- addi r5,r3,320
- mfspr r0,256
- stw r0,168(r3) // VRSAVE
- addi r6,r5,16
- stvx v20,0,r5
- addi r5,r5,32
- stvx v21,0,r6
- addi r6,r6,32
- stvx v22,0,r5
- addi r5,r5,32
- stvx v23,0,r6
- addi r6,r6,32
- stvx v24,0,r5
- addi r5,r5,32
- stvx v25,0,r6
- addi r6,r6,32
- stvx v26,0,r5
- addi r5,r5,32
- stvx v27,0,r6
- addi r6,r6,32
- stvx v28,0,r5
- addi r5,r5,32
- stvx v29,0,r6
- addi r6,r6,32
- stvx v30,0,r5
- stvx v31,0,r6
- // Save into the "mask-saved" slot.
- stw r4,512(r3)
- // Restore TOC, LR, and stack and return to caller.
- ld r2,24(r1)
- ld r0,48(r1)
- addi r1,r1,64
- li r3,0 // This is the sigsetjmp return path
- mtlr r0
- blr
- .size __sigsetjmp, .-.L.__sigsetjmp
- .globl sigsetjmp
- .type sigsetjmp, @function
- .align 4
- sigsetjmp:
- b __sigsetjmp
- .size sigsetjmp, .-sigsetjmp
|