sanitizer_libc.cc revision eb2809311c94b73c269ccef8d68ae368642e5754
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
47f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenkovoid *internal_memmove(void *dest, const void *src, uptr n) {
48f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko  char *d = (char*)dest;
49f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko  char *s = (char*)src;
5071a8273b3729ffaef40d178739f48dc38417d86aAlexander Potapenko  sptr i, signed_n = (sptr)n;
5171a8273b3729ffaef40d178739f48dc38417d86aAlexander Potapenko  CHECK_GE(signed_n, 0);
52f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko  if (d < s) {
5371a8273b3729ffaef40d178739f48dc38417d86aAlexander Potapenko    for (i = 0; i < signed_n; ++i)
54f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko      d[i] = s[i];
55f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko  } else {
5671a8273b3729ffaef40d178739f48dc38417d86aAlexander Potapenko    if (d > s && signed_n > 0)
5771a8273b3729ffaef40d178739f48dc38417d86aAlexander Potapenko      for (i = signed_n - 1; i >= 0 ; --i) {
585759d92e99e2b7adcc46a8729f16023208dd8f37Kostya Serebryany        d[i] = s[i];
59f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko      }
60f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko  }
61f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko  return dest;
62f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko}
63f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko
644fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonovvoid *internal_memset(void* s, int c, uptr n) {
654fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  // The next line prevents Clang from making a call to memset() instead of the
664fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  // loop below.
674fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  // FIXME: building the runtime with -ffreestanding is a better idea. However
684fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  // there currently are linktime problems due to PR12396.
694fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  char volatile *t = (char*)s;
704fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  for (uptr i = 0; i < n; ++i, ++t) {
714fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov    *t = c;
724fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  }
734fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  return s;
744fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov}
754fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov
76251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonovuptr internal_strcspn(const char *s, const char *reject) {
77251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov  uptr i;
78251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov  for (i = 0; s[i]; i++) {
79251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov    if (internal_strchr(reject, s[i]) != 0)
80251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov      return i;
81251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov  }
82251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov  return i;
83251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov}
84251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov
85f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonovchar* internal_strdup(const char *s) {
86f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  uptr len = internal_strlen(s);
87f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  char *s2 = (char*)InternalAlloc(len + 1);
88f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  internal_memcpy(s2, s, len);
89f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  s2[len] = 0;
90f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov  return s2;
91f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov}
92f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov
93c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonovint internal_strcmp(const char *s1, const char *s2) {
94c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov  while (true) {
95c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov    unsigned c1 = *s1;
96c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov    unsigned c2 = *s2;
97c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov    if (c1 != c2) return (c1 < c2) ? -1 : 1;
98c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov    if (c1 == 0) break;
99c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov    s1++;
100c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov    s2++;
101c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov  }
102c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov  return 0;
103c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov}
104c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov
1058cd0df78c317106be477c5496f481af0563a5208Alexey Samsonovint internal_strncmp(const char *s1, const char *s2, uptr n) {
1068cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov  for (uptr i = 0; i < n; i++) {
1078cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov    unsigned c1 = *s1;
1088cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov    unsigned c2 = *s2;
1098cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov    if (c1 != c2) return (c1 < c2) ? -1 : 1;
1108cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov    if (c1 == 0) break;
1118cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov    s1++;
1128cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov    s2++;
1138cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov  }
1148cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov  return 0;
1158cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov}
1168cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov
11788207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonovchar* internal_strchr(const char *s, int c) {
11888207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov  while (true) {
11988207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov    if (*s == (char)c)
12088207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov      return (char*)s;
12188207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov    if (*s == 0)
12288207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov      return 0;
12388207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov    s++;
12488207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov  }
12588207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov}
12688207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov
1274fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonovchar *internal_strrchr(const char *s, int c) {
1284fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  const char *res = 0;
1294fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  for (uptr i = 0; s[i]; i++) {
1304fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov    if (s[i] == c) res = s + i;
1314fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  }
1324fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov  return (char*)res;
1334fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov}
1344fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov
135230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonovuptr internal_strlen(const char *s) {
136230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  uptr i = 0;
137230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  while (s[i]) i++;
138230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  return i;
139230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov}
140230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov
141c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovchar *internal_strncat(char *dst, const char *src, uptr n) {
142c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  uptr len = internal_strlen(dst);
143c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  uptr i;
144c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  for (i = 0; i < n && src[i]; i++)
145c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    dst[len + i] = src[i];
146c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  dst[len + i] = 0;
147c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  return dst;
148c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov}
149c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov
1503836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonovchar *internal_strncpy(char *dst, const char *src, uptr n) {
1513836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov  uptr i;
1523836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov  for (i = 0; i < n && src[i]; i++)
1533836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov    dst[i] = src[i];
1543836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov  for (; i < n; i++)
1553836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov    dst[i] = '\0';
1563836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov  return dst;
1573836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov}
1583836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov
159c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovuptr internal_strnlen(const char *s, uptr maxlen) {
160c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  uptr i = 0;
161c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  while (i < maxlen && s[i]) i++;
162c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  return i;
163c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov}
164c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov
165c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovchar *internal_strstr(const char *haystack, const char *needle) {
166c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  // This is O(N^2), but we are not using it in hot places.
167c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  uptr len1 = internal_strlen(haystack);
168c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  uptr len2 = internal_strlen(needle);
169c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  if (len1 < len2) return 0;
170c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  for (uptr pos = 0; pos <= len1 - len2; pos++) {
171c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    if (internal_memcmp(haystack + pos, needle, len2) == 0)
172c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov      return (char*)haystack + pos;
173c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  }
174c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  return 0;
175c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov}
176c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov
177c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovs64 internal_simple_strtoll(const char *nptr, char **endptr, int base) {
1786985085c4860bf945358f227ddba26511ae770e9Kostya Serebryany  CHECK_EQ(base, 10);
179c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  while (IsSpace(*nptr)) nptr++;
180c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  int sgn = 1;
181c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  u64 res = 0;
182c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  bool have_digits = false;
183c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  char *old_nptr = (char*)nptr;
184c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  if (*nptr == '+') {
185c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    sgn = 1;
186c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    nptr++;
187c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  } else if (*nptr == '-') {
188c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    sgn = -1;
189c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    nptr++;
190c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  }
191c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  while (IsDigit(*nptr)) {
192c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    res = (res <= UINT64_MAX / 10) ? res * 10 : UINT64_MAX;
193c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    int digit = ((*nptr) - '0');
194c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    res = (res <= UINT64_MAX - digit) ? res + digit : UINT64_MAX;
195c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    have_digits = true;
196c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    nptr++;
197c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  }
198c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  if (endptr != 0) {
199c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    *endptr = (have_digits) ? (char*)nptr : old_nptr;
200c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  }
201c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  if (sgn > 0) {
202c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    return (s64)(Min((u64)INT64_MAX, res));
203c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  } else {
204c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov    return (res > INT64_MAX) ? INT64_MIN : ((s64)res * -1);
205c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov  }
206c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov}
207c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov
208eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryanybool mem_is_zero(const char *beg, uptr size) {
209eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  CHECK_LE(size, 1UL << FIRST_32_SECOND_64(30, 40));  // Sanity check.
210eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  const char *end = beg + size;
211eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  uptr *aligned_beg = (uptr *)RoundUpTo((uptr)beg, sizeof(uptr));
212eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  uptr *aligned_end = (uptr *)RoundDownTo((uptr)end, sizeof(uptr));
213eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  uptr all = 0;
214eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  // Prologue.
215eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  for (const char *mem = beg; mem < (char*)aligned_beg && mem < end; mem++)
216eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany    all |= *mem;
217eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  // Aligned loop.
218eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  for (; aligned_beg < aligned_end; aligned_beg++)
219eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany    all |= *aligned_beg;
220eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  // Epilogue.
221eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  if ((char*)aligned_end >= beg)
222eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany    for (const char *mem = (char*)aligned_end; mem < end; mem++)
223eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany      all |= *mem;
224eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  return all == 0;
225eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany}
226eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany
227b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany}  // namespace __sanitizer
228