111
|
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
|
|
33 0:
|
|
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
|
|
142 setjmp:
|
|
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
|
|
177 1:
|
|
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
|
|
286 sigsetjmp:
|
|
287 b __sigsetjmp
|
|
288 .size sigsetjmp, .-sigsetjmp
|