diff options
Diffstat (limited to 'lib/asan/asan_internal.h')
-rw-r--r-- | lib/asan/asan_internal.h | 210 |
1 files changed, 85 insertions, 125 deletions
diff --git a/lib/asan/asan_internal.h b/lib/asan/asan_internal.h index d0790a7..8c1f320 100644 --- a/lib/asan/asan_internal.h +++ b/lib/asan/asan_internal.h @@ -14,40 +14,49 @@ #ifndef ASAN_INTERNAL_H #define ASAN_INTERNAL_H -#if !defined(__linux__) && !defined(__APPLE__) +#include "asan_flags.h" +#include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_internal_defs.h" +#include "sanitizer_common/sanitizer_libc.h" + +#if !defined(__linux__) && !defined(__APPLE__) && !defined(_WIN32) # error "This operating system is not supported by AddressSanitizer" #endif -#include <stdint.h> // for __WORDSIZE -#include <stdlib.h> // for size_t -#include <unistd.h> // for _exit +#if defined(_WIN32) +extern "C" void* _ReturnAddress(void); +# pragma intrinsic(_ReturnAddress) +#endif // defined(_WIN32) + +#define ASAN_DEFAULT_FAILURE_EXITCODE 1 -// If __WORDSIZE was undefined by the platform, define it in terms of the -// compiler built-in __LP64__. -#ifndef __WORDSIZE -#if __LP64__ -#define __WORDSIZE 64 +#if defined(__linux__) +# define ASAN_LINUX 1 #else -#define __WORDSIZE 32 +# define ASAN_LINUX 0 #endif + +#if defined(__APPLE__) +# define ASAN_MAC 1 +#else +# define ASAN_MAC 0 #endif -#ifdef ANDROID -#include <sys/atomics.h> +#if defined(_WIN32) +# define ASAN_WINDOWS 1 +#else +# define ASAN_WINDOWS 0 #endif -#if defined(__has_feature) && __has_feature(address_sanitizer) +#define ASAN_POSIX (ASAN_LINUX || ASAN_MAC) + +#if __has_feature(address_sanitizer) # error "The AddressSanitizer run-time should not be" " instrumented by AddressSanitizer" #endif // Build-time configuration options. -// If set, sysinfo/sysinfo.h will be used to iterate over /proc/maps. -#ifndef ASAN_USE_SYSINFO -# define ASAN_USE_SYSINFO 1 -#endif - // If set, asan will install its own SEGV signal handler. #ifndef ASAN_NEEDS_SEGV # define ASAN_NEEDS_SEGV 1 @@ -64,6 +73,12 @@ # define ASAN_FLEXIBLE_MAPPING_AND_OFFSET 0 #endif +// If set, values like allocator chunk size, as well as defaults for some flags +// will be changed towards less memory overhead. +#ifndef ASAN_LOW_MEMORY +# define ASAN_LOW_MEMORY 0 +#endif + // All internal functions in asan reside inside the __asan namespace // to avoid namespace collisions with the user programs. // Seperate namespace also makes it simpler to distinguish the asan run-time @@ -74,109 +89,81 @@ class AsanThread; struct AsanStackTrace; // asan_rtl.cc -void CheckFailed(const char *cond, const char *file, int line); -void ShowStatsAndAbort(); +void NORETURN ShowStatsAndAbort(); // asan_globals.cc -bool DescribeAddrIfGlobal(uintptr_t addr); +bool DescribeAddrIfGlobal(uptr addr); +void ReplaceOperatorsNewAndDelete(); // asan_malloc_linux.cc / asan_malloc_mac.cc void ReplaceSystemMalloc(); -void OutOfMemoryMessageAndDie(const char *mem_type, size_t size); - -// asan_linux.cc / asan_mac.cc +// asan_linux.cc / asan_mac.cc / asan_win.cc void *AsanDoesNotSupportStaticLinkage(); -int AsanOpenReadonly(const char* filename); -void *AsanMmapFixedNoReserve(uintptr_t fixed_addr, size_t size); -void *AsanMmapFixedReserve(uintptr_t fixed_addr, size_t size); -void *AsanMprotect(uintptr_t fixed_addr, size_t size); -void *AsanMmapSomewhereOrDie(size_t size, const char *where); -void AsanUnmapOrDie(void *ptr, size_t size); +void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp); -ssize_t AsanRead(int fd, void *buf, size_t count); -ssize_t AsanWrite(int fd, const void *buf, size_t count); -int AsanClose(int fd); +bool AsanInterceptsSignal(int signum); +void SetAlternateSignalStack(); +void UnsetAlternateSignalStack(); +void InstallSignalHandlers(); +void AsanPlatformThreadInit(); -// asan_printf.cc -void RawWrite(const char *buffer); -int SNPrint(char *buffer, size_t length, const char *format, ...); -void Printf(const char *format, ...); -void Report(const char *format, ...); +// Wrapper for TLS/TSD. +void AsanTSDInit(void (*destructor)(void *tsd)); +void *AsanTSDGet(); +void AsanTSDSet(void *tsd); -// Don't use std::min and std::max, to minimize dependency on libstdc++. -template<class T> T Min(T a, T b) { return a < b ? a : b; } -template<class T> T Max(T a, T b) { return a > b ? a : b; } +void AppendToErrorMessageBuffer(const char *buffer); +// asan_printf.cc +void AsanPrintf(const char *format, ...); +void AsanReport(const char *format, ...); // asan_poisoning.cc // Poisons the shadow memory for "size" bytes starting from "addr". -void PoisonShadow(uintptr_t addr, size_t size, uint8_t value); +void PoisonShadow(uptr addr, uptr size, u8 value); // Poisons the shadow memory for "redzone_size" bytes starting from // "addr + size". -void PoisonShadowPartialRightRedzone(uintptr_t addr, - uintptr_t size, - uintptr_t redzone_size, - uint8_t value); - -extern size_t FLAG_quarantine_size; -extern int FLAG_demangle; -extern bool FLAG_symbolize; -extern int FLAG_v; -extern size_t FLAG_redzone; -extern int FLAG_debug; -extern bool FLAG_poison_shadow; -extern int FLAG_report_globals; -extern size_t FLAG_malloc_context_size; -extern bool FLAG_replace_str; -extern bool FLAG_replace_intrin; -extern bool FLAG_replace_cfallocator; -extern bool FLAG_fast_unwind; -extern bool FLAG_use_fake_stack; -extern size_t FLAG_max_malloc_fill_size; -extern int FLAG_exitcode; -extern bool FLAG_allow_user_poisoning; +void PoisonShadowPartialRightRedzone(uptr addr, + uptr size, + uptr redzone_size, + u8 value); + +// Platfrom-specific options. +#ifdef __APPLE__ +bool PlatformHasDifferentMemcpyAndMemmove(); +# define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE \ + (PlatformHasDifferentMemcpyAndMemmove()) +#else +# define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE true +#endif // __APPLE__ extern int asan_inited; // Used to avoid infinite recursion in __asan_init(). extern bool asan_init_is_running; +extern void (*death_callback)(void); enum LinkerInitialized { LINKER_INITIALIZED = 0 }; -#ifndef ASAN_DIE -#define ASAN_DIE _exit(FLAG_exitcode) -#endif // ASAN_DIE - -#define CHECK(cond) do { if (!(cond)) { \ - CheckFailed(#cond, __FILE__, __LINE__); \ -}}while(0) - -#define RAW_CHECK_MSG(expr, msg) do { \ - if (!(expr)) { \ - RawWrite(msg); \ - ASAN_DIE; \ - } \ -} while (0) - -#define RAW_CHECK(expr) RAW_CHECK_MSG(expr, #expr) - -#define UNIMPLEMENTED() CHECK("unimplemented" && 0) - #define ASAN_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) -const size_t kWordSize = __WORDSIZE / 8; -const size_t kWordSizeInBits = 8 * kWordSize; -const size_t kPageSizeBits = 12; -const size_t kPageSize = 1UL << kPageSizeBits; - -#define GET_CALLER_PC() (uintptr_t)__builtin_return_address(0) -#define GET_CURRENT_FRAME() (uintptr_t)__builtin_frame_address(0) +#if !defined(_WIN32) || defined(__clang__) +# define GET_CALLER_PC() (uptr)__builtin_return_address(0) +# define GET_CURRENT_FRAME() (uptr)__builtin_frame_address(0) +#else +# define GET_CALLER_PC() (uptr)_ReturnAddress() +// CaptureStackBackTrace doesn't need to know BP on Windows. +// FIXME: This macro is still used when printing error reports though it's not +// clear if the BP value is needed in the ASan reports on Windows. +# define GET_CURRENT_FRAME() (uptr)0xDEADBEEF +#endif -#define GET_BP_PC_SP \ - uintptr_t bp = GET_CURRENT_FRAME(); \ - uintptr_t pc = GET_CALLER_PC(); \ - uintptr_t local_stack; \ - uintptr_t sp = (uintptr_t)&local_stack; +#ifdef _WIN32 +# ifndef ASAN_USE_EXTERNAL_SYMBOLIZER +# define ASAN_USE_EXTERNAL_SYMBOLIZER __asan_WinSymbolize +bool __asan_WinSymbolize(const void *addr, char *out_buffer, int buffer_size); +# endif +#endif // _WIN32 // These magic values are written to shadow for better error reporting. const int kAsanHeapLeftRedzoneMagic = 0xfa; @@ -191,18 +178,8 @@ const int kAsanUserPoisonedMemoryMagic = 0xf7; const int kAsanGlobalRedzoneMagic = 0xf9; const int kAsanInternalHeapMagic = 0xfe; -static const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3; -static const uintptr_t kRetiredStackFrameMagic = 0x45E0360E; - -// --------------------------- Bit twiddling ------- {{{1 -inline bool IsPowerOfTwo(size_t x) { - return (x & (x - 1)) == 0; -} - -inline size_t RoundUpTo(size_t size, size_t boundary) { - CHECK(IsPowerOfTwo(boundary)); - return (size + boundary - 1) & ~(boundary - 1); -} +static const uptr kCurrentStackFrameMagic = 0x41B58AB3; +static const uptr kRetiredStackFrameMagic = 0x45E0360E; // -------------------------- LowLevelAllocator ----- {{{1 // A simple low-level memory allocator for internal use. @@ -211,29 +188,12 @@ class LowLevelAllocator { explicit LowLevelAllocator(LinkerInitialized) {} // 'size' must be a power of two. // Requires an external lock. - void *Allocate(size_t size); + void *Allocate(uptr size); private: char *allocated_end_; char *allocated_current_; }; -// -------------------------- Atomic ---------------- {{{1 -static inline int AtomicInc(int *a) { -#ifdef ANDROID - return __atomic_inc(a) + 1; -#else - return __sync_add_and_fetch(a, 1); -#endif -} - -static inline int AtomicDec(int *a) { -#ifdef ANDROID - return __atomic_dec(a) - 1; -#else - return __sync_add_and_fetch(a, -1); -#endif -} - } // namespace __asan #endif // ASAN_INTERNAL_H |