Big clean-up: changed the core/tool interface to be mediated entirely
through the VG_(tdict) function dictionary, rather than using TL_(foo)
functions.
This facilitated the following changes:
- Removed the "TL_" prefix, which is no longer needed.
- Removed the auto-generated files vg_toolint.[ch], which were no longer
needed, which simplifies the build a great deal. Their (greatly
streamlined) contents went into core.h and vg_needs.h (and will soon
go into a new module defining the core/tool interface).
This also meant that tool.h.base reverted to tool.h (so no more
accidentally editing tool.h and not having the changes go into the
repo, hooray!) And gen_toolint.pl was removed. And toolfuncs.def was
removed.
- Removed VG_(missing_tool_func)(), no longer used.
- Bumped the core/tool interface major version number to 8. And I
killed the minor version number, which was never used. The layout
of the ToolInfo struct is such that this should not cause problems.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3644 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am
index a819fe1..5d4f753 100644
--- a/coregrind/Makefile.am
+++ b/coregrind/Makefile.am
@@ -47,15 +47,11 @@
pub_core_syscalls.h \
ume.h \
vg_symtab2.h \
- vg_symtypes.h \
- vg_toolint.h
+ vg_symtypes.h
EXTRA_DIST = \
valgrind.vs \
- gen_toolint.pl toolfuncs.def README_MODULES.txt
-
-BUILT_SOURCES = vg_toolint.c vg_toolint.h
-CLEANFILES = vg_toolint.c vg_toolint.h
+ README_MODULES.txt
valgrind_SOURCES = \
ume.c \
@@ -93,7 +89,6 @@
vg_stabs.c \
vg_skiplist.c \
vg_symtypes.c \
- vg_toolint.c \
vg_translate.c \
vg_transtab.c
@@ -131,19 +126,6 @@
stage2_LDADD= $(stage2_extra) -ldl
-vg_toolint.c: $(srcdir)/gen_toolint.pl $(srcdir)/toolfuncs.def ./Makefile
- rm -f $@
- $(PERL) $(srcdir)/gen_toolint.pl callwrap < $(srcdir)/toolfuncs.def > $@ || rm -f $@
- $(PERL) $(srcdir)/gen_toolint.pl missingfuncs < $(srcdir)/toolfuncs.def >> $@ || rm -f $@
- $(PERL) $(srcdir)/gen_toolint.pl initfunc < $(srcdir)/toolfuncs.def >> $@ || rm -f $@
- $(PERL) $(srcdir)/gen_toolint.pl structdef < $(srcdir)/toolfuncs.def >> $@ || rm -f $@
-
-vg_toolint.h: $(srcdir)/gen_toolint.pl $(srcdir)/toolfuncs.def ./Makefile
- rm -f $@
- $(PERL) $(srcdir)/gen_toolint.pl proto < $(srcdir)/toolfuncs.def > $@ || rm -f $@
- $(PERL) $(srcdir)/gen_toolint.pl struct < $(srcdir)/toolfuncs.def >> $@ || rm -f $@
-
-
vg_inject_so_SOURCES = vg_intercept.c
vg_inject_so_CFLAGS = $(AM_CFLAGS) -fpic
vg_inject_so_LDADD = -ldl
diff --git a/coregrind/core.h b/coregrind/core.h
index 0174458..f52bf57 100644
--- a/coregrind/core.h
+++ b/coregrind/core.h
@@ -101,10 +101,6 @@
#include "valgrind.h"
-#undef TL_
-#define TL_(x) vgToolInternal_##x
-
-
/* ---------------------------------------------------------------------
Global macros.
------------------------------------------------------------------ */
@@ -321,13 +317,6 @@
extern VgDetails VG_(details);
-/* If new fields are added to this type, update:
- * - vg_main.c:initialisation of VG_(needs)
- * - vg_main.c:sanity_check_needs()
- *
- * If the name of this type or any of its fields change, update:
- * - dependent comments (just search for "VG_(needs)").
- */
typedef
struct {
Bool libc_freeres;
@@ -347,7 +336,118 @@
extern VgNeeds VG_(needs);
-#include "vg_toolint.h"
+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);
+
/* ---------------------------------------------------------------------
@@ -1065,15 +1165,21 @@
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_(defined_##fn)()) \
- TL_(fn)(args); \
+ if (VG_(tdict).track_##fn) \
+ VG_(tdict).track_##fn(args); \
} while(0)
-__attribute__ ((noreturn))
-extern void VG_(missing_tool_func) ( const Char* fn );
-
// ---------------------------------------------------------------------
// Architecture-specific things defined in eg. x86/*.c
// ---------------------------------------------------------------------
diff --git a/coregrind/gen_toolint.pl b/coregrind/gen_toolint.pl
deleted file mode 100644
index e6f629c..0000000
--- a/coregrind/gen_toolint.pl
+++ /dev/null
@@ -1,266 +0,0 @@
-#!/usr/bin/perl -w
-
-# 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.
-
-use strict;
-
-my $output = shift @ARGV;
-my $indent = "";
-my $headerguard;
-my $include;
-my $passcomment = 1;
-my $pre;
-my $post;
-my $generate;
-
-my $struct = "VG_(tdict)";
-
-my %pfxmap = ("track" => "TL_",
- "tool" => "TL_",
- "malloc"=> "TL_",
- );
-
-sub getargnames(@) {
- my @args = @_;
- my @ret;
-
- foreach my $a (@args) {
- my @pieces = split /\s+/, $a;
- my $name = pop @pieces;
- push @ret, $name unless $name eq "void";
- }
- return @ret;
-}
-
-sub getargtypes(@) {
- my @args = @_;
- my @ret;
-
- foreach my $a (@args) {
- my @pieces = split /\s+/, $a;
- pop @pieces;
- push @ret, (join " ", @pieces);
- }
- @ret = "void" if ($#ret == -1);
- return @ret;
-}
-
-# Different output modes
-if ($output eq "callwrap") {
- $include = "core.h";
- $generate = sub ($$$@) {
- my ($pfx, $ret, $func, @args) = @_;
- my $args = join ", ", @args;
- my $argnames = join ", ", getargnames(@args);
- print "$ret $pfxmap{$pfx}($func)($args)\n{\n";
- print " return (*$struct.${pfx}_$func)($argnames);\n";
- print "}\n";
- }
-} elsif ($output eq "proto") {
- $include = "core.h";
- $generate = sub ($$$@) {
- my ($pfx, $ret, $func, @args) = @_;
- my $args = join ', ', @args;
-
- print "$ret $pfxmap{$pfx}($func)($args);\n";
- print "$ret VG_(missing_$func)($args);\n";
- print "Bool VG_(defined_$func)(void);\n";
- }
-} elsif ($output eq "toolproto") {
- $generate = sub ($$$@) {
- my ($pfx, $ret, $func, @args) = @_;
- my $args = join ', ', @args;
-
- print "$ret $pfxmap{$pfx}($func)($args);\n";
- }
-} elsif ($output eq "missingfuncs") {
- $include = "core.h";
- $generate = sub ($$$@) {
- my ($pfx, $ret, $func, @args) = @_;
- my $args = join ", ", @args;
-
- print "__attribute__ ((weak))\n$ret VG_(missing_$func)($args) {\n";
- print " VG_(missing_tool_func)(\"${pfx}_$func\");\n";
- print "}\n";
- print "Bool VG_(defined_$func)(void) {\n";
- print " return $struct.${pfx}_$func != VG_(missing_$func);\n";
- print "}\n\n";
- };
- $indent = " ";
-} elsif ($output eq "struct") {
- $include = "core.h";
- $pre = sub () {
- print "typedef struct {\n";
- };
- $post = sub () {
- print "} VgToolInterface;\n\n";
- print "extern VgToolInterface $struct;\n"
- };
- $generate = sub ($$$@) {
- my ($pfx, $ret, $func, @args) = @_;
- my $args = join ", ", @args;
-
- print "$indent$ret (*${pfx}_$func)($args);\n";
- };
- $indent = " ";
- $headerguard=$output;
-} elsif ($output eq "structdef") {
- $include = "vg_toolint.h";
- $pre = sub () {
- print "VgToolInterface $struct = {\n";
- };
- $post = sub () {
- print "};\n";
- };
- $generate = sub ($$$@) {
- my ($pfx, $ret, $func, @args) = @_;
-
- print "$indent.${pfx}_$func = VG_(missing_$func),\n"
- };
- $indent = " ";
-} elsif ($output eq "initfunc") {
- $include = "tool.h";
- $generate = sub ($$$@) {
- my ($pfx, $ret, $func, @args) = @_;
- my $args = join ", ", @args;
- my $argnames = join ", ", getargnames(@args);
-
- print <<EOF;
-void VG_(init_$func)($ret (*func)($args))
-{
- if (func == NULL)
- func = VG_(missing_$func);
- if (VG_(defined_$func)())
- VG_(printf)("Warning tool is redefining $func\\n");
- if (func == TL_($func))
- VG_(printf)("Warning tool is defining $func recursively\\n");
- $struct.${pfx}_$func = func;
-}
-EOF
- }
-} elsif ($output eq "initproto") {
- $generate = sub ($$$@) {
- my ($pfx, $ret, $func, @args) = @_;
- my $args = join ', ', @args;
- print "void VG_(init_$func)($ret (*func)($args));\n";
- };
- $headerguard=$output;
-}
-
-die "Unknown output format \"$output\"" unless defined $generate;
-
-print "/* Generated by \"gen_toolint.pl $output\" */\n";
-
-print <<EOF if defined $headerguard;
-
-#ifndef VG_toolint_$headerguard
-#define VG_toolint_$headerguard
-
-EOF
-
-print <<EOF if defined $include;
-#include \"$include\"
-EOF
-
-&$pre() if defined $pre; # preamble
-
-my $state = "idle";
-
-my $buf;
-my $lines;
-my $prefix;
-
-while(<STDIN>) {
- # skip simple comments
- next if (/^#[^#]/);
-
- if (/^:/) {
- s/^://;
- chomp;
- $prefix=$_;
- next;
- }
-
- # look for inserted comments
- if (/^##/) {
- if ($state eq "idle") {
- $state = "comment";
- $lines = 1;
- $_ =~ s,^## ,/* ,;
- $buf = $_;
- next;
- } elsif ($state eq "comment") {
- $lines++;
- $_ =~ s,^## , ,;
- print $indent.$buf if $passcomment;
- $buf = $_;
- next;
- }
- next;
- }
-
- # blank lines in a comment are part of the comment
- if (/^\s*$/) {
- if ($state eq "comment") {
- $lines++;
- print $indent.$buf if $passcomment;
- $buf = "\n";
- } else {
- print "\n" if $passcomment;
- }
- next;
- }
-
- # coming out of a comment
- if ($state eq "comment") {
- chomp $buf;
-
- if ($passcomment) {
- if ($lines == 1) {
- print "$indent$buf */\n";
- } else {
- print "$indent$buf\n$indent */\n";
- }
- }
- $buf = "";
- $state = "idle";
- }
-
- chomp;
- my @func = split /,\s*/;
-
- my $rettype = shift @func;
- my $funcname = shift @func;
-
- @func = "void" if scalar @func == 0;
-
- &$generate ($prefix, $rettype, $funcname, @func);
-}
-
-&$post() if defined $post; # postamble
-
-print <<EOF if defined $headerguard;
-
-#endif /* VG_toolint_$headerguard */
-EOF
diff --git a/coregrind/m_aspacemgr/aspacemgr.c b/coregrind/m_aspacemgr/aspacemgr.c
index e5505c0..b4e1a87 100644
--- a/coregrind/m_aspacemgr/aspacemgr.c
+++ b/coregrind/m_aspacemgr/aspacemgr.c
@@ -1228,7 +1228,7 @@
VG_(printf)("init_shadow_range(%p, %d)\n", p, sz);
vg_assert(VG_(needs).shadow_memory);
- vg_assert(VG_(defined_init_shadow_page)());
+ vg_assert(VG_(tdict).track_init_shadow_page);
sz = PGROUNDUP(p+sz) - PGROUNDDN(p);
p = PGROUNDDN(p);
@@ -1254,7 +1254,7 @@
if (0) show_segments("shadow_alloc(before)");
vg_assert(VG_(needs).shadow_memory);
- vg_assert(!VG_(defined_init_shadow_page)());
+ vg_assert(!VG_(tdict).track_init_shadow_page);
size = PGROUNDUP(size);
diff --git a/coregrind/m_errormgr.c b/coregrind/m_errormgr.c
index fc10a3d..70ccb09 100644
--- a/coregrind/m_errormgr.c
+++ b/coregrind/m_errormgr.c
@@ -235,9 +235,9 @@
// vg_assert(VG_(needs).core_errors);
// return VG_(tm_error_equal)(res, e1, e2);
default:
- if (VG_(needs).tool_errors)
- return TL_(eq_Error)(res, e1, e2);
- else {
+ if (VG_(needs).tool_errors) {
+ return VG_TDICT_CALL(tool_eq_Error, res, e1, e2);
+ } else {
VG_(printf)("\nUnhandled error type: %u. VG_(needs).tool_errors\n"
"probably needs to be set.\n",
e1->ekind);
@@ -263,7 +263,7 @@
// break;
default:
if (VG_(needs).tool_errors)
- TL_(pp_Error)( err );
+ VG_TDICT_CALL( tool_pp_Error, err );
else {
VG_(printf)("\nUnhandled error type: %u. VG_(needs).tool_errors\n"
"probably needs to be set?\n",
@@ -373,14 +373,14 @@
VG_(printf)(" core:PThread\n");
} else {
- Char* name = TL_(get_error_name)(err);
+ Char* name = VG_TDICT_CALL(tool_get_error_name, err);
if (NULL == name) {
VG_(message)(Vg_UserMsg,
"(tool does not allow error to be suppressed)");
return;
}
VG_(printf)(" %s:%s\n", VG_(details).name, name);
- TL_(print_extra_suppression_info)(err);
+ VG_TDICT_CALL(tool_print_extra_suppression_info, err);
}
// Print stack trace elements
@@ -524,15 +524,15 @@
will disappear shortly, so we must copy it. First do the main
(non-`extra') part.
- Then TL_(update_extra) can update the `extra' part. This is for when
- there are more details to fill in which take time to work out but
- don't affect our earlier decision to include the error -- by
+ Then VG_(tdict).tool_update_extra can update the `extra' part. This
+ is for when there are more details to fill in which take time to work
+ out but don't affect our earlier decision to include the error -- by
postponing those details until now, we avoid the extra work in the
case where we ignore the error. Ugly.
Then, if there is an `extra' part, copy it too, using the size that
- TL_(update_extra) returned. Also allow for people using the void*
- extra field for a scalar value like an integer.
+ VG_(tdict).tool_update_extra returned. Also allow for people using
+ the void* extra field for a scalar value like an integer.
*/
/* copy main part */
@@ -548,7 +548,7 @@
// break;
default:
vg_assert(VG_(needs).tool_errors);
- extra_size = TL_(update_extra)(p);
+ extra_size = VG_TDICT_CALL(tool_update_extra, p);
break;
}
@@ -595,10 +595,11 @@
/* Unless it's suppressed, we're going to show it. Don't need to make
a copy, because it's only temporary anyway.
- Then update the `extra' part with TL_(update_extra), because that can
- have an affect on whether it's suppressed. Ignore the size return
- value of TL_(update_extra), because we're not copying `extra'. */
- (void)TL_(update_extra)(&err);
+ Then update the `extra' part with VG_(tdict).tool_update_extra),
+ because that can have an affect on whether it's suppressed. Ignore
+ the size return value of VG_(tdict).tool_update_extra, because we're
+ not copying `extra'. */
+ (void)VG_TDICT_CALL(tool_update_extra, &err);
if (NULL == is_suppressible_error(&err)) {
if (count_error)
@@ -865,7 +866,7 @@
tool_name_present(VG_(details).name, tool_names))
{
// A tool suppression
- if (TL_(recognised_suppression)(supp_name, supp)) {
+ if (VG_TDICT_CALL(tool_recognised_suppression, supp_name, supp)) {
/* Do nothing, function fills in supp->skind */
} else {
BOMB("unknown tool suppression type");
@@ -883,7 +884,7 @@
}
if (VG_(needs).tool_errors &&
- !TL_(read_extra_suppression_info)(fd, buf, N_BUF, supp))
+ !VG_TDICT_CALL(tool_read_extra_suppression_info, fd, buf, N_BUF, supp))
{
BOMB("bad or missing extra suppression info");
}
@@ -965,7 +966,7 @@
return (err->ekind == ThreadErr || err->ekind == MutexErr);
default:
if (VG_(needs).tool_errors) {
- return TL_(error_matches_suppression)(err, su);
+ return VG_TDICT_CALL(tool_error_matches_suppression, err, su);
} else {
VG_(printf)(
"\nUnhandled suppression type: %u. VG_(needs).tool_errors\n"
diff --git a/coregrind/m_syscalls/priv_syscalls.h b/coregrind/m_syscalls/priv_syscalls.h
index 8add5ec..1544aab 100644
--- a/coregrind/m_syscalls/priv_syscalls.h
+++ b/coregrind/m_syscalls/priv_syscalls.h
@@ -393,44 +393,44 @@
*/
#define PRRSN \
- TL_(pre_reg_read)(Vg_CoreSysCall, tid, "(syscallno)", \
- O_SYSCALL_NUM, sizeof(UWord));
+ VG_(tdict).track_pre_reg_read(Vg_CoreSysCall, tid, "(syscallno)", \
+ O_SYSCALL_NUM, sizeof(UWord));
#define PRRAn(n,s,t,a) \
- TL_(pre_reg_read)(Vg_CoreSysCall, tid, s"("#a")", \
- O_SYSCALL_ARG##n, sizeof(t));
+ VG_(tdict).track_pre_reg_read(Vg_CoreSysCall, tid, s"("#a")", \
+ O_SYSCALL_ARG##n, sizeof(t));
#define PRE_REG_READ0(tr, s) \
- if (VG_(defined_pre_reg_read)()) { \
+ if (VG_(tdict).track_pre_reg_read) { \
PRRSN; \
}
#define PRE_REG_READ1(tr, s, t1, a1) \
- if (VG_(defined_pre_reg_read)()) { \
+ if (VG_(tdict).track_pre_reg_read) { \
PRRSN; \
PRRAn(1,s,t1,a1); \
}
#define PRE_REG_READ2(tr, s, t1, a1, t2, a2) \
- if (VG_(defined_pre_reg_read)()) { \
+ if (VG_(tdict).track_pre_reg_read) { \
PRRSN; \
PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); \
}
#define PRE_REG_READ3(tr, s, t1, a1, t2, a2, t3, a3) \
- if (VG_(defined_pre_reg_read)()) { \
+ if (VG_(tdict).track_pre_reg_read) { \
PRRSN; \
PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); PRRAn(3,s,t3,a3); \
}
#define PRE_REG_READ4(tr, s, t1, a1, t2, a2, t3, a3, t4, a4) \
- if (VG_(defined_pre_reg_read)()) { \
+ if (VG_(tdict).track_pre_reg_read) { \
PRRSN; \
PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); PRRAn(3,s,t3,a3); \
PRRAn(4,s,t4,a4); \
}
#define PRE_REG_READ5(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5) \
- if (VG_(defined_pre_reg_read)()) { \
+ if (VG_(tdict).track_pre_reg_read) { \
PRRSN; \
PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); PRRAn(3,s,t3,a3); \
PRRAn(4,s,t4,a4); PRRAn(5,s,t5,a5); \
}
#define PRE_REG_READ6(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5, t6, a6) \
- if (VG_(defined_pre_reg_read)()) { \
+ if (VG_(tdict).track_pre_reg_read) { \
PRRSN; \
PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); PRRAn(3,s,t3,a3); \
PRRAn(4,s,t4,a4); PRRAn(5,s,t5,a5); PRRAn(6,s,t6,a6); \
diff --git a/coregrind/m_syscalls/syscalls.c b/coregrind/m_syscalls/syscalls.c
index 118e956..66d4e1d 100644
--- a/coregrind/m_syscalls/syscalls.c
+++ b/coregrind/m_syscalls/syscalls.c
@@ -841,10 +841,10 @@
void buf_and_len_pre_check( ThreadId tid, Addr buf_p, Addr buflen_p,
Char* buf_s, Char* buflen_s )
{
- if (VG_(defined_pre_mem_write)()) {
+ if (VG_(tdict).track_pre_mem_write) {
UInt buflen_in = deref_UInt( tid, buflen_p, buflen_s);
if (buflen_in > 0) {
- TL_(pre_mem_write) ( Vg_CoreSysCall, tid, buf_s, buf_p, buflen_in );
+ VG_(tdict).track_pre_mem_write( Vg_CoreSysCall, tid, buf_s, buf_p, buflen_in );
}
}
}
@@ -853,10 +853,11 @@
void buf_and_len_post_check( ThreadId tid, Int res,
Addr buf_p, Addr buflen_p, Char* s )
{
- if (!VG_(is_kerror)(res) && VG_(defined_post_mem_write)()) {
+ if (!VG_(is_kerror)(res) && VG_(tdict).track_post_mem_write)
+ {
UInt buflen_out = deref_UInt( tid, buflen_p, s);
if (buflen_out > 0 && buf_p != (Addr)NULL) {
- TL_(post_mem_write) ( Vg_CoreSysCall, tid, buf_p, buflen_out );
+ VG_(tdict).track_post_mem_write( Vg_CoreSysCall, tid, buf_p, buflen_out );
}
}
}
@@ -6037,9 +6038,7 @@
pre_syscall again, without calling post_syscall (ie, more
pre's than post's) */
if (VG_(needs).syscall_wrapper) {
- //VGP_PUSHCC(VgpSkinSysWrap);
- TL_(post_syscall)(tid, syscallno, RES);
- //VGP_POPCC(VgpSkinSysWrap);
+ VG_TDICT_CALL(tool_post_syscall, tid, syscallno, RES);
}
}
@@ -6096,9 +6095,7 @@
/* Do any pre-syscall actions */
if (VG_(needs).syscall_wrapper) {
- VGP_PUSHCC(VgpToolSysWrap);
- TL_(pre_syscall)(tid, syscallno);
- VGP_POPCC(VgpToolSysWrap);
+ VG_TDICT_CALL(tool_pre_syscall, tid, syscallno);
}
PRINT("SYSCALL[%d,%d](%3d)%s%s:",
diff --git a/coregrind/toolfuncs.def b/coregrind/toolfuncs.def
deleted file mode 100644
index 42c9b79..0000000
--- a/coregrind/toolfuncs.def
+++ /dev/null
@@ -1,273 +0,0 @@
-# Tool interface functions
-# The format for an interface function definition is:
-# return_type, func_name, type arg, type arg
-# If the function has no arguments, specify no arguments (rather than void)
-#
-# Comments starting with "##" are turned into C comments in the output
-#
-# Lines starting with : set the prefix
-
-## These are the parameterised functions in the core. Some/all default
-## definitions are overridden by the tool version. At the very least, a tool
-## must define the fundamental template functions. Depending on what needs
-## are set, extra template functions will be used too. Functions are
-## grouped under the needs that govern their use.
-
-:tool
-## ------------------------------------------------------------------
-## Fundamental template functions
-
-## Do initialisation that can be done before command line processing.
-void, pre_clo_init
-
-## Do initialisation that can only be done after command line processing.
-void, post_clo_init
-
-## 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, 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 exitcode
-
-
-## ------------------------------------------------------------------
-## VG_(needs).core_errors
-
-## (none needed)
-
-## ------------------------------------------------------------------
-## 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 TL_(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
-## TL_(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
-## TL_(read_extra_suppression_info)().
-void, print_extra_suppression_info, Error* err
-
-
-## ------------------------------------------------------------------
-## 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
-
-
-## ------------------------------------------------------------------
-## 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
-
-## Print out command line usage for options for debugging the tool.
-void, print_debug_usage
-
-## ------------------------------------------------------------------
-## 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
-
-
-## ------------------------------------------------------------------
-## VG_(needs).syscall_wrapper
-
-## If either of the pre_ functions malloc() something to return, the
-## corresponding post_ function had better free() it!
-
-void, pre_syscall, ThreadId tid, UInt syscallno
-void, post_syscall, ThreadId tid, UInt syscallno, Int res
-
-
-## ---------------------------------------------------------------------
-## VG_(needs).sanity_checks
-
-## Can be useful for ensuring a tool's correctness. TL_(cheap_sanity_check)
-## is called very frequently; TL_(expensive_sanity_check) is called less
-## frequently and can be more involved.
-Bool, cheap_sanity_check
-Bool, expensive_sanity_check
-
-
-## ================================================================================
-## Event tracking functions
-:track
-
-## 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, new_mem_startup, Addr a, SizeT len, Bool rr, Bool ww, Bool xx
-void, new_mem_stack_signal, Addr a, SizeT len
-void, new_mem_brk, Addr a, SizeT len
-void, new_mem_mmap, Addr a, SizeT len, Bool rr, Bool ww, Bool xx
-
-void, copy_mem_remap, Addr from, Addr to, SizeT len
-void, change_mem_mprotect, Addr a, SizeT len, Bool rr, Bool ww, Bool xx
-void, die_mem_stack_signal, Addr a, SizeT len
-void, die_mem_brk, Addr a, SizeT len
-void, die_mem_munmap, Addr a, SizeT len
-
-## These ones are called when %esp 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: they must all use the VGA_REGPARM(n) attribute.
-VGA_REGPARM(1) void, new_mem_stack_4, Addr new_ESP
-VGA_REGPARM(1) void, new_mem_stack_8, Addr new_ESP
-VGA_REGPARM(1) void, new_mem_stack_12, Addr new_ESP
-VGA_REGPARM(1) void, new_mem_stack_16, Addr new_ESP
-VGA_REGPARM(1) void, new_mem_stack_32, Addr new_ESP
-void, new_mem_stack, Addr a, SizeT len
-
-VGA_REGPARM(1) void, die_mem_stack_4, Addr die_ESP
-VGA_REGPARM(1) void, die_mem_stack_8, Addr die_ESP
-VGA_REGPARM(1) void, die_mem_stack_12, Addr die_ESP
-VGA_REGPARM(1) void, die_mem_stack_16, Addr die_ESP
-VGA_REGPARM(1) void, die_mem_stack_32, Addr die_ESP
-void, die_mem_stack, Addr a, SizeT len
-
-## Used for redzone at end of thread stacks
-void, ban_mem_stack, Addr a, SizeT len
-
-## These ones occur around syscalls, signal handling, etc
-void, pre_mem_read, CorePart part, ThreadId tid, Char* s, Addr a, SizeT size
-void, pre_mem_read_asciiz,CorePart part, ThreadId tid, Char* s, Addr a
-void, pre_mem_write, CorePart part, ThreadId tid, Char* s, Addr a, SizeT size
-void, post_mem_write, 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, pre_reg_read, CorePart part, ThreadId tid, Char* s, OffT guest_state_offset, SizeT size
-void, post_reg_write, 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, post_reg_write_clientcall_return, ThreadId tid, OffT guest_state_offset, SizeT size, Addr f
-
-
-## Scheduler events (not exhaustive)
-void, thread_run, ThreadId tid
-
-
-## Thread events (not exhaustive)
-
-## Called during thread create, before the new thread has run any
-## instructions (or touched any memory).
-void, post_thread_create, ThreadId tid, ThreadId child
-void, post_thread_join, 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, pre_mutex_lock, ThreadId tid, void* mutex
-## Called once the thread actually holds the mutex (always paired with
-## pre_mutex_lock).
-void, post_mutex_lock, 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, post_mutex_unlock, 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, pre_deliver_signal, 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, post_deliver_signal, ThreadId tid, Int sigNo
-
-
-## Others... condition variable...
-## ...
-
-## Shadow memory management
-void, init_shadow_page, Addr p
-
-## ================================================================================
-## malloc and friends
-:malloc
-void*, malloc, ThreadId tid, SizeT n
-void*, __builtin_new, ThreadId tid, SizeT n
-void*, __builtin_vec_new, ThreadId tid, SizeT n
-void*, memalign, ThreadId tid, SizeT align, SizeT n
-void*, calloc, ThreadId tid, SizeT nmemb, SizeT n
-void, free, ThreadId tid, void* p
-void, __builtin_delete, ThreadId tid, void* p
-void, __builtin_vec_delete, ThreadId tid, void* p
-void*, realloc, ThreadId tid, void* p, SizeT size
diff --git a/coregrind/vg_main.c b/coregrind/vg_main.c
index 45e9f4d..ba89b42 100644
--- a/coregrind/vg_main.c
+++ b/coregrind/vg_main.c
@@ -1212,31 +1212,29 @@
goto bad_load;
}
- toolinfo = dlsym(handle, "vgTool_tool_info");
+ toolinfo = dlsym(handle, "vgPlain_tool_info");
ok = (NULL != toolinfo);
if (!ok) {
- fprintf(stderr, "Tool \"%s\" doesn't define TL_(tool_info) - "
+ fprintf(stderr, "Tool \"%s\" doesn't define its ToolInfo - "
"add VG_DETERMINE_INTERFACE_VERSION?\n", toolname);
goto bad_load;
}
ok = (toolinfo->sizeof_ToolInfo == sizeof(*toolinfo) &&
- toolinfo->interface_major_version == VG_CORE_INTERFACE_MAJOR_VERSION &&
- toolinfo->tl_pre_clo_init != NULL);
+ toolinfo->interface_version == VG_CORE_INTERFACE_VERSION &&
+ toolinfo->tl_pre_clo_init != NULL);
if (!ok) {
fprintf(stderr, "Error:\n"
" Tool and core interface versions do not match.\n"
- " Interface version used by core is: %d.%d (size %d)\n"
- " Interface version used by tool is: %d.%d (size %d)\n"
- " The major version numbers must match.\n",
- VG_CORE_INTERFACE_MAJOR_VERSION,
- VG_CORE_INTERFACE_MINOR_VERSION,
+ " Interface version used by core is: %d (size %d)\n"
+ " Interface version used by tool is: %d (size %d)\n"
+ " The version numbers must match.\n",
+ VG_CORE_INTERFACE_VERSION,
(Int)sizeof(*toolinfo),
- toolinfo->interface_major_version,
- toolinfo->interface_minor_version,
+ toolinfo->interface_version,
toolinfo->sizeof_ToolInfo);
fprintf(stderr, " You need to at least recompile, and possibly update,\n");
- if (VG_CORE_INTERFACE_MAJOR_VERSION > toolinfo->interface_major_version)
+ if (VG_CORE_INTERFACE_VERSION > toolinfo->interface_version)
fprintf(stderr, " your tool to work with this version of Valgrind.\n");
else
fprintf(stderr, " your version of Valgrind to work with this tool.\n");
@@ -1557,7 +1555,7 @@
if (VG_(details).name) {
VG_(printf)(" user options for %s:\n", VG_(details).name);
if (VG_(needs).command_line_options)
- TL_(print_usage)();
+ VG_TDICT_CALL(tool_print_usage);
else
VG_(printf)(" (none)\n");
}
@@ -1568,7 +1566,7 @@
VG_(printf)(" debugging options for %s:\n", VG_(details).name);
if (VG_(needs).command_line_options)
- TL_(print_debug_usage)();
+ VG_TDICT_CALL(tool_print_debug_usage);
else
VG_(printf)(" (none)\n");
}
@@ -1811,7 +1809,7 @@
VG_(clo_gen_suppressions) = 2;
else if ( ! VG_(needs).command_line_options
- || ! TL_(process_cmd_line_option)(arg) ) {
+ || ! VG_TDICT_CALL(tool_process_cmd_line_option, arg) ) {
VG_(bad_option)(arg);
}
skip_arg:
@@ -2297,7 +2295,7 @@
last 16 pages of memory have become accessible [...] */
if (VG_(needs).sanity_checks) {
VGP_PUSHCC(VgpToolCheapSanity);
- vg_assert(TL_(cheap_sanity_check)());
+ vg_assert(VG_TDICT_CALL(tool_cheap_sanity_check));
VGP_POPCC(VgpToolCheapSanity);
}
@@ -2320,7 +2318,7 @@
if (VG_(needs).sanity_checks) {
VGP_PUSHCC(VgpToolExpensiveSanity);
- vg_assert(TL_(expensive_sanity_check)());
+ vg_assert(VG_TDICT_CALL(tool_expensive_sanity_check));
VGP_POPCC(VgpToolExpensiveSanity);
}
@@ -2628,7 +2626,7 @@
}
process_cmd_line_options(client_auxv, tool);
- TL_(post_clo_init)();
+ VG_TDICT_CALL(tool_post_clo_init);
//--------------------------------------------------------------
// Determine CPU architecture and subarchitecture
@@ -2857,7 +2855,7 @@
if (VG_(needs).core_errors || VG_(needs).tool_errors)
VG_(show_all_errors)();
- TL_(fini)( 0 /*exitcode*/ );
+ VG_TDICT_CALL(tool_fini, 0/*exitcode*/);
VG_(sanity_check_general)( True /*include expensive checks*/ );
@@ -2874,21 +2872,6 @@
LibVEX_ShowAllocStats();
}
-/* If the tool fails to define one or more of the required functions,
- * make it very clear what went wrong! */
-// XXX: this is not a very good place for this function. Hopefully we'll be
-// able to remove it in the future.
-__attribute__ ((noreturn))
-void VG_(missing_tool_func) ( const Char* fn )
-{
- VG_(printf)(
- "\nTool error:\n"
- " The tool you have selected is missing the function `%s',\n"
- " which is required.\n\n",
- fn);
- VG_(tool_panic)("Missing tool function");
-}
-
/*--------------------------------------------------------------------*/
/*--- end vg_main.c ---*/
/*--------------------------------------------------------------------*/
diff --git a/coregrind/vg_needs.c b/coregrind/vg_needs.c
index 74bc314..9627a61 100644
--- a/coregrind/vg_needs.c
+++ b/coregrind/vg_needs.c
@@ -31,10 +31,8 @@
#include "core.h"
-
-/* ---------------------------------------------------------------------
- Tool data structure initialisation
- ------------------------------------------------------------------ */
+// The core/tool dictionary of functions (initially zeroed, as we want it)
+VgToolInterface VG_(tdict);
/*--------------------------------------------------------------------*/
/* Setting basic functions */
@@ -50,6 +48,7 @@
VG_(tdict).tool_fini = fini;
}
+
/*--------------------------------------------------------------------*/
/* Setting details */
@@ -77,6 +76,7 @@
DETAILS(Char*, bug_reports_to)
DETAILS(UInt, avg_translation_sizeB)
+
/*--------------------------------------------------------------------*/
/* Setting needs */
@@ -112,24 +112,24 @@
CHECK_NOT(VG_(details).copyright_author, NULL);
CHECK_NOT(VG_(details).bug_reports_to, NULL);
- if ( (VG_(defined_new_mem_stack_4)() ||
- VG_(defined_new_mem_stack_8)() ||
- VG_(defined_new_mem_stack_12)() ||
- VG_(defined_new_mem_stack_16)() ||
- VG_(defined_new_mem_stack_32)()) &&
- ! VG_(defined_new_mem_stack)())
+ if ( (VG_(tdict).track_new_mem_stack_4 ||
+ VG_(tdict).track_new_mem_stack_8 ||
+ VG_(tdict).track_new_mem_stack_12 ||
+ VG_(tdict).track_new_mem_stack_16 ||
+ VG_(tdict).track_new_mem_stack_32 ) &&
+ ! VG_(tdict).track_new_mem_stack)
{
VG_(printf)("\nTool error: one of the specialised `new_mem_stack_n'\n"
"events tracked, but not the generic `new_mem_stack' one.\n");
VG_(tool_panic)("`new_mem_stack' should be defined\n");
}
- if ( (VG_(defined_die_mem_stack_4)() ||
- VG_(defined_die_mem_stack_8)() ||
- VG_(defined_die_mem_stack_12)() ||
- VG_(defined_die_mem_stack_16)() ||
- VG_(defined_die_mem_stack_32)()) &&
- ! VG_(defined_die_mem_stack)())
+ if ( (VG_(tdict).track_die_mem_stack_4 ||
+ VG_(tdict).track_die_mem_stack_8 ||
+ VG_(tdict).track_die_mem_stack_12 ||
+ VG_(tdict).track_die_mem_stack_16 ||
+ VG_(tdict).track_die_mem_stack_32 ) &&
+ ! VG_(tdict).track_die_mem_stack)
{
VG_(printf)("\nTool error: one of the specialised `die_mem_stack_n'\n"
"events tracked, but not the generic `die_mem_stack' one.\n");
@@ -143,7 +143,7 @@
else
VG_(printf)("\nTool error: tool didn't allocate shadow memory, but apparently "
"needs it.\n");
- VG_(tool_panic)("VG_(needs).shadow_memory need should be set to match TL_(shadow_ratio)\n");
+ VG_(tool_panic)("VG_(needs).shadow_memory need should be set to match 'shadow_ratio'\n");
}
#undef CHECK_NOT
@@ -233,6 +233,7 @@
}
+/*--------------------------------------------------------------------*/
/* Replacing malloc() */
extern void VG_(malloc_funcs)(
@@ -261,8 +262,75 @@
VG_(set_client_malloc_redzone_szB)( client_malloc_redzone_szB );
}
+
/*--------------------------------------------------------------------*/
-/*--- end vg_needs.c ---*/
+/* Tracked events */
+
+#define DEF(fn, args...) \
+void VG_(fn)(void(*f)(args)) \
+{ \
+ VG_(tdict).fn = f; \
+}
+
+#define DEF2(fn, args...) \
+void VG_(fn)(VGA_REGPARM(1) void(*f)(args)) \
+{ \
+ VG_(tdict).fn = f; \
+}
+
+DEF(track_new_mem_startup, Addr, SizeT, Bool, Bool, Bool)
+DEF(track_new_mem_stack_signal, Addr, SizeT)
+DEF(track_new_mem_brk, Addr, SizeT)
+DEF(track_new_mem_mmap, Addr, SizeT, Bool, Bool, Bool)
+
+DEF(track_copy_mem_remap, Addr, Addr, SizeT)
+DEF(track_change_mem_mprotect, Addr, SizeT, Bool, Bool, Bool)
+DEF(track_die_mem_stack_signal, Addr, SizeT)
+DEF(track_die_mem_brk, Addr, SizeT)
+DEF(track_die_mem_munmap, Addr, SizeT)
+
+DEF2(track_new_mem_stack_4, Addr)
+DEF2(track_new_mem_stack_8, Addr)
+DEF2(track_new_mem_stack_12, Addr)
+DEF2(track_new_mem_stack_16, Addr)
+DEF2(track_new_mem_stack_32, Addr)
+DEF (track_new_mem_stack, Addr, SizeT)
+
+DEF2(track_die_mem_stack_4, Addr)
+DEF2(track_die_mem_stack_8, Addr)
+DEF2(track_die_mem_stack_12, Addr)
+DEF2(track_die_mem_stack_16, Addr)
+DEF2(track_die_mem_stack_32, Addr)
+DEF (track_die_mem_stack, Addr, SizeT)
+
+DEF(track_ban_mem_stack, Addr, SizeT)
+
+DEF(track_pre_mem_read, CorePart, ThreadId, Char*, Addr, SizeT)
+DEF(track_pre_mem_read_asciiz, CorePart, ThreadId, Char*, Addr)
+DEF(track_pre_mem_write, CorePart, ThreadId, Char*, Addr, SizeT)
+DEF(track_post_mem_write, CorePart, ThreadId, Addr, SizeT)
+
+DEF(track_pre_reg_read, CorePart, ThreadId, Char*, OffT, SizeT)
+DEF(track_post_reg_write, CorePart, ThreadId, OffT, SizeT)
+
+DEF(track_post_reg_write_clientcall_return, ThreadId, OffT, SizeT, Addr)
+
+DEF(track_thread_run, ThreadId)
+
+DEF(track_post_thread_create, ThreadId, ThreadId)
+DEF(track_post_thread_join, ThreadId, ThreadId)
+
+DEF(track_pre_mutex_lock, ThreadId, void*)
+DEF(track_post_mutex_lock, ThreadId, void*)
+DEF(track_post_mutex_unlock, ThreadId, void*)
+
+DEF(track_pre_deliver_signal, ThreadId, Int sigNo, Bool)
+DEF(track_post_deliver_signal, ThreadId, Int sigNo)
+
+DEF(track_init_shadow_page, Addr)
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
/*--------------------------------------------------------------------*/
diff --git a/coregrind/vg_replace_malloc.c b/coregrind/vg_replace_malloc.c
index 3880d92..39ca3f3 100644
--- a/coregrind/vg_replace_malloc.c
+++ b/coregrind/vg_replace_malloc.c
@@ -37,8 +37,8 @@
gory details.
This file can be linked into the injected so file for any tool that
- wishes to know about calls to malloc(). It should define functions
- TL_(malloc) et al that will be called.
+ wishes to know about calls to malloc(). The tool must define all
+ the functions that will be called via 'info'.
------------------------------------------------------------------ */
#include "valgrind.h" /* for VALGRIND_NON_SIMD_CALL[12] */
diff --git a/coregrind/vg_scheduler.c b/coregrind/vg_scheduler.c
index 75dec98..5d7bf02 100644
--- a/coregrind/vg_scheduler.c
+++ b/coregrind/vg_scheduler.c
@@ -1109,7 +1109,7 @@
VG_(printf)("client request: code %x, addr %p, len %d\n",
arg[0], (void*)arg[1], arg[2] );
- if (TL_(handle_client_request) ( tid, arg, &ret ))
+ if ( VG_TDICT_CALL(tool_handle_client_request, tid, arg, &ret) )
SET_CLREQ_RETVAL(tid, ret);
} else {
static Bool whined = False;
diff --git a/coregrind/vg_translate.c b/coregrind/vg_translate.c
index b6c31ac..b28d0e9 100644
--- a/coregrind/vg_translate.c
+++ b/coregrind/vg_translate.c
@@ -93,7 +93,7 @@
# define DO(kind, syze) \
do { \
- if (!VG_(defined_##kind##_mem_stack_##syze)()) \
+ if (!VG_(tdict).track_##kind##_mem_stack_##syze) \
goto generic; \
\
/* I don't know if it's really necessary to say that the */ \
@@ -327,19 +327,18 @@
static Bool need_to_handle_SP_assignment(void)
{
- return ( VG_(defined_new_mem_stack_4)() ||
- VG_(defined_die_mem_stack_4)() ||
- VG_(defined_new_mem_stack_8)() ||
- VG_(defined_die_mem_stack_8)() ||
- VG_(defined_new_mem_stack_12)() ||
- VG_(defined_die_mem_stack_12)() ||
- VG_(defined_new_mem_stack_16)() ||
- VG_(defined_die_mem_stack_16)() ||
- VG_(defined_new_mem_stack_32)() ||
- VG_(defined_die_mem_stack_32)() ||
- VG_(defined_new_mem_stack)() ||
- VG_(defined_die_mem_stack)()
- );
+ return ( VG_(tdict).track_new_mem_stack_4 ||
+ VG_(tdict).track_die_mem_stack_4 ||
+ VG_(tdict).track_new_mem_stack_8 ||
+ VG_(tdict).track_die_mem_stack_8 ||
+ VG_(tdict).track_new_mem_stack_12 ||
+ VG_(tdict).track_die_mem_stack_12 ||
+ VG_(tdict).track_new_mem_stack_16 ||
+ VG_(tdict).track_die_mem_stack_16 ||
+ VG_(tdict).track_new_mem_stack_32 ||
+ VG_(tdict).track_die_mem_stack_32 ||
+ VG_(tdict).track_new_mem_stack ||
+ VG_(tdict).track_die_mem_stack );
}
@@ -443,6 +442,8 @@
}
/* Actually do the translation. */
+ tl_assert2(VG_(tdict).tool_instrument,
+ "you forgot to set VgToolInterface function 'tool_instrument'");
tres = LibVEX_Translate (
VG_(vex_arch), VG_(vex_subarch),
VG_(vex_arch), VG_(vex_subarch),
@@ -451,7 +452,7 @@
chase_into_ok,
&vge,
tmpbuf, N_TMPBUF, &tmpbuf_used,
- TL_(instrument),
+ VG_(tdict).tool_instrument,
need_to_handle_SP_assignment()
? vg_SP_update_pass
: NULL,