sanitizer_libc.cc revision 8cd0df78c317106be477c5496f481af0563a5208
1//===-- sanitizer_libc.cc -------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file is shared between AddressSanitizer and ThreadSanitizer 11// run-time libraries. See sanitizer_libc.h for details. 12//===----------------------------------------------------------------------===// 13#include "sanitizer_common.h" 14#include "sanitizer_libc.h" 15 16namespace __sanitizer { 17 18s64 internal_atoll(const char *nptr) { 19 return internal_simple_strtoll(nptr, (char**)0, 10); 20} 21 22void *internal_memchr(const void *s, int c, uptr n) { 23 const char* t = (char*)s; 24 for (uptr i = 0; i < n; ++i, ++t) 25 if (*t == c) 26 return (void*)t; 27 return 0; 28} 29 30int internal_memcmp(const void* s1, const void* s2, uptr n) { 31 const char* t1 = (char*)s1; 32 const char* t2 = (char*)s2; 33 for (uptr i = 0; i < n; ++i, ++t1, ++t2) 34 if (*t1 != *t2) 35 return *t1 < *t2 ? -1 : 1; 36 return 0; 37} 38 39void *internal_memcpy(void *dest, const void *src, uptr n) { 40 char *d = (char*)dest; 41 char *s = (char*)src; 42 for (uptr i = 0; i < n; ++i) 43 d[i] = s[i]; 44 return dest; 45} 46 47void *internal_memset(void* s, int c, uptr n) { 48 // The next line prevents Clang from making a call to memset() instead of the 49 // loop below. 50 // FIXME: building the runtime with -ffreestanding is a better idea. However 51 // there currently are linktime problems due to PR12396. 52 char volatile *t = (char*)s; 53 for (uptr i = 0; i < n; ++i, ++t) { 54 *t = c; 55 } 56 return s; 57} 58 59char* internal_strdup(const char *s) { 60 uptr len = internal_strlen(s); 61 char *s2 = (char*)InternalAlloc(len + 1); 62 internal_memcpy(s2, s, len); 63 s2[len] = 0; 64 return s2; 65} 66 67int internal_strcmp(const char *s1, const char *s2) { 68 while (true) { 69 unsigned c1 = *s1; 70 unsigned c2 = *s2; 71 if (c1 != c2) return (c1 < c2) ? -1 : 1; 72 if (c1 == 0) break; 73 s1++; 74 s2++; 75 } 76 return 0; 77} 78 79int internal_strncmp(const char *s1, const char *s2, uptr n) { 80 for (uptr i = 0; i < n; i++) { 81 unsigned c1 = *s1; 82 unsigned c2 = *s2; 83 if (c1 != c2) return (c1 < c2) ? -1 : 1; 84 if (c1 == 0) break; 85 s1++; 86 s2++; 87 } 88 return 0; 89} 90 91char* internal_strchr(const char *s, int c) { 92 while (true) { 93 if (*s == (char)c) 94 return (char*)s; 95 if (*s == 0) 96 return 0; 97 s++; 98 } 99} 100 101char *internal_strrchr(const char *s, int c) { 102 const char *res = 0; 103 for (uptr i = 0; s[i]; i++) { 104 if (s[i] == c) res = s + i; 105 } 106 return (char*)res; 107} 108 109uptr internal_strlen(const char *s) { 110 uptr i = 0; 111 while (s[i]) i++; 112 return i; 113} 114 115char *internal_strncat(char *dst, const char *src, uptr n) { 116 uptr len = internal_strlen(dst); 117 uptr i; 118 for (i = 0; i < n && src[i]; i++) 119 dst[len + i] = src[i]; 120 dst[len + i] = 0; 121 return dst; 122} 123 124char *internal_strncpy(char *dst, const char *src, uptr n) { 125 uptr i; 126 for (i = 0; i < n && src[i]; i++) 127 dst[i] = src[i]; 128 for (; i < n; i++) 129 dst[i] = '\0'; 130 return dst; 131} 132 133uptr internal_strnlen(const char *s, uptr maxlen) { 134 uptr i = 0; 135 while (i < maxlen && s[i]) i++; 136 return i; 137} 138 139char *internal_strstr(const char *haystack, const char *needle) { 140 // This is O(N^2), but we are not using it in hot places. 141 uptr len1 = internal_strlen(haystack); 142 uptr len2 = internal_strlen(needle); 143 if (len1 < len2) return 0; 144 for (uptr pos = 0; pos <= len1 - len2; pos++) { 145 if (internal_memcmp(haystack + pos, needle, len2) == 0) 146 return (char*)haystack + pos; 147 } 148 return 0; 149} 150 151s64 internal_simple_strtoll(const char *nptr, char **endptr, int base) { 152 CHECK(base == 10); 153 while (IsSpace(*nptr)) nptr++; 154 int sgn = 1; 155 u64 res = 0; 156 bool have_digits = false; 157 char *old_nptr = (char*)nptr; 158 if (*nptr == '+') { 159 sgn = 1; 160 nptr++; 161 } else if (*nptr == '-') { 162 sgn = -1; 163 nptr++; 164 } 165 while (IsDigit(*nptr)) { 166 res = (res <= UINT64_MAX / 10) ? res * 10 : UINT64_MAX; 167 int digit = ((*nptr) - '0'); 168 res = (res <= UINT64_MAX - digit) ? res + digit : UINT64_MAX; 169 have_digits = true; 170 nptr++; 171 } 172 if (endptr != 0) { 173 *endptr = (have_digits) ? (char*)nptr : old_nptr; 174 } 175 if (sgn > 0) { 176 return (s64)(Min((u64)INT64_MAX, res)); 177 } else { 178 return (res > INT64_MAX) ? INT64_MIN : ((s64)res * -1); 179 } 180} 181 182} // namespace __sanitizer 183