[linux] Make malloc and linux_umalloc valgrindable

Make the allocators used by malloc and linux_umalloc valgrindable.
Include valgrind headers in the codebase to avoid a build dependency
on valgrind.

Signed-off-by: Piotr Jaroszyński <p.jaroszynski@gmail.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Piotr Jaroszyński
2010-07-01 03:47:52 +02:00
committed by Michael Brown
parent 3c1bdfd5d9
commit b604e8a388
9 changed files with 4953 additions and 12 deletions

View File

@@ -18,6 +18,8 @@
FILE_LICENCE(GPL2_OR_LATER);
#include <valgrind/memcheck.h>
/** @file
*
* iPXE user memory allocation API for linux
@@ -56,7 +58,9 @@ static void * linux_realloc(void *ptr, size_t size)
/* Check whether we have a valid pointer */
if (ptr != NULL && ptr != NOWHERE) {
mdptr = ptr - SIZE_MD;
VALGRIND_MAKE_MEM_DEFINED(mdptr, SIZE_MD);
md = *mdptr;
VALGRIND_MAKE_MEM_NOACCESS(mdptr, SIZE_MD);
/* Check for poison in the metadata */
if (md.poison != POISON) {
@@ -78,32 +82,56 @@ static void * linux_realloc(void *ptr, size_t size)
if (mdptr) {
if (linux_munmap(mdptr, md.size))
DBG("linux_realloc munmap failed: %s\n", linux_strerror(linux_errno));
VALGRIND_FREELIKE_BLOCK(ptr, sizeof(*mdptr));
}
return NOWHERE;
}
if (ptr) {
/* ptr is pointing to an already allocated memory, mremap() it with new size */
char *vbits = NULL;
if (RUNNING_ON_VALGRIND > 0)
vbits = linux_realloc(NULL, min(size, md.size));
/* prevent an unused variable warning when building w/o valgrind support */
#ifndef NVALGRIND
VALGRIND_GET_VBITS(ptr, vbits, min(size, md.size));
#endif
VALGRIND_FREELIKE_BLOCK(ptr, SIZE_MD);
mdptr = linux_mremap(mdptr, md.size + SIZE_MD, size + SIZE_MD, MREMAP_MAYMOVE);
if (mdptr == MAP_FAILED) {
DBG("linux_realloc mremap failed: %s\n", linux_strerror(linux_errno));
return NULL;
}
ptr = ((void *)mdptr) + SIZE_MD;
VALGRIND_MALLOCLIKE_BLOCK(ptr, size, SIZE_MD, 0);
/* prevent an unused variable warning when building w/o valgrind support */
#ifndef NVALGRIND
VALGRIND_SET_VBITS(ptr, vbits, min(size, md.size));
#endif
if (RUNNING_ON_VALGRIND > 0)
linux_realloc(vbits, 0);
} else {
/* allocate new memory with mmap() */
mdptr = linux_mmap(NULL, size + SIZE_MD, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (mdptr == MAP_FAILED) {
DBG("linux_realloc mmap failed: %s\n", linux_strerror(linux_errno));
return NULL;
}
ptr = ((void *)mdptr) + SIZE_MD;
VALGRIND_MALLOCLIKE_BLOCK(ptr, size, SIZE_MD, 0);
}
/* Update the metadata */
VALGRIND_MAKE_MEM_DEFINED(mdptr, SIZE_MD);
mdptr->poison = POISON;
mdptr->size = size;
VALGRIND_MAKE_MEM_NOACCESS(mdptr, SIZE_MD);
// VALGRIND_MALLOCLIKE_BLOCK ignores redzones currently, make our own
VALGRIND_MAKE_MEM_NOACCESS(ptr + size, SIZE_MD);
return ptr;
}