summaryrefslogtreecommitdiff
path: root/coregrind/m_tooliface.c
diff options
context:
space:
mode:
authorStephane Marchesin <marchesin@icps.u-strasbg.fr>2009-05-04 19:05:59 +0200
committerStephane Marchesin <marchesin@icps.u-strasbg.fr>2009-05-04 19:05:59 +0200
commit6e410b3bb6ff51580897431105aae14591cbf7fb (patch)
treef8aeba9352710f10cd6b1d5138c8fc3ece91c8c3 /coregrind/m_tooliface.c
Initial import of fatgrind.HEADmaster
Diffstat (limited to 'coregrind/m_tooliface.c')
-rw-r--r--coregrind/m_tooliface.c413
1 files changed, 413 insertions, 0 deletions
diff --git a/coregrind/m_tooliface.c b/coregrind/m_tooliface.c
new file mode 100644
index 0000000..79a5e4b
--- /dev/null
+++ b/coregrind/m_tooliface.c
@@ -0,0 +1,413 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Stuff relating to tool data structures. ---*/
+/*--- m_tooliface.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2009 Nicholas Nethercote
+ njn@valgrind.org
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "pub_core_basics.h"
+#include "pub_core_tooliface.h"
+
+// The core/tool dictionary of functions (initially zeroed, as we want it)
+VgToolInterface VG_(tdict);
+
+/*--------------------------------------------------------------------*/
+/* Setting basic functions */
+
+void VG_(basic_tool_funcs)(
+ void(*post_clo_init)(void),
+ IRSB*(*instrument)(VgCallbackClosure*, IRSB*,
+ VexGuestLayout*, VexGuestExtents*, IRType, IRType),
+ void(*fini)(Int)
+)
+{
+ VG_(tdict).tool_post_clo_init = post_clo_init;
+ VG_(tdict).tool_instrument = instrument;
+ VG_(tdict).tool_fini = fini;
+}
+
+
+/*--------------------------------------------------------------------*/
+/* Setting details */
+
+/* Init with default values. */
+VgDetails VG_(details) = {
+ .name = NULL,
+ .version = NULL,
+ .description = NULL,
+ .copyright_author = NULL,
+ .bug_reports_to = NULL,
+ .avg_translation_sizeB = VG_DEFAULT_TRANS_SIZEB,
+};
+
+/* Use macro because they're so repetitive */
+#define DETAILS(type, detail) \
+ extern void VG_(details_##detail)(type detail) \
+ { \
+ VG_(details).detail = detail; \
+ }
+
+DETAILS(Char*, name)
+DETAILS(Char*, version)
+DETAILS(Char*, description)
+DETAILS(Char*, copyright_author)
+DETAILS(Char*, bug_reports_to)
+DETAILS(UInt, avg_translation_sizeB)
+
+
+/*--------------------------------------------------------------------*/
+/* Setting needs */
+
+VgNeeds VG_(needs) = {
+ .core_errors = False,
+ .tool_errors = False,
+ .libc_freeres = False,
+ .superblock_discards = False,
+ .command_line_options = False,
+ .client_requests = False,
+ .syscall_wrapper = False,
+ .sanity_checks = False,
+ .var_info = False,
+ .malloc_replacement = False,
+ .xml_output = False,
+ .final_IR_tidy_pass = False
+};
+
+/* static */
+Bool VG_(sanity_check_needs)(Char** failmsg)
+{
+ Bool any_new_mem_stack_N, any_new_mem_stack_N_w_ECU;
+ Bool any_new_mem_stack_w_conflicting_otags;
+ Bool any_die_mem_stack_N;
+
+#define CHECK_NOT(var, value) \
+ if ((var)==(value)) { \
+ *failmsg = "Tool error: '" #var "' not initialised\n"; \
+ return False; \
+ }
+
+ /* Ones that must be set */
+ CHECK_NOT(VG_(details).name, NULL);
+ /* Nb: .version can be NULL */
+ CHECK_NOT(VG_(details).description, NULL);
+ CHECK_NOT(VG_(details).copyright_author, NULL);
+ CHECK_NOT(VG_(details).bug_reports_to, NULL);
+
+ /* Check that new_mem_stack is defined if any new_mem_stack_N
+ are. */
+ any_new_mem_stack_N
+ = 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_112 ||
+ VG_(tdict).track_new_mem_stack_128 ||
+ VG_(tdict).track_new_mem_stack_144 ||
+ VG_(tdict).track_new_mem_stack_160;
+
+ if (any_new_mem_stack_N && ! VG_(tdict).track_new_mem_stack) {
+ *failmsg = "Tool error: one of the specialised 'new_mem_stack_N'\n"
+ " events tracked, but not the generic 'new_mem_stack' one.\n"
+ " 'new_mem_stack' should be defined\n";
+ return False;
+ }
+
+ /* Check that new_mem_stack_w_ECU is defined if any
+ new_mem_stack_N_w_ECU are. */
+ any_new_mem_stack_N_w_ECU
+ = VG_(tdict).track_new_mem_stack_4_w_ECU ||
+ VG_(tdict).track_new_mem_stack_8_w_ECU ||
+ VG_(tdict).track_new_mem_stack_12_w_ECU ||
+ VG_(tdict).track_new_mem_stack_16_w_ECU ||
+ VG_(tdict).track_new_mem_stack_32_w_ECU ||
+ VG_(tdict).track_new_mem_stack_112_w_ECU ||
+ VG_(tdict).track_new_mem_stack_128_w_ECU ||
+ VG_(tdict).track_new_mem_stack_144_w_ECU ||
+ VG_(tdict).track_new_mem_stack_160_w_ECU;
+
+ if (any_new_mem_stack_N_w_ECU && ! VG_(tdict).track_new_mem_stack_w_ECU) {
+ *failmsg = "Tool error: one of the specialised 'new_mem_stack_N_w_ECU'\n"
+ " events tracked, but not the generic 'new_mem_stack_w_ECU' one.\n"
+ " 'new_mem_stack_w_ECU' should be defined\n";
+ return False;
+ }
+
+ /* Check that in no cases are both with- and without-otag versions of the
+ same new_mem_stack_ function defined. */
+ any_new_mem_stack_w_conflicting_otags
+ = (VG_(tdict).track_new_mem_stack_4 && VG_(tdict).track_new_mem_stack_4_w_ECU) ||
+ (VG_(tdict).track_new_mem_stack_8 && VG_(tdict).track_new_mem_stack_8_w_ECU) ||
+ (VG_(tdict).track_new_mem_stack_12 && VG_(tdict).track_new_mem_stack_12_w_ECU) ||
+ (VG_(tdict).track_new_mem_stack_16 && VG_(tdict).track_new_mem_stack_16_w_ECU) ||
+ (VG_(tdict).track_new_mem_stack_32 && VG_(tdict).track_new_mem_stack_32_w_ECU) ||
+ (VG_(tdict).track_new_mem_stack_112 && VG_(tdict).track_new_mem_stack_112_w_ECU) ||
+ (VG_(tdict).track_new_mem_stack_128 && VG_(tdict).track_new_mem_stack_128_w_ECU) ||
+ (VG_(tdict).track_new_mem_stack_144 && VG_(tdict).track_new_mem_stack_144_w_ECU) ||
+ (VG_(tdict).track_new_mem_stack_160 && VG_(tdict).track_new_mem_stack_160_w_ECU) ||
+ (VG_(tdict).track_new_mem_stack && VG_(tdict).track_new_mem_stack_w_ECU);
+
+ if (any_new_mem_stack_w_conflicting_otags) {
+ *failmsg = "Tool error: tool supplies both a 'new_mem_stack_N' and a\n"
+ " 'new_mem_stack_N_w_ECU' function for some N (or none),\n"
+ " but you can only have one or the other (not both)\n";
+ return False;
+ }
+
+ /* Check that die_mem_stack is defined if any die_mem_stack_N
+ are. */
+ any_die_mem_stack_N
+ = 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_112 ||
+ VG_(tdict).track_die_mem_stack_128 ||
+ VG_(tdict).track_die_mem_stack_144 ||
+ VG_(tdict).track_die_mem_stack_160;
+
+ if (any_die_mem_stack_N && ! VG_(tdict).track_die_mem_stack) {
+ *failmsg = "Tool error: one of the specialised 'die_mem_stack_N'\n"
+ " events tracked, but not the generic 'die_mem_stack' one.\n"
+ " 'die_mem_stack' should be defined\n";
+ return False;
+ }
+
+ return True;
+
+#undef CHECK_NOT
+}
+
+/* Use macro because they're so repetitive */
+#define NEEDS(need) \
+ extern void VG_(needs_##need)(void) \
+ { \
+ VG_(needs).need = True; \
+ }
+
+// These ones don't require any tool-supplied functions
+NEEDS(libc_freeres)
+NEEDS(core_errors)
+NEEDS(var_info)
+NEEDS(xml_output)
+
+void VG_(needs_superblock_discards)(
+ void (*discard)(Addr64, VexGuestExtents)
+)
+{
+ VG_(needs).superblock_discards = True;
+ VG_(tdict).tool_discard_superblock_info = discard;
+}
+
+void VG_(needs_tool_errors)(
+ Bool (*eq) (VgRes, Error*, Error*),
+ void (*pp) (Error*),
+ Bool show_TIDs,
+ UInt (*update) (Error*),
+ Bool (*recog) (Char*, Supp*),
+ Bool (*read_extra) (Int, Char*, Int, Supp*),
+ Bool (*matches) (Error*, Supp*),
+ Char* (*name) (Error*),
+ void (*print_extra)(Error*)
+)
+{
+ VG_(needs).tool_errors = True;
+ VG_(tdict).tool_eq_Error = eq;
+ VG_(tdict).tool_pp_Error = pp;
+ VG_(tdict).tool_show_ThreadIDs_for_errors = show_TIDs;
+ VG_(tdict).tool_update_extra = update;
+ VG_(tdict).tool_recognised_suppression = recog;
+ VG_(tdict).tool_read_extra_suppression_info = read_extra;
+ VG_(tdict).tool_error_matches_suppression = matches;
+ VG_(tdict).tool_get_error_name = name;
+ VG_(tdict).tool_print_extra_suppression_info = print_extra;
+}
+
+void VG_(needs_command_line_options)(
+ Bool (*process)(Char*),
+ void (*usage)(void),
+ void (*debug_usage)(void)
+)
+{
+ VG_(needs).command_line_options = True;
+ VG_(tdict).tool_process_cmd_line_option = process;
+ VG_(tdict).tool_print_usage = usage;
+ VG_(tdict).tool_print_debug_usage = debug_usage;
+}
+
+void VG_(needs_client_requests)(
+ Bool (*handle)(ThreadId, UWord*, UWord*)
+)
+{
+ VG_(needs).client_requests = True;
+ VG_(tdict).tool_handle_client_request = handle;
+}
+
+void VG_(needs_syscall_wrapper)(
+ void(*pre) (ThreadId, UInt),
+ void(*post)(ThreadId, UInt, SysRes res)
+)
+{
+ VG_(needs).syscall_wrapper = True;
+ VG_(tdict).tool_pre_syscall = pre;
+ VG_(tdict).tool_post_syscall = post;
+}
+
+void VG_(needs_sanity_checks)(
+ Bool(*cheap)(void),
+ Bool(*expen)(void)
+)
+{
+ VG_(needs).sanity_checks = True;
+ VG_(tdict).tool_cheap_sanity_check = cheap;
+ VG_(tdict).tool_expensive_sanity_check = expen;
+}
+
+void VG_(needs_malloc_replacement)(
+ void* (*malloc) ( ThreadId, SizeT ),
+ void* (*__builtin_new) ( ThreadId, SizeT ),
+ void* (*__builtin_vec_new) ( ThreadId, SizeT ),
+ void* (*memalign) ( ThreadId, SizeT, SizeT ),
+ void* (*calloc) ( ThreadId, SizeT, SizeT ),
+ void (*free) ( ThreadId, void* ),
+ void (*__builtin_delete) ( ThreadId, void* ),
+ void (*__builtin_vec_delete) ( ThreadId, void* ),
+ void* (*realloc) ( ThreadId, void*, SizeT ),
+ SizeT (*malloc_usable_size) ( ThreadId, void* ),
+ SizeT client_malloc_redzone_szB
+)
+{
+ VG_(needs).malloc_replacement = True;
+ VG_(tdict).tool_malloc = malloc;
+ VG_(tdict).tool___builtin_new = __builtin_new;
+ VG_(tdict).tool___builtin_vec_new = __builtin_vec_new;
+ VG_(tdict).tool_memalign = memalign;
+ VG_(tdict).tool_calloc = calloc;
+ VG_(tdict).tool_free = free;
+ VG_(tdict).tool___builtin_delete = __builtin_delete;
+ VG_(tdict).tool___builtin_vec_delete = __builtin_vec_delete;
+ VG_(tdict).tool_realloc = realloc;
+ VG_(tdict).tool_malloc_usable_size = malloc_usable_size;
+ VG_(tdict).tool_client_redzone_szB = client_malloc_redzone_szB;
+}
+
+void VG_(needs_final_IR_tidy_pass)(
+ IRSB*(*final_tidy)(IRSB*)
+)
+{
+ VG_(needs).final_IR_tidy_pass = True;
+ VG_(tdict).tool_final_IR_tidy_pass = final_tidy;
+}
+
+/*--------------------------------------------------------------------*/
+/* Tracked events. Digit 'n' on DEFn is the REGPARMness. */
+
+#define DEF0(fn, args...) \
+void VG_(fn)(void(*f)(args)) { \
+ VG_(tdict).fn = f; \
+}
+
+#define DEF1(fn, args...) \
+void VG_(fn)(VG_REGPARM(1) void(*f)(args)) { \
+ VG_(tdict).fn = f; \
+}
+
+#define DEF2(fn, args...) \
+void VG_(fn)(VG_REGPARM(2) void(*f)(args)) { \
+ VG_(tdict).fn = f; \
+}
+
+DEF0(track_new_mem_startup, Addr, SizeT, Bool, Bool, Bool, ULong)
+DEF0(track_new_mem_stack_signal, Addr, SizeT, UInt)
+DEF0(track_new_mem_brk, Addr, SizeT, UInt)
+DEF0(track_new_mem_mmap, Addr, SizeT, Bool, Bool, Bool, ULong)
+
+DEF0(track_copy_mem_remap, Addr, Addr, SizeT)
+DEF0(track_change_mem_mprotect, Addr, SizeT, Bool, Bool, Bool)
+DEF0(track_die_mem_stack_signal, Addr, SizeT)
+DEF0(track_die_mem_brk, Addr, SizeT)
+DEF0(track_die_mem_munmap, Addr, SizeT)
+
+DEF2(track_new_mem_stack_4_w_ECU, Addr, UInt)
+DEF2(track_new_mem_stack_8_w_ECU, Addr, UInt)
+DEF2(track_new_mem_stack_12_w_ECU, Addr, UInt)
+DEF2(track_new_mem_stack_16_w_ECU, Addr, UInt)
+DEF2(track_new_mem_stack_32_w_ECU, Addr, UInt)
+DEF2(track_new_mem_stack_112_w_ECU, Addr, UInt)
+DEF2(track_new_mem_stack_128_w_ECU, Addr, UInt)
+DEF2(track_new_mem_stack_144_w_ECU, Addr, UInt)
+DEF2(track_new_mem_stack_160_w_ECU, Addr, UInt)
+DEF0(track_new_mem_stack_w_ECU, Addr, SizeT, UInt)
+
+DEF1(track_new_mem_stack_4, Addr)
+DEF1(track_new_mem_stack_8, Addr)
+DEF1(track_new_mem_stack_12, Addr)
+DEF1(track_new_mem_stack_16, Addr)
+DEF1(track_new_mem_stack_32, Addr)
+DEF1(track_new_mem_stack_112, Addr)
+DEF1(track_new_mem_stack_128, Addr)
+DEF1(track_new_mem_stack_144, Addr)
+DEF1(track_new_mem_stack_160, Addr)
+DEF0(track_new_mem_stack, Addr, SizeT)
+
+DEF1(track_die_mem_stack_4, Addr)
+DEF1(track_die_mem_stack_8, Addr)
+DEF1(track_die_mem_stack_12, Addr)
+DEF1(track_die_mem_stack_16, Addr)
+DEF1(track_die_mem_stack_32, Addr)
+DEF1(track_die_mem_stack_112, Addr)
+DEF1(track_die_mem_stack_128, Addr)
+DEF1(track_die_mem_stack_144, Addr)
+DEF1(track_die_mem_stack_160, Addr)
+DEF0(track_die_mem_stack, Addr, SizeT)
+
+DEF0(track_ban_mem_stack, Addr, SizeT)
+
+DEF0(track_pre_mem_read, CorePart, ThreadId, Char*, Addr, SizeT)
+DEF0(track_pre_mem_read_asciiz, CorePart, ThreadId, Char*, Addr)
+DEF0(track_pre_mem_write, CorePart, ThreadId, Char*, Addr, SizeT)
+DEF0(track_post_mem_write, CorePart, ThreadId, Addr, SizeT)
+
+DEF0(track_pre_reg_read, CorePart, ThreadId, Char*, PtrdiffT, SizeT)
+DEF0(track_post_reg_write, CorePart, ThreadId, PtrdiffT, SizeT)
+
+DEF0(track_post_reg_write_clientcall_return, ThreadId, PtrdiffT, SizeT, Addr)
+
+DEF0(track_start_client_code, ThreadId, ULong)
+DEF0(track_stop_client_code, ThreadId, ULong)
+
+DEF0(track_pre_thread_ll_create, ThreadId, ThreadId)
+DEF0(track_pre_thread_first_insn, ThreadId)
+DEF0(track_pre_thread_ll_exit, ThreadId)
+
+DEF0(track_pre_deliver_signal, ThreadId, Int sigNo, Bool)
+DEF0(track_post_deliver_signal, ThreadId, Int sigNo)
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/