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, 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_libcassert.h" // VG_(exit_now)
33 #include "pub_core_debuglog.h" // VG_(debugLog)
34 #include "pub_core_libcbase.h"
37 /* ---------------------------------------------------------------------
38 Assert machinery for use in this file. vg_assert cannot be called
39 here due to cyclic dependencies.
40 ------------------------------------------------------------------ */
42 #define libcbase_assert(expr) \
43 ((void) (LIKELY(expr) ? 0 : \
44 (ML_(libcbase_assert_fail)(#expr, \
46 __PRETTY_FUNCTION__))))
48 static void ML_(libcbase_assert_fail
)( const HChar
*expr
,
53 VG_(debugLog
)(0, "libcbase",
54 "Valgrind: FATAL: assertion failed:\n");
55 VG_(debugLog
)(0, "libcbase", " %s\n", expr
);
56 VG_(debugLog
)(0, "libcbase", " at %s:%d (%s)\n", file
, line
, fn
);
57 VG_(debugLog
)(0, "libcbase", "Exiting now.\n");
62 /* ---------------------------------------------------------------------
64 ------------------------------------------------------------------ */
66 Bool
VG_(isspace
) ( HChar c
)
68 return (c
== ' ' || c
== '\n' || c
== '\t' ||
69 c
== '\f' || c
== '\v' || c
== '\r');
72 Bool
VG_(isdigit
) ( HChar c
)
74 return (c
>= '0' && c
<= '9');
77 /* ---------------------------------------------------------------------
78 Converting strings to numbers
79 ------------------------------------------------------------------ */
81 static Bool
is_dec_digit(HChar c
, Long
* digit
)
83 if (c
>= '0' && c
<= '9') { *digit
= (Long
)(c
- '0'); return True
; }
87 static Bool
is_hex_digit(HChar c
, Long
* digit
)
89 if (c
>= '0' && c
<= '9') { *digit
= (Long
)(c
- '0'); return True
; }
90 if (c
>= 'A' && c
<= 'F') { *digit
= (Long
)((c
- 'A') + 10); return True
; }
91 if (c
>= 'a' && c
<= 'f') { *digit
= (Long
)((c
- 'a') + 10); return True
; }
95 Long
VG_(strtoll10
) ( const HChar
* str
, HChar
** endptr
)
97 Bool neg
= False
, converted
= False
;
98 Long n
= 0, digit
= 0;
99 const HChar
* str0
= str
;
101 // Skip leading whitespace.
102 while (VG_(isspace
)(*str
)) str
++;
104 // Allow a leading '-' or '+'.
105 if (*str
== '-') { str
++; neg
= True
; }
106 else if (*str
== '+') { str
++; }
108 while (is_dec_digit(*str
, &digit
)) {
109 converted
= True
; // Ok, we've actually converted a digit.
114 if (!converted
) str
= str0
; // If nothing converted, endptr points to
115 if (neg
) n
= -n
; // the start of the string.
117 *endptr
= CONST_CAST(HChar
*,str
); // Record first failing character.
121 ULong
VG_(strtoull10
) ( const HChar
* str
, HChar
** endptr
)
123 Bool converted
= False
;
126 const HChar
* str0
= str
;
128 // Skip leading whitespace.
129 while (VG_(isspace
)(*str
)) str
++;
131 // Allow a leading '+'.
132 if (*str
== '+') { str
++; }
134 while (is_dec_digit(*str
, &digit
)) {
135 converted
= True
; // Ok, we've actually converted a digit.
140 if (!converted
) str
= str0
; // If nothing converted, endptr points to
141 // the start of the string.
143 *endptr
= CONST_CAST(HChar
*,str
); // Record first failing character.
147 Long
VG_(strtoll16
) ( const HChar
* str
, HChar
** endptr
)
149 Bool neg
= False
, converted
= False
;
150 Long n
= 0, digit
= 0;
151 const HChar
* str0
= str
;
153 // Skip leading whitespace.
154 while (VG_(isspace
)(*str
)) str
++;
156 // Allow a leading '-' or '+'.
157 if (*str
== '-') { str
++; neg
= True
; }
158 else if (*str
== '+') { str
++; }
160 // Allow leading "0x", but only if there's a hex digit
163 && (*(str
+1) == 'x' || *(str
+1) == 'X')
164 && is_hex_digit( *(str
+2), &digit
)) {
168 while (is_hex_digit(*str
, &digit
)) {
169 converted
= True
; // Ok, we've actually converted a digit.
174 if (!converted
) str
= str0
; // If nothing converted, endptr points to
175 if (neg
) n
= -n
; // the start of the string.
177 *endptr
= CONST_CAST(HChar
*,str
); // Record first failing character.
181 ULong
VG_(strtoull16
) ( const HChar
* str
, HChar
** endptr
)
183 Bool converted
= False
;
186 const HChar
* str0
= str
;
188 // Skip leading whitespace.
189 while (VG_(isspace
)(*str
)) str
++;
191 // Allow a leading '+'.
192 if (*str
== '+') { str
++; }
194 // Allow leading "0x", but only if there's a hex digit
197 && (*(str
+1) == 'x' || *(str
+1) == 'X')
198 && is_hex_digit( *(str
+2), &digit
)) {
202 while (is_hex_digit(*str
, &digit
)) {
203 converted
= True
; // Ok, we've actually converted a digit.
208 if (!converted
) str
= str0
; // If nothing converted, endptr points to
209 // the start of the string.
211 *endptr
= CONST_CAST(HChar
*,str
); // Record first failing character.
215 double VG_(strtod
) ( const HChar
* str
, HChar
** endptr
)
219 double n
= 0, frac
= 0, x
= 0.1;
221 // Skip leading whitespace.
222 while (VG_(isspace
)(*str
)) str
++;
224 // Allow a leading '-' or '+'.
225 if (*str
== '-') { str
++; neg
= True
; }
226 else if (*str
== '+') { str
++; }
228 while (is_dec_digit(*str
, &digit
)) {
235 while (is_dec_digit(*str
, &digit
)) {
245 *endptr
= CONST_CAST(HChar
*,str
); // Record first failing character.
249 HChar
VG_(tolower
) ( HChar c
)
251 if ( c
>= 'A' && c
<= 'Z' ) {
252 return c
- 'A' + 'a';
258 /* ---------------------------------------------------------------------
260 ------------------------------------------------------------------ */
262 SizeT
VG_(strlen
) ( const HChar
* str
)
265 while (str
[i
] != 0) i
++;
269 SizeT
VG_(strnlen
)(const HChar
* str
, SizeT n
)
272 while (i
< n
&& str
[i
] != 0)
277 HChar
* VG_(strcat
) ( HChar
* dest
, const HChar
* src
)
279 HChar
* dest_orig
= dest
;
280 while (*dest
) dest
++;
281 while (*src
) *dest
++ = *src
++;
286 HChar
* VG_(strncat
) ( HChar
* dest
, const HChar
* src
, SizeT n
)
288 HChar
* dest_orig
= dest
;
289 while (*dest
) dest
++;
290 while (*src
&& n
> 0) { *dest
++ = *src
++; n
--; }
295 HChar
* VG_(strpbrk
) ( const HChar
* s
, const HChar
* accpt
)
302 return CONST_CAST(HChar
*,s
);
308 HChar
* VG_(strcpy
) ( HChar
* dest
, const HChar
* src
)
310 HChar
* dest_orig
= dest
;
311 while (*src
) *dest
++ = *src
++;
316 HChar
* VG_(strncpy
) ( HChar
* dest
, const HChar
* src
, SizeT ndest
)
320 if (i
>= ndest
) return dest
; /* reached limit */
323 /* reached NUL; pad rest with zeroes as required */
324 while (i
< ndest
) dest
[i
++] = 0;
330 /* Copies up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
331 Returns strlen(src). Does not zero-fill the remainder of dst. */
332 SizeT
VG_(strlcpy
)(HChar
*dst
, const HChar
*src
, SizeT n
)
334 const HChar
*src_orig
= src
;
337 while (m
< n
- 1 && *src
!= '\0') {
342 /* Nul-terminate dst. */ \
346 /* Finish counting strlen(src). */ \
350 return src
- src_orig
;
353 Int
VG_(strcmp
) ( const HChar
* s1
, const HChar
* s2
)
356 if (*(const UChar
*)s1
< *(const UChar
*)s2
) return -1;
357 if (*(const UChar
*)s1
> *(const UChar
*)s2
) return 1;
360 if (*s1
== 0) return 0;
366 Int
VG_(strcasecmp
) ( const HChar
* s1
, const HChar
* s2
)
369 UChar c1
= (UChar
)VG_(tolower
)(*s1
);
370 UChar c2
= (UChar
)VG_(tolower
)(*s2
);
371 if (c1
< c2
) return -1;
372 if (c1
> c2
) return 1;
375 if (c1
== 0) return 0;
381 Int
VG_(strncmp
) ( const HChar
* s1
, const HChar
* s2
, SizeT nmax
)
385 if (n
>= nmax
) return 0;
386 if (*(const UChar
*)s1
< *(const UChar
*)s2
) return -1;
387 if (*(const UChar
*)s1
> *(const UChar
*)s2
) return 1;
390 if (*s1
== 0) return 0;
396 Int
VG_(strncasecmp
) ( const HChar
* s1
, const HChar
* s2
, SizeT nmax
)
402 if (n
>= nmax
) return 0;
403 c1
= (UChar
)VG_(tolower
)(*s1
);
404 c2
= (UChar
)VG_(tolower
)(*s2
);
405 if (c1
< c2
) return -1;
406 if (c1
> c2
) return 1;
409 if (c1
== 0) return 0;
415 HChar
* VG_(strstr
) ( const HChar
* haystack
, const HChar
* needle
)
418 if (haystack
== NULL
)
420 n
= VG_(strlen
)(needle
);
422 if (haystack
[0] == 0)
424 if (VG_(strncmp
)(haystack
, needle
, n
) == 0)
425 return CONST_CAST(HChar
*,haystack
);
430 HChar
* VG_(strcasestr
) ( const HChar
* haystack
, const HChar
* needle
)
433 if (haystack
== NULL
)
435 n
= VG_(strlen
)(needle
);
437 if (haystack
[0] == 0)
439 if (VG_(strncasecmp
)(haystack
, needle
, n
) == 0)
440 return CONST_CAST(HChar
*,haystack
);
445 HChar
* VG_(strchr
) ( const HChar
* s
, HChar c
)
448 if (*s
== c
) return CONST_CAST(HChar
*,s
);
449 if (*s
== 0) return NULL
;
454 HChar
* VG_(strrchr
) ( const HChar
* s
, HChar c
)
456 Int n
= VG_(strlen
)(s
);
458 if (s
[n
] == c
) return CONST_CAST(HChar
*,s
) + n
;
463 /* (code copied from glib then updated to valgrind types) */
466 VG_(strtok
) (HChar
*s
, const HChar
*delim
)
468 return VG_(strtok_r
) (s
, delim
, &olds
);
472 VG_(strtok_r
) (HChar
* s
, const HChar
* delim
, HChar
** saveptr
)
479 /* Scan leading delimiters. */
480 s
+= VG_(strspn
) (s
, delim
);
487 /* Find the end of the token. */
489 s
= VG_(strpbrk
) (token
, delim
);
491 /* This token finishes the string. */
492 *saveptr
= token
+ VG_(strlen
) (token
);
495 /* Terminate the token and make OLDS point past it. */
502 static Bool
isHex ( HChar c
)
504 return ((c
>= '0' && c
<= '9') ||
505 (c
>= 'a' && c
<= 'f') ||
506 (c
>= 'A' && c
<= 'F'));
509 static UInt
fromHex ( HChar c
)
511 if (c
>= '0' && c
<= '9')
512 return (UInt
)c
- (UInt
)'0';
513 if (c
>= 'a' && c
<= 'f')
514 return 10 + (UInt
)c
- (UInt
)'a';
515 if (c
>= 'A' && c
<= 'F')
516 return 10 + (UInt
)c
- (UInt
)'A';
518 // ??? need to vg_assert(0);
522 Bool
VG_(parse_Addr
) ( const HChar
** ppc
, Addr
* result
)
524 Int used
, limit
= 2 * sizeof(Addr
);
533 while (isHex(**ppc
)) {
534 // ??? need to vg_assert(d < fromHex(**ppc));
535 *result
= ((*result
) << 4) | fromHex(**ppc
);
538 if (used
> limit
) return False
;
545 Bool
VG_(parse_UInt
) ( const HChar
** ppc
, UInt
* result
)
548 Int used
, limit
= 10;
550 while (VG_(isdigit
)(**ppc
)) {
551 res64
= res64
* 10 + ((ULong
)(**ppc
)) - (ULong
)'0';
554 if (used
> limit
) return False
;
558 if ((res64
>> 32) != 0)
560 *result
= (UInt
)res64
;
564 Bool
VG_(parse_enum_set
) ( const HChar
*tokens
,
569 const SizeT tokens_len
= VG_(strlen
)(tokens
);
570 if (tokens_len
> 1000) return False
; /* "obviously invalid" */
571 HChar tok_tokens
[tokens_len
+1];
572 HChar
*tokens_saveptr
;
577 const SizeT input_len
= VG_(strlen
)(input
);
578 if (input_len
> 1000) return False
; /* "obviously invalid" */
579 HChar tok_input
[input_len
+1];
580 HChar
*input_saveptr
;
583 UInt known_words
= 0;
584 Bool seen_all_kw
= False
;
585 Bool seen_none_kw
= False
;
589 VG_(strcpy
) (tok_input
, input
);
590 for (input_word
= VG_(strtok_r
)(tok_input
, ",", &input_saveptr
);
592 input_word
= VG_(strtok_r
)(NULL
, ",", &input_saveptr
)) {
594 if (allow_all
&& 0 == VG_(strcmp
)(input_word
, "all")) {
597 } else if (0 == VG_(strcmp
)(input_word
, "none")) {
602 // Scan tokens + compute all_set. Do that even if all or none was
603 // recognised to have a correct value for all_set when exiting
604 // of the 'input' loop.
607 VG_(strcpy
) (tok_tokens
, tokens
);
608 for (token
= VG_(strtok_r
)(tok_tokens
, ",", &tokens_saveptr
);
610 token
= VG_(strtok_r
)(NULL
, ",", &tokens_saveptr
)) {
611 if (0 != VG_(strcmp
)(token
, "-")) {
612 if (0 == VG_(strcmp
)(input_word
, token
)) {
613 *enum_set
|= 1 << token_nr
;
616 all_set
|= 1 << token_nr
;
622 if (known_words
!= word_nr
)
623 return False
; // One or more input_words not recognised.
625 if (seen_none_kw
|| *enum_set
)
626 return False
; // mixing all with either none or a specific value.
628 } else if (seen_none_kw
) {
629 if (seen_all_kw
|| *enum_set
)
630 return False
; // mixing none with either all or a specific value.
633 // seen neither all or none, we must see at least one value
641 SizeT
VG_(strspn
) ( const HChar
* s
, const HChar
* accpt
)
645 for (p
= s
; *p
!= '\0'; ++p
) {
646 for (a
= accpt
; *a
!= '\0'; ++a
)
657 SizeT
VG_(strcspn
) ( const HChar
* s
, const HChar
* reject
)
661 if (VG_(strchr
) (reject
, *s
++) == NULL
)
670 /* ---------------------------------------------------------------------
672 ------------------------------------------------------------------ */
674 void* VG_(memcpy
) ( void *dest
, const void *src
, SizeT sz
)
676 const UChar
* s
= (const UChar
*)src
;
677 UChar
* d
= (UChar
*)dest
;
678 const UInt
* sI
= (const UInt
*)src
;
679 UInt
* dI
= (UInt
*)dest
;
681 if (VG_IS_4_ALIGNED(dI
) && VG_IS_4_ALIGNED(sI
)) {
701 s
= (const UChar
*)sI
;
705 /* If we're unlucky, the alignment constraints for the fast case
706 above won't apply, and we'll have to do it all here. Hence the
727 void* VG_(memmove
)(void *dest
, const void *src
, SizeT sz
)
733 for (i
= 0; i
< sz
; i
++) {
734 ((UChar
*)dest
)[i
] = ((const UChar
*)src
)[i
];
737 else if (dest
> src
) {
738 for (i
= 0; i
< sz
; i
++) {
739 ((UChar
*)dest
)[sz
-i
-1] = ((const UChar
*)src
)[sz
-i
-1];
745 void* VG_(memset
) ( void *destV
, Int c
, SizeT sz
)
751 while ((!VG_IS_4_ALIGNED(d
)) && sz
>= 1) {
756 UInt
* d4
= ASSUME_ALIGNED(UInt
*, d
);
784 Int
VG_(memcmp
) ( const void* s1
, const void* s2
, SizeT n
)
787 const UChar
*p1
= s1
;
788 const UChar
*p2
= s2
;
805 /* ---------------------------------------------------------------------
806 Misc useful functions
807 ------------------------------------------------------------------ */
809 /////////////////////////////////////////////////////////////
810 /////////////////////////////////////////////////////////////
811 /// begin Bentley-McIlroy style quicksort
812 /// See "Engineering a Sort Function". Jon L Bentley, M. Douglas
813 /// McIlroy. Software Practice and Experience Vol 23(11), Nov 1993.
815 #define BM_MIN(a, b) \
818 #define BM_SWAPINIT(a, es) \
819 swaptype = ((a-(Char*)0) | es) % sizeof(Word) ? 2 \
820 : es > (SizeT)sizeof(Word) ? 1 \
823 #define BM_EXCH(a, b, t) \
824 (t = a, a = b, b = t)
826 #define BM_SWAP(a, b) \
828 ? bm_swapfunc(a, b, es, swaptype) \
829 : (void)BM_EXCH(*ASSUME_ALIGNED(Word*, (a)), \
830 *ASSUME_ALIGNED(Word*, (b)), t)
832 #define BM_VECSWAP(a, b, n) \
833 if (n > 0) bm_swapfunc(a, b, n, swaptype)
835 #define BM_PVINIT(pv, pm) \
837 pv = a, BM_SWAP(pv, pm); \
839 pv = (Char*)&v, v = *ASSUME_ALIGNED(Word*, pm)
841 static Char
* bm_med3 ( Char
* a
, Char
* b
, Char
* c
,
842 Int (*cmp
)(const void*, const void*) ) {
844 ? (cmp(b
, c
) < 0 ? b
: cmp(a
, c
) < 0 ? c
: a
)
845 : (cmp(b
, c
) > 0 ? b
: cmp(a
, c
) > 0 ? c
: a
);
848 static void bm_swapfunc ( Char
* a
, Char
* b
, SizeT n
, Int swaptype
)
852 for ( ; n
> 0; a
+= sizeof(Word
), b
+= sizeof(Word
),
854 BM_EXCH(*ASSUME_ALIGNED(Word
*, a
), *ASSUME_ALIGNED(Word
*, b
), t
);
857 for ( ; n
> 0; a
+= 1, b
+= 1, n
-= 1)
862 static void bm_qsort ( Char
* a
, SizeT n
, SizeT es
,
863 Int (*cmp
)(const void*, const void*) )
865 Char
*pa
, *pb
, *pc
, *pd
, *pl
, *pm
, *pn
, *pv
;
872 for (pm
= a
+ es
; pm
< a
+ n
*es
; pm
+= es
)
873 for (pl
= pm
; pl
> a
&& cmp(pl
-es
, pl
) > 0; pl
-= es
)
883 pl
= bm_med3(pl
, pl
+s
, pl
+2*s
, cmp
);
884 pm
= bm_med3(pm
-s
, pm
, pm
+s
, cmp
);
885 pn
= bm_med3(pn
-2*s
, pn
-s
, pn
, cmp
);
887 pm
= bm_med3(pl
, pm
, pn
, cmp
);
891 pc
= pd
= a
+ (n
-1)*es
;
893 while (pb
<= pc
&& (r
= cmp(pb
, pv
)) <= 0) {
894 if (r
== 0) { BM_SWAP(pa
, pb
); pa
+= es
; }
897 while (pc
>= pb
&& (r
= cmp(pc
, pv
)) >= 0) {
898 if (r
== 0) { BM_SWAP(pc
, pd
); pd
-= es
; }
907 s
= BM_MIN(pa
-a
, pb
-pa
); BM_VECSWAP(a
, pb
-s
, s
);
908 s
= BM_MIN(pd
-pc
, pn
-pd
-es
); BM_VECSWAP(pb
, pn
-s
, s
);
909 /* Now recurse. Do the smaller partition first with an explicit
910 recursion, then do the larger partition using a tail call.
911 Except we can't rely on gcc to implement a tail call in any sane
912 way, so simply jump back to the start. This guarantees stack
913 growth can never exceed O(log N) even in the worst case. */
918 bm_qsort(a
, s1
/es
, es
, cmp
);
921 /* bm_qsort(pn-s2, s2/es, es, cmp); */
922 a
= pn
-s2
; n
= s2
/es
; es
= es
; cmp
= cmp
;
927 bm_qsort(pn
-s2
, s2
/es
, es
, cmp
);
930 /* bm_qsort(a, s1/es, es, cmp); */
931 a
= a
; n
= s1
/es
; es
= es
; cmp
= cmp
;
944 /// end Bentley-McIlroy style quicksort
945 /////////////////////////////////////////////////////////////
946 /////////////////////////////////////////////////////////////
948 /* Returns the base-2 logarithm of x. Returns -1 if x is not a power
950 Int
VG_(log2
) ( UInt x
)
953 /* Any more than 32 and we overflow anyway... */
954 for (i
= 0; i
< 32; i
++) {
955 if ((1U << i
) == x
) return i
;
960 /* Ditto for 64 bit numbers. */
961 Int
VG_(log2_64
) ( ULong x
)
964 for (i
= 0; i
< 64; i
++) {
965 if ((1ULL << i
) == x
) return i
;
970 // Generic quick sort.
971 void VG_(ssort
)( void* base
, SizeT nmemb
, SizeT size
,
972 Int (*compar
)(const void*, const void*) )
974 bm_qsort(base
,nmemb
,size
,compar
);
978 // This random number generator is based on the one suggested in Kernighan
979 // and Ritchie's "The C Programming Language".
981 // A pseudo-random number generator returning a random UInt. If pSeed
982 // is NULL, it uses its own seed, which starts at zero. If pSeed is
983 // non-NULL, it uses and updates whatever pSeed points at.
985 UInt
VG_(random
)( /*MOD*/UInt
* pSeed
)
987 static UInt seed
= 0;
992 *pSeed
= (1103515245 * *pSeed
+ 12345);
997 /* The following Adler-32 checksum code is taken from zlib-1.2.3, which
998 has the following copyright notice. */
1002 (C) 1995-2004 Jean-loup Gailly and Mark Adler
1004 This software is provided 'as-is', without any express or implied
1005 warranty. In no event will the authors be held liable for any damages
1006 arising from the use of this software.
1008 Permission is granted to anyone to use this software for any purpose,
1009 including commercial applications, and to alter it and redistribute it
1010 freely, subject to the following restrictions:
1012 1. The origin of this software must not be misrepresented; you must not
1013 claim that you wrote the original software. If you use this software
1014 in a product, an acknowledgment in the product documentation would be
1015 appreciated but is not required.
1016 2. Altered source versions must be plainly marked as such, and must not be
1017 misrepresented as being the original software.
1018 3. This notice may not be removed or altered from any source distribution.
1020 Jean-loup Gailly Mark Adler
1021 jloup@gzip.org madler@alumni.caltech.edu
1023 If you use the zlib library in a product, we would appreciate *not*
1024 receiving lengthy legal documents to sign. The sources are provided
1025 for free but without warranty of any kind. The library has been
1026 entirely written by Jean-loup Gailly and Mark Adler; it does not
1027 include third-party code.
1029 If you redistribute modified sources, we would appreciate that you include
1030 in the file ChangeLog history information documenting your changes. Please
1031 read the FAQ for more information on the distribution of modified source
1035 /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and
1036 return the updated checksum. If buf is NULL, this function returns
1037 the required initial value for the checksum. An Adler-32 checksum is
1038 almost as reliable as a CRC32 but can be computed much faster. */
1039 UInt
VG_(adler32
)( UInt adler
, const UChar
* buf
, UInt len
)
1041 # define BASE 65521UL /* largest prime smaller than 65536 */
1043 /* NMAX is the largest n such that
1044 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
1046 # define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
1047 # define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
1048 # define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
1049 # define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
1050 # define DO16(buf) DO8(buf,0); DO8(buf,8);
1052 /* The zlib sources recommend this definition of MOD if the
1053 processor cannot do integer division in hardware. */
1056 if (a >= (BASE << 16)) a -= (BASE << 16); \
1057 if (a >= (BASE << 15)) a -= (BASE << 15); \
1058 if (a >= (BASE << 14)) a -= (BASE << 14); \
1059 if (a >= (BASE << 13)) a -= (BASE << 13); \
1060 if (a >= (BASE << 12)) a -= (BASE << 12); \
1061 if (a >= (BASE << 11)) a -= (BASE << 11); \
1062 if (a >= (BASE << 10)) a -= (BASE << 10); \
1063 if (a >= (BASE << 9)) a -= (BASE << 9); \
1064 if (a >= (BASE << 8)) a -= (BASE << 8); \
1065 if (a >= (BASE << 7)) a -= (BASE << 7); \
1066 if (a >= (BASE << 6)) a -= (BASE << 6); \
1067 if (a >= (BASE << 5)) a -= (BASE << 5); \
1068 if (a >= (BASE << 4)) a -= (BASE << 4); \
1069 if (a >= (BASE << 3)) a -= (BASE << 3); \
1070 if (a >= (BASE << 2)) a -= (BASE << 2); \
1071 if (a >= (BASE << 1)) a -= (BASE << 1); \
1072 if (a >= BASE) a -= BASE; \
1076 if (a >= (BASE << 4)) a -= (BASE << 4); \
1077 if (a >= (BASE << 3)) a -= (BASE << 3); \
1078 if (a >= (BASE << 2)) a -= (BASE << 2); \
1079 if (a >= (BASE << 1)) a -= (BASE << 1); \
1080 if (a >= BASE) a -= BASE; \
1086 /* split Adler-32 into component sums */
1087 sum2
= (adler
>> 16) & 0xffff;
1090 /* in case user likes doing a byte at a time, keep it fast */
1098 return adler
| (sum2
<< 16);
1101 /* initial Adler-32 value (deferred check for len == 1 speed) */
1105 /* in case short lengths are provided, keep it somewhat fast */
1113 MOD4(sum2
); /* only added so many BASE's */
1114 return adler
| (sum2
<< 16);
1117 /* do length NMAX blocks -- requires just one modulo operation */
1118 while (len
>= NMAX
) {
1120 n
= NMAX
/ 16; /* NMAX is divisible by 16 */
1122 DO16(buf
); /* 16 sums unrolled */
1129 /* do remaining bytes (less than NMAX, still just one modulo) */
1130 if (len
) { /* avoid modulos if none remaining */
1144 /* return recombined sums */
1145 return adler
| (sum2
<< 16);
1158 /*--------------------------------------------------------------------*/
1160 /*--------------------------------------------------------------------*/