1292925Sdim#include "tsan_ppc_regs.h" 2292925Sdim 3292925Sdim .section .text 4292925Sdim .hidden __tsan_setjmp 5292925Sdim .globl _setjmp 6292925Sdim .type _setjmp, @function 7292925Sdim .align 4 8292925Sdim#if _CALL_ELF == 2 9292925Sdim_setjmp: 10292925Sdim#else 11292925Sdim .section ".opd","aw" 12292925Sdim .align 3 13292925Sdim_setjmp: 14292925Sdim .quad .L._setjmp,.TOC.@tocbase,0 15292925Sdim .previous 16292925Sdim#endif 17292925Sdim.L._setjmp: 18292925Sdim mflr r0 19292925Sdim stdu r1,-48(r1) 20292925Sdim std r2,24(r1) 21292925Sdim std r3,32(r1) 22292925Sdim std r0,40(r1) 23292925Sdim // r3 is the original stack pointer. 24292925Sdim addi r3,r1,48 25292925Sdim // r4 is the mangled stack pointer (see glibc) 26292925Sdim ld r4,-28696(r13) 27292925Sdim xor r4,r3,r4 28292925Sdim // Materialize a TOC in case we were called from libc. 29292925Sdim // For big-endian, we load the TOC from the OPD. For little- 30292925Sdim // endian, we use the .TOC. symbol to find it. 31292925Sdim nop 32292925Sdim bcl 20,31,0f 33292925Sdim0: 34292925Sdim mflr r2 35292925Sdim#if _CALL_ELF == 2 36292925Sdim addis r2,r2,.TOC.-0b@ha 37292925Sdim addi r2,r2,.TOC.-0b@l 38292925Sdim#else 39292925Sdim addis r2,r2,_setjmp-0b@ha 40292925Sdim addi r2,r2,_setjmp-0b@l 41292925Sdim ld r2,8(r2) 42292925Sdim#endif 43292925Sdim // Call the interceptor. 44292925Sdim bl __tsan_setjmp 45292925Sdim nop 46292925Sdim // Restore regs needed for setjmp. 47292925Sdim ld r3,32(r1) 48292925Sdim ld r0,40(r1) 49292925Sdim // Emulate the real setjmp function. We do this because we can't 50292925Sdim // perform a sibcall: The real setjmp function trashes the TOC 51292925Sdim // pointer, and with a sibcall we have no way to restore it. 52292925Sdim // This way we can make sure our caller's stack pointer and 53292925Sdim // link register are saved correctly in the jmpbuf. 54292925Sdim ld r6,-28696(r13) 55292925Sdim addi r5,r1,48 // original stack ptr of caller 56292925Sdim xor r5,r6,r5 57292925Sdim std r5,0(r3) // mangled stack ptr of caller 58292925Sdim ld r5,24(r1) 59292925Sdim std r5,8(r3) // caller's saved TOC pointer 60292925Sdim xor r0,r6,r0 61292925Sdim std r0,16(r3) // caller's mangled return address 62292925Sdim mfcr r0 63292925Sdim // Nonvolatiles. 64292925Sdim std r14,24(r3) 65292925Sdim stfd f14,176(r3) 66292925Sdim stw r0,172(r3) // CR 67292925Sdim std r15,32(r3) 68292925Sdim stfd f15,184(r3) 69292925Sdim std r16,40(r3) 70292925Sdim stfd f16,192(r3) 71292925Sdim std r17,48(r3) 72292925Sdim stfd f17,200(r3) 73292925Sdim std r18,56(r3) 74292925Sdim stfd f18,208(r3) 75292925Sdim std r19,64(r3) 76292925Sdim stfd f19,216(r3) 77292925Sdim std r20,72(r3) 78292925Sdim stfd f20,224(r3) 79292925Sdim std r21,80(r3) 80292925Sdim stfd f21,232(r3) 81292925Sdim std r22,88(r3) 82292925Sdim stfd f22,240(r3) 83292925Sdim std r23,96(r3) 84292925Sdim stfd f23,248(r3) 85292925Sdim std r24,104(r3) 86292925Sdim stfd f24,256(r3) 87292925Sdim std r25,112(r3) 88292925Sdim stfd f25,264(r3) 89292925Sdim std r26,120(r3) 90292925Sdim stfd f26,272(r3) 91292925Sdim std r27,128(r3) 92292925Sdim stfd f27,280(r3) 93292925Sdim std r28,136(r3) 94292925Sdim stfd f28,288(r3) 95292925Sdim std r29,144(r3) 96292925Sdim stfd f29,296(r3) 97292925Sdim std r30,152(r3) 98292925Sdim stfd f30,304(r3) 99292925Sdim std r31,160(r3) 100292925Sdim stfd f31,312(r3) 101292925Sdim addi r5,r3,320 102292925Sdim mfspr r0,256 103292925Sdim stw r0,168(r3) // VRSAVE 104292925Sdim addi r6,r5,16 105292925Sdim stvx v20,0,r5 106292925Sdim addi r5,r5,32 107292925Sdim stvx v21,0,r6 108292925Sdim addi r6,r6,32 109292925Sdim stvx v22,0,r5 110292925Sdim addi r5,r5,32 111292925Sdim stvx v23,0,r6 112292925Sdim addi r6,r6,32 113292925Sdim stvx v24,0,r5 114292925Sdim addi r5,r5,32 115292925Sdim stvx v25,0,r6 116292925Sdim addi r6,r6,32 117292925Sdim stvx v26,0,r5 118292925Sdim addi r5,r5,32 119292925Sdim stvx v27,0,r6 120292925Sdim addi r6,r6,32 121292925Sdim stvx v28,0,r5 122292925Sdim addi r5,r5,32 123292925Sdim stvx v29,0,r6 124292925Sdim addi r6,r6,32 125292925Sdim stvx v30,0,r5 126292925Sdim stvx v31,0,r6 127292925Sdim // Clear the "mask-saved" slot. 128292925Sdim li r4,0 129292925Sdim stw r4,512(r3) 130292925Sdim // Restore TOC, LR, and stack and return to caller. 131292925Sdim ld r2,24(r1) 132292925Sdim ld r0,40(r1) 133292925Sdim addi r1,r1,48 134292925Sdim li r3,0 // This is the setjmp return path 135292925Sdim mtlr r0 136292925Sdim blr 137292925Sdim .size _setjmp, .-.L._setjmp 138292925Sdim 139292925Sdim .globl setjmp 140292925Sdim .type setjmp, @function 141292925Sdim .align 4 142292925Sdimsetjmp: 143292925Sdim b _setjmp 144292925Sdim .size setjmp, .-setjmp 145292925Sdim 146292925Sdim // sigsetjmp is like setjmp, except that the mask in r4 needs 147292925Sdim // to be saved at offset 512 of the jump buffer. 148292925Sdim .globl __sigsetjmp 149292925Sdim .type __sigsetjmp, @function 150292925Sdim .align 4 151292925Sdim#if _CALL_ELF == 2 152292925Sdim__sigsetjmp: 153292925Sdim#else 154292925Sdim .section ".opd","aw" 155292925Sdim .align 3 156292925Sdim__sigsetjmp: 157292925Sdim .quad .L.__sigsetjmp,.TOC.@tocbase,0 158292925Sdim .previous 159292925Sdim#endif 160292925Sdim.L.__sigsetjmp: 161292925Sdim mflr r0 162292925Sdim stdu r1,-64(r1) 163292925Sdim std r2,24(r1) 164292925Sdim std r3,32(r1) 165292925Sdim std r4,40(r1) 166292925Sdim std r0,48(r1) 167292925Sdim // r3 is the original stack pointer. 168292925Sdim addi r3,r1,64 169292925Sdim // r4 is the mangled stack pointer (see glibc) 170292925Sdim ld r4,-28696(r13) 171292925Sdim xor r4,r3,r4 172292925Sdim // Materialize a TOC in case we were called from libc. 173292925Sdim // For big-endian, we load the TOC from the OPD. For little- 174292925Sdim // endian, we use the .TOC. symbol to find it. 175292925Sdim nop 176292925Sdim bcl 20,31,1f 177292925Sdim1: 178292925Sdim mflr r2 179292925Sdim#if _CALL_ELF == 2 180292925Sdim addis r2,r2,.TOC.-1b@ha 181292925Sdim addi r2,r2,.TOC.-1b@l 182292925Sdim#else 183292925Sdim addis r2,r2,_setjmp-1b@ha 184292925Sdim addi r2,r2,_setjmp-1b@l 185292925Sdim ld r2,8(r2) 186292925Sdim#endif 187292925Sdim // Call the interceptor. 188292925Sdim bl __tsan_setjmp 189292925Sdim nop 190292925Sdim // Restore regs needed for __sigsetjmp. 191292925Sdim ld r3,32(r1) 192292925Sdim ld r4,40(r1) 193292925Sdim ld r0,48(r1) 194292925Sdim // Emulate the real sigsetjmp function. We do this because we can't 195292925Sdim // perform a sibcall: The real sigsetjmp function trashes the TOC 196292925Sdim // pointer, and with a sibcall we have no way to restore it. 197292925Sdim // This way we can make sure our caller's stack pointer and 198292925Sdim // link register are saved correctly in the jmpbuf. 199292925Sdim ld r6,-28696(r13) 200292925Sdim addi r5,r1,64 // original stack ptr of caller 201292925Sdim xor r5,r6,r5 202292925Sdim std r5,0(r3) // mangled stack ptr of caller 203292925Sdim ld r5,24(r1) 204292925Sdim std r5,8(r3) // caller's saved TOC pointer 205292925Sdim xor r0,r6,r0 206292925Sdim std r0,16(r3) // caller's mangled return address 207292925Sdim mfcr r0 208292925Sdim // Nonvolatiles. 209292925Sdim std r14,24(r3) 210292925Sdim stfd f14,176(r3) 211292925Sdim stw r0,172(r3) // CR 212292925Sdim std r15,32(r3) 213292925Sdim stfd f15,184(r3) 214292925Sdim std r16,40(r3) 215292925Sdim stfd f16,192(r3) 216292925Sdim std r17,48(r3) 217292925Sdim stfd f17,200(r3) 218292925Sdim std r18,56(r3) 219292925Sdim stfd f18,208(r3) 220292925Sdim std r19,64(r3) 221292925Sdim stfd f19,216(r3) 222292925Sdim std r20,72(r3) 223292925Sdim stfd f20,224(r3) 224292925Sdim std r21,80(r3) 225292925Sdim stfd f21,232(r3) 226292925Sdim std r22,88(r3) 227292925Sdim stfd f22,240(r3) 228292925Sdim std r23,96(r3) 229292925Sdim stfd f23,248(r3) 230292925Sdim std r24,104(r3) 231292925Sdim stfd f24,256(r3) 232292925Sdim std r25,112(r3) 233292925Sdim stfd f25,264(r3) 234292925Sdim std r26,120(r3) 235292925Sdim stfd f26,272(r3) 236292925Sdim std r27,128(r3) 237292925Sdim stfd f27,280(r3) 238292925Sdim std r28,136(r3) 239292925Sdim stfd f28,288(r3) 240292925Sdim std r29,144(r3) 241292925Sdim stfd f29,296(r3) 242292925Sdim std r30,152(r3) 243292925Sdim stfd f30,304(r3) 244292925Sdim std r31,160(r3) 245292925Sdim stfd f31,312(r3) 246292925Sdim addi r5,r3,320 247292925Sdim mfspr r0,256 248292925Sdim stw r0,168(r3) // VRSAVE 249292925Sdim addi r6,r5,16 250292925Sdim stvx v20,0,r5 251292925Sdim addi r5,r5,32 252292925Sdim stvx v21,0,r6 253292925Sdim addi r6,r6,32 254292925Sdim stvx v22,0,r5 255292925Sdim addi r5,r5,32 256292925Sdim stvx v23,0,r6 257292925Sdim addi r6,r6,32 258292925Sdim stvx v24,0,r5 259292925Sdim addi r5,r5,32 260292925Sdim stvx v25,0,r6 261292925Sdim addi r6,r6,32 262292925Sdim stvx v26,0,r5 263292925Sdim addi r5,r5,32 264292925Sdim stvx v27,0,r6 265292925Sdim addi r6,r6,32 266292925Sdim stvx v28,0,r5 267292925Sdim addi r5,r5,32 268292925Sdim stvx v29,0,r6 269292925Sdim addi r6,r6,32 270292925Sdim stvx v30,0,r5 271292925Sdim stvx v31,0,r6 272292925Sdim // Save into the "mask-saved" slot. 273292925Sdim stw r4,512(r3) 274292925Sdim // Restore TOC, LR, and stack and return to caller. 275292925Sdim ld r2,24(r1) 276292925Sdim ld r0,48(r1) 277292925Sdim addi r1,r1,64 278292925Sdim li r3,0 // This is the sigsetjmp return path 279292925Sdim mtlr r0 280292925Sdim blr 281292925Sdim .size __sigsetjmp, .-.L.__sigsetjmp 282292925Sdim 283292925Sdim .globl sigsetjmp 284292925Sdim .type sigsetjmp, @function 285292925Sdim .align 4 286292925Sdimsigsetjmp: 287292925Sdim b __sigsetjmp 288292925Sdim .size sigsetjmp, .-sigsetjmp 289