1 #ifndef INTERNAL_SANITIZERS_H
2 #define INTERNAL_SANITIZERS_H
11 #include "ruby/internal/config.h"
12 #include "internal/compilers.h"
14 #ifdef HAVE_VALGRIND_MEMCHECK_H
15 # include <valgrind/memcheck.h>
18 #ifdef HAVE_SANITIZER_ASAN_INTERFACE_H
19 # include <sanitizer/asan_interface.h>
22 #ifdef HAVE_SANITIZER_MSAN_INTERFACE_H
23 # if __has_feature(memory_sanitizer)
24 # include <sanitizer/msan_interface.h>
32 #elif __has_feature(memory_sanitizer) && __has_feature(address_sanitizer)
33 # define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) \
34 __attribute__((__no_sanitize__("memory, address"), __noinline__)) x
35 #elif __has_feature(address_sanitizer)
36 # define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) \
37 __attribute__((__no_sanitize__("address"), __noinline__)) x
38 #elif defined(NO_SANITIZE_ADDRESS)
39 # define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) \
40 NO_SANITIZE_ADDRESS(NOINLINE(x))
41 #elif defined(NO_ADDRESS_SAFETY_ANALYSIS)
42 # define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) \
43 NO_ADDRESS_SAFETY_ANALYSIS(NOINLINE(x))
45 # define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) x
48 #if defined(NO_SANITIZE) && RBIMPL_COMPILER_IS(GCC)
50 # include "internal/warnings.h"
52 # define NO_SANITIZE(x, y) \
53 COMPILER_WARNING_PUSH; \
54 COMPILER_WARNING_IGNORED(-Wattributes); \
55 __attribute__((__no_sanitize__(x))) y; \
60 # define NO_SANITIZE(x, y) y
63 #if !__has_feature(address_sanitizer)
64 # define __asan_poison_memory_region(x, y)
65 # define __asan_unpoison_memory_region(x, y)
66 # define __asan_region_is_poisoned(x, y) 0
69 #if !__has_feature(memory_sanitizer)
70 # define __msan_allocated_memory(x, y) ((void)(x), (void)(y))
71 # define __msan_poison(x, y) ((void)(x), (void)(y))
72 # define __msan_unpoison(x, y) ((void)(x), (void)(y))
73 # define __msan_unpoison_string(x) ((void)(x))
76 #ifdef VALGRIND_MAKE_READABLE
77 # define VALGRIND_MAKE_MEM_DEFINED(p, n) VALGRIND_MAKE_READABLE((p), (n))
80 #ifdef VALGRIND_MAKE_WRITABLE
81 # define VALGRIND_MAKE_MEM_UNDEFINED(p, n) VALGRIND_MAKE_WRITABLE((p), (n))
84 #ifndef VALGRIND_MAKE_MEM_DEFINED
85 # define VALGRIND_MAKE_MEM_DEFINED(p, n) 0
88 #ifndef VALGRIND_MAKE_MEM_UNDEFINED
89 # define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 0
108 asan_poison_memory_region(
const volatile void *ptr,
size_t size)
110 __msan_poison(ptr, size);
111 __asan_poison_memory_region(ptr, size);
120 asan_poison_object(
VALUE obj)
122 MAYBE_UNUSED(
struct RVALUE *) ptr = (
void *)obj;
126 #if !__has_feature(address_sanitizer)
127 #define asan_poison_object_if(ptr, obj) ((void)(ptr), (void)(obj))
129 #define asan_poison_object_if(ptr, obj) do { \
130 if (ptr) asan_poison_object(obj); \
142 asan_poisoned_object_p(
VALUE obj)
144 MAYBE_UNUSED(
struct RVALUE *) ptr = (
void *)obj;
164 asan_unpoison_memory_region(
const volatile void *ptr,
size_t size,
bool malloc_p)
166 __asan_unpoison_memory_region(ptr, size);
168 __msan_allocated_memory(ptr, size);
171 __msan_unpoison(ptr, size);
182 asan_unpoison_object(
VALUE obj,
bool newobj_p)
184 MAYBE_UNUSED(
struct RVALUE *) ptr = (
void *)obj;
185 asan_unpoison_memory_region(ptr,
SIZEOF_VALUE, newobj_p);
#define SIZEOF_VALUE
Identical to sizeof(VALUE), except it is a macro that can also be used inside of preprocessor directi...
uintptr_t VALUE
Type that represents a Ruby object.