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