2012-10-29 Wei Mi <wmi@google.com>
[official-gcc.git] / libasan / sanitizer_common / sanitizer_libc.cc
blob21869bc4846fbe7356a192f8d5ee72a0a8b92207
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_memset(void* s, int c, uptr n) {
46 // The next line prevents Clang from making a call to memset() instead of the
47 // loop below.
48 // FIXME: building the runtime with -ffreestanding is a better idea. However
49 // there currently are linktime problems due to PR12396.
50 char volatile *t = (char*)s;
51 for (uptr i = 0; i < n; ++i, ++t) {
52 *t = c;
54 return s;
57 uptr internal_strcspn(const char *s, const char *reject) {
58 uptr i;
59 for (i = 0; s[i]; i++) {
60 if (internal_strchr(reject, s[i]) != 0)
61 return i;
63 return i;
66 char* internal_strdup(const char *s) {
67 uptr len = internal_strlen(s);
68 char *s2 = (char*)InternalAlloc(len + 1);
69 internal_memcpy(s2, s, len);
70 s2[len] = 0;
71 return s2;
74 int internal_strcmp(const char *s1, const char *s2) {
75 while (true) {
76 unsigned c1 = *s1;
77 unsigned c2 = *s2;
78 if (c1 != c2) return (c1 < c2) ? -1 : 1;
79 if (c1 == 0) break;
80 s1++;
81 s2++;
83 return 0;
86 int internal_strncmp(const char *s1, const char *s2, uptr n) {
87 for (uptr i = 0; i < n; i++) {
88 unsigned c1 = *s1;
89 unsigned c2 = *s2;
90 if (c1 != c2) return (c1 < c2) ? -1 : 1;
91 if (c1 == 0) break;
92 s1++;
93 s2++;
95 return 0;
98 char* internal_strchr(const char *s, int c) {
99 while (true) {
100 if (*s == (char)c)
101 return (char*)s;
102 if (*s == 0)
103 return 0;
104 s++;
108 char *internal_strrchr(const char *s, int c) {
109 const char *res = 0;
110 for (uptr i = 0; s[i]; i++) {
111 if (s[i] == c) res = s + i;
113 return (char*)res;
116 uptr internal_strlen(const char *s) {
117 uptr i = 0;
118 while (s[i]) i++;
119 return i;
122 char *internal_strncat(char *dst, const char *src, uptr n) {
123 uptr len = internal_strlen(dst);
124 uptr i;
125 for (i = 0; i < n && src[i]; i++)
126 dst[len + i] = src[i];
127 dst[len + i] = 0;
128 return dst;
131 char *internal_strncpy(char *dst, const char *src, uptr n) {
132 uptr i;
133 for (i = 0; i < n && src[i]; i++)
134 dst[i] = src[i];
135 for (; i < n; i++)
136 dst[i] = '\0';
137 return dst;
140 uptr internal_strnlen(const char *s, uptr maxlen) {
141 uptr i = 0;
142 while (i < maxlen && s[i]) i++;
143 return i;
146 char *internal_strstr(const char *haystack, const char *needle) {
147 // This is O(N^2), but we are not using it in hot places.
148 uptr len1 = internal_strlen(haystack);
149 uptr len2 = internal_strlen(needle);
150 if (len1 < len2) return 0;
151 for (uptr pos = 0; pos <= len1 - len2; pos++) {
152 if (internal_memcmp(haystack + pos, needle, len2) == 0)
153 return (char*)haystack + pos;
155 return 0;
158 s64 internal_simple_strtoll(const char *nptr, char **endptr, int base) {
159 CHECK_EQ(base, 10);
160 while (IsSpace(*nptr)) nptr++;
161 int sgn = 1;
162 u64 res = 0;
163 bool have_digits = false;
164 char *old_nptr = (char*)nptr;
165 if (*nptr == '+') {
166 sgn = 1;
167 nptr++;
168 } else if (*nptr == '-') {
169 sgn = -1;
170 nptr++;
172 while (IsDigit(*nptr)) {
173 res = (res <= UINT64_MAX / 10) ? res * 10 : UINT64_MAX;
174 int digit = ((*nptr) - '0');
175 res = (res <= UINT64_MAX - digit) ? res + digit : UINT64_MAX;
176 have_digits = true;
177 nptr++;
179 if (endptr != 0) {
180 *endptr = (have_digits) ? (char*)nptr : old_nptr;
182 if (sgn > 0) {
183 return (s64)(Min((u64)INT64_MAX, res));
184 } else {
185 return (res > INT64_MAX) ? INT64_MIN : ((s64)res * -1);
189 } // namespace __sanitizer