blob: 0c334ed2485180af19a56315b86573b3bb2845f9 [file] [log] [blame]
njn97405b22005-06-02 03:39:33 +00001
2/*--------------------------------------------------------------------*/
3/*--- Entirely standalone libc stuff. m_libcbase.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
sewardj0f157dd2013-10-18 14:27:36 +000010 Copyright (C) 2000-2013 Julian Seward
njn97405b22005-06-02 03:39:33 +000011 jseward@acm.org
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., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
njnc7561b92005-06-19 01:24:32 +000031#include "pub_core_basics.h"
njn97405b22005-06-02 03:39:33 +000032#include "pub_core_libcbase.h"
33
34/* ---------------------------------------------------------------------
florian19f91bb2012-11-10 22:29:54 +000035 HChar functions.
njn97405b22005-06-02 03:39:33 +000036 ------------------------------------------------------------------ */
37
florian19f91bb2012-11-10 22:29:54 +000038Bool VG_(isspace) ( HChar c )
njn97405b22005-06-02 03:39:33 +000039{
40 return (c == ' ' || c == '\n' || c == '\t' ||
41 c == '\f' || c == '\v' || c == '\r');
42}
43
florian19f91bb2012-11-10 22:29:54 +000044Bool VG_(isdigit) ( HChar c )
njn97405b22005-06-02 03:39:33 +000045{
46 return (c >= '0' && c <= '9');
47}
48
49/* ---------------------------------------------------------------------
50 Converting strings to numbers
51 ------------------------------------------------------------------ */
52
florian19f91bb2012-11-10 22:29:54 +000053static Bool is_dec_digit(HChar c, Long* digit)
njnea5d2352007-11-11 21:58:21 +000054{
55 if (c >= '0' && c <= '9') { *digit = (Long)(c - '0'); return True; }
56 return False;
57}
58
florian19f91bb2012-11-10 22:29:54 +000059static Bool is_hex_digit(HChar c, Long* digit)
njnea5d2352007-11-11 21:58:21 +000060{
61 if (c >= '0' && c <= '9') { *digit = (Long)(c - '0'); return True; }
62 if (c >= 'A' && c <= 'F') { *digit = (Long)((c - 'A') + 10); return True; }
63 if (c >= 'a' && c <= 'f') { *digit = (Long)((c - 'a') + 10); return True; }
64 return False;
65}
66
florian19f91bb2012-11-10 22:29:54 +000067Long VG_(strtoll10) ( const HChar* str, HChar** endptr )
njnea5d2352007-11-11 21:58:21 +000068{
njn8a0b7042009-02-20 06:10:44 +000069 Bool neg = False, converted = False;
njn7d9b3af2007-11-20 07:04:36 +000070 Long n = 0, digit = 0;
florian19f91bb2012-11-10 22:29:54 +000071 const HChar* str0 = str;
njnea5d2352007-11-11 21:58:21 +000072
73 // Skip leading whitespace.
74 while (VG_(isspace)(*str)) str++;
75
76 // Allow a leading '-' or '+'.
77 if (*str == '-') { str++; neg = True; }
78 else if (*str == '+') { str++; }
79
80 while (is_dec_digit(*str, &digit)) {
njn8a0b7042009-02-20 06:10:44 +000081 converted = True; // Ok, we've actually converted a digit.
njnea5d2352007-11-11 21:58:21 +000082 n = 10*n + digit;
83 str++;
84 }
85
njn8a0b7042009-02-20 06:10:44 +000086 if (!converted) str = str0; // If nothing converted, endptr points to
87 if (neg) n = -n; // the start of the string.
florian19f91bb2012-11-10 22:29:54 +000088 if (endptr) *endptr = (HChar *)str; // Record first failing character.
njnea5d2352007-11-11 21:58:21 +000089 return n;
90}
91
florian19f91bb2012-11-10 22:29:54 +000092ULong VG_(strtoull10) ( const HChar* str, HChar** endptr )
sewardj3b290482011-05-06 21:02:55 +000093{
94 Bool converted = False;
95 ULong n = 0;
96 Long digit = 0;
florian19f91bb2012-11-10 22:29:54 +000097 const HChar* str0 = str;
sewardj3b290482011-05-06 21:02:55 +000098
99 // Skip leading whitespace.
100 while (VG_(isspace)(*str)) str++;
101
102 // Allow a leading '+'.
103 if (*str == '+') { str++; }
104
105 while (is_dec_digit(*str, &digit)) {
106 converted = True; // Ok, we've actually converted a digit.
107 n = 10*n + digit;
108 str++;
109 }
110
111 if (!converted) str = str0; // If nothing converted, endptr points to
112 // the start of the string.
florian19f91bb2012-11-10 22:29:54 +0000113 if (endptr) *endptr = (HChar *)str; // Record first failing character.
sewardj3b290482011-05-06 21:02:55 +0000114 return n;
115}
116
florian19f91bb2012-11-10 22:29:54 +0000117Long VG_(strtoll16) ( const HChar* str, HChar** endptr )
njnea5d2352007-11-11 21:58:21 +0000118{
njn8a0b7042009-02-20 06:10:44 +0000119 Bool neg = False, converted = False;
njn7d9b3af2007-11-20 07:04:36 +0000120 Long n = 0, digit = 0;
florian19f91bb2012-11-10 22:29:54 +0000121 const HChar* str0 = str;
njnea5d2352007-11-11 21:58:21 +0000122
123 // Skip leading whitespace.
124 while (VG_(isspace)(*str)) str++;
125
126 // Allow a leading '-' or '+'.
127 if (*str == '-') { str++; neg = True; }
128 else if (*str == '+') { str++; }
129
130 // Allow leading "0x", but only if there's a hex digit
131 // following it.
132 if (*str == '0'
133 && (*(str+1) == 'x' || *(str+1) == 'X')
134 && is_hex_digit( *(str+2), &digit )) {
135 str += 2;
136 }
137
138 while (is_hex_digit(*str, &digit)) {
njn8a0b7042009-02-20 06:10:44 +0000139 converted = True; // Ok, we've actually converted a digit.
njnea5d2352007-11-11 21:58:21 +0000140 n = 16*n + digit;
141 str++;
142 }
143
njn8a0b7042009-02-20 06:10:44 +0000144 if (!converted) str = str0; // If nothing converted, endptr points to
145 if (neg) n = -n; // the start of the string.
florian19f91bb2012-11-10 22:29:54 +0000146 if (endptr) *endptr = (HChar *)str; // Record first failing character.
njnea5d2352007-11-11 21:58:21 +0000147 return n;
148}
149
florian19f91bb2012-11-10 22:29:54 +0000150ULong VG_(strtoull16) ( const HChar* str, HChar** endptr )
sewardj3b290482011-05-06 21:02:55 +0000151{
152 Bool converted = False;
153 ULong n = 0;
154 Long digit = 0;
florian19f91bb2012-11-10 22:29:54 +0000155 const HChar* str0 = str;
sewardj3b290482011-05-06 21:02:55 +0000156
157 // Skip leading whitespace.
158 while (VG_(isspace)(*str)) str++;
159
160 // Allow a leading '+'.
161 if (*str == '+') { str++; }
162
163 // Allow leading "0x", but only if there's a hex digit
164 // following it.
165 if (*str == '0'
166 && (*(str+1) == 'x' || *(str+1) == 'X')
167 && is_hex_digit( *(str+2), &digit )) {
168 str += 2;
169 }
170
171 while (is_hex_digit(*str, &digit)) {
172 converted = True; // Ok, we've actually converted a digit.
173 n = 16*n + digit;
174 str++;
175 }
176
177 if (!converted) str = str0; // If nothing converted, endptr points to
178 // the start of the string.
florian19f91bb2012-11-10 22:29:54 +0000179 if (endptr) *endptr = (HChar *)str; // Record first failing character.
sewardj3b290482011-05-06 21:02:55 +0000180 return n;
181}
182
florian19f91bb2012-11-10 22:29:54 +0000183double VG_(strtod) ( const HChar* str, HChar** endptr )
njnea5d2352007-11-11 21:58:21 +0000184{
185 Bool neg = False;
186 Long digit;
187 double n = 0, frac = 0, x = 0.1;
188
189 // Skip leading whitespace.
190 while (VG_(isspace)(*str)) str++;
191
192 // Allow a leading '-' or '+'.
193 if (*str == '-') { str++; neg = True; }
194 else if (*str == '+') { str++; }
195
196 while (is_dec_digit(*str, &digit)) {
197 n = 10*n + digit;
198 str++;
199 }
200
201 if (*str == '.') {
202 str++;
203 while (is_dec_digit(*str, &digit)) {
204 frac += x*digit;
205 x /= 10;
206 str++;
207 }
208 }
209
210 n += frac;
211 if (neg) n = -n;
florian19f91bb2012-11-10 22:29:54 +0000212 if (endptr) *endptr = (HChar *)str; // Record first failing character.
njnea5d2352007-11-11 21:58:21 +0000213 return n;
214}
215
florian19f91bb2012-11-10 22:29:54 +0000216HChar VG_(tolower) ( HChar c )
njnf76d27a2009-05-28 01:53:07 +0000217{
218 if ( c >= 'A' && c <= 'Z' ) {
219 return c - 'A' + 'a';
220 } else {
221 return c;
222 }
223}
224
njn97405b22005-06-02 03:39:33 +0000225/* ---------------------------------------------------------------------
226 String functions
227 ------------------------------------------------------------------ */
228
florian19f91bb2012-11-10 22:29:54 +0000229SizeT VG_(strlen) ( const HChar* str )
njn97405b22005-06-02 03:39:33 +0000230{
sewardj4f2683a2008-10-26 11:53:30 +0000231 SizeT i = 0;
njn97405b22005-06-02 03:39:33 +0000232 while (str[i] != 0) i++;
233 return i;
234}
235
florian19f91bb2012-11-10 22:29:54 +0000236HChar* VG_(strcat) ( HChar* dest, const HChar* src )
njn97405b22005-06-02 03:39:33 +0000237{
florian19f91bb2012-11-10 22:29:54 +0000238 HChar* dest_orig = dest;
njn97405b22005-06-02 03:39:33 +0000239 while (*dest) dest++;
240 while (*src) *dest++ = *src++;
241 *dest = 0;
242 return dest_orig;
243}
244
florian19f91bb2012-11-10 22:29:54 +0000245HChar* VG_(strncat) ( HChar* dest, const HChar* src, SizeT n )
njn97405b22005-06-02 03:39:33 +0000246{
florian19f91bb2012-11-10 22:29:54 +0000247 HChar* dest_orig = dest;
njn97405b22005-06-02 03:39:33 +0000248 while (*dest) dest++;
249 while (*src && n > 0) { *dest++ = *src++; n--; }
250 *dest = 0;
251 return dest_orig;
252}
253
florian19f91bb2012-11-10 22:29:54 +0000254HChar* VG_(strpbrk) ( const HChar* s, const HChar* accpt )
njn97405b22005-06-02 03:39:33 +0000255{
florian19f91bb2012-11-10 22:29:54 +0000256 const HChar* a;
njn97405b22005-06-02 03:39:33 +0000257 while (*s) {
njnf9dcb3b2009-05-19 05:50:34 +0000258 a = accpt;
njn97405b22005-06-02 03:39:33 +0000259 while (*a)
260 if (*a++ == *s)
florian19f91bb2012-11-10 22:29:54 +0000261 return (HChar *)s;
njn97405b22005-06-02 03:39:33 +0000262 s++;
263 }
264 return NULL;
265}
266
florian19f91bb2012-11-10 22:29:54 +0000267HChar* VG_(strcpy) ( HChar* dest, const HChar* src )
njn97405b22005-06-02 03:39:33 +0000268{
florian19f91bb2012-11-10 22:29:54 +0000269 HChar* dest_orig = dest;
njn97405b22005-06-02 03:39:33 +0000270 while (*src) *dest++ = *src++;
271 *dest = 0;
272 return dest_orig;
273}
274
275/* Copy bytes, not overrunning the end of dest and always ensuring
276 zero termination. */
florian19f91bb2012-11-10 22:29:54 +0000277void VG_(strncpy_safely) ( HChar* dest, const HChar* src, SizeT ndest )
njn97405b22005-06-02 03:39:33 +0000278{
sewardj4f2683a2008-10-26 11:53:30 +0000279 SizeT i = 0;
njn97405b22005-06-02 03:39:33 +0000280 while (True) {
281 dest[i] = 0;
282 if (src[i] == 0) return;
283 if (i >= ndest-1) return;
284 dest[i] = src[i];
285 i++;
286 }
287}
288
florian19f91bb2012-11-10 22:29:54 +0000289HChar* VG_(strncpy) ( HChar* dest, const HChar* src, SizeT ndest )
njn97405b22005-06-02 03:39:33 +0000290{
sewardj4f2683a2008-10-26 11:53:30 +0000291 SizeT i = 0;
njn97405b22005-06-02 03:39:33 +0000292 while (True) {
293 if (i >= ndest) return dest; /* reached limit */
294 dest[i] = src[i];
295 if (src[i++] == 0) {
296 /* reached NUL; pad rest with zeroes as required */
297 while (i < ndest) dest[i++] = 0;
298 return dest;
299 }
300 }
301}
302
florian19f91bb2012-11-10 22:29:54 +0000303Int VG_(strcmp) ( const HChar* s1, const HChar* s2 )
njn97405b22005-06-02 03:39:33 +0000304{
305 while (True) {
florian3e798632012-11-24 19:41:54 +0000306 if (*(const UChar*)s1 < *(const UChar*)s2) return -1;
307 if (*(const UChar*)s1 > *(const UChar*)s2) return 1;
njn97405b22005-06-02 03:39:33 +0000308
philippe56ddd5b2012-07-26 22:44:07 +0000309 /* *s1 == *s2 */
310 if (*s1 == 0) return 0;
311
njn97405b22005-06-02 03:39:33 +0000312 s1++; s2++;
313 }
314}
315
florian19f91bb2012-11-10 22:29:54 +0000316Int VG_(strcasecmp) ( const HChar* s1, const HChar* s2 )
njnf76d27a2009-05-28 01:53:07 +0000317{
318 while (True) {
319 UChar c1 = (UChar)VG_(tolower)(*s1);
320 UChar c2 = (UChar)VG_(tolower)(*s2);
njnf76d27a2009-05-28 01:53:07 +0000321 if (c1 < c2) return -1;
322 if (c1 > c2) return 1;
philippe56ddd5b2012-07-26 22:44:07 +0000323
324 /* c1 == c2 */
325 if (c1 == 0) return 0;
njnf76d27a2009-05-28 01:53:07 +0000326
327 s1++; s2++;
328 }
329}
330
florian19f91bb2012-11-10 22:29:54 +0000331Int VG_(strncmp) ( const HChar* s1, const HChar* s2, SizeT nmax )
njn97405b22005-06-02 03:39:33 +0000332{
sewardj4f2683a2008-10-26 11:53:30 +0000333 SizeT n = 0;
njn97405b22005-06-02 03:39:33 +0000334 while (True) {
335 if (n >= nmax) return 0;
florian3e798632012-11-24 19:41:54 +0000336 if (*(const UChar*)s1 < *(const UChar*)s2) return -1;
337 if (*(const UChar*)s1 > *(const UChar*)s2) return 1;
philippe56ddd5b2012-07-26 22:44:07 +0000338
339 /* *s1 == *s2 */
340 if (*s1 == 0) return 0;
njn97405b22005-06-02 03:39:33 +0000341
342 s1++; s2++; n++;
343 }
344}
345
florian19f91bb2012-11-10 22:29:54 +0000346Int VG_(strncasecmp) ( const HChar* s1, const HChar* s2, SizeT nmax )
njnf76d27a2009-05-28 01:53:07 +0000347{
348 Int n = 0;
349 while (True) {
350 UChar c1;
351 UChar c2;
352 if (n >= nmax) return 0;
353 c1 = (UChar)VG_(tolower)(*s1);
354 c2 = (UChar)VG_(tolower)(*s2);
njnf76d27a2009-05-28 01:53:07 +0000355 if (c1 < c2) return -1;
356 if (c1 > c2) return 1;
357
philippe56ddd5b2012-07-26 22:44:07 +0000358 /* c1 == c2 */
359 if (c1 == 0) return 0;
360
njnf76d27a2009-05-28 01:53:07 +0000361 s1++; s2++; n++;
362 }
363}
364
florian19f91bb2012-11-10 22:29:54 +0000365HChar* VG_(strstr) ( const HChar* haystack, const HChar* needle )
njn97405b22005-06-02 03:39:33 +0000366{
sewardj4f2683a2008-10-26 11:53:30 +0000367 SizeT n;
njn97405b22005-06-02 03:39:33 +0000368 if (haystack == NULL)
369 return NULL;
370 n = VG_(strlen)(needle);
371 while (True) {
372 if (haystack[0] == 0)
373 return NULL;
374 if (VG_(strncmp)(haystack, needle, n) == 0)
florian19f91bb2012-11-10 22:29:54 +0000375 return (HChar*)haystack;
njn97405b22005-06-02 03:39:33 +0000376 haystack++;
377 }
378}
379
florian19f91bb2012-11-10 22:29:54 +0000380HChar* VG_(strcasestr) ( const HChar* haystack, const HChar* needle )
njnf76d27a2009-05-28 01:53:07 +0000381{
382 Int n;
383 if (haystack == NULL)
384 return NULL;
385 n = VG_(strlen)(needle);
386 while (True) {
387 if (haystack[0] == 0)
388 return NULL;
389 if (VG_(strncasecmp)(haystack, needle, n) == 0)
florian19f91bb2012-11-10 22:29:54 +0000390 return (HChar*)haystack;
njnf76d27a2009-05-28 01:53:07 +0000391 haystack++;
392 }
393}
394
florian19f91bb2012-11-10 22:29:54 +0000395HChar* VG_(strchr) ( const HChar* s, HChar c )
njn97405b22005-06-02 03:39:33 +0000396{
397 while (True) {
florian19f91bb2012-11-10 22:29:54 +0000398 if (*s == c) return (HChar *)s;
njn97405b22005-06-02 03:39:33 +0000399 if (*s == 0) return NULL;
400 s++;
401 }
402}
403
florian19f91bb2012-11-10 22:29:54 +0000404HChar* VG_(strrchr) ( const HChar* s, HChar c )
njn97405b22005-06-02 03:39:33 +0000405{
406 Int n = VG_(strlen)(s);
407 while (--n > 0) {
florian19f91bb2012-11-10 22:29:54 +0000408 if (s[n] == c) return (HChar *)s + n;
njn97405b22005-06-02 03:39:33 +0000409 }
410 return NULL;
411}
412
sewardj3b290482011-05-06 21:02:55 +0000413/* (code copied from glib then updated to valgrind types) */
florian19f91bb2012-11-10 22:29:54 +0000414static HChar *olds;
415HChar *
416VG_(strtok) (HChar *s, const HChar *delim)
sewardj3b290482011-05-06 21:02:55 +0000417{
418 return VG_(strtok_r) (s, delim, &olds);
419}
420
florian19f91bb2012-11-10 22:29:54 +0000421HChar *
422VG_(strtok_r) (HChar* s, const HChar* delim, HChar** saveptr)
sewardj3b290482011-05-06 21:02:55 +0000423{
florian19f91bb2012-11-10 22:29:54 +0000424 HChar *token;
sewardj3b290482011-05-06 21:02:55 +0000425
426 if (s == NULL)
427 s = *saveptr;
428
429 /* Scan leading delimiters. */
430 s += VG_(strspn (s, delim));
431 if (*s == '\0')
432 {
433 *saveptr = s;
434 return NULL;
435 }
436
437 /* Find the end of the token. */
438 token = s;
439 s = VG_(strpbrk (token, delim));
440 if (s == NULL)
441 /* This token finishes the string. */
442 *saveptr = token + VG_(strlen) (token);
443 else
444 {
445 /* Terminate the token and make OLDS point past it. */
446 *s = '\0';
447 *saveptr = s + 1;
448 }
449 return token;
450}
451
florian19f91bb2012-11-10 22:29:54 +0000452static Bool isHex ( HChar c )
sewardj3b290482011-05-06 21:02:55 +0000453{
454 return ((c >= '0' && c <= '9') ||
455 (c >= 'a' && c <= 'f') ||
456 (c >= 'A' && c <= 'F'));
457}
458
florian19f91bb2012-11-10 22:29:54 +0000459static UInt fromHex ( HChar c )
sewardj3b290482011-05-06 21:02:55 +0000460{
461 if (c >= '0' && c <= '9')
462 return (UInt)c - (UInt)'0';
463 if (c >= 'a' && c <= 'f')
464 return 10 + (UInt)c - (UInt)'a';
465 if (c >= 'A' && c <= 'F')
466 return 10 + (UInt)c - (UInt)'A';
467 /*NOTREACHED*/
468 // ??? need to vg_assert(0);
469 return 0;
470}
471
florian19f91bb2012-11-10 22:29:54 +0000472Bool VG_(parse_Addr) ( const HChar** ppc, Addr* result )
sewardj3b290482011-05-06 21:02:55 +0000473{
474 Int used, limit = 2 * sizeof(Addr);
475 if (**ppc != '0')
476 return False;
477 (*ppc)++;
478 if (**ppc != 'x')
479 return False;
480 (*ppc)++;
481 *result = 0;
482 used = 0;
483 while (isHex(**ppc)) {
484 // ??? need to vg_assert(d < fromHex(**ppc));
485 *result = ((*result) << 4) | fromHex(**ppc);
486 (*ppc)++;
487 used++;
488 if (used > limit) return False;
489 }
490 if (used == 0)
491 return False;
492 return True;
493}
494
florian19f91bb2012-11-10 22:29:54 +0000495SizeT VG_(strspn) ( const HChar* s, const HChar* accpt )
sewardj4f2683a2008-10-26 11:53:30 +0000496{
florian19f91bb2012-11-10 22:29:54 +0000497 const HChar *p, *a;
sewardj4f2683a2008-10-26 11:53:30 +0000498 SizeT count = 0;
499 for (p = s; *p != '\0'; ++p) {
njnf9dcb3b2009-05-19 05:50:34 +0000500 for (a = accpt; *a != '\0'; ++a)
sewardj4f2683a2008-10-26 11:53:30 +0000501 if (*p == *a)
502 break;
503 if (*a == '\0')
504 return count;
505 else
506 ++count;
507 }
508 return count;
509}
510
florian19f91bb2012-11-10 22:29:54 +0000511SizeT VG_(strcspn) ( const HChar* s, const HChar* reject )
sewardj4f2683a2008-10-26 11:53:30 +0000512{
513 SizeT count = 0;
514 while (*s != '\0') {
515 if (VG_(strchr) (reject, *s++) == NULL)
516 ++count;
517 else
518 return count;
519 }
520 return count;
521}
522
523
njn97405b22005-06-02 03:39:33 +0000524/* ---------------------------------------------------------------------
njn97405b22005-06-02 03:39:33 +0000525 mem* functions
526 ------------------------------------------------------------------ */
527
528void* VG_(memcpy) ( void *dest, const void *src, SizeT sz )
529{
sewardj45f4e7c2005-09-27 19:20:21 +0000530 const UChar* s = (const UChar*)src;
531 UChar* d = (UChar*)dest;
532 const UInt* sI = (const UInt*)src;
533 UInt* dI = (UInt*)dest;
534
535 if (VG_IS_4_ALIGNED(dI) && VG_IS_4_ALIGNED(sI)) {
536 while (sz >= 16) {
537 dI[0] = sI[0];
538 dI[1] = sI[1];
539 dI[2] = sI[2];
540 dI[3] = sI[3];
541 sz -= 16;
542 dI += 4;
543 sI += 4;
544 }
545 if (sz == 0)
546 return dest;
547 while (sz >= 4) {
548 dI[0] = sI[0];
549 sz -= 4;
550 dI += 1;
551 sI += 1;
552 }
553 if (sz == 0)
554 return dest;
555 s = (const UChar*)sI;
556 d = (UChar*)dI;
557 }
njn97405b22005-06-02 03:39:33 +0000558
sewardj5d616df2013-07-02 08:07:15 +0000559 /* If we're unlucky, the alignment constraints for the fast case
560 above won't apply, and we'll have to to it all here. Hence the
561 unrolling. */
562 while (sz >= 4) {
563 d[0] = s[0];
564 d[1] = s[1];
565 d[2] = s[2];
566 d[3] = s[3];
567 d += 4;
568 s += 4;
569 sz -= 4;
570 }
571 while (sz >= 1) {
572 d[0] = s[0];
573 d += 1;
574 s += 1;
575 sz -= 1;
576 }
njn97405b22005-06-02 03:39:33 +0000577
578 return dest;
579}
580
sewardjbbec7722007-11-25 14:08:53 +0000581void* VG_(memmove)(void *dest, const void *src, SizeT sz)
582{
583 SizeT i;
584 if (sz == 0)
585 return dest;
586 if (dest < src) {
587 for (i = 0; i < sz; i++) {
florian3e798632012-11-24 19:41:54 +0000588 ((UChar*)dest)[i] = ((const UChar*)src)[i];
sewardjbbec7722007-11-25 14:08:53 +0000589 }
590 }
591 else if (dest > src) {
tom4634b012009-11-03 21:14:31 +0000592 for (i = 0; i < sz; i++) {
florian3e798632012-11-24 19:41:54 +0000593 ((UChar*)dest)[sz-i-1] = ((const UChar*)src)[sz-i-1];
sewardjbbec7722007-11-25 14:08:53 +0000594 }
595 }
596 return dest;
597}
598
sewardjb8b79ad2008-03-03 01:35:41 +0000599void* VG_(memset) ( void *destV, Int c, SizeT sz )
njn97405b22005-06-02 03:39:33 +0000600{
sewardjb8b79ad2008-03-03 01:35:41 +0000601 Int c4;
florian19f91bb2012-11-10 22:29:54 +0000602 HChar* d = (HChar*)destV;
sewardjb8b79ad2008-03-03 01:35:41 +0000603 while ((!VG_IS_4_ALIGNED(d)) && sz >= 1) {
sewardj3187a4e2005-12-04 23:27:14 +0000604 d[0] = c;
605 d++;
606 sz--;
607 }
sewardjb8b79ad2008-03-03 01:35:41 +0000608 if (sz == 0)
609 return destV;
610 c4 = c & 0xFF;
611 c4 |= (c4 << 8);
612 c4 |= (c4 << 16);
613 while (sz >= 16) {
614 ((Int*)d)[0] = c4;
615 ((Int*)d)[1] = c4;
616 ((Int*)d)[2] = c4;
617 ((Int*)d)[3] = c4;
618 d += 16;
619 sz -= 16;
620 }
621 while (sz >= 4) {
622 ((Int*)d)[0] = c4;
623 d += 4;
624 sz -= 4;
625 }
626 while (sz >= 1) {
627 d[0] = c;
628 d++;
629 sz--;
630 }
631 return destV;
njn97405b22005-06-02 03:39:33 +0000632}
633
634Int VG_(memcmp) ( const void* s1, const void* s2, SizeT n )
635{
636 Int res;
tom151a6392005-11-11 12:30:36 +0000637 const UChar *p1 = s1;
638 const UChar *p2 = s2;
njn97405b22005-06-02 03:39:33 +0000639 UChar a0;
640 UChar b0;
641
642 while (n != 0) {
tom151a6392005-11-11 12:30:36 +0000643 a0 = p1[0];
644 b0 = p2[0];
645 p1 += 1;
646 p2 += 1;
njn97405b22005-06-02 03:39:33 +0000647 res = a0 - b0;
648 if (res != 0)
649 return res;
650 n -= 1;
651 }
652 return 0;
653}
654
655/* ---------------------------------------------------------------------
656 Misc useful functions
657 ------------------------------------------------------------------ */
658
sewardjb8b79ad2008-03-03 01:35:41 +0000659/////////////////////////////////////////////////////////////
660/////////////////////////////////////////////////////////////
661/// begin Bentley-McIlroy style quicksort
662/// See "Engineering a Sort Function". Jon L Bentley, M. Douglas
663/// McIlroy. Software Practice and Experience Vol 23(11), Nov 1993.
664
665#define BM_MIN(a, b) \
666 (a) < (b) ? a : b
667
668#define BM_SWAPINIT(a, es) \
669 swaptype = ((a-(Char*)0) | es) % sizeof(Word) ? 2 \
670 : es > (SizeT)sizeof(Word) ? 1 \
671 : 0
672
673#define BM_EXCH(a, b, t) \
674 (t = a, a = b, b = t)
675
676#define BM_SWAP(a, b) \
677 swaptype != 0 \
678 ? bm_swapfunc(a, b, es, swaptype) \
679 : (void)BM_EXCH(*(Word*)(a), *(Word*)(b), t)
680
681#define BM_VECSWAP(a, b, n) \
682 if (n > 0) bm_swapfunc(a, b, n, swaptype)
683
684#define BM_PVINIT(pv, pm) \
685 if (swaptype != 0) \
686 pv = a, BM_SWAP(pv, pm); \
687 else \
688 pv = (Char*)&v, v = *(Word*)pm
689
690static Char* bm_med3 ( Char* a, Char* b, Char* c,
florian6bd9dc12012-11-23 16:17:43 +0000691 Int (*cmp)(const void*, const void*) ) {
sewardjb8b79ad2008-03-03 01:35:41 +0000692 return cmp(a, b) < 0
693 ? (cmp(b, c) < 0 ? b : cmp(a, c) < 0 ? c : a)
694 : (cmp(b, c) > 0 ? b : cmp(a, c) > 0 ? c : a);
695}
696
697static void bm_swapfunc ( Char* a, Char* b, SizeT n, Int swaptype )
698{
699 if (swaptype <= 1) {
700 Word t;
701 for ( ; n > 0; a += sizeof(Word), b += sizeof(Word),
702 n -= sizeof(Word))
703 BM_EXCH(*(Word*)a, *(Word*)b, t);
704 } else {
705 Char t;
706 for ( ; n > 0; a += 1, b += 1, n -= 1)
707 BM_EXCH(*a, *b, t);
708 }
709}
710
711static void bm_qsort ( Char* a, SizeT n, SizeT es,
florian6bd9dc12012-11-23 16:17:43 +0000712 Int (*cmp)(const void*, const void*) )
sewardjb8b79ad2008-03-03 01:35:41 +0000713{
714 Char *pa, *pb, *pc, *pd, *pl, *pm, *pn, *pv;
715 Int r, swaptype;
716 Word t, v;
717 SizeT s, s1, s2;
718 tailcall:
719 BM_SWAPINIT(a, es);
720 if (n < 7) {
721 for (pm = a + es; pm < a + n*es; pm += es)
722 for (pl = pm; pl > a && cmp(pl-es, pl) > 0; pl -= es)
723 BM_SWAP(pl, pl-es);
724 return;
725 }
726 pm = a + (n/2)*es;
727 if (n > 7) {
728 pl = a;
729 pn = a + (n-1)*es;
730 if (n > 40) {
731 s = (n/8)*es;
732 pl = bm_med3(pl, pl+s, pl+2*s, cmp);
733 pm = bm_med3(pm-s, pm, pm+s, cmp);
734 pn = bm_med3(pn-2*s, pn-s, pn, cmp);
735 }
736 pm = bm_med3(pl, pm, pn, cmp);
737 }
738 BM_PVINIT(pv, pm);
739 pa = pb = a;
740 pc = pd = a + (n-1)*es;
741 for (;;) {
742 while (pb <= pc && (r = cmp(pb, pv)) <= 0) {
743 if (r == 0) { BM_SWAP(pa, pb); pa += es; }
744 pb += es;
745 }
746 while (pc >= pb && (r = cmp(pc, pv)) >= 0) {
747 if (r == 0) { BM_SWAP(pc, pd); pd -= es; }
748 pc -= es;
749 }
750 if (pb > pc) break;
751 BM_SWAP(pb, pc);
752 pb += es;
753 pc -= es;
754 }
755 pn = a + n*es;
756 s = BM_MIN(pa-a, pb-pa ); BM_VECSWAP(a, pb-s, s);
757 s = BM_MIN(pd-pc, pn-pd-es); BM_VECSWAP(pb, pn-s, s);
758 /* Now recurse. Do the smaller partition first with an explicit
759 recursion, then do the larger partition using a tail call.
760 Except we can't rely on gcc to implement a tail call in any sane
761 way, so simply jump back to the start. This guarantees stack
762 growth can never exceed O(log N) even in the worst case. */
763 s1 = pb-pa;
764 s2 = pd-pc;
765 if (s1 < s2) {
766 if (s1 > es) {
767 bm_qsort(a, s1/es, es, cmp);
768 }
769 if (s2 > es) {
770 /* bm_qsort(pn-s2, s2/es, es, cmp); */
771 a = pn-s2; n = s2/es; es = es; cmp = cmp;
772 goto tailcall;
773 }
774 } else {
775 if (s2 > es) {
776 bm_qsort(pn-s2, s2/es, es, cmp);
777 }
778 if (s1 > es) {
779 /* bm_qsort(a, s1/es, es, cmp); */
780 a = a; n = s1/es; es = es; cmp = cmp;
781 goto tailcall;
782 }
783 }
784}
785
786#undef BM_MIN
787#undef BM_SWAPINIT
788#undef BM_EXCH
789#undef BM_SWAP
790#undef BM_VECSWAP
791#undef BM_PVINIT
792
793/// end Bentley-McIlroy style quicksort
794/////////////////////////////////////////////////////////////
795/////////////////////////////////////////////////////////////
796
797/* Returns the base-2 logarithm of x. Returns -1 if x is not a power
798 of two. */
799Int VG_(log2) ( UInt x )
njn97405b22005-06-02 03:39:33 +0000800{
801 Int i;
802 /* Any more than 32 and we overflow anyway... */
803 for (i = 0; i < 32; i++) {
sewardjb8b79ad2008-03-03 01:35:41 +0000804 if ((1U << i) == x) return i;
njn97405b22005-06-02 03:39:33 +0000805 }
806 return -1;
807}
808
sewardjaebbf1c2011-06-13 13:14:00 +0000809/* Ditto for 64 bit numbers. */
810Int VG_(log2_64) ( ULong x )
811{
812 Int i;
813 for (i = 0; i < 64; i++) {
814 if ((1ULL << i) == x) return i;
815 }
816 return -1;
817}
njn97405b22005-06-02 03:39:33 +0000818
njnfab29902008-03-03 02:15:03 +0000819// Generic quick sort.
njn97405b22005-06-02 03:39:33 +0000820void VG_(ssort)( void* base, SizeT nmemb, SizeT size,
florian6bd9dc12012-11-23 16:17:43 +0000821 Int (*compar)(const void*, const void*) )
njn97405b22005-06-02 03:39:33 +0000822{
sewardjb8b79ad2008-03-03 01:35:41 +0000823 bm_qsort(base,nmemb,size,compar);
njn97405b22005-06-02 03:39:33 +0000824}
825
sewardjb8b79ad2008-03-03 01:35:41 +0000826
njn9828b342005-07-08 04:08:59 +0000827// This random number generator is based on the one suggested in Kernighan
828// and Ritchie's "The C Programming Language".
sewardj45f4e7c2005-09-27 19:20:21 +0000829
830// A pseudo-random number generator returning a random UInt. If pSeed
831// is NULL, it uses its own seed, which starts at zero. If pSeed is
832// non-NULL, it uses and updates whatever pSeed points at.
833
834static UInt seed = 0;
835
836UInt VG_(random)( /*MOD*/UInt* pSeed )
njn9828b342005-07-08 04:08:59 +0000837{
sewardj45f4e7c2005-09-27 19:20:21 +0000838 if (pSeed == NULL)
839 pSeed = &seed;
840
841 *pSeed = (1103515245 * *pSeed + 12345);
842 return *pSeed;
njn9828b342005-07-08 04:08:59 +0000843}
844
sewardj5d616df2013-07-02 08:07:15 +0000845
846/* The following Adler-32 checksum code is taken from zlib-1.2.3, which
847 has the following copyright notice. */
848/*
849Copyright notice:
850
851 (C) 1995-2004 Jean-loup Gailly and Mark Adler
852
853 This software is provided 'as-is', without any express or implied
854 warranty. In no event will the authors be held liable for any damages
855 arising from the use of this software.
856
857 Permission is granted to anyone to use this software for any purpose,
858 including commercial applications, and to alter it and redistribute it
859 freely, subject to the following restrictions:
860
861 1. The origin of this software must not be misrepresented; you must not
862 claim that you wrote the original software. If you use this software
863 in a product, an acknowledgment in the product documentation would be
864 appreciated but is not required.
865 2. Altered source versions must be plainly marked as such, and must not be
866 misrepresented as being the original software.
867 3. This notice may not be removed or altered from any source distribution.
868
869 Jean-loup Gailly Mark Adler
870 jloup@gzip.org madler@alumni.caltech.edu
871
872If you use the zlib library in a product, we would appreciate *not*
873receiving lengthy legal documents to sign. The sources are provided
874for free but without warranty of any kind. The library has been
875entirely written by Jean-loup Gailly and Mark Adler; it does not
876include third-party code.
877
878If you redistribute modified sources, we would appreciate that you include
879in the file ChangeLog history information documenting your changes. Please
880read the FAQ for more information on the distribution of modified source
881versions.
882*/
883
884/* Update a running Adler-32 checksum with the bytes buf[0..len-1] and
885 return the updated checksum. If buf is NULL, this function returns
886 the required initial value for the checksum. An Adler-32 checksum is
887 almost as reliable as a CRC32 but can be computed much faster. */
888UInt VG_(adler32)( UInt adler, const UChar* buf, UInt len )
889{
890# define BASE 65521UL /* largest prime smaller than 65536 */
891# define NMAX 5552
892 /* NMAX is the largest n such that
893 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
894
895# define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
896# define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
897# define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
898# define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
899# define DO16(buf) DO8(buf,0); DO8(buf,8);
900
901 /* The zlib sources recommend this definition of MOD if the
902 processor cannot do integer division in hardware. */
903# define MOD(a) \
904 do { \
905 if (a >= (BASE << 16)) a -= (BASE << 16); \
906 if (a >= (BASE << 15)) a -= (BASE << 15); \
907 if (a >= (BASE << 14)) a -= (BASE << 14); \
908 if (a >= (BASE << 13)) a -= (BASE << 13); \
909 if (a >= (BASE << 12)) a -= (BASE << 12); \
910 if (a >= (BASE << 11)) a -= (BASE << 11); \
911 if (a >= (BASE << 10)) a -= (BASE << 10); \
912 if (a >= (BASE << 9)) a -= (BASE << 9); \
913 if (a >= (BASE << 8)) a -= (BASE << 8); \
914 if (a >= (BASE << 7)) a -= (BASE << 7); \
915 if (a >= (BASE << 6)) a -= (BASE << 6); \
916 if (a >= (BASE << 5)) a -= (BASE << 5); \
917 if (a >= (BASE << 4)) a -= (BASE << 4); \
918 if (a >= (BASE << 3)) a -= (BASE << 3); \
919 if (a >= (BASE << 2)) a -= (BASE << 2); \
920 if (a >= (BASE << 1)) a -= (BASE << 1); \
921 if (a >= BASE) a -= BASE; \
922 } while (0)
923# define MOD4(a) \
924 do { \
925 if (a >= (BASE << 4)) a -= (BASE << 4); \
926 if (a >= (BASE << 3)) a -= (BASE << 3); \
927 if (a >= (BASE << 2)) a -= (BASE << 2); \
928 if (a >= (BASE << 1)) a -= (BASE << 1); \
929 if (a >= BASE) a -= BASE; \
930 } while (0)
931
932 UInt sum2;
933 UInt n;
934
935 /* split Adler-32 into component sums */
936 sum2 = (adler >> 16) & 0xffff;
937 adler &= 0xffff;
938
939 /* in case user likes doing a byte at a time, keep it fast */
940 if (len == 1) {
941 adler += buf[0];
942 if (adler >= BASE)
943 adler -= BASE;
944 sum2 += adler;
945 if (sum2 >= BASE)
946 sum2 -= BASE;
947 return adler | (sum2 << 16);
948 }
949
950 /* initial Adler-32 value (deferred check for len == 1 speed) */
951 if (buf == NULL)
952 return 1L;
953
954 /* in case short lengths are provided, keep it somewhat fast */
955 if (len < 16) {
956 while (len--) {
957 adler += *buf++;
958 sum2 += adler;
959 }
960 if (adler >= BASE)
961 adler -= BASE;
962 MOD4(sum2); /* only added so many BASE's */
963 return adler | (sum2 << 16);
964 }
965
966 /* do length NMAX blocks -- requires just one modulo operation */
967 while (len >= NMAX) {
968 len -= NMAX;
969 n = NMAX / 16; /* NMAX is divisible by 16 */
970 do {
971 DO16(buf); /* 16 sums unrolled */
972 buf += 16;
973 } while (--n);
974 MOD(adler);
975 MOD(sum2);
976 }
977
978 /* do remaining bytes (less than NMAX, still just one modulo) */
979 if (len) { /* avoid modulos if none remaining */
980 while (len >= 16) {
981 len -= 16;
982 DO16(buf);
983 buf += 16;
984 }
985 while (len--) {
986 adler += *buf++;
987 sum2 += adler;
988 }
989 MOD(adler);
990 MOD(sum2);
991 }
992
993 /* return recombined sums */
994 return adler | (sum2 << 16);
995
996# undef MOD4
997# undef MOD
998# undef DO16
999# undef DO8
1000# undef DO4
1001# undef DO2
1002# undef DO1
1003# undef NMAX
1004# undef BASE
1005}
1006
njn97405b22005-06-02 03:39:33 +00001007/*--------------------------------------------------------------------*/
1008/*--- end ---*/
1009/*--------------------------------------------------------------------*/
1010