mirror of
https://github.com/ipxe/ipxe
synced 2025-12-23 21:41:43 +03:00
[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:
committed by
Michael Brown
parent
3c1bdfd5d9
commit
b604e8a388
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user