internal_defs.h 7.1 KB

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