#include "tool.h"
#include "pub_tool_mallocfree.h"
+#include "pub_tool_tooliface.h"
#include "cg_arch.h"
#include "cg_sim.c"
*/
#include "tool.h"
+#include "pub_tool_tooliface.h"
static void cc_post_clo_init(void)
{
pub_core_sigframe.h \
pub_core_stacktrace.h \
pub_core_syscalls.h \
+ pub_core_tooliface.h \
ume.h \
vg_symtab2.h \
vg_symtypes.h
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 \
vg_main.c \
vg_messages.c \
vg_mylibc.c \
- vg_needs.c \
vg_dummy_profile.c \
vg_signals.c \
vg_symtab2.c \
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
*/
#include "core.h"
+#include "pub_core_tooliface.h"
#include "amd64_private.h"
#include <sys/ptrace.h>
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
-
#define VGP_POPCC(x) if (VG_(clo_profile)) VG_(popcc)(x)
-/* ---------------------------------------------------------------------
- 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
------------------------------------------------------------------ */
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
// ---------------------------------------------------------------------
+
+/*--------------------------------------------------------------------*/
+/*--- 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)
{
return handled;
}
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------*/
+/*--- 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
Taken from futex-2.2/usersem.c
Based on work by Matthew Kirkwood <matthew@hairy.beasts.org>.
- */
-
+*/
#define FUTEX_PASSED (-(1024 * 1024 * 1024))
}
#endif /* FUTEX_SEMA */
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
+
+
#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. */
#include "pub_core_errormgr.h"
#include "pub_core_execontext.h"
#include "pub_core_stacktrace.h"
+#include "pub_core_tooliface.h"
/*------------------------------------------------------------*/
/*--- Globals ---*/
*/
#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"
*/
#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"
#include "pub_core_aspacemgr.h"
#include "pub_core_sigframe.h"
#include "pub_core_syscalls.h"
+#include "pub_core_tooliface.h"
#include "priv_syscalls.h"
#include "core.h"
#include "pub_core_aspacemgr.h"
+#include "pub_core_tooliface.h"
#include "priv_syscalls.h"
/* ---------------------------------------------------------------------
#include "pub_core_aspacemgr.h"
#include "pub_core_sigframe.h"
#include "pub_core_syscalls.h"
+#include "pub_core_tooliface.h"
#include "priv_syscalls.h"
#include "pub_core_aspacemgr.h"
#include "pub_core_stacktrace.h"
#include "pub_core_syscalls.h"
+#include "pub_core_tooliface.h"
#include "priv_syscalls.h"
*/
#include "core.h"
+#include "pub_core_tooliface.h"
// The core/tool dictionary of functions (initially zeroed, as we want it)
VgToolInterface VG_(tdict);
/*--------------------------------------------------------------------*/
-/*--- The address space manager. ---*/
-/*--- pub_core_aspacemgr.h ---*/
+/*--- The address space manager. pub_core_aspacemgr.h ---*/
/*--------------------------------------------------------------------*/
/*
--- /dev/null
+
+/*--------------------------------------------------------------------*/
+/*--- 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 ---*/
+/*--------------------------------------------------------------------*/
#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>
#include "pub_core_debuglog.h" /* VG_(debugLog_vprintf) */
#include "pub_core_stacktrace.h"
#include "pub_core_syscalls.h"
+#include "pub_core_tooliface.h"
/* ---------------------------------------------------------------------
#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.
#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. */
#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;
#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 */
#include "core.h"
#include "pub_core_aspacemgr.h"
+#include "pub_core_tooliface.h"
/*------------------------------------------------------------*/
*/
#include "core.h"
+#include "pub_core_tooliface.h"
/* #define DEBUG_TRANSTAB */
"(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);
*/
#include "core.h"
+#include "pub_core_tooliface.h"
#include "x86_private.h"
#include "libvex_guest_x86.h"
*/
#include "core.h"
+#include "pub_core_tooliface.h"
#include "x86_private.h"
#include <sys/ptrace.h>
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
-
#include "tool.h"
#include "pub_tool_mallocfree.h"
#include "pub_tool_replacemalloc.h"
+#include "pub_tool_tooliface.h"
#include "helgrind.h"
pub_tool_mallocfree.h \
pub_tool_replacemalloc.h\
pub_tool_stacktrace.h \
+ pub_tool_tooliface.h \
valgrind.h
BUILT_SOURCES = valgrind.h
--- /dev/null
+
+/*--------------------------------------------------------------------*/
+/*--- 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 ---*/
+/*--------------------------------------------------------------------*/
extern const Char *VG_(libdir);
-/*====================================================================*/
-/*=== 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 ===*/
/*====================================================================*/
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 */
*/
#include "tool.h"
+#include "pub_tool_tooliface.h"
/* Nb: use ULongs because the numbers can get very big */
static ULong n_dlrr_calls = 0;
#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
#include "tool.h"
#include "pub_tool_mallocfree.h"
#include "pub_tool_replacemalloc.h"
+#include "pub_tool_tooliface.h"
#define MAC_(str) VGAPPEND(vgMAC_,str)
*/
#include "tool.h"
+#include "pub_tool_tooliface.h"
static void nl_post_clo_init(void)
{