1351282Sdim//===-- internal_defs.h -----------------------------------------*- C++ -*-===// 2351282Sdim// 3351282Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4351282Sdim// See https://llvm.org/LICENSE.txt for license information. 5351282Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6351282Sdim// 7351282Sdim//===----------------------------------------------------------------------===// 8351282Sdim 9351282Sdim#ifndef SCUDO_INTERNAL_DEFS_H_ 10351282Sdim#define SCUDO_INTERNAL_DEFS_H_ 11351282Sdim 12351282Sdim#include "platform.h" 13351282Sdim 14351282Sdim#include <stdint.h> 15351282Sdim 16351282Sdim#ifndef SCUDO_DEBUG 17351282Sdim#define SCUDO_DEBUG 0 18351282Sdim#endif 19351282Sdim 20351282Sdim#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0])) 21351282Sdim 22351282Sdim// String related macros. 23351282Sdim 24351282Sdim#define STRINGIFY_(S) #S 25351282Sdim#define STRINGIFY(S) STRINGIFY_(S) 26351282Sdim#define CONCATENATE_(S, C) S##C 27351282Sdim#define CONCATENATE(S, C) CONCATENATE_(S, C) 28351282Sdim 29351282Sdim// Attributes & builtins related macros. 30351282Sdim 31351282Sdim#define INTERFACE __attribute__((visibility("default"))) 32351282Sdim#define WEAK __attribute__((weak)) 33351282Sdim#define ALWAYS_INLINE inline __attribute__((always_inline)) 34351282Sdim#define ALIAS(X) __attribute__((alias(X))) 35351282Sdim// Please only use the ALIGNED macro before the type. Using ALIGNED after the 36351282Sdim// variable declaration is not portable. 37351282Sdim#define ALIGNED(X) __attribute__((aligned(X))) 38351282Sdim#define FORMAT(F, A) __attribute__((format(printf, F, A))) 39351282Sdim#define NOINLINE __attribute__((noinline)) 40351282Sdim#define NORETURN __attribute__((noreturn)) 41351282Sdim#define THREADLOCAL __thread 42351282Sdim#define LIKELY(X) __builtin_expect(!!(X), 1) 43351282Sdim#define UNLIKELY(X) __builtin_expect(!!(X), 0) 44351282Sdim#if defined(__i386__) || defined(__x86_64__) 45351282Sdim// __builtin_prefetch(X) generates prefetchnt0 on x86 46351282Sdim#define PREFETCH(X) __asm__("prefetchnta (%0)" : : "r"(X)) 47351282Sdim#else 48351282Sdim#define PREFETCH(X) __builtin_prefetch(X) 49351282Sdim#endif 50351282Sdim#define UNUSED __attribute__((unused)) 51351282Sdim#define USED __attribute__((used)) 52351282Sdim#define NOEXCEPT noexcept 53351282Sdim 54351282Sdimnamespace scudo { 55351282Sdim 56351282Sdimtypedef unsigned long uptr; 57351282Sdimtypedef unsigned char u8; 58351282Sdimtypedef unsigned short u16; 59351282Sdimtypedef unsigned int u32; 60351282Sdimtypedef unsigned long long u64; 61360784Sdimtypedef signed long sptr; 62351282Sdimtypedef signed char s8; 63351282Sdimtypedef signed short s16; 64351282Sdimtypedef signed int s32; 65351282Sdimtypedef signed long long s64; 66351282Sdim 67351282Sdim// The following two functions have platform specific implementations. 68351282Sdimvoid outputRaw(const char *Buffer); 69351282Sdimvoid NORETURN die(); 70351282Sdim 71351282Sdim#define RAW_CHECK_MSG(Expr, Msg) \ 72351282Sdim do { \ 73351282Sdim if (UNLIKELY(!(Expr))) { \ 74351282Sdim outputRaw(Msg); \ 75351282Sdim die(); \ 76351282Sdim } \ 77351282Sdim } while (false) 78351282Sdim 79351282Sdim#define RAW_CHECK(Expr) RAW_CHECK_MSG(Expr, #Expr) 80351282Sdim 81351282Sdimvoid NORETURN reportCheckFailed(const char *File, int Line, 82351282Sdim const char *Condition, u64 Value1, u64 Value2); 83351282Sdim 84351282Sdim#define CHECK_IMPL(C1, Op, C2) \ 85351282Sdim do { \ 86360784Sdim scudo::u64 V1 = (scudo::u64)(C1); \ 87360784Sdim scudo::u64 V2 = (scudo::u64)(C2); \ 88351282Sdim if (UNLIKELY(!(V1 Op V2))) { \ 89360784Sdim scudo::reportCheckFailed(__FILE__, __LINE__, \ 90360784Sdim "(" #C1 ") " #Op " (" #C2 ")", V1, V2); \ 91360784Sdim scudo::die(); \ 92351282Sdim } \ 93351282Sdim } while (false) 94351282Sdim 95351282Sdim#define CHECK(A) CHECK_IMPL((A), !=, 0) 96351282Sdim#define CHECK_EQ(A, B) CHECK_IMPL((A), ==, (B)) 97351282Sdim#define CHECK_NE(A, B) CHECK_IMPL((A), !=, (B)) 98351282Sdim#define CHECK_LT(A, B) CHECK_IMPL((A), <, (B)) 99351282Sdim#define CHECK_LE(A, B) CHECK_IMPL((A), <=, (B)) 100351282Sdim#define CHECK_GT(A, B) CHECK_IMPL((A), >, (B)) 101351282Sdim#define CHECK_GE(A, B) CHECK_IMPL((A), >=, (B)) 102351282Sdim 103351282Sdim#if SCUDO_DEBUG 104351282Sdim#define DCHECK(A) CHECK(A) 105351282Sdim#define DCHECK_EQ(A, B) CHECK_EQ(A, B) 106351282Sdim#define DCHECK_NE(A, B) CHECK_NE(A, B) 107351282Sdim#define DCHECK_LT(A, B) CHECK_LT(A, B) 108351282Sdim#define DCHECK_LE(A, B) CHECK_LE(A, B) 109351282Sdim#define DCHECK_GT(A, B) CHECK_GT(A, B) 110351282Sdim#define DCHECK_GE(A, B) CHECK_GE(A, B) 111351282Sdim#else 112351282Sdim#define DCHECK(A) 113351282Sdim#define DCHECK_EQ(A, B) 114351282Sdim#define DCHECK_NE(A, B) 115351282Sdim#define DCHECK_LT(A, B) 116351282Sdim#define DCHECK_LE(A, B) 117351282Sdim#define DCHECK_GT(A, B) 118351282Sdim#define DCHECK_GE(A, B) 119351282Sdim#endif 120351282Sdim 121351282Sdim// The superfluous die() call effectively makes this macro NORETURN. 122351282Sdim#define UNREACHABLE(Msg) \ 123351282Sdim do { \ 124351282Sdim CHECK(0 && Msg); \ 125351282Sdim die(); \ 126351282Sdim } while (0) 127351282Sdim 128351282Sdim} // namespace scudo 129351282Sdim 130351282Sdim#endif // SCUDO_INTERNAL_DEFS_H_ 131