|
From: <sv...@va...> - 2017-07-27 19:10:41
|
Author: philippe
Date: Thu Jul 27 20:10:30 2017
New Revision: 3399
Log:
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
Added:
trunk/pub/libvex_inner.h
Modified:
trunk/priv/main_util.c
trunk/priv/main_util.h
Modified: trunk/priv/main_util.c
==============================================================================
--- trunk/priv/main_util.c (original)
+++ trunk/priv/main_util.c Thu Jul 27 20:10:30 2017
@@ -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 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 @@
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];
Modified: trunk/priv/main_util.h
==============================================================================
--- trunk/priv/main_util.h (original)
+++ trunk/priv/main_util.h Thu Jul 27 20:10:30 2017
@@ -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 @@
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 @@
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
}
Added: trunk/pub/libvex_inner.h
==============================================================================
--- trunk/pub/libvex_inner.h (added)
+++ trunk/pub/libvex_inner.h Thu Jul 27 20:10:30 2017
@@ -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
+ phi...@sk...
+
+ 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 ---*/
+/*--------------------------------------------------------------------*/
|