1
2 /*---------------------------------------------------------------*/
3 /*--- begin main_util.h ---*/
4 /*---------------------------------------------------------------*/
5
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright (C) 2004-2017 OpenWorks LLP
11 info@open-works.net
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29
30 Neither the names of the U.S. Department of Energy nor the
31 University of California nor the names of its contributors may be
32 used to endorse or promote products derived from this software
33 without prior written permission.
34 */
35
36 #ifndef __VEX_MAIN_UTIL_H
37 #define __VEX_MAIN_UTIL_H
38
39 #include "libvex_basictypes.h"
40
41 #include "libvex_inner.h"
42 #if defined(ENABLE_INNER_CLIENT_REQUEST)
43 /* Including here memcheck include file is kind of a hack, but this is needed
44 to have self-hosting checking VEX. Note however that this is included only
45 when Valgrind and VEX are configured using --enable-inner. */
46 #include "memcheck/memcheck.h"
47 #endif
48
49 /* Misc. */
50
51 #define NULL ((void*)0)
52
53 #if defined(_MSC_VER) // building with MSVC
54 # define LIKELY(x) (x)
55 # define UNLIKELY(x) (x)
56 # define CAST_TO_TYPEOF(x) /**/
57 #else
58 # define LIKELY(x) __builtin_expect(!!(x), 1)
59 # define UNLIKELY(x) __builtin_expect(!!(x), 0)
60 # define CAST_TO_TYPEOF(x) (__typeof__(x))
61 #endif // defined(_MSC_VER)
62
63 #if !defined(offsetof)
64 # define offsetof(type,memb) ((SizeT)(HWord)&((type*)0)->memb)
65 #endif
66
67 // Poor man's static assert
68 #define STATIC_ASSERT(x) extern int vex__unused_array[(x) ? 1 : -1] \
69 __attribute__((unused))
70
71 /* Stuff for panicking and assertion. */
72
73 #define vassert(expr) \
74 ((void) (LIKELY(expr) ? 0 : \
75 (vex_assert_fail (#expr, \
76 __FILE__, __LINE__, \
77 __PRETTY_FUNCTION__), 0)))
78
79 __attribute__ ((__noreturn__))
80 extern void vex_assert_fail ( const HChar* expr, const HChar* file,
81 Int line, const HChar* fn );
82 __attribute__ ((__noreturn__))
83 extern void vpanic ( const HChar* str );
84
85 __attribute__ ((__noreturn__)) __attribute__ ((format (printf, 1, 2)))
86 extern void vfatal ( const HChar* format, ... );
87
88
89 /* Printing */
90
91 __attribute__ ((format (printf, 1, 2)))
92 extern UInt vex_printf ( const HChar *format, ... );
93
94 __attribute__ ((format (printf, 2, 3)))
95 extern UInt vex_sprintf ( HChar* buf, const HChar *format, ... );
96
97
98 /* String ops */
99
100 extern Bool vex_streq ( const HChar* s1, const HChar* s2 );
101 extern SizeT vex_strlen ( const HChar* str );
102 extern void vex_bzero ( void* s, SizeT n );
103
104
105 /* Storage management: clear the area, and allocate from it. */
106
107 /* By default allocation occurs in the temporary area. However, it is
108 possible to switch to permanent area allocation if that's what you
109 want. Permanent area allocation is very limited, tho. */
110
111 typedef
112 enum {
113 VexAllocModeTEMP,
114 VexAllocModePERM
115 }
116 VexAllocMode;
117
118 extern void vexSetAllocMode ( VexAllocMode );
119 extern VexAllocMode vexGetAllocMode ( void );
120 extern void vexAllocSanityCheck ( void );
121
122 extern void vexSetAllocModeTEMP_and_clear ( void );
123
124 /* Allocate in Vex's temporary allocation area. Be careful with this.
125 You can only call it inside an instrumentation or optimisation
126 callback that you have previously specified in a call to
127 LibVEX_Translate. The storage allocated will only stay alive until
128 translation of the current basic block is complete.
129 */
130 extern HChar* private_LibVEX_alloc_first;
131 extern HChar* private_LibVEX_alloc_curr;
132 extern HChar* private_LibVEX_alloc_last;
133 extern void private_LibVEX_alloc_OOM(void) __attribute__((noreturn));
134
135 /* Allocated memory as returned by LibVEX_Alloc will be aligned on this
136 boundary. */
137 #define REQ_ALIGN 8
138
139 #if defined(ENABLE_INNER)
140 #define VEX_REDZONE_SIZEB (2*REQ_ALIGN)
141 #endif
142
LibVEX_Alloc_inline(SizeT nbytes)143 static inline void* LibVEX_Alloc_inline ( SizeT nbytes )
144 {
145 struct align {
146 char c;
147 union {
148 char c;
149 short s;
150 int i;
151 long l;
152 long long ll;
153 float f;
154 double d;
155 /* long double is currently not used and would increase alignment
156 unnecessarily. */
157 /* long double ld; */
158 void *pto;
159 void (*ptf)(void);
160 } x;
161 };
162
163 /* Make sure the compiler does no surprise us */
164 vassert(offsetof(struct align,x) <= REQ_ALIGN);
165
166 #if 0
167 /* Nasty debugging hack, do not use. */
168 return malloc(nbytes);
169 #else
170 HChar* curr;
171 HChar* next;
172 SizeT ALIGN;
173 ALIGN = offsetof(struct align,x) - 1;
174 curr = private_LibVEX_alloc_curr;
175 next = curr + ((nbytes + ALIGN) & ~ALIGN);
176 INNER_REQUEST(next += 2 * VEX_REDZONE_SIZEB);
177 if (next >= private_LibVEX_alloc_last)
178 private_LibVEX_alloc_OOM();
179 private_LibVEX_alloc_curr = next;
180 INNER_REQUEST(curr += VEX_REDZONE_SIZEB);
181 INNER_REQUEST(VALGRIND_MEMPOOL_ALLOC(private_LibVEX_alloc_first,
182 curr, nbytes));
183 return curr;
184 #endif
185 }
186
187 /* Misaligned memory access support. */
188
189 extern UInt read_misaligned_UInt_LE ( void* addr );
190 extern ULong read_misaligned_ULong_LE ( void* addr );
191
192 extern void write_misaligned_UInt_LE ( void* addr, UInt w );
193 extern void write_misaligned_ULong_LE ( void* addr, ULong w );
194
195 #endif /* ndef __VEX_MAIN_UTIL_H */
196
197 /*---------------------------------------------------------------*/
198 /*--- main_util.h ---*/
199 /*---------------------------------------------------------------*/
200