sanitizer_libc.cc revision c925697df6626bb0ea27ea96539bf0580f8f3d3d
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 79char* internal_strchr(const char *s, int c) { 80 while (true) { 81 if (*s == (char)c) 82 return (char*)s; 83 if (*s == 0) 84 return 0; 85 s++; 86 } 87} 88 89char *internal_strrchr(const char *s, int c) { 90 const char *res = 0; 91 for (uptr i = 0; s[i]; i++) { 92 if (s[i] == c) res = s + i; 93 } 94 return (char*)res; 95} 96 97uptr internal_strlen(const char *s) { 98 uptr i = 0; 99 while (s[i]) i++; 100 return i; 101} 102 103char *internal_strncat(char *dst, const char *src, uptr n) { 104 uptr len = internal_strlen(dst); 105 uptr i; 106 for (i = 0; i < n && src[i]; i++) 107 dst[len + i] = src[i]; 108 dst[len + i] = 0; 109 return dst; 110} 111 112char *internal_strncpy(char *dst, const char *src, uptr n) { 113 uptr i; 114 for (i = 0; i < n && src[i]; i++) 115 dst[i] = src[i]; 116 for (; i < n; i++) 117 dst[i] = '\0'; 118 return dst; 119} 120 121uptr internal_strnlen(const char *s, uptr maxlen) { 122 uptr i = 0; 123 while (i < maxlen && s[i]) i++; 124 return i; 125} 126 127char *internal_strstr(const char *haystack, const char *needle) { 128 // This is O(N^2), but we are not using it in hot places. 129 uptr len1 = internal_strlen(haystack); 130 uptr len2 = internal_strlen(needle); 131 if (len1 < len2) return 0; 132 for (uptr pos = 0; pos <= len1 - len2; pos++) { 133 if (internal_memcmp(haystack + pos, needle, len2) == 0) 134 return (char*)haystack + pos; 135 } 136 return 0; 137} 138 139s64 internal_simple_strtoll(const char *nptr, char **endptr, int base) { 140 CHECK(base == 10); 141 while (IsSpace(*nptr)) nptr++; 142 int sgn = 1; 143 u64 res = 0; 144 bool have_digits = false; 145 char *old_nptr = (char*)nptr; 146 if (*nptr == '+') { 147 sgn = 1; 148 nptr++; 149 } else if (*nptr == '-') { 150 sgn = -1; 151 nptr++; 152 } 153 while (IsDigit(*nptr)) { 154 res = (res <= UINT64_MAX / 10) ? res * 10 : UINT64_MAX; 155 int digit = ((*nptr) - '0'); 156 res = (res <= UINT64_MAX - digit) ? res + digit : UINT64_MAX; 157 have_digits = true; 158 nptr++; 159 } 160 if (endptr != 0) { 161 *endptr = (have_digits) ? (char*)nptr : old_nptr; 162 } 163 if (sgn > 0) { 164 return (s64)(Min((u64)INT64_MAX, res)); 165 } else { 166 return (res > INT64_MAX) ? INT64_MIN : ((s64)res * -1); 167 } 168} 169 170} // namespace __sanitizer 171