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