289 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
			
		
		
	
	
			289 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
#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
 |