289 lines · plain
1#include "tsan_ppc_regs.h"2 3 .section .text4 .hidden __tsan_setjmp5 .globl _setjmp6 .type _setjmp, @function7 .align 48#if _CALL_ELF == 29_setjmp:10#else11 .section ".opd","aw"12 .align 313_setjmp:14 .quad .L._setjmp,.TOC.@tocbase,015 .previous16#endif17.L._setjmp:18 mflr r019 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,4825 // r4 is the mangled stack pointer (see glibc)26 ld r4,-28696(r13)27 xor r4,r3,r428 // 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 nop32 bcl 20,31,0f330:34 mflr r235#if _CALL_ELF == 236 addis r2,r2,.TOC.-0b@ha37 addi r2,r2,.TOC.-0b@l38#else39 addis r2,r2,_setjmp-0b@ha40 addi r2,r2,_setjmp-0b@l41 ld r2,8(r2)42#endif43 // Call the interceptor.44 bl __tsan_setjmp45 nop46 // 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't50 // perform a sibcall: The real setjmp function trashes the TOC51 // pointer, and with a sibcall we have no way to restore it.52 // This way we can make sure our caller's stack pointer and53 // link register are saved correctly in the jmpbuf.54 ld r6,-28696(r13)55 addi r5,r1,48 // original stack ptr of caller56 xor r5,r6,r557 std r5,0(r3) // mangled stack ptr of caller58 ld r5,24(r1)59 std r5,8(r3) // caller's saved TOC pointer60 xor r0,r6,r061 std r0,16(r3) // caller's mangled return address62 mfcr r063 // Nonvolatiles.64 std r14,24(r3)65 stfd f14,176(r3)66 stw r0,172(r3) // CR67 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,320102 mfspr r0,256103 stw r0,168(r3) // VRSAVE104 addi r6,r5,16105 stvx v20,0,r5106 addi r5,r5,32107 stvx v21,0,r6108 addi r6,r6,32109 stvx v22,0,r5110 addi r5,r5,32111 stvx v23,0,r6112 addi r6,r6,32113 stvx v24,0,r5114 addi r5,r5,32115 stvx v25,0,r6116 addi r6,r6,32117 stvx v26,0,r5118 addi r5,r5,32119 stvx v27,0,r6120 addi r6,r6,32121 stvx v28,0,r5122 addi r5,r5,32123 stvx v29,0,r6124 addi r6,r6,32125 stvx v30,0,r5126 stvx v31,0,r6127 // Clear the "mask-saved" slot.128 li r4,0129 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,48134 li r3,0 // This is the setjmp return path135 mtlr r0136 blr137 .size _setjmp, .-.L._setjmp138 139 .globl setjmp140 .type setjmp, @function141 .align 4142setjmp:143 b _setjmp144 .size setjmp, .-setjmp145 146 // sigsetjmp is like setjmp, except that the mask in r4 needs147 // to be saved at offset 512 of the jump buffer.148 .globl __sigsetjmp149 .type __sigsetjmp, @function150 .align 4151#if _CALL_ELF == 2152__sigsetjmp:153#else154 .section ".opd","aw"155 .align 3156__sigsetjmp:157 .quad .L.__sigsetjmp,.TOC.@tocbase,0158 .previous159#endif160.L.__sigsetjmp:161 mflr r0162 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,64169 // r4 is the mangled stack pointer (see glibc)170 ld r4,-28696(r13)171 xor r4,r3,r4172 // 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 nop176 bcl 20,31,1f1771:178 mflr r2179#if _CALL_ELF == 2180 addis r2,r2,.TOC.-1b@ha181 addi r2,r2,.TOC.-1b@l182#else183 addis r2,r2,_setjmp-1b@ha184 addi r2,r2,_setjmp-1b@l185 ld r2,8(r2)186#endif187 // Call the interceptor.188 bl __tsan_setjmp189 nop190 // 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't195 // perform a sibcall: The real sigsetjmp function trashes the TOC196 // pointer, and with a sibcall we have no way to restore it.197 // This way we can make sure our caller's stack pointer and198 // link register are saved correctly in the jmpbuf.199 ld r6,-28696(r13)200 addi r5,r1,64 // original stack ptr of caller201 xor r5,r6,r5202 std r5,0(r3) // mangled stack ptr of caller203 ld r5,24(r1)204 std r5,8(r3) // caller's saved TOC pointer205 xor r0,r6,r0206 std r0,16(r3) // caller's mangled return address207 mfcr r0208 // Nonvolatiles.209 std r14,24(r3)210 stfd f14,176(r3)211 stw r0,172(r3) // CR212 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,320247 mfspr r0,256248 stw r0,168(r3) // VRSAVE249 addi r6,r5,16250 stvx v20,0,r5251 addi r5,r5,32252 stvx v21,0,r6253 addi r6,r6,32254 stvx v22,0,r5255 addi r5,r5,32256 stvx v23,0,r6257 addi r6,r6,32258 stvx v24,0,r5259 addi r5,r5,32260 stvx v25,0,r6261 addi r6,r6,32262 stvx v26,0,r5263 addi r5,r5,32264 stvx v27,0,r6265 addi r6,r6,32266 stvx v28,0,r5267 addi r5,r5,32268 stvx v29,0,r6269 addi r6,r6,32270 stvx v30,0,r5271 stvx v31,0,r6272 // 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,64278 li r3,0 // This is the sigsetjmp return path279 mtlr r0280 blr281 .size __sigsetjmp, .-.L.__sigsetjmp282 283 .globl sigsetjmp284 .type sigsetjmp, @function285 .align 4286sigsetjmp:287 b __sigsetjmp288 .size sigsetjmp, .-sigsetjmp289