• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*- mode: C; c-basic-offset: 3; -*- */
2 
3 /*--------------------------------------------------------------------*/
4 /*--- Compiler specific stuff.                        m_compiler.c ---*/
5 /*--------------------------------------------------------------------*/
6 
7 /*
8    This file is part of Valgrind, a dynamic binary instrumentation
9    framework.
10 
11    Copyright (C) 2014-2017 Florian Krohm
12       florian@eich-krohm.de
13 
14    This program is free software; you can redistribute it and/or
15    modify it under the terms of the GNU General Public License as
16    published by the Free Software Foundation; either version 2 of the
17    License, or (at your option) any later version.
18 
19    This program is distributed in the hope that it will be useful, but
20    WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22    General Public License for more details.
23 
24    You should have received a copy of the GNU General Public License
25    along with this program; if not, write to the Free Software
26    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27    02111-1307, USA.
28 
29    The GNU General Public License is contained in the file COPYING.
30 */
31 
32 /* Currently, this file provides definitions for builtins that not all
33    compilers or compiler versions provide.
34 
35    Missing builtins are rare. Therefore, no attempt has been made to
36    provide efficient implementations.
37  */
38 
39 #include "config.h"
40 #include "pub_core_basics.h"
41 #include "pub_core_libcbase.h"
42 #include "pub_core_libcassert.h"
43 #include "pub_core_debuglog.h"
44 
45 #ifndef HAVE_BUILTIN_POPCOUT
46 
47 /* From the GCC documentation:
48    Returns the number of 1-bits in x. */
49 
50 UInt
__builtin_popcount(UInt x)51 __builtin_popcount(UInt x)
52 {
53    UInt i, count = 0;
54 
55    for (i = 0; i < 32; ++i) {
56       count += x & 1;
57       x >>= 1;
58    }
59    return count;
60 }
61 
62 UInt
__builtin_popcountll(ULong x)63 __builtin_popcountll(ULong x)
64 {
65    UInt i, count = 0;
66 
67    for (i = 0; i < 64; ++i) {
68       count += x & 1;
69       x >>= 1;
70    }
71    return count;
72 }
73 #endif
74 
75 #ifndef HAVE_BUILTIN_CLZ
76 
77 /* From the GCC documentation:
78    Returns the number of leading 0-bits in x, starting at the most
79    significant position. If x is 0, the result is undefined. */
80 
81 UInt
__builtin_clz(UInt x)82 __builtin_clz(UInt x)
83 {
84    UInt count = 32;
85    UInt y;
86 
87    y = x >> 16; if (y != 0) { count -= 16; x = y; }
88    y = x >> 8;  if (y != 0) { count -= 8;  x = y; }
89    y = x >> 4;  if (y != 0) { count -= 4;  x = y; }
90    y = x >> 2;  if (y != 0) { count -= 2;  x = y; }
91    y = x >> 1;  if (y != 0) return count - 2;
92    return count - x;
93 }
94 
95 UInt
__builtin_clzll(ULong x)96 __builtin_clzll(ULong x)
97 {
98    UInt count = 64;
99    ULong y;
100 
101    y = x >> 32; if (y != 0) { count -= 32; x = y; }
102    y = x >> 16; if (y != 0) { count -= 16; x = y; }
103    y = x >> 8;  if (y != 0) { count -= 8;  x = y; }
104    y = x >> 4;  if (y != 0) { count -= 4;  x = y; }
105    y = x >> 2;  if (y != 0) { count -= 2;  x = y; }
106    y = x >> 1;  if (y != 0) return count - 2;
107    return count - x;
108 }
109 #endif
110 
111 #ifndef HAVE_BUILTIN_CTZ
112 
113 /* From the GCC documentation:
114    Returns the number of trailing 0-bits in x, starting at the least
115    significant bit position. If x is 0, the result is undefined. */
116 
117 UInt
__builtin_ctz(UInt x)118 __builtin_ctz(UInt x)
119 {
120    UInt i, count = 0;
121 
122    for (i = 0; i < 32; ++i) {
123       if (x & 1) break;
124       ++count;
125       x >>= 1;
126    }
127    return count;
128 }
129 
130 UInt
__builtin_ctzll(ULong x)131 __builtin_ctzll(ULong x)
132 {
133    UInt i, count = 0;
134 
135    for (i = 0; i < 64; ++i) {
136       if (x & 1) break;
137       ++count;
138       x >>= 1;
139    }
140    return count;
141 }
142 #endif
143 
144 
145 #ifdef __INTEL_COMPILER
146 
147 /* Provide certain functions Intel's ICC compiler expects to be defined. */
148 
149 void *
__intel_memcpy(void * dest,const void * src,SizeT sz)150 __intel_memcpy(void *dest, const void *src, SizeT sz)
151 {
152    return VG_(memcpy)( dest, src, sz );
153 }
154 
155 void *
__intel_mic_avx512f_memcpy(void * dest,const void * src,SizeT sz)156 __intel_mic_avx512f_memcpy(void *dest, const void *src, SizeT sz)
157 {
158    return VG_(memcpy)( dest, src, sz );
159 }
160 
161 void *
__intel_new_memcpy(void * dest,const void * src,SizeT sz)162 __intel_new_memcpy(void *dest, const void *src, SizeT sz)
163 {
164    return VG_(memcpy)( dest, src, sz );
165 }
166 
167 void *
__intel_ssse3_memcpy(void * dest,const void * src,SizeT sz)168 __intel_ssse3_memcpy(void *dest, const void *src, SizeT sz)
169 {
170    return VG_(memcpy)( dest, src, sz );
171 }
172 
173 void *
__intel_ssse3_rep_memcpy(void * dest,const void * src,SizeT sz)174 __intel_ssse3_rep_memcpy(void *dest, const void *src, SizeT sz)
175 {
176    return VG_(memcpy)( dest, src, sz );
177 }
178 
179 void *
_intel_fast_memcpy(void * dest,const void * src,SizeT sz)180 _intel_fast_memcpy(void *dest, const void *src, SizeT sz)
181 {
182    return VG_(memcpy)( dest, src, sz );
183 }
184 
185 void *
__intel_lrb_memcpy(void * dest,const void * src,SizeT sz)186 __intel_lrb_memcpy(void *dest, const void *src, SizeT sz)
187 {
188    return VG_(memcpy)( dest, src, sz );
189 }
190 
191 void *
__intel_memset(void * dest,int value,SizeT num)192 __intel_memset(void *dest, int value, SizeT num)
193 {
194    return VG_(memset)( dest, value, num );
195 }
196 
197 void *
__intel_new_memset(void * dest,int value,SizeT num)198 __intel_new_memset(void *dest, int value, SizeT num)
199 {
200    return VG_(memset)( dest, value, num );
201 }
202 
203 void *
__intel_mic_avx512f_memset(void * dest,int value,SizeT num)204 __intel_mic_avx512f_memset(void *dest, int value, SizeT num)
205 {
206    return VG_(memset)( dest, value, num );
207 }
208 
209 void *
__intel_lrb_memset(void * dest,int value,SizeT num)210 __intel_lrb_memset(void *dest, int value, SizeT num)
211 {
212    return VG_(memset)( dest, value, num );
213 }
214 
215 void *
_intel_fast_memset(void * dest,int value,SizeT num)216 _intel_fast_memset(void *dest, int value, SizeT num)
217 {
218    return VG_(memset)( dest, value, num );
219 }
220 
221 #endif
222 
223 
224 /*====================================================================*/
225 /*=== gcc -fsanitize=undefined helper function support             ===*/
226 /*====================================================================*/
227 
228 void __ubsan_handle_type_mismatch ( void );
__ubsan_handle_type_mismatch(void)229 void __ubsan_handle_type_mismatch ( void )
230 {
231    VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
232    vg_assert(0);
233 }
234 
235 void __ubsan_handle_mul_overflow ( void );
__ubsan_handle_mul_overflow(void)236 void __ubsan_handle_mul_overflow ( void )
237 {
238    VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
239    vg_assert(0);
240 }
241 
242 void __ubsan_handle_add_overflow ( void );
__ubsan_handle_add_overflow(void)243 void __ubsan_handle_add_overflow ( void )
244 {
245    VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
246    vg_assert(0);
247 }
248 
249 void __ubsan_handle_sub_overflow ( void );
__ubsan_handle_sub_overflow(void)250 void __ubsan_handle_sub_overflow ( void )
251 {
252    VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
253    vg_assert(0);
254 }
255 
256 void __ubsan_handle_divrem_overflow ( void );
__ubsan_handle_divrem_overflow(void)257 void __ubsan_handle_divrem_overflow ( void )
258 {
259    VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
260    vg_assert(0);
261 }
262 
263 void __ubsan_handle_negate_overflow ( void );
__ubsan_handle_negate_overflow(void)264 void __ubsan_handle_negate_overflow ( void )
265 {
266    VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
267    vg_assert(0);
268 }
269 
270 void __ubsan_handle_out_of_bounds ( void );
__ubsan_handle_out_of_bounds(void)271 void __ubsan_handle_out_of_bounds ( void )
272 {
273    VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
274    vg_assert(0);
275 }
276 
277 void __ubsan_handle_shift_out_of_bounds ( void );
__ubsan_handle_shift_out_of_bounds(void)278 void __ubsan_handle_shift_out_of_bounds ( void )
279 {
280    VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
281    vg_assert(0);
282 }
283 
284 void __ubsan_handle_vla_bound_not_positive ( void );
__ubsan_handle_vla_bound_not_positive(void)285 void __ubsan_handle_vla_bound_not_positive ( void )
286 {
287    VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
288    vg_assert(0);
289 }
290 
291 void __ubsan_handle_nonnull_arg ( void );
__ubsan_handle_nonnull_arg(void)292 void __ubsan_handle_nonnull_arg ( void )
293 {
294    VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
295    vg_assert(0);
296 }
297 
298 /*--------------------------------------------------------------------*/
299 /*--- end                                                          ---*/
300 /*--------------------------------------------------------------------*/
301