From: Philippe Waroquiers Date: Thu, 27 Jul 2017 19:10:30 +0000 (+0000) Subject: Add inner requests in VEX X-Git-Tag: VALGRIND_3_14_0~300^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a10216bdde433fd19346c94fba2c8e054d3dd56f;p=thirdparty%2Fvalgrind.git Add inner requests in VEX When running Valgrind under Valgrind, the VEX memory allocation (temporary or permanent) was not checked, as there was no inner request. This patch changes VEX to mark the temporary and permanent allocations with redzone, and memory is marked unaddressable when the VEX temporary pool is cleared. The changes are: * add a file libvex_inner.h which mostly takes over what was in pub_core_inner.h (which now just includes libvex_inner.h) * modify main_util.h and main_util.c to mark the temporary and permanent pool with memcheck pool requests to indicate when a block is allocated or freed. * Impact is (should be) none, unless Valgrind is configured as an inner. * Outer memcheck/inner regression tests run on gcc20 (amd64). Nothing (more worrying than the 3.13 self hosting) detected git-svn-id: svn://svn.valgrind.org/vex/trunk@3399 --- diff --git a/VEX/priv/main_util.c b/VEX/priv/main_util.c index 4e0494b62f..865fe0c7a7 100644 --- a/VEX/priv/main_util.c +++ b/VEX/priv/main_util.c @@ -52,7 +52,14 @@ into memory, the rate falls by about a factor of 3. */ +#if defined(ENABLE_INNER) +/* 5 times more memory to be on the safe side: consider each allocation is + 8 bytes, and we need 16 bytes redzone before and after. */ +#define N_TEMPORARY_BYTES (5*5000000) +static Bool mempools_created = False; +#else #define N_TEMPORARY_BYTES 5000000 +#endif static HChar temporary[N_TEMPORARY_BYTES] __attribute__((aligned(REQ_ALIGN))); static HChar* temporary_first = &temporary[0]; @@ -61,7 +68,12 @@ static HChar* temporary_last = &temporary[N_TEMPORARY_BYTES-1]; static ULong temporary_bytes_allocd_TOT = 0; +#if defined(ENABLE_INNER) +/* See N_TEMPORARY_BYTES */ +#define N_PERMANENT_BYTES (5*10000) +#else #define N_PERMANENT_BYTES 10000 +#endif static HChar permanent[N_PERMANENT_BYTES] __attribute__((aligned(REQ_ALIGN))); static HChar* permanent_first = &permanent[0]; @@ -178,6 +190,18 @@ void vexSetAllocModeTEMP_and_clear ( void ) temporary_bytes_allocd_TOT += (ULong)(private_LibVEX_alloc_curr - private_LibVEX_alloc_first); +#if defined(ENABLE_INNER) + if (mempools_created) { + VALGRIND_MEMPOOL_TRIM(&temporary[0], &temporary[0], 0); + } else { + VALGRIND_CREATE_MEMPOOL(&temporary[0], VEX_REDZONE_SIZEB, 0); + VALGRIND_CREATE_MEMPOOL(&permanent[0], VEX_REDZONE_SIZEB, 0); + VALGRIND_MAKE_MEM_NOACCESS(&permanent[0], N_PERMANENT_BYTES); + mempools_created = True; + } + VALGRIND_MAKE_MEM_NOACCESS(&temporary[0], N_TEMPORARY_BYTES); +#endif + mode = VexAllocModeTEMP; temporary_curr = &temporary[0]; private_LibVEX_alloc_curr = &temporary[0]; diff --git a/VEX/priv/main_util.h b/VEX/priv/main_util.h index 8627d1f8e0..82b9a5f1e6 100644 --- a/VEX/priv/main_util.h +++ b/VEX/priv/main_util.h @@ -38,6 +38,13 @@ #include "libvex_basictypes.h" +#include "libvex_inner.h" +#if defined(ENABLE_INNER_CLIENT_REQUEST) +/* Including here memcheck include file is kind of a hack, but this is needed + to have self-hosting checking VEX. Note however that this is included only + when Valgrind and VEX are configured using --enable-inner. */ +#include "memcheck/memcheck.h" +#endif /* Misc. */ @@ -129,6 +136,10 @@ extern void private_LibVEX_alloc_OOM(void) __attribute__((noreturn)); boundary. */ #define REQ_ALIGN 8 +#if defined(ENABLE_INNER) +#define VEX_REDZONE_SIZEB (2*REQ_ALIGN) +#endif + static inline void* LibVEX_Alloc_inline ( SizeT nbytes ) { struct align { @@ -160,12 +171,15 @@ static inline void* LibVEX_Alloc_inline ( SizeT nbytes ) HChar* next; SizeT ALIGN; ALIGN = offsetof(struct align,x) - 1; - nbytes = (nbytes + ALIGN) & ~ALIGN; curr = private_LibVEX_alloc_curr; - next = curr + nbytes; + next = curr + ((nbytes + ALIGN) & ~ALIGN); + INNER_REQUEST(next += 2 * VEX_REDZONE_SIZEB); if (next >= private_LibVEX_alloc_last) private_LibVEX_alloc_OOM(); private_LibVEX_alloc_curr = next; + INNER_REQUEST(curr += VEX_REDZONE_SIZEB); + INNER_REQUEST(VALGRIND_MEMPOOL_ALLOC(private_LibVEX_alloc_first, + curr, nbytes)); return curr; #endif } diff --git a/VEX/pub/libvex_inner.h b/VEX/pub/libvex_inner.h new file mode 100644 index 0000000000..9fb563e38c --- /dev/null +++ b/VEX/pub/libvex_inner.h @@ -0,0 +1,73 @@ + +/*--------------------------------------------------------------------*/ +/*--- Utilities for inner Valgrind libvex_inner.h ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2017-2017 Philippe Waroquiers + philippe.waroquiers@skynet.be + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#ifndef __LIBVEX_INNER_H +#define __LIBVEX_INNER_H + +//-------------------------------------------------------------------- +// PURPOSE: This header should be imported by every file in Valgrind +// which needs specific behaviour when running as an "inner" Valgrind. +// Valgrind can self-host itself (i.e. Valgrind can run Valgrind) : +// The outer Valgrind executes the inner Valgrind. +// For more details, see README_DEVELOPPERS. +//-------------------------------------------------------------------- + +#include "config.h" + +// The code of the inner Valgrind (core or tool code) contains client +// requests (e.g. from helgrind.h, memcheck.h, ...) to help the +// outer Valgrind finding (relevant) errors in the inner Valgrind. +// Such client requests should only be compiled in for an inner Valgrind. +// Use the macro INNER_REQUEST to allow a central enabling/disabling +// of these client requests. +#if defined(ENABLE_INNER) + +// By default, the inner Valgrind annotates various actions to help +// the outer tool (memcheck or helgrind). +// Undefine the below to have an inner Valgrind without any annotation. +#define ENABLE_INNER_CLIENT_REQUEST 1 + +#if defined(ENABLE_INNER_CLIENT_REQUEST) +#define INNER_REQUEST(__zza) __zza +#else +#define INNER_REQUEST(__zza) do {} while (0) +#endif + +#else + +#define INNER_REQUEST(__zza) do {} while (0) + +#endif + +#endif // __LIBVEX_INNER_H + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/