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(maybe_moved, tsdn, ptr, usize,	\
40    ptr_maybe_null, old_ptr, old_usize, old_rzsize, old_ptr_maybe_null,	\
41    zero) do {								\
42	if (unlikely(in_valgrind)) {					\
43		size_t rzsize = p2rz(tsdn, ptr);			\
44									\
45		if (!maybe_moved || ptr == old_ptr) {			\
46			VALGRIND_RESIZEINPLACE_BLOCK(ptr, old_usize,	\
47			    usize, rzsize);				\
48			if (zero && old_usize < usize) {		\
49				valgrind_make_mem_defined(		\
50				    (void *)((uintptr_t)ptr +		\
51				    old_usize), usize - old_usize);	\
52			}						\
53		} else {						\
54			if (!old_ptr_maybe_null || old_ptr != NULL) {	\
55				valgrind_freelike_block(old_ptr,	\
56				    old_rzsize);			\
57			}						\
58			if (!ptr_maybe_null || ptr != NULL) {		\
59				size_t copy_size = (old_usize < usize)	\
60				    ?  old_usize : usize;		\
61				size_t tail_size = usize - copy_size;	\
62				VALGRIND_MALLOCLIKE_BLOCK(ptr, usize,	\
63				    rzsize, false);			\
64				if (copy_size > 0) {			\
65					valgrind_make_mem_defined(ptr,	\
66					copy_size);			\
67				}					\
68				if (zero && tail_size > 0) {		\
69					valgrind_make_mem_defined(	\
70					    (void *)((uintptr_t)ptr +	\
71					    copy_size), tail_size);	\
72				}					\
73			}						\
74		}							\
75	}								\
76} while (0)
77#define	JEMALLOC_VALGRIND_FREE(ptr, rzsize) do {			\
78	if (unlikely(in_valgrind))					\
79		valgrind_freelike_block(ptr, rzsize);			\
80} while (0)
81#else
82#define	RUNNING_ON_VALGRIND	((unsigned)0)
83#define	JEMALLOC_VALGRIND_MAKE_MEM_NOACCESS(ptr, usize) do {} while (0)
84#define	JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ptr, usize) do {} while (0)
85#define	JEMALLOC_VALGRIND_MAKE_MEM_DEFINED(ptr, usize) do {} while (0)
86#define	JEMALLOC_VALGRIND_MALLOC(cond, tsdn, ptr, usize, zero) do {} while (0)
87#define	JEMALLOC_VALGRIND_REALLOC(maybe_moved, tsdn, ptr, usize,	\
88    ptr_maybe_null, old_ptr, old_usize, old_rzsize, old_ptr_maybe_null,	\
89    zero) do {} while (0)
90#define	JEMALLOC_VALGRIND_FREE(ptr, rzsize) do {} while (0)
91#endif
92
93#endif /* JEMALLOC_H_TYPES */
94/******************************************************************************/
95#ifdef JEMALLOC_H_STRUCTS
96
97#endif /* JEMALLOC_H_STRUCTS */
98/******************************************************************************/
99#ifdef JEMALLOC_H_EXTERNS
100
101#ifdef JEMALLOC_VALGRIND
102void	valgrind_make_mem_noaccess(void *ptr, size_t usize);
103void	valgrind_make_mem_undefined(void *ptr, size_t usize);
104void	valgrind_make_mem_defined(void *ptr, size_t usize);
105void	valgrind_freelike_block(void *ptr, size_t usize);
106#endif
107
108#endif /* JEMALLOC_H_EXTERNS */
109/******************************************************************************/
110#ifdef JEMALLOC_H_INLINES
111
112#endif /* JEMALLOC_H_INLINES */
113/******************************************************************************/
114
115