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];
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];
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];
#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. */
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 {
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
}
--- /dev/null
+
+/*--------------------------------------------------------------------*/
+/*--- 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 ---*/
+/*--------------------------------------------------------------------*/