1 /* Copyright (C) 2010, 2020, MariaDB Corporation. 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License as published by 5 the Free Software Foundation; version 2 of the License. 6 7 This program is distributed in the hope that it will be useful, 8 but WITHOUT ANY WARRANTY; without even the implied warranty of 9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 GNU General Public License for more details. 11 12 You should have received a copy of the GNU General Public License 13 along with this program; if not, write to the Free Software 14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ 15 16 #ifndef MY_VALGRIND_INCLUDED 17 #define MY_VALGRIND_INCLUDED 18 19 /* clang -> gcc */ 20 #ifndef __has_feature 21 # define __has_feature(x) 0 22 #endif 23 #if __has_feature(address_sanitizer) 24 # define __SANITIZE_ADDRESS__ 1 25 #endif 26 27 #if __has_feature(memory_sanitizer) 28 # include <sanitizer/msan_interface.h> 29 # define HAVE_valgrind 30 # define HAVE_MEM_CHECK 31 # define MEM_UNDEFINED(a,len) __msan_allocated_memory(a,len) 32 # define MEM_MAKE_ADDRESSABLE(a,len) MEM_UNDEFINED(a,len) 33 # define MEM_MAKE_DEFINED(a,len) __msan_unpoison(a,len) 34 # define MEM_NOACCESS(a,len) ((void) 0) 35 # define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0) 36 # define MEM_CHECK_DEFINED(a,len) __msan_check_mem_is_initialized(a,len) 37 # define MEM_GET_VBITS(a,b,len) __msan_copy_shadow(b,a,len) 38 # define MEM_SET_VBITS(a,b,len) __msan_copy_shadow(a,b,len) 39 # define REDZONE_SIZE 8 40 #elif defined(HAVE_VALGRIND_MEMCHECK_H) && defined(HAVE_valgrind) 41 # include <valgrind/memcheck.h> 42 # define HAVE_MEM_CHECK 43 # define MEM_UNDEFINED(a,len) VALGRIND_MAKE_MEM_UNDEFINED(a,len) 44 # define MEM_MAKE_ADDRESSABLE(a,len) MEM_UNDEFINED(a,len) 45 # define MEM_MAKE_DEFINED(a,len) VALGRIND_MAKE_MEM_DEFINED(a,len) 46 # define MEM_NOACCESS(a,len) VALGRIND_MAKE_MEM_NOACCESS(a,len) 47 # define MEM_CHECK_ADDRESSABLE(a,len) VALGRIND_CHECK_MEM_IS_ADDRESSABLE(a,len) 48 # define MEM_CHECK_DEFINED(a,len) VALGRIND_CHECK_MEM_IS_DEFINED(a,len) 49 # define MEM_GET_VBITS(a,b,len) VALGRIND_GET_VBITS(a,b,len) 50 # define MEM_SET_VBITS(a,b,len) VALGRIND_SET_VBITS(a,b,len) 51 # define REDZONE_SIZE 8 52 #elif defined(__SANITIZE_ADDRESS__) && (!defined(_MSC_VER) || defined (__clang__)) 53 # include <sanitizer/asan_interface.h> 54 /* How to do manual poisoning: 55 https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning */ 56 # define MEM_UNDEFINED(a,len) ((void) 0) 57 # define MEM_MAKE_ADDRESSABLE(a,len) ASAN_UNPOISON_MEMORY_REGION(a,len) 58 # define MEM_MAKE_DEFINED(a,len) ((void) 0) 59 # define MEM_NOACCESS(a,len) ASAN_POISON_MEMORY_REGION(a,len) 60 # define MEM_CHECK_ADDRESSABLE(a,len) \ 61 assert(!__asan_region_is_poisoned((void*) a,len)) 62 # define MEM_CHECK_DEFINED(a,len) ((void) 0) 63 # define MEM_GET_VBITS(a,b,len) ((void) 0) 64 # define MEM_SET_VBITS(a,b,len) ((void) 0) 65 # define REDZONE_SIZE 8 66 #else 67 # define MEM_UNDEFINED(a,len) ((void) 0) 68 # define MEM_MAKE_ADDRESSABLE(a,len) ((void) 0) 69 # define MEM_MAKE_DEFINED(a,len) ((void) 0) 70 # define MEM_NOACCESS(a,len) ((void) 0) 71 # define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0) 72 # define MEM_CHECK_DEFINED(a,len) ((void) 0) 73 # define MEM_GET_VBITS(a,b,len) ((void) 0) 74 # define MEM_SET_VBITS(a,b,len) ((void) 0) 75 # define REDZONE_SIZE 0 76 #endif /* __has_feature(memory_sanitizer) */ 77 78 #ifdef HAVE_valgrind 79 #define IF_VALGRIND(A,B) A 80 #else 81 #define IF_VALGRIND(A,B) B 82 #endif 83 84 #ifdef TRASH_FREED_MEMORY 85 /* 86 _TRASH_FILL() has to call MEM_MAKE_ADDRESSABLE() to cancel any effect of 87 TRASH_FREE(). 88 This can happen in the case one does 89 TRASH_ALLOC(A,B) ; TRASH_FREE(A,B) ; TRASH_ALLOC(A,B) 90 to reuse the same memory in an internal memory allocator like MEM_ROOT. 91 _TRASH_FILL() is an internal function and should not be used externally. 92 */ 93 #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) 94 #else 95 #define _TRASH_FILL(A,B,C) do { MEM_UNDEFINED((A), (B)); } while (0) 96 #endif 97 /** Note that some memory became allocated and/or uninitialized. */ 98 #define TRASH_ALLOC(A,B) do { _TRASH_FILL(A,B,0xA5); MEM_MAKE_ADDRESSABLE(A,B); } while(0) 99 /** Note that some memory became freed. (Prohibit further access to it.) */ 100 #define TRASH_FREE(A,B) do { _TRASH_FILL(A,B,0x8F); MEM_NOACCESS(A,B); } while(0) 101 102 #endif /* MY_VALGRIND_INCLUDED */ 103