blob: d6c6b985946014d5ea146f052da12b889db50ff5 [file] [log] [blame]
sewardj6c591e12011-04-11 16:17:51 +00001
2/*--------------------------------------------------------------------*/
3/*--- A minimal setjmp/longjmp facility. pub_tool_libcsetjmp.h ---*/
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#ifndef __PUB_TOOL_LIBCSETJMP_H
33#define __PUB_TOOL_LIBCSETJMP_H
34
florian535fb1b2013-09-15 13:54:34 +000035#include "pub_tool_basics.h" // UWord
36
sewardj6c591e12011-04-11 16:17:51 +000037//--------------------------------------------------------------------
38// PURPOSE: Provides a minimal setjmp/longjmp facility, that saves/
39// restores integer registers, but not necessarily anything more.
40//--------------------------------------------------------------------
41
42
43/* This provides an extremely minimal setjmp/longjmp facility, in
44 which only the host's integer registers are saved/restored. Or at
45 least, that is the minimal guaranteed functionality.
46
47 Until Apr 2011 we used __builtin_setjmp and __builtin_longjmp, but
48 it appears that that is not always correctly implemented. See
49 https://bugs.kde.org/show_bug.cgi?id=259977. So this module wraps
50 those functions up and facilitates replacing them with our own
51 implementations where necessary.
52*/
53
54/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
55#include <setjmp.h>
56/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
57
58
59/* Don't use jmp_buf, __builtin_setjmp or __builtin_longjmp directly.
60 They don't always work reliably. Instead use these macros, which
61 provide the opportunity to supply alternative implementations as
62 necessary.
63
64 Note that the abstraction is done with macros (ick) rather than
65 functions and typedefs, since wrapping __builtin_setjmp up in a
66 second function (eg, VG_(minimal_setjmp)) doesn't seem to work for
67 whatever reason -- returns via a VG_(minimal_longjmp) go wrong.
sewardjfc824cb2011-09-29 17:33:58 +000068
69 VG_MINIMAL_SETJMP stores the current integer register state in the
70 supplied argument, and returns zero. VG_MINIMAL_LONGJMP resumes
71 with the previously saved state, and returns a nonzero, word-sized
72 value. The caller must test all bits of the value in order to make
73 a zero/non-zero determination.
sewardj6c591e12011-04-11 16:17:51 +000074*/
sewardj97d3ebb2011-04-11 18:36:34 +000075
76#if defined(VGP_ppc32_linux)
77
78#define VG_MINIMAL_JMP_BUF(_name) UInt _name [32+1+1]
sewardjfc824cb2011-09-29 17:33:58 +000079__attribute__((returns_twice))
80UWord VG_MINIMAL_SETJMP(VG_MINIMAL_JMP_BUF(_env));
sewardj82f8bfd2011-05-09 09:15:28 +000081__attribute__((noreturn))
sewardjfc824cb2011-09-29 17:33:58 +000082void VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env));
83
sewardj97d3ebb2011-04-11 18:36:34 +000084
carllcae0cc22014-08-07 23:17:29 +000085#elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
sewardj2a88a012011-04-11 21:26:27 +000086
87#define VG_MINIMAL_JMP_BUF(_name) ULong _name [32+1+1]
sewardjfc824cb2011-09-29 17:33:58 +000088__attribute__((returns_twice))
89UWord VG_MINIMAL_SETJMP(VG_MINIMAL_JMP_BUF(_env));
sewardj82f8bfd2011-05-09 09:15:28 +000090__attribute__((noreturn))
sewardjfc824cb2011-09-29 17:33:58 +000091void VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env));
92
93
Elliott Hughesa0664b92017-04-18 17:46:52 -070094#elif defined(VGP_amd64_linux) || defined(VGP_amd64_darwin) || \
95 defined(VGP_amd64_solaris)
sewardjfc824cb2011-09-29 17:33:58 +000096
97#define VG_MINIMAL_JMP_BUF(_name) ULong _name [16+1]
98__attribute__((returns_twice))
99UWord VG_MINIMAL_SETJMP(VG_MINIMAL_JMP_BUF(_env));
100__attribute__((noreturn))
101void VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env));
102
103
Elliott Hughesa0664b92017-04-18 17:46:52 -0700104#elif defined(VGP_x86_linux) || defined(VGP_x86_darwin) || \
105 defined(VGP_x86_solaris)
sewardjfc824cb2011-09-29 17:33:58 +0000106
107#define VG_MINIMAL_JMP_BUF(_name) UInt _name [8+1]
108__attribute__((returns_twice))
109__attribute__((regparm(1))) // this is critical; don't delete
110UWord VG_MINIMAL_SETJMP(VG_MINIMAL_JMP_BUF(_env));
111__attribute__((noreturn))
112__attribute__((regparm(1))) // ditto
113void VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env));
114
dejanj5f790e82013-07-25 08:22:08 +0000115#elif defined(VGP_mips32_linux)
116
Elliott Hughesed398002017-06-21 14:41:24 -0700117#define VG_MINIMAL_JMP_BUF(_name) ULong _name [104 / sizeof(ULong)]
118__attribute__((returns_twice))
119UWord VG_MINIMAL_SETJMP(VG_MINIMAL_JMP_BUF(_env));
120__attribute__((noreturn))
121void VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env));
122
123#elif defined(VGP_mips64_linux)
124
125#define VG_MINIMAL_JMP_BUF(_name) ULong _name [168 / sizeof(ULong)]
dejanj5f790e82013-07-25 08:22:08 +0000126__attribute__((returns_twice))
127UWord VG_MINIMAL_SETJMP(VG_MINIMAL_JMP_BUF(_env));
128__attribute__((noreturn))
129void VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env));
sewardj2a88a012011-04-11 21:26:27 +0000130
Elliott Hughesa0664b92017-04-18 17:46:52 -0700131#elif defined(VGPV_arm64_linux_android)
Chih-Hung Hsieh85106a52016-10-14 23:36:20 -0700132
133/* Android clang/llvm has no __builtin_{setjmp,longjmp} for aarch64. */
134/* Use the same setjmp/longjmp functions for both gcc and clang. */
135#define VG_MINIMAL_JMP_BUF(_name) jmp_buf _name
136#define VG_MINIMAL_SETJMP(_env) ((UWord)(setjmp((_env))))
137#define VG_MINIMAL_LONGJMP(_env) longjmp((_env),1)
138
sewardj97d3ebb2011-04-11 18:36:34 +0000139#else
140
141/* The default implementation. */
142#define VG_MINIMAL_JMP_BUF(_name) jmp_buf _name
sewardjfc824cb2011-09-29 17:33:58 +0000143#define VG_MINIMAL_SETJMP(_env) ((UWord)(__builtin_setjmp((_env))))
sewardj6c591e12011-04-11 16:17:51 +0000144#define VG_MINIMAL_LONGJMP(_env) __builtin_longjmp((_env),1)
145
sewardj97d3ebb2011-04-11 18:36:34 +0000146#endif
sewardj6c591e12011-04-11 16:17:51 +0000147
148#endif // __PUB_TOOL_LIBCSETJMP_H
149
150/*--------------------------------------------------------------------*/
151/*--- end pub_tool_libcsetjmp.h ---*/
152/*--------------------------------------------------------------------*/