1 /******************************************************************************/ 2 #ifdef JEMALLOC_H_TYPES 3 4 #ifdef JEMALLOC_VALGRIND 5 #include <valgrind/valgrind.h> 6 7 /* 8 * The size that is reported to Valgrind must be consistent through a chain of 9 * malloc..realloc..realloc calls. Request size isn't recorded anywhere in 10 * jemalloc, so it is critical that all callers of these macros provide usize 11 * rather than request size. As a result, buffer overflow detection is 12 * technically weakened for the standard API, though it is generally accepted 13 * practice to consider any extra bytes reported by malloc_usable_size() as 14 * usable space. 15 */ 16 #define JEMALLOC_VALGRIND_MAKE_MEM_NOACCESS(ptr, usize) do { \ 17 if (unlikely(in_valgrind)) \ 18 valgrind_make_mem_noaccess(ptr, usize); \ 19 } while (0) 20 #define JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ptr, usize) do { \ 21 if (unlikely(in_valgrind)) \ 22 valgrind_make_mem_undefined(ptr, usize); \ 23 } while (0) 24 #define JEMALLOC_VALGRIND_MAKE_MEM_DEFINED(ptr, usize) do { \ 25 if (unlikely(in_valgrind)) \ 26 valgrind_make_mem_defined(ptr, usize); \ 27 } while (0) 28 /* 29 * The VALGRIND_MALLOCLIKE_BLOCK() and VALGRIND_RESIZEINPLACE_BLOCK() macro 30 * calls must be embedded in macros rather than in functions so that when 31 * Valgrind reports errors, there are no extra stack frames in the backtraces. 32 */ 33 #define JEMALLOC_VALGRIND_MALLOC(cond, tsdn, ptr, usize, zero) do { \ 34 if (unlikely(in_valgrind && cond)) { \ 35 VALGRIND_MALLOCLIKE_BLOCK(ptr, usize, p2rz(tsdn, ptr), \ 36 zero); \ 37 } \ 38 } while (0) 39 #define JEMALLOC_VALGRIND_REALLOC_MOVED_no(ptr, old_ptr) \ 40 (false) 41 #define JEMALLOC_VALGRIND_REALLOC_MOVED_maybe(ptr, old_ptr) \ 42 ((ptr) != (old_ptr)) 43 #define JEMALLOC_VALGRIND_REALLOC_PTR_NULL_no(ptr) \ 44 (false) 45 #define JEMALLOC_VALGRIND_REALLOC_PTR_NULL_maybe(ptr) \ 46 (ptr == NULL) 47 #define JEMALLOC_VALGRIND_REALLOC_OLD_PTR_NULL_no(old_ptr) \ 48 (false) 49 #define JEMALLOC_VALGRIND_REALLOC_OLD_PTR_NULL_maybe(old_ptr) \ 50 (old_ptr == NULL) 51 #define JEMALLOC_VALGRIND_REALLOC(moved, tsdn, ptr, usize, ptr_null, \ 52 old_ptr, old_usize, old_rzsize, old_ptr_null, zero) do { \ 53 if (unlikely(in_valgrind)) { \ 54 size_t rzsize = p2rz(tsdn, ptr); \ 55 \ 56 if (!JEMALLOC_VALGRIND_REALLOC_MOVED_##moved(ptr, \ 57 old_ptr)) { \ 58 VALGRIND_RESIZEINPLACE_BLOCK(ptr, old_usize, \ 59 usize, rzsize); \ 60 if (zero && old_usize < usize) { \ 61 valgrind_make_mem_defined( \ 62 (void *)((uintptr_t)ptr + \ 63 old_usize), usize - old_usize); \ 64 } \ 65 } else { \ 66 if (!JEMALLOC_VALGRIND_REALLOC_OLD_PTR_NULL_## \ 67 old_ptr_null(old_ptr)) { \ 68 valgrind_freelike_block(old_ptr, \ 69 old_rzsize); \ 70 } \ 71 if (!JEMALLOC_VALGRIND_REALLOC_PTR_NULL_## \ 72 ptr_null(ptr)) { \ 73 size_t copy_size = (old_usize < usize) \ 74 ? old_usize : usize; \ 75 size_t tail_size = usize - copy_size; \ 76 VALGRIND_MALLOCLIKE_BLOCK(ptr, usize, \ 77 rzsize, false); \ 78 if (copy_size > 0) { \ 79 valgrind_make_mem_defined(ptr, \ 80 copy_size); \ 81 } \ 82 if (zero && tail_size > 0) { \ 83 valgrind_make_mem_defined( \ 84 (void *)((uintptr_t)ptr + \ 85 copy_size), tail_size); \ 86 } \ 87 } \ 88 } \ 89 } \ 90 } while (0) 91 #define JEMALLOC_VALGRIND_FREE(ptr, rzsize) do { \ 92 if (unlikely(in_valgrind)) \ 93 valgrind_freelike_block(ptr, rzsize); \ 94 } while (0) 95 #else 96 #define RUNNING_ON_VALGRIND ((unsigned)0) 97 #define JEMALLOC_VALGRIND_MAKE_MEM_NOACCESS(ptr, usize) do {} while (0) 98 #define JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ptr, usize) do {} while (0) 99 #define JEMALLOC_VALGRIND_MAKE_MEM_DEFINED(ptr, usize) do {} while (0) 100 #define JEMALLOC_VALGRIND_MALLOC(cond, tsdn, ptr, usize, zero) do {} while (0) 101 #define JEMALLOC_VALGRIND_REALLOC(maybe_moved, tsdn, ptr, usize, \ 102 ptr_maybe_null, old_ptr, old_usize, old_rzsize, old_ptr_maybe_null, \ 103 zero) do {} while (0) 104 #define JEMALLOC_VALGRIND_FREE(ptr, rzsize) do {} while (0) 105 #endif 106 107 #endif /* JEMALLOC_H_TYPES */ 108 /******************************************************************************/ 109 #ifdef JEMALLOC_H_STRUCTS 110 111 #endif /* JEMALLOC_H_STRUCTS */ 112 /******************************************************************************/ 113 #ifdef JEMALLOC_H_EXTERNS 114 115 #ifdef JEMALLOC_VALGRIND 116 void valgrind_make_mem_noaccess(void *ptr, size_t usize); 117 void valgrind_make_mem_undefined(void *ptr, size_t usize); 118 void valgrind_make_mem_defined(void *ptr, size_t usize); 119 void valgrind_freelike_block(void *ptr, size_t usize); 120 #endif 121 122 #endif /* JEMALLOC_H_EXTERNS */ 123 /******************************************************************************/ 124 #ifdef JEMALLOC_H_INLINES 125 126 #endif /* JEMALLOC_H_INLINES */ 127 /******************************************************************************/ 128 129