Remove a trivial assert (missed in previous checkin)
[official-gcc.git] / libsanitizer / sanitizer_common / sanitizer_libc.cc
blobc57128a54cbd06641cab81db1f5cdea57503aed8
1 //===-- sanitizer_libc.cc -------------------------------------------------===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is shared between AddressSanitizer and ThreadSanitizer
9 // run-time libraries. See sanitizer_libc.h for details.
10 //===----------------------------------------------------------------------===//
11 #include "sanitizer_common.h"
12 #include "sanitizer_libc.h"
14 namespace __sanitizer {
16 s64 internal_atoll(const char *nptr) {
17 return internal_simple_strtoll(nptr, (char**)0, 10);
20 void *internal_memchr(const void *s, int c, uptr n) {
21 const char* t = (char*)s;
22 for (uptr i = 0; i < n; ++i, ++t)
23 if (*t == c)
24 return (void*)t;
25 return 0;
28 int internal_memcmp(const void* s1, const void* s2, uptr n) {
29 const char* t1 = (char*)s1;
30 const char* t2 = (char*)s2;
31 for (uptr i = 0; i < n; ++i, ++t1, ++t2)
32 if (*t1 != *t2)
33 return *t1 < *t2 ? -1 : 1;
34 return 0;
37 void *internal_memcpy(void *dest, const void *src, uptr n) {
38 char *d = (char*)dest;
39 char *s = (char*)src;
40 for (uptr i = 0; i < n; ++i)
41 d[i] = s[i];
42 return dest;
45 void *internal_memmove(void *dest, const void *src, uptr n) {
46 char *d = (char*)dest;
47 char *s = (char*)src;
48 sptr i, signed_n = (sptr)n;
49 CHECK_GE(signed_n, 0);
50 if (d < s) {
51 for (i = 0; i < signed_n; ++i)
52 d[i] = s[i];
53 } else {
54 if (d > s && signed_n > 0)
55 for (i = signed_n - 1; i >= 0 ; --i) {
56 d[i] = s[i];
59 return dest;
62 void *internal_memset(void* s, int c, uptr n) {
63 // The next line prevents Clang from making a call to memset() instead of the
64 // loop below.
65 // FIXME: building the runtime with -ffreestanding is a better idea. However
66 // there currently are linktime problems due to PR12396.
67 char volatile *t = (char*)s;
68 for (uptr i = 0; i < n; ++i, ++t) {
69 *t = c;
71 return s;
74 uptr internal_strcspn(const char *s, const char *reject) {
75 uptr i;
76 for (i = 0; s[i]; i++) {
77 if (internal_strchr(reject, s[i]) != 0)
78 return i;
80 return i;
83 char* internal_strdup(const char *s) {
84 uptr len = internal_strlen(s);
85 char *s2 = (char*)InternalAlloc(len + 1);
86 internal_memcpy(s2, s, len);
87 s2[len] = 0;
88 return s2;
91 int internal_strcmp(const char *s1, const char *s2) {
92 while (true) {
93 unsigned c1 = *s1;
94 unsigned c2 = *s2;
95 if (c1 != c2) return (c1 < c2) ? -1 : 1;
96 if (c1 == 0) break;
97 s1++;
98 s2++;
100 return 0;
103 int internal_strncmp(const char *s1, const char *s2, uptr n) {
104 for (uptr i = 0; i < n; i++) {
105 unsigned c1 = *s1;
106 unsigned c2 = *s2;
107 if (c1 != c2) return (c1 < c2) ? -1 : 1;
108 if (c1 == 0) break;
109 s1++;
110 s2++;
112 return 0;
115 char* internal_strchr(const char *s, int c) {
116 while (true) {
117 if (*s == (char)c)
118 return (char*)s;
119 if (*s == 0)
120 return 0;
121 s++;
125 char *internal_strrchr(const char *s, int c) {
126 const char *res = 0;
127 for (uptr i = 0; s[i]; i++) {
128 if (s[i] == c) res = s + i;
130 return (char*)res;
133 uptr internal_strlen(const char *s) {
134 uptr i = 0;
135 while (s[i]) i++;
136 return i;
139 char *internal_strncat(char *dst, const char *src, uptr n) {
140 uptr len = internal_strlen(dst);
141 uptr i;
142 for (i = 0; i < n && src[i]; i++)
143 dst[len + i] = src[i];
144 dst[len + i] = 0;
145 return dst;
148 char *internal_strncpy(char *dst, const char *src, uptr n) {
149 uptr i;
150 for (i = 0; i < n && src[i]; i++)
151 dst[i] = src[i];
152 for (; i < n; i++)
153 dst[i] = '\0';
154 return dst;
157 uptr internal_strnlen(const char *s, uptr maxlen) {
158 uptr i = 0;
159 while (i < maxlen && s[i]) i++;
160 return i;
163 char *internal_strstr(const char *haystack, const char *needle) {
164 // This is O(N^2), but we are not using it in hot places.
165 uptr len1 = internal_strlen(haystack);
166 uptr len2 = internal_strlen(needle);
167 if (len1 < len2) return 0;
168 for (uptr pos = 0; pos <= len1 - len2; pos++) {
169 if (internal_memcmp(haystack + pos, needle, len2) == 0)
170 return (char*)haystack + pos;
172 return 0;
175 s64 internal_simple_strtoll(const char *nptr, char **endptr, int base) {
176 CHECK_EQ(base, 10);
177 while (IsSpace(*nptr)) nptr++;
178 int sgn = 1;
179 u64 res = 0;
180 bool have_digits = false;
181 char *old_nptr = (char*)nptr;
182 if (*nptr == '+') {
183 sgn = 1;
184 nptr++;
185 } else if (*nptr == '-') {
186 sgn = -1;
187 nptr++;
189 while (IsDigit(*nptr)) {
190 res = (res <= UINT64_MAX / 10) ? res * 10 : UINT64_MAX;
191 int digit = ((*nptr) - '0');
192 res = (res <= UINT64_MAX - digit) ? res + digit : UINT64_MAX;
193 have_digits = true;
194 nptr++;
196 if (endptr != 0) {
197 *endptr = (have_digits) ? (char*)nptr : old_nptr;
199 if (sgn > 0) {
200 return (s64)(Min((u64)INT64_MAX, res));
201 } else {
202 return (res > INT64_MAX) ? INT64_MIN : ((s64)res * -1);
206 bool mem_is_zero(const char *beg, uptr size) {
207 CHECK_LE(size, 1ULL << FIRST_32_SECOND_64(30, 40)); // Sanity check.
208 const char *end = beg + size;
209 uptr *aligned_beg = (uptr *)RoundUpTo((uptr)beg, sizeof(uptr));
210 uptr *aligned_end = (uptr *)RoundDownTo((uptr)end, sizeof(uptr));
211 uptr all = 0;
212 // Prologue.
213 for (const char *mem = beg; mem < (char*)aligned_beg && mem < end; mem++)
214 all |= *mem;
215 // Aligned loop.
216 for (; aligned_beg < aligned_end; aligned_beg++)
217 all |= *aligned_beg;
218 // Epilogue.
219 if ((char*)aligned_end >= beg)
220 for (const char *mem = (char*)aligned_end; mem < end; mem++)
221 all |= *mem;
222 return all == 0;
225 } // namespace __sanitizer