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