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
108asan_poison_memory_region(
const volatile void *ptr,
size_t size)
110 __msan_poison(ptr, size);
111 __asan_poison_memory_region(ptr, size);
120asan_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); \
142asan_poisoned_object_p(VALUE obj)
144 MAYBE_UNUSED(
struct RVALUE *) ptr = (
void *)obj;
164asan_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);
182asan_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...