sanitizer_libc.cc revision 71a8273b3729ffaef40d178739f48dc38417d86a
15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu//===-- sanitizer_libc.cc -------------------------------------------------===//
25c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu//
35c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu//                     The LLVM Compiler Infrastructure
45c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu//
55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// This file is distributed under the University of Illinois Open Source
65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// License. See LICENSE.TXT for details.
75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu//
85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu//===----------------------------------------------------------------------===//
95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu//
105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// This file is shared between AddressSanitizer and ThreadSanitizer
115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// run-time libraries. See sanitizer_libc.h for details.
125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu//===----------------------------------------------------------------------===//
135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "sanitizer_common.h"
145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "sanitizer_libc.h"
155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace __sanitizer {
175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Lius64 internal_atoll(const char *nptr) {
195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return internal_simple_strtoll(nptr, (char**)0, 10);
205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid *internal_memchr(const void *s, int c, uptr n) {
235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  const char* t = (char*)s;
245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  for (uptr i = 0; i < n; ++i, ++t)
255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (*t == c)
26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return (void*)t;
275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return 0;
28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuint internal_memcmp(const void* s1, const void* s2, uptr n) {
31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const char* t1 = (char*)s1;
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const char* t2 = (char*)s2;
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (uptr i = 0; i < n; ++i, ++t1, ++t2)
345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (*t1 != *t2)
355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      return *t1 < *t2 ? -1 : 1;
365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return 0;
375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid *internal_memcpy(void *dest, const void *src, uptr n) {
405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  char *d = (char*)dest;
415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  char *s = (char*)src;
425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  for (uptr i = 0; i < n; ++i)
435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    d[i] = s[i];
445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return dest;
455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid *internal_memmove(void *dest, const void *src, uptr n) {
485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  char *d = (char*)dest;
49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  char *s = (char*)src;
50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  sptr i, signed_n = (sptr)n;
515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  CHECK_GE(signed_n, 0);
525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (d < s) {
535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    for (i = 0; i < signed_n; ++i)
545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      d[i] = s[i];
555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  } else {
565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (d > s && signed_n > 0)
575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      for (i = signed_n - 1; i >= 0 ; --i) {
585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        d[i] = s[i];
595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      }
605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return dest;
625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid *internal_memset(void* s, int c, uptr n) {
655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // The next line prevents Clang from making a call to memset() instead of the
66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // loop below.
67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // FIXME: building the runtime with -ffreestanding is a better idea. However
685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // there currently are linktime problems due to PR12396.
695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  char volatile *t = (char*)s;
705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  for (uptr i = 0; i < n; ++i, ++t) {
715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    *t = c;
725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return s;
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)uptr internal_strcspn(const char *s, const char *reject) {
77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  uptr i;
78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (i = 0; s[i]; i++) {
79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (internal_strchr(reject, s[i]) != 0)
80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return i;
815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return i;
83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)char* internal_strdup(const char *s) {
86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  uptr len = internal_strlen(s);
87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  char *s2 = (char*)InternalAlloc(len + 1);
88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  internal_memcpy(s2, s, len);
89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  s2[len] = 0;
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return s2;
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int internal_strcmp(const char *s1, const char *s2) {
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  while (true) {
95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    unsigned c1 = *s1;
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    unsigned c2 = *s2;
975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (c1 != c2) return (c1 < c2) ? -1 : 1;
985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (c1 == 0) break;
995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    s1++;
1005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    s2++;
1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return 0;
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int internal_strncmp(const char *s1, const char *s2, uptr n) {
1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  for (uptr i = 0; i < n; i++) {
107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    unsigned c1 = *s1;
108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    unsigned c2 = *s2;
109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (c1 != c2) return (c1 < c2) ? -1 : 1;
110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (c1 == 0) break;
111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    s1++;
112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    s2++;
1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return 0;
1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuchar* internal_strchr(const char *s, int c) {
1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  while (true) {
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (*s == (char)c)
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return (char*)s;
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (*s == 0)
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return 0;
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    s++;
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)char *internal_strrchr(const char *s, int c) {
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const char *res = 0;
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (uptr i = 0; s[i]; i++) {
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (s[i] == c) res = s + i;
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return (char*)res;
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)uptr internal_strlen(const char *s) {
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  uptr i = 0;
137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  while (s[i]) i++;
138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return i;
139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)char *internal_strncat(char *dst, const char *src, uptr n) {
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  uptr len = internal_strlen(dst);
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  uptr i;
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (i = 0; i < n && src[i]; i++)
145010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    dst[len + i] = src[i];
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  dst[len + i] = 0;
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return dst;
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)char *internal_strncpy(char *dst, const char *src, uptr n) {
151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  uptr i;
152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (i = 0; i < n && src[i]; i++)
153010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    dst[i] = src[i];
154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (; i < n; i++)
155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    dst[i] = '\0';
156010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return dst;
157010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)uptr internal_strnlen(const char *s, uptr maxlen) {
160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  uptr i = 0;
161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  while (i < maxlen && s[i]) i++;
162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return i;
163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
165010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)char *internal_strstr(const char *haystack, const char *needle) {
166010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // This is O(N^2), but we are not using it in hot places.
167010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  uptr len1 = internal_strlen(haystack);
168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  uptr len2 = internal_strlen(needle);
169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (len1 < len2) return 0;
170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (uptr pos = 0; pos <= len1 - len2; pos++) {
171010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (internal_memcmp(haystack + pos, needle, len2) == 0)
172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return (char*)haystack + pos;
173010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return 0;
175010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
176010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
177010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)s64 internal_simple_strtoll(const char *nptr, char **endptr, int base) {
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CHECK_EQ(base, 10);
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  while (IsSpace(*nptr)) nptr++;
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int sgn = 1;
181010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  u64 res = 0;
182010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  bool have_digits = false;
183010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  char *old_nptr = (char*)nptr;
184010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (*nptr == '+') {
185010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    sgn = 1;
186010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    nptr++;
187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  } else if (*nptr == '-') {
188010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    sgn = -1;
189010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    nptr++;
190010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
191010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  while (IsDigit(*nptr)) {
192010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    res = (res <= UINT64_MAX / 10) ? res * 10 : UINT64_MAX;
193010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    int digit = ((*nptr) - '0');
194010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    res = (res <= UINT64_MAX - digit) ? res + digit : UINT64_MAX;
195010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    have_digits = true;
1965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    nptr++;
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
198010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (endptr != 0) {
199010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    *endptr = (have_digits) ? (char*)nptr : old_nptr;
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (sgn > 0) {
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return (s64)(Min((u64)INT64_MAX, res));
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else {
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return (res > INT64_MAX) ? INT64_MIN : ((s64)res * -1);
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace __sanitizer
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)