comments, complaints, performance data, etc to dl@cs.oswego.edu
*/
+#include <vppinfra/clib.h>
#include <vppinfra/dlmalloc.h>
/*------------------------------ internal #includes ---------------------- */
#if !defined(USE_RECURSIVE_LOCKS) || USE_RECURSIVE_LOCKS == 0
/* Plain spin locks use single word (embedded in malloc_states) */
+__clib_nosanitize_addr
static int spin_acquire_lock(int *sl) {
int spins = 0;
while (*(volatile int *)sl != 0 || CAS_LOCK(sl)) {
#define disable_expand(M) ((M)->mflags |= USE_NOEXPAND_BIT)
#define use_trace(M) ((M)->mflags & USE_TRACE_BIT)
#define enable_trace(M) ((M)->mflags |= USE_TRACE_BIT)
-#define disable_trace(M) ((M)->mflags |= USE_TRACE_BIT)
+#define disable_trace(M) ((M)->mflags &= ~USE_TRACE_BIT)
#define set_lock(M,L)\
((M)->mflags = (L)?\
((char*)(A) >= S->base && (char*)(A) < S->base + S->size)
/* Return segment holding given address */
+__clib_nosanitize_addr
static msegmentptr segment_holding(mstate m, char* addr) {
msegmentptr sp = &m->seg;
for (;;) {
}
/* Return true if segment contains a segment link */
+__clib_nosanitize_addr
static int has_segment_link(mstate m, msegmentptr ss) {
msegmentptr sp = &m->seg;
for (;;) {
#if (FOOTERS && !INSECURE)
/* Check if (alleged) mstate m has expected magic field */
+__clib_nosanitize_addr
static inline int
ok_magic (const mstate m)
{
/* ----------------------------- statistics ------------------------------ */
#if !NO_MALLINFO
+__clib_nosanitize_addr
static struct dlmallinfo internal_mallinfo(mstate m) {
struct dlmallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
ensure_initialization();
/* -------------------------- mspace management -------------------------- */
/* Initialize top chunk and its size */
+__clib_nosanitize_addr
static void init_top(mstate m, mchunkptr p, size_t psize) {
/* Ensure alignment */
size_t offset = align_offset(chunk2mem(p));
#endif /* PROCEED_ON_ERROR */
/* Allocate chunk and prepend remainder with chunk in successor base. */
+__clib_nosanitize_addr
static void* prepend_alloc(mstate m, char* newbase, char* oldbase,
size_t nb) {
mchunkptr p = align_as_chunk(newbase);
}
/* Add a segment to hold a new noncontiguous region */
+__clib_nosanitize_addr
static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) {
/* Determine locations and sizes of segment, fenceposts, old top */
char* old_top = (char*)m->top;
msegmentptr ss = (msegmentptr)(chunk2mem(sp));
mchunkptr tnext = chunk_plus_offset(sp, ssize);
mchunkptr p = tnext;
- int nfences = 0;
+ int __attribute__((unused)) nfences = 0;
/* reset top to new space */
init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);
/* -------------------------- System allocation -------------------------- */
/* Get memory from system using MORECORE or MMAP */
+__clib_nosanitize_addr
static void* sys_alloc(mstate m, size_t nb) {
char* tbase = CMFAIL;
size_t tsize = 0;
/* ----------------------- system deallocation -------------------------- */
/* Unmap and unlink any mmapped segments that don't contain used chunks */
+__clib_nosanitize_addr
static size_t release_unused_segments(mstate m) {
size_t released = 0;
int nsegs = 0;
return released;
}
+__clib_nosanitize_addr
static int sys_trim(mstate m, size_t pad) {
size_t released = 0;
ensure_initialization();
/* Consolidate and bin a chunk. Differs from exported versions
of free mainly in that the chunk need not be marked as inuse.
*/
+__clib_nosanitize_addr
static void dispose_chunk(mstate m, mchunkptr p, size_t psize) {
mchunkptr next = chunk_plus_offset(p, psize);
if (!pinuse(p)) {
/* ---------------------------- malloc --------------------------- */
/* allocate a large request from the best fitting chunk in a treebin */
+__clib_nosanitize_addr
static void* tmalloc_large(mstate m, size_t nb) {
tchunkptr v = 0;
size_t rsize = -nb; /* Unsigned negation */
}
/* allocate a small request from the best fitting chunk in a treebin */
+__clib_nosanitize_addr
static void* tmalloc_small(mstate m, size_t nb) {
tchunkptr t, v;
size_t rsize;
/* ------------ Internal support for realloc, memalign, etc -------------- */
/* Try to realloc; only in-place unless can_move true */
-static mchunkptr try_realloc_chunk(mstate m, mchunkptr p, size_t nb,
+static __clib_nosanitize_addr mchunkptr try_realloc_chunk(mstate m, mchunkptr p, size_t nb,
int can_move) {
mchunkptr newp = 0;
size_t oldsize = chunksize(p);
return newp;
}
+__clib_nosanitize_addr
static void* internal_memalign(mstate m, size_t alignment, size_t bytes) {
void* mem = 0;
if (alignment < MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */
return ret;
}
+__clib_nosanitize_addr
size_t destroy_mspace(mspace msp) {
size_t freed = 0;
mstate ms = (mstate)msp;
{
mstate ms;
msegment *this_seg;
-
+
ms = (mstate)msp;
this_seg = &ms->seg;
*sizep = this_seg->size;
}
+__clib_nosanitize_addr
int mspace_is_heap_object (mspace msp, void *p)
{
msegment *this_seg;
return 0;
}
+__clib_nosanitize_addr
void *mspace_least_addr (mspace msp)
{
mstate ms = (mstate) msp;
disable_expand (ms);
}
+__clib_nosanitize_addr
int mspace_enable_disable_trace (mspace msp, int enable)
{
mstate ms = (mstate)msp;
return (was_enabled);
}
-void* mspace_get_aligned (mspace msp,
+__clib_nosanitize_addr
+int mspace_is_traced (mspace msp)
+{
+ mstate ms = (mstate)msp;
+
+ if (use_trace(ms))
+ return 1;
+ return 0;
+}
+
+__clib_nosanitize_addr
+void* mspace_get_aligned (mspace msp,
unsigned long n_user_data_bytes,
- unsigned long align,
+ unsigned long align,
unsigned long align_offset) {
char *rv;
unsigned long searchp;
mstate ms = (mstate)msp;
/*
- * Allocate space for the "Where's Waldo?" pointer
+ * Allocate space for the "Where's Waldo?" pointer
* the base of the dlmalloc object
*/
n_user_data_bytes += sizeof(unsigned);
-
- /*
- * Alignment requests less than the size of an mmx vector are ignored
- */
- if (align < sizeof (uword)) {
- rv = mspace_malloc (msp, n_user_data_bytes);
- if (rv == 0)
- return rv;
-
- if (use_trace(ms)) {
- mchunkptr p = mem2chunk(rv);
- size_t psize = chunksize(p);
-
- mheap_get_trace ((unsigned long)rv + sizeof (unsigned), psize);
- }
-
- wwp = (unsigned *)rv;
- *wwp = 0;
- rv += sizeof (unsigned);
-
- return rv;
- }
+ align = align < MALLOC_ALIGNMENT ? MALLOC_ALIGNMENT : align;
/*
* Alignment requests greater than 4K must be at offset zero,
* and must be freed using mspace_free_no_offset - or never freed -
* since the "Where's Waldo?" pointer would waste too much space.
- *
- * Waldo is the address of the chunk of memory returned by mspace_malloc,
+ *
+ * Waldo is the address of the chunk of memory returned by mspace_malloc,
* which we need later to call mspace_free...
*/
if (align > 4<<10 || align_offset == ~0UL) {
n_user_data_bytes -= sizeof(unsigned);
assert(align_offset == 0);
rv = internal_memalign(ms, (size_t)align, n_user_data_bytes);
-
+
/* Trace the allocation */
if (rv && use_trace(ms)) {
mchunkptr p = mem2chunk(rv);
return (void *) searchp;
}
+__clib_nosanitize_addr
void mspace_put (mspace msp, void *p_arg)
{
char *object_header;
mheap_put_trace ((unsigned long)p_arg, psize);
}
-#if CLIB_DEBUG > 0
+#if CLIB_DEBUG > 0 && !defined(CLIB_SANITIZE_ADDR)
/* Poison the object */
{
size_t psize = mspace_usable_size (object_header);
mspace_free (msp, p_arg);
}
+__clib_nosanitize_addr
size_t mspace_usable_size_with_delta (const void *p)
{
size_t usable_size;
versions. This is not so nice but better than the alternatives.
*/
+__clib_nosanitize_addr
void* mspace_malloc(mspace msp, size_t bytes) {
mstate ms = (mstate)msp;
if (!ok_magic(ms)) {
return 0;
}
+__clib_nosanitize_addr
void mspace_free(mspace msp, void* mem) {
if (mem != 0) {
mchunkptr p = mem2chunk(mem);
return mem;
}
+__clib_nosanitize_addr
void* mspace_realloc_in_place(mspace msp, void* oldmem, size_t bytes) {
void* mem = 0;
if (oldmem != 0) {
return mem;
}
+__clib_nosanitize_addr
void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) {
mstate ms = (mstate)msp;
if (!ok_magic(ms)) {
}
#if !NO_MALLINFO
+__clib_nosanitize_addr
struct dlmallinfo mspace_mallinfo(mspace msp) {
mstate ms = (mstate)msp;
if (!ok_magic(ms)) {
}
#endif /* NO_MALLINFO */
+__clib_nosanitize_addr
size_t mspace_usable_size(const void* mem) {
if (mem != 0) {
mchunkptr p = mem2chunk(mem);