1#include "tsan_ppc_regs.h" 2 3 .section .text 4 .hidden __tsan_setjmp 5 .globl _setjmp 6 .type _setjmp, @function 7 .align 4 8#if _CALL_ELF == 2 9_setjmp: 10#else 11 .section ".opd","aw" 12 .align 3 13_setjmp: 14 .quad .L._setjmp,.TOC.@tocbase,0 15 .previous 16#endif 17.L._setjmp: 18 mflr r0 19 stdu r1,-48(r1) 20 std r2,24(r1) 21 std r3,32(r1) 22 std r0,40(r1) 23 // r3 is the original stack pointer. 24 addi r3,r1,48 25 // r4 is the mangled stack pointer (see glibc) 26 ld r4,-28696(r13) 27 xor r4,r3,r4 28 // Materialize a TOC in case we were called from libc. 29 // For big-endian, we load the TOC from the OPD. For little- 30 // endian, we use the .TOC. symbol to find it. 31 nop 32 bcl 20,31,0f 330: 34 mflr r2 35#if _CALL_ELF == 2 36 addis r2,r2,.TOC.-0b@ha 37 addi r2,r2,.TOC.-0b@l 38#else 39 addis r2,r2,_setjmp-0b@ha 40 addi r2,r2,_setjmp-0b@l 41 ld r2,8(r2) 42#endif 43 // Call the interceptor. 44 bl __tsan_setjmp 45 nop 46 // Restore regs needed for setjmp. 47 ld r3,32(r1) 48 ld r0,40(r1) 49 // Emulate the real setjmp function. We do this because we can't 50 // perform a sibcall: The real setjmp function trashes the TOC 51 // pointer, and with a sibcall we have no way to restore it. 52 // This way we can make sure our caller's stack pointer and 53 // link register are saved correctly in the jmpbuf. 54 ld r6,-28696(r13) 55 addi r5,r1,48 // original stack ptr of caller 56 xor r5,r6,r5 57 std r5,0(r3) // mangled stack ptr of caller 58 ld r5,24(r1) 59 std r5,8(r3) // caller's saved TOC pointer 60 xor r0,r6,r0 61 std r0,16(r3) // caller's mangled return address 62 mfcr r0 63 // Nonvolatiles. 64 std r14,24(r3) 65 stfd f14,176(r3) 66 stw r0,172(r3) // CR 67 std r15,32(r3) 68 stfd f15,184(r3) 69 std r16,40(r3) 70 stfd f16,192(r3) 71 std r17,48(r3) 72 stfd f17,200(r3) 73 std r18,56(r3) 74 stfd f18,208(r3) 75 std r19,64(r3) 76 stfd f19,216(r3) 77 std r20,72(r3) 78 stfd f20,224(r3) 79 std r21,80(r3) 80 stfd f21,232(r3) 81 std r22,88(r3) 82 stfd f22,240(r3) 83 std r23,96(r3) 84 stfd f23,248(r3) 85 std r24,104(r3) 86 stfd f24,256(r3) 87 std r25,112(r3) 88 stfd f25,264(r3) 89 std r26,120(r3) 90 stfd f26,272(r3) 91 std r27,128(r3) 92 stfd f27,280(r3) 93 std r28,136(r3) 94 stfd f28,288(r3) 95 std r29,144(r3) 96 stfd f29,296(r3) 97 std r30,152(r3) 98 stfd f30,304(r3) 99 std r31,160(r3) 100 stfd f31,312(r3) 101 addi r5,r3,320 102 mfspr r0,256 103 stw r0,168(r3) // VRSAVE 104 addi r6,r5,16 105 stvx v20,0,r5 106 addi r5,r5,32 107 stvx v21,0,r6 108 addi r6,r6,32 109 stvx v22,0,r5 110 addi r5,r5,32 111 stvx v23,0,r6 112 addi r6,r6,32 113 stvx v24,0,r5 114 addi r5,r5,32 115 stvx v25,0,r6 116 addi r6,r6,32 117 stvx v26,0,r5 118 addi r5,r5,32 119 stvx v27,0,r6 120 addi r6,r6,32 121 stvx v28,0,r5 122 addi r5,r5,32 123 stvx v29,0,r6 124 addi r6,r6,32 125 stvx v30,0,r5 126 stvx v31,0,r6 127 // Clear the "mask-saved" slot. 128 li r4,0 129 stw r4,512(r3) 130 // Restore TOC, LR, and stack and return to caller. 131 ld r2,24(r1) 132 ld r0,40(r1) 133 addi r1,r1,48 134 li r3,0 // This is the setjmp return path 135 mtlr r0 136 blr 137 .size _setjmp, .-.L._setjmp 138 139 .globl setjmp 140 .type setjmp, @function 141 .align 4 142setjmp: 143 b _setjmp 144 .size setjmp, .-setjmp 145 146 // sigsetjmp is like setjmp, except that the mask in r4 needs 147 // to be saved at offset 512 of the jump buffer. 148 .globl __sigsetjmp 149 .type __sigsetjmp, @function 150 .align 4 151#if _CALL_ELF == 2 152__sigsetjmp: 153#else 154 .section ".opd","aw" 155 .align 3 156__sigsetjmp: 157 .quad .L.__sigsetjmp,.TOC.@tocbase,0 158 .previous 159#endif 160.L.__sigsetjmp: 161 mflr r0 162 stdu r1,-64(r1) 163 std r2,24(r1) 164 std r3,32(r1) 165 std r4,40(r1) 166 std r0,48(r1) 167 // r3 is the original stack pointer. 168 addi r3,r1,64 169 // r4 is the mangled stack pointer (see glibc) 170 ld r4,-28696(r13) 171 xor r4,r3,r4 172 // Materialize a TOC in case we were called from libc. 173 // For big-endian, we load the TOC from the OPD. For little- 174 // endian, we use the .TOC. symbol to find it. 175 nop 176 bcl 20,31,1f 1771: 178 mflr r2 179#if _CALL_ELF == 2 180 addis r2,r2,.TOC.-1b@ha 181 addi r2,r2,.TOC.-1b@l 182#else 183 addis r2,r2,_setjmp-1b@ha 184 addi r2,r2,_setjmp-1b@l 185 ld r2,8(r2) 186#endif 187 // Call the interceptor. 188 bl __tsan_setjmp 189 nop 190 // Restore regs needed for __sigsetjmp. 191 ld r3,32(r1) 192 ld r4,40(r1) 193 ld r0,48(r1) 194 // Emulate the real sigsetjmp function. We do this because we can't 195 // perform a sibcall: The real sigsetjmp function trashes the TOC 196 // pointer, and with a sibcall we have no way to restore it. 197 // This way we can make sure our caller's stack pointer and 198 // link register are saved correctly in the jmpbuf. 199 ld r6,-28696(r13) 200 addi r5,r1,64 // original stack ptr of caller 201 xor r5,r6,r5 202 std r5,0(r3) // mangled stack ptr of caller 203 ld r5,24(r1) 204 std r5,8(r3) // caller's saved TOC pointer 205 xor r0,r6,r0 206 std r0,16(r3) // caller's mangled return address 207 mfcr r0 208 // Nonvolatiles. 209 std r14,24(r3) 210 stfd f14,176(r3) 211 stw r0,172(r3) // CR 212 std r15,32(r3) 213 stfd f15,184(r3) 214 std r16,40(r3) 215 stfd f16,192(r3) 216 std r17,48(r3) 217 stfd f17,200(r3) 218 std r18,56(r3) 219 stfd f18,208(r3) 220 std r19,64(r3) 221 stfd f19,216(r3) 222 std r20,72(r3) 223 stfd f20,224(r3) 224 std r21,80(r3) 225 stfd f21,232(r3) 226 std r22,88(r3) 227 stfd f22,240(r3) 228 std r23,96(r3) 229 stfd f23,248(r3) 230 std r24,104(r3) 231 stfd f24,256(r3) 232 std r25,112(r3) 233 stfd f25,264(r3) 234 std r26,120(r3) 235 stfd f26,272(r3) 236 std r27,128(r3) 237 stfd f27,280(r3) 238 std r28,136(r3) 239 stfd f28,288(r3) 240 std r29,144(r3) 241 stfd f29,296(r3) 242 std r30,152(r3) 243 stfd f30,304(r3) 244 std r31,160(r3) 245 stfd f31,312(r3) 246 addi r5,r3,320 247 mfspr r0,256 248 stw r0,168(r3) // VRSAVE 249 addi r6,r5,16 250 stvx v20,0,r5 251 addi r5,r5,32 252 stvx v21,0,r6 253 addi r6,r6,32 254 stvx v22,0,r5 255 addi r5,r5,32 256 stvx v23,0,r6 257 addi r6,r6,32 258 stvx v24,0,r5 259 addi r5,r5,32 260 stvx v25,0,r6 261 addi r6,r6,32 262 stvx v26,0,r5 263 addi r5,r5,32 264 stvx v27,0,r6 265 addi r6,r6,32 266 stvx v28,0,r5 267 addi r5,r5,32 268 stvx v29,0,r6 269 addi r6,r6,32 270 stvx v30,0,r5 271 stvx v31,0,r6 272 // Save into the "mask-saved" slot. 273 stw r4,512(r3) 274 // Restore TOC, LR, and stack and return to caller. 275 ld r2,24(r1) 276 ld r0,48(r1) 277 addi r1,r1,64 278 li r3,0 // This is the sigsetjmp return path 279 mtlr r0 280 blr 281 .size __sigsetjmp, .-.L.__sigsetjmp 282 283 .globl sigsetjmp 284 .type sigsetjmp, @function 285 .align 4 286sigsetjmp: 287 b __sigsetjmp 288 .size sigsetjmp, .-sigsetjmp 289