1//===-- internal_defs.h -----------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef SCUDO_INTERNAL_DEFS_H_
10#define SCUDO_INTERNAL_DEFS_H_
11
12#include "platform.h"
13
14#include <stdint.h>
15
16#ifndef SCUDO_DEBUG
17#define SCUDO_DEBUG 0
18#endif
19
20#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
21
22// String related macros.
23
24#define STRINGIFY_(S) #S
25#define STRINGIFY(S) STRINGIFY_(S)
26#define CONCATENATE_(S, C) S##C
27#define CONCATENATE(S, C) CONCATENATE_(S, C)
28
29// Attributes & builtins related macros.
30
31#define INTERFACE __attribute__((visibility("default")))
32#define WEAK __attribute__((weak))
33#define ALWAYS_INLINE inline __attribute__((always_inline))
34#define ALIAS(X) __attribute__((alias(X)))
35// Please only use the ALIGNED macro before the type. Using ALIGNED after the
36// variable declaration is not portable.
37#define ALIGNED(X) __attribute__((aligned(X)))
38#define FORMAT(F, A) __attribute__((format(printf, F, A)))
39#define NOINLINE __attribute__((noinline))
40#define NORETURN __attribute__((noreturn))
41#define THREADLOCAL __thread
42#define LIKELY(X) __builtin_expect(!!(X), 1)
43#define UNLIKELY(X) __builtin_expect(!!(X), 0)
44#if defined(__i386__) || defined(__x86_64__)
45// __builtin_prefetch(X) generates prefetchnt0 on x86
46#define PREFETCH(X) __asm__("prefetchnta (%0)" : : "r"(X))
47#else
48#define PREFETCH(X) __builtin_prefetch(X)
49#endif
50#define UNUSED __attribute__((unused))
51#define USED __attribute__((used))
52#define NOEXCEPT noexcept
53
54namespace scudo {
55
56typedef unsigned long uptr;
57typedef unsigned char u8;
58typedef unsigned short u16;
59typedef unsigned int u32;
60typedef unsigned long long u64;
61typedef signed long sptr;
62typedef signed char s8;
63typedef signed short s16;
64typedef signed int s32;
65typedef signed long long s64;
66
67// The following two functions have platform specific implementations.
68void outputRaw(const char *Buffer);
69void NORETURN die();
70
71#define RAW_CHECK_MSG(Expr, Msg)                                               \
72  do {                                                                         \
73    if (UNLIKELY(!(Expr))) {                                                   \
74      outputRaw(Msg);                                                          \
75      die();                                                                   \
76    }                                                                          \
77  } while (false)
78
79#define RAW_CHECK(Expr) RAW_CHECK_MSG(Expr, #Expr)
80
81void NORETURN reportCheckFailed(const char *File, int Line,
82                                const char *Condition, u64 Value1, u64 Value2);
83
84#define CHECK_IMPL(C1, Op, C2)                                                 \
85  do {                                                                         \
86    scudo::u64 V1 = (scudo::u64)(C1);                                          \
87    scudo::u64 V2 = (scudo::u64)(C2);                                          \
88    if (UNLIKELY(!(V1 Op V2))) {                                               \
89      scudo::reportCheckFailed(__FILE__, __LINE__,                             \
90                               "(" #C1 ") " #Op " (" #C2 ")", V1, V2);         \
91      scudo::die();                                                            \
92    }                                                                          \
93  } while (false)
94
95#define CHECK(A) CHECK_IMPL((A), !=, 0)
96#define CHECK_EQ(A, B) CHECK_IMPL((A), ==, (B))
97#define CHECK_NE(A, B) CHECK_IMPL((A), !=, (B))
98#define CHECK_LT(A, B) CHECK_IMPL((A), <, (B))
99#define CHECK_LE(A, B) CHECK_IMPL((A), <=, (B))
100#define CHECK_GT(A, B) CHECK_IMPL((A), >, (B))
101#define CHECK_GE(A, B) CHECK_IMPL((A), >=, (B))
102
103#if SCUDO_DEBUG
104#define DCHECK(A) CHECK(A)
105#define DCHECK_EQ(A, B) CHECK_EQ(A, B)
106#define DCHECK_NE(A, B) CHECK_NE(A, B)
107#define DCHECK_LT(A, B) CHECK_LT(A, B)
108#define DCHECK_LE(A, B) CHECK_LE(A, B)
109#define DCHECK_GT(A, B) CHECK_GT(A, B)
110#define DCHECK_GE(A, B) CHECK_GE(A, B)
111#else
112#define DCHECK(A)
113#define DCHECK_EQ(A, B)
114#define DCHECK_NE(A, B)
115#define DCHECK_LT(A, B)
116#define DCHECK_LE(A, B)
117#define DCHECK_GT(A, B)
118#define DCHECK_GE(A, B)
119#endif
120
121// The superfluous die() call effectively makes this macro NORETURN.
122#define UNREACHABLE(Msg)                                                       \
123  do {                                                                         \
124    CHECK(0 && Msg);                                                           \
125    die();                                                                     \
126  } while (0)
127
128} // namespace scudo
129
130#endif // SCUDO_INTERNAL_DEFS_H_
131