2 /*--------------------------------------------------------------------*/
3 /*--- Entirely standalone libc stuff. m_libcbase.c ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2000-2012 Julian Seward
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.
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.
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
28 The GNU General Public License is contained in the file COPYING.
31 #include "pub_core_basics.h"
32 #include "pub_core_libcbase.h"
34 /* ---------------------------------------------------------------------
36 ------------------------------------------------------------------ */
38 Bool
VG_(isspace
) ( HChar c
)
40 return (c
== ' ' || c
== '\n' || c
== '\t' ||
41 c
== '\f' || c
== '\v' || c
== '\r');
44 Bool
VG_(isdigit
) ( HChar c
)
46 return (c
>= '0' && c
<= '9');
49 /* ---------------------------------------------------------------------
50 Converting strings to numbers
51 ------------------------------------------------------------------ */
53 static Bool
is_dec_digit(HChar c
, Long
* digit
)
55 if (c
>= '0' && c
<= '9') { *digit
= (Long
)(c
- '0'); return True
; }
59 static Bool
is_hex_digit(HChar c
, Long
* digit
)
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
; }
67 Long
VG_(strtoll10
) ( const HChar
* str
, HChar
** endptr
)
69 Bool neg
= False
, converted
= False
;
70 Long n
= 0, digit
= 0;
71 const HChar
* str0
= str
;
73 // Skip leading whitespace.
74 while (VG_(isspace
)(*str
)) str
++;
76 // Allow a leading '-' or '+'.
77 if (*str
== '-') { str
++; neg
= True
; }
78 else if (*str
== '+') { str
++; }
80 while (is_dec_digit(*str
, &digit
)) {
81 converted
= True
; // Ok, we've actually converted a digit.
86 if (!converted
) str
= str0
; // If nothing converted, endptr points to
87 if (neg
) n
= -n
; // the start of the string.
88 if (endptr
) *endptr
= (HChar
*)str
; // Record first failing character.
92 ULong
VG_(strtoull10
) ( const HChar
* str
, HChar
** endptr
)
94 Bool converted
= False
;
97 const HChar
* str0
= str
;
99 // Skip leading whitespace.
100 while (VG_(isspace
)(*str
)) str
++;
102 // Allow a leading '+'.
103 if (*str
== '+') { str
++; }
105 while (is_dec_digit(*str
, &digit
)) {
106 converted
= True
; // Ok, we've actually converted a digit.
111 if (!converted
) str
= str0
; // If nothing converted, endptr points to
112 // the start of the string.
113 if (endptr
) *endptr
= (HChar
*)str
; // Record first failing character.
117 Long
VG_(strtoll16
) ( const HChar
* str
, HChar
** endptr
)
119 Bool neg
= False
, converted
= False
;
120 Long n
= 0, digit
= 0;
121 const HChar
* str0
= str
;
123 // Skip leading whitespace.
124 while (VG_(isspace
)(*str
)) str
++;
126 // Allow a leading '-' or '+'.
127 if (*str
== '-') { str
++; neg
= True
; }
128 else if (*str
== '+') { str
++; }
130 // Allow leading "0x", but only if there's a hex digit
133 && (*(str
+1) == 'x' || *(str
+1) == 'X')
134 && is_hex_digit( *(str
+2), &digit
)) {
138 while (is_hex_digit(*str
, &digit
)) {
139 converted
= True
; // Ok, we've actually converted a digit.
144 if (!converted
) str
= str0
; // If nothing converted, endptr points to
145 if (neg
) n
= -n
; // the start of the string.
146 if (endptr
) *endptr
= (HChar
*)str
; // Record first failing character.
150 ULong
VG_(strtoull16
) ( const HChar
* str
, HChar
** endptr
)
152 Bool converted
= False
;
155 const HChar
* str0
= str
;
157 // Skip leading whitespace.
158 while (VG_(isspace
)(*str
)) str
++;
160 // Allow a leading '+'.
161 if (*str
== '+') { str
++; }
163 // Allow leading "0x", but only if there's a hex digit
166 && (*(str
+1) == 'x' || *(str
+1) == 'X')
167 && is_hex_digit( *(str
+2), &digit
)) {
171 while (is_hex_digit(*str
, &digit
)) {
172 converted
= True
; // Ok, we've actually converted a digit.
177 if (!converted
) str
= str0
; // If nothing converted, endptr points to
178 // the start of the string.
179 if (endptr
) *endptr
= (HChar
*)str
; // Record first failing character.
183 double VG_(strtod
) ( const HChar
* str
, HChar
** endptr
)
187 double n
= 0, frac
= 0, x
= 0.1;
189 // Skip leading whitespace.
190 while (VG_(isspace
)(*str
)) str
++;
192 // Allow a leading '-' or '+'.
193 if (*str
== '-') { str
++; neg
= True
; }
194 else if (*str
== '+') { str
++; }
196 while (is_dec_digit(*str
, &digit
)) {
203 while (is_dec_digit(*str
, &digit
)) {
212 if (endptr
) *endptr
= (HChar
*)str
; // Record first failing character.
216 HChar
VG_(tolower
) ( HChar c
)
218 if ( c
>= 'A' && c
<= 'Z' ) {
219 return c
- 'A' + 'a';
225 /* ---------------------------------------------------------------------
227 ------------------------------------------------------------------ */
229 SizeT
VG_(strlen
) ( const HChar
* str
)
232 while (str
[i
] != 0) i
++;
236 HChar
* VG_(strcat
) ( HChar
* dest
, const HChar
* src
)
238 HChar
* dest_orig
= dest
;
239 while (*dest
) dest
++;
240 while (*src
) *dest
++ = *src
++;
245 HChar
* VG_(strncat
) ( HChar
* dest
, const HChar
* src
, SizeT n
)
247 HChar
* dest_orig
= dest
;
248 while (*dest
) dest
++;
249 while (*src
&& n
> 0) { *dest
++ = *src
++; n
--; }
254 HChar
* VG_(strpbrk
) ( const HChar
* s
, const HChar
* accpt
)
267 HChar
* VG_(strcpy
) ( HChar
* dest
, const HChar
* src
)
269 HChar
* dest_orig
= dest
;
270 while (*src
) *dest
++ = *src
++;
275 /* Copy bytes, not overrunning the end of dest and always ensuring
277 void VG_(strncpy_safely
) ( HChar
* dest
, const HChar
* src
, SizeT ndest
)
282 if (src
[i
] == 0) return;
283 if (i
>= ndest
-1) return;
289 HChar
* VG_(strncpy
) ( HChar
* dest
, const HChar
* src
, SizeT ndest
)
293 if (i
>= ndest
) return dest
; /* reached limit */
296 /* reached NUL; pad rest with zeroes as required */
297 while (i
< ndest
) dest
[i
++] = 0;
303 Int
VG_(strcmp
) ( const HChar
* s1
, const HChar
* s2
)
306 if (*(const UChar
*)s1
< *(const UChar
*)s2
) return -1;
307 if (*(const UChar
*)s1
> *(const UChar
*)s2
) return 1;
310 if (*s1
== 0) return 0;
316 Int
VG_(strcasecmp
) ( const HChar
* s1
, const HChar
* s2
)
319 UChar c1
= (UChar
)VG_(tolower
)(*s1
);
320 UChar c2
= (UChar
)VG_(tolower
)(*s2
);
321 if (c1
< c2
) return -1;
322 if (c1
> c2
) return 1;
325 if (c1
== 0) return 0;
331 Int
VG_(strncmp
) ( const HChar
* s1
, const HChar
* s2
, SizeT nmax
)
335 if (n
>= nmax
) return 0;
336 if (*(const UChar
*)s1
< *(const UChar
*)s2
) return -1;
337 if (*(const UChar
*)s1
> *(const UChar
*)s2
) return 1;
340 if (*s1
== 0) return 0;
346 Int
VG_(strncasecmp
) ( const HChar
* s1
, const HChar
* s2
, SizeT nmax
)
352 if (n
>= nmax
) return 0;
353 c1
= (UChar
)VG_(tolower
)(*s1
);
354 c2
= (UChar
)VG_(tolower
)(*s2
);
355 if (c1
< c2
) return -1;
356 if (c1
> c2
) return 1;
359 if (c1
== 0) return 0;
365 HChar
* VG_(strstr
) ( const HChar
* haystack
, const HChar
* needle
)
368 if (haystack
== NULL
)
370 n
= VG_(strlen
)(needle
);
372 if (haystack
[0] == 0)
374 if (VG_(strncmp
)(haystack
, needle
, n
) == 0)
375 return (HChar
*)haystack
;
380 HChar
* VG_(strcasestr
) ( const HChar
* haystack
, const HChar
* needle
)
383 if (haystack
== NULL
)
385 n
= VG_(strlen
)(needle
);
387 if (haystack
[0] == 0)
389 if (VG_(strncasecmp
)(haystack
, needle
, n
) == 0)
390 return (HChar
*)haystack
;
395 HChar
* VG_(strchr
) ( const HChar
* s
, HChar c
)
398 if (*s
== c
) return (HChar
*)s
;
399 if (*s
== 0) return NULL
;
404 HChar
* VG_(strrchr
) ( const HChar
* s
, HChar c
)
406 Int n
= VG_(strlen
)(s
);
408 if (s
[n
] == c
) return (HChar
*)s
+ n
;
413 /* (code copied from glib then updated to valgrind types) */
416 VG_(strtok
) (HChar
*s
, const HChar
*delim
)
418 return VG_(strtok_r
) (s
, delim
, &olds
);
422 VG_(strtok_r
) (HChar
* s
, const HChar
* delim
, HChar
** saveptr
)
429 /* Scan leading delimiters. */
430 s
+= VG_(strspn (s
, delim
));
437 /* Find the end of the token. */
439 s
= VG_(strpbrk (token
, delim
));
441 /* This token finishes the string. */
442 *saveptr
= token
+ VG_(strlen
) (token
);
445 /* Terminate the token and make OLDS point past it. */
452 static Bool
isHex ( HChar c
)
454 return ((c
>= '0' && c
<= '9') ||
455 (c
>= 'a' && c
<= 'f') ||
456 (c
>= 'A' && c
<= 'F'));
459 static UInt
fromHex ( HChar c
)
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';
468 // ??? need to vg_assert(0);
472 Bool
VG_(parse_Addr
) ( const HChar
** ppc
, Addr
* result
)
474 Int used
, limit
= 2 * sizeof(Addr
);
483 while (isHex(**ppc
)) {
484 // ??? need to vg_assert(d < fromHex(**ppc));
485 *result
= ((*result
) << 4) | fromHex(**ppc
);
488 if (used
> limit
) return False
;
495 SizeT
VG_(strspn
) ( const HChar
* s
, const HChar
* accpt
)
499 for (p
= s
; *p
!= '\0'; ++p
) {
500 for (a
= accpt
; *a
!= '\0'; ++a
)
511 SizeT
VG_(strcspn
) ( const HChar
* s
, const HChar
* reject
)
515 if (VG_(strchr
) (reject
, *s
++) == NULL
)
524 /* ---------------------------------------------------------------------
526 ------------------------------------------------------------------ */
528 void* VG_(memcpy
) ( void *dest
, const void *src
, SizeT sz
)
530 const UChar
* s
= (const UChar
*)src
;
531 UChar
* d
= (UChar
*)dest
;
532 const UInt
* sI
= (const UInt
*)src
;
533 UInt
* dI
= (UInt
*)dest
;
535 if (VG_IS_4_ALIGNED(dI
) && VG_IS_4_ALIGNED(sI
)) {
555 s
= (const UChar
*)sI
;
565 void* VG_(memmove
)(void *dest
, const void *src
, SizeT sz
)
571 for (i
= 0; i
< sz
; i
++) {
572 ((UChar
*)dest
)[i
] = ((const UChar
*)src
)[i
];
575 else if (dest
> src
) {
576 for (i
= 0; i
< sz
; i
++) {
577 ((UChar
*)dest
)[sz
-i
-1] = ((const UChar
*)src
)[sz
-i
-1];
583 void* VG_(memset
) ( void *destV
, Int c
, SizeT sz
)
586 HChar
* d
= (HChar
*)destV
;
587 while ((!VG_IS_4_ALIGNED(d
)) && sz
>= 1) {
618 Int
VG_(memcmp
) ( const void* s1
, const void* s2
, SizeT n
)
621 const UChar
*p1
= s1
;
622 const UChar
*p2
= s2
;
639 /* ---------------------------------------------------------------------
640 Misc useful functions
641 ------------------------------------------------------------------ */
643 /////////////////////////////////////////////////////////////
644 /////////////////////////////////////////////////////////////
645 /// begin Bentley-McIlroy style quicksort
646 /// See "Engineering a Sort Function". Jon L Bentley, M. Douglas
647 /// McIlroy. Software Practice and Experience Vol 23(11), Nov 1993.
649 #define BM_MIN(a, b) \
652 #define BM_SWAPINIT(a, es) \
653 swaptype = ((a-(Char*)0) | es) % sizeof(Word) ? 2 \
654 : es > (SizeT)sizeof(Word) ? 1 \
657 #define BM_EXCH(a, b, t) \
658 (t = a, a = b, b = t)
660 #define BM_SWAP(a, b) \
662 ? bm_swapfunc(a, b, es, swaptype) \
663 : (void)BM_EXCH(*(Word*)(a), *(Word*)(b), t)
665 #define BM_VECSWAP(a, b, n) \
666 if (n > 0) bm_swapfunc(a, b, n, swaptype)
668 #define BM_PVINIT(pv, pm) \
670 pv = a, BM_SWAP(pv, pm); \
672 pv = (Char*)&v, v = *(Word*)pm
674 static Char
* bm_med3 ( Char
* a
, Char
* b
, Char
* c
,
675 Int (*cmp
)(const void*, const void*) ) {
677 ? (cmp(b
, c
) < 0 ? b
: cmp(a
, c
) < 0 ? c
: a
)
678 : (cmp(b
, c
) > 0 ? b
: cmp(a
, c
) > 0 ? c
: a
);
681 static void bm_swapfunc ( Char
* a
, Char
* b
, SizeT n
, Int swaptype
)
685 for ( ; n
> 0; a
+= sizeof(Word
), b
+= sizeof(Word
),
687 BM_EXCH(*(Word
*)a
, *(Word
*)b
, t
);
690 for ( ; n
> 0; a
+= 1, b
+= 1, n
-= 1)
695 static void bm_qsort ( Char
* a
, SizeT n
, SizeT es
,
696 Int (*cmp
)(const void*, const void*) )
698 Char
*pa
, *pb
, *pc
, *pd
, *pl
, *pm
, *pn
, *pv
;
705 for (pm
= a
+ es
; pm
< a
+ n
*es
; pm
+= es
)
706 for (pl
= pm
; pl
> a
&& cmp(pl
-es
, pl
) > 0; pl
-= es
)
716 pl
= bm_med3(pl
, pl
+s
, pl
+2*s
, cmp
);
717 pm
= bm_med3(pm
-s
, pm
, pm
+s
, cmp
);
718 pn
= bm_med3(pn
-2*s
, pn
-s
, pn
, cmp
);
720 pm
= bm_med3(pl
, pm
, pn
, cmp
);
724 pc
= pd
= a
+ (n
-1)*es
;
726 while (pb
<= pc
&& (r
= cmp(pb
, pv
)) <= 0) {
727 if (r
== 0) { BM_SWAP(pa
, pb
); pa
+= es
; }
730 while (pc
>= pb
&& (r
= cmp(pc
, pv
)) >= 0) {
731 if (r
== 0) { BM_SWAP(pc
, pd
); pd
-= es
; }
740 s
= BM_MIN(pa
-a
, pb
-pa
); BM_VECSWAP(a
, pb
-s
, s
);
741 s
= BM_MIN(pd
-pc
, pn
-pd
-es
); BM_VECSWAP(pb
, pn
-s
, s
);
742 /* Now recurse. Do the smaller partition first with an explicit
743 recursion, then do the larger partition using a tail call.
744 Except we can't rely on gcc to implement a tail call in any sane
745 way, so simply jump back to the start. This guarantees stack
746 growth can never exceed O(log N) even in the worst case. */
751 bm_qsort(a
, s1
/es
, es
, cmp
);
754 /* bm_qsort(pn-s2, s2/es, es, cmp); */
755 a
= pn
-s2
; n
= s2
/es
; es
= es
; cmp
= cmp
;
760 bm_qsort(pn
-s2
, s2
/es
, es
, cmp
);
763 /* bm_qsort(a, s1/es, es, cmp); */
764 a
= a
; n
= s1
/es
; es
= es
; cmp
= cmp
;
777 /// end Bentley-McIlroy style quicksort
778 /////////////////////////////////////////////////////////////
779 /////////////////////////////////////////////////////////////
781 /* Returns the base-2 logarithm of x. Returns -1 if x is not a power
783 Int
VG_(log2
) ( UInt x
)
786 /* Any more than 32 and we overflow anyway... */
787 for (i
= 0; i
< 32; i
++) {
788 if ((1U << i
) == x
) return i
;
793 /* Ditto for 64 bit numbers. */
794 Int
VG_(log2_64
) ( ULong x
)
797 for (i
= 0; i
< 64; i
++) {
798 if ((1ULL << i
) == x
) return i
;
803 // Generic quick sort.
804 void VG_(ssort
)( void* base
, SizeT nmemb
, SizeT size
,
805 Int (*compar
)(const void*, const void*) )
807 bm_qsort(base
,nmemb
,size
,compar
);
811 // This random number generator is based on the one suggested in Kernighan
812 // and Ritchie's "The C Programming Language".
814 // A pseudo-random number generator returning a random UInt. If pSeed
815 // is NULL, it uses its own seed, which starts at zero. If pSeed is
816 // non-NULL, it uses and updates whatever pSeed points at.
818 static UInt seed
= 0;
820 UInt
VG_(random
)( /*MOD*/UInt
* pSeed
)
825 *pSeed
= (1103515245 * *pSeed
+ 12345);
829 /*--------------------------------------------------------------------*/
831 /*--------------------------------------------------------------------*/