blob: 68c101e8cb3c445fb3794fc50b48760a902184ee [file] [log] [blame]
sewardj6c591e12011-04-11 16:17:51 +00001
2/*--------------------------------------------------------------------*/
3/*--- A minimal setjmp/longjmp implementation. m_libcsetjmp.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
Elliott Hughesed398002017-06-21 14:41:24 -070010 Copyright (C) 2010-2017 Mozilla Inc
sewardj6c591e12011-04-11 16:17:51 +000011
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25 02111-1307, USA.
26
27 The GNU General Public License is contained in the file COPYING.
28*/
29
30/* Contributed by Julian Seward <jseward@acm.org> */
31
32
33#include "pub_core_basics.h"
34#include "pub_core_libcsetjmp.h" /* self */
35
36
37/* See include/pub_tool_libcsetjmp.h for background and rationale. */
38
sewardjda91ee72011-09-29 18:29:41 +000039/* The alternative implementations are for ppc{32,64}-linux and
Elliott Hughesa0664b92017-04-18 17:46:52 -070040 {amd64,x86}-{linux,darwin,solaris}. See #259977. That leaves only
sewardjda91ee72011-09-29 18:29:41 +000041 {arm,s390x}-linux using the gcc builtins now.
42*/
sewardj97d3ebb2011-04-11 18:36:34 +000043
sewardj2a88a012011-04-11 21:26:27 +000044/* ------------ ppc32-linux ------------ */
45
sewardj97d3ebb2011-04-11 18:36:34 +000046#if defined(VGP_ppc32_linux)
47
48__asm__(
49".text" "\n"
sewardj2a88a012011-04-11 21:26:27 +000050"" "\n"
sewardj97d3ebb2011-04-11 18:36:34 +000051".global VG_MINIMAL_SETJMP" "\n" // r3 = jmp_buf
52"VG_MINIMAL_SETJMP:" "\n"
53" stw 0, 0(3)" "\n"
54" stw 1, 4(3)" "\n"
55" stw 2, 8(3)" "\n"
56" stw 3, 12(3)" "\n"
57" stw 4, 16(3)" "\n"
58" stw 5, 20(3)" "\n"
59" stw 6, 24(3)" "\n"
60" stw 7, 28(3)" "\n"
61" stw 8, 32(3)" "\n"
62" stw 9, 36(3)" "\n"
63" stw 10, 40(3)" "\n"
64" stw 11, 44(3)" "\n"
65" stw 12, 48(3)" "\n"
66" stw 13, 52(3)" "\n"
67" stw 14, 56(3)" "\n"
68" stw 15, 60(3)" "\n"
69" stw 16, 64(3)" "\n"
70" stw 17, 68(3)" "\n"
71" stw 18, 72(3)" "\n"
72" stw 19, 76(3)" "\n"
73" stw 20, 80(3)" "\n"
74" stw 21, 84(3)" "\n"
75" stw 22, 88(3)" "\n"
76" stw 23, 92(3)" "\n"
77" stw 24, 96(3)" "\n"
78" stw 25, 100(3)" "\n"
79" stw 26, 104(3)" "\n"
80" stw 27, 108(3)" "\n"
81" stw 28, 112(3)" "\n"
82" stw 29, 116(3)" "\n"
83" stw 30, 120(3)" "\n"
84" stw 31, 124(3)" "\n"
85 // must use a caller-save register here as scratch, hence r4
86" mflr 4" "\n"
87" stw 4, 128(3)" "\n"
88" mfcr 4" "\n"
89" stw 4, 132(3)" "\n"
90" li 3, 0" "\n"
91" blr" "\n"
sewardj2a88a012011-04-11 21:26:27 +000092"" "\n"
sewardj97d3ebb2011-04-11 18:36:34 +000093
94
95".global VG_MINIMAL_LONGJMP" "\n"
96"VG_MINIMAL_LONGJMP:" "\n" // r3 = jmp_buf
97 // do r4 = 1
98 // and park it in the restore slot for r3 (the ret reg)
99" li 4, 1" "\n"
100" stw 4, 12(3)" "\n"
101 // restore everything except r3
102 // then r3 last of all
103 // then blr
104" lwz 0, 128(3)" "\n"
105" mtlr 0" "\n"
106" lwz 0, 132(3)" "\n"
107" mtcr 0" "\n"
108" lwz 0, 0(3)" "\n"
109" lwz 1, 4(3)" "\n"
110" lwz 2, 8(3)" "\n"
111 // r3 is done at the end
112" lwz 4, 16(3)" "\n"
113" lwz 5, 20(3)" "\n"
114" lwz 6, 24(3)" "\n"
115" lwz 7, 28(3)" "\n"
116" lwz 8, 32(3)" "\n"
117" lwz 9, 36(3)" "\n"
118" lwz 10, 40(3)" "\n"
119" lwz 11, 44(3)" "\n"
120" lwz 12, 48(3)" "\n"
121" lwz 13, 52(3)" "\n"
122" lwz 14, 56(3)" "\n"
123" lwz 15, 60(3)" "\n"
124" lwz 16, 64(3)" "\n"
125" lwz 17, 68(3)" "\n"
126" lwz 18, 72(3)" "\n"
127" lwz 19, 76(3)" "\n"
128" lwz 20, 80(3)" "\n"
129" lwz 21, 84(3)" "\n"
130" lwz 22, 88(3)" "\n"
131" lwz 23, 92(3)" "\n"
132" lwz 24, 96(3)" "\n"
133" lwz 25, 100(3)" "\n"
134" lwz 26, 104(3)" "\n"
135" lwz 27, 108(3)" "\n"
136" lwz 28, 112(3)" "\n"
137" lwz 29, 116(3)" "\n"
138" lwz 30, 120(3)" "\n"
139" lwz 31, 124(3)" "\n"
140" lwz 3, 12(3)" "\n"
141" blr" "\n"
sewardj2a88a012011-04-11 21:26:27 +0000142"" "\n"
sewardj97d3ebb2011-04-11 18:36:34 +0000143
144".previous" "\n"
145);
146
147#endif /* VGP_ppc32_linux */
sewardj6c591e12011-04-11 16:17:51 +0000148
149
sewardj2a88a012011-04-11 21:26:27 +0000150/* ------------ ppc64-linux ------------ */
151
carllcae0cc22014-08-07 23:17:29 +0000152#if defined(VGP_ppc64be_linux)
sewardj2a88a012011-04-11 21:26:27 +0000153
154__asm__(
155".section \".toc\",\"aw\"" "\n"
156
157".section \".text\"" "\n"
158".align 2" "\n"
159".p2align 4,,15" "\n"
160".globl VG_MINIMAL_SETJMP" "\n"
sewardj2a88a012011-04-11 21:26:27 +0000161".section \".opd\",\"aw\"" "\n"
162".align 3" "\n"
163"VG_MINIMAL_SETJMP:" "\n"
164".quad .L.VG_MINIMAL_SETJMP,.TOC.@tocbase,0" "\n"
165".previous" "\n"
166
167".type VG_MINIMAL_SETJMP, @function" "\n"
168".L.VG_MINIMAL_SETJMP:" "\n"
169" std 0, 0(3)" "\n"
170" std 1, 8(3)" "\n"
171" std 2, 16(3)" "\n"
172" std 3, 24(3)" "\n"
173" std 4, 32(3)" "\n"
174" std 5, 40(3)" "\n"
175" std 6, 48(3)" "\n"
176" std 7, 56(3)" "\n"
177" std 8, 64(3)" "\n"
178" std 9, 72(3)" "\n"
179" std 10, 80(3)" "\n"
180" std 11, 88(3)" "\n"
181" std 12, 96(3)" "\n"
182" std 13, 104(3)" "\n"
183" std 14, 112(3)" "\n"
184" std 15, 120(3)" "\n"
185" std 16, 128(3)" "\n"
186" std 17, 136(3)" "\n"
187" std 18, 144(3)" "\n"
188" std 19, 152(3)" "\n"
189" std 20, 160(3)" "\n"
190" std 21, 168(3)" "\n"
191" std 22, 176(3)" "\n"
192" std 23, 184(3)" "\n"
193" std 24, 192(3)" "\n"
194" std 25, 200(3)" "\n"
195" std 26, 208(3)" "\n"
196" std 27, 216(3)" "\n"
197" std 28, 224(3)" "\n"
198" std 29, 232(3)" "\n"
199" std 30, 240(3)" "\n"
200" std 31, 248(3)" "\n"
201 // must use a caller-save register here as scratch, hence r4
202" mflr 4" "\n"
203" std 4, 256(3)" "\n"
204" mfcr 4" "\n"
205" std 4, 264(3)" "\n"
206" li 3, 0" "\n"
207" blr" "\n"
208"" "\n"
209
210
211".globl VG_MINIMAL_LONGJMP" "\n"
212
213".section \".opd\",\"aw\"" "\n"
214".align 3" "\n"
215"VG_MINIMAL_LONGJMP:" "\n"
216".quad .L.VG_MINIMAL_LONGJMP,.TOC.@tocbase,0" "\n"
217".previous" "\n"
218
219".type VG_MINIMAL_LONGJMP, @function" "\n"
220".L.VG_MINIMAL_LONGJMP:" "\n"
221 // do r4 = 1
222 // and park it in the restore slot for r3 (the ret reg)
223" li 4, 1" "\n"
224" std 4, 24(3)" "\n"
225 // restore everything except r3
226 // then r3 last of all
227 // then blr
228" ld 0, 256(3)" "\n"
229" mtlr 0" "\n"
230" ld 0, 264(3)" "\n"
231" mtcr 0" "\n"
232" ld 0, 0(3)" "\n"
233" ld 1, 8(3)" "\n"
234" ld 2, 16(3)" "\n"
235 // r3 is done at the end
236" ld 4, 32(3)" "\n"
237" ld 5, 40(3)" "\n"
238" ld 6, 48(3)" "\n"
239" ld 7, 56(3)" "\n"
240" ld 8, 64(3)" "\n"
241" ld 9, 72(3)" "\n"
242" ld 10, 80(3)" "\n"
243" ld 11, 88(3)" "\n"
244" ld 12, 96(3)" "\n"
245" ld 13, 104(3)" "\n"
246" ld 14, 112(3)" "\n"
247" ld 15, 120(3)" "\n"
248" ld 16, 128(3)" "\n"
249" ld 17, 136(3)" "\n"
250" ld 18, 144(3)" "\n"
251" ld 19, 152(3)" "\n"
252" ld 20, 160(3)" "\n"
253" ld 21, 168(3)" "\n"
254" ld 22, 176(3)" "\n"
255" ld 23, 184(3)" "\n"
256" ld 24, 192(3)" "\n"
257" ld 25, 200(3)" "\n"
258" ld 26, 208(3)" "\n"
259" ld 27, 216(3)" "\n"
260" ld 28, 224(3)" "\n"
261" ld 29, 232(3)" "\n"
262" ld 30, 240(3)" "\n"
263" ld 31, 248(3)" "\n"
264" ld 3, 24(3)" "\n"
265" blr" "\n"
266"" "\n"
267
268".previous" "\n"
sewardj2a88a012011-04-11 21:26:27 +0000269);
270
carll582d5822014-08-07 23:35:54 +0000271#elif defined(VGP_ppc64le_linux)
272__asm__(
273".section \".toc\",\"aw\"" "\n"
274
275".section \".text\"" "\n"
276".align 2" "\n"
277".p2align 4,,15" "\n"
278".globl VG_MINIMAL_SETJMP" "\n"
279".type VG_MINIMAL_SETJMP,@function" "\n"
280"VG_MINIMAL_SETJMP:" "\n"
281" .localentry VG_MINIMAL_SETJMP, .-VG_MINIMAL_SETJMP" "\n"
282" std 0, 0(3)" "\n"
283" std 1, 8(3)" "\n"
284" std 2, 16(3)" "\n"
285" std 3, 24(3)" "\n"
286" std 4, 32(3)" "\n"
287" std 5, 40(3)" "\n"
288" std 6, 48(3)" "\n"
289" std 7, 56(3)" "\n"
290" std 8, 64(3)" "\n"
291" std 9, 72(3)" "\n"
292" std 10, 80(3)" "\n"
293" std 11, 88(3)" "\n"
294" std 12, 96(3)" "\n"
295" std 13, 104(3)" "\n"
296" std 14, 112(3)" "\n"
297" std 15, 120(3)" "\n"
298" std 16, 128(3)" "\n"
299" std 17, 136(3)" "\n"
300" std 18, 144(3)" "\n"
301" std 19, 152(3)" "\n"
302" std 20, 160(3)" "\n"
303" std 21, 168(3)" "\n"
304" std 22, 176(3)" "\n"
305" std 23, 184(3)" "\n"
306" std 24, 192(3)" "\n"
307" std 25, 200(3)" "\n"
308" std 26, 208(3)" "\n"
309" std 27, 216(3)" "\n"
310" std 28, 224(3)" "\n"
311" std 29, 232(3)" "\n"
312" std 30, 240(3)" "\n"
313" std 31, 248(3)" "\n"
314// must use a caller-save register here as scratch, hence r4
315" mflr 4" "\n"
316" std 4, 256(3)" "\n"
317" mfcr 4" "\n"
318" std 4, 264(3)" "\n"
319" li 3, 0" "\n"
320" blr" "\n"
321"" "\n"
322
323
324".globl VG_MINIMAL_LONGJMP" "\n"
325".type VG_MINIMAL_LONGJMP, @function" "\n"
326"VG_MINIMAL_LONGJMP:" "\n"
327" .localentry VG_MINIMAL_LONGJMP, .-VG_MINIMAL_LONGJMP" "\n"
328 // do r4 = 1
329 // and park it in the restore slot for r3 (the ret reg)
330" li 4, 1" "\n"
331" std 4, 24(3)" "\n"
332 // restore everything except r3
333 // then r3 last of all
334 // then blr
335" ld 0, 256(3)" "\n"
336" mtlr 0" "\n"
337" ld 0, 264(3)" "\n"
338" mtcr 0" "\n"
339" ld 0, 0(3)" "\n"
340" ld 1, 8(3)" "\n"
341" ld 2, 16(3)" "\n"
342 // r3 is done at the end
343" ld 4, 32(3)" "\n"
344" ld 5, 40(3)" "\n"
345" ld 6, 48(3)" "\n"
346" ld 7, 56(3)" "\n"
347" ld 8, 64(3)" "\n"
348" ld 9, 72(3)" "\n"
349" ld 10, 80(3)" "\n"
350" ld 11, 88(3)" "\n"
351" ld 12, 96(3)" "\n"
352" ld 13, 104(3)" "\n"
353" ld 14, 112(3)" "\n"
354" ld 15, 120(3)" "\n"
355" ld 16, 128(3)" "\n"
356" ld 17, 136(3)" "\n"
357" ld 18, 144(3)" "\n"
358" ld 19, 152(3)" "\n"
359" ld 20, 160(3)" "\n"
360" ld 21, 168(3)" "\n"
361" ld 22, 176(3)" "\n"
362" ld 23, 184(3)" "\n"
363" ld 24, 192(3)" "\n"
364" ld 25, 200(3)" "\n"
365" ld 26, 208(3)" "\n"
366" ld 27, 216(3)" "\n"
367" ld 28, 224(3)" "\n"
368" ld 29, 232(3)" "\n"
369" ld 30, 240(3)" "\n"
370" ld 31, 248(3)" "\n"
371" ld 3, 24(3)" "\n"
372" blr" "\n"
373"" "\n"
374
375".previous" "\n"
376);
carllcae0cc22014-08-07 23:17:29 +0000377#endif /* VGP_ppc64be_linux */
sewardj2a88a012011-04-11 21:26:27 +0000378
sewardjfc824cb2011-09-29 17:33:58 +0000379
Elliott Hughesa0664b92017-04-18 17:46:52 -0700380/* -------- amd64-{linux,darwin,solaris} -------- */
sewardjfc824cb2011-09-29 17:33:58 +0000381
Elliott Hughesa0664b92017-04-18 17:46:52 -0700382#if defined(VGP_amd64_linux) || defined(VGP_amd64_darwin) || \
383 defined(VGP_amd64_solaris)
sewardjfc824cb2011-09-29 17:33:58 +0000384
385__asm__(
386".text" "\n"
387"" "\n"
sewardjda91ee72011-09-29 18:29:41 +0000388
Elliott Hughesa0664b92017-04-18 17:46:52 -0700389#if defined(VGP_amd64_linux) || defined(VGP_amd64_solaris)
sewardjfc824cb2011-09-29 17:33:58 +0000390".global VG_MINIMAL_SETJMP" "\n" // rdi = jmp_buf
391"VG_MINIMAL_SETJMP:" "\n"
sewardjda91ee72011-09-29 18:29:41 +0000392
393#elif defined(VGP_amd64_darwin)
394".globl _VG_MINIMAL_SETJMP" "\n" // rdi = jmp_buf
395"_VG_MINIMAL_SETJMP:" "\n"
396
397#else
398# error "Huh?"
399#endif
400
sewardjfc824cb2011-09-29 17:33:58 +0000401" movq %rax, 0(%rdi)" "\n"
402" movq %rbx, 8(%rdi)" "\n"
403" movq %rcx, 16(%rdi)" "\n"
404" movq %rdx, 24(%rdi)" "\n"
405" movq %rdi, 32(%rdi)" "\n"
406" movq %rsi, 40(%rdi)" "\n"
407" movq %rbp, 48(%rdi)" "\n"
408" movq %rsp, 56(%rdi)" "\n"
409" movq %r8, 64(%rdi)" "\n"
410" movq %r9, 72(%rdi)" "\n"
411" movq %r10, 80(%rdi)" "\n"
412" movq %r11, 88(%rdi)" "\n"
413" movq %r12, 96(%rdi)" "\n"
414" movq %r13, 104(%rdi)" "\n"
415" movq %r14, 112(%rdi)" "\n"
416" movq %r15, 120(%rdi)" "\n"
417 // store the return address
418" movq 0(%rsp), %rax" "\n"
419" movq %rax, 128(%rdi)" "\n"
420 // and return zero
421" movq $0, %rax" "\n"
422" ret" "\n"
423"" "\n"
424
sewardjda91ee72011-09-29 18:29:41 +0000425
Elliott Hughesa0664b92017-04-18 17:46:52 -0700426#if defined(VGP_amd64_linux) || defined(VGP_amd64_solaris)
sewardjda91ee72011-09-29 18:29:41 +0000427".global VG_MINIMAL_LONGJMP" "\n"
sewardjfc824cb2011-09-29 17:33:58 +0000428"VG_MINIMAL_LONGJMP:" "\n" // rdi = jmp_buf
sewardjda91ee72011-09-29 18:29:41 +0000429
430#elif defined(VGP_amd64_darwin)
431".globl _VG_MINIMAL_LONGJMP" "\n"
432"_VG_MINIMAL_LONGJMP:" "\n" // rdi = jmp_buf
433
434#else
435# error "Huh?"
436#endif
sewardjfc824cb2011-09-29 17:33:58 +0000437 // skip restoring rax; it's pointless
438" movq 8(%rdi), %rbx" "\n"
439" movq 16(%rdi), %rcx" "\n"
440" movq 24(%rdi), %rdx" "\n"
441 // defer restoring rdi; we still need it
442" movq 40(%rdi), %rsi" "\n"
443" movq 48(%rdi), %rbp" "\n"
444" movq 56(%rdi), %rsp" "\n"
445" movq 64(%rdi), %r8" "\n"
446" movq 72(%rdi), %r9" "\n"
447" movq 80(%rdi), %r10" "\n"
448" movq 88(%rdi), %r11" "\n"
449" movq 96(%rdi), %r12" "\n"
450" movq 104(%rdi), %r13" "\n"
451" movq 112(%rdi), %r14" "\n"
452" movq 120(%rdi), %r15" "\n"
453 // restore the return address
454" movq 128(%rdi), %rax" "\n"
455 // restore rdi; this is the last use
456" movq 32(%rdi), %rdi" "\n"
457 // make %rsp look like we really did a return
458" addq $8, %rsp" "\n"
459 // continue at RA of original call. Note: this is a
460 // nasty trick. We assume that %rax is nonzero, and so the
461 // caller can differentiate this case from the normal _SETJMP
462 // return case. If the return address ever is zero, then
463 // we're hosed; but that seems pretty unlikely given that it
464 // would mean we'd be executing at the wraparound point of the
465 // address space.
466" jmp *%rax" "\n"
467"" "\n"
468
sewardjda91ee72011-09-29 18:29:41 +0000469#if !defined(VGP_amd64_darwin)
sewardjfc824cb2011-09-29 17:33:58 +0000470".previous" "\n"
sewardjda91ee72011-09-29 18:29:41 +0000471#endif
sewardjfc824cb2011-09-29 17:33:58 +0000472);
473
Elliott Hughesa0664b92017-04-18 17:46:52 -0700474#endif /* VGP_amd64_linux || VGP_amd64_darwin || VGP_amd64_solaris */
sewardjfc824cb2011-09-29 17:33:58 +0000475
476
Elliott Hughesa0664b92017-04-18 17:46:52 -0700477/* -------- x86-{linux,darwin,solaris} -------- */
sewardjfc824cb2011-09-29 17:33:58 +0000478
Elliott Hughesa0664b92017-04-18 17:46:52 -0700479#if defined(VGP_x86_linux) || defined(VGP_x86_darwin) || \
480 defined(VGP_x86_solaris)
sewardjfc824cb2011-09-29 17:33:58 +0000481
482__asm__(
483".text" "\n"
484"" "\n"
sewardjda91ee72011-09-29 18:29:41 +0000485
Elliott Hughesa0664b92017-04-18 17:46:52 -0700486#if defined(VGP_x86_linux) || defined(VGP_x86_solaris)
sewardjfc824cb2011-09-29 17:33:58 +0000487".global VG_MINIMAL_SETJMP" "\n" // eax = jmp_buf
488"VG_MINIMAL_SETJMP:" "\n"
sewardjda91ee72011-09-29 18:29:41 +0000489
490#elif defined(VGP_x86_darwin)
491".globl _VG_MINIMAL_SETJMP" "\n" // eax = jmp_buf
492"_VG_MINIMAL_SETJMP:" "\n"
493
494#else
495# error "Huh?"
496#endif
497
sewardjfc824cb2011-09-29 17:33:58 +0000498" movl %eax, 0(%eax)" "\n"
499" movl %ebx, 4(%eax)" "\n"
500" movl %ecx, 8(%eax)" "\n"
501" movl %edx, 12(%eax)" "\n"
502" movl %edi, 16(%eax)" "\n"
503" movl %esi, 20(%eax)" "\n"
504" movl %ebp, 24(%eax)" "\n"
505" movl %esp, 28(%eax)" "\n"
506 // store the return address
507" movl 0(%esp), %ebx" "\n"
508" movl %ebx, 32(%eax)" "\n"
509 // un-trash ebx (necessary? i don't know)
510" movl 4(%eax), %ebx" "\n"
511 // and return zero
512" movl $0, %eax" "\n"
513" ret" "\n"
514"" "\n"
515
sewardjda91ee72011-09-29 18:29:41 +0000516
Elliott Hughesa0664b92017-04-18 17:46:52 -0700517#if defined(VGP_x86_linux) || defined(VGP_x86_solaris)
sewardjda91ee72011-09-29 18:29:41 +0000518".global VG_MINIMAL_LONGJMP" "\n"
sewardjfc824cb2011-09-29 17:33:58 +0000519"VG_MINIMAL_LONGJMP:" "\n" // eax = jmp_buf
sewardjda91ee72011-09-29 18:29:41 +0000520
521#elif defined(VGP_x86_darwin)
522".globl _VG_MINIMAL_LONGJMP" "\n"
523"_VG_MINIMAL_LONGJMP:" "\n" // eax = jmp_buf
524
525#else
526# error "Huh?"
527#endif
528
sewardjfc824cb2011-09-29 17:33:58 +0000529 // skip restoring eax; it's pointless
530" movl 4(%eax), %ebx" "\n"
531" movl 8(%eax), %ecx" "\n"
532" movl 12(%eax), %edx" "\n"
533" movl 16(%eax), %edi" "\n"
534" movl 20(%eax), %esi" "\n"
535" movl 24(%eax), %ebp" "\n"
536" movl 28(%eax), %esp" "\n"
537 // restore the return address
538" movl 32(%eax), %eax" "\n"
539 // make %esp look like we really did a return
540" addl $4, %esp" "\n"
541 // continue at RA of original call. Same zero-vs-nonzero
542 // trick/assumption as documented for the amd64-linux case.
543" jmp *%eax" "\n"
544"" "\n"
545
sewardjda91ee72011-09-29 18:29:41 +0000546#if !defined(VGP_x86_darwin)
sewardjfc824cb2011-09-29 17:33:58 +0000547".previous" "\n"
sewardjda91ee72011-09-29 18:29:41 +0000548#endif
sewardjfc824cb2011-09-29 17:33:58 +0000549);
550
Elliott Hughesa0664b92017-04-18 17:46:52 -0700551#endif /* VGP_x86_linux || VGP_x86_darwin || VGP_x86_solaris */
sewardjfc824cb2011-09-29 17:33:58 +0000552
dejanj5f790e82013-07-25 08:22:08 +0000553#if defined(VGP_mips32_linux)
554
555__asm__(
556".text \n\t"
557".globl VG_MINIMAL_SETJMP; \n\t"
Elliott Hughesed398002017-06-21 14:41:24 -0700558".set push \n\t"
559".set noreorder \n\t"
560"VG_MINIMAL_SETJMP: \n\t"
561#if defined(__mips_hard_float)
562" sdc1 $f20, 56($a0) \n\t"
563" sdc1 $f22, 64($a0) \n\t"
564" sdc1 $f24, 72($a0) \n\t"
565" sdc1 $f26, 80($a0) \n\t"
566" sdc1 $f28, 88($a0) \n\t"
567" sdc1 $f30, 96($a0) \n\t"
568#endif
569" sw $gp, 44($a0) \n\t"
570" sw $s0, 8($a0) \n\t"
571" sw $s1, 12($a0) \n\t"
572" sw $s2, 16($a0) \n\t"
573" sw $s3, 20($a0) \n\t"
574" sw $s4, 24($a0) \n\t"
575" sw $s5, 28($a0) \n\t"
576" sw $s6, 32($a0) \n\t"
577" sw $s7, 36($a0) \n\t"
578" sw $ra, 0($a0) \n\t"
579" sw $sp, 4($a0) \n\t"
580" sw $fp, 40($a0) \n\t"
581" jr $ra \n\t"
582" move $v0, $zero \n\t"
583".set pop \n\t"
dejanj751c1e62013-08-15 13:37:29 +0000584".previous \n\t"
dejanj5f790e82013-07-25 08:22:08 +0000585" \n\t"
Elliott Hughesed398002017-06-21 14:41:24 -0700586".text \n\t"
dejanj5f790e82013-07-25 08:22:08 +0000587".globl VG_MINIMAL_LONGJMP; \n\t"
Elliott Hughesed398002017-06-21 14:41:24 -0700588".set push \n\t"
589".set noreorder \n\t"
590"VG_MINIMAL_LONGJMP: \n\t"
591#if defined(__mips_hard_float)
592" ldc1 $f20, 56($a0) \n\t"
593" ldc1 $f22, 64($a0) \n\t"
594" ldc1 $f24, 72($a0) \n\t"
595" ldc1 $f26, 80($a0) \n\t"
596" ldc1 $f28, 88($a0) \n\t"
597" ldc1 $f30, 96($a0) \n\t"
598#endif
599" lw $gp, 44($a0) \n\t"
600" lw $s0, 8($a0) \n\t"
601" lw $s1, 12($a0) \n\t"
602" lw $s2, 16($a0) \n\t"
603" lw $s3, 20($a0) \n\t"
604" lw $s4, 24($a0) \n\t"
605" lw $s5, 28($a0) \n\t"
606" lw $s6, 32($a0) \n\t"
607" lw $s7, 36($a0) \n\t"
608" lw $ra, 0($a0) \n\t"
609" lw $sp, 4($a0) \n\t"
610" bnez $a1, 1f \n\t"
611" lw $fp, 40($a0) \n\t"
612" addiu $a1, $a1, 1 \n\t"
dejanj5f790e82013-07-25 08:22:08 +0000613"1: \n\t"
Elliott Hughesed398002017-06-21 14:41:24 -0700614" jr $ra \n\t"
615" move $v0, $a1 \n\t"
616".set pop \n\t"
dejanj751c1e62013-08-15 13:37:29 +0000617".previous \n\t"
dejanj5f790e82013-07-25 08:22:08 +0000618);
619#endif /* VGP_mips32_linux */
620
Elliott Hughesed398002017-06-21 14:41:24 -0700621#if defined(VGP_mips64_linux)
622
623__asm__(
624".text \n\t"
625".globl VG_MINIMAL_SETJMP; \n\t"
626".set push \n\t"
627".set noreorder \n\t"
628"VG_MINIMAL_SETJMP: \n\t"
629#if defined(__mips_hard_float)
630" sdc1 $f24, 104($a0) \n\t"
631" sdc1 $f25, 112($a0) \n\t"
632" sdc1 $f26, 120($a0) \n\t"
633" sdc1 $f27, 128($a0) \n\t"
634" sdc1 $f28, 136($a0) \n\t"
635" sdc1 $f29, 144($a0) \n\t"
636" sdc1 $f30, 152($a0) \n\t"
637" sdc1 $f31, 160($a0) \n\t"
638#endif
639" sd $gp, 88($a0) \n\t"
640" sd $s0, 16($a0) \n\t"
641" sd $s1, 24($a0) \n\t"
642" sd $s2, 32($a0) \n\t"
643" sd $s3, 40($a0) \n\t"
644" sd $s4, 48($a0) \n\t"
645" sd $s5, 56($a0) \n\t"
646" sd $s6, 64($a0) \n\t"
647" sd $s7, 72($a0) \n\t"
648" sd $ra, 0($a0) \n\t"
649" sd $sp, 8($a0) \n\t"
650" sd $fp, 80($a0) \n\t"
651" jr $ra \n\t"
652" move $v0, $zero \n\t"
653".set pop \n\t"
654".previous \n\t"
655" \n\t"
656".text \n\t"
657".globl VG_MINIMAL_LONGJMP; \n\t"
658".set push \n\t"
659".set noreorder \n\t"
660"VG_MINIMAL_LONGJMP: \n\t"
661#if defined(__mips_hard_float)
662" ldc1 $f24, 104($a0) \n\t"
663" ldc1 $f25, 112($a0) \n\t"
664" ldc1 $f26, 120($a0) \n\t"
665" ldc1 $f27, 128($a0) \n\t"
666" ldc1 $f28, 136($a0) \n\t"
667" ldc1 $f29, 144($a0) \n\t"
668" ldc1 $f30, 152($a0) \n\t"
669" ldc1 $f31, 160($a0) \n\t"
670#endif
671" ld $gp, 88($a0) \n\t"
672" ld $s0, 16($a0) \n\t"
673" ld $s1, 24($a0) \n\t"
674" ld $s2, 32($a0) \n\t"
675" ld $s3, 40($a0) \n\t"
676" ld $s4, 48($a0) \n\t"
677" ld $s5, 56($a0) \n\t"
678" ld $s6, 64($a0) \n\t"
679" ld $s7, 72($a0) \n\t"
680" ld $ra, 0($a0) \n\t"
681" ld $sp, 8($a0) \n\t"
682" bnez $a1, 1f \n\t"
683" ld $fp, 80($a0) \n\t"
684" daddiu $a1, $a1, 1 \n\t"
685"1: \n\t"
686" jr $ra \n\t"
687" move $v0, $a1 \n\t"
688".set pop \n\t"
689".previous \n\t"
690);
691#endif /* VGP_mips64_linux */
692
sewardj6c591e12011-04-11 16:17:51 +0000693/*--------------------------------------------------------------------*/
694/*--- end ---*/
695/*--------------------------------------------------------------------*/