• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
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 
10    Copyright (C) 2010-2017 Mozilla Inc
11 
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 
35 #include "pub_tool_basics.h"   // UWord
36 
37 //--------------------------------------------------------------------
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.
68 
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.
74 */
75 
76 #if defined(VGP_ppc32_linux)
77 
78 #define VG_MINIMAL_JMP_BUF(_name)        UInt _name [32+1+1]
79 __attribute__((returns_twice))
80 UWord VG_MINIMAL_SETJMP(VG_MINIMAL_JMP_BUF(_env));
81 __attribute__((noreturn))
82 void  VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env));
83 
84 
85 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
86 
87 #define VG_MINIMAL_JMP_BUF(_name)        ULong _name [32+1+1]
88 __attribute__((returns_twice))
89 UWord VG_MINIMAL_SETJMP(VG_MINIMAL_JMP_BUF(_env));
90 __attribute__((noreturn))
91 void  VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env));
92 
93 
94 #elif defined(VGP_amd64_linux) || defined(VGP_amd64_darwin) || \
95       defined(VGP_amd64_solaris)
96 
97 #define VG_MINIMAL_JMP_BUF(_name)        ULong _name [16+1]
98 __attribute__((returns_twice))
99 UWord VG_MINIMAL_SETJMP(VG_MINIMAL_JMP_BUF(_env));
100 __attribute__((noreturn))
101 void  VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env));
102 
103 
104 #elif defined(VGP_x86_linux) || defined(VGP_x86_darwin) || \
105       defined(VGP_x86_solaris)
106 
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
110 UWord VG_MINIMAL_SETJMP(VG_MINIMAL_JMP_BUF(_env));
111 __attribute__((noreturn))
112 __attribute__((regparm(1))) // ditto
113 void  VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env));
114 
115 #elif defined(VGP_mips32_linux)
116 
117 #define VG_MINIMAL_JMP_BUF(_name)        ULong _name [104 / sizeof(ULong)]
118 __attribute__((returns_twice))
119 UWord VG_MINIMAL_SETJMP(VG_MINIMAL_JMP_BUF(_env));
120 __attribute__((noreturn))
121 void  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)]
126 __attribute__((returns_twice))
127 UWord VG_MINIMAL_SETJMP(VG_MINIMAL_JMP_BUF(_env));
128 __attribute__((noreturn))
129 void  VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env));
130 
131 #elif defined(VGPV_arm64_linux_android)
132 
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 
139 #else
140 
141 /* The default implementation. */
142 #define VG_MINIMAL_JMP_BUF(_name) jmp_buf _name
143 #define VG_MINIMAL_SETJMP(_env)   ((UWord)(__builtin_setjmp((_env))))
144 #define VG_MINIMAL_LONGJMP(_env)  __builtin_longjmp((_env),1)
145 
146 #endif
147 
148 #endif   // __PUB_TOOL_LIBCSETJMP_H
149 
150 /*--------------------------------------------------------------------*/
151 /*--- end                                    pub_tool_libcsetjmp.h ---*/
152 /*--------------------------------------------------------------------*/
153