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//===----------------------------------------------------------------------===//
131f3c2fee395abc36230c445e9ebdba55c4729d35Alexey Samsonov#include "sanitizer_allocator_internal.h"
14f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov#include "sanitizer_common.h"
1516e0075746b21ed866ec3be21ef0d1e46f0efed5Kostya Serebryany#include "sanitizer_libc.h"
16b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany
17b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryanynamespace __sanitizer {
18b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany
19c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovs64 internal_atoll(const char *nptr) {
20c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  return internal_simple_strtoll(nptr, (char**)0, 10);
21b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany}
22b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany
231f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonovvoid *internal_memchr(const void *s, int c, uptr n) {
241f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov  const char* t = (char*)s;
251f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov  for (uptr i = 0; i < n; ++i, ++t)
261f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov    if (*t == c)
271f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov      return (void*)t;
281f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov  return 0;
291f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov}
301f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov
31327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonovint internal_memcmp(const void* s1, const void* s2, uptr n) {
32327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov  const char* t1 = (char*)s1;
33327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov  const char* t2 = (char*)s2;
34327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov  for (uptr i = 0; i < n; ++i, ++t1, ++t2)
35327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov    if (*t1 != *t2)
36327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov      return *t1 < *t2 ? -1 : 1;
37327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov  return 0;
38327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov}
39327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov
40f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonovvoid *internal_memcpy(void *dest, const void *src, uptr n) {
41f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  char *d = (char*)dest;
42f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  char *s = (char*)src;
43f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  for (uptr i = 0; i < n; ++i)
44f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov    d[i] = s[i];
45f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  return dest;
46f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov}
47f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov
48f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenkovoid *internal_memmove(void *dest, const void *src, uptr n) {
49f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko  char *d = (char*)dest;
50f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko  char *s = (char*)src;
5171a8273b3729ffaef40d178739f48dc38417d86aAlexander Potapenko  sptr i, signed_n = (sptr)n;
5271a8273b3729ffaef40d178739f48dc38417d86aAlexander Potapenko  CHECK_GE(signed_n, 0);
53f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko  if (d < s) {
5471a8273b3729ffaef40d178739f48dc38417d86aAlexander Potapenko    for (i = 0; i < signed_n; ++i)
55f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko      d[i] = s[i];
56f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko  } else {
5771a8273b3729ffaef40d178739f48dc38417d86aAlexander Potapenko    if (d > s && signed_n > 0)
5871a8273b3729ffaef40d178739f48dc38417d86aAlexander Potapenko      for (i = signed_n - 1; i >= 0 ; --i) {
595759d92e99e2b7adcc46a8729f16023208dd8f37Kostya Serebryany        d[i] = s[i];
60f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko      }
61f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko  }
62f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko  return dest;
63f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko}
64f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko
654fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonovvoid *internal_memset(void* s, int c, uptr n) {
664fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  // The next line prevents Clang from making a call to memset() instead of the
674fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  // loop below.
684fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  // FIXME: building the runtime with -ffreestanding is a better idea. However
694fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  // there currently are linktime problems due to PR12396.
704fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  char volatile *t = (char*)s;
714fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  for (uptr i = 0; i < n; ++i, ++t) {
724fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov    *t = c;
734fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  }
744fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  return s;
754fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov}
764fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov
77251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonovuptr internal_strcspn(const char *s, const char *reject) {
78251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov  uptr i;
79251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov  for (i = 0; s[i]; i++) {
80251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov    if (internal_strchr(reject, s[i]) != 0)
81251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov      return i;
82251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov  }
83251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov  return i;
84251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov}
85251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov
86f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonovchar* internal_strdup(const char *s) {
87f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  uptr len = internal_strlen(s);
88f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  char *s2 = (char*)InternalAlloc(len + 1);
89f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  internal_memcpy(s2, s, len);
90f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  s2[len] = 0;
91f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  return s2;
92f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov}
93f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov
94c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonovint internal_strcmp(const char *s1, const char *s2) {
95c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov  while (true) {
96c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov    unsigned c1 = *s1;
97c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov    unsigned c2 = *s2;
98c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov    if (c1 != c2) return (c1 < c2) ? -1 : 1;
99c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov    if (c1 == 0) break;
100c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov    s1++;
101c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov    s2++;
102c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov  }
103c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov  return 0;
104c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov}
105c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov
1068cd0df78c317106be477c5496f481af0563a5208Alexey Samsonovint internal_strncmp(const char *s1, const char *s2, uptr n) {
1078cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov  for (uptr i = 0; i < n; i++) {
1088cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov    unsigned c1 = *s1;
1098cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov    unsigned c2 = *s2;
1108cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov    if (c1 != c2) return (c1 < c2) ? -1 : 1;
1118cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov    if (c1 == 0) break;
1128cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov    s1++;
1138cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov    s2++;
1148cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov  }
1158cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov  return 0;
1168cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov}
1178cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov
11888207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonovchar* internal_strchr(const char *s, int c) {
11988207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov  while (true) {
12088207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov    if (*s == (char)c)
12188207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov      return (char*)s;
12288207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov    if (*s == 0)
12388207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov      return 0;
12488207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov    s++;
12588207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov  }
12688207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov}
12788207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov
1284fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonovchar *internal_strrchr(const char *s, int c) {
1294fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  const char *res = 0;
1304fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  for (uptr i = 0; s[i]; i++) {
1314fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov    if (s[i] == c) res = s + i;
1324fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  }
1334fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  return (char*)res;
1344fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov}
1354fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov
136230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonovuptr internal_strlen(const char *s) {
137230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  uptr i = 0;
138230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  while (s[i]) i++;
139230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  return i;
140230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov}
141230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov
142c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovchar *internal_strncat(char *dst, const char *src, uptr n) {
143c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  uptr len = internal_strlen(dst);
144c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  uptr i;
145c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  for (i = 0; i < n && src[i]; i++)
146c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    dst[len + i] = src[i];
147c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  dst[len + i] = 0;
148c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  return dst;
149c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov}
150c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov
1513836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonovchar *internal_strncpy(char *dst, const char *src, uptr n) {
1523836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov  uptr i;
1533836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov  for (i = 0; i < n && src[i]; i++)
1543836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov    dst[i] = src[i];
1553836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov  for (; i < n; i++)
1563836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov    dst[i] = '\0';
1573836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov  return dst;
1583836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov}
1593836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov
160c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovuptr internal_strnlen(const char *s, uptr maxlen) {
161c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  uptr i = 0;
162c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  while (i < maxlen && s[i]) i++;
163c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  return i;
164c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov}
165c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov
166c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovchar *internal_strstr(const char *haystack, const char *needle) {
167c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  // This is O(N^2), but we are not using it in hot places.
168c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  uptr len1 = internal_strlen(haystack);
169c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  uptr len2 = internal_strlen(needle);
170c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  if (len1 < len2) return 0;
171c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  for (uptr pos = 0; pos <= len1 - len2; pos++) {
172c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    if (internal_memcmp(haystack + pos, needle, len2) == 0)
173c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov      return (char*)haystack + pos;
174c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  }
175c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  return 0;
176c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov}
177c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov
178c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovs64 internal_simple_strtoll(const char *nptr, char **endptr, int base) {
1796985085c4860bf945358f227ddba26511ae770e9Kostya Serebryany  CHECK_EQ(base, 10);
180c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  while (IsSpace(*nptr)) nptr++;
181c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  int sgn = 1;
182c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  u64 res = 0;
183c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  bool have_digits = false;
184c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  char *old_nptr = (char*)nptr;
185c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  if (*nptr == '+') {
186c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    sgn = 1;
187c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    nptr++;
188c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  } else if (*nptr == '-') {
189c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    sgn = -1;
190c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    nptr++;
191c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  }
192c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  while (IsDigit(*nptr)) {
193c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    res = (res <= UINT64_MAX / 10) ? res * 10 : UINT64_MAX;
194c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    int digit = ((*nptr) - '0');
195c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    res = (res <= UINT64_MAX - digit) ? res + digit : UINT64_MAX;
196c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    have_digits = true;
197c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    nptr++;
198c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  }
199c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  if (endptr != 0) {
200c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    *endptr = (have_digits) ? (char*)nptr : old_nptr;
201c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  }
202c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  if (sgn > 0) {
203c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    return (s64)(Min((u64)INT64_MAX, res));
204c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  } else {
205c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    return (res > INT64_MAX) ? INT64_MIN : ((s64)res * -1);
206c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  }
207c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov}
208c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov
209eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryanybool mem_is_zero(const char *beg, uptr size) {
2108ceeec4f343768b199e7c891865029360b7225dcDmitry Vyukov  CHECK_LE(size, 1ULL << FIRST_32_SECOND_64(30, 40));  // Sanity check.
211eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  const char *end = beg + size;
212eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  uptr *aligned_beg = (uptr *)RoundUpTo((uptr)beg, sizeof(uptr));
213eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  uptr *aligned_end = (uptr *)RoundDownTo((uptr)end, sizeof(uptr));
214eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  uptr all = 0;
215eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  // Prologue.
216eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  for (const char *mem = beg; mem < (char*)aligned_beg && mem < end; mem++)
217eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany    all |= *mem;
218eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  // Aligned loop.
219eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  for (; aligned_beg < aligned_end; aligned_beg++)
220eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany    all |= *aligned_beg;
221eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  // Epilogue.
222eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  if ((char*)aligned_end >= beg)
223eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany    for (const char *mem = (char*)aligned_end; mem < end; mem++)
224eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany      all |= *mem;
225eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  return all == 0;
226eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany}
227eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany
228b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany}  // namespace __sanitizer
229