|
24 | 24 | # define __SANITIZE_ADDRESS__ 1
|
25 | 25 | #endif
|
26 | 26 |
|
27 |
| -#ifdef HAVE_valgrind |
28 |
| -#define IF_VALGRIND(A,B) A |
29 |
| -#else |
30 |
| -#define IF_VALGRIND(A,B) B |
31 |
| -#endif |
32 |
| - |
33 |
| -#if defined(HAVE_VALGRIND_MEMCHECK_H) && defined(HAVE_valgrind) |
| 27 | +#if __has_feature(memory_sanitizer) |
| 28 | +# include <sanitizer/msan_interface.h> |
| 29 | +# define HAVE_valgrind |
| 30 | +# define MEM_UNDEFINED(a,len) __msan_allocated_memory(a,len) |
| 31 | +# define MEM_MAKE_ADDRESSABLE(a,len) MEM_UNDEFINED(a,len) |
| 32 | +# define MEM_MAKE_DEFINED(a,len) __msan_unpoison(a,len) |
| 33 | +# define MEM_NOACCESS(a,len) ((void) 0) |
| 34 | +# define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0) |
| 35 | +# define MEM_CHECK_DEFINED(a,len) __msan_check_mem_is_initialized(a,len) |
| 36 | +# define MEM_GET_VBITS(a,b,len) __msan_copy_shadow(b,a,len) |
| 37 | +# define MEM_SET_VBITS(a,b,len) __msan_copy_shadow(a,b,len) |
| 38 | +# define REDZONE_SIZE 8 |
| 39 | +#elif defined(HAVE_VALGRIND_MEMCHECK_H) && defined(HAVE_valgrind) |
34 | 40 | # include <valgrind/memcheck.h>
|
35 |
| -# define HAVE_valgrind_or_MSAN |
36 | 41 | # define MEM_UNDEFINED(a,len) VALGRIND_MAKE_MEM_UNDEFINED(a,len)
|
| 42 | +# define MEM_MAKE_ADDRESSABLE(a,len) MEM_UNDEFINED(a,len) |
37 | 43 | # define MEM_MAKE_DEFINED(a,len) VALGRIND_MAKE_MEM_DEFINED(a,len)
|
38 | 44 | # define MEM_NOACCESS(a,len) VALGRIND_MAKE_MEM_NOACCESS(a,len)
|
39 | 45 | # define MEM_CHECK_ADDRESSABLE(a,len) VALGRIND_CHECK_MEM_IS_ADDRESSABLE(a,len)
|
|
45 | 51 | # include <sanitizer/asan_interface.h>
|
46 | 52 | /* How to do manual poisoning:
|
47 | 53 | https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning */
|
48 |
| -# define MEM_UNDEFINED(a,len) ASAN_UNPOISON_MEMORY_REGION(a,len) |
| 54 | +# define MEM_UNDEFINED(a,len) ((void) 0) |
| 55 | +# define MEM_MAKE_ADDRESSABLE(a,len) ASAN_UNPOISON_MEMORY_REGION(a,len) |
49 | 56 | # define MEM_MAKE_DEFINED(a,len) ((void) 0)
|
50 | 57 | # define MEM_NOACCESS(a,len) ASAN_POISON_MEMORY_REGION(a,len)
|
51 |
| -# define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0) |
| 58 | +# define MEM_CHECK_ADDRESSABLE(a,len) \ |
| 59 | + assert(!__asan_region_is_poisoned((void*) a,len)) |
52 | 60 | # define MEM_CHECK_DEFINED(a,len) ((void) 0)
|
53 | 61 | # define MEM_GET_VBITS(a,b,len) ((void) 0)
|
54 | 62 | # define MEM_SET_VBITS(a,b,len) ((void) 0)
|
55 | 63 | # define REDZONE_SIZE 8
|
56 |
| -#elif __has_feature(memory_sanitizer) |
57 |
| -# include <sanitizer/msan_interface.h> |
58 |
| -# define HAVE_valgrind_or_MSAN |
59 |
| -# define MEM_UNDEFINED(a,len) __msan_allocated_memory(a,len) |
60 |
| -# define MEM_MAKE_DEFINED(a,len) __msan_unpoison(a,len) |
61 |
| -# define MEM_NOACCESS(a,len) ((void) 0) |
62 |
| -# define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0) |
63 |
| -# define MEM_CHECK_DEFINED(a,len) __msan_check_mem_is_initialized(a,len) |
64 |
| -# define MEM_GET_VBITS(a,b,len) __msan_copy_shadow(b,a,len) |
65 |
| -# define MEM_SET_VBITS(a,b,len) __msan_copy_shadow(a,b,len) |
66 |
| -# define REDZONE_SIZE 8 |
67 | 64 | #else
|
68 |
| -# define MEM_UNDEFINED(a,len) ((void) (a), (void) (len)) |
| 65 | +# define MEM_UNDEFINED(a,len) ((void) 0) |
| 66 | +# define MEM_MAKE_ADDRESSABLE(a,len) ((void) 0) |
69 | 67 | # define MEM_MAKE_DEFINED(a,len) ((void) 0)
|
70 | 68 | # define MEM_NOACCESS(a,len) ((void) 0)
|
71 | 69 | # define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0)
|
72 | 70 | # define MEM_CHECK_DEFINED(a,len) ((void) 0)
|
73 | 71 | # define MEM_GET_VBITS(a,b,len) ((void) 0)
|
74 | 72 | # define MEM_SET_VBITS(a,b,len) ((void) 0)
|
75 | 73 | # define REDZONE_SIZE 0
|
76 |
| -#endif /* HAVE_VALGRIND_MEMCHECK_H */ |
| 74 | +#endif /* __has_feature(memory_sanitizer) */ |
| 75 | + |
| 76 | +#ifdef HAVE_valgrind |
| 77 | +#define IF_VALGRIND(A,B) A |
| 78 | +#else |
| 79 | +#define IF_VALGRIND(A,B) B |
| 80 | +#endif |
77 | 81 |
|
78 | 82 | #ifdef TRASH_FREED_MEMORY
|
79 | 83 | /*
|
80 |
| - TRASH_FILL() has to call MEM_UNDEFINED() to cancel any effect of TRASH_FREE(). |
| 84 | + _TRASH_FILL() has to call MEM_MAKE_ADDRESSABLE() to cancel any effect of |
| 85 | + TRASH_FREE(). |
81 | 86 | This can happen in the case one does
|
82 | 87 | TRASH_ALLOC(A,B) ; TRASH_FREE(A,B) ; TRASH_ALLOC(A,B)
|
83 | 88 | to reuse the same memory in an internal memory allocator like MEM_ROOT.
|
84 |
| - For my_malloc() and safemalloc() the extra MEM_UNDEFINED is bit of an |
85 |
| - overkill. |
86 |
| - TRASH_FILL() is an internal function and should not be used externally. |
| 89 | + _TRASH_FILL() is an internal function and should not be used externally. |
87 | 90 | */
|
88 |
| -#define TRASH_FILL(A,B,C) do { const size_t trash_tmp= (B); MEM_UNDEFINED(A, trash_tmp); memset(A, C, trash_tmp); } while (0) |
| 91 | +#define _TRASH_FILL(A,B,C) do { const size_t trash_tmp= (B); MEM_MAKE_ADDRESSABLE(A, trash_tmp); memset(A, C, trash_tmp); } while (0) |
89 | 92 | #else
|
90 |
| -#define TRASH_FILL(A,B,C) do { MEM_UNDEFINED((A), (B)); } while (0) |
| 93 | +#define _TRASH_FILL(A,B,C) do { MEM_UNDEFINED((A), (B)); } while (0) |
91 | 94 | #endif
|
92 |
| -/** Note that some memory became allocated or uninitialized. */ |
93 |
| -#define TRASH_ALLOC(A,B) do { TRASH_FILL(A,B,0xA5); MEM_UNDEFINED(A,B); } while(0) |
| 95 | +/** Note that some memory became allocated and/or uninitialized. */ |
| 96 | +#define TRASH_ALLOC(A,B) do { _TRASH_FILL(A,B,0xA5); MEM_MAKE_ADDRESSABLE(A,B); } while(0) |
94 | 97 | /** Note that some memory became freed. (Prohibit further access to it.) */
|
95 |
| -#define TRASH_FREE(A,B) do { TRASH_FILL(A,B,0x8F); MEM_NOACCESS(A,B); } while(0) |
| 98 | +#define TRASH_FREE(A,B) do { _TRASH_FILL(A,B,0x8F); MEM_NOACCESS(A,B); } while(0) |
96 | 99 |
|
97 | 100 | #endif /* MY_VALGRIND_INCLUDED */
|
0 commit comments