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-2017 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, see <http://www.gnu.org/licenses/>.
26 The GNU General Public License is contained in the file COPYING.
29 #include "pub_core_basics.h"
30 #include "pub_core_libcassert.h" // VG_(exit_now)
31 #include "pub_core_debuglog.h" // VG_(debugLog)
32 #include "pub_core_libcbase.h"
35 /* ---------------------------------------------------------------------
36 Assert machinery for use in this file. vg_assert cannot be called
37 here due to cyclic dependencies.
38 ------------------------------------------------------------------ */
40 #define libcbase_assert(expr) \
41 ((void) (LIKELY(expr) ? 0 : \
42 (ML_(libcbase_assert_fail)(#expr, \
44 __PRETTY_FUNCTION__))))
46 static void ML_(libcbase_assert_fail
)( const HChar
*expr
,
51 VG_(debugLog
)(0, "libcbase",
52 "Valgrind: FATAL: assertion failed:\n");
53 VG_(debugLog
)(0, "libcbase", " %s\n", expr
);
54 VG_(debugLog
)(0, "libcbase", " at %s:%d (%s)\n", file
, line
, fn
);
55 VG_(debugLog
)(0, "libcbase", "Exiting now.\n");
60 /* ---------------------------------------------------------------------
62 ------------------------------------------------------------------ */
64 Bool
VG_(isspace
) ( HChar c
)
66 return (c
== ' ' || c
== '\n' || c
== '\t' ||
67 c
== '\f' || c
== '\v' || c
== '\r');
70 Bool
VG_(isdigit
) ( HChar c
)
72 return (c
>= '0' && c
<= '9');
75 /* ---------------------------------------------------------------------
76 Converting strings to numbers
77 ------------------------------------------------------------------ */
79 static Bool
is_dec_digit(HChar c
, Long
* digit
)
81 if (c
>= '0' && c
<= '9') { *digit
= (Long
)(c
- '0'); return True
; }
85 static Bool
is_hex_digit(HChar c
, Long
* digit
)
87 if (c
>= '0' && c
<= '9') { *digit
= (Long
)(c
- '0'); return True
; }
88 if (c
>= 'A' && c
<= 'F') { *digit
= (Long
)((c
- 'A') + 10); return True
; }
89 if (c
>= 'a' && c
<= 'f') { *digit
= (Long
)((c
- 'a') + 10); return True
; }
93 Long
VG_(strtoll10
) ( const HChar
* str
, HChar
** endptr
)
95 Bool neg
= False
, converted
= False
;
96 Long n
= 0, digit
= 0;
97 const HChar
* str0
= str
;
99 // Skip leading whitespace.
100 while (VG_(isspace
)(*str
)) str
++;
102 // Allow a leading '-' or '+'.
103 if (*str
== '-') { str
++; neg
= True
; }
104 else if (*str
== '+') { str
++; }
106 while (is_dec_digit(*str
, &digit
)) {
107 converted
= True
; // Ok, we've actually converted a digit.
112 if (!converted
) str
= str0
; // If nothing converted, endptr points to
113 if (neg
) n
= -n
; // the start of the string.
115 *endptr
= CONST_CAST(HChar
*,str
); // Record first failing character.
119 ULong
VG_(strtoull10
) ( const HChar
* str
, HChar
** endptr
)
121 Bool converted
= False
;
124 const HChar
* str0
= str
;
126 // Skip leading whitespace.
127 while (VG_(isspace
)(*str
)) str
++;
129 // Allow a leading '+'.
130 if (*str
== '+') { str
++; }
132 while (is_dec_digit(*str
, &digit
)) {
133 converted
= True
; // Ok, we've actually converted a digit.
138 if (!converted
) str
= str0
; // If nothing converted, endptr points to
139 // the start of the string.
141 *endptr
= CONST_CAST(HChar
*,str
); // Record first failing character.
145 Long
VG_(strtoll16
) ( const HChar
* str
, HChar
** endptr
)
147 Bool neg
= False
, converted
= False
;
148 Long n
= 0, digit
= 0;
149 const HChar
* str0
= str
;
151 // Skip leading whitespace.
152 while (VG_(isspace
)(*str
)) str
++;
154 // Allow a leading '-' or '+'.
155 if (*str
== '-') { str
++; neg
= True
; }
156 else if (*str
== '+') { str
++; }
158 // Allow leading "0x", but only if there's a hex digit
161 && (*(str
+1) == 'x' || *(str
+1) == 'X')
162 && is_hex_digit( *(str
+2), &digit
)) {
166 while (is_hex_digit(*str
, &digit
)) {
167 converted
= True
; // Ok, we've actually converted a digit.
172 if (!converted
) str
= str0
; // If nothing converted, endptr points to
173 if (neg
) n
= -n
; // the start of the string.
175 *endptr
= CONST_CAST(HChar
*,str
); // Record first failing character.
179 ULong
VG_(strtoull16
) ( const HChar
* str
, HChar
** endptr
)
181 Bool converted
= False
;
184 const HChar
* str0
= str
;
186 // Skip leading whitespace.
187 while (VG_(isspace
)(*str
)) str
++;
189 // Allow a leading '+'.
190 if (*str
== '+') { str
++; }
192 // Allow leading "0x", but only if there's a hex digit
195 && (*(str
+1) == 'x' || *(str
+1) == 'X')
196 && is_hex_digit( *(str
+2), &digit
)) {
200 while (is_hex_digit(*str
, &digit
)) {
201 converted
= True
; // Ok, we've actually converted a digit.
206 if (!converted
) str
= str0
; // If nothing converted, endptr points to
207 // the start of the string.
209 *endptr
= CONST_CAST(HChar
*,str
); // Record first failing character.
213 double VG_(strtod
) ( const HChar
* str
, HChar
** endptr
)
217 double n
= 0, frac
= 0, x
= 0.1;
219 // Skip leading whitespace.
220 while (VG_(isspace
)(*str
)) str
++;
222 // Allow a leading '-' or '+'.
223 if (*str
== '-') { str
++; neg
= True
; }
224 else if (*str
== '+') { str
++; }
226 while (is_dec_digit(*str
, &digit
)) {
233 while (is_dec_digit(*str
, &digit
)) {
243 *endptr
= CONST_CAST(HChar
*,str
); // Record first failing character.
247 HChar
VG_(tolower
) ( HChar c
)
249 if ( c
>= 'A' && c
<= 'Z' ) {
250 return c
- 'A' + 'a';
256 /* ---------------------------------------------------------------------
258 ------------------------------------------------------------------ */
260 SizeT
VG_(strlen
) ( const HChar
* str
)
263 while (str
[i
] != 0) i
++;
267 SizeT
VG_(strnlen
)(const HChar
* str
, SizeT n
)
270 while (i
< n
&& str
[i
] != 0)
275 HChar
* VG_(strcat
) ( HChar
* dest
, const HChar
* src
)
277 HChar
* dest_orig
= dest
;
278 while (*dest
) dest
++;
279 while (*src
) *dest
++ = *src
++;
284 HChar
* VG_(strncat
) ( HChar
* dest
, const HChar
* src
, SizeT n
)
286 HChar
* dest_orig
= dest
;
287 while (*dest
) dest
++;
288 while (*src
&& n
> 0) { *dest
++ = *src
++; n
--; }
293 HChar
* VG_(strpbrk
) ( const HChar
* s
, const HChar
* accpt
)
300 return CONST_CAST(HChar
*,s
);
306 HChar
* VG_(strcpy
) ( HChar
* dest
, const HChar
* src
)
308 HChar
* dest_orig
= dest
;
309 while (*src
) *dest
++ = *src
++;
314 HChar
* VG_(strncpy
) ( HChar
* dest
, const HChar
* src
, SizeT ndest
)
318 if (i
>= ndest
) return dest
; /* reached limit */
321 /* reached NUL; pad rest with zeroes as required */
322 while (i
< ndest
) dest
[i
++] = 0;
328 /* Copies up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
329 Returns strlen(src). Does not zero-fill the remainder of dst. */
330 SizeT
VG_(strlcpy
)(HChar
*dst
, const HChar
*src
, SizeT n
)
332 const HChar
*src_orig
= src
;
335 while (m
< n
- 1 && *src
!= '\0') {
340 /* Nul-terminate dst. */ \
344 /* Finish counting strlen(src). */ \
348 return src
- src_orig
;
351 Int
VG_(strcmp
) ( const HChar
* s1
, const HChar
* s2
)
354 if (*(const UChar
*)s1
< *(const UChar
*)s2
) return -1;
355 if (*(const UChar
*)s1
> *(const UChar
*)s2
) return 1;
358 if (*s1
== 0) return 0;
364 Int
VG_(strcasecmp
) ( const HChar
* s1
, const HChar
* s2
)
367 UChar c1
= (UChar
)VG_(tolower
)(*s1
);
368 UChar c2
= (UChar
)VG_(tolower
)(*s2
);
369 if (c1
< c2
) return -1;
370 if (c1
> c2
) return 1;
373 if (c1
== 0) return 0;
379 Int
VG_(strncmp
) ( const HChar
* s1
, const HChar
* s2
, SizeT nmax
)
383 if (n
>= nmax
) return 0;
384 if (*(const UChar
*)s1
< *(const UChar
*)s2
) return -1;
385 if (*(const UChar
*)s1
> *(const UChar
*)s2
) return 1;
388 if (*s1
== 0) return 0;
394 Int
VG_(strncasecmp
) ( const HChar
* s1
, const HChar
* s2
, SizeT nmax
)
400 if (n
>= nmax
) return 0;
401 c1
= (UChar
)VG_(tolower
)(*s1
);
402 c2
= (UChar
)VG_(tolower
)(*s2
);
403 if (c1
< c2
) return -1;
404 if (c1
> c2
) return 1;
407 if (c1
== 0) return 0;
413 HChar
* VG_(strstr
) ( const HChar
* haystack
, const HChar
* needle
)
416 if (haystack
== NULL
)
418 n
= VG_(strlen
)(needle
);
420 if (haystack
[0] == 0)
422 if (VG_(strncmp
)(haystack
, needle
, n
) == 0)
423 return CONST_CAST(HChar
*,haystack
);
428 HChar
* VG_(strcasestr
) ( const HChar
* haystack
, const HChar
* needle
)
431 if (haystack
== NULL
)
433 n
= VG_(strlen
)(needle
);
435 if (haystack
[0] == 0)
437 if (VG_(strncasecmp
)(haystack
, needle
, n
) == 0)
438 return CONST_CAST(HChar
*,haystack
);
443 HChar
* VG_(strchr
) ( const HChar
* s
, HChar c
)
446 if (*s
== c
) return CONST_CAST(HChar
*,s
);
447 if (*s
== 0) return NULL
;
452 HChar
* VG_(strrchr
) ( const HChar
* s
, HChar c
)
454 Int n
= VG_(strlen
)(s
);
456 if (s
[n
] == c
) return CONST_CAST(HChar
*,s
) + n
;
461 /* (code copied from glib then updated to valgrind types) */
464 VG_(strtok
) (HChar
*s
, const HChar
*delim
)
466 return VG_(strtok_r
) (s
, delim
, &olds
);
470 VG_(strtok_r
) (HChar
* s
, const HChar
* delim
, HChar
** saveptr
)
477 /* Scan leading delimiters. */
478 s
+= VG_(strspn
) (s
, delim
);
485 /* Find the end of the token. */
487 s
= VG_(strpbrk
) (token
, delim
);
489 /* This token finishes the string. */
490 *saveptr
= token
+ VG_(strlen
) (token
);
493 /* Terminate the token and make OLDS point past it. */
500 static Bool
isHex ( HChar c
)
502 return ((c
>= '0' && c
<= '9') ||
503 (c
>= 'a' && c
<= 'f') ||
504 (c
>= 'A' && c
<= 'F'));
507 static UInt
fromHex ( HChar c
)
509 if (c
>= '0' && c
<= '9')
510 return (UInt
)c
- (UInt
)'0';
511 if (c
>= 'a' && c
<= 'f')
512 return 10 + (UInt
)c
- (UInt
)'a';
513 if (c
>= 'A' && c
<= 'F')
514 return 10 + (UInt
)c
- (UInt
)'A';
516 // ??? need to vg_assert(0);
520 Bool
VG_(parse_Addr
) ( const HChar
** ppc
, Addr
* result
)
522 Int used
, limit
= 2 * sizeof(Addr
);
531 while (isHex(**ppc
)) {
532 // ??? need to vg_assert(d < fromHex(**ppc));
533 *result
= ((*result
) << 4) | fromHex(**ppc
);
536 if (used
> limit
) return False
;
543 Bool
VG_(parse_UInt
) ( const HChar
** ppc
, UInt
* result
)
546 Int used
, limit
= 10;
548 while (VG_(isdigit
)(**ppc
)) {
549 res64
= res64
* 10 + ((ULong
)(**ppc
)) - (ULong
)'0';
552 if (used
> limit
) return False
;
556 if ((res64
>> 32) != 0)
558 *result
= (UInt
)res64
;
562 Bool
VG_(parse_enum_set
) ( const HChar
*tokens
,
567 const SizeT tokens_len
= VG_(strlen
)(tokens
);
568 if (tokens_len
> 1000) return False
; /* "obviously invalid" */
569 HChar tok_tokens
[tokens_len
+1];
570 HChar
*tokens_saveptr
;
575 const SizeT input_len
= VG_(strlen
)(input
);
576 if (input_len
> 1000) return False
; /* "obviously invalid" */
577 HChar tok_input
[input_len
+1];
578 HChar
*input_saveptr
;
581 UInt known_words
= 0;
582 Bool seen_all_kw
= False
;
583 Bool seen_none_kw
= False
;
587 VG_(strcpy
) (tok_input
, input
);
588 for (input_word
= VG_(strtok_r
)(tok_input
, ",", &input_saveptr
);
590 input_word
= VG_(strtok_r
)(NULL
, ",", &input_saveptr
)) {
592 if (allow_all
&& 0 == VG_(strcmp
)(input_word
, "all")) {
595 } else if (0 == VG_(strcmp
)(input_word
, "none")) {
600 // Scan tokens + compute all_set. Do that even if all or none was
601 // recognised to have a correct value for all_set when exiting
602 // of the 'input' loop.
605 VG_(strcpy
) (tok_tokens
, tokens
);
606 for (token
= VG_(strtok_r
)(tok_tokens
, ",", &tokens_saveptr
);
608 token
= VG_(strtok_r
)(NULL
, ",", &tokens_saveptr
)) {
609 if (0 != VG_(strcmp
)(token
, "-")) {
610 if (0 == VG_(strcmp
)(input_word
, token
)) {
611 *enum_set
|= 1 << token_nr
;
614 all_set
|= 1 << token_nr
;
620 if (known_words
!= word_nr
)
621 return False
; // One or more input_words not recognised.
623 if (seen_none_kw
|| *enum_set
)
624 return False
; // mixing all with either none or a specific value.
626 } else if (seen_none_kw
) {
627 if (seen_all_kw
|| *enum_set
)
628 return False
; // mixing none with either all or a specific value.
631 // seen neither all or none, we must see at least one value
639 SizeT
VG_(strspn
) ( const HChar
* s
, const HChar
* accpt
)
643 for (p
= s
; *p
!= '\0'; ++p
) {
644 for (a
= accpt
; *a
!= '\0'; ++a
)
655 SizeT
VG_(strcspn
) ( const HChar
* s
, const HChar
* reject
)
659 if (VG_(strchr
) (reject
, *s
++) == NULL
)
668 /* ---------------------------------------------------------------------
670 ------------------------------------------------------------------ */
672 void* VG_(memcpy
) ( void *dest
, const void *src
, SizeT sz
)
674 const UChar
* s
= (const UChar
*)src
;
675 UChar
* d
= (UChar
*)dest
;
676 const UInt
* sI
= (const UInt
*)src
;
677 UInt
* dI
= (UInt
*)dest
;
679 if (VG_IS_4_ALIGNED(dI
) && VG_IS_4_ALIGNED(sI
)) {
699 s
= (const UChar
*)sI
;
703 /* If we're unlucky, the alignment constraints for the fast case
704 above won't apply, and we'll have to do it all here. Hence the
725 void* VG_(memmove
)(void *dest
, const void *src
, SizeT sz
)
731 for (i
= 0; i
< sz
; i
++) {
732 ((UChar
*)dest
)[i
] = ((const UChar
*)src
)[i
];
735 else if (dest
> src
) {
736 for (i
= 0; i
< sz
; i
++) {
737 ((UChar
*)dest
)[sz
-i
-1] = ((const UChar
*)src
)[sz
-i
-1];
743 void* VG_(memset
) ( void *destV
, Int c
, SizeT sz
)
749 while ((!VG_IS_4_ALIGNED(d
)) && sz
>= 1) {
754 UInt
* d4
= ASSUME_ALIGNED(UInt
*, d
);
782 Int
VG_(memcmp
) ( const void* s1
, const void* s2
, SizeT n
)
785 const UChar
*p1
= s1
;
786 const UChar
*p2
= s2
;
803 /* ---------------------------------------------------------------------
804 Misc useful functions
805 ------------------------------------------------------------------ */
807 /////////////////////////////////////////////////////////////
808 /////////////////////////////////////////////////////////////
809 /// begin Bentley-McIlroy style quicksort
810 /// See "Engineering a Sort Function". Jon L Bentley, M. Douglas
811 /// McIlroy. Software Practice and Experience Vol 23(11), Nov 1993.
813 #define BM_MIN(a, b) \
816 #define BM_SWAPINIT(a, es) \
817 swaptype = ((a-(Char*)0) | es) % sizeof(Word) ? 2 \
818 : es > (SizeT)sizeof(Word) ? 1 \
821 #define BM_EXCH(a, b, t) \
822 (t = a, a = b, b = t)
824 #define BM_SWAP(a, b) \
826 ? bm_swapfunc(a, b, es, swaptype) \
827 : (void)BM_EXCH(*ASSUME_ALIGNED(Word*, (a)), \
828 *ASSUME_ALIGNED(Word*, (b)), t)
830 #define BM_VECSWAP(a, b, n) \
831 if (n > 0) bm_swapfunc(a, b, n, swaptype)
833 #define BM_PVINIT(pv, pm) \
835 pv = a, BM_SWAP(pv, pm); \
837 pv = (Char*)&v, v = *ASSUME_ALIGNED(Word*, pm)
839 static Char
* bm_med3 ( Char
* a
, Char
* b
, Char
* c
,
840 Int (*cmp
)(const void*, const void*) ) {
842 ? (cmp(b
, c
) < 0 ? b
: cmp(a
, c
) < 0 ? c
: a
)
843 : (cmp(b
, c
) > 0 ? b
: cmp(a
, c
) > 0 ? c
: a
);
846 static void bm_swapfunc ( Char
* a
, Char
* b
, SizeT n
, Int swaptype
)
850 for ( ; n
> 0; a
+= sizeof(Word
), b
+= sizeof(Word
),
852 BM_EXCH(*ASSUME_ALIGNED(Word
*, a
), *ASSUME_ALIGNED(Word
*, b
), t
);
855 for ( ; n
> 0; a
+= 1, b
+= 1, n
-= 1)
860 static void bm_qsort ( Char
* a
, SizeT n
, SizeT es
,
861 Int (*cmp
)(const void*, const void*) )
863 Char
*pa
, *pb
, *pc
, *pd
, *pl
, *pm
, *pn
, *pv
;
870 for (pm
= a
+ es
; pm
< a
+ n
*es
; pm
+= es
)
871 for (pl
= pm
; pl
> a
&& cmp(pl
-es
, pl
) > 0; pl
-= es
)
881 pl
= bm_med3(pl
, pl
+s
, pl
+2*s
, cmp
);
882 pm
= bm_med3(pm
-s
, pm
, pm
+s
, cmp
);
883 pn
= bm_med3(pn
-2*s
, pn
-s
, pn
, cmp
);
885 pm
= bm_med3(pl
, pm
, pn
, cmp
);
889 pc
= pd
= a
+ (n
-1)*es
;
891 while (pb
<= pc
&& (r
= cmp(pb
, pv
)) <= 0) {
892 if (r
== 0) { BM_SWAP(pa
, pb
); pa
+= es
; }
895 while (pc
>= pb
&& (r
= cmp(pc
, pv
)) >= 0) {
896 if (r
== 0) { BM_SWAP(pc
, pd
); pd
-= es
; }
905 s
= BM_MIN(pa
-a
, pb
-pa
); BM_VECSWAP(a
, pb
-s
, s
);
906 s
= BM_MIN(pd
-pc
, pn
-pd
-es
); BM_VECSWAP(pb
, pn
-s
, s
);
907 /* Now recurse. Do the smaller partition first with an explicit
908 recursion, then do the larger partition using a tail call.
909 Except we can't rely on gcc to implement a tail call in any sane
910 way, so simply jump back to the start. This guarantees stack
911 growth can never exceed O(log N) even in the worst case. */
916 bm_qsort(a
, s1
/es
, es
, cmp
);
919 /* bm_qsort(pn-s2, s2/es, es, cmp); */
920 a
= pn
-s2
; n
= s2
/es
; es
= es
; cmp
= cmp
;
925 bm_qsort(pn
-s2
, s2
/es
, es
, cmp
);
928 /* bm_qsort(a, s1/es, es, cmp); */
929 a
= a
; n
= s1
/es
; es
= es
; cmp
= cmp
;
942 /// end Bentley-McIlroy style quicksort
943 /////////////////////////////////////////////////////////////
944 /////////////////////////////////////////////////////////////
946 /* Returns the base-2 logarithm of x. Returns -1 if x is not a power
948 Int
VG_(log2
) ( UInt x
)
951 /* Any more than 32 and we overflow anyway... */
952 for (i
= 0; i
< 32; i
++) {
953 if ((1U << i
) == x
) return i
;
958 /* Ditto for 64 bit numbers. */
959 Int
VG_(log2_64
) ( ULong x
)
962 for (i
= 0; i
< 64; i
++) {
963 if ((1ULL << i
) == x
) return i
;
968 // Generic quick sort.
969 void VG_(ssort
)( void* base
, SizeT nmemb
, SizeT size
,
970 Int (*compar
)(const void*, const void*) )
972 bm_qsort(base
,nmemb
,size
,compar
);
976 // This random number generator is based on the one suggested in Kernighan
977 // and Ritchie's "The C Programming Language".
979 // A pseudo-random number generator returning a random UInt. If pSeed
980 // is NULL, it uses its own seed, which starts at zero. If pSeed is
981 // non-NULL, it uses and updates whatever pSeed points at.
983 UInt
VG_(random
)( /*MOD*/UInt
* pSeed
)
985 static UInt seed
= 0;
990 *pSeed
= (1103515245 * *pSeed
+ 12345);
995 /* The following Adler-32 checksum code is taken from zlib-1.2.3, which
996 has the following copyright notice. */
1000 (C) 1995-2004 Jean-loup Gailly and Mark Adler
1002 This software is provided 'as-is', without any express or implied
1003 warranty. In no event will the authors be held liable for any damages
1004 arising from the use of this software.
1006 Permission is granted to anyone to use this software for any purpose,
1007 including commercial applications, and to alter it and redistribute it
1008 freely, subject to the following restrictions:
1010 1. The origin of this software must not be misrepresented; you must not
1011 claim that you wrote the original software. If you use this software
1012 in a product, an acknowledgment in the product documentation would be
1013 appreciated but is not required.
1014 2. Altered source versions must be plainly marked as such, and must not be
1015 misrepresented as being the original software.
1016 3. This notice may not be removed or altered from any source distribution.
1018 Jean-loup Gailly Mark Adler
1019 jloup@gzip.org madler@alumni.caltech.edu
1021 If you use the zlib library in a product, we would appreciate *not*
1022 receiving lengthy legal documents to sign. The sources are provided
1023 for free but without warranty of any kind. The library has been
1024 entirely written by Jean-loup Gailly and Mark Adler; it does not
1025 include third-party code.
1027 If you redistribute modified sources, we would appreciate that you include
1028 in the file ChangeLog history information documenting your changes. Please
1029 read the FAQ for more information on the distribution of modified source
1033 /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and
1034 return the updated checksum. If buf is NULL, this function returns
1035 the required initial value for the checksum. An Adler-32 checksum is
1036 almost as reliable as a CRC32 but can be computed much faster. */
1037 UInt
VG_(adler32
)( UInt adler
, const UChar
* buf
, UInt len
)
1039 # define BASE 65521UL /* largest prime smaller than 65536 */
1041 /* NMAX is the largest n such that
1042 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
1044 # define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
1045 # define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
1046 # define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
1047 # define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
1048 # define DO16(buf) DO8(buf,0); DO8(buf,8);
1050 /* The zlib sources recommend this definition of MOD if the
1051 processor cannot do integer division in hardware. */
1054 if (a >= (BASE << 16)) a -= (BASE << 16); \
1055 if (a >= (BASE << 15)) a -= (BASE << 15); \
1056 if (a >= (BASE << 14)) a -= (BASE << 14); \
1057 if (a >= (BASE << 13)) a -= (BASE << 13); \
1058 if (a >= (BASE << 12)) a -= (BASE << 12); \
1059 if (a >= (BASE << 11)) a -= (BASE << 11); \
1060 if (a >= (BASE << 10)) a -= (BASE << 10); \
1061 if (a >= (BASE << 9)) a -= (BASE << 9); \
1062 if (a >= (BASE << 8)) a -= (BASE << 8); \
1063 if (a >= (BASE << 7)) a -= (BASE << 7); \
1064 if (a >= (BASE << 6)) a -= (BASE << 6); \
1065 if (a >= (BASE << 5)) a -= (BASE << 5); \
1066 if (a >= (BASE << 4)) a -= (BASE << 4); \
1067 if (a >= (BASE << 3)) a -= (BASE << 3); \
1068 if (a >= (BASE << 2)) a -= (BASE << 2); \
1069 if (a >= (BASE << 1)) a -= (BASE << 1); \
1070 if (a >= BASE) a -= BASE; \
1074 if (a >= (BASE << 4)) a -= (BASE << 4); \
1075 if (a >= (BASE << 3)) a -= (BASE << 3); \
1076 if (a >= (BASE << 2)) a -= (BASE << 2); \
1077 if (a >= (BASE << 1)) a -= (BASE << 1); \
1078 if (a >= BASE) a -= BASE; \
1084 /* split Adler-32 into component sums */
1085 sum2
= (adler
>> 16) & 0xffff;
1088 /* in case user likes doing a byte at a time, keep it fast */
1096 return adler
| (sum2
<< 16);
1099 /* initial Adler-32 value (deferred check for len == 1 speed) */
1103 /* in case short lengths are provided, keep it somewhat fast */
1111 MOD4(sum2
); /* only added so many BASE's */
1112 return adler
| (sum2
<< 16);
1115 /* do length NMAX blocks -- requires just one modulo operation */
1116 while (len
>= NMAX
) {
1118 n
= NMAX
/ 16; /* NMAX is divisible by 16 */
1120 DO16(buf
); /* 16 sums unrolled */
1127 /* do remaining bytes (less than NMAX, still just one modulo) */
1128 if (len
) { /* avoid modulos if none remaining */
1142 /* return recombined sums */
1143 return adler
| (sum2
<< 16);
1156 /*--------------------------------------------------------------------*/
1158 /*--------------------------------------------------------------------*/