diff options
author | Piotr Jaroszyński | 2010-07-01 03:47:52 +0200 |
---|---|---|
committer | Michael Brown | 2011-03-27 22:03:05 +0200 |
commit | b604e8a388702df3cd4d3d64cf42dfc361b235c0 (patch) | |
tree | d3e581fc9462b3658fb1a2d354794108e85a3086 /src/interface/linux | |
parent | [image] Remove redundant call to basename() (diff) | |
download | ipxe-b604e8a388702df3cd4d3d64cf42dfc361b235c0.tar.gz ipxe-b604e8a388702df3cd4d3d64cf42dfc361b235c0.tar.xz ipxe-b604e8a388702df3cd4d3d64cf42dfc361b235c0.zip |
[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>
Diffstat (limited to 'src/interface/linux')
-rw-r--r-- | src/interface/linux/linux_umalloc.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/src/interface/linux/linux_umalloc.c b/src/interface/linux/linux_umalloc.c index 5167d382..aa0052c5 100644 --- a/src/interface/linux/linux_umalloc.c +++ b/src/interface/linux/linux_umalloc.c @@ -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; } |