sanitizer_libc.cc revision c925697df6626bb0ea27ea96539bf0580f8f3d3d
1603c4be006d8c53905d736bf1f19a49f5ce98276Alexey Samsonov//===-- sanitizer_libc.cc -------------------------------------------------===//
2b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany//
3b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany//                     The LLVM Compiler Infrastructure
4b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany//
5b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany// This file is distributed under the University of Illinois Open Source
6b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany// License. See LICENSE.TXT for details.
7b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany//
8b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany//===----------------------------------------------------------------------===//
9b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany//
10b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany// This file is shared between AddressSanitizer and ThreadSanitizer
1116e0075746b21ed866ec3be21ef0d1e46f0efed5Kostya Serebryany// run-time libraries. See sanitizer_libc.h for details.
12b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany//===----------------------------------------------------------------------===//
13f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov#include "sanitizer_common.h"
1416e0075746b21ed866ec3be21ef0d1e46f0efed5Kostya Serebryany#include "sanitizer_libc.h"
15b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany
16b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryanynamespace __sanitizer {
17b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany
18c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovs64 internal_atoll(const char *nptr) {
19c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  return internal_simple_strtoll(nptr, (char**)0, 10);
20b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany}
21b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany
221f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonovvoid *internal_memchr(const void *s, int c, uptr n) {
231f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov  const char* t = (char*)s;
241f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov  for (uptr i = 0; i < n; ++i, ++t)
251f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov    if (*t == c)
261f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov      return (void*)t;
271f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov  return 0;
281f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov}
291f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov
30327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonovint internal_memcmp(const void* s1, const void* s2, uptr n) {
31327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov  const char* t1 = (char*)s1;
32327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov  const char* t2 = (char*)s2;
33327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov  for (uptr i = 0; i < n; ++i, ++t1, ++t2)
34327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov    if (*t1 != *t2)
35327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov      return *t1 < *t2 ? -1 : 1;
36327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov  return 0;
37327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov}
38327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov
39f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonovvoid *internal_memcpy(void *dest, const void *src, uptr n) {
40f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  char *d = (char*)dest;
41f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  char *s = (char*)src;
42f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  for (uptr i = 0; i < n; ++i)
43f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov    d[i] = s[i];
44f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  return dest;
45f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov}
46f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov
474fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonovvoid *internal_memset(void* s, int c, uptr n) {
484fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  // The next line prevents Clang from making a call to memset() instead of the
494fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  // loop below.
504fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  // FIXME: building the runtime with -ffreestanding is a better idea. However
514fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  // there currently are linktime problems due to PR12396.
524fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  char volatile *t = (char*)s;
534fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  for (uptr i = 0; i < n; ++i, ++t) {
544fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov    *t = c;
554fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  }
564fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  return s;
574fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov}
584fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov
59f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonovchar* internal_strdup(const char *s) {
60f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  uptr len = internal_strlen(s);
61f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  char *s2 = (char*)InternalAlloc(len + 1);
62f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  internal_memcpy(s2, s, len);
63f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  s2[len] = 0;
64f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  return s2;
65f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov}
66f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov
67c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonovint internal_strcmp(const char *s1, const char *s2) {
68c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov  while (true) {
69c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov    unsigned c1 = *s1;
70c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov    unsigned c2 = *s2;
71c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov    if (c1 != c2) return (c1 < c2) ? -1 : 1;
72c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov    if (c1 == 0) break;
73c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov    s1++;
74c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov    s2++;
75c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov  }
76c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov  return 0;
77c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov}
78c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov
7988207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonovchar* internal_strchr(const char *s, int c) {
8088207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov  while (true) {
8188207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov    if (*s == (char)c)
8288207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov      return (char*)s;
8388207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov    if (*s == 0)
8488207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov      return 0;
8588207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov    s++;
8688207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov  }
8788207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov}
8888207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov
894fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonovchar *internal_strrchr(const char *s, int c) {
904fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  const char *res = 0;
914fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  for (uptr i = 0; s[i]; i++) {
924fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov    if (s[i] == c) res = s + i;
934fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  }
944fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  return (char*)res;
954fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov}
964fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov
97230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonovuptr internal_strlen(const char *s) {
98230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  uptr i = 0;
99230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  while (s[i]) i++;
100230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  return i;
101230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov}
102230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov
103c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovchar *internal_strncat(char *dst, const char *src, uptr n) {
104c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  uptr len = internal_strlen(dst);
105c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  uptr i;
106c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  for (i = 0; i < n && src[i]; i++)
107c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    dst[len + i] = src[i];
108c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  dst[len + i] = 0;
109c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  return dst;
110c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov}
111c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov
1123836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonovchar *internal_strncpy(char *dst, const char *src, uptr n) {
1133836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov  uptr i;
1143836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov  for (i = 0; i < n && src[i]; i++)
1153836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov    dst[i] = src[i];
1163836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov  for (; i < n; i++)
1173836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov    dst[i] = '\0';
1183836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov  return dst;
1193836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov}
1203836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov
121c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovuptr internal_strnlen(const char *s, uptr maxlen) {
122c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  uptr i = 0;
123c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  while (i < maxlen && s[i]) i++;
124c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  return i;
125c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov}
126c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov
127c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovchar *internal_strstr(const char *haystack, const char *needle) {
128c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  // This is O(N^2), but we are not using it in hot places.
129c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  uptr len1 = internal_strlen(haystack);
130c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  uptr len2 = internal_strlen(needle);
131c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  if (len1 < len2) return 0;
132c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  for (uptr pos = 0; pos <= len1 - len2; pos++) {
133c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    if (internal_memcmp(haystack + pos, needle, len2) == 0)
134c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov      return (char*)haystack + pos;
135c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  }
136c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  return 0;
137c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov}
138c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov
139c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovs64 internal_simple_strtoll(const char *nptr, char **endptr, int base) {
140c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  CHECK(base == 10);
141c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  while (IsSpace(*nptr)) nptr++;
142c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  int sgn = 1;
143c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  u64 res = 0;
144c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  bool have_digits = false;
145c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  char *old_nptr = (char*)nptr;
146c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  if (*nptr == '+') {
147c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    sgn = 1;
148c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    nptr++;
149c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  } else if (*nptr == '-') {
150c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    sgn = -1;
151c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    nptr++;
152c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  }
153c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  while (IsDigit(*nptr)) {
154c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    res = (res <= UINT64_MAX / 10) ? res * 10 : UINT64_MAX;
155c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    int digit = ((*nptr) - '0');
156c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    res = (res <= UINT64_MAX - digit) ? res + digit : UINT64_MAX;
157c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    have_digits = true;
158c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    nptr++;
159c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  }
160c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  if (endptr != 0) {
161c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    *endptr = (have_digits) ? (char*)nptr : old_nptr;
162c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  }
163c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  if (sgn > 0) {
164c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    return (s64)(Min((u64)INT64_MAX, res));
165c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  } else {
166c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    return (res > INT64_MAX) ? INT64_MIN : ((s64)res * -1);
167c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  }
168c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov}
169c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov
170b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany}  // namespace __sanitizer
171