xref: /aosp_15_r20/external/scudo/standalone/internal_defs.h (revision 76559068c068bd27e82aff38fac3bfc865233bca)
1*76559068SAndroid Build Coastguard Worker //===-- internal_defs.h -----------------------------------------*- C++ -*-===//
2*76559068SAndroid Build Coastguard Worker //
3*76559068SAndroid Build Coastguard Worker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*76559068SAndroid Build Coastguard Worker // See https://llvm.org/LICENSE.txt for license information.
5*76559068SAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*76559068SAndroid Build Coastguard Worker //
7*76559068SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
8*76559068SAndroid Build Coastguard Worker 
9*76559068SAndroid Build Coastguard Worker #ifndef SCUDO_INTERNAL_DEFS_H_
10*76559068SAndroid Build Coastguard Worker #define SCUDO_INTERNAL_DEFS_H_
11*76559068SAndroid Build Coastguard Worker 
12*76559068SAndroid Build Coastguard Worker #include "platform.h"
13*76559068SAndroid Build Coastguard Worker 
14*76559068SAndroid Build Coastguard Worker #include <stdint.h>
15*76559068SAndroid Build Coastguard Worker 
16*76559068SAndroid Build Coastguard Worker #ifndef SCUDO_DEBUG
17*76559068SAndroid Build Coastguard Worker #define SCUDO_DEBUG 0
18*76559068SAndroid Build Coastguard Worker #endif
19*76559068SAndroid Build Coastguard Worker 
20*76559068SAndroid Build Coastguard Worker #define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
21*76559068SAndroid Build Coastguard Worker 
22*76559068SAndroid Build Coastguard Worker // String related macros.
23*76559068SAndroid Build Coastguard Worker 
24*76559068SAndroid Build Coastguard Worker #define STRINGIFY_(S) #S
25*76559068SAndroid Build Coastguard Worker #define STRINGIFY(S) STRINGIFY_(S)
26*76559068SAndroid Build Coastguard Worker #define CONCATENATE_(S, C) S##C
27*76559068SAndroid Build Coastguard Worker #define CONCATENATE(S, C) CONCATENATE_(S, C)
28*76559068SAndroid Build Coastguard Worker 
29*76559068SAndroid Build Coastguard Worker // Attributes & builtins related macros.
30*76559068SAndroid Build Coastguard Worker 
31*76559068SAndroid Build Coastguard Worker #define INTERFACE __attribute__((visibility("default")))
32*76559068SAndroid Build Coastguard Worker #define HIDDEN __attribute__((visibility("hidden")))
33*76559068SAndroid Build Coastguard Worker #define WEAK __attribute__((weak))
34*76559068SAndroid Build Coastguard Worker #define ALWAYS_INLINE inline __attribute__((always_inline))
35*76559068SAndroid Build Coastguard Worker #define ALIAS(X) __attribute__((alias(X)))
36*76559068SAndroid Build Coastguard Worker #define FORMAT(F, A) __attribute__((format(printf, F, A)))
37*76559068SAndroid Build Coastguard Worker #define NOINLINE __attribute__((noinline))
38*76559068SAndroid Build Coastguard Worker #define NORETURN __attribute__((noreturn))
39*76559068SAndroid Build Coastguard Worker #define LIKELY(X) __builtin_expect(!!(X), 1)
40*76559068SAndroid Build Coastguard Worker #define UNLIKELY(X) __builtin_expect(!!(X), 0)
41*76559068SAndroid Build Coastguard Worker #if defined(__i386__) || defined(__x86_64__)
42*76559068SAndroid Build Coastguard Worker // __builtin_prefetch(X) generates prefetchnt0 on x86
43*76559068SAndroid Build Coastguard Worker #define PREFETCH(X) __asm__("prefetchnta (%0)" : : "r"(X))
44*76559068SAndroid Build Coastguard Worker #else
45*76559068SAndroid Build Coastguard Worker #define PREFETCH(X) __builtin_prefetch(X)
46*76559068SAndroid Build Coastguard Worker #endif
47*76559068SAndroid Build Coastguard Worker #define UNUSED __attribute__((unused))
48*76559068SAndroid Build Coastguard Worker #define USED __attribute__((used))
49*76559068SAndroid Build Coastguard Worker #define NOEXCEPT noexcept
50*76559068SAndroid Build Coastguard Worker 
51*76559068SAndroid Build Coastguard Worker // This check is only available on Clang. This is essentially an alias of
52*76559068SAndroid Build Coastguard Worker // C++20's 'constinit' specifier which will take care of this when (if?) we can
53*76559068SAndroid Build Coastguard Worker // ask all libc's that use Scudo to compile us with C++20. Dynamic
54*76559068SAndroid Build Coastguard Worker // initialization is bad; Scudo is designed to be lazy-initializated on the
55*76559068SAndroid Build Coastguard Worker // first call to malloc/free (and friends), and this generally happens in the
56*76559068SAndroid Build Coastguard Worker // loader somewhere in libdl's init. After the loader is done, control is
57*76559068SAndroid Build Coastguard Worker // transferred to libc's initialization, and the dynamic initializers are run.
58*76559068SAndroid Build Coastguard Worker // If there's a dynamic initializer for Scudo, then it will clobber the
59*76559068SAndroid Build Coastguard Worker // already-initialized Scudo, and re-initialize all its members back to default
60*76559068SAndroid Build Coastguard Worker // values, causing various explosions. Unfortunately, marking
61*76559068SAndroid Build Coastguard Worker // scudo::Allocator<>'s constructor as 'constexpr' isn't sufficient to prevent
62*76559068SAndroid Build Coastguard Worker // dynamic initialization, as default initialization is fine under 'constexpr'
63*76559068SAndroid Build Coastguard Worker // (but not 'constinit'). Clang at -O0, and gcc at all opt levels will emit a
64*76559068SAndroid Build Coastguard Worker // dynamic initializer for any constant-initialized variables if there is a mix
65*76559068SAndroid Build Coastguard Worker // of default-initialized and constant-initialized variables.
66*76559068SAndroid Build Coastguard Worker //
67*76559068SAndroid Build Coastguard Worker // If you're looking at this because your build failed, you probably introduced
68*76559068SAndroid Build Coastguard Worker // a new member to scudo::Allocator<> (possibly transiently) that didn't have an
69*76559068SAndroid Build Coastguard Worker // initializer. The fix is easy - just add one.
70*76559068SAndroid Build Coastguard Worker #if defined(__has_attribute)
71*76559068SAndroid Build Coastguard Worker #if __has_attribute(require_constant_initialization)
72*76559068SAndroid Build Coastguard Worker #define SCUDO_REQUIRE_CONSTANT_INITIALIZATION                                  \
73*76559068SAndroid Build Coastguard Worker   __attribute__((__require_constant_initialization__))
74*76559068SAndroid Build Coastguard Worker #else
75*76559068SAndroid Build Coastguard Worker #define SCUDO_REQUIRE_CONSTANT_INITIALIZATION
76*76559068SAndroid Build Coastguard Worker #endif
77*76559068SAndroid Build Coastguard Worker #endif
78*76559068SAndroid Build Coastguard Worker 
79*76559068SAndroid Build Coastguard Worker namespace scudo {
80*76559068SAndroid Build Coastguard Worker 
81*76559068SAndroid Build Coastguard Worker typedef uintptr_t uptr;
82*76559068SAndroid Build Coastguard Worker typedef uint8_t u8;
83*76559068SAndroid Build Coastguard Worker typedef uint16_t u16;
84*76559068SAndroid Build Coastguard Worker typedef uint32_t u32;
85*76559068SAndroid Build Coastguard Worker typedef uint64_t u64;
86*76559068SAndroid Build Coastguard Worker typedef intptr_t sptr;
87*76559068SAndroid Build Coastguard Worker typedef int8_t s8;
88*76559068SAndroid Build Coastguard Worker typedef int16_t s16;
89*76559068SAndroid Build Coastguard Worker typedef int32_t s32;
90*76559068SAndroid Build Coastguard Worker typedef int64_t s64;
91*76559068SAndroid Build Coastguard Worker 
92*76559068SAndroid Build Coastguard Worker // The following two functions have platform specific implementations.
93*76559068SAndroid Build Coastguard Worker void outputRaw(const char *Buffer);
94*76559068SAndroid Build Coastguard Worker void NORETURN die();
95*76559068SAndroid Build Coastguard Worker 
96*76559068SAndroid Build Coastguard Worker #define RAW_CHECK_MSG(Expr, Msg)                                               \
97*76559068SAndroid Build Coastguard Worker   do {                                                                         \
98*76559068SAndroid Build Coastguard Worker     if (UNLIKELY(!(Expr))) {                                                   \
99*76559068SAndroid Build Coastguard Worker       outputRaw(Msg);                                                          \
100*76559068SAndroid Build Coastguard Worker       die();                                                                   \
101*76559068SAndroid Build Coastguard Worker     }                                                                          \
102*76559068SAndroid Build Coastguard Worker   } while (false)
103*76559068SAndroid Build Coastguard Worker 
104*76559068SAndroid Build Coastguard Worker #define RAW_CHECK(Expr) RAW_CHECK_MSG(Expr, #Expr)
105*76559068SAndroid Build Coastguard Worker 
106*76559068SAndroid Build Coastguard Worker void NORETURN reportCheckFailed(const char *File, int Line,
107*76559068SAndroid Build Coastguard Worker                                 const char *Condition, u64 Value1, u64 Value2);
108*76559068SAndroid Build Coastguard Worker #define CHECK_IMPL(C1, Op, C2)                                                 \
109*76559068SAndroid Build Coastguard Worker   do {                                                                         \
110*76559068SAndroid Build Coastguard Worker     if (UNLIKELY(!(C1 Op C2))) {                                               \
111*76559068SAndroid Build Coastguard Worker       scudo::reportCheckFailed(__FILE__, __LINE__, #C1 " " #Op " " #C2,        \
112*76559068SAndroid Build Coastguard Worker                                (scudo::u64)C1, (scudo::u64)C2);                \
113*76559068SAndroid Build Coastguard Worker       scudo::die();                                                            \
114*76559068SAndroid Build Coastguard Worker     }                                                                          \
115*76559068SAndroid Build Coastguard Worker   } while (false)
116*76559068SAndroid Build Coastguard Worker 
117*76559068SAndroid Build Coastguard Worker #define CHECK(A) CHECK_IMPL((A), !=, 0)
118*76559068SAndroid Build Coastguard Worker #define CHECK_EQ(A, B) CHECK_IMPL((A), ==, (B))
119*76559068SAndroid Build Coastguard Worker #define CHECK_NE(A, B) CHECK_IMPL((A), !=, (B))
120*76559068SAndroid Build Coastguard Worker #define CHECK_LT(A, B) CHECK_IMPL((A), <, (B))
121*76559068SAndroid Build Coastguard Worker #define CHECK_LE(A, B) CHECK_IMPL((A), <=, (B))
122*76559068SAndroid Build Coastguard Worker #define CHECK_GT(A, B) CHECK_IMPL((A), >, (B))
123*76559068SAndroid Build Coastguard Worker #define CHECK_GE(A, B) CHECK_IMPL((A), >=, (B))
124*76559068SAndroid Build Coastguard Worker 
125*76559068SAndroid Build Coastguard Worker #if SCUDO_DEBUG
126*76559068SAndroid Build Coastguard Worker #define DCHECK(A) CHECK(A)
127*76559068SAndroid Build Coastguard Worker #define DCHECK_EQ(A, B) CHECK_EQ(A, B)
128*76559068SAndroid Build Coastguard Worker #define DCHECK_NE(A, B) CHECK_NE(A, B)
129*76559068SAndroid Build Coastguard Worker #define DCHECK_LT(A, B) CHECK_LT(A, B)
130*76559068SAndroid Build Coastguard Worker #define DCHECK_LE(A, B) CHECK_LE(A, B)
131*76559068SAndroid Build Coastguard Worker #define DCHECK_GT(A, B) CHECK_GT(A, B)
132*76559068SAndroid Build Coastguard Worker #define DCHECK_GE(A, B) CHECK_GE(A, B)
133*76559068SAndroid Build Coastguard Worker #else
134*76559068SAndroid Build Coastguard Worker #define DCHECK(A)                                                              \
135*76559068SAndroid Build Coastguard Worker   do {                                                                         \
136*76559068SAndroid Build Coastguard Worker   } while (false && (A))
137*76559068SAndroid Build Coastguard Worker #define DCHECK_EQ(A, B)                                                        \
138*76559068SAndroid Build Coastguard Worker   do {                                                                         \
139*76559068SAndroid Build Coastguard Worker   } while (false && (A) == (B))
140*76559068SAndroid Build Coastguard Worker #define DCHECK_NE(A, B)                                                        \
141*76559068SAndroid Build Coastguard Worker   do {                                                                         \
142*76559068SAndroid Build Coastguard Worker   } while (false && (A) != (B))
143*76559068SAndroid Build Coastguard Worker #define DCHECK_LT(A, B)                                                        \
144*76559068SAndroid Build Coastguard Worker   do {                                                                         \
145*76559068SAndroid Build Coastguard Worker   } while (false && (A) < (B))
146*76559068SAndroid Build Coastguard Worker #define DCHECK_LE(A, B)                                                        \
147*76559068SAndroid Build Coastguard Worker   do {                                                                         \
148*76559068SAndroid Build Coastguard Worker   } while (false && (A) <= (B))
149*76559068SAndroid Build Coastguard Worker #define DCHECK_GT(A, B)                                                        \
150*76559068SAndroid Build Coastguard Worker   do {                                                                         \
151*76559068SAndroid Build Coastguard Worker   } while (false && (A) > (B))
152*76559068SAndroid Build Coastguard Worker #define DCHECK_GE(A, B)                                                        \
153*76559068SAndroid Build Coastguard Worker   do {                                                                         \
154*76559068SAndroid Build Coastguard Worker   } while (false && (A) >= (B))
155*76559068SAndroid Build Coastguard Worker #endif
156*76559068SAndroid Build Coastguard Worker 
157*76559068SAndroid Build Coastguard Worker // The superfluous die() call effectively makes this macro NORETURN.
158*76559068SAndroid Build Coastguard Worker #define UNREACHABLE(Msg)                                                       \
159*76559068SAndroid Build Coastguard Worker   do {                                                                         \
160*76559068SAndroid Build Coastguard Worker     CHECK(0 && Msg);                                                           \
161*76559068SAndroid Build Coastguard Worker     die();                                                                     \
162*76559068SAndroid Build Coastguard Worker   } while (0)
163*76559068SAndroid Build Coastguard Worker 
164*76559068SAndroid Build Coastguard Worker } // namespace scudo
165*76559068SAndroid Build Coastguard Worker 
166*76559068SAndroid Build Coastguard Worker #endif // SCUDO_INTERNAL_DEFS_H_
167