internal_defs.h revision 351282
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 INLINE inline
34#define ALWAYS_INLINE inline __attribute__((always_inline))
35#define ALIAS(X) __attribute__((alias(X)))
36// Please only use the ALIGNED macro before the type. Using ALIGNED after the
37// variable declaration is not portable.
38#define ALIGNED(X) __attribute__((aligned(X)))
39#define FORMAT(F, A) __attribute__((format(printf, F, A)))
40#define NOINLINE __attribute__((noinline))
41#define NORETURN __attribute__((noreturn))
42#define THREADLOCAL __thread
43#define LIKELY(X) __builtin_expect(!!(X), 1)
44#define UNLIKELY(X) __builtin_expect(!!(X), 0)
45#if defined(__i386__) || defined(__x86_64__)
46// __builtin_prefetch(X) generates prefetchnt0 on x86
47#define PREFETCH(X) __asm__("prefetchnta (%0)" : : "r"(X))
48#else
49#define PREFETCH(X) __builtin_prefetch(X)
50#endif
51#define UNUSED __attribute__((unused))
52#define USED __attribute__((used))
53#define NOEXCEPT noexcept
54
55namespace scudo {
56
57typedef unsigned long uptr;
58typedef signed long sptr;
59typedef unsigned char u8;
60typedef unsigned short u16;
61typedef unsigned int u32;
62typedef unsigned long long u64;
63typedef signed char s8;
64typedef signed short s16;
65typedef signed int s32;
66typedef signed long long s64;
67
68// The following two functions have platform specific implementations.
69void outputRaw(const char *Buffer);
70void NORETURN die();
71
72#define RAW_CHECK_MSG(Expr, Msg)                                               \
73  do {                                                                         \
74    if (UNLIKELY(!(Expr))) {                                                   \
75      outputRaw(Msg);                                                          \
76      die();                                                                   \
77    }                                                                          \
78  } while (false)
79
80#define RAW_CHECK(Expr) RAW_CHECK_MSG(Expr, #Expr)
81
82void NORETURN reportCheckFailed(const char *File, int Line,
83                                const char *Condition, u64 Value1, u64 Value2);
84
85#define CHECK_IMPL(C1, Op, C2)                                                 \
86  do {                                                                         \
87    u64 V1 = (u64)(C1);                                                        \
88    u64 V2 = (u64)(C2);                                                        \
89    if (UNLIKELY(!(V1 Op V2))) {                                               \
90      reportCheckFailed(__FILE__, __LINE__, "(" #C1 ") " #Op " (" #C2 ")", V1, \
91                        V2);                                                   \
92      die();                                                                   \
93    }                                                                          \
94  } while (false)
95
96#define CHECK(A) CHECK_IMPL((A), !=, 0)
97#define CHECK_EQ(A, B) CHECK_IMPL((A), ==, (B))
98#define CHECK_NE(A, B) CHECK_IMPL((A), !=, (B))
99#define CHECK_LT(A, B) CHECK_IMPL((A), <, (B))
100#define CHECK_LE(A, B) CHECK_IMPL((A), <=, (B))
101#define CHECK_GT(A, B) CHECK_IMPL((A), >, (B))
102#define CHECK_GE(A, B) CHECK_IMPL((A), >=, (B))
103
104#if SCUDO_DEBUG
105#define DCHECK(A) CHECK(A)
106#define DCHECK_EQ(A, B) CHECK_EQ(A, B)
107#define DCHECK_NE(A, B) CHECK_NE(A, B)
108#define DCHECK_LT(A, B) CHECK_LT(A, B)
109#define DCHECK_LE(A, B) CHECK_LE(A, B)
110#define DCHECK_GT(A, B) CHECK_GT(A, B)
111#define DCHECK_GE(A, B) CHECK_GE(A, B)
112#else
113#define DCHECK(A)
114#define DCHECK_EQ(A, B)
115#define DCHECK_NE(A, B)
116#define DCHECK_LT(A, B)
117#define DCHECK_LE(A, B)
118#define DCHECK_GT(A, B)
119#define DCHECK_GE(A, B)
120#endif
121
122// The superfluous die() call effectively makes this macro NORETURN.
123#define UNREACHABLE(Msg)                                                       \
124  do {                                                                         \
125    CHECK(0 && Msg);                                                           \
126    die();                                                                     \
127  } while (0)
128
129#define COMPILER_CHECK(Pred) static_assert(Pred, "")
130
131enum LinkerInitialized { LINKER_INITIALIZED = 0 };
132
133} // namespace scudo
134
135#endif // SCUDO_INTERNAL_DEFS_H_
136