asan_internal.h revision 13ebae606b526399771e9cca1d6a9d24458ad0f1
11e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===-- asan_internal.h -----------------------------------------*- C++ -*-===// 21e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 31e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The LLVM Compiler Infrastructure 41e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 51e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is distributed under the University of Illinois Open Source 61e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// License. See LICENSE.TXT for details. 71e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 81e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===// 91e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker. 111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// ASan-private header which defines various general utilities. 131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===// 141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#ifndef ASAN_INTERNAL_H 151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ASAN_INTERNAL_H 161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 17d6567c5166412f6acdde851e767c26f332d51d3dKostya Serebryany#if !defined(__linux__) && !defined(__APPLE__) 18d6567c5166412f6acdde851e767c26f332d51d3dKostya Serebryany# error "This operating system is not supported by AddressSanitizer" 19d6567c5166412f6acdde851e767c26f332d51d3dKostya Serebryany#endif 20d6567c5166412f6acdde851e767c26f332d51d3dKostya Serebryany 211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <stdint.h> // for __WORDSIZE 221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <stdlib.h> // for size_t 231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <unistd.h> // for _exit 241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 254616633bb9e20f66d83bfac70c9afce1922d1eecDaniel Dunbar// If __WORDSIZE was undefined by the platform, define it in terms of the 264616633bb9e20f66d83bfac70c9afce1922d1eecDaniel Dunbar// compiler built-in __LP64__. 274616633bb9e20f66d83bfac70c9afce1922d1eecDaniel Dunbar#ifndef __WORDSIZE 284616633bb9e20f66d83bfac70c9afce1922d1eecDaniel Dunbar#if __LP64__ 294616633bb9e20f66d83bfac70c9afce1922d1eecDaniel Dunbar#define __WORDSIZE 64 304616633bb9e20f66d83bfac70c9afce1922d1eecDaniel Dunbar#else 314616633bb9e20f66d83bfac70c9afce1922d1eecDaniel Dunbar#define __WORDSIZE 32 324616633bb9e20f66d83bfac70c9afce1922d1eecDaniel Dunbar#endif 334616633bb9e20f66d83bfac70c9afce1922d1eecDaniel Dunbar#endif 344616633bb9e20f66d83bfac70c9afce1922d1eecDaniel Dunbar 351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#ifdef ANDROID 361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <sys/atomics.h> 371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#endif 381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 3913ebae606b526399771e9cca1d6a9d24458ad0f1Kostya Serebryany#if defined(__has_feature) && __has_feature(address_sanitizer) 401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany# error "The AddressSanitizer run-time should not be" 411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany " instrumented by AddressSanitizer" 421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#endif 431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 44c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany// Build-time configuration options. 45c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany 46c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany// If set, sysinfo/sysinfo.h will be used to iterate over /proc/maps. 47c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany#ifndef ASAN_USE_SYSINFO 48c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany# define ASAN_USE_SYSINFO 1 49c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany#endif 50c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany 51c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany// If set, asan will install its own SEGV signal handler. 52c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany#ifndef ASAN_NEEDS_SEGV 53c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany# define ASAN_NEEDS_SEGV 1 54c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany#endif 55c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany 56c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany// If set, asan will intercept C++ exception api call(s). 57c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany#ifndef ASAN_HAS_EXCEPTIONS 58c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany# define ASAN_HAS_EXCEPTIONS 1 59c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany#endif 60c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany 61c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany// If set, asan uses the values of SHADOW_SCALE and SHADOW_OFFSET 62c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany// provided by the instrumented objects. Otherwise constants are used. 63c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany#ifndef ASAN_FLEXIBLE_MAPPING_AND_OFFSET 64c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany# define ASAN_FLEXIBLE_MAPPING_AND_OFFSET 0 65c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany#endif 66c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany 671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// All internal functions in asan reside inside the __asan namespace 681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// to avoid namespace collisions with the user programs. 691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Seperate namespace also makes it simpler to distinguish the asan run-time 701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// functions from the instrumented user code in a profile. 711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan { 721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 731e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyclass AsanThread; 741e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystruct AsanStackTrace; 751e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 76218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany// asan_rtl.cc 771e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid CheckFailed(const char *cond, const char *file, int line); 781e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid ShowStatsAndAbort(); 791e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 80218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany// asan_globals.cc 811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanybool DescribeAddrIfGlobal(uintptr_t addr); 821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 83218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany// asan_malloc_linux.cc / asan_malloc_mac.cc 841e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid ReplaceSystemMalloc(); 851e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 86218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany// asan_linux.cc / asan_mac.cc 871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *AsanDoesNotSupportStaticLinkage(); 881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *asan_mmap(void *addr, size_t length, int prot, int flags, 891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany int fd, uint64_t offset); 901e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyssize_t asan_write(int fd, const void *buf, size_t count); 911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 92218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany// asan_printf.cc 931e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid RawWrite(const char *buffer); 941e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyint SNPrint(char *buffer, size_t length, const char *format, ...); 951e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid Printf(const char *format, ...); 961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid Report(const char *format, ...); 971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 982d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany// Don't use std::min and std::max, to minimize dependency on libstdc++. 992d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryanytemplate<class T> T Min(T a, T b) { return a < b ? a : b; } 1002d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryanytemplate<class T> T Max(T a, T b) { return a > b ? a : b; } 1012d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany 102218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany// asan_poisoning.cc 103218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany// Poisons the shadow memory for "size" bytes starting from "addr". 104218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryanyvoid PoisonShadow(uintptr_t addr, size_t size, uint8_t value); 105218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany// Poisons the shadow memory for "redzone_size" bytes starting from 106218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany// "addr + size". 107218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryanyvoid PoisonShadowPartialRightRedzone(uintptr_t addr, 108218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany uintptr_t size, 109218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany uintptr_t redzone_size, 110218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany uint8_t value); 111218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany 112218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany 1131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern size_t FLAG_quarantine_size; 1141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern int FLAG_demangle; 1151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern bool FLAG_symbolize; 1161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern int FLAG_v; 1171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern size_t FLAG_redzone; 1181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern int FLAG_debug; 1191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern bool FLAG_poison_shadow; 1201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern int FLAG_report_globals; 1211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern size_t FLAG_malloc_context_size; 1221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern bool FLAG_replace_str; 1231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern bool FLAG_replace_intrin; 1241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern bool FLAG_replace_cfallocator; 1251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern bool FLAG_fast_unwind; 1261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern bool FLAG_use_fake_stack; 1271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern size_t FLAG_max_malloc_fill_size; 1281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern int FLAG_exitcode; 1291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern bool FLAG_allow_user_poisoning; 1301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern int asan_inited; 1321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Used to avoid infinite recursion in __asan_init(). 1331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern bool asan_init_is_running; 1341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyenum LinkerInitialized { LINKER_INITIALIZED = 0 }; 1361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#ifndef ASAN_DIE 1381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ASAN_DIE _exit(FLAG_exitcode) 1391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#endif // ASAN_DIE 1401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define CHECK(cond) do { if (!(cond)) { \ 1421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany CheckFailed(#cond, __FILE__, __LINE__); \ 1431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}}while(0) 1441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define RAW_CHECK_MSG(expr, msg) do { \ 1461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (!(expr)) { \ 1471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany RawWrite(msg); \ 1481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_DIE; \ 1491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } \ 1501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} while (0) 1511e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define RAW_CHECK(expr) RAW_CHECK_MSG(expr, #expr) 1531e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define UNIMPLEMENTED() CHECK("unimplemented" && 0) 1551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ASAN_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) 1571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst size_t kWordSize = __WORDSIZE / 8; 1591e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst size_t kWordSizeInBits = 8 * kWordSize; 1601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst size_t kPageSizeBits = 12; 1611e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst size_t kPageSize = 1UL << kPageSizeBits; 1621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define GET_CALLER_PC() (uintptr_t)__builtin_return_address(0) 1641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define GET_CURRENT_FRAME() (uintptr_t)__builtin_frame_address(0) 1651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define GET_BP_PC_SP \ 1671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany uintptr_t bp = GET_CURRENT_FRAME(); \ 1681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany uintptr_t pc = GET_CALLER_PC(); \ 1691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany uintptr_t local_stack; \ 1701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany uintptr_t sp = (uintptr_t)&local_stack; 1711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// These magic values are written to shadow for better error reporting. 1731e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst int kAsanHeapLeftRedzoneMagic = 0xfa; 1741e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst int kAsanHeapRightRedzoneMagic = 0xfb; 1751e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst int kAsanHeapFreeMagic = 0xfd; 1761e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst int kAsanStackLeftRedzoneMagic = 0xf1; 1771e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst int kAsanStackMidRedzoneMagic = 0xf2; 1781e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst int kAsanStackRightRedzoneMagic = 0xf3; 1791e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst int kAsanStackPartialRedzoneMagic = 0xf4; 1801e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst int kAsanStackAfterReturnMagic = 0xf5; 1811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst int kAsanUserPoisonedMemoryMagic = 0xf7; 1821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst int kAsanGlobalRedzoneMagic = 0xf9; 1836b30e2cf0d9d471d276f91ef4bb74dbd9876f4d9Kostya Serebryanyconst int kAsanInternalHeapMagic = 0xfe; 1841e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1851e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystatic const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3; 1861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystatic const uintptr_t kRetiredStackFrameMagic = 0x45E0360E; 1871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 188b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany// -------------------------- LowLevelAllocator ----- {{{1 189b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany// A simple low-level memory allocator for internal use. 190b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryanyclass LowLevelAllocator { 191b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany public: 192b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany explicit LowLevelAllocator(LinkerInitialized) {} 193b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany // 'size' must be a power of two. 194b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany // Requires an external lock. 195b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany void *Allocate(size_t size); 196b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany private: 197b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany char *allocated_end_; 198b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany char *allocated_current_; 199b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany}; 200b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany 2011e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// -------------------------- Atomic ---------------- {{{1 2021e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystatic inline int AtomicInc(int *a) { 2031e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#ifdef ANDROID 2041e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return __atomic_inc(a) + 1; 2051e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#else 2061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return __sync_add_and_fetch(a, 1); 2071e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#endif 2081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystatic inline int AtomicDec(int *a) { 2111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#ifdef ANDROID 2121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return __atomic_dec(a) - 1; 2131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#else 2141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return __sync_add_and_fetch(a, -1); 2151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#endif 2161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} // namespace __asan 2191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#endif // ASAN_INTERNAL_H 221