asan_internal.h revision 3e81fe43798c096d1d3565596f0717b9919de4fb
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
176f0452914ec76c786eb865983793bc03b00fc7b6Alexander Potapenko#if !defined(__linux__) && !defined(__APPLE__) && !defined(_WIN32)
18d6567c5166412f6acdde851e767c26f332d51d3dKostya Serebryany# error "This operating system is not supported by AddressSanitizer"
19d6567c5166412f6acdde851e767c26f332d51d3dKostya Serebryany#endif
20d6567c5166412f6acdde851e767c26f332d51d3dKostya Serebryany
216f0452914ec76c786eb865983793bc03b00fc7b6Alexander Potapenko#include <stdlib.h>  // for size_t, uintptr_t, etc.
226f0452914ec76c786eb865983793bc03b00fc7b6Alexander Potapenko
23858220837f85db7eb5eedd5ea68603803b5eb3c9Kostya Serebryany#if defined(_WIN32)
246f0452914ec76c786eb865983793bc03b00fc7b6Alexander Potapenko// There's no <stdint.h> in Visual Studio 9, so we have to define [u]int*_t.
256f0452914ec76c786eb865983793bc03b00fc7b6Alexander Potapenkotypedef unsigned __int8  uint8_t;
266f0452914ec76c786eb865983793bc03b00fc7b6Alexander Potapenkotypedef unsigned __int16 uint16_t;
276f0452914ec76c786eb865983793bc03b00fc7b6Alexander Potapenkotypedef unsigned __int32 uint32_t;
286f0452914ec76c786eb865983793bc03b00fc7b6Alexander Potapenkotypedef unsigned __int64 uint64_t;
296f0452914ec76c786eb865983793bc03b00fc7b6Alexander Potapenkotypedef __int8           int8_t;
306f0452914ec76c786eb865983793bc03b00fc7b6Alexander Potapenkotypedef __int16          int16_t;
316f0452914ec76c786eb865983793bc03b00fc7b6Alexander Potapenkotypedef __int32          int32_t;
326f0452914ec76c786eb865983793bc03b00fc7b6Alexander Potapenkotypedef __int64          int64_t;
33adf2b036127d7e887392d9be5b02069b777ee280Alexey Samsonov
3471d3b398a39663c771918747762142215a1dc87dAlexander Potapenkoextern "C" void* _ReturnAddress(void);
3571d3b398a39663c771918747762142215a1dc87dAlexander Potapenko# pragma intrinsic(_ReturnAddress)
3671d3b398a39663c771918747762142215a1dc87dAlexander Potapenko
37adf2b036127d7e887392d9be5b02069b777ee280Alexey Samsonov# define ALIAS(x)   // TODO(timurrrr): do we need this on Windows?
38adf2b036127d7e887392d9be5b02069b777ee280Alexey Samsonov# define ALIGNED(x) __declspec(align(x))
39adf2b036127d7e887392d9be5b02069b777ee280Alexey Samsonov# define NOINLINE __declspec(noinline)
40adf2b036127d7e887392d9be5b02069b777ee280Alexey Samsonov
41adf2b036127d7e887392d9be5b02069b777ee280Alexey Samsonov# define ASAN_INTERFACE_ATTRIBUTE  // TODO(timurrrr): do we need this on Win?
42adf2b036127d7e887392d9be5b02069b777ee280Alexey Samsonov#else  // defined(_WIN32)
43858220837f85db7eb5eedd5ea68603803b5eb3c9Kostya Serebryany# include <stdint.h>  // for __WORDSIZE
44adf2b036127d7e887392d9be5b02069b777ee280Alexey Samsonov
45adf2b036127d7e887392d9be5b02069b777ee280Alexey Samsonov# define ALIAS(x) __attribute__((alias(x)))
46adf2b036127d7e887392d9be5b02069b777ee280Alexey Samsonov# define ALIGNED(x) __attribute__((aligned(x)))
47adf2b036127d7e887392d9be5b02069b777ee280Alexey Samsonov# define NOINLINE __attribute__((noinline))
48adf2b036127d7e887392d9be5b02069b777ee280Alexey Samsonov
49adf2b036127d7e887392d9be5b02069b777ee280Alexey Samsonov# define ASAN_INTERFACE_ATTRIBUTE __attribute__((visibility("default")))
50adf2b036127d7e887392d9be5b02069b777ee280Alexey Samsonov#endif  // defined(_WIN32)
511e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
524616633bb9e20f66d83bfac70c9afce1922d1eecDaniel Dunbar// If __WORDSIZE was undefined by the platform, define it in terms of the
53669f543c1400f7a1b9a48313d2f95e54f750bd4bKostya Serebryany// compiler built-ins __LP64__ and _WIN64.
544616633bb9e20f66d83bfac70c9afce1922d1eecDaniel Dunbar#ifndef __WORDSIZE
55669f543c1400f7a1b9a48313d2f95e54f750bd4bKostya Serebryany#if __LP64__ || defined(_WIN64)
564616633bb9e20f66d83bfac70c9afce1922d1eecDaniel Dunbar#define __WORDSIZE 64
574616633bb9e20f66d83bfac70c9afce1922d1eecDaniel Dunbar#else
584616633bb9e20f66d83bfac70c9afce1922d1eecDaniel Dunbar#define __WORDSIZE 32
594616633bb9e20f66d83bfac70c9afce1922d1eecDaniel Dunbar#endif
604616633bb9e20f66d83bfac70c9afce1922d1eecDaniel Dunbar#endif
614616633bb9e20f66d83bfac70c9afce1922d1eecDaniel Dunbar
623e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov#if defined(__linux__)
633e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov# define ASAN_LINUX   1
643e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov#else
653e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov# define ASAN_LINUX   0
663e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov#endif
673e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov
683e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov#if defined(__APPLE__)
693e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov# define ASAN_MAC     1
703e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov#else
713e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov# define ASAN_MAC     0
723e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov#endif
733e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov
743e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov#if defined(_WIN32)
753e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov# define ASAN_WINDOWS 1
763e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov#else
773e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov# define ASAN_WINDOWS 0
783e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov#endif
793e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov
80c8365231004cb1d956aba4164c89ea1398eadd6bAlexander Potapenko#if !defined(__has_feature)
81c8365231004cb1d956aba4164c89ea1398eadd6bAlexander Potapenko#define __has_feature(x) 0
82c8365231004cb1d956aba4164c89ea1398eadd6bAlexander Potapenko#endif
83c8365231004cb1d956aba4164c89ea1398eadd6bAlexander Potapenko
8413ebae606b526399771e9cca1d6a9d24458ad0f1Kostya Serebryany#if defined(__has_feature) && __has_feature(address_sanitizer)
851e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany# error "The AddressSanitizer run-time should not be"
861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany        " instrumented by AddressSanitizer"
871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#endif
881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
89c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany// Build-time configuration options.
90c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany
91c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany// If set, asan will install its own SEGV signal handler.
92c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany#ifndef ASAN_NEEDS_SEGV
93c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany# define ASAN_NEEDS_SEGV 1
94c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany#endif
95c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany
96c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany// If set, asan will intercept C++ exception api call(s).
97c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany#ifndef ASAN_HAS_EXCEPTIONS
98c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany# define ASAN_HAS_EXCEPTIONS 1
99c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany#endif
100c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany
101c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany// If set, asan uses the values of SHADOW_SCALE and SHADOW_OFFSET
102c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany// provided by the instrumented objects. Otherwise constants are used.
103c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany#ifndef ASAN_FLEXIBLE_MAPPING_AND_OFFSET
104c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany# define ASAN_FLEXIBLE_MAPPING_AND_OFFSET 0
105c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany#endif
106c6f2223a8772262e5e682403f2d57f0b465a98fcKostya Serebryany
1071e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// All internal functions in asan reside inside the __asan namespace
1081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// to avoid namespace collisions with the user programs.
1091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Seperate namespace also makes it simpler to distinguish the asan run-time
1101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// functions from the instrumented user code in a profile.
1111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan {
1121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyclass AsanThread;
1141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystruct AsanStackTrace;
1151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
116218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany// asan_rtl.cc
1171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid CheckFailed(const char *cond, const char *file, int line);
1181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid ShowStatsAndAbort();
1191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
120218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany// asan_globals.cc
1211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanybool DescribeAddrIfGlobal(uintptr_t addr);
1221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
123218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany// asan_malloc_linux.cc / asan_malloc_mac.cc
1241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid ReplaceSystemMalloc();
1251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
126de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryanyvoid OutOfMemoryMessageAndDie(const char *mem_type, size_t size);
127de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany
128218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany// asan_linux.cc / asan_mac.cc
1291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *AsanDoesNotSupportStaticLinkage();
130de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryanyint AsanOpenReadonly(const char* filename);
1311e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenkoconst char *AsanGetEnv(const char *name);
132de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany
133a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryanyvoid *AsanMmapFixedNoReserve(uintptr_t fixed_addr, size_t size);
134a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryanyvoid *AsanMmapFixedReserve(uintptr_t fixed_addr, size_t size);
135a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryanyvoid *AsanMprotect(uintptr_t fixed_addr, size_t size);
136de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryanyvoid *AsanMmapSomewhereOrDie(size_t size, const char *where);
137de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryanyvoid AsanUnmapOrDie(void *ptr, size_t size);
138de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany
139ef14ff6512d7b2e20aa3206dff820b5f90285420Kostya Serebryanyvoid AsanDisableCoreDumper();
1409107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryanyvoid GetPcSpBp(void *context, uintptr_t *pc, uintptr_t *sp, uintptr_t *bp);
141ef14ff6512d7b2e20aa3206dff820b5f90285420Kostya Serebryany
1420ecf5eb729dd81a43f8585cb438d3cb2a35899edKostya Serebryanysize_t AsanRead(int fd, void *buf, size_t count);
1430ecf5eb729dd81a43f8585cb438d3cb2a35899edKostya Serebryanysize_t AsanWrite(int fd, const void *buf, size_t count);
144de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryanyint AsanClose(int fd);
1451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1464803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanybool AsanInterceptsSignal(int signum);
147a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryanyvoid InstallSignalHandlers();
1480ecf5eb729dd81a43f8585cb438d3cb2a35899edKostya Serebryanyint GetPid();
149cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryanyuintptr_t GetThreadSelf();
150dde7c33df06a9a0a8056f2357d764a10512206eeKostya Serebryanyint AtomicInc(int *a);
151cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany
152cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany// Wrapper for TLS/TSD.
153f58f998066db0231e521169d2f50af439ceecb49Kostya Serebryanyvoid AsanTSDInit(void (*destructor)(void *tsd));
154cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryanyvoid *AsanTSDGet();
155cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryanyvoid AsanTSDSet(void *tsd);
1564803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
157df499b44de81fc757a789878f07fcaf19ebb0016Kostya Serebryany// Opens the file 'file_name" and reads up to 'max_len' bytes.
158df499b44de81fc757a789878f07fcaf19ebb0016Kostya Serebryany// The resulting buffer is mmaped and stored in '*buff'.
159df499b44de81fc757a789878f07fcaf19ebb0016Kostya Serebryany// The size of the mmaped region is stored in '*buff_size',
1600ecf5eb729dd81a43f8585cb438d3cb2a35899edKostya Serebryany// Returns the number of read bytes or 0 if file can not be opened.
1610ecf5eb729dd81a43f8585cb438d3cb2a35899edKostya Serebryanysize_t ReadFileToBuffer(const char *file_name, char **buff,
1620ecf5eb729dd81a43f8585cb438d3cb2a35899edKostya Serebryany                        size_t *buff_size, size_t max_len);
163df499b44de81fc757a789878f07fcaf19ebb0016Kostya Serebryany
164218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany// asan_printf.cc
1651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid RawWrite(const char *buffer);
166a0935fa0ef02e47408996c25dac00b5f8a6b1406Alexander Potapenkoint SNPrintf(char *buffer, size_t length, const char *format, ...);
1671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid Printf(const char *format, ...);
168df499b44de81fc757a789878f07fcaf19ebb0016Kostya Serebryanyint SScanf(const char *str, const char *format, ...);
1691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid Report(const char *format, ...);
1701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1712d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany// Don't use std::min and std::max, to minimize dependency on libstdc++.
1722d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryanytemplate<class T> T Min(T a, T b) { return a < b ? a : b; }
1732d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryanytemplate<class T> T Max(T a, T b) { return a > b ? a : b; }
1742d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany
175218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany// asan_poisoning.cc
176218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany// Poisons the shadow memory for "size" bytes starting from "addr".
177218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryanyvoid PoisonShadow(uintptr_t addr, size_t size, uint8_t value);
178218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany// Poisons the shadow memory for "redzone_size" bytes starting from
179218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany// "addr + size".
180218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryanyvoid PoisonShadowPartialRightRedzone(uintptr_t addr,
181218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany                                     uintptr_t size,
182218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany                                     uintptr_t redzone_size,
183218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany                                     uint8_t value);
184218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany
1851e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern size_t FLAG_quarantine_size;
1861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern int    FLAG_demangle;
1871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern bool   FLAG_symbolize;
1881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern int    FLAG_v;
1891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern size_t FLAG_redzone;
1901e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern int    FLAG_debug;
1911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern bool   FLAG_poison_shadow;
1921e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern int    FLAG_report_globals;
1931e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern size_t FLAG_malloc_context_size;
1941e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern bool   FLAG_replace_str;
1951e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern bool   FLAG_replace_intrin;
1961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern bool   FLAG_replace_cfallocator;
1971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern bool   FLAG_fast_unwind;
1981e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern bool   FLAG_use_fake_stack;
1991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern size_t FLAG_max_malloc_fill_size;
2001e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern int    FLAG_exitcode;
2011e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern bool   FLAG_allow_user_poisoning;
202cb00d134727c322e2f26298912f77e10be46aefeKostya Serebryanyextern int    FLAG_sleep_before_dying;
2034803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern bool   FLAG_handle_segv;
2041e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2051e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern int asan_inited;
2061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Used to avoid infinite recursion in __asan_init().
2071e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern bool asan_init_is_running;
2081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyenum LinkerInitialized { LINKER_INITIALIZED = 0 };
2101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2110ecf5eb729dd81a43f8585cb438d3cb2a35899edKostya Serebryanyvoid AsanDie();
2121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define CHECK(cond) do { if (!(cond)) { \
2141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  CheckFailed(#cond, __FILE__, __LINE__); \
2151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}}while(0)
2161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define RAW_CHECK_MSG(expr, msg) do { \
2181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (!(expr)) { \
2191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    RawWrite(msg); \
2200ecf5eb729dd81a43f8585cb438d3cb2a35899edKostya Serebryany    AsanDie(); \
2211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  } \
2221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} while (0)
2231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define RAW_CHECK(expr) RAW_CHECK_MSG(expr, #expr)
2251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define UNIMPLEMENTED() CHECK("unimplemented" && 0)
2271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ASAN_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
2291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst size_t kWordSize = __WORDSIZE / 8;
2311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst size_t kWordSizeInBits = 8 * kWordSize;
2321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst size_t kPageSizeBits = 12;
2331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst size_t kPageSize = 1UL << kPageSizeBits;
2341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2356f0452914ec76c786eb865983793bc03b00fc7b6Alexander Potapenko#ifndef _WIN32
2363e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanovconst size_t kMmapGranularity = kPageSize;
2371c83ae34f32737a203c66e9d9c419f821a0db02fKostya Serebryany# define GET_CALLER_PC() (uintptr_t)__builtin_return_address(0)
2381c83ae34f32737a203c66e9d9c419f821a0db02fKostya Serebryany# define GET_CURRENT_FRAME() (uintptr_t)__builtin_frame_address(0)
2396f0452914ec76c786eb865983793bc03b00fc7b6Alexander Potapenko#else
2403e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanovconst size_t kMmapGranularity = 1UL << 16;
2411c83ae34f32737a203c66e9d9c419f821a0db02fKostya Serebryany# define GET_CALLER_PC() (uintptr_t)_ReturnAddress()
2421c83ae34f32737a203c66e9d9c419f821a0db02fKostya Serebryany// CaptureStackBackTrace doesn't need to know BP on Windows.
2431c83ae34f32737a203c66e9d9c419f821a0db02fKostya Serebryany// FIXME: This macro is still used when printing error reports though it's not
2441c83ae34f32737a203c66e9d9c419f821a0db02fKostya Serebryany// clear if the BP value is needed in the ASan reports on Windows.
2451c83ae34f32737a203c66e9d9c419f821a0db02fKostya Serebryany# define GET_CURRENT_FRAME() (uintptr_t)0xDEADBEEF
2463e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov
2473e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov# ifndef ASAN_USE_EXTERNAL_SYMBOLIZER
2483e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov#  define ASAN_USE_EXTERNAL_SYMBOLIZER __asan::WinSymbolize
2493e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanovbool WinSymbolize(const void *addr, char *out_buffer, int buffer_size);
2503e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov# endif
2516f0452914ec76c786eb865983793bc03b00fc7b6Alexander Potapenko#endif
2521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2531e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define GET_BP_PC_SP \
2541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  uintptr_t bp = GET_CURRENT_FRAME();              \
2551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  uintptr_t pc = GET_CALLER_PC();                  \
2561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  uintptr_t local_stack;                           \
2571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  uintptr_t sp = (uintptr_t)&local_stack;
2581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2591e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// These magic values are written to shadow for better error reporting.
2601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst int kAsanHeapLeftRedzoneMagic = 0xfa;
2611e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst int kAsanHeapRightRedzoneMagic = 0xfb;
2621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst int kAsanHeapFreeMagic = 0xfd;
2631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst int kAsanStackLeftRedzoneMagic = 0xf1;
2641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst int kAsanStackMidRedzoneMagic = 0xf2;
2651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst int kAsanStackRightRedzoneMagic = 0xf3;
2661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst int kAsanStackPartialRedzoneMagic = 0xf4;
2671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst int kAsanStackAfterReturnMagic = 0xf5;
2681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst int kAsanUserPoisonedMemoryMagic = 0xf7;
2691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst int kAsanGlobalRedzoneMagic = 0xf9;
2706b30e2cf0d9d471d276f91ef4bb74dbd9876f4d9Kostya Serebryanyconst int kAsanInternalHeapMagic = 0xfe;
2711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystatic const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3;
2731e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystatic const uintptr_t kRetiredStackFrameMagic = 0x45E0360E;
2741e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
275de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany// --------------------------- Bit twiddling ------- {{{1
276de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryanyinline bool IsPowerOfTwo(size_t x) {
277de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany  return (x & (x - 1)) == 0;
278de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany}
279de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany
280de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryanyinline size_t RoundUpTo(size_t size, size_t boundary) {
281de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany  CHECK(IsPowerOfTwo(boundary));
282de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany  return (size + boundary - 1) & ~(boundary - 1);
283de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany}
284de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany
285b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany// -------------------------- LowLevelAllocator ----- {{{1
286b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany// A simple low-level memory allocator for internal use.
287b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryanyclass LowLevelAllocator {
288b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany public:
289b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany  explicit LowLevelAllocator(LinkerInitialized) {}
290b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany  // 'size' must be a power of two.
291b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany  // Requires an external lock.
292b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany  void *Allocate(size_t size);
293b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany private:
294b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany  char *allocated_end_;
295b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany  char *allocated_current_;
296b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany};
297b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany
2981e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}  // namespace __asan
2991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
3001e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#endif  // ASAN_INTERNAL_H
301