From: Nicholas Nethercote Date: Mon, 9 May 2005 01:02:08 +0000 (+0000) Subject: Big clean-up: changed the core/tool interface to be mediated entirely X-Git-Tag: svn/VALGRIND_3_0_0~674 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a08662c48c7bcf86cca643d0e328295a6712f44a;p=thirdparty%2Fvalgrind.git 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 --- diff --git a/addrcheck/ac_main.c b/addrcheck/ac_main.c index 343799c913..07a21d601b 100644 --- a/addrcheck/ac_main.c +++ b/addrcheck/ac_main.c @@ -39,7 +39,7 @@ /*--- Comparing and printing errors ---*/ /*------------------------------------------------------------*/ -void TL_(pp_Error) ( Error* err ) +static void ac_pp_Error ( Error* err ) { MAC_Error* err_extra = VG_(get_error_extra)(err); @@ -75,7 +75,7 @@ void TL_(pp_Error) ( Error* err ) /*--- Suppressions ---*/ /*------------------------------------------------------------*/ -Bool TL_(recognised_suppression) ( Char* name, Supp* su ) +static Bool ac_recognised_suppression ( Char* name, Supp* su ) { return MAC_(shared_recognised_suppression)(name, su); } @@ -381,10 +381,6 @@ void set_address_range_perms ( Addr a, SizeT len, UInt example_a_bit ) } # endif - /* Check that zero page and highest page have not been written to - -- this could happen with buggy syscall wrappers. Today - (2001-04-26) had precisely such a problem with __NR_setitimer. */ - tl_assert(TL_(cheap_sanity_check)()); VGP_POPCC(VgpSetMem); } @@ -986,8 +982,8 @@ void ac_fpu_ACCESS_check_SLOWLY ( Addr addr, SizeT size, Bool isWrite ) /*--- Our instrumenter ---*/ /*------------------------------------------------------------*/ -IRBB* TL_(instrument)(IRBB* bb_in, VexGuestLayout* layout, - IRType gWordTy, IRType hWordTy ) +static IRBB* ac_instrument(IRBB* bb_in, VexGuestLayout* layout, + IRType gWordTy, IRType hWordTy ) { Int i, hsz; IRStmt* st; @@ -1189,13 +1185,13 @@ static void ac_detect_memory_leaks ( ThreadId tid, LeakCheckMode mode ) Sanity check machinery (permanently engaged). ------------------------------------------------------------------ */ -Bool TL_(cheap_sanity_check) ( void ) +static Bool ac_cheap_sanity_check ( void ) { /* nothing useful we can rapidly check */ return True; } -Bool TL_(expensive_sanity_check) ( void ) +static Bool ac_expensive_sanity_check ( void ) { Int i; @@ -1219,7 +1215,7 @@ Bool TL_(expensive_sanity_check) ( void ) /*--- Client requests ---*/ /*------------------------------------------------------------*/ -Bool TL_(handle_client_request) ( ThreadId tid, UWord* arg, UWord *ret ) +static Bool ac_handle_client_request ( ThreadId tid, UWord* arg, UWord *ret ) { #define IGNORE(what) \ do { \ @@ -1288,27 +1284,36 @@ Bool TL_(handle_client_request) ( ThreadId tid, UWord* arg, UWord *ret ) /*--- Setup ---*/ /*------------------------------------------------------------*/ -Bool TL_(process_cmd_line_option)(Char* arg) +static Bool ac_process_cmd_line_option(Char* arg) { return MAC_(process_common_cmd_line_option)(arg); } -void TL_(print_usage)(void) +static void ac_print_usage(void) { MAC_(print_common_usage)(); } -void TL_(print_debug_usage)(void) +static void ac_print_debug_usage(void) { MAC_(print_common_debug_usage)(); } /*------------------------------------------------------------*/ -/*--- Setup ---*/ +/*--- Setup and finalisation ---*/ /*------------------------------------------------------------*/ -void TL_(pre_clo_init)(void) +static void ac_post_clo_init ( void ) +{ +} + +static void ac_fini ( Int exitcode ) +{ + MAC_(common_fini)( ac_detect_memory_leaks ); +} + +static void ac_pre_clo_init(void) { VG_(details_name) ("Addrcheck"); VG_(details_version) (NULL); @@ -1318,38 +1323,38 @@ void TL_(pre_clo_init)(void) VG_(details_bug_reports_to) (VG_BUGS_TO); VG_(details_avg_translation_sizeB) ( 135 ); - VG_(basic_tool_funcs) (TL_(post_clo_init), - TL_(instrument), - TL_(fini)); + VG_(basic_tool_funcs) (ac_post_clo_init, + ac_instrument, + ac_fini); VG_(needs_core_errors) (); - VG_(needs_tool_errors) (TL_(eq_Error), - TL_(pp_Error), - TL_(update_extra), - TL_(recognised_suppression), - TL_(read_extra_suppression_info), - TL_(error_matches_suppression), - TL_(get_error_name), - TL_(print_extra_suppression_info)); + VG_(needs_tool_errors) (MAC_(eq_Error), + ac_pp_Error, + MAC_(update_extra), + MAC_(shared_recognised_suppression), + MAC_(read_extra_suppression_info), + MAC_(error_matches_suppression), + MAC_(get_error_name), + MAC_(print_extra_suppression_info)); VG_(needs_libc_freeres) (); - VG_(needs_command_line_options)(TL_(process_cmd_line_option), - TL_(print_usage), - TL_(print_debug_usage)); - VG_(needs_client_requests) (TL_(handle_client_request)); - VG_(needs_sanity_checks) (TL_(cheap_sanity_check), - TL_(expensive_sanity_check)); + VG_(needs_command_line_options)(MAC_(process_common_cmd_line_option), + MAC_(print_common_usage), + MAC_(print_common_debug_usage)); + VG_(needs_client_requests) (ac_handle_client_request); + VG_(needs_sanity_checks) (ac_cheap_sanity_check, + ac_expensive_sanity_check); VG_(needs_shadow_memory) (); - VG_(malloc_funcs) (TL_(malloc), - TL_(__builtin_new), - TL_(__builtin_vec_new), - TL_(memalign), - TL_(calloc), - TL_(free), - TL_(__builtin_delete), - TL_(__builtin_vec_delete), - TL_(realloc), - MALLOC_REDZONE_SZB ); + VG_(malloc_funcs) (MAC_(malloc), + MAC_(__builtin_new), + MAC_(__builtin_vec_new), + MAC_(memalign), + MAC_(calloc), + MAC_(free), + MAC_(__builtin_delete), + MAC_(__builtin_vec_delete), + MAC_(realloc), + MAC_MALLOC_REDZONE_SZB ); MAC_( new_mem_heap) = & ac_new_mem_heap; MAC_( ban_mem_heap) = & ac_make_noaccess; @@ -1357,37 +1362,37 @@ void TL_(pre_clo_init)(void) MAC_( die_mem_heap) = & ac_make_noaccess; MAC_(check_noaccess) = & ac_check_noaccess; - VG_(init_new_mem_startup) ( & ac_new_mem_startup ); - VG_(init_new_mem_stack_signal) ( & ac_make_accessible ); - VG_(init_new_mem_brk) ( & ac_make_accessible ); - VG_(init_new_mem_mmap) ( & ac_new_mem_mmap ); + VG_(track_new_mem_startup) ( & ac_new_mem_startup ); + VG_(track_new_mem_stack_signal)( & ac_make_accessible ); + VG_(track_new_mem_brk) ( & ac_make_accessible ); + VG_(track_new_mem_mmap) ( & ac_new_mem_mmap ); - VG_(init_copy_mem_remap) ( & ac_copy_address_range_state ); + VG_(track_copy_mem_remap) ( & ac_copy_address_range_state ); - VG_(init_die_mem_stack_signal) ( & ac_make_noaccess ); - VG_(init_die_mem_brk) ( & ac_make_noaccess ); - VG_(init_die_mem_munmap) ( & ac_make_noaccess ); - - VG_(init_new_mem_stack_4) ( & MAC_(new_mem_stack_4) ); - VG_(init_new_mem_stack_8) ( & MAC_(new_mem_stack_8) ); - VG_(init_new_mem_stack_12) ( & MAC_(new_mem_stack_12) ); - VG_(init_new_mem_stack_16) ( & MAC_(new_mem_stack_16) ); - VG_(init_new_mem_stack_32) ( & MAC_(new_mem_stack_32) ); - VG_(init_new_mem_stack) ( & MAC_(new_mem_stack) ); - - VG_(init_die_mem_stack_4) ( & MAC_(die_mem_stack_4) ); - VG_(init_die_mem_stack_8) ( & MAC_(die_mem_stack_8) ); - VG_(init_die_mem_stack_12) ( & MAC_(die_mem_stack_12) ); - VG_(init_die_mem_stack_16) ( & MAC_(die_mem_stack_16) ); - VG_(init_die_mem_stack_32) ( & MAC_(die_mem_stack_32) ); - VG_(init_die_mem_stack) ( & MAC_(die_mem_stack) ); + VG_(track_die_mem_stack_signal)( & ac_make_noaccess ); + VG_(track_die_mem_brk) ( & ac_make_noaccess ); + VG_(track_die_mem_munmap) ( & ac_make_noaccess ); + + VG_(track_new_mem_stack_4) ( & MAC_(new_mem_stack_4) ); + VG_(track_new_mem_stack_8) ( & MAC_(new_mem_stack_8) ); + VG_(track_new_mem_stack_12) ( & MAC_(new_mem_stack_12) ); + VG_(track_new_mem_stack_16) ( & MAC_(new_mem_stack_16) ); + VG_(track_new_mem_stack_32) ( & MAC_(new_mem_stack_32) ); + VG_(track_new_mem_stack) ( & MAC_(new_mem_stack) ); + + VG_(track_die_mem_stack_4) ( & MAC_(die_mem_stack_4) ); + VG_(track_die_mem_stack_8) ( & MAC_(die_mem_stack_8) ); + VG_(track_die_mem_stack_12) ( & MAC_(die_mem_stack_12) ); + VG_(track_die_mem_stack_16) ( & MAC_(die_mem_stack_16) ); + VG_(track_die_mem_stack_32) ( & MAC_(die_mem_stack_32) ); + VG_(track_die_mem_stack) ( & MAC_(die_mem_stack) ); - VG_(init_ban_mem_stack) ( & ac_make_noaccess ); + VG_(track_ban_mem_stack) ( & ac_make_noaccess ); - VG_(init_pre_mem_read) ( & ac_check_is_readable ); - VG_(init_pre_mem_read_asciiz) ( & ac_check_is_readable_asciiz ); - VG_(init_pre_mem_write) ( & ac_check_is_writable ); - VG_(init_post_mem_write) ( & ac_post_mem_write ); + VG_(track_pre_mem_read) ( & ac_check_is_readable ); + VG_(track_pre_mem_read_asciiz) ( & ac_check_is_readable_asciiz ); + VG_(track_pre_mem_write) ( & ac_check_is_writable ); + VG_(track_post_mem_write) ( & ac_post_mem_write ); VG_(register_profile_event) ( VgpSetMem, "set-mem-perms" ); VG_(register_profile_event) ( VgpCheckMem, "check-mem-perms" ); @@ -1397,16 +1402,7 @@ void TL_(pre_clo_init)(void) MAC_(common_pre_clo_init)(); } -void TL_(post_clo_init) ( void ) -{ -} - -void TL_(fini) ( Int exitcode ) -{ - MAC_(common_fini)( ac_detect_memory_leaks ); -} - -VG_DETERMINE_INTERFACE_VERSION(TL_(pre_clo_init), 1./8) +VG_DETERMINE_INTERFACE_VERSION(ac_pre_clo_init, 1./8) /*--------------------------------------------------------------------*/ diff --git a/cachegrind/cg_main.c b/cachegrind/cg_main.c index 6421b1037c..2b36d43cad 100644 --- a/cachegrind/cg_main.c +++ b/cachegrind/cg_main.c @@ -401,7 +401,7 @@ void handleOneStatement(IRTypeEnv* tyenv, IRBB* bbOut, IRStmt* st, to the host's native pointer type; if that is 32 bits then it discards the upper 32 bits. If we are cachegrinding on a 32-bit host then we are also ensured that the guest word size - is 32 bits, due to the assertion in TL_(instrument) that the + is 32 bits, due to the assertion in cg_instrument that the host and guest word sizes must be the same. Hence st->Ist.IMark.addr will have been derived from a 32-bit guest code address and truncation of it is safe. I believe this @@ -603,8 +603,8 @@ void endOfInstr(IRBB* bbOut, instr_info* i_node, Bool bbSeenBefore, addStmtToIRBB( bbOut, IRStmt_Dirty(di) ); } -IRBB* TL_(instrument) ( IRBB* bbIn, VexGuestLayout* layout, - IRType gWordTy, IRType hWordTy ) +static IRBB* cg_instrument ( IRBB* bbIn, VexGuestLayout* layout, + IRType gWordTy, IRType hWordTy ) { Int i, dataSize = 0, bbInfo_i; IRBB* bbOut; @@ -768,7 +768,7 @@ void configure_caches(cache_t* I1c, cache_t* D1c, cache_t* L2c) } /*------------------------------------------------------------*/ -/*--- TL_(fini)() and related function ---*/ +/*--- cg_fini() and related function ---*/ /*------------------------------------------------------------*/ // Total reads/writes/misses. Calculated during CC traversal at the end. @@ -902,7 +902,7 @@ void percentify(Int n, Int ex, Int field_width, char buf[]) for (i = 0; i < space; i++) buf[i] = ' '; } -void TL_(fini)(Int exitcode) +static void cg_fini(Int exitcode) { static char buf1[128], buf2[128], buf3[128], fmt [128]; @@ -1025,7 +1025,7 @@ void TL_(fini)(Int exitcode) /*--------------------------------------------------------------------*/ // Called when a translation is invalidated due to code unloading. -void TL_(discard_basic_block_info) ( Addr a, SizeT size ) +static void cg_discard_basic_block_info ( Addr a, SizeT size ) { VgHashNode** prev_next_ptr; VgHashNode* bbInfo; @@ -1075,7 +1075,7 @@ static void parse_cache_opt ( cache_t* cache, char* opt ) VG_(bad_option)(opt); } -Bool TL_(process_cmd_line_option)(Char* arg) +static Bool cg_process_cmd_line_option(Char* arg) { // 5 is length of "--I1=" if (VG_CLO_STREQN(5, arg, "--I1=")) @@ -1090,7 +1090,7 @@ Bool TL_(process_cmd_line_option)(Char* arg) return True; } -void TL_(print_usage)(void) +static void cg_print_usage(void) { VG_(printf)( " --I1=,, set I1 cache manually\n" @@ -1099,7 +1099,7 @@ void TL_(print_usage)(void) ); } -void TL_(print_debug_usage)(void) +static void cg_print_debug_usage(void) { VG_(printf)( " (none)\n" @@ -1110,7 +1110,22 @@ void TL_(print_debug_usage)(void) /*--- Setup ---*/ /*--------------------------------------------------------------------*/ -void TL_(pre_clo_init)(void) +static void cg_post_clo_init(void) +{ + cache_t I1c, D1c, L2c; + + configure_caches(&I1c, &D1c, &L2c); + + cachesim_I1_initcache(I1c); + cachesim_D1_initcache(D1c); + cachesim_L2_initcache(L2c); + + VG_(register_profile_event)(VgpGetLineCC, "get-lineCC"); + VG_(register_profile_event)(VgpCacheSimulate, "cache-simulate"); + VG_(register_profile_event)(VgpCacheResults, "cache-results"); +} + +static void cg_pre_clo_init(void) { Char* base_dir = NULL; @@ -1122,14 +1137,14 @@ void TL_(pre_clo_init)(void) VG_(details_bug_reports_to) (VG_BUGS_TO); VG_(details_avg_translation_sizeB) ( 155 ); - VG_(basic_tool_funcs) (TL_(post_clo_init), - TL_(instrument), - TL_(fini)); + VG_(basic_tool_funcs) (cg_post_clo_init, + cg_instrument, + cg_fini); - VG_(needs_basic_block_discards)(TL_(discard_basic_block_info)); - VG_(needs_command_line_options)(TL_(process_cmd_line_option), - TL_(print_usage), - TL_(print_debug_usage)); + VG_(needs_basic_block_discards)(cg_discard_basic_block_info); + VG_(needs_command_line_options)(cg_process_cmd_line_option, + cg_print_usage, + cg_print_debug_usage); /* Get working directory */ tl_assert( VG_(getcwd_alloc)(&base_dir) ); @@ -1143,22 +1158,7 @@ void TL_(pre_clo_init)(void) instr_info_table = VG_(HT_construct)(); } -void TL_(post_clo_init)(void) -{ - cache_t I1c, D1c, L2c; - - configure_caches(&I1c, &D1c, &L2c); - - cachesim_I1_initcache(I1c); - cachesim_D1_initcache(D1c); - cachesim_L2_initcache(L2c); - - VG_(register_profile_event)(VgpGetLineCC, "get-lineCC"); - VG_(register_profile_event)(VgpCacheSimulate, "cache-simulate"); - VG_(register_profile_event)(VgpCacheResults, "cache-results"); -} - -VG_DETERMINE_INTERFACE_VERSION(TL_(pre_clo_init), 0) +VG_DETERMINE_INTERFACE_VERSION(cg_pre_clo_init, 0) /*--------------------------------------------------------------------*/ /*--- end cg_main.c ---*/ diff --git a/corecheck/cc_main.c b/corecheck/cc_main.c index c7ad1a5940..213e4a208d 100644 --- a/corecheck/cc_main.c +++ b/corecheck/cc_main.c @@ -31,7 +31,21 @@ #include "tool.h" -void TL_(pre_clo_init)(void) +static void cc_post_clo_init(void) +{ +} + +static IRBB* cc_instrument(IRBB* bb_in, VexGuestLayout* layout, + IRType gWordTy, IRType hWordTy ) +{ + return bb_in; +} + +static void cc_fini(Int exitcode) +{ +} + +static void cc_pre_clo_init(void) { VG_(details_name) ("Corecheck"); VG_(details_version) (NULL); @@ -40,30 +54,16 @@ void TL_(pre_clo_init)(void) "Copyright (C) 2002-2005, and GNU GPL'd, by Nicholas Nethercote."); VG_(details_bug_reports_to) (VG_BUGS_TO); - VG_(basic_tool_funcs) (TL_(post_clo_init), - TL_(instrument), - TL_(fini)); + VG_(basic_tool_funcs) (cc_post_clo_init, + cc_instrument, + cc_fini); VG_(needs_core_errors)(); /* No core events to track */ } -void TL_(post_clo_init)(void) -{ -} - -IRBB* TL_(instrument)(IRBB* bb_in, VexGuestLayout* layout, - IRType gWordTy, IRType hWordTy ) -{ - return bb_in; -} - -void TL_(fini)(Int exitcode) -{ -} - -VG_DETERMINE_INTERFACE_VERSION(TL_(pre_clo_init), 0) +VG_DETERMINE_INTERFACE_VERSION(cc_pre_clo_init, 0) /*--------------------------------------------------------------------*/ /*--- end cc_main.c ---*/ diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am index a819fe1215..5d4f7534c9 100644 --- a/coregrind/Makefile.am +++ b/coregrind/Makefile.am @@ -47,15 +47,11 @@ noinst_HEADERS = \ 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 @@ stage2_SOURCES = \ vg_stabs.c \ vg_skiplist.c \ vg_symtypes.c \ - vg_toolint.c \ vg_translate.c \ vg_transtab.c @@ -131,19 +126,6 @@ endif 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 017445844d..f52bf5774d 100644 --- a/coregrind/core.h +++ b/coregrind/core.h @@ -101,10 +101,6 @@ typedef struct _ThreadState ThreadState; #include "valgrind.h" -#undef TL_ -#define TL_(x) vgToolInternal_##x - - /* --------------------------------------------------------------------- Global macros. ------------------------------------------------------------------ */ @@ -321,13 +317,6 @@ typedef 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 @@ typedef 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 @@ 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_(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 e6f629ce50..0000000000 --- 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 <) { - # 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 <ekind); @@ -263,7 +263,7 @@ static void pp_Error ( Error* err, Bool printCount ) // 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 @@ static void gen_suppression(Error* err) 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 @@ void VG_(maybe_record_error) ( ThreadId tid, 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 @@ void VG_(maybe_record_error) ( ThreadId tid, // 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 @@ Bool VG_(unique_error) ( ThreadId tid, ErrorKind ekind, Addr a, Char* s, /* 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 @@ static void load_one_suppressions_file ( Char* filename ) 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 @@ static void load_one_suppressions_file ( Char* filename ) } 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 @@ Bool supp_matches_error(Supp* su, Error* err) 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 8add5ec11e..1544aabacf 100644 --- a/coregrind/m_syscalls/priv_syscalls.h +++ b/coregrind/m_syscalls/priv_syscalls.h @@ -393,44 +393,44 @@ GEN_SYSCALL_WRAPPER(sys_mq_getsetattr); // * P? */ #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 118e95677b..66d4e1dc50 100644 --- a/coregrind/m_syscalls/syscalls.c +++ b/coregrind/m_syscalls/syscalls.c @@ -841,10 +841,10 @@ static 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 @@ static 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 @@ void VG_(post_syscall) (ThreadId tid) 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 @@ void VG_(client_syscall) ( ThreadId tid ) /* 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 42c9b79007..0000000000 --- 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 45e9f4d23c..ba89b423d9 100644 --- a/coregrind/vg_main.c +++ b/coregrind/vg_main.c @@ -1212,31 +1212,29 @@ static void load_tool( const char *toolname, 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 @@ static void usage ( Bool debug_help ) 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 @@ static void usage ( Bool debug_help ) 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 @@ static void process_cmd_line_options( UInt* client_auxv, const char* toolname ) 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 @@ void VG_(sanity_check_general) ( Bool force_expensive ) 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 @@ void VG_(sanity_check_general) ( Bool force_expensive ) 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 @@ int main(int argc, char **argv, char **envp) } 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 @@ void VG_(shutdown_actions)(ThreadId tid) 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 @@ void VG_(shutdown_actions)(ThreadId tid) 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 74bc3146e5..9627a61b71 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 @@ void VG_(basic_tool_funcs)( VG_(tdict).tool_fini = fini; } + /*--------------------------------------------------------------------*/ /* Setting details */ @@ -77,6 +76,7 @@ DETAILS(Char*, copyright_author) DETAILS(Char*, bug_reports_to) DETAILS(UInt, avg_translation_sizeB) + /*--------------------------------------------------------------------*/ /* Setting needs */ @@ -112,24 +112,24 @@ void VG_(sanity_check_needs) ( void) 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 @@ void VG_(sanity_check_needs) ( void) 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 @@ void VG_(needs_sanity_checks)( } +/*--------------------------------------------------------------------*/ /* Replacing malloc() */ extern void VG_(malloc_funcs)( @@ -261,8 +262,75 @@ extern void VG_(malloc_funcs)( VG_(set_client_malloc_redzone_szB)( client_malloc_redzone_szB ); } + +/*--------------------------------------------------------------------*/ +/* 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 vg_needs.c ---*/ +/*--- end ---*/ /*--------------------------------------------------------------------*/ diff --git a/coregrind/vg_replace_malloc.c b/coregrind/vg_replace_malloc.c index 3880d921e6..39ca3f3a85 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 75dec9816f..5d7bf02d92 100644 --- a/coregrind/vg_scheduler.c +++ b/coregrind/vg_scheduler.c @@ -1109,7 +1109,7 @@ void do_client_request ( ThreadId tid ) 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 b6c31ac7e4..b28d0e93a5 100644 --- a/coregrind/vg_translate.c +++ b/coregrind/vg_translate.c @@ -93,7 +93,7 @@ IRBB* vg_SP_update_pass ( IRBB* bb_in, VexGuestLayout* layout, # 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 chase_into_ok ( Addr64 addr64 ) 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 @@ Bool VG_(translate) ( ThreadId tid, } /* 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 @@ Bool VG_(translate) ( ThreadId tid, 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, diff --git a/docs/xml/writing-tools.xml b/docs/xml/writing-tools.xml index 8915a3632b..f91672f279 100644 --- a/docs/xml/writing-tools.xml +++ b/docs/xml/writing-tools.xml @@ -291,7 +291,7 @@ object valgrind.so, using the dynamic linker's LD_PRELOAD variable. Any functions defined in the tool that share the name with a function defined in core (such as the instrumentation -function TL_(instrument)()) +function instrument()) override the core's definition. Thus the core can call the necessary tool functions. @@ -384,7 +384,7 @@ top-level directory valgrind/. Copy none/nl_main.c into foobar/, renaming it as fb_main.c. Edit it by changing the lines - in TL_(pre_clo_init)() to + in pre_clo_init() to something appropriate for the tool. These fields are used in the startup message, except for bug_reports_to which is used @@ -459,16 +459,16 @@ possible tool, onto the interesting stuff... A tool must define at least these four functions: + pre_clo_init() + post_clo_init() + instrument() + fini()]]> Also, it must use the macro VG_DETERMINE_INTERFACE_VERSION exactly once in its source code. If it doesn't, you will get a link error involving -VG_(tool_interface_major_version). +VG_(tool_interface_version). This macro is used to ensure the core/tool interface used by the core and a plugged-in tool are binary compatible. @@ -484,8 +484,8 @@ functions. Initialisation Most of the initialisation should be done in -TL_(pre_clo_init)(). Only use -TL_(post_clo_init)() if a tool +pre_clo_init(). Only use +post_clo_init() if a tool provides command line options and must do some initialisation after option processing takes place ("clo" stands for "command line @@ -547,7 +547,7 @@ events" can be found in Instrumentation -TL_(instrument)() is the +instrument() is the interesting one. It allows you to instrument UCode, which is Valgrind's RISC-like intermediate language. UCode is described in diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c index d192136947..0ea7b17e38 100644 --- a/helgrind/hg_main.c +++ b/helgrind/hg_main.c @@ -1652,11 +1652,6 @@ void set_address_range_state ( Addr a, SizeT len /* in bytes */, VG_(tool_panic)("Unexpected Vge_InitStatus"); } - /* Check that zero page and highest page have not been written to - -- this could happen with buggy syscall wrappers. Today - (2001-04-26) had precisely such a problem with - __NR_setitimer. */ - tl_assert(TL_(cheap_sanity_check)()); VGP_POPCC(VgpSARP); } @@ -1841,27 +1836,27 @@ void* alloc_and_new_mem ( ThreadId tid, SizeT size, SizeT alignment, return (void*)p; } -void* TL_(malloc) ( ThreadId tid, SizeT n ) +static void* hg_malloc ( ThreadId tid, SizeT n ) { return alloc_and_new_mem ( tid, n, VG_(clo_alignment), /*is_zeroed*/False ); } -void* TL_(__builtin_new) ( ThreadId tid, SizeT n ) +static void* hg___builtin_new ( ThreadId tid, SizeT n ) { return alloc_and_new_mem ( tid, n, VG_(clo_alignment), /*is_zeroed*/False ); } -void* TL_(__builtin_vec_new) ( ThreadId tid, SizeT n ) +static void* hg___builtin_vec_new ( ThreadId tid, SizeT n ) { return alloc_and_new_mem ( tid, n, VG_(clo_alignment), /*is_zeroed*/False ); } -void* TL_(memalign) ( ThreadId tid, SizeT align, SizeT n ) +static void* hg_memalign ( ThreadId tid, SizeT align, SizeT n ) { return alloc_and_new_mem ( tid, n, align, /*is_zeroed*/False ); } -void* TL_(calloc) ( ThreadId tid, SizeT nmemb, SizeT size ) +static void* hg_calloc ( ThreadId tid, SizeT nmemb, SizeT size ) { return alloc_and_new_mem ( tid, nmemb*size, VG_(clo_alignment), /*is_zeroed*/True ); @@ -1927,22 +1922,22 @@ void handle_free ( ThreadId tid, void* p ) die_and_free_mem ( tid, hc, prev_chunks_next_ptr ); } -void TL_(free) ( ThreadId tid, void* p ) +static void hg_free ( ThreadId tid, void* p ) { handle_free(tid, p); } -void TL_(__builtin_delete) ( ThreadId tid, void* p ) +static void hg___builtin_delete ( ThreadId tid, void* p ) { handle_free(tid, p); } -void TL_(__builtin_vec_delete) ( ThreadId tid, void* p ) +static void hg___builtin_vec_delete ( ThreadId tid, void* p ) { handle_free(tid, p); } -void* TL_(realloc) ( ThreadId tid, void* p, SizeT new_size ) +static void* hg_realloc ( ThreadId tid, void* p, SizeT new_size ) { HG_Chunk *hc; HG_Chunk **prev_chunks_next_ptr; @@ -1999,13 +1994,13 @@ void* TL_(realloc) ( ThreadId tid, void* p, SizeT new_size ) /*--- Machinery to support sanity checking ---*/ /*--------------------------------------------------------------*/ -Bool TL_(cheap_sanity_check) ( void ) +static Bool hg_cheap_sanity_check ( void ) { /* nothing useful we can rapidly check */ return True; } -Bool TL_(expensive_sanity_check)(void) +static Bool hg_expensive_sanity_check(void) { Int i; @@ -2266,8 +2261,8 @@ UCodeBlock* TL_(instrument) ( UCodeBlock* cb_in, Addr not_used ) return cb; } #endif -IRBB* TL_(instrument) ( IRBB* bb_in, VexGuestLayout* layout, - IRType gWordTy, IRType hWordTy ) +static IRBB* hg_instrument ( IRBB* bb_in, VexGuestLayout* layout, + IRType gWordTy, IRType hWordTy ) { VG_(message)(Vg_DebugMsg, "Helgrind is not yet ready to handle Vex IR"); VG_(exit)(1); @@ -2466,7 +2461,7 @@ static void describe_addr ( Addr a, AddrInfo* ai ) /* Updates the copy with address info if necessary. */ -UInt TL_(update_extra)(Error* err) +static UInt hg_update_extra(Error* err) { HelgrindError* extra; @@ -2540,7 +2535,7 @@ static void record_lockgraph_error(ThreadId tid, Mutex *mutex, VG_(maybe_record_error)(tid, LockGraphErr, mutex->mutexp, "", &err_extra); } -Bool TL_(eq_Error) ( VgRes not_used, Error* e1, Error* e2 ) +static Bool hg_eq_Error ( VgRes not_used, Error* e1, Error* e2 ) { Char *e1s, *e2s; @@ -2649,7 +2644,7 @@ static Char *lockset_str(const Char *prefix, const LockSet *lockset) return buf; } -void TL_(pp_Error) ( Error* err ) +static void hg_pp_Error ( Error* err ) { HelgrindError *extra = (HelgrindError *)VG_(get_error_extra)(err); Char buf[100]; @@ -2781,7 +2776,7 @@ void TL_(pp_Error) ( Error* err ) } -Bool TL_(recognised_suppression) ( Char* name, Supp *su ) +static Bool hg_recognised_suppression ( Char* name, Supp *su ) { if (0 == VG_(strcmp)(name, "Eraser")) { VG_(set_supp_kind)(su, EraserSupp); @@ -2792,7 +2787,7 @@ Bool TL_(recognised_suppression) ( Char* name, Supp *su ) } -Bool TL_(read_extra_suppression_info) ( Int fd, Char* buf, Int nBuf, Supp* su ) +static Bool hg_read_extra_suppression_info ( Int fd, Char* buf, Int nBuf, Supp* su ) { /* do nothing -- no extra suppression info present. Return True to indicate nothing bad happened. */ @@ -2800,14 +2795,14 @@ Bool TL_(read_extra_suppression_info) ( Int fd, Char* buf, Int nBuf, Supp* su ) } -Bool TL_(error_matches_suppression)(Error* err, Supp* su) +static Bool hg_error_matches_suppression(Error* err, Supp* su) { tl_assert(VG_(get_supp_kind)(su) == EraserSupp); return (VG_(get_error_kind)(err) == EraserErr); } -extern Char* TL_(get_error_name) ( Error* err ) +static Char* hg_get_error_name ( Error* err ) { if (EraserErr == VG_(get_error_kind)(err)) { return "Eraser"; @@ -2816,7 +2811,7 @@ extern Char* TL_(get_error_name) ( Error* err ) } } -extern void TL_(print_extra_suppression_info) ( Error* err ) +static void hg_print_extra_suppression_info ( Error* err ) { /* Do nothing */ } @@ -3237,7 +3232,7 @@ static void bus_unlock(void) /*--- Client requests ---*/ /*--------------------------------------------------------------------*/ -Bool TL_(handle_client_request)(ThreadId tid, UWord *args, UWord *ret) +static Bool hg_handle_client_request(ThreadId tid, UWord *args, UWord *ret) { if (!VG_IS_TOOL_USERREQ('H','G',args[0])) return False; @@ -3262,100 +3257,10 @@ Bool TL_(handle_client_request)(ThreadId tid, UWord *args, UWord *ret) /*--------------------------------------------------------------------*/ -/*--- Setup ---*/ +/*--- Setup and finalisation ---*/ /*--------------------------------------------------------------------*/ -void TL_(pre_clo_init)(void) -{ - Int i; - LockSet *empty; - - VG_(details_name) ("Helgrind"); - VG_(details_version) (NULL); - VG_(details_description) ("a data race detector"); - VG_(details_copyright_author)( - "Copyright (C) 2002-2005, and GNU GPL'd, by Nicholas Nethercote et al."); - VG_(details_bug_reports_to) (VG_BUGS_TO); - VG_(details_avg_translation_sizeB) ( 115 ); - - VG_(basic_tool_funcs) (TL_(post_clo_init), - TL_(instrument), - TL_(fini)); - - VG_(needs_core_errors) (); - VG_(needs_tool_errors) (TL_(eq_Error), - TL_(pp_Error), - TL_(update_extra), - TL_(recognised_suppression), - TL_(read_extra_suppression_info), - TL_(error_matches_suppression), - TL_(get_error_name), - TL_(print_extra_suppression_info)); - VG_(needs_data_syms) (); - VG_(needs_client_requests) (TL_(handle_client_request)); - VG_(needs_command_line_options)(TL_(process_cmd_line_option), - TL_(print_usage), - TL_(print_debug_usage)); - VG_(needs_shadow_memory) (); - - VG_(malloc_funcs) (TL_(malloc), - TL_(__builtin_new), - TL_(__builtin_vec_new), - TL_(memalign), - TL_(calloc), - TL_(free), - TL_(__builtin_delete), - TL_(__builtin_vec_delete), - TL_(realloc), - 8 ); - - VG_(init_new_mem_startup) (& eraser_new_mem_startup); - - /* stack ones not decided until VG_(post_clo_init)() */ - - VG_(init_new_mem_brk) (& make_writable); - VG_(init_new_mem_mmap) (& eraser_new_mem_startup); - - VG_(init_change_mem_mprotect) (& eraser_set_perms); - - VG_(init_ban_mem_stack) (NULL); - - VG_(init_die_mem_stack) (NULL); - VG_(init_die_mem_stack_signal) (NULL); - VG_(init_die_mem_brk) (NULL); - VG_(init_die_mem_munmap) (NULL); - - VG_(init_pre_mem_read) (& eraser_pre_mem_read); - VG_(init_pre_mem_read_asciiz) (& eraser_pre_mem_read_asciiz); - VG_(init_pre_mem_write) (& eraser_pre_mem_write); - VG_(init_post_mem_write) (NULL); - - VG_(init_post_thread_create) (& hg_thread_create); - VG_(init_post_thread_join) (& hg_thread_join); - - VG_(init_pre_mutex_lock) (& eraser_pre_mutex_lock); - VG_(init_post_mutex_lock) (& eraser_post_mutex_lock); - VG_(init_post_mutex_unlock) (& eraser_post_mutex_unlock); - - for (i = 0; i < LOCKSET_HASH_SZ; i++) - lockset_hash[i] = NULL; - - empty = alloc_LockSet(0); - insert_LockSet(empty); - emptyset = empty; - - /* Init lock table and thread segments */ - for (i = 0; i < VG_N_THREADS; i++) { - thread_locks[i] = empty; - - newTLS(i); - } - - init_shadow_memory(); - hg_malloc_list = VG_(HT_construct)(); -} - -Bool TL_(process_cmd_line_option)(Char* arg) +static Bool hg_process_cmd_line_option(Char* arg) { if (VG_CLO_STREQ(arg, "--show-last-access=no")) clo_execontext = EC_None; @@ -3372,7 +3277,7 @@ Bool TL_(process_cmd_line_option)(Char* arg) return True; } -void TL_(print_usage)(void) +static void hg_print_usage(void) { VG_(printf)( " --private-stacks=yes|no assume thread stacks are used privately [no]\n" @@ -3382,12 +3287,12 @@ void TL_(print_usage)(void) VG_(replacement_malloc_print_usage)(); } -void TL_(print_debug_usage)(void) +static void hg_print_debug_usage(void) { VG_(replacement_malloc_print_debug_usage)(); } -void TL_(post_clo_init)(void) +static void hg_post_clo_init(void) { void (*stack_tracker)(Addr a, SizeT len); @@ -3401,12 +3306,12 @@ void TL_(post_clo_init)(void) else stack_tracker = & eraser_new_mem_stack; - VG_(init_new_mem_stack) (stack_tracker); - VG_(init_new_mem_stack_signal) (stack_tracker); + VG_(track_new_mem_stack) (stack_tracker); + VG_(track_new_mem_stack_signal) (stack_tracker); } -void TL_(fini)(Int exitcode) +static void hg_fini(Int exitcode) { if (DEBUG_LOCK_TABLE) { pp_all_LockSets(); @@ -3414,7 +3319,7 @@ void TL_(fini)(Int exitcode) } if (LOCKSET_SANITY) - sanity_check_locksets("TL_(fini)"); + sanity_check_locksets("hg_fini"); if (VG_(clo_verbosity) > 0) VG_(message)(Vg_UserMsg, "%u possible data races found; %u lock order problems", @@ -3427,8 +3332,100 @@ void TL_(fini)(Int exitcode) ((stk_ld+stk_st)*100) / (stk_ld + stk_st + nonstk_ld + nonstk_st)); } +static void hg_pre_clo_init(void) +{ + Int i; + LockSet *empty; + + VG_(details_name) ("Helgrind"); + VG_(details_version) (NULL); + VG_(details_description) ("a data race detector"); + VG_(details_copyright_author)( + "Copyright (C) 2002-2005, and GNU GPL'd, by Nicholas Nethercote et al."); + VG_(details_bug_reports_to) (VG_BUGS_TO); + VG_(details_avg_translation_sizeB) ( 115 ); + + VG_(basic_tool_funcs) (hg_post_clo_init, + hg_instrument, + hg_fini); + + VG_(needs_core_errors) (); + VG_(needs_tool_errors) (hg_eq_Error, + hg_pp_Error, + hg_update_extra, + hg_recognised_suppression, + hg_read_extra_suppression_info, + hg_error_matches_suppression, + hg_get_error_name, + hg_print_extra_suppression_info); + VG_(needs_data_syms) (); + VG_(needs_client_requests) (hg_handle_client_request); + VG_(needs_sanity_checks) (hg_cheap_sanity_check, + hg_expensive_sanity_check); + VG_(needs_command_line_options)(hg_process_cmd_line_option, + hg_print_usage, + hg_print_debug_usage); + VG_(needs_shadow_memory) (); + + VG_(malloc_funcs) (hg_malloc, + hg___builtin_new, + hg___builtin_vec_new, + hg_memalign, + hg_calloc, + hg_free, + hg___builtin_delete, + hg___builtin_vec_delete, + hg_realloc, + 8 ); + + VG_(track_new_mem_startup) (& eraser_new_mem_startup); + + /* stack ones not decided until hg_post_clo_init() */ + + VG_(track_new_mem_brk) (& make_writable); + VG_(track_new_mem_mmap) (& eraser_new_mem_startup); + + VG_(track_change_mem_mprotect) (& eraser_set_perms); + + VG_(track_ban_mem_stack) (NULL); + + VG_(track_die_mem_stack) (NULL); + VG_(track_die_mem_stack_signal)(NULL); + VG_(track_die_mem_brk) (NULL); + VG_(track_die_mem_munmap) (NULL); + + VG_(track_pre_mem_read) (& eraser_pre_mem_read); + VG_(track_pre_mem_read_asciiz) (& eraser_pre_mem_read_asciiz); + VG_(track_pre_mem_write) (& eraser_pre_mem_write); + VG_(track_post_mem_write) (NULL); + + VG_(track_post_thread_create) (& hg_thread_create); + VG_(track_post_thread_join) (& hg_thread_join); + + VG_(track_pre_mutex_lock) (& eraser_pre_mutex_lock); + VG_(track_post_mutex_lock) (& eraser_post_mutex_lock); + VG_(track_post_mutex_unlock) (& eraser_post_mutex_unlock); + + for (i = 0; i < LOCKSET_HASH_SZ; i++) + lockset_hash[i] = NULL; + + empty = alloc_LockSet(0); + insert_LockSet(empty); + emptyset = empty; + + /* Init lock table and thread segments */ + for (i = 0; i < VG_N_THREADS; i++) { + thread_locks[i] = empty; + + newTLS(i); + } + + init_shadow_memory(); + hg_malloc_list = VG_(HT_construct)(); +} + /* Uses a 1:1 mapping */ -VG_DETERMINE_INTERFACE_VERSION(TL_(pre_clo_init), 1.0) +VG_DETERMINE_INTERFACE_VERSION(hg_pre_clo_init, 1.0) /*--------------------------------------------------------------------*/ /*--- end hg_main.c ---*/ diff --git a/include/Makefile.am b/include/Makefile.am index 6bdd5fc278..503c5dd9bd 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -3,7 +3,6 @@ SUBDIRS = $(VG_ARCH) $(VG_OS) $(VG_PLATFORM) . DIST_SUBDIRS = $(VG_ARCH_ALL) $(VG_OS_ALL) $(VG_PLATFORM_ALL) . EXTRA_DIST = \ - tool.h.base \ valgrind.h.in \ vg_profile.c @@ -18,12 +17,5 @@ incinc_HEADERS = \ pub_tool_stacktrace.h \ valgrind.h -BUILT_SOURCES = tool.h valgrind.h -CLEANFILES = tool.h valgrind.h - -tool.h: $(srcdir)/tool.h.base \ - $(top_srcdir)/coregrind/gen_toolint.pl $(top_srcdir)/coregrind/toolfuncs.def - rm -f $@ - cat $(srcdir)/tool.h.base > $@ - $(PERL) $(top_srcdir)/coregrind/gen_toolint.pl toolproto < $(top_srcdir)/coregrind/toolfuncs.def >> $@ || rm -f $@ - $(PERL) $(top_srcdir)/coregrind/gen_toolint.pl initproto < $(top_srcdir)/coregrind/toolfuncs.def >> $@ || rm -f $@ +BUILT_SOURCES = valgrind.h +CLEANFILES = valgrind.h diff --git a/include/pub_tool_errormgr.h b/include/pub_tool_errormgr.h index 6c5211a91d..7cc389375a 100644 --- a/include/pub_tool_errormgr.h +++ b/include/pub_tool_errormgr.h @@ -54,7 +54,8 @@ typedef struct _Error Error; -/* Useful in TL_(error_matches_suppression)(), TL_(pp_Error)(), etc */ +/* Useful in VG_(tdict).tool_error_matches_suppression(), + * VG_(tdict).tool_pp_Error(), etc */ ExeContext* VG_(get_error_where) ( Error* err ); ErrorKind VG_(get_error_kind) ( Error* err ); Addr VG_(get_error_address) ( Error* err ); @@ -112,7 +113,7 @@ typedef struct _Supp Supp; -/* Useful in TL_(error_matches_suppression)() */ +/* Useful in VG_(tdict).tool_error_matches_suppression() */ SuppKind VG_(get_supp_kind) ( Supp* su ); Char* VG_(get_supp_string) ( Supp* su ); void* VG_(get_supp_extra) ( Supp* su ); diff --git a/include/tool.h.base b/include/tool.h similarity index 84% rename from include/tool.h.base rename to include/tool.h index 3ef0730c0a..3571fb23b8 100644 --- a/include/tool.h.base +++ b/include/tool.h @@ -77,20 +77,14 @@ extern const Char *VG_(libdir); /*=== Core/tool interface version ===*/ /*====================================================================*/ -/* The major version number indicates binary-incompatible changes to the - interface; if the core and tool major versions don't match, Valgrind - will abort. The minor version indicates binary-compatible changes. - - (Update: as it happens, we're never using the minor version number, because - there's no point in doing so.) -*/ -#define VG_CORE_INTERFACE_MAJOR_VERSION 7 -#define VG_CORE_INTERFACE_MINOR_VERSION 0 +/* 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_major_version; - Int interface_minor_version; + Int interface_version; /* Initialise tool. Must do the following: - initialise the `details' struct, via the VG_(details_*)() functions @@ -103,21 +97,20 @@ typedef struct _ToolInfo { - register any tool-specific profiling events - any other tool-specific initialisation */ - void (*tl_pre_clo_init) ( void ); + 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; + float shadow_ratio; } ToolInfo; /* Every tool must include this macro somewhere, exactly once. */ -#define VG_DETERMINE_INTERFACE_VERSION(pre_clo_init, shadow) \ - const ToolInfo TL_(tool_info) = { \ - .sizeof_ToolInfo = sizeof(ToolInfo), \ - .interface_major_version = VG_CORE_INTERFACE_MAJOR_VERSION, \ - .interface_minor_version = VG_CORE_INTERFACE_MINOR_VERSION, \ - .tl_pre_clo_init = pre_clo_init, \ - .shadow_ratio = shadow, \ +#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, \ }; /*====================================================================*/ @@ -166,7 +159,7 @@ extern Bool VG_(clo_profile); /* Call this if a recognised option was bad for some reason. Note: don't use it just because an option was unrecognised -- return 'False' - from TL_(process_cmd_line_option) to indicate that. */ + from VG_(tdict).tool_process_cmd_line_option) to indicate that. */ extern void VG_(bad_option) ( Char* opt ); /* Client args */ @@ -797,7 +790,8 @@ extern void VG_(set_shadow_regs_area) ( ThreadId tid, OffT guest_state_offset, follow the following instructions. You can do it from scratch, though, if you enjoy that sort of thing. */ -/* Can be called from TL_(malloc) et al to do the actual alloc/freeing. */ +/* Can be called from VG_(tdict).malloc_malloc et al to do the actual + * alloc/freeing. */ extern void* VG_(cli_malloc) ( SizeT align, SizeT nbytes ); extern void VG_(cli_free) ( void* p ); @@ -828,10 +822,19 @@ extern void VG_(replacement_malloc_print_debug_usage) ( void ); /* Basic tool functions */ extern void VG_(basic_tool_funcs)( - void(*post_clo_init)(void), - IRBB*(*instrument)(IRBB* bb_in, VexGuestLayout* layout, - IRType gWordTy, IRType hWordTy ), - void(*fini)(Int) + // 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) ); /* ------------------------------------------------------------------ */ @@ -897,7 +900,8 @@ extern void VG_(needs_tool_errors) ( // 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. + // 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. @@ -920,12 +924,12 @@ extern void VG_(needs_tool_errors) ( // 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)(). + // 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 - // TL_(read_extra_suppression_info)(). + // VG_(tdict).tool_read_extra_suppression_info(). void (*print_extra_suppression_info)(Error* err) ); @@ -980,8 +984,8 @@ extern void VG_(needs_syscall_wrapper) ( ); /* Are tool-state sanity checks performed? */ -// Can be useful for ensuring a tool's correctness. TL_(cheap_sanity_check) -// is called very frequently; TL_(expensive_sanity_check) is called less +// 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), @@ -991,12 +995,8 @@ extern void VG_(needs_sanity_checks) ( /* Do we need to see data symbols? */ extern void VG_(needs_data_syms) ( void ); -/* Does the tool need shadow memory allocated (if you set this, you must also statically initialize - float TL_(shadow_ratio) = n./m; - to define how many shadow bits you need per client address space bit. -*/ +/* Does the tool need shadow memory allocated? */ extern void VG_(needs_shadow_memory)( void ); -extern float TL_(shadow_ratio); /* ------------------------------------------------------------------ */ /* Malloc replacement */ @@ -1025,6 +1025,132 @@ typedef Vg_CoreTranslate, Vg_CoreClientReq } CorePart; -#endif /* NDEF __TOOL_H */ +/* 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 */ + -/* gen_toolint.pl will put the VG_(init_*)() functions here: */ diff --git a/include/tool_asm.h b/include/tool_asm.h index 8b9f52884a..c8d01dc4c1 100644 --- a/include/tool_asm.h +++ b/include/tool_asm.h @@ -45,9 +45,6 @@ #define VGO_(str) VGAPPEND(vgOS_,str) #define VGP_(str) VGAPPEND(vgPlatform_,str) -/* Tool-specific ones. Note that final name still starts with "vg". */ -#define TL_(str) VGAPPEND(vgTool_,str) - #endif /* ndef __TOOL_ASM_H */ /*--------------------------------------------------------------------*/ diff --git a/lackey/lk_main.c b/lackey/lk_main.c index dbeabb8cf6..4657340d21 100644 --- a/lackey/lk_main.c +++ b/lackey/lk_main.c @@ -44,7 +44,7 @@ static void add_one_dlrr_call(void) n_dlrr_calls++; } -/* See comment above TL_(instrument) for reason why n_machine_instrs is +/* See comment above lk_instrument for reason why n_machine_instrs is incremented here. */ static void add_one_BB(void) { @@ -72,22 +72,7 @@ static void add_one_Jcc_untaken(void) n_Jccs_untaken++; } -void TL_(pre_clo_init)(void) -{ - VG_(details_name) ("Lackey"); - VG_(details_version) (NULL); - VG_(details_description) ("an example Valgrind tool"); - VG_(details_copyright_author)( - "Copyright (C) 2002-2005, and GNU GPL'd, by Nicholas Nethercote."); - VG_(details_bug_reports_to) (VG_BUGS_TO); - VG_(details_avg_translation_sizeB) ( 175 ); - - VG_(basic_tool_funcs) (TL_(post_clo_init), - TL_(instrument), - TL_(fini)); -} - -void TL_(post_clo_init)(void) +static void lk_post_clo_init(void) { } @@ -133,8 +118,8 @@ void TL_(post_clo_init)(void) Which gives us the right answer. And just to avoid two C calls, we fold the basic-block-beginning call in with add_one_BB(). Phew. */ -IRBB* TL_(instrument)(IRBB* bb_in, VexGuestLayout* layout, - IRType gWordTy, IRType hWordTy ) +static IRBB* lk_instrument(IRBB* bb_in, VexGuestLayout* layout, + IRType gWordTy, IRType hWordTy ) { IRDirty* di; Int i; @@ -251,7 +236,7 @@ IRBB* TL_(instrument)(IRBB* bb_in, VexGuestLayout* layout, #endif } -void TL_(fini)(Int exitcode) +static void lk_fini(Int exitcode) { VG_(message)(Vg_UserMsg, "Counted %d calls to _dl_runtime_resolve()", n_dlrr_calls); @@ -282,7 +267,22 @@ void TL_(fini)(Int exitcode) VG_(message)(Vg_UserMsg, "Exit code: %d", exitcode); } -VG_DETERMINE_INTERFACE_VERSION(TL_(pre_clo_init), 0) +static void lk_pre_clo_init(void) +{ + VG_(details_name) ("Lackey"); + VG_(details_version) (NULL); + VG_(details_description) ("an example Valgrind tool"); + VG_(details_copyright_author)( + "Copyright (C) 2002-2005, and GNU GPL'd, by Nicholas Nethercote."); + VG_(details_bug_reports_to) (VG_BUGS_TO); + VG_(details_avg_translation_sizeB) ( 175 ); + + VG_(basic_tool_funcs) (lk_post_clo_init, + lk_instrument, + lk_fini); +} + +VG_DETERMINE_INTERFACE_VERSION(lk_pre_clo_init, 0) /*--------------------------------------------------------------------*/ /*--- end lk_main.c ---*/ diff --git a/massif/ms_main.c b/massif/ms_main.c index fae3d71f38..530ef21f8e 100644 --- a/massif/ms_main.c +++ b/massif/ms_main.c @@ -251,6 +251,8 @@ static VgHashTable malloc_list = NULL; // HP_Chunks static UInt n_heap_blocks = 0; +// Current directory at startup. +static Char* base_dir; #define MAX_ALLOC_FNS 32 // includes the builtin ones @@ -288,7 +290,7 @@ static Bool clo_stacks = True; static Bool clo_depth = 3; static XFormat clo_format = XText; -Bool TL_(process_cmd_line_option)(Char* arg) +static Bool ms_process_cmd_line_option(Char* arg) { VG_BOOL_CLO(arg, "--heap", clo_heap) else VG_BOOL_CLO(arg, "--stacks", clo_stacks) @@ -316,7 +318,7 @@ Bool TL_(process_cmd_line_option)(Char* arg) return True; } -void TL_(print_usage)(void) +static void ms_print_usage(void) { VG_(printf)( " --heap=no|yes profile heap blocks [yes]\n" @@ -329,7 +331,7 @@ void TL_(print_usage)(void) VG_(replacement_malloc_print_usage)(); } -void TL_(print_debug_usage)(void) +static void ms_print_debug_usage(void) { VG_(replacement_malloc_print_debug_usage)(); } @@ -739,47 +741,47 @@ void die_block ( void* p, Bool custom_free ) } -void* TL_(malloc) ( ThreadId tid, SizeT n ) +static void* ms_malloc ( ThreadId tid, SizeT n ) { return new_block( tid, NULL, n, VG_(clo_alignment), /*is_zeroed*/False ); } -void* TL_(__builtin_new) ( ThreadId tid, SizeT n ) +static void* ms___builtin_new ( ThreadId tid, SizeT n ) { return new_block( tid, NULL, n, VG_(clo_alignment), /*is_zeroed*/False ); } -void* TL_(__builtin_vec_new) ( ThreadId tid, SizeT n ) +static void* ms___builtin_vec_new ( ThreadId tid, SizeT n ) { return new_block( tid, NULL, n, VG_(clo_alignment), /*is_zeroed*/False ); } -void* TL_(calloc) ( ThreadId tid, SizeT m, SizeT size ) +static void* ms_calloc ( ThreadId tid, SizeT m, SizeT size ) { return new_block( tid, NULL, m*size, VG_(clo_alignment), /*is_zeroed*/True ); } -void *TL_(memalign)( ThreadId tid, SizeT align, SizeT n ) +static void *ms_memalign ( ThreadId tid, SizeT align, SizeT n ) { return new_block( tid, NULL, n, align, False ); } -void TL_(free) ( ThreadId tid, void* p ) +static void ms_free ( ThreadId tid, void* p ) { die_block( p, /*custom_free*/False ); } -void TL_(__builtin_delete) ( ThreadId tid, void* p ) +static void ms___builtin_delete ( ThreadId tid, void* p ) { die_block( p, /*custom_free*/False); } -void TL_(__builtin_vec_delete) ( ThreadId tid, void* p ) +static void ms___builtin_vec_delete ( ThreadId tid, void* p ) { die_block( p, /*custom_free*/False ); } -void* TL_(realloc) ( ThreadId tid, void* p_old, SizeT new_size ) +static void* ms_realloc ( ThreadId tid, void* p_old, SizeT new_size ) { HP_Chunk* hc; HP_Chunk** remove_handle; @@ -1128,7 +1130,7 @@ static void die_mem_stack_signal(Addr a, SizeT len) /*--- Client Requests ---*/ /*------------------------------------------------------------*/ -Bool TL_(handle_client_request) ( ThreadId tid, UWord* argv, UWord* ret ) +static Bool ms_handle_client_request ( ThreadId tid, UWord* argv, UWord* ret ) { switch (argv[0]) { case VG_USERREQ__MALLOCLIKE_BLOCK: { @@ -1152,84 +1154,12 @@ Bool TL_(handle_client_request) ( ThreadId tid, UWord* argv, UWord* ret ) } } -/*------------------------------------------------------------*/ -/*--- Initialisation ---*/ -/*------------------------------------------------------------*/ - -// Current directory at startup. -static Char* base_dir; - -void TL_(pre_clo_init)() -{ - VG_(details_name) ("Massif"); - VG_(details_version) (NULL); - VG_(details_description) ("a space profiler"); - VG_(details_copyright_author)("Copyright (C) 2003, Nicholas Nethercote"); - VG_(details_bug_reports_to) (VG_BUGS_TO); - - // Basic functions - VG_(basic_tool_funcs) (TL_(post_clo_init), - TL_(instrument), - TL_(fini)); - - // Needs - VG_(needs_libc_freeres)(); - VG_(needs_command_line_options)(TL_(process_cmd_line_option), - TL_(print_usage), - TL_(print_debug_usage)); - VG_(needs_client_requests) (TL_(handle_client_request)); - - // Malloc replacement - VG_(malloc_funcs) (TL_(malloc), - TL_(__builtin_new), - TL_(__builtin_vec_new), - TL_(memalign), - TL_(calloc), - TL_(free), - TL_(__builtin_delete), - TL_(__builtin_vec_delete), - TL_(realloc), - 0 ); - - // Events to track - VG_(init_new_mem_stack_signal) ( new_mem_stack_signal ); - VG_(init_die_mem_stack_signal) ( die_mem_stack_signal ); - - // Profiling events - VG_(register_profile_event)(VgpGetXPt, "get-XPt"); - VG_(register_profile_event)(VgpGetXPtSearch, "get-XPt-search"); - VG_(register_profile_event)(VgpCensus, "census"); - VG_(register_profile_event)(VgpCensusHeap, "census-heap"); - VG_(register_profile_event)(VgpCensusSnapshot, "census-snapshot"); - VG_(register_profile_event)(VgpCensusTreeSize, "census-treesize"); - VG_(register_profile_event)(VgpUpdateXCon, "update-XCon"); - VG_(register_profile_event)(VgpCalcSpacetime2, "calc-exact_ST_dbld"); - VG_(register_profile_event)(VgpPrintHp, "print-hp"); - VG_(register_profile_event)(VgpPrintXPts, "print-XPts"); - - // HP_Chunks - malloc_list = VG_(HT_construct)(); - - // Dummy node at top of the context structure. - alloc_xpt = new_XPt(0, NULL, /*is_bottom*/False); - - tl_assert( VG_(getcwd_alloc)(&base_dir) ); -} - -void TL_(post_clo_init)(void) -{ - ms_interval = 1; - - // Do an initial sample for t = 0 - hp_census(); -} - /*------------------------------------------------------------*/ /*--- Instrumentation ---*/ /*------------------------------------------------------------*/ -IRBB* TL_(instrument) ( IRBB* bb_in, VexGuestLayout* layout, - IRType gWordTy, IRType hWordTy ) +static IRBB* ms_instrument ( IRBB* bb_in, VexGuestLayout* layout, + IRType gWordTy, IRType hWordTy ) { /* XXX Will Massif work when gWordTy != hWordTy ? */ return bb_in; @@ -1811,7 +1741,7 @@ print_summary(ULong total_ST, ULong heap_ST, ULong heap_admin_ST, } } -void TL_(fini)(Int exit_status) +static void ms_fini(Int exit_status) { ULong total_ST = 0; ULong heap_ST = 0; @@ -1829,7 +1759,76 @@ void TL_(fini)(Int exit_status) print_summary ( total_ST, heap_ST, heap_admin_ST, stack_ST ); } -VG_DETERMINE_INTERFACE_VERSION(TL_(pre_clo_init), 0) +/*------------------------------------------------------------*/ +/*--- Initialisation ---*/ +/*------------------------------------------------------------*/ + +static void ms_post_clo_init(void) +{ + ms_interval = 1; + + // Do an initial sample for t = 0 + hp_census(); +} + +static void ms_pre_clo_init() +{ + VG_(details_name) ("Massif"); + VG_(details_version) (NULL); + VG_(details_description) ("a space profiler"); + VG_(details_copyright_author)("Copyright (C) 2003, Nicholas Nethercote"); + VG_(details_bug_reports_to) (VG_BUGS_TO); + + // Basic functions + VG_(basic_tool_funcs) (ms_post_clo_init, + ms_instrument, + ms_fini); + + // Needs + VG_(needs_libc_freeres)(); + VG_(needs_command_line_options)(ms_process_cmd_line_option, + ms_print_usage, + ms_print_debug_usage); + VG_(needs_client_requests) (ms_handle_client_request); + + // Malloc replacement + VG_(malloc_funcs) (ms_malloc, + ms___builtin_new, + ms___builtin_vec_new, + ms_memalign, + ms_calloc, + ms_free, + ms___builtin_delete, + ms___builtin_vec_delete, + ms_realloc, + 0 ); + + // Events to track + VG_(track_new_mem_stack_signal)( new_mem_stack_signal ); + VG_(track_die_mem_stack_signal)( die_mem_stack_signal ); + + // Profiling events + VG_(register_profile_event)(VgpGetXPt, "get-XPt"); + VG_(register_profile_event)(VgpGetXPtSearch, "get-XPt-search"); + VG_(register_profile_event)(VgpCensus, "census"); + VG_(register_profile_event)(VgpCensusHeap, "census-heap"); + VG_(register_profile_event)(VgpCensusSnapshot, "census-snapshot"); + VG_(register_profile_event)(VgpCensusTreeSize, "census-treesize"); + VG_(register_profile_event)(VgpUpdateXCon, "update-XCon"); + VG_(register_profile_event)(VgpCalcSpacetime2, "calc-exact_ST_dbld"); + VG_(register_profile_event)(VgpPrintHp, "print-hp"); + VG_(register_profile_event)(VgpPrintXPts, "print-XPts"); + + // HP_Chunks + malloc_list = VG_(HT_construct)(); + + // Dummy node at top of the context structure. + alloc_xpt = new_XPt(0, NULL, /*is_bottom*/False); + + tl_assert( VG_(getcwd_alloc)(&base_dir) ); +} + +VG_DETERMINE_INTERFACE_VERSION(ms_pre_clo_init, 0) /*--------------------------------------------------------------------*/ /*--- end ms_main.c ---*/ diff --git a/memcheck/mac_malloc_wrappers.c b/memcheck/mac_malloc_wrappers.c index c14e33fc9c..8119a02cde 100644 --- a/memcheck/mac_malloc_wrappers.c +++ b/memcheck/mac_malloc_wrappers.c @@ -212,57 +212,57 @@ void* MAC_(new_block) ( ThreadId tid, return (void*)p; } -void* TL_(malloc) ( ThreadId tid, SizeT n ) +void* MAC_(malloc) ( ThreadId tid, SizeT n ) { if (complain_about_silly_args(n, "malloc")) { return NULL; } else { return MAC_(new_block) ( tid, 0, n, VG_(clo_alignment), - MALLOC_REDZONE_SZB, /*is_zeroed*/False, MAC_AllocMalloc, + MAC_MALLOC_REDZONE_SZB, /*is_zeroed*/False, MAC_AllocMalloc, MAC_(malloc_list)); } } -void* TL_(__builtin_new) ( ThreadId tid, SizeT n ) +void* MAC_(__builtin_new) ( ThreadId tid, SizeT n ) { if (complain_about_silly_args(n, "__builtin_new")) { return NULL; } else { return MAC_(new_block) ( tid, 0, n, VG_(clo_alignment), - MALLOC_REDZONE_SZB, /*is_zeroed*/False, MAC_AllocNew, + MAC_MALLOC_REDZONE_SZB, /*is_zeroed*/False, MAC_AllocNew, MAC_(malloc_list)); } } -void* TL_(__builtin_vec_new) ( ThreadId tid, SizeT n ) +void* MAC_(__builtin_vec_new) ( ThreadId tid, SizeT n ) { if (complain_about_silly_args(n, "__builtin_vec_new")) { return NULL; } else { return MAC_(new_block) ( tid, 0, n, VG_(clo_alignment), - MALLOC_REDZONE_SZB, /*is_zeroed*/False, MAC_AllocNewVec, + MAC_MALLOC_REDZONE_SZB, /*is_zeroed*/False, MAC_AllocNewVec, MAC_(malloc_list)); } } -void* TL_(memalign) ( ThreadId tid, SizeT align, SizeT n ) +void* MAC_(memalign) ( ThreadId tid, SizeT align, SizeT n ) { if (complain_about_silly_args(n, "memalign")) { return NULL; } else { return MAC_(new_block) ( tid, 0, n, align, - MALLOC_REDZONE_SZB, /*is_zeroed*/False, MAC_AllocMalloc, + MAC_MALLOC_REDZONE_SZB, /*is_zeroed*/False, MAC_AllocMalloc, MAC_(malloc_list)); } } -void* TL_(calloc) ( ThreadId tid, SizeT nmemb, SizeT size1 ) +void* MAC_(calloc) ( ThreadId tid, SizeT nmemb, SizeT size1 ) { if (complain_about_silly_args2(nmemb, size1)) { return NULL; } else { return MAC_(new_block) ( tid, 0, nmemb*size1, VG_(clo_alignment), - MALLOC_REDZONE_SZB, /*is_zeroed*/True, MAC_AllocMalloc, + MAC_MALLOC_REDZONE_SZB, /*is_zeroed*/True, MAC_AllocMalloc, MAC_(malloc_list)); } } @@ -320,25 +320,25 @@ void MAC_(handle_free) ( ThreadId tid, Addr p, UInt rzB, MAC_AllocKind kind ) VGP_POPCC(VgpCliMalloc); } -void TL_(free) ( ThreadId tid, void* p ) +void MAC_(free) ( ThreadId tid, void* p ) { MAC_(handle_free)( - tid, (Addr)p, MALLOC_REDZONE_SZB, MAC_AllocMalloc ); + tid, (Addr)p, MAC_MALLOC_REDZONE_SZB, MAC_AllocMalloc ); } -void TL_(__builtin_delete) ( ThreadId tid, void* p ) +void MAC_(__builtin_delete) ( ThreadId tid, void* p ) { MAC_(handle_free)( - tid, (Addr)p, MALLOC_REDZONE_SZB, MAC_AllocNew); + tid, (Addr)p, MAC_MALLOC_REDZONE_SZB, MAC_AllocNew); } -void TL_(__builtin_vec_delete) ( ThreadId tid, void* p ) +void MAC_(__builtin_vec_delete) ( ThreadId tid, void* p ) { MAC_(handle_free)( - tid, (Addr)p, MALLOC_REDZONE_SZB, MAC_AllocNewVec); + tid, (Addr)p, MAC_MALLOC_REDZONE_SZB, MAC_AllocNewVec); } -void* TL_(realloc) ( ThreadId tid, void* p, SizeT new_size ) +void* MAC_(realloc) ( ThreadId tid, void* p, SizeT new_size ) { MAC_Chunk *mc; MAC_Chunk **prev_chunks_next_ptr; @@ -394,17 +394,17 @@ void* TL_(realloc) ( ThreadId tid, void* p, SizeT new_size ) /* First half kept and copied, second half new, red zones as normal */ - MAC_(ban_mem_heap) ( p_new-MALLOC_REDZONE_SZB, MALLOC_REDZONE_SZB ); + MAC_(ban_mem_heap) ( p_new-MAC_MALLOC_REDZONE_SZB, MAC_MALLOC_REDZONE_SZB ); MAC_(copy_mem_heap)( (Addr)p, p_new, mc->size ); MAC_(new_mem_heap) ( p_new+mc->size, new_size-mc->size, /*inited*/False ); - MAC_(ban_mem_heap) ( p_new+new_size, MALLOC_REDZONE_SZB ); + MAC_(ban_mem_heap) ( p_new+new_size, MAC_MALLOC_REDZONE_SZB ); /* Copy from old to new */ for (i = 0; i < mc->size; i++) ((UChar*)p_new)[i] = ((UChar*)p)[i]; /* Free old memory */ - die_and_free_mem ( tid, mc, prev_chunks_next_ptr, MALLOC_REDZONE_SZB ); + die_and_free_mem ( tid, mc, prev_chunks_next_ptr, MAC_MALLOC_REDZONE_SZB ); /* this has to be after die_and_free_mem, otherwise the former succeeds in shorting out the new block, not the diff --git a/memcheck/mac_needs.c b/memcheck/mac_needs.c index 032ca4dfb2..ad11507855 100644 --- a/memcheck/mac_needs.c +++ b/memcheck/mac_needs.c @@ -145,7 +145,7 @@ static Bool eq_AddrInfo ( VgRes res, AddrInfo* ai1, AddrInfo* ai2 ) are otherwise the same, the faulting addrs and associated rwoffsets are allowed to be different. */ -Bool TL_(eq_Error) ( VgRes res, Error* e1, Error* e2 ) +Bool MAC_(eq_Error) ( VgRes res, Error* e1, Error* e2 ) { MAC_Error* e1_extra = VG_(get_error_extra)(e1); MAC_Error* e2_extra = VG_(get_error_extra)(e2); @@ -207,7 +207,7 @@ Bool TL_(eq_Error) ( VgRes res, Error* e1, Error* e2 ) return True; case LeakErr: - VG_(tool_panic)("Shouldn't get LeakErr in TL_(eq_Error),\n" + VG_(tool_panic)("Shouldn't get LeakErr in MAC_(eq_Error),\n" "since it's handled with VG_(unique_error)()!"); case IllegalMempoolErr: @@ -216,7 +216,7 @@ Bool TL_(eq_Error) ( VgRes res, Error* e1, Error* e2 ) default: VG_(printf)("Error:\n unknown error code %d\n", VG_(get_error_kind)(e1)); - VG_(tool_panic)("unknown error code in TL_(eq_Error)"); + VG_(tool_panic)("unknown error code in MAC_(eq_Error)"); } } @@ -315,7 +315,7 @@ void MAC_(pp_shared_Error) ( Error* err ) "stated on the next line"); break; default: - VG_(tool_panic)("TL_(pp_shared_Error)(axskind)"); + VG_(tool_panic)("MAC_(pp_shared_Error)(axskind)"); } VG_(pp_ExeContext)( VG_(get_error_where)(err) ); MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo); @@ -545,7 +545,7 @@ void MAC_(record_overlap_error) ( ThreadId tid, /* Updates the copy with address info if necessary (but not for all errors). */ -UInt TL_(update_extra)( Error* err ) +UInt MAC_(update_extra)( Error* err ) { switch (VG_(get_error_kind)(err)) { case ValueErr: @@ -597,7 +597,7 @@ Bool MAC_(shared_recognised_suppression) ( Char* name, Supp* su ) return True; } -Bool TL_(read_extra_suppression_info) ( Int fd, Char* buf, Int nBuf, Supp *su ) +Bool MAC_(read_extra_suppression_info) ( Int fd, Char* buf, Int nBuf, Supp *su ) { Bool eof; @@ -609,7 +609,7 @@ Bool TL_(read_extra_suppression_info) ( Int fd, Char* buf, Int nBuf, Supp *su ) return True; } -Bool TL_(error_matches_suppression)(Error* err, Supp* su) +Bool MAC_(error_matches_suppression)(Error* err, Supp* su) { Int su_size; MAC_Error* err_extra = VG_(get_error_extra)(err); @@ -660,11 +660,11 @@ Bool TL_(error_matches_suppression)(Error* err, Supp* su) " unknown suppression type %d\n", VG_(get_supp_kind)(su)); VG_(tool_panic)("unknown suppression type in " - "TL_(error_matches_suppression)"); + "MAC_(error_matches_suppression)"); } } -Char* TL_(get_error_name) ( Error* err ) +Char* MAC_(get_error_name) ( Error* err ) { Char* s; switch (VG_(get_error_kind)(err)) { @@ -701,7 +701,7 @@ Char* TL_(get_error_name) ( Error* err ) VG_(printf)(s); } -void TL_(print_extra_suppression_info) ( Error* err ) +void MAC_(print_extra_suppression_info) ( Error* err ) { if (ParamErr == VG_(get_error_kind)(err)) { VG_(printf)(" %s\n", VG_(get_error_string)(err)); diff --git a/memcheck/mac_shared.h b/memcheck/mac_shared.h index 6d07e44bc3..c541fc9ad5 100644 --- a/memcheck/mac_shared.h +++ b/memcheck/mac_shared.h @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------*/ -/*--- Declarations shared between MemCheck and AddrCheck. ---*/ +/*--- Declarations shared between Memcheck and Addrcheck. ---*/ /*--- mac_shared.h ---*/ /*--------------------------------------------------------------------*/ @@ -323,7 +323,7 @@ extern void MAC_(print_common_usage) ( void ); extern void MAC_(print_common_debug_usage) ( void ); /* We want a 16B redzone on heap blocks for Addrcheck and Memcheck */ -#define MALLOC_REDZONE_SZB 16 +#define MAC_MALLOC_REDZONE_SZB 16 /*------------------------------------------------------------*/ /*--- Variables ---*/ @@ -362,7 +362,14 @@ extern void MAC_(pp_AddrInfo) ( Addr a, AddrInfo* ai ); extern void MAC_(clear_MAC_Error) ( MAC_Error* err_extra ); -extern Bool MAC_(shared_recognised_suppression) ( Char* name, Supp* su ); +extern Bool MAC_(eq_Error) ( VgRes res, Error* e1, Error* e2 ); +extern UInt MAC_(update_extra)( Error* err ); +extern Bool MAC_(read_extra_suppression_info) ( Int fd, Char* buf, Int nBuf, Supp *su ); +extern Bool MAC_(error_matches_suppression)(Error* err, Supp* su); +extern Char* MAC_(get_error_name) ( Error* err ); +extern void MAC_(print_extra_suppression_info) ( Error* err ); + +extern Bool MAC_(shared_recognised_suppression) ( Char* name, Supp* su ); extern void* MAC_(new_block) ( ThreadId tid, Addr p, SizeT size, SizeT align, UInt rzB, @@ -430,6 +437,15 @@ extern VGA_REGPARM(1) void MAC_(die_mem_stack_32) ( Addr old_ESP ); extern void MAC_(die_mem_stack) ( Addr a, SizeT len); extern void MAC_(new_mem_stack) ( Addr a, SizeT len); +extern void* MAC_(malloc) ( ThreadId tid, SizeT n ); +extern void* MAC_(__builtin_new) ( ThreadId tid, SizeT n ); +extern void* MAC_(__builtin_vec_new) ( ThreadId tid, SizeT n ); +extern void* MAC_(memalign) ( ThreadId tid, SizeT align, SizeT n ); +extern void* MAC_(calloc) ( ThreadId tid, SizeT nmemb, SizeT size1 ); +extern void MAC_(free) ( ThreadId tid, void* p ); +extern void MAC_(__builtin_delete) ( ThreadId tid, void* p ); +extern void MAC_(__builtin_vec_delete) ( ThreadId tid, void* p ); +extern void* MAC_(realloc) ( ThreadId tid, void* p, SizeT new_size ); /*------------------------------------------------------------*/ /*--- Stack pointer adjustment ---*/ diff --git a/memcheck/mc_include.h b/memcheck/mc_include.h index 9a9bcb89ca..7ac22fc9c9 100644 --- a/memcheck/mc_include.h +++ b/memcheck/mc_include.h @@ -70,6 +70,10 @@ extern VGA_REGPARM(1) UWord MC_(helperc_LOADV2) ( Addr ); extern VGA_REGPARM(1) UWord MC_(helperc_LOADV4) ( Addr ); extern VGA_REGPARM(1) ULong MC_(helperc_LOADV8) ( Addr ); +/* Functions defined in mc_translate.c */ +extern IRBB* MC_(instrument) ( IRBB* bb_in, VexGuestLayout* layout, + IRType gWordTy, IRType hWordTy ); + #endif /*--------------------------------------------------------------------*/ diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c index 37ca0b538c..547c5a94a7 100644 --- a/memcheck/mc_main.c +++ b/memcheck/mc_main.c @@ -1209,7 +1209,7 @@ static void mc_pre_reg_read ( CorePart part, ThreadId tid, Char* s, /*--- Printing errors ---*/ /*------------------------------------------------------------*/ -void TL_(pp_Error) ( Error* err ) +static void mc_pp_Error ( Error* err ) { MAC_Error* err_extra = VG_(get_error_extra)(err); @@ -1299,7 +1299,7 @@ static void mc_record_user_error ( ThreadId tid, Addr a, Bool isWrite, /*--- Suppressions ---*/ /*------------------------------------------------------------*/ -Bool TL_(recognised_suppression) ( Char* name, Supp* su ) +static Bool mc_recognised_suppression ( Char* name, Supp* su ) { SuppKind skind; @@ -1923,7 +1923,7 @@ static void init_shadow_memory ( void ) /*--- Sanity check machinery (permanently engaged) ---*/ /*------------------------------------------------------------*/ -Bool TL_(cheap_sanity_check) ( void ) +static Bool mc_cheap_sanity_check ( void ) { /* nothing useful we can rapidly check */ n_sanity_cheap++; @@ -1931,7 +1931,7 @@ Bool TL_(cheap_sanity_check) ( void ) return True; } -Bool TL_(expensive_sanity_check) ( void ) +static Bool mc_expensive_sanity_check ( void ) { Int i, n_secmaps_found; SecMap* sm; @@ -2039,9 +2039,9 @@ Bool TL_(expensive_sanity_check) ( void ) /*--- Command line args ---*/ /*------------------------------------------------------------*/ -Bool MC_(clo_avoid_strlen_errors) = True; +Bool MC_(clo_avoid_strlen_errors) = True; -Bool TL_(process_cmd_line_option)(Char* arg) +static Bool mc_process_cmd_line_option(Char* arg) { VG_BOOL_CLO(arg, "--avoid-strlen-errors", MC_(clo_avoid_strlen_errors)) else @@ -2050,7 +2050,7 @@ Bool TL_(process_cmd_line_option)(Char* arg) return True; } -void TL_(print_usage)(void) +static void mc_print_usage(void) { MAC_(print_common_usage)(); VG_(printf)( @@ -2058,7 +2058,7 @@ void TL_(print_usage)(void) ); } -void TL_(print_debug_usage)(void) +static void mc_print_debug_usage(void) { MAC_(print_common_debug_usage)(); VG_(printf)( @@ -2205,7 +2205,7 @@ static Bool client_perm_maybe_describe( Addr a, AddrInfo* ai ) return False; } -Bool TL_(handle_client_request) ( ThreadId tid, UWord* arg, UWord* ret ) +static Bool mc_handle_client_request ( ThreadId tid, UWord* arg, UWord* ret ) { Int i; Bool ok; @@ -2320,113 +2320,14 @@ Bool TL_(handle_client_request) ( ThreadId tid, UWord* arg, UWord* ret ) } /*------------------------------------------------------------*/ -/*--- Setup ---*/ +/*--- Setup and finalisation ---*/ /*------------------------------------------------------------*/ -void TL_(pre_clo_init)(void) -{ - VG_(details_name) ("Memcheck"); - VG_(details_version) (NULL); - VG_(details_description) ("a memory error detector"); - VG_(details_copyright_author)( - "Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al."); - VG_(details_bug_reports_to) (VG_BUGS_TO); - VG_(details_avg_translation_sizeB) ( 370 ); - - VG_(basic_tool_funcs) (TL_(post_clo_init), - TL_(instrument), - TL_(fini)); - - VG_(needs_core_errors) (); - VG_(needs_tool_errors) (TL_(eq_Error), - TL_(pp_Error), - TL_(update_extra), - TL_(recognised_suppression), - TL_(read_extra_suppression_info), - TL_(error_matches_suppression), - TL_(get_error_name), - TL_(print_extra_suppression_info)); - VG_(needs_libc_freeres) (); - VG_(needs_command_line_options)(TL_(process_cmd_line_option), - TL_(print_usage), - TL_(print_debug_usage)); - VG_(needs_client_requests) (TL_(handle_client_request)); - VG_(needs_sanity_checks) (TL_(cheap_sanity_check), - TL_(expensive_sanity_check)); - VG_(needs_shadow_memory) (); - - VG_(malloc_funcs) (TL_(malloc), - TL_(__builtin_new), - TL_(__builtin_vec_new), - TL_(memalign), - TL_(calloc), - TL_(free), - TL_(__builtin_delete), - TL_(__builtin_vec_delete), - TL_(realloc), - MALLOC_REDZONE_SZB ); - - MAC_( new_mem_heap) = & mc_new_mem_heap; - MAC_( ban_mem_heap) = & mc_make_noaccess; - MAC_(copy_mem_heap) = & mc_copy_address_range_state; - MAC_( die_mem_heap) = & mc_make_noaccess; - MAC_(check_noaccess) = & mc_check_noaccess; - - VG_(init_new_mem_startup) ( & mc_new_mem_startup ); - VG_(init_new_mem_stack_signal) ( & mc_make_writable ); - VG_(init_new_mem_brk) ( & mc_make_writable ); - VG_(init_new_mem_mmap) ( & mc_new_mem_mmap ); - - VG_(init_copy_mem_remap) ( & mc_copy_address_range_state ); - - VG_(init_die_mem_stack_signal) ( & mc_make_noaccess ); - VG_(init_die_mem_brk) ( & mc_make_noaccess ); - VG_(init_die_mem_munmap) ( & mc_make_noaccess ); - - VG_(init_new_mem_stack_4) ( & MAC_(new_mem_stack_4) ); - VG_(init_new_mem_stack_8) ( & MAC_(new_mem_stack_8) ); - VG_(init_new_mem_stack_12) ( & MAC_(new_mem_stack_12) ); - VG_(init_new_mem_stack_16) ( & MAC_(new_mem_stack_16) ); - VG_(init_new_mem_stack_32) ( & MAC_(new_mem_stack_32) ); - VG_(init_new_mem_stack) ( & MAC_(new_mem_stack) ); - - VG_(init_die_mem_stack_4) ( & MAC_(die_mem_stack_4) ); - VG_(init_die_mem_stack_8) ( & MAC_(die_mem_stack_8) ); - VG_(init_die_mem_stack_12) ( & MAC_(die_mem_stack_12) ); - VG_(init_die_mem_stack_16) ( & MAC_(die_mem_stack_16) ); - VG_(init_die_mem_stack_32) ( & MAC_(die_mem_stack_32) ); - VG_(init_die_mem_stack) ( & MAC_(die_mem_stack) ); - - VG_(init_ban_mem_stack) ( & mc_make_noaccess ); - - VG_(init_pre_mem_read) ( & mc_check_is_readable ); - VG_(init_pre_mem_read_asciiz) ( & mc_check_is_readable_asciiz ); - VG_(init_pre_mem_write) ( & mc_check_is_writable ); - VG_(init_post_mem_write) ( & mc_post_mem_write ); - - VG_(init_pre_reg_read) ( & mc_pre_reg_read ); - - VG_(init_post_reg_write) ( & mc_post_reg_write ); - VG_(init_post_reg_write_clientcall_return) ( & mc_post_reg_write_clientcall ); - - VG_(register_profile_event) ( VgpSetMem, "set-mem-perms" ); - VG_(register_profile_event) ( VgpCheckMem, "check-mem-perms" ); - VG_(register_profile_event) ( VgpESPAdj, "adjust-ESP" ); - - /* Additional block description for VG_(describe_addr)() */ - MAC_(describe_addr_supp) = client_perm_maybe_describe; - - init_shadow_memory(); - MAC_(common_pre_clo_init)(); - - tl_assert( TL_(expensive_sanity_check)() ); -} - -void TL_(post_clo_init) ( void ) +static void mc_post_clo_init ( void ) { } -void TL_(fini) ( Int exitcode ) +static void mc_fini ( Int exitcode ) { MAC_(common_fini)( mc_detect_memory_leaks ); @@ -2480,7 +2381,106 @@ void TL_(fini) ( Int exitcode ) } } -VG_DETERMINE_INTERFACE_VERSION(TL_(pre_clo_init), 9./8) +static void mc_pre_clo_init(void) +{ + VG_(details_name) ("Memcheck"); + VG_(details_version) (NULL); + VG_(details_description) ("a memory error detector"); + VG_(details_copyright_author)( + "Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al."); + VG_(details_bug_reports_to) (VG_BUGS_TO); + VG_(details_avg_translation_sizeB) ( 370 ); + + VG_(basic_tool_funcs) (mc_post_clo_init, + MC_(instrument), + mc_fini); + + VG_(needs_core_errors) (); + VG_(needs_tool_errors) (MAC_(eq_Error), + mc_pp_Error, + MAC_(update_extra), + mc_recognised_suppression, + MAC_(read_extra_suppression_info), + MAC_(error_matches_suppression), + MAC_(get_error_name), + MAC_(print_extra_suppression_info)); + VG_(needs_libc_freeres) (); + VG_(needs_command_line_options)(mc_process_cmd_line_option, + mc_print_usage, + mc_print_debug_usage); + VG_(needs_client_requests) (mc_handle_client_request); + VG_(needs_sanity_checks) (mc_cheap_sanity_check, + mc_expensive_sanity_check); + VG_(needs_shadow_memory) (); + + VG_(malloc_funcs) (MAC_(malloc), + MAC_(__builtin_new), + MAC_(__builtin_vec_new), + MAC_(memalign), + MAC_(calloc), + MAC_(free), + MAC_(__builtin_delete), + MAC_(__builtin_vec_delete), + MAC_(realloc), + MAC_MALLOC_REDZONE_SZB ); + + MAC_( new_mem_heap) = & mc_new_mem_heap; + MAC_( ban_mem_heap) = & mc_make_noaccess; + MAC_(copy_mem_heap) = & mc_copy_address_range_state; + MAC_( die_mem_heap) = & mc_make_noaccess; + MAC_(check_noaccess) = & mc_check_noaccess; + + VG_(track_new_mem_startup) ( & mc_new_mem_startup ); + VG_(track_new_mem_stack_signal)( & mc_make_writable ); + VG_(track_new_mem_brk) ( & mc_make_writable ); + VG_(track_new_mem_mmap) ( & mc_new_mem_mmap ); + + VG_(track_copy_mem_remap) ( & mc_copy_address_range_state ); + + VG_(track_die_mem_stack_signal)( & mc_make_noaccess ); + VG_(track_die_mem_brk) ( & mc_make_noaccess ); + VG_(track_die_mem_munmap) ( & mc_make_noaccess ); + + VG_(track_new_mem_stack_4) ( & MAC_(new_mem_stack_4) ); + VG_(track_new_mem_stack_8) ( & MAC_(new_mem_stack_8) ); + VG_(track_new_mem_stack_12) ( & MAC_(new_mem_stack_12) ); + VG_(track_new_mem_stack_16) ( & MAC_(new_mem_stack_16) ); + VG_(track_new_mem_stack_32) ( & MAC_(new_mem_stack_32) ); + VG_(track_new_mem_stack) ( & MAC_(new_mem_stack) ); + + VG_(track_die_mem_stack_4) ( & MAC_(die_mem_stack_4) ); + VG_(track_die_mem_stack_8) ( & MAC_(die_mem_stack_8) ); + VG_(track_die_mem_stack_12) ( & MAC_(die_mem_stack_12) ); + VG_(track_die_mem_stack_16) ( & MAC_(die_mem_stack_16) ); + VG_(track_die_mem_stack_32) ( & MAC_(die_mem_stack_32) ); + VG_(track_die_mem_stack) ( & MAC_(die_mem_stack) ); + + VG_(track_ban_mem_stack) ( & mc_make_noaccess ); + + VG_(track_pre_mem_read) ( & mc_check_is_readable ); + VG_(track_pre_mem_read_asciiz) ( & mc_check_is_readable_asciiz ); + VG_(track_pre_mem_write) ( & mc_check_is_writable ); + VG_(track_post_mem_write) ( & mc_post_mem_write ); + + VG_(track_pre_reg_read) ( & mc_pre_reg_read ); + + VG_(track_post_reg_write) ( & mc_post_reg_write ); + VG_(track_post_reg_write_clientcall_return)( & mc_post_reg_write_clientcall ); + + VG_(register_profile_event) ( VgpSetMem, "set-mem-perms" ); + VG_(register_profile_event) ( VgpCheckMem, "check-mem-perms" ); + VG_(register_profile_event) ( VgpESPAdj, "adjust-ESP" ); + + /* Additional block description for VG_(describe_addr)() */ + MAC_(describe_addr_supp) = client_perm_maybe_describe; + + init_shadow_memory(); + MAC_(common_pre_clo_init)(); + + tl_assert( mc_expensive_sanity_check() ); +} + +VG_DETERMINE_INTERFACE_VERSION(mc_pre_clo_init, 9./8) /*--------------------------------------------------------------------*/ /*--- end mc_main.c ---*/ diff --git a/memcheck/mc_translate.c b/memcheck/mc_translate.c index e8508cff45..1e2a7a92c1 100644 --- a/memcheck/mc_translate.c +++ b/memcheck/mc_translate.c @@ -2505,7 +2505,7 @@ static Bool checkForBogusLiterals ( /*FLAT*/ IRStmt* st ) } -IRBB* TL_(instrument) ( IRBB* bb_in, VexGuestLayout* layout, +IRBB* MC_(instrument) ( IRBB* bb_in, VexGuestLayout* layout, IRType gWordTy, IRType hWordTy ) { Bool verboze = False; //True; diff --git a/none/nl_main.c b/none/nl_main.c index ca716e0a34..63d2fe0219 100644 --- a/none/nl_main.c +++ b/none/nl_main.c @@ -30,37 +30,37 @@ #include "tool.h" -void TL_(pre_clo_init)(void) +static void nl_post_clo_init(void) { - VG_(details_name) ("Nulgrind"); - VG_(details_version) (NULL); - VG_(details_description) ("a binary JIT-compiler"); - VG_(details_copyright_author)( - "Copyright (C) 2002-2005, and GNU GPL'd, by Nicholas Nethercote."); - VG_(details_bug_reports_to) (VG_BUGS_TO); - - VG_(basic_tool_funcs) (TL_(post_clo_init), - TL_(instrument), - TL_(fini)); - - /* No needs, no core events to track */ } -void TL_(post_clo_init)(void) +static IRBB* nl_instrument(IRBB* bb, VexGuestLayout* layout, + IRType gWordTy, IRType hWordTy) { + return bb; } -IRBB* TL_(instrument)(IRBB* bb, VexGuestLayout* layout, - IRType gWordTy, IRType hWordTy) +static void nl_fini(Int exitcode) { - return bb; } -void TL_(fini)(Int exitcode) +static void nl_pre_clo_init(void) { + VG_(details_name) ("Nulgrind"); + VG_(details_version) (NULL); + VG_(details_description) ("a binary JIT-compiler"); + VG_(details_copyright_author)( + "Copyright (C) 2002-2005, and GNU GPL'd, by Nicholas Nethercote."); + VG_(details_bug_reports_to) (VG_BUGS_TO); + + VG_(basic_tool_funcs) (nl_post_clo_init, + nl_instrument, + nl_fini); + + /* No needs, no core events to track */ } -VG_DETERMINE_INTERFACE_VERSION(TL_(pre_clo_init), 0) +VG_DETERMINE_INTERFACE_VERSION(nl_pre_clo_init, 0) /*--------------------------------------------------------------------*/ /*--- end ---*/