sanitizer_libc.cc revision f1673e61768cb08d488a75584b61bfdf24ffdac1
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_memmove(void *dest, const void *src, uptr n) { 48 char *d = (char*)dest; 49 char *s = (char*)src; 50 uptr i; 51 if (d < s) { 52 for (i = 0; i < n; ++i) 53 d[i] = s[i]; 54 } else { 55 if (d > s && n > 0) 56 for (i = n - 1; i > 0 ; --i) { 57 d[i] = s[i]; 58 } 59 } 60 return dest; 61} 62 63void *internal_memset(void* s, int c, uptr n) { 64 // The next line prevents Clang from making a call to memset() instead of the 65 // loop below. 66 // FIXME: building the runtime with -ffreestanding is a better idea. However 67 // there currently are linktime problems due to PR12396. 68 char volatile *t = (char*)s; 69 for (uptr i = 0; i < n; ++i, ++t) { 70 *t = c; 71 } 72 return s; 73} 74 75uptr internal_strcspn(const char *s, const char *reject) { 76 uptr i; 77 for (i = 0; s[i]; i++) { 78 if (internal_strchr(reject, s[i]) != 0) 79 return i; 80 } 81 return i; 82} 83 84char* internal_strdup(const char *s) { 85 uptr len = internal_strlen(s); 86 char *s2 = (char*)InternalAlloc(len + 1); 87 internal_memcpy(s2, s, len); 88 s2[len] = 0; 89 return s2; 90} 91 92int internal_strcmp(const char *s1, const char *s2) { 93 while (true) { 94 unsigned c1 = *s1; 95 unsigned c2 = *s2; 96 if (c1 != c2) return (c1 < c2) ? -1 : 1; 97 if (c1 == 0) break; 98 s1++; 99 s2++; 100 } 101 return 0; 102} 103 104int internal_strncmp(const char *s1, const char *s2, uptr n) { 105 for (uptr i = 0; i < n; i++) { 106 unsigned c1 = *s1; 107 unsigned c2 = *s2; 108 if (c1 != c2) return (c1 < c2) ? -1 : 1; 109 if (c1 == 0) break; 110 s1++; 111 s2++; 112 } 113 return 0; 114} 115 116char* internal_strchr(const char *s, int c) { 117 while (true) { 118 if (*s == (char)c) 119 return (char*)s; 120 if (*s == 0) 121 return 0; 122 s++; 123 } 124} 125 126char *internal_strrchr(const char *s, int c) { 127 const char *res = 0; 128 for (uptr i = 0; s[i]; i++) { 129 if (s[i] == c) res = s + i; 130 } 131 return (char*)res; 132} 133 134uptr internal_strlen(const char *s) { 135 uptr i = 0; 136 while (s[i]) i++; 137 return i; 138} 139 140char *internal_strncat(char *dst, const char *src, uptr n) { 141 uptr len = internal_strlen(dst); 142 uptr i; 143 for (i = 0; i < n && src[i]; i++) 144 dst[len + i] = src[i]; 145 dst[len + i] = 0; 146 return dst; 147} 148 149char *internal_strncpy(char *dst, const char *src, uptr n) { 150 uptr i; 151 for (i = 0; i < n && src[i]; i++) 152 dst[i] = src[i]; 153 for (; i < n; i++) 154 dst[i] = '\0'; 155 return dst; 156} 157 158uptr internal_strnlen(const char *s, uptr maxlen) { 159 uptr i = 0; 160 while (i < maxlen && s[i]) i++; 161 return i; 162} 163 164char *internal_strstr(const char *haystack, const char *needle) { 165 // This is O(N^2), but we are not using it in hot places. 166 uptr len1 = internal_strlen(haystack); 167 uptr len2 = internal_strlen(needle); 168 if (len1 < len2) return 0; 169 for (uptr pos = 0; pos <= len1 - len2; pos++) { 170 if (internal_memcmp(haystack + pos, needle, len2) == 0) 171 return (char*)haystack + pos; 172 } 173 return 0; 174} 175 176s64 internal_simple_strtoll(const char *nptr, char **endptr, int base) { 177 CHECK_EQ(base, 10); 178 while (IsSpace(*nptr)) nptr++; 179 int sgn = 1; 180 u64 res = 0; 181 bool have_digits = false; 182 char *old_nptr = (char*)nptr; 183 if (*nptr == '+') { 184 sgn = 1; 185 nptr++; 186 } else if (*nptr == '-') { 187 sgn = -1; 188 nptr++; 189 } 190 while (IsDigit(*nptr)) { 191 res = (res <= UINT64_MAX / 10) ? res * 10 : UINT64_MAX; 192 int digit = ((*nptr) - '0'); 193 res = (res <= UINT64_MAX - digit) ? res + digit : UINT64_MAX; 194 have_digits = true; 195 nptr++; 196 } 197 if (endptr != 0) { 198 *endptr = (have_digits) ? (char*)nptr : old_nptr; 199 } 200 if (sgn > 0) { 201 return (s64)(Min((u64)INT64_MAX, res)); 202 } else { 203 return (res > INT64_MAX) ? INT64_MIN : ((s64)res * -1); 204 } 205} 206 207} // namespace __sanitizer 208