sanitizer_libc.cc revision 2d1fdb26e458c4ddc04155c1d421bced3ba90cd0
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 192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Make the compiler think that something is going on there. 202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic inline void break_optimization(void *arg) { 212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if _MSC_VER 222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // FIXME: make sure this is actually enough. 232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines __asm; 242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else 252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines __asm__ __volatile__("" : : "r" (arg) : "memory"); 262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 29c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovs64 internal_atoll(const char *nptr) { 30c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov return internal_simple_strtoll(nptr, (char**)0, 10); 31b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany} 32b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany 331f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonovvoid *internal_memchr(const void *s, int c, uptr n) { 341f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov const char* t = (char*)s; 351f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov for (uptr i = 0; i < n; ++i, ++t) 361f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov if (*t == c) 371f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov return (void*)t; 381f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov return 0; 391f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov} 401f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov 41327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonovint internal_memcmp(const void* s1, const void* s2, uptr n) { 42327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov const char* t1 = (char*)s1; 43327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov const char* t2 = (char*)s2; 44327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov for (uptr i = 0; i < n; ++i, ++t1, ++t2) 45327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov if (*t1 != *t2) 46327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov return *t1 < *t2 ? -1 : 1; 47327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov return 0; 48327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov} 49327c1c17d9557ed8b197f732c8a070fd6ba821b5Alexey Samsonov 50f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonovvoid *internal_memcpy(void *dest, const void *src, uptr n) { 51f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov char *d = (char*)dest; 52f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov char *s = (char*)src; 53f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov for (uptr i = 0; i < n; ++i) 54f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov d[i] = s[i]; 55f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov return dest; 56f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov} 57f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov 58f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenkovoid *internal_memmove(void *dest, const void *src, uptr n) { 59f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko char *d = (char*)dest; 60f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko char *s = (char*)src; 6171a8273b3729ffaef40d178739f48dc38417d86aAlexander Potapenko sptr i, signed_n = (sptr)n; 6271a8273b3729ffaef40d178739f48dc38417d86aAlexander Potapenko CHECK_GE(signed_n, 0); 63f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko if (d < s) { 6471a8273b3729ffaef40d178739f48dc38417d86aAlexander Potapenko for (i = 0; i < signed_n; ++i) 65f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko d[i] = s[i]; 66f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko } else { 6771a8273b3729ffaef40d178739f48dc38417d86aAlexander Potapenko if (d > s && signed_n > 0) 6871a8273b3729ffaef40d178739f48dc38417d86aAlexander Potapenko for (i = signed_n - 1; i >= 0 ; --i) { 695759d92e99e2b7adcc46a8729f16023208dd8f37Kostya Serebryany d[i] = s[i]; 70f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko } 71f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko } 72f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko return dest; 73f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko} 74f1673e61768cb08d488a75584b61bfdf24ffdac1Alexander Potapenko 752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Semi-fast bzero for 16-aligned data. Still far from peak performance. 762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid internal_bzero_aligned16(void *s, uptr n) { 772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines struct S16 { u64 a, b; } ALIGNED(16); 782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines CHECK_EQ((reinterpret_cast<uptr>(s) | n) & 15, 0); 792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines for (S16 *p = reinterpret_cast<S16*>(s), *end = p + n / 16; p < end; p++) { 802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines p->a = p->b = 0; 812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines break_optimization(0); // Make sure this does not become memset. 822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 854fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonovvoid *internal_memset(void* s, int c, uptr n) { 864fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov // The next line prevents Clang from making a call to memset() instead of the 874fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov // loop below. 884fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov // FIXME: building the runtime with -ffreestanding is a better idea. However 894fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov // there currently are linktime problems due to PR12396. 904fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov char volatile *t = (char*)s; 914fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov for (uptr i = 0; i < n; ++i, ++t) { 924fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov *t = c; 934fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov } 944fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov return s; 954fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov} 964fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov 97251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonovuptr internal_strcspn(const char *s, const char *reject) { 98251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov uptr i; 99251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov for (i = 0; s[i]; i++) { 100251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov if (internal_strchr(reject, s[i]) != 0) 101251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov return i; 102251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov } 103251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov return i; 104251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov} 105251134734f71a7e21a7bd17bc7b5821f07c803b2Alexey Samsonov 106f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonovchar* internal_strdup(const char *s) { 107f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov uptr len = internal_strlen(s); 108f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov char *s2 = (char*)InternalAlloc(len + 1); 109f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov internal_memcpy(s2, s, len); 110f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov s2[len] = 0; 111f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov return s2; 112f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov} 113f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov 114c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonovint internal_strcmp(const char *s1, const char *s2) { 115c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov while (true) { 116c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov unsigned c1 = *s1; 117c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov unsigned c2 = *s2; 118c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov if (c1 != c2) return (c1 < c2) ? -1 : 1; 119c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov if (c1 == 0) break; 120c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov s1++; 121c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov s2++; 122c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov } 123c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov return 0; 124c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov} 125c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov 1268cd0df78c317106be477c5496f481af0563a5208Alexey Samsonovint internal_strncmp(const char *s1, const char *s2, uptr n) { 1278cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov for (uptr i = 0; i < n; i++) { 1288cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov unsigned c1 = *s1; 1298cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov unsigned c2 = *s2; 1308cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov if (c1 != c2) return (c1 < c2) ? -1 : 1; 1318cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov if (c1 == 0) break; 1328cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov s1++; 1338cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov s2++; 1348cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov } 1358cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov return 0; 1368cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov} 1378cd0df78c317106be477c5496f481af0563a5208Alexey Samsonov 13888207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonovchar* internal_strchr(const char *s, int c) { 13988207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov while (true) { 14088207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov if (*s == (char)c) 14188207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov return (char*)s; 14288207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov if (*s == 0) 14388207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov return 0; 14488207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov s++; 14588207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov } 14688207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov} 14788207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov 14872870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonovchar *internal_strchrnul(const char *s, int c) { 14972870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov char *res = internal_strchr(s, c); 15072870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov if (!res) 15172870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov res = (char*)s + internal_strlen(s); 15272870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov return res; 15372870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov} 15472870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov 1554fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonovchar *internal_strrchr(const char *s, int c) { 1564fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov const char *res = 0; 1574fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov for (uptr i = 0; s[i]; i++) { 1584fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov if (s[i] == c) res = s + i; 1594fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov } 1604fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov return (char*)res; 1614fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov} 1624fac1482179c6bfd84fa129560caa43f341c7336Alexey Samsonov 163230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonovuptr internal_strlen(const char *s) { 164230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov uptr i = 0; 165230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov while (s[i]) i++; 166230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov return i; 167230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov} 168230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov 169c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovchar *internal_strncat(char *dst, const char *src, uptr n) { 170c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov uptr len = internal_strlen(dst); 171c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov uptr i; 172c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov for (i = 0; i < n && src[i]; i++) 173c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov dst[len + i] = src[i]; 174c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov dst[len + i] = 0; 175c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov return dst; 176c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov} 177c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov 1783836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonovchar *internal_strncpy(char *dst, const char *src, uptr n) { 1793836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov uptr i; 1803836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov for (i = 0; i < n && src[i]; i++) 1813836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov dst[i] = src[i]; 18298432980845d10da7ea1aa8fc4d330a763d193edWill Dietz internal_memset(dst + i, '\0', n - i); 1833836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov return dst; 1843836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov} 1853836ff2733d40e1182e301ef7de3eff9469777aeAlexey Samsonov 186c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovuptr internal_strnlen(const char *s, uptr maxlen) { 187c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov uptr i = 0; 188c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov while (i < maxlen && s[i]) i++; 189c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov return i; 190c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov} 191c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov 192c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovchar *internal_strstr(const char *haystack, const char *needle) { 193c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov // This is O(N^2), but we are not using it in hot places. 194c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov uptr len1 = internal_strlen(haystack); 195c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov uptr len2 = internal_strlen(needle); 196c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov if (len1 < len2) return 0; 197c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov for (uptr pos = 0; pos <= len1 - len2; pos++) { 198c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov if (internal_memcmp(haystack + pos, needle, len2) == 0) 199c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov return (char*)haystack + pos; 200c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov } 201c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov return 0; 202c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov} 203c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov 204c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovs64 internal_simple_strtoll(const char *nptr, char **endptr, int base) { 2056985085c4860bf945358f227ddba26511ae770e9Kostya Serebryany CHECK_EQ(base, 10); 206c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov while (IsSpace(*nptr)) nptr++; 207c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov int sgn = 1; 208c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov u64 res = 0; 209c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov bool have_digits = false; 210c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov char *old_nptr = (char*)nptr; 211c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov if (*nptr == '+') { 212c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov sgn = 1; 213c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov nptr++; 214c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov } else if (*nptr == '-') { 215c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov sgn = -1; 216c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov nptr++; 217c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov } 218c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov while (IsDigit(*nptr)) { 219c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov res = (res <= UINT64_MAX / 10) ? res * 10 : UINT64_MAX; 220c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov int digit = ((*nptr) - '0'); 221c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov res = (res <= UINT64_MAX - digit) ? res + digit : UINT64_MAX; 222c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov have_digits = true; 223c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov nptr++; 224c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov } 225c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov if (endptr != 0) { 226c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov *endptr = (have_digits) ? (char*)nptr : old_nptr; 227c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov } 228c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov if (sgn > 0) { 229c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov return (s64)(Min((u64)INT64_MAX, res)); 230c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov } else { 231c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov return (res > INT64_MAX) ? INT64_MIN : ((s64)res * -1); 232c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov } 233c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov} 234c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov 235eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryanybool mem_is_zero(const char *beg, uptr size) { 2368ceeec4f343768b199e7c891865029360b7225dcDmitry Vyukov CHECK_LE(size, 1ULL << FIRST_32_SECOND_64(30, 40)); // Sanity check. 237eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany const char *end = beg + size; 238eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany uptr *aligned_beg = (uptr *)RoundUpTo((uptr)beg, sizeof(uptr)); 239eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany uptr *aligned_end = (uptr *)RoundDownTo((uptr)end, sizeof(uptr)); 240eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany uptr all = 0; 241eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany // Prologue. 242eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany for (const char *mem = beg; mem < (char*)aligned_beg && mem < end; mem++) 243eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany all |= *mem; 244eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany // Aligned loop. 245eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany for (; aligned_beg < aligned_end; aligned_beg++) 246eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany all |= *aligned_beg; 247eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany // Epilogue. 248eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany if ((char*)aligned_end >= beg) 249eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany for (const char *mem = (char*)aligned_end; mem < end; mem++) 250eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany all |= *mem; 251eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany return all == 0; 252eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany} 253eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany 254b3cedf98a3c8545da2234c2d35cb5d687984035fKostya Serebryany} // namespace __sanitizer 255