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