1 //===-- sanitizer_internal_defs.h -------------------------------*- C++ -*-===// 2 // 3 // This file is distributed under the University of Illinois Open Source 4 // License. See LICENSE.TXT for details. 5 // 6 //===----------------------------------------------------------------------===// 7 // 8 // This file is shared between AddressSanitizer and ThreadSanitizer. 9 // It contains macro used in run-time libraries code. 10 //===----------------------------------------------------------------------===// 11 #ifndef SANITIZER_DEFS_H 12 #define SANITIZER_DEFS_H 13 14 #if defined(_WIN32) 15 // FIXME find out what we need on Windows. __declspec(dllexport) ? 16 # define SANITIZER_INTERFACE_ATTRIBUTE 17 # define SANITIZER_WEAK_ATTRIBUTE 18 #elif defined(SANITIZER_GO) 19 # define SANITIZER_INTERFACE_ATTRIBUTE 20 # define SANITIZER_WEAK_ATTRIBUTE 21 #else 22 # define SANITIZER_INTERFACE_ATTRIBUTE __attribute__((visibility("default"))) 23 # define SANITIZER_WEAK_ATTRIBUTE __attribute__((weak)) 24 #endif 25 26 #ifdef __linux__ 27 # define SANITIZER_SUPPORTS_WEAK_HOOKS 1 28 #else 29 # define SANITIZER_SUPPORTS_WEAK_HOOKS 0 30 #endif 31 32 // GCC does not understand __has_feature 33 #if !defined(__has_feature) 34 # define __has_feature(x) 0 35 #endif 36 37 // For portability reasons we do not include stddef.h, stdint.h or any other 38 // system header, but we do need some basic types that are not defined 39 // in a portable way by the language itself. 40 namespace __sanitizer { 41 42 #if defined(_WIN64) 43 // 64-bit Windows uses LLP64 data model. 44 typedef unsigned long long uptr; // NOLINT 45 typedef signed long long sptr; // NOLINT 46 #else 47 typedef unsigned long uptr; // NOLINT 48 typedef signed long sptr; // NOLINT 49 #endif // defined(_WIN64) 50 #if defined(__x86_64__) 51 // Since x32 uses ILP32 data model in 64-bit hardware mode, we must use 52 // 64-bit pointer to unwind stack frame. 53 typedef unsigned long long uhwptr; // NOLINT 54 #else 55 typedef uptr uhwptr; // NOLINT 56 #endif 57 typedef unsigned char u8; 58 typedef unsigned short u16; // NOLINT 59 typedef unsigned int u32; 60 typedef unsigned long long u64; // NOLINT 61 typedef signed char s8; 62 typedef signed short s16; // NOLINT 63 typedef signed int s32; 64 typedef signed long long s64; // NOLINT 65 typedef int fd_t; 66 67 } // namespace __sanitizer 68 69 extern "C" { 70 // Tell the tools to write their reports to "path.<pid>" instead of stderr. 71 void __sanitizer_set_report_path(const char *path) 72 SANITIZER_INTERFACE_ATTRIBUTE; 73 74 // Tell the tools to write their reports to given file descriptor instead of 75 // stderr. 76 void __sanitizer_set_report_fd(int fd) 77 SANITIZER_INTERFACE_ATTRIBUTE; 78 79 // Notify the tools that the sandbox is going to be turned on. The reserved 80 // parameter will be used in the future to hold a structure with functions 81 // that the tools may call to bypass the sandbox. 82 void __sanitizer_sandbox_on_notify(void *reserved) 83 SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE; 84 85 // This function is called by the tool when it has just finished reporting 86 // an error. 'error_summary' is a one-line string that summarizes 87 // the error message. This function can be overridden by the client. 88 void __sanitizer_report_error_summary(const char *error_summary) 89 SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE; 90 } // extern "C" 91 92 93 using namespace __sanitizer; // NOLINT 94 // ----------- ATTENTION ------------- 95 // This header should NOT include any other headers to avoid portability issues. 96 97 // Common defs. 98 #define INLINE static inline 99 #define INTERFACE_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE 100 #define WEAK SANITIZER_WEAK_ATTRIBUTE 101 102 // Platform-specific defs. 103 #if defined(_MSC_VER) 104 # define ALWAYS_INLINE __declspec(forceinline) 105 // FIXME(timurrrr): do we need this on Windows? 106 # define ALIAS(x) 107 # define ALIGNED(x) __declspec(align(x)) 108 # define FORMAT(f, a) 109 # define NOINLINE __declspec(noinline) 110 # define NORETURN __declspec(noreturn) 111 # define THREADLOCAL __declspec(thread) 112 # define NOTHROW 113 # define LIKELY(x) (x) 114 # define UNLIKELY(x) (x) 115 # define UNUSED 116 # define USED 117 # define PREFETCH(x) /* _mm_prefetch(x, _MM_HINT_NTA) */ 118 #else // _MSC_VER 119 # ifdef __NetBSD__ 120 # define ALWAYS_INLINE // __attribute__((always_inline)) 121 # else 122 # define ALWAYS_INLINE __attribute__((always_inline)) 123 # endif 124 # define ALIAS(x) __attribute__((alias(x))) 125 # define ALIGNED(x) __attribute__((aligned(x))) 126 # define FORMAT(f, a) __attribute__((format(printf, f, a))) 127 # define NOINLINE __attribute__((noinline)) 128 # define NORETURN __attribute__((noreturn)) 129 # define THREADLOCAL __thread 130 # define NOTHROW throw() 131 # define LIKELY(x) __builtin_expect(!!(x), 1) 132 # define UNLIKELY(x) __builtin_expect(!!(x), 0) 133 # define UNUSED __attribute__((unused)) 134 # define USED __attribute__((used)) 135 # if defined(__i386__) || defined(__x86_64__) 136 // __builtin_prefetch(x) generates prefetchnt0 on x86 137 # define PREFETCH(x) __asm__("prefetchnta (%0)" : : "r" (x)) 138 # else 139 # define PREFETCH(x) __builtin_prefetch(x) 140 # endif 141 #endif // _MSC_VER 142 143 #if defined(_WIN32) 144 typedef unsigned long DWORD; // NOLINT 145 typedef DWORD thread_return_t; 146 # define THREAD_CALLING_CONV __stdcall 147 #else // _WIN32 148 typedef void* thread_return_t; 149 # define THREAD_CALLING_CONV 150 #endif // _WIN32 151 typedef thread_return_t (THREAD_CALLING_CONV *thread_callback_t)(void* arg); 152 153 #if __LP64__ || defined(_WIN64) 154 # define SANITIZER_WORDSIZE 64 155 #else 156 # define SANITIZER_WORDSIZE 32 157 #endif 158 159 // NOTE: Functions below must be defined in each run-time. 160 namespace __sanitizer { 161 void NORETURN Die(); 162 void NORETURN CheckFailed(const char *file, int line, const char *cond, 163 u64 v1, u64 v2); 164 } // namespace __sanitizer 165 166 // Check macro 167 #define RAW_CHECK_MSG(expr, msg) do { \ 168 if (!(expr)) { \ 169 RawWrite(msg); \ 170 Die(); \ 171 } \ 172 } while (0) 173 174 #define RAW_CHECK(expr) RAW_CHECK_MSG(expr, #expr) 175 176 #define CHECK_IMPL(c1, op, c2) \ 177 do { \ 178 __sanitizer::u64 v1 = (u64)(c1); \ 179 __sanitizer::u64 v2 = (u64)(c2); \ 180 if (!(v1 op v2)) \ 181 __sanitizer::CheckFailed(__FILE__, __LINE__, \ 182 "(" #c1 ") " #op " (" #c2 ")", v1, v2); \ 183 } while (false) \ 184 /**/ 185 186 #define CHECK(a) CHECK_IMPL((a), !=, 0) 187 #define CHECK_EQ(a, b) CHECK_IMPL((a), ==, (b)) 188 #define CHECK_NE(a, b) CHECK_IMPL((a), !=, (b)) 189 #define CHECK_LT(a, b) CHECK_IMPL((a), <, (b)) 190 #define CHECK_LE(a, b) CHECK_IMPL((a), <=, (b)) 191 #define CHECK_GT(a, b) CHECK_IMPL((a), >, (b)) 192 #define CHECK_GE(a, b) CHECK_IMPL((a), >=, (b)) 193 194 #if TSAN_DEBUG 195 #define DCHECK(a) CHECK(a) 196 #define DCHECK_EQ(a, b) CHECK_EQ(a, b) 197 #define DCHECK_NE(a, b) CHECK_NE(a, b) 198 #define DCHECK_LT(a, b) CHECK_LT(a, b) 199 #define DCHECK_LE(a, b) CHECK_LE(a, b) 200 #define DCHECK_GT(a, b) CHECK_GT(a, b) 201 #define DCHECK_GE(a, b) CHECK_GE(a, b) 202 #else 203 #define DCHECK(a) 204 #define DCHECK_EQ(a, b) 205 #define DCHECK_NE(a, b) 206 #define DCHECK_LT(a, b) 207 #define DCHECK_LE(a, b) 208 #define DCHECK_GT(a, b) 209 #define DCHECK_GE(a, b) 210 #endif 211 212 #define UNREACHABLE(msg) do { \ 213 CHECK(0 && msg); \ 214 Die(); \ 215 } while (0) 216 217 #define UNIMPLEMENTED() UNREACHABLE("unimplemented") 218 219 #define COMPILER_CHECK(pred) IMPL_COMPILER_ASSERT(pred, __LINE__) 220 221 #define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) 222 223 #define IMPL_PASTE(a, b) a##b 224 #define IMPL_COMPILER_ASSERT(pred, line) \ 225 typedef char IMPL_PASTE(assertion_failed_##_, line)[2*(int)(pred)-1] 226 227 // Limits for integral types. We have to redefine it in case we don't 228 // have stdint.h (like in Visual Studio 9). 229 #undef __INT64_C 230 #undef __UINT64_C 231 #if SANITIZER_WORDSIZE == 64 232 # define __INT64_C(c) c ## L 233 # define __UINT64_C(c) c ## UL 234 #else 235 # define __INT64_C(c) c ## LL 236 # define __UINT64_C(c) c ## ULL 237 #endif // SANITIZER_WORDSIZE == 64 238 #undef INT32_MIN 239 #define INT32_MIN (-2147483647-1) 240 #undef INT32_MAX 241 #define INT32_MAX (2147483647) 242 #undef UINT32_MAX 243 #define UINT32_MAX (4294967295U) 244 #undef INT64_MIN 245 #define INT64_MIN (-__INT64_C(9223372036854775807)-1) 246 #undef INT64_MAX 247 #define INT64_MAX (__INT64_C(9223372036854775807)) 248 #undef UINT64_MAX 249 #define UINT64_MAX (__UINT64_C(18446744073709551615)) 250 251 enum LinkerInitialized { LINKER_INITIALIZED = 0 }; 252 253 #if !defined(_MSC_VER) || defined(__clang__) 254 # define GET_CALLER_PC() (uptr)__builtin_return_address(0) 255 # define GET_CURRENT_FRAME() (uptr)__builtin_frame_address(0) 256 #else 257 extern "C" void* _ReturnAddress(void); 258 # pragma intrinsic(_ReturnAddress) 259 # define GET_CALLER_PC() (uptr)_ReturnAddress() 260 // CaptureStackBackTrace doesn't need to know BP on Windows. 261 // FIXME: This macro is still used when printing error reports though it's not 262 // clear if the BP value is needed in the ASan reports on Windows. 263 # define GET_CURRENT_FRAME() (uptr)0xDEADBEEF 264 #endif 265 266 #define HANDLE_EINTR(res, f) { \ 267 do { \ 268 res = (f); \ 269 } while (res == -1 && errno == EINTR); \ 270 } 271 272 #endif // SANITIZER_DEFS_H 273