Modularised the core/tool interface ('details', 'needs' and VG_(tdict))
into a new module m_tooliface.  Pretty straightforward.  Touches a lot
of files because many files use this interface and so need to include
the headers for the new module.



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3652 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/cachegrind/cg_main.c b/cachegrind/cg_main.c
index 02fccc1..b82d452 100644
--- a/cachegrind/cg_main.c
+++ b/cachegrind/cg_main.c
@@ -31,6 +31,7 @@
 
 #include "tool.h"
 #include "pub_tool_mallocfree.h"
+#include "pub_tool_tooliface.h"
 
 #include "cg_arch.h"
 #include "cg_sim.c"
diff --git a/corecheck/cc_main.c b/corecheck/cc_main.c
index 213e4a2..bae14a8 100644
--- a/corecheck/cc_main.c
+++ b/corecheck/cc_main.c
@@ -30,6 +30,7 @@
 */
 
 #include "tool.h"
+#include "pub_tool_tooliface.h"
 
 static void cc_post_clo_init(void)
 {
diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am
index 4a9ddc9..0d01f4b 100644
--- a/coregrind/Makefile.am
+++ b/coregrind/Makefile.am
@@ -46,6 +46,7 @@
 	pub_core_sigframe.h	\
 	pub_core_stacktrace.h	\
 	pub_core_syscalls.h	\
+	pub_core_tooliface.h	\
 	ume.h			\
 	vg_symtab2.h		\
 	vg_symtypes.h
@@ -65,11 +66,12 @@
 valgrind_LDADD=
 
 stage2_SOURCES = \
+	m_debuglog.c \
 	m_errormgr.c \
 	m_execontext.c \
 	m_mallocfree.c \
 	m_stacktrace.c \
-	m_debuglog.c \
+	m_tooliface.c \
 	ume.c \
 	\
 	vg_scheduler.c \
@@ -78,7 +80,6 @@
 	vg_main.c \
 	vg_messages.c \
 	vg_mylibc.c \
-	vg_needs.c \
 	vg_dummy_profile.c \
 	vg_signals.c \
 	vg_symtab2.c \
diff --git a/coregrind/amd64/state.c b/coregrind/amd64/state.c
index 1ab749f..ebee8f2 100644
--- a/coregrind/amd64/state.c
+++ b/coregrind/amd64/state.c
@@ -7,8 +7,8 @@
    This file is part of Valgrind, a dynamic binary instrumentation
    framework.
 
-   Copyright (C) 2000-2005 Nicholas Nethercote
-      njn@valgrind.org
+   Copyright (C) 2000-2005 Julian Seward
+      jseward@acm.org
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -29,6 +29,7 @@
 */
 
 #include "core.h"
+#include "pub_core_tooliface.h"
 #include "amd64_private.h"
 #include <sys/ptrace.h>
 
@@ -236,4 +237,3 @@
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
 /*--------------------------------------------------------------------*/
-
diff --git a/coregrind/core.h b/coregrind/core.h
index 8c2aece..0ab6bc5 100644
--- a/coregrind/core.h
+++ b/coregrind/core.h
@@ -299,165 +299,6 @@
 
 
 /* ---------------------------------------------------------------------
-   Tool-related types
-   ------------------------------------------------------------------ */
-/* These structs are not exposed to tools to mitigate possibility of
-   binary-incompatibilities when the core/tool interface changes.  Instead,
-   set functions are provided (see include/tool.h). */
-typedef
-   struct {
-      Char* name;
-      Char* version;
-      Char* description;
-      Char* copyright_author;
-      Char* bug_reports_to;
-      UInt  avg_translation_sizeB;
-   }
-   VgDetails;
-
-extern VgDetails VG_(details);
-
-typedef
-   struct {
-      Bool libc_freeres;
-      Bool core_errors;
-      Bool tool_errors;
-      Bool basic_block_discards;
-      Bool no_longer_used_1;     // for backwards compatibility
-      Bool command_line_options;
-      Bool client_requests;
-      Bool no_longer_used_0;     // for backwards compatibility
-      Bool syscall_wrapper;
-      Bool sanity_checks;
-      Bool data_syms;
-      Bool shadow_memory;
-   } 
-   VgNeeds;
-
-extern VgNeeds VG_(needs);
-
-typedef struct {
-   // ---------------------------------------------
-   // 'Needs' and related functions
-   // ---------------------------------------------
-   // Basic functions
-   void  (*tool_pre_clo_init) (void);
-   void  (*tool_post_clo_init)(void);
-   IRBB* (*tool_instrument)   (IRBB*, VexGuestLayout*, IRType, IRType);
-   void  (*tool_fini)         (Int);
-
-   // VG_(needs).core_errors
-   // (none)
-   
-   // VG_(needs).tool_errors
-   Bool  (*tool_eq_Error)                    (VgRes, Error*, Error*);
-   void  (*tool_pp_Error)                    (Error*);
-   UInt  (*tool_update_extra)                (Error*);
-   Bool  (*tool_recognised_suppression)      (Char*, Supp*);
-   Bool  (*tool_read_extra_suppression_info) (Int, Char*, Int, Supp*);
-   Bool  (*tool_error_matches_suppression)   (Error*, Supp*);
-   Char* (*tool_get_error_name)              (Error*);
-   void  (*tool_print_extra_suppression_info)(Error*);
-
-   // VG_(needs).basic_block_discards
-   void (*tool_discard_basic_block_info)(Addr, SizeT);
-
-   // VG_(needs).command_line_options
-   Bool (*tool_process_cmd_line_option)(Char*);
-   void (*tool_print_usage)            (void);
-   void (*tool_print_debug_usage)      (void);
-
-   // VG_(needs).client_requests
-   Bool (*tool_handle_client_request)(ThreadId, UWord*, UWord*);
-
-   // VG_(needs).syscall_wrapper
-   void (*tool_pre_syscall) (ThreadId, UInt);
-   void (*tool_post_syscall)(ThreadId, UInt, Int);
-
-   // VG_(needs).sanity_checks
-   Bool (*tool_cheap_sanity_check)(void);
-   Bool (*tool_expensive_sanity_check)(void);
-
-   // ---------------------------------------------
-   // Event tracking functions
-   // ---------------------------------------------
-   void (*track_new_mem_startup)     (Addr, SizeT, Bool, Bool, Bool);
-   void (*track_new_mem_stack_signal)(Addr, SizeT);
-   void (*track_new_mem_brk)         (Addr, SizeT);
-   void (*track_new_mem_mmap)        (Addr, SizeT, Bool, Bool, Bool);
-
-   void (*track_copy_mem_remap)      (Addr, Addr, SizeT);
-   void (*track_change_mem_mprotect) (Addr, SizeT, Bool, Bool, Bool);
-   void (*track_die_mem_stack_signal)(Addr, SizeT);
-   void (*track_die_mem_brk)         (Addr, SizeT);
-   void (*track_die_mem_munmap)      (Addr, SizeT);
-
-   VGA_REGPARM(1) void (*track_new_mem_stack_4) (Addr);
-   VGA_REGPARM(1) void (*track_new_mem_stack_8) (Addr);
-   VGA_REGPARM(1) void (*track_new_mem_stack_12)(Addr);
-   VGA_REGPARM(1) void (*track_new_mem_stack_16)(Addr);
-   VGA_REGPARM(1) void (*track_new_mem_stack_32)(Addr);
-   void (*track_new_mem_stack)(Addr, SizeT);
-
-   VGA_REGPARM(1) void (*track_die_mem_stack_4) (Addr);
-   VGA_REGPARM(1) void (*track_die_mem_stack_8) (Addr);
-   VGA_REGPARM(1) void (*track_die_mem_stack_12)(Addr);
-   VGA_REGPARM(1) void (*track_die_mem_stack_16)(Addr);
-   VGA_REGPARM(1) void (*track_die_mem_stack_32)(Addr);
-   void (*track_die_mem_stack)(Addr, SizeT);
-
-   void (*track_ban_mem_stack)(Addr, SizeT);
-
-   void (*track_pre_mem_read)       (CorePart, ThreadId, Char*, Addr, SizeT);
-   void (*track_pre_mem_read_asciiz)(CorePart, ThreadId, Char*, Addr);
-   void (*track_pre_mem_write)      (CorePart, ThreadId, Char*, Addr, SizeT);
-   void (*track_post_mem_write)     (CorePart, ThreadId, Addr, SizeT);
-
-   void (*track_pre_reg_read)  (CorePart, ThreadId, Char*, OffT, SizeT);
-   void (*track_post_reg_write)(CorePart, ThreadId,        OffT, SizeT);
-   void (*track_post_reg_write_clientcall_return)(ThreadId, OffT, SizeT, Addr);
-
-   void (*track_thread_run)(ThreadId);
-
-   void (*track_post_thread_create)(ThreadId, ThreadId);
-   void (*track_post_thread_join)  (ThreadId, ThreadId);
-
-   void (*track_pre_mutex_lock)   (ThreadId, void*);
-   void (*track_post_mutex_lock)  (ThreadId, void*);
-   void (*track_post_mutex_unlock)(ThreadId, void*);
-
-   void (*track_pre_deliver_signal) (ThreadId, Int sigNo, Bool);
-   void (*track_post_deliver_signal)(ThreadId, Int sigNo);
-
-   void (*track_init_shadow_page)(Addr);
-
-   // ---------------------------------------------
-   // malloc/free replacements
-   // ---------------------------------------------
-   void* (*malloc_malloc)              (ThreadId, SizeT);
-   void* (*malloc___builtin_new)       (ThreadId, SizeT);
-   void* (*malloc___builtin_vec_new)   (ThreadId, SizeT);
-   void* (*malloc_memalign)            (ThreadId, SizeT, SizeT);
-   void* (*malloc_calloc)              (ThreadId, SizeT, SizeT);
-   void  (*malloc_free)                (ThreadId, void*);
-   void  (*malloc___builtin_delete)    (ThreadId, void*);
-   void  (*malloc___builtin_vec_delete)(ThreadId, void*);
-   void* (*malloc_realloc)             (ThreadId, void*, SizeT);
-
-} VgToolInterface;
-
-extern VgToolInterface VG_(tdict);
-
-
-
-/* ---------------------------------------------------------------------
-   Exports of vg_needs.c
-   ------------------------------------------------------------------ */
-
-void VG_(sanity_check_needs)(void);
-
-
-/* ---------------------------------------------------------------------
    Exports of vg_intercept.c
    ------------------------------------------------------------------ */
 
@@ -1110,25 +951,6 @@
 extern const Int  VG_(tramp_gettimeofday_offset);
 extern const Int  VG_(tramp_time_offset);
 
-/* ---------------------------------------------------------------------
-   Things relating to the used tool
-   ------------------------------------------------------------------ */
-
-// Note the use of C's comma operator here -- it means that we execute both
-// statements, and the rvalue of the whole thing is the rvalue of the last
-// statement.  This lets us say "x = VG_TDICT_CALL(...)" in the required
-// places, while still checking the assertion.
-#define VG_TDICT_CALL(fn, args...) \
-   ( tl_assert2(VG_(tdict).fn, \
-                "you forgot to set VgToolInterface function '" #fn "'"), \
-     VG_(tdict).fn(args) )
-
-#define VG_TRACK(fn, args...) 			\
-   do {						\
-      if (VG_(tdict).track_##fn)		\
-	 VG_(tdict).track_##fn(args);           \
-   } while(0)
-
 // ---------------------------------------------------------------------
 // Architecture-specific things defined in eg. x86/*.c
 // ---------------------------------------------------------------------
diff --git a/coregrind/linux/core_os.c b/coregrind/linux/core_os.c
index 7b25cb1..c5d990d 100644
--- a/coregrind/linux/core_os.c
+++ b/coregrind/linux/core_os.c
@@ -1,4 +1,35 @@
+
+/*--------------------------------------------------------------------*/
+/*--- OS-specific stuff.                           linux/core_os.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2000-2005 Nicholas Nethercote
+      njn@valgrind.org
+
+   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.
+*/
+
 #include "core.h"
+#include "pub_core_tooliface.h"
 
 void VGA_(os_state_clear)(ThreadState *tst)
 {
@@ -169,3 +200,7 @@
 
    return handled;
 }
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
diff --git a/coregrind/linux/sema.c b/coregrind/linux/sema.c
index e15392d..09b6efc 100644
--- a/coregrind/linux/sema.c
+++ b/coregrind/linux/sema.c
@@ -1,3 +1,34 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Semaphore stuff.                                linux/sema.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2000-2005 Julian Seward
+      jseward@acm.org
+   (except where noted below)
+
+   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.
+*/
+
 #include "core.h"
 
 #if FUTEX_SEMA
@@ -6,8 +37,7 @@
 
    Taken from futex-2.2/usersem.c
    Based on work by Matthew Kirkwood <matthew@hairy.beasts.org>. 
- */
-
+*/
 
 #define FUTEX_PASSED (-(1024 * 1024 * 1024))
 
@@ -110,3 +140,9 @@
 }
 
 #endif	/* FUTEX_SEMA */
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
+
+
diff --git a/coregrind/m_aspacemgr/aspacemgr.c b/coregrind/m_aspacemgr/aspacemgr.c
index b4e1a87..eb70990 100644
--- a/coregrind/m_aspacemgr/aspacemgr.c
+++ b/coregrind/m_aspacemgr/aspacemgr.c
@@ -33,6 +33,7 @@
 #include "core.h"
 #include "pub_core_aspacemgr.h"
 #include "pub_core_syscalls.h"
+#include "pub_core_tooliface.h"
 
 
 /* Define to debug the memory-leak-detector. */
diff --git a/coregrind/m_errormgr.c b/coregrind/m_errormgr.c
index 70ccb09..264e03f 100644
--- a/coregrind/m_errormgr.c
+++ b/coregrind/m_errormgr.c
@@ -32,6 +32,7 @@
 #include "pub_core_errormgr.h"
 #include "pub_core_execontext.h"
 #include "pub_core_stacktrace.h"
+#include "pub_core_tooliface.h"
 
 /*------------------------------------------------------------*/
 /*--- Globals                                              ---*/
diff --git a/coregrind/m_sigframe/sigframe-amd64-linux.c b/coregrind/m_sigframe/sigframe-amd64-linux.c
index 8c765c4..df1e085 100644
--- a/coregrind/m_sigframe/sigframe-amd64-linux.c
+++ b/coregrind/m_sigframe/sigframe-amd64-linux.c
@@ -30,8 +30,9 @@
 */
 
 #include "core.h"
-#include "pub_core_sigframe.h"
 #include "pub_core_aspacemgr.h"
+#include "pub_core_sigframe.h"
+#include "pub_core_tooliface.h"
 
 #include "libvex_guest_amd64.h"
 
diff --git a/coregrind/m_sigframe/sigframe-x86-linux.c b/coregrind/m_sigframe/sigframe-x86-linux.c
index e19cac7..9df64f9 100644
--- a/coregrind/m_sigframe/sigframe-x86-linux.c
+++ b/coregrind/m_sigframe/sigframe-x86-linux.c
@@ -30,9 +30,9 @@
 */
 
 #include "core.h"
-#include "pub_core_sigframe.h"
 #include "pub_core_aspacemgr.h" /* find_segment */
-
+#include "pub_core_sigframe.h"
+#include "pub_core_tooliface.h"
 
 #include "libvex_guest_x86.h"
 
diff --git a/coregrind/m_syscalls/syscalls-amd64-linux.c b/coregrind/m_syscalls/syscalls-amd64-linux.c
index 2d253c9..fb4e754 100644
--- a/coregrind/m_syscalls/syscalls-amd64-linux.c
+++ b/coregrind/m_syscalls/syscalls-amd64-linux.c
@@ -33,6 +33,7 @@
 #include "pub_core_aspacemgr.h"
 #include "pub_core_sigframe.h"
 #include "pub_core_syscalls.h"
+#include "pub_core_tooliface.h"
 #include "priv_syscalls.h"
 
 
diff --git a/coregrind/m_syscalls/syscalls-linux.c b/coregrind/m_syscalls/syscalls-linux.c
index 028701f..1902b24 100644
--- a/coregrind/m_syscalls/syscalls-linux.c
+++ b/coregrind/m_syscalls/syscalls-linux.c
@@ -30,6 +30,7 @@
 
 #include "core.h"
 #include "pub_core_aspacemgr.h"
+#include "pub_core_tooliface.h"
 #include "priv_syscalls.h"
 
 /* ---------------------------------------------------------------------
diff --git a/coregrind/m_syscalls/syscalls-x86-linux.c b/coregrind/m_syscalls/syscalls-x86-linux.c
index 201da46..f3eeeaa 100644
--- a/coregrind/m_syscalls/syscalls-x86-linux.c
+++ b/coregrind/m_syscalls/syscalls-x86-linux.c
@@ -38,6 +38,7 @@
 #include "pub_core_aspacemgr.h"
 #include "pub_core_sigframe.h"
 #include "pub_core_syscalls.h"
+#include "pub_core_tooliface.h"
 #include "priv_syscalls.h"
 
 
diff --git a/coregrind/m_syscalls/syscalls.c b/coregrind/m_syscalls/syscalls.c
index 66d4e1d..82bf2e5 100644
--- a/coregrind/m_syscalls/syscalls.c
+++ b/coregrind/m_syscalls/syscalls.c
@@ -32,6 +32,7 @@
 #include "pub_core_aspacemgr.h"
 #include "pub_core_stacktrace.h"
 #include "pub_core_syscalls.h"
+#include "pub_core_tooliface.h"
 #include "priv_syscalls.h"
 
 
diff --git a/coregrind/vg_needs.c b/coregrind/m_tooliface.c
similarity index 99%
rename from coregrind/vg_needs.c
rename to coregrind/m_tooliface.c
index 9627a61..f007eaa 100644
--- a/coregrind/vg_needs.c
+++ b/coregrind/m_tooliface.c
@@ -30,6 +30,7 @@
 */
 
 #include "core.h"
+#include "pub_core_tooliface.h"
 
 // The core/tool dictionary of functions (initially zeroed, as we want it)
 VgToolInterface VG_(tdict);
diff --git a/coregrind/pub_core_aspacemgr.h b/coregrind/pub_core_aspacemgr.h
index 0debc0d..1c01ece 100644
--- a/coregrind/pub_core_aspacemgr.h
+++ b/coregrind/pub_core_aspacemgr.h
@@ -1,7 +1,6 @@
 
 /*--------------------------------------------------------------------*/
-/*--- The address space manager.                                   ---*/
-/*---                                         pub_core_aspacemgr.h ---*/
+/*--- The address space manager.              pub_core_aspacemgr.h ---*/
 /*--------------------------------------------------------------------*/
 
 /*
diff --git a/coregrind/pub_core_tooliface.h b/coregrind/pub_core_tooliface.h
new file mode 100644
index 0000000..e695c73
--- /dev/null
+++ b/coregrind/pub_core_tooliface.h
@@ -0,0 +1,220 @@
+
+/*--------------------------------------------------------------------*/
+/*--- The core/tool interface.                pub_core_tooliface.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2000-2005 Julian Seward
+      jseward@acm.org
+
+   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 __PUB_CORE_TOOLIFACE_H
+#define __PUB_CORE_TOOLIFACE_H
+
+#include "pub_tool_tooliface.h"
+
+//--------------------------------------------------------------------
+// PURPOSE: This module encapsulates the key parts of the core/tool
+// interface: 'details', 'needs' and 'trackable events'.
+//--------------------------------------------------------------------
+
+// Note the use of C's comma operator here -- it means that we execute both
+// statements, and the rvalue of the whole thing is the rvalue of the last
+// statement.  This lets us say "x = VG_TDICT_CALL(...)" in the required
+// places, while still checking the assertion.
+#define VG_TDICT_CALL(fn, args...) \
+   ( tl_assert2(VG_(tdict).fn, \
+                "you forgot to set VgToolInterface function '" #fn "'"), \
+     VG_(tdict).fn(args) )
+
+#define VG_TRACK(fn, args...) 			\
+   do {						\
+      if (VG_(tdict).track_##fn)		\
+	 VG_(tdict).track_##fn(args);           \
+   } while(0)
+
+/* These structs are not exposed to tools to mitigate possibility of
+   binary-incompatibilities when the core/tool interface changes.  Instead,
+   set functions are provided (see include/tool.h). */
+
+/* ---------------------------------------------------------------------
+   'Details'
+   ------------------------------------------------------------------ */
+
+typedef
+   struct {
+      Char* name;
+      Char* version;
+      Char* description;
+      Char* copyright_author;
+      Char* bug_reports_to;
+      UInt  avg_translation_sizeB;
+   }
+   VgDetails;
+
+extern VgDetails VG_(details);
+
+/* ---------------------------------------------------------------------
+   'Needs'
+   ------------------------------------------------------------------ */
+
+typedef
+   struct {
+      Bool libc_freeres;
+      Bool core_errors;
+      Bool tool_errors;
+      Bool basic_block_discards;
+      Bool no_longer_used_1;     // for backwards compatibility
+      Bool command_line_options;
+      Bool client_requests;
+      Bool no_longer_used_0;     // for backwards compatibility
+      Bool syscall_wrapper;
+      Bool sanity_checks;
+      Bool data_syms;
+      Bool shadow_memory;
+   } 
+   VgNeeds;
+
+extern VgNeeds VG_(needs);
+
+/* ---------------------------------------------------------------------
+   The dictionary of callable tool functions
+   ------------------------------------------------------------------ */
+
+typedef struct {
+   // -- 'Needs'-related functions ----------------------------------
+   // Basic functions
+   void  (*tool_pre_clo_init) (void);
+   void  (*tool_post_clo_init)(void);
+   IRBB* (*tool_instrument)   (IRBB*, VexGuestLayout*, IRType, IRType);
+   void  (*tool_fini)         (Int);
+
+   // VG_(needs).core_errors
+   // (none)
+   
+   // VG_(needs).tool_errors
+   Bool  (*tool_eq_Error)                    (VgRes, Error*, Error*);
+   void  (*tool_pp_Error)                    (Error*);
+   UInt  (*tool_update_extra)                (Error*);
+   Bool  (*tool_recognised_suppression)      (Char*, Supp*);
+   Bool  (*tool_read_extra_suppression_info) (Int, Char*, Int, Supp*);
+   Bool  (*tool_error_matches_suppression)   (Error*, Supp*);
+   Char* (*tool_get_error_name)              (Error*);
+   void  (*tool_print_extra_suppression_info)(Error*);
+
+   // VG_(needs).basic_block_discards
+   void (*tool_discard_basic_block_info)(Addr, SizeT);
+
+   // VG_(needs).command_line_options
+   Bool (*tool_process_cmd_line_option)(Char*);
+   void (*tool_print_usage)            (void);
+   void (*tool_print_debug_usage)      (void);
+
+   // VG_(needs).client_requests
+   Bool (*tool_handle_client_request)(ThreadId, UWord*, UWord*);
+
+   // VG_(needs).syscall_wrapper
+   void (*tool_pre_syscall) (ThreadId, UInt);
+   void (*tool_post_syscall)(ThreadId, UInt, Int);
+
+   // VG_(needs).sanity_checks
+   Bool (*tool_cheap_sanity_check)(void);
+   Bool (*tool_expensive_sanity_check)(void);
+
+   // -- Event tracking functions ------------------------------------
+   void (*track_new_mem_startup)     (Addr, SizeT, Bool, Bool, Bool);
+   void (*track_new_mem_stack_signal)(Addr, SizeT);
+   void (*track_new_mem_brk)         (Addr, SizeT);
+   void (*track_new_mem_mmap)        (Addr, SizeT, Bool, Bool, Bool);
+
+   void (*track_copy_mem_remap)      (Addr, Addr, SizeT);
+   void (*track_change_mem_mprotect) (Addr, SizeT, Bool, Bool, Bool);
+   void (*track_die_mem_stack_signal)(Addr, SizeT);
+   void (*track_die_mem_brk)         (Addr, SizeT);
+   void (*track_die_mem_munmap)      (Addr, SizeT);
+
+   VGA_REGPARM(1) void (*track_new_mem_stack_4) (Addr);
+   VGA_REGPARM(1) void (*track_new_mem_stack_8) (Addr);
+   VGA_REGPARM(1) void (*track_new_mem_stack_12)(Addr);
+   VGA_REGPARM(1) void (*track_new_mem_stack_16)(Addr);
+   VGA_REGPARM(1) void (*track_new_mem_stack_32)(Addr);
+   void (*track_new_mem_stack)(Addr, SizeT);
+
+   VGA_REGPARM(1) void (*track_die_mem_stack_4) (Addr);
+   VGA_REGPARM(1) void (*track_die_mem_stack_8) (Addr);
+   VGA_REGPARM(1) void (*track_die_mem_stack_12)(Addr);
+   VGA_REGPARM(1) void (*track_die_mem_stack_16)(Addr);
+   VGA_REGPARM(1) void (*track_die_mem_stack_32)(Addr);
+   void (*track_die_mem_stack)(Addr, SizeT);
+
+   void (*track_ban_mem_stack)(Addr, SizeT);
+
+   void (*track_pre_mem_read)       (CorePart, ThreadId, Char*, Addr, SizeT);
+   void (*track_pre_mem_read_asciiz)(CorePart, ThreadId, Char*, Addr);
+   void (*track_pre_mem_write)      (CorePart, ThreadId, Char*, Addr, SizeT);
+   void (*track_post_mem_write)     (CorePart, ThreadId, Addr, SizeT);
+
+   void (*track_pre_reg_read)  (CorePart, ThreadId, Char*, OffT, SizeT);
+   void (*track_post_reg_write)(CorePart, ThreadId,        OffT, SizeT);
+   void (*track_post_reg_write_clientcall_return)(ThreadId, OffT, SizeT, Addr);
+
+   void (*track_thread_run)(ThreadId);
+
+   void (*track_post_thread_create)(ThreadId, ThreadId);
+   void (*track_post_thread_join)  (ThreadId, ThreadId);
+
+   void (*track_pre_mutex_lock)   (ThreadId, void*);
+   void (*track_post_mutex_lock)  (ThreadId, void*);
+   void (*track_post_mutex_unlock)(ThreadId, void*);
+
+   void (*track_pre_deliver_signal) (ThreadId, Int sigNo, Bool);
+   void (*track_post_deliver_signal)(ThreadId, Int sigNo);
+
+   void (*track_init_shadow_page)(Addr);
+
+   // -- malloc/free replacements -----------------------------------
+   void* (*malloc_malloc)              (ThreadId, SizeT);
+   void* (*malloc___builtin_new)       (ThreadId, SizeT);
+   void* (*malloc___builtin_vec_new)   (ThreadId, SizeT);
+   void* (*malloc_memalign)            (ThreadId, SizeT, SizeT);
+   void* (*malloc_calloc)              (ThreadId, SizeT, SizeT);
+   void  (*malloc_free)                (ThreadId, void*);
+   void  (*malloc___builtin_delete)    (ThreadId, void*);
+   void  (*malloc___builtin_vec_delete)(ThreadId, void*);
+   void* (*malloc_realloc)             (ThreadId, void*, SizeT);
+
+} VgToolInterface;
+
+extern VgToolInterface VG_(tdict);
+
+/* ---------------------------------------------------------------------
+   Miscellaneous functions
+   ------------------------------------------------------------------ */
+
+void VG_(sanity_check_needs)(void);
+
+#endif   // __PUB_CORE_TOOLIFACE_H
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
diff --git a/coregrind/vg_main.c b/coregrind/vg_main.c
index ba89b42..71196fe 100644
--- a/coregrind/vg_main.c
+++ b/coregrind/vg_main.c
@@ -37,6 +37,7 @@
 #include "pub_core_errormgr.h"
 #include "pub_core_execontext.h"
 #include "pub_core_syscalls.h"
+#include "pub_core_tooliface.h"
 
 #include <dirent.h>
 #include <dlfcn.h>
diff --git a/coregrind/vg_mylibc.c b/coregrind/vg_mylibc.c
index caf5af2..750d59b 100644
--- a/coregrind/vg_mylibc.c
+++ b/coregrind/vg_mylibc.c
@@ -35,6 +35,7 @@
 #include "pub_core_debuglog.h"    /* VG_(debugLog_vprintf) */
 #include "pub_core_stacktrace.h"
 #include "pub_core_syscalls.h"
+#include "pub_core_tooliface.h"
 
 
 /* ---------------------------------------------------------------------
diff --git a/coregrind/vg_scheduler.c b/coregrind/vg_scheduler.c
index 4a4eacc..d0ee0d8 100644
--- a/coregrind/vg_scheduler.c
+++ b/coregrind/vg_scheduler.c
@@ -64,6 +64,7 @@
 #include "pub_core_replacemalloc.h"
 #include "pub_core_stacktrace.h"
 #include "pub_core_syscalls.h"
+#include "pub_core_tooliface.h"
 
 /* ---------------------------------------------------------------------
    Types and globals for the scheduler.
diff --git a/coregrind/vg_signals.c b/coregrind/vg_signals.c
index 4496b20..79d2d97 100644
--- a/coregrind/vg_signals.c
+++ b/coregrind/vg_signals.c
@@ -85,6 +85,7 @@
 #include "pub_core_errormgr.h"
 #include "pub_core_sigframe.h"
 #include "pub_core_syscalls.h"
+#include "pub_core_tooliface.h"
 
 
 /* Define to give more sanity checking for signals. */
diff --git a/coregrind/vg_symtab2.c b/coregrind/vg_symtab2.c
index 23d5a51..1f1b861 100644
--- a/coregrind/vg_symtab2.c
+++ b/coregrind/vg_symtab2.c
@@ -34,8 +34,9 @@
 #include "vg_symtab2.h"
 
 #include "pub_core_aspacemgr.h"
+#include "pub_core_tooliface.h"
 
-#include <elf.h>          /* ELF defns                      */
+#include <elf.h>          /* ELF defns */
 
 static SegInfo* segInfo = NULL;
 
diff --git a/coregrind/vg_symtypes.c b/coregrind/vg_symtypes.c
index 10c421b..6b5f4db 100644
--- a/coregrind/vg_symtypes.c
+++ b/coregrind/vg_symtypes.c
@@ -30,6 +30,7 @@
 #include "core.h"
 #include "vg_symtypes.h"
 #include "pub_core_debuglog.h"    /* VG_(debugLog_vprintf) */
+#include "pub_core_tooliface.h"
 
 typedef enum {
    TyUnknown,			/* unknown type */
diff --git a/coregrind/vg_translate.c b/coregrind/vg_translate.c
index b28d0e9..a4218bf 100644
--- a/coregrind/vg_translate.c
+++ b/coregrind/vg_translate.c
@@ -31,6 +31,7 @@
 
 #include "core.h"
 #include "pub_core_aspacemgr.h"
+#include "pub_core_tooliface.h"
 
 
 /*------------------------------------------------------------*/
diff --git a/coregrind/vg_transtab.c b/coregrind/vg_transtab.c
index 69f7254..535184d 100644
--- a/coregrind/vg_transtab.c
+++ b/coregrind/vg_transtab.c
@@ -30,6 +30,7 @@
 */
 
 #include "core.h"
+#include "pub_core_tooliface.h"
 
 /* #define DEBUG_TRANSTAB */
 
@@ -575,11 +576,8 @@
                    "(startup of code management)");
 
    /* Figure out how big each tc area should be.  */
-   avg_codeszQ 
-      = (VG_(details).avg_translation_sizeB + 7) / 8;
-
-   tc_sector_szQ
-      = N_TTES_PER_SECTOR_USABLE * (1 + avg_codeszQ);
+   avg_codeszQ   = (VG_(details).avg_translation_sizeB + 7) / 8;
+   tc_sector_szQ = N_TTES_PER_SECTOR_USABLE * (1 + avg_codeszQ);
 
    /* Ensure the calculated value is not way crazy. */
    vg_assert(tc_sector_szQ >= 2 * N_TTES_PER_SECTOR_USABLE);
diff --git a/coregrind/x86-linux/ldt.c b/coregrind/x86-linux/ldt.c
index e35ac14..968de80 100644
--- a/coregrind/x86-linux/ldt.c
+++ b/coregrind/x86-linux/ldt.c
@@ -84,6 +84,7 @@
 */
 
 #include "core.h"
+#include "pub_core_tooliface.h"
 #include "x86_private.h"
 #include "libvex_guest_x86.h"
 
diff --git a/coregrind/x86/state.c b/coregrind/x86/state.c
index f74e711..161c6c2 100644
--- a/coregrind/x86/state.c
+++ b/coregrind/x86/state.c
@@ -29,6 +29,7 @@
 */
 
 #include "core.h"
+#include "pub_core_tooliface.h"
 #include "x86_private.h"
 #include <sys/ptrace.h>
 
@@ -345,4 +346,3 @@
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
 /*--------------------------------------------------------------------*/
-
diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c
index 0677c80..4a028b8 100644
--- a/helgrind/hg_main.c
+++ b/helgrind/hg_main.c
@@ -32,6 +32,7 @@
 #include "tool.h"
 #include "pub_tool_mallocfree.h"
 #include "pub_tool_replacemalloc.h"
+#include "pub_tool_tooliface.h"
 
 #include "helgrind.h"
 
diff --git a/include/Makefile.am b/include/Makefile.am
index 75fdaea..c346bbf 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -17,6 +17,7 @@
 	pub_tool_mallocfree.h 	\
 	pub_tool_replacemalloc.h\
 	pub_tool_stacktrace.h 	\
+	pub_tool_tooliface.h 	\
 	valgrind.h
 
 BUILT_SOURCES = valgrind.h
diff --git a/include/pub_tool_tooliface.h b/include/pub_tool_tooliface.h
new file mode 100644
index 0000000..f5840b5
--- /dev/null
+++ b/include/pub_tool_tooliface.h
@@ -0,0 +1,408 @@
+
+/*--------------------------------------------------------------------*/
+/*--- The core/tool interface.                pub_tool_tooliface.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2000-2005 Julian Seward
+      jseward@acm.org
+
+   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 __PUB_TOOL_TOOLIFACE_H
+#define __PUB_TOOL_TOOLIFACE_H
+
+/* ------------------------------------------------------------------ */
+/* The interface version */
+
+/* The version number indicates binary-incompatible changes to the
+   interface;  if the core and tool versions don't match, Valgrind
+   will abort.  */
+#define VG_CORE_INTERFACE_VERSION   8
+
+typedef struct _ToolInfo {
+   Int	sizeof_ToolInfo;
+   Int	interface_version;
+
+   /* Initialise tool.   Must do the following:
+      - initialise the `details' struct, via the VG_(details_*)() functions
+      - register any helpers called by generated code
+      
+      May do the following:
+      - initialise the `needs' struct to indicate certain requirements, via
+      the VG_(needs_*)() functions
+      - initialize all the tool's entrypoints via the VG_(init_*)() functions
+      - register any tool-specific profiling events
+      - any other tool-specific initialisation
+   */
+   void (*tl_pre_clo_init) ( void );
+
+   /* Specifies how big the shadow segment should be as a ratio to the
+      client address space.  0 for no shadow segment. */
+   float shadow_ratio;
+} ToolInfo;
+
+/* Every tool must include this macro somewhere, exactly once. */
+#define VG_DETERMINE_INTERFACE_VERSION(pre_clo_init, shadow)   \
+   const ToolInfo VG_(tool_info) = {                           \
+      .sizeof_ToolInfo   = sizeof(ToolInfo),                   \
+      .interface_version = VG_CORE_INTERFACE_VERSION,          \
+      .tl_pre_clo_init   = pre_clo_init,                       \
+      .shadow_ratio	 = shadow,                             \
+   };
+
+/* ------------------------------------------------------------------ */
+/* Basic tool functions */
+
+extern void VG_(basic_tool_funcs)(
+   // Do any initialisation that can only be done after command line
+   // processing.
+   void  (*post_clo_init)(void),
+
+   // Instrument a basic block.  Must be a true function, ie. the same input
+   // always results in the same output, because basic blocks can be
+   // retranslated.  Unless you're doing something really strange...
+   IRBB* (*instrument)(IRBB* bb_in, VexGuestLayout* layout, 
+                       IRType gWordTy, IRType hWordTy ),
+
+   // Finish up, print out any results, etc.  `exitcode' is program's exit
+   // code.  The shadow can be found with VG_(get_exit_status_shadow)().
+   void  (*fini)(Int)
+);
+
+/* ------------------------------------------------------------------ */
+/* Details */
+
+/* Default value for avg_translations_sizeB (in bytes), indicating typical
+   code expansion of about 6:1. */
+#define VG_DEFAULT_TRANS_SIZEB   100
+
+/* Information used in the startup message.  `name' also determines the
+   string used for identifying suppressions in a suppression file as
+   belonging to this tool.  `version' can be NULL, in which case (not
+   surprisingly) no version info is printed; this mechanism is designed for
+   tools distributed with Valgrind that share a version number with
+   Valgrind.  Other tools not distributed as part of Valgrind should
+   probably have their own version number.  */
+extern void VG_(details_name)                  ( Char* name );
+extern void VG_(details_version)               ( Char* version );
+extern void VG_(details_description)           ( Char* description );
+extern void VG_(details_copyright_author)      ( Char* copyright_author );
+
+/* Average size of a translation, in bytes, so that the translation
+   storage machinery can allocate memory appropriately.  Not critical,
+   setting is optional. */
+extern void VG_(details_avg_translation_sizeB) ( UInt size );
+
+/* String printed if an `tl_assert' assertion fails or VG_(tool_panic)
+   is called.  Should probably be an email address. */
+extern void VG_(details_bug_reports_to)   ( Char* bug_reports_to );
+
+/* ------------------------------------------------------------------ */
+/* Needs */
+
+/* Booleans that decide core behaviour, but don't require extra
+   operations to be defined if `True' */
+
+/* Should __libc_freeres() be run?  Bugs in it can crash the tool. */
+extern void VG_(needs_libc_freeres) ( void );
+
+/* Want to have errors detected by Valgrind's core reported?  Includes:
+   - pthread API errors (many;  eg. unlocking a non-locked mutex)
+   - invalid file descriptors to blocking syscalls read() and write()
+   - bad signal numbers passed to sigaction()
+   - attempt to install signal handler for SIGKILL or SIGSTOP */
+extern void VG_(needs_core_errors) ( void );
+
+/* Booleans that indicate extra operations are defined;  if these are True,
+   the corresponding template functions (given below) must be defined.  A
+   lot like being a member of a type class. */
+
+/* Want to report errors from tool?  This implies use of suppressions, too. */
+extern void VG_(needs_tool_errors) (
+   // Identify if two errors are equal, or equal enough.  `res' indicates how
+   // close is "close enough".  `res' should be passed on as necessary, eg. if
+   // the Error's `extra' part contains an ExeContext, `res' should be
+   // passed to VG_(eq_ExeContext)() if the ExeContexts are considered.  Other
+   // than that, probably don't worry about it unless you have lots of very
+   // similar errors occurring.
+   Bool (*eq_Error)(VgRes res, Error* e1, Error* e2),
+
+   // Print error context.
+   void (*pp_Error)(Error* err),
+
+   // Should fill in any details that could be postponed until after the
+   // decision whether to ignore the error (ie. details not affecting the
+   // result of VG_(tdict).tool_eq_Error()).  This saves time when errors
+   // are ignored.
+   // Yuk.
+   // Return value: must be the size of the `extra' part in bytes -- used by
+   // the core to make a copy.
+   UInt (*update_extra)(Error* err),
+
+   // Return value indicates recognition.  If recognised, must set skind using
+   // VG_(set_supp_kind)().
+   Bool (*recognised_suppression)(Char* name, Supp* su),
+
+   // Read any extra info for this suppression kind.  Most likely for filling
+   // in the `extra' and `string' parts (with VG_(set_supp_{extra, string})())
+   // of a suppression if necessary.  Should return False if a syntax error
+   // occurred, True otherwise.
+   Bool (*read_extra_suppression_info)(Int fd, Char* buf, Int nBuf, Supp* su),
+
+   // This should just check the kinds match and maybe some stuff in the
+   // `string' and `extra' field if appropriate (using VG_(get_supp_*)() to
+   // get the relevant suppression parts).
+   Bool (*error_matches_suppression)(Error* err, Supp* su),
+
+   // This should return the suppression name, for --gen-suppressions, or NULL
+   // if that error type cannot be suppressed.  This is the inverse of
+   // VG_(tdict).tool_recognised_suppression().
+   Char* (*get_error_name)(Error* err),
+
+   // This should print any extra info for the error, for --gen-suppressions,
+   // including the newline.  This is the inverse of
+   // VG_(tdict).tool_read_extra_suppression_info().
+   void (*print_extra_suppression_info)(Error* err)
+);
+
+
+/* Is information kept about specific individual basic blocks?  (Eg. for
+   cachegrind there are cost-centres for every instruction, stored at a
+   basic block level.)  If so, it sometimes has to be discarded, because
+   .so mmap/munmap-ping or self-modifying code (informed by the
+   DISCARD_TRANSLATIONS user request) can cause one instruction address
+   to be used for more than one instruction in one program run...  */
+extern void VG_(needs_basic_block_discards) (
+   // Should discard any information that pertains to specific basic blocks
+   // or instructions within the address range given.
+   void (*discard_basic_block_info)(Addr a, SizeT size)
+);
+
+/* Tool defines its own command line options? */
+extern void VG_(needs_command_line_options) (
+   // Return True if option was recognised.  Presumably sets some state to
+   // record the option as well.
+   Bool (*process_cmd_line_option)(Char* argv),
+
+   // Print out command line usage for options for normal tool operation.
+   void (*print_usage)(void),
+
+   // Print out command line usage for options for debugging the tool.
+   void (*print_debug_usage)(void)
+);
+
+/* Tool defines its own client requests? */
+extern void VG_(needs_client_requests) (
+   // If using client requests, the number of the first request should be equal
+   // to VG_USERREQ_TOOL_BASE('X', 'Y'), where 'X' and 'Y' form a suitable two
+   // character identification for the string.  The second and subsequent
+   // requests should follow.
+   //
+   // This function should use the VG_IS_TOOL_USERREQ macro (in
+   // include/valgrind.h) to first check if it's a request for this tool.  Then
+   // should handle it if it's recognised (and return True), or return False if
+   // not recognised.  arg_block[0] holds the request number, any further args
+   // from the request are in arg_block[1..].  'ret' is for the return value...
+   // it should probably be filled, if only with 0.
+   Bool (*handle_client_request)(ThreadId tid, UWord* arg_block, UWord* ret)
+);
+
+/* Tool does stuff before and/or after system calls? */
+// Nb: If either of the pre_ functions malloc() something to return, the
+// corresponding post_ function had better free() it!
+extern void VG_(needs_syscall_wrapper) (
+   void (* pre_syscall)(ThreadId tid, UInt syscallno),
+   void (*post_syscall)(ThreadId tid, UInt syscallno, Int res)
+);
+
+/* Are tool-state sanity checks performed? */
+// Can be useful for ensuring a tool's correctness.  cheap_sanity_check()
+// is called very frequently;  expensive_sanity_check() is called less
+// frequently and can be more involved.
+extern void VG_(needs_sanity_checks) (
+   Bool(*cheap_sanity_check)(void),
+   Bool(*expensive_sanity_check)(void)
+);
+
+/* Do we need to see data symbols? */
+extern void VG_(needs_data_syms) ( void );
+
+/* Does the tool need shadow memory allocated? */
+extern void VG_(needs_shadow_memory)( void );
+
+/* ------------------------------------------------------------------ */
+/* Malloc replacement */
+
+// The 'p' prefix avoids GCC complaints about overshadowing global names.
+extern void VG_(malloc_funcs)(
+   void* (*pmalloc)               ( ThreadId tid, SizeT n ),
+   void* (*p__builtin_new)        ( ThreadId tid, SizeT n ),
+   void* (*p__builtin_vec_new)    ( ThreadId tid, SizeT n ),
+   void* (*pmemalign)             ( ThreadId tid, SizeT align, SizeT n ),
+   void* (*pcalloc)               ( ThreadId tid, SizeT nmemb, SizeT size1 ),
+   void  (*pfree)                 ( ThreadId tid, void* p ),
+   void  (*p__builtin_delete)     ( ThreadId tid, void* p ),
+   void  (*p__builtin_vec_delete) ( ThreadId tid, void* p ),
+   void* (*prealloc)              ( ThreadId tid, void* p, SizeT new_size ),
+   SizeT client_malloc_redzone_szB
+);
+
+/* ------------------------------------------------------------------ */
+/* Core events to track */
+
+/* Part of the core from which this call was made.  Useful for determining
+   what kind of error message should be emitted. */
+typedef
+   enum { Vg_CoreStartup, Vg_CorePThread, Vg_CoreSignal, Vg_CoreSysCall,
+          Vg_CoreTranslate, Vg_CoreClientReq }
+   CorePart;
+
+/* Events happening in core to track.  To be notified, pass a callback
+   function to the appropriate function.  To ignore an event, don't do
+   anything (the default is for events to be ignored).
+
+   Note that most events aren't passed a ThreadId.  If the event is one called
+   from generated code (eg. new_mem_stack_*), you can use
+   VG_(get_running_tid)() to find it.  Otherwise, it has to be passed in,
+   as in pre_mem_read, and so the event signature will require changing.
+
+   Memory events (Nb: to track heap allocation/freeing, a tool must replace
+   malloc() et al.  See above how to do this.)
+
+   These ones occur at startup, upon some signals, and upon some syscalls
+ */
+void VG_(track_new_mem_startup)     (void(*f)(Addr a, SizeT len,
+                                              Bool rr, Bool ww, Bool xx));
+void VG_(track_new_mem_stack_signal)(void(*f)(Addr a, SizeT len));
+void VG_(track_new_mem_brk)         (void(*f)(Addr a, SizeT len));
+void VG_(track_new_mem_mmap)        (void(*f)(Addr a, SizeT len,
+                                              Bool rr, Bool ww, Bool xx));
+
+void VG_(track_copy_mem_remap)      (void(*f)(Addr from, Addr to, SizeT len));
+void VG_(track_change_mem_mprotect) (void(*f)(Addr a, SizeT len,
+                                              Bool rr, Bool ww, Bool xx));
+void VG_(track_die_mem_stack_signal)(void(*f)(Addr a, SizeT len));
+void VG_(track_die_mem_brk)         (void(*f)(Addr a, SizeT len));
+void VG_(track_die_mem_munmap)      (void(*f)(Addr a, SizeT len));
+
+/* These ones are called when SP changes.  A tool could track these itself
+   (except for ban_mem_stack) but it's much easier to use the core's help.
+
+   The specialised ones are called in preference to the general one, if they
+   are defined.  These functions are called a lot if they are used, so
+   specialising can optimise things significantly.  If any of the
+   specialised cases are defined, the general case must be defined too.
+
+   Nb: all the specialised ones must use the VGA_REGPARM(n) attribute.
+ */
+void VG_(track_new_mem_stack_4) (VGA_REGPARM(1) void(*f)(Addr new_ESP));
+void VG_(track_new_mem_stack_8) (VGA_REGPARM(1) void(*f)(Addr new_ESP));
+void VG_(track_new_mem_stack_12)(VGA_REGPARM(1) void(*f)(Addr new_ESP));
+void VG_(track_new_mem_stack_16)(VGA_REGPARM(1) void(*f)(Addr new_ESP));
+void VG_(track_new_mem_stack_32)(VGA_REGPARM(1) void(*f)(Addr new_ESP));
+void VG_(track_new_mem_stack)                  (void(*f)(Addr a, SizeT len));
+
+void VG_(track_die_mem_stack_4) (VGA_REGPARM(1) void(*f)(Addr die_ESP));
+void VG_(track_die_mem_stack_8) (VGA_REGPARM(1) void(*f)(Addr die_ESP));
+void VG_(track_die_mem_stack_12)(VGA_REGPARM(1) void(*f)(Addr die_ESP));
+void VG_(track_die_mem_stack_16)(VGA_REGPARM(1) void(*f)(Addr die_ESP));
+void VG_(track_die_mem_stack_32)(VGA_REGPARM(1) void(*f)(Addr die_ESP));
+void VG_(track_die_mem_stack)                  (void(*f)(Addr a, SizeT len));
+
+/* Used for redzone at end of thread stacks */
+void VG_(track_ban_mem_stack)      (void(*f)(Addr a, SizeT len));
+
+/* These ones occur around syscalls, signal handling, etc */
+void VG_(track_pre_mem_read)       (void(*f)(CorePart part, ThreadId tid,
+                                             Char* s, Addr a, SizeT size));
+void VG_(track_pre_mem_read_asciiz)(void(*f)(CorePart part, ThreadId tid,
+                                             Char* s, Addr a));
+void VG_(track_pre_mem_write)      (void(*f)(CorePart part, ThreadId tid,
+                                             Char* s, Addr a, SizeT size));
+void VG_(track_post_mem_write)     (void(*f)(CorePart part, ThreadId tid,
+                                             Addr a, SizeT size));
+
+/* Register events.  Use VG_(set_shadow_state_area)() to set the shadow regs
+   for these events.  */
+void VG_(track_pre_reg_read)  (void(*f)(CorePart part, ThreadId tid,
+                                        Char* s, OffT guest_state_offset,
+                                        SizeT size));
+void VG_(track_post_reg_write)(void(*f)(CorePart part, ThreadId tid,
+                                        OffT guest_state_offset,
+                                        SizeT size));
+
+/* This one is called for malloc() et al if they are replaced by a tool. */
+void VG_(track_post_reg_write_clientcall_return)(
+      void(*f)(ThreadId tid, OffT guest_state_offset, SizeT size, Addr f));
+
+
+/* Scheduler events (not exhaustive) */
+void VG_(track_thread_run)(void(*f)(ThreadId tid));
+
+
+/* Thread events (not exhaustive)
+
+   Called during thread create, before the new thread has run any
+   instructions (or touched any memory).
+ */
+void VG_(track_post_thread_create)(void(*f)(ThreadId tid, ThreadId child));
+void VG_(track_post_thread_join)  (void(*f)(ThreadId joiner, ThreadId joinee));
+
+/* Mutex events (not exhaustive)
+   "void *mutex" is really a pthread_mutex *
+
+   Called before a thread can block while waiting for a mutex (called
+   regardless of whether the thread will block or not).  */
+void VG_(track_pre_mutex_lock)(void(*f)(ThreadId tid, void* mutex));
+
+/* Called once the thread actually holds the mutex (always paired with
+   pre_mutex_lock).  */
+void VG_(track_post_mutex_lock)(void(*f)(ThreadId tid, void* mutex));
+
+/* Called after a thread has released a mutex (no need for a corresponding
+   pre_mutex_unlock, because unlocking can't block).  */
+void VG_(track_post_mutex_unlock)(void(*f)(ThreadId tid, void* mutex));
+
+/* Signal events (not exhaustive)
+
+   ... pre_send_signal, post_send_signal ...
+
+   Called before a signal is delivered;  `alt_stack' indicates if it is
+   delivered on an alternative stack.  */
+void VG_(track_pre_deliver_signal) (void(*f)(ThreadId tid, Int sigNo,
+                                             Bool alt_stack));
+/* Called after a signal is delivered.  Nb: unfortunately, if the signal
+   handler longjmps, this won't be called.  */
+void VG_(track_post_deliver_signal)(void(*f)(ThreadId tid, Int sigNo));
+
+/* Others... condition variables...
+   ...
+   Shadow memory management
+ */
+void VG_(track_init_shadow_page)(void(*f)(Addr p));
+
+#endif   // __PUB_TOOL_TOOLIFACE_H
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
diff --git a/include/tool.h b/include/tool.h
index 39caa89..5f5b789 100644
--- a/include/tool.h
+++ b/include/tool.h
@@ -74,46 +74,6 @@
 
 
 /*====================================================================*/
-/*=== Core/tool interface version                                  ===*/
-/*====================================================================*/
-
-/* The version number indicates binary-incompatible changes to the
-   interface;  if the core and tool versions don't match, Valgrind
-   will abort.  */
-#define VG_CORE_INTERFACE_VERSION   8
-
-typedef struct _ToolInfo {
-   Int	sizeof_ToolInfo;
-   Int	interface_version;
-
-   /* Initialise tool.   Must do the following:
-      - initialise the `details' struct, via the VG_(details_*)() functions
-      - register any helpers called by generated code
-      
-      May do the following:
-      - initialise the `needs' struct to indicate certain requirements, via
-      the VG_(needs_*)() functions
-      - initialize all the tool's entrypoints via the VG_(init_*)() functions
-      - register any tool-specific profiling events
-      - any other tool-specific initialisation
-   */
-   void (*tl_pre_clo_init) ( void );
-
-   /* Specifies how big the shadow segment should be as a ratio to the
-      client address space.  0 for no shadow segment. */
-   float shadow_ratio;
-} ToolInfo;
-
-/* Every tool must include this macro somewhere, exactly once. */
-#define VG_DETERMINE_INTERFACE_VERSION(pre_clo_init, shadow)   \
-   const ToolInfo VG_(tool_info) = {                           \
-      .sizeof_ToolInfo   = sizeof(ToolInfo),                   \
-      .interface_version = VG_CORE_INTERFACE_VERSION,          \
-      .tl_pre_clo_init   = pre_clo_init,                       \
-      .shadow_ratio	 = shadow,                             \
-   };
-
-/*====================================================================*/
 /*=== Command-line options                                         ===*/
 /*====================================================================*/
 
@@ -776,343 +736,6 @@
 extern void VG_(set_shadow_regs_area) ( ThreadId tid, OffT guest_state_offset,
                                         SizeT size, const UChar* area );
 
-/*====================================================================*/
-/*=== Tool-specific stuff                                          ===*/
-/*====================================================================*/
-
-/* ------------------------------------------------------------------ */
-/* Basic tool functions */
-
-extern void VG_(basic_tool_funcs)(
-   // Do any initialisation that can only be done after command line
-   // processing.
-   void  (*post_clo_init)(void),
-
-   // Instrument a basic block.  Must be a true function, ie. the same input
-   // always results in the same output, because basic blocks can be
-   // retranslated.  Unless you're doing something really strange...
-   IRBB* (*instrument)(IRBB* bb_in, VexGuestLayout* layout, 
-                       IRType gWordTy, IRType hWordTy ),
-
-   // Finish up, print out any results, etc.  `exitcode' is program's exit
-   // code.  The shadow can be found with VG_(get_exit_status_shadow)().
-   void  (*fini)(Int)
-);
-
-/* ------------------------------------------------------------------ */
-/* Details */
-
-/* Default value for avg_translations_sizeB (in bytes), indicating typical
-   code expansion of about 6:1. */
-#define VG_DEFAULT_TRANS_SIZEB   100
-
-/* Information used in the startup message.  `name' also determines the
-   string used for identifying suppressions in a suppression file as
-   belonging to this tool.  `version' can be NULL, in which case (not
-   surprisingly) no version info is printed; this mechanism is designed for
-   tools distributed with Valgrind that share a version number with
-   Valgrind.  Other tools not distributed as part of Valgrind should
-   probably have their own version number.  */
-extern void VG_(details_name)                  ( Char* name );
-extern void VG_(details_version)               ( Char* version );
-extern void VG_(details_description)           ( Char* description );
-extern void VG_(details_copyright_author)      ( Char* copyright_author );
-
-/* Average size of a translation, in bytes, so that the translation
-   storage machinery can allocate memory appropriately.  Not critical,
-   setting is optional. */
-extern void VG_(details_avg_translation_sizeB) ( UInt size );
-
-/* String printed if an `tl_assert' assertion fails or VG_(tool_panic)
-   is called.  Should probably be an email address. */
-extern void VG_(details_bug_reports_to)   ( Char* bug_reports_to );
-
-/* ------------------------------------------------------------------ */
-/* Needs */
-
-/* Booleans that decide core behaviour, but don't require extra
-   operations to be defined if `True' */
-
-/* Should __libc_freeres() be run?  Bugs in it can crash the tool. */
-extern void VG_(needs_libc_freeres) ( void );
-
-/* Want to have errors detected by Valgrind's core reported?  Includes:
-   - pthread API errors (many;  eg. unlocking a non-locked mutex)
-   - invalid file descriptors to blocking syscalls read() and write()
-   - bad signal numbers passed to sigaction()
-   - attempt to install signal handler for SIGKILL or SIGSTOP */
-extern void VG_(needs_core_errors) ( void );
-
-/* Booleans that indicate extra operations are defined;  if these are True,
-   the corresponding template functions (given below) must be defined.  A
-   lot like being a member of a type class. */
-
-/* Want to report errors from tool?  This implies use of suppressions, too. */
-extern void VG_(needs_tool_errors) (
-   // Identify if two errors are equal, or equal enough.  `res' indicates how
-   // close is "close enough".  `res' should be passed on as necessary, eg. if
-   // the Error's `extra' part contains an ExeContext, `res' should be
-   // passed to VG_(eq_ExeContext)() if the ExeContexts are considered.  Other
-   // than that, probably don't worry about it unless you have lots of very
-   // similar errors occurring.
-   Bool (*eq_Error)(VgRes res, Error* e1, Error* e2),
-
-   // Print error context.
-   void (*pp_Error)(Error* err),
-
-   // Should fill in any details that could be postponed until after the
-   // decision whether to ignore the error (ie. details not affecting the
-   // result of VG_(tdict).tool_eq_Error()).  This saves time when errors
-   // are ignored.
-   // Yuk.
-   // Return value: must be the size of the `extra' part in bytes -- used by
-   // the core to make a copy.
-   UInt (*update_extra)(Error* err),
-
-   // Return value indicates recognition.  If recognised, must set skind using
-   // VG_(set_supp_kind)().
-   Bool (*recognised_suppression)(Char* name, Supp* su),
-
-   // Read any extra info for this suppression kind.  Most likely for filling
-   // in the `extra' and `string' parts (with VG_(set_supp_{extra, string})())
-   // of a suppression if necessary.  Should return False if a syntax error
-   // occurred, True otherwise.
-   Bool (*read_extra_suppression_info)(Int fd, Char* buf, Int nBuf, Supp* su),
-
-   // This should just check the kinds match and maybe some stuff in the
-   // `string' and `extra' field if appropriate (using VG_(get_supp_*)() to
-   // get the relevant suppression parts).
-   Bool (*error_matches_suppression)(Error* err, Supp* su),
-
-   // This should return the suppression name, for --gen-suppressions, or NULL
-   // if that error type cannot be suppressed.  This is the inverse of
-   // VG_(tdict).tool_recognised_suppression().
-   Char* (*get_error_name)(Error* err),
-
-   // This should print any extra info for the error, for --gen-suppressions,
-   // including the newline.  This is the inverse of
-   // VG_(tdict).tool_read_extra_suppression_info().
-   void (*print_extra_suppression_info)(Error* err)
-);
-
-
-/* Is information kept about specific individual basic blocks?  (Eg. for
-   cachegrind there are cost-centres for every instruction, stored at a
-   basic block level.)  If so, it sometimes has to be discarded, because
-   .so mmap/munmap-ping or self-modifying code (informed by the
-   DISCARD_TRANSLATIONS user request) can cause one instruction address
-   to be used for more than one instruction in one program run...  */
-extern void VG_(needs_basic_block_discards) (
-   // Should discard any information that pertains to specific basic blocks
-   // or instructions within the address range given.
-   void (*discard_basic_block_info)(Addr a, SizeT size)
-);
-
-/* Tool defines its own command line options? */
-extern void VG_(needs_command_line_options) (
-   // Return True if option was recognised.  Presumably sets some state to
-   // record the option as well.
-   Bool (*process_cmd_line_option)(Char* argv),
-
-   // Print out command line usage for options for normal tool operation.
-   void (*print_usage)(void),
-
-   // Print out command line usage for options for debugging the tool.
-   void (*print_debug_usage)(void)
-);
-
-/* Tool defines its own client requests? */
-extern void VG_(needs_client_requests) (
-   // If using client requests, the number of the first request should be equal
-   // to VG_USERREQ_TOOL_BASE('X', 'Y'), where 'X' and 'Y' form a suitable two
-   // character identification for the string.  The second and subsequent
-   // requests should follow.
-   //
-   // This function should use the VG_IS_TOOL_USERREQ macro (in
-   // include/valgrind.h) to first check if it's a request for this tool.  Then
-   // should handle it if it's recognised (and return True), or return False if
-   // not recognised.  arg_block[0] holds the request number, any further args
-   // from the request are in arg_block[1..].  'ret' is for the return value...
-   // it should probably be filled, if only with 0.
-   Bool (*handle_client_request)(ThreadId tid, UWord* arg_block, UWord* ret)
-);
-
-/* Tool does stuff before and/or after system calls? */
-// Nb: If either of the pre_ functions malloc() something to return, the
-// corresponding post_ function had better free() it!
-extern void VG_(needs_syscall_wrapper) (
-   void (* pre_syscall)(ThreadId tid, UInt syscallno),
-   void (*post_syscall)(ThreadId tid, UInt syscallno, Int res)
-);
-
-/* Are tool-state sanity checks performed? */
-// Can be useful for ensuring a tool's correctness.  cheap_sanity_check()
-// is called very frequently;  expensive_sanity_check() is called less
-// frequently and can be more involved.
-extern void VG_(needs_sanity_checks) (
-   Bool(*cheap_sanity_check)(void),
-   Bool(*expensive_sanity_check)(void)
-);
-
-/* Do we need to see data symbols? */
-extern void VG_(needs_data_syms) ( void );
-
-/* Does the tool need shadow memory allocated? */
-extern void VG_(needs_shadow_memory)( void );
-
-/* ------------------------------------------------------------------ */
-/* Malloc replacement */
-
-// The 'p' prefix avoids GCC complaints about overshadowing global names.
-extern void VG_(malloc_funcs)(
-   void* (*pmalloc)               ( ThreadId tid, SizeT n ),
-   void* (*p__builtin_new)        ( ThreadId tid, SizeT n ),
-   void* (*p__builtin_vec_new)    ( ThreadId tid, SizeT n ),
-   void* (*pmemalign)             ( ThreadId tid, SizeT align, SizeT n ),
-   void* (*pcalloc)               ( ThreadId tid, SizeT nmemb, SizeT size1 ),
-   void  (*pfree)                 ( ThreadId tid, void* p ),
-   void  (*p__builtin_delete)     ( ThreadId tid, void* p ),
-   void  (*p__builtin_vec_delete) ( ThreadId tid, void* p ),
-   void* (*prealloc)              ( ThreadId tid, void* p, SizeT new_size ),
-   SizeT client_malloc_redzone_szB
-);
-
-/* ------------------------------------------------------------------ */
-/* Core events to track */
-
-/* Part of the core from which this call was made.  Useful for determining
-   what kind of error message should be emitted. */
-typedef
-   enum { Vg_CoreStartup, Vg_CorePThread, Vg_CoreSignal, Vg_CoreSysCall,
-          Vg_CoreTranslate, Vg_CoreClientReq }
-   CorePart;
-
-/* Events happening in core to track.  To be notified, pass a callback
-   function to the appropriate function.  To ignore an event, don't do
-   anything (the default is for events to be ignored).
-
-   Note that most events aren't passed a ThreadId.  If the event is one called
-   from generated code (eg. new_mem_stack_*), you can use
-   VG_(get_running_tid)() to find it.  Otherwise, it has to be passed in,
-   as in pre_mem_read, and so the event signature will require changing.
-
-   Memory events (Nb: to track heap allocation/freeing, a tool must replace
-   malloc() et al.  See above how to do this.)
-
-   These ones occur at startup, upon some signals, and upon some syscalls
- */
-void VG_(track_new_mem_startup)     (void(*f)(Addr a, SizeT len,
-                                              Bool rr, Bool ww, Bool xx));
-void VG_(track_new_mem_stack_signal)(void(*f)(Addr a, SizeT len));
-void VG_(track_new_mem_brk)         (void(*f)(Addr a, SizeT len));
-void VG_(track_new_mem_mmap)        (void(*f)(Addr a, SizeT len,
-                                              Bool rr, Bool ww, Bool xx));
-
-void VG_(track_copy_mem_remap)      (void(*f)(Addr from, Addr to, SizeT len));
-void VG_(track_change_mem_mprotect) (void(*f)(Addr a, SizeT len,
-                                              Bool rr, Bool ww, Bool xx));
-void VG_(track_die_mem_stack_signal)(void(*f)(Addr a, SizeT len));
-void VG_(track_die_mem_brk)         (void(*f)(Addr a, SizeT len));
-void VG_(track_die_mem_munmap)      (void(*f)(Addr a, SizeT len));
-
-/* These ones are called when SP changes.  A tool could track these itself
-   (except for ban_mem_stack) but it's much easier to use the core's help.
-
-   The specialised ones are called in preference to the general one, if they
-   are defined.  These functions are called a lot if they are used, so
-   specialising can optimise things significantly.  If any of the
-   specialised cases are defined, the general case must be defined too.
-
-   Nb: all the specialised ones must use the VGA_REGPARM(n) attribute.
- */
-void VG_(track_new_mem_stack_4) (VGA_REGPARM(1) void(*f)(Addr new_ESP));
-void VG_(track_new_mem_stack_8) (VGA_REGPARM(1) void(*f)(Addr new_ESP));
-void VG_(track_new_mem_stack_12)(VGA_REGPARM(1) void(*f)(Addr new_ESP));
-void VG_(track_new_mem_stack_16)(VGA_REGPARM(1) void(*f)(Addr new_ESP));
-void VG_(track_new_mem_stack_32)(VGA_REGPARM(1) void(*f)(Addr new_ESP));
-void VG_(track_new_mem_stack)                  (void(*f)(Addr a, SizeT len));
-
-void VG_(track_die_mem_stack_4) (VGA_REGPARM(1) void(*f)(Addr die_ESP));
-void VG_(track_die_mem_stack_8) (VGA_REGPARM(1) void(*f)(Addr die_ESP));
-void VG_(track_die_mem_stack_12)(VGA_REGPARM(1) void(*f)(Addr die_ESP));
-void VG_(track_die_mem_stack_16)(VGA_REGPARM(1) void(*f)(Addr die_ESP));
-void VG_(track_die_mem_stack_32)(VGA_REGPARM(1) void(*f)(Addr die_ESP));
-void VG_(track_die_mem_stack)                  (void(*f)(Addr a, SizeT len));
-
-/* Used for redzone at end of thread stacks */
-void VG_(track_ban_mem_stack)      (void(*f)(Addr a, SizeT len));
-
-/* These ones occur around syscalls, signal handling, etc */
-void VG_(track_pre_mem_read)       (void(*f)(CorePart part, ThreadId tid,
-                                             Char* s, Addr a, SizeT size));
-void VG_(track_pre_mem_read_asciiz)(void(*f)(CorePart part, ThreadId tid,
-                                             Char* s, Addr a));
-void VG_(track_pre_mem_write)      (void(*f)(CorePart part, ThreadId tid,
-                                             Char* s, Addr a, SizeT size));
-void VG_(track_post_mem_write)     (void(*f)(CorePart part, ThreadId tid,
-                                             Addr a, SizeT size));
-
-/* Register events.  Use VG_(set_shadow_state_area)() to set the shadow regs
-   for these events.  */
-void VG_(track_pre_reg_read)  (void(*f)(CorePart part, ThreadId tid,
-                                        Char* s, OffT guest_state_offset,
-                                        SizeT size));
-void VG_(track_post_reg_write)(void(*f)(CorePart part, ThreadId tid,
-                                        OffT guest_state_offset,
-                                        SizeT size));
-
-/* This one is called for malloc() et al if they are replaced by a tool. */
-void VG_(track_post_reg_write_clientcall_return)(
-      void(*f)(ThreadId tid, OffT guest_state_offset, SizeT size, Addr f));
-
-
-/* Scheduler events (not exhaustive) */
-void VG_(track_thread_run)(void(*f)(ThreadId tid));
-
-
-/* Thread events (not exhaustive)
-
-   Called during thread create, before the new thread has run any
-   instructions (or touched any memory).
- */
-void VG_(track_post_thread_create)(void(*f)(ThreadId tid, ThreadId child));
-void VG_(track_post_thread_join)  (void(*f)(ThreadId joiner, ThreadId joinee));
-
-/* Mutex events (not exhaustive)
-   "void *mutex" is really a pthread_mutex *
-
-   Called before a thread can block while waiting for a mutex (called
-   regardless of whether the thread will block or not).  */
-void VG_(track_pre_mutex_lock)(void(*f)(ThreadId tid, void* mutex));
-
-/* Called once the thread actually holds the mutex (always paired with
-   pre_mutex_lock).  */
-void VG_(track_post_mutex_lock)(void(*f)(ThreadId tid, void* mutex));
-
-/* Called after a thread has released a mutex (no need for a corresponding
-   pre_mutex_unlock, because unlocking can't block).  */
-void VG_(track_post_mutex_unlock)(void(*f)(ThreadId tid, void* mutex));
-
-/* Signal events (not exhaustive)
-
-   ... pre_send_signal, post_send_signal ...
-
-   Called before a signal is delivered;  `alt_stack' indicates if it is
-   delivered on an alternative stack.  */
-void VG_(track_pre_deliver_signal) (void(*f)(ThreadId tid, Int sigNo,
-                                             Bool alt_stack));
-/* Called after a signal is delivered.  Nb: unfortunately, if the signal
-   handler longjmps, this won't be called.  */
-void VG_(track_post_deliver_signal)(void(*f)(ThreadId tid, Int sigNo));
-
-
-/* Others... condition variables...
-   ...
-
-   Shadow memory management
- */
-void VG_(track_init_shadow_page)(void(*f)(Addr p));
-
 #endif   /* __TOOL_H */
 
 
diff --git a/lackey/lk_main.c b/lackey/lk_main.c
index 4657340..80a987b 100644
--- a/lackey/lk_main.c
+++ b/lackey/lk_main.c
@@ -30,6 +30,7 @@
 */
 
 #include "tool.h"
+#include "pub_tool_tooliface.h"
 
 /* Nb: use ULongs because the numbers can get very big */
 static ULong n_dlrr_calls   = 0;
diff --git a/massif/ms_main.c b/massif/ms_main.c
index df2ca80..55be3c2 100644
--- a/massif/ms_main.c
+++ b/massif/ms_main.c
@@ -38,6 +38,7 @@
 #include "pub_tool_mallocfree.h"
 #include "pub_tool_replacemalloc.h"
 #include "pub_tool_stacktrace.h"
+#include "pub_tool_tooliface.h"
 
 #include "valgrind.h"           // For {MALLOC,FREE}LIKE_BLOCK
 
diff --git a/memcheck/mac_shared.h b/memcheck/mac_shared.h
index 82303e8..186021d 100644
--- a/memcheck/mac_shared.h
+++ b/memcheck/mac_shared.h
@@ -39,6 +39,7 @@
 #include "tool.h"
 #include "pub_tool_mallocfree.h"
 #include "pub_tool_replacemalloc.h"
+#include "pub_tool_tooliface.h"
 
 #define MAC_(str)    VGAPPEND(vgMAC_,str)
 
diff --git a/none/nl_main.c b/none/nl_main.c
index 63d2fe0..c2e680b 100644
--- a/none/nl_main.c
+++ b/none/nl_main.c
@@ -29,6 +29,7 @@
 */
 
 #include "tool.h"
+#include "pub_tool_tooliface.h"
 
 static void nl_post_clo_init(void)
 {