diff options
author | Marcin Slusarz <marcin.slusarz@gmail.com> | 2011-09-07 20:17:19 +0200 |
---|---|---|
committer | Marcin Slusarz <marcin.slusarz@gmail.com> | 2011-09-17 22:57:44 +0200 |
commit | 6f05aba48d3ab8742d9fd23a04bfdb82b8452051 (patch) | |
tree | fb57b63ca638bdf9eadc69ebe72fed706b9f7d69 | |
parent | 8384a95dd0666bbe4a66a34b7081f0543a850689 (diff) |
mmt: move tracing functions to separate file
-rw-r--r-- | mmt/Makefile.am | 2 | ||||
-rw-r--r-- | mmt/mmt_instrument.c | 14 | ||||
-rw-r--r-- | mmt/mmt_main.c | 466 | ||||
-rw-r--r-- | mmt/mmt_main.h | 51 | ||||
-rw-r--r-- | mmt/mmt_nv_ioctl.c | 12 | ||||
-rw-r--r-- | mmt/mmt_trace.c | 442 | ||||
-rw-r--r-- | mmt/mmt_trace.h | 68 |
7 files changed, 535 insertions, 520 deletions
diff --git a/mmt/Makefile.am b/mmt/Makefile.am index 01387682..279a1f67 100644 --- a/mmt/Makefile.am +++ b/mmt/Makefile.am @@ -5,7 +5,7 @@ if VGCONF_HAVE_PLATFORM_SEC noinst_PROGRAMS += mmt-@VGCONF_ARCH_SEC@-@VGCONF_OS@ endif -MMT_SOURCES_COMMON = mmt_main.c mmt_nv_ioctl.c mmt_instrument.c +MMT_SOURCES_COMMON = mmt_main.c mmt_nv_ioctl.c mmt_instrument.c mmt_trace.c mmt_@VGCONF_ARCH_PRI@_@VGCONF_OS@_SOURCES = \ $(MMT_SOURCES_COMMON) diff --git a/mmt/mmt_instrument.c b/mmt/mmt_instrument.c index 5d9d1cac..1c4a0bcd 100644 --- a/mmt/mmt_instrument.c +++ b/mmt/mmt_instrument.c @@ -22,7 +22,7 @@ */ #include "mmt_instrument.h" -#include "mmt_main.h" +#include "mmt_trace.h" #include "pub_tool_machine.h" #include "pub_tool_libcprint.h" @@ -36,7 +36,7 @@ static void add_trace_load1(IRSB *bb, IRExpr *addr, Int size, Addr inst_addr, IR mkIRExpr_HWord(inst_addr), val1); IRDirty *di = unsafeIRDirty_0_N(2, "trace_load", - VG_(fnptr_to_fnentry) (trace_load), + VG_(fnptr_to_fnentry) (mmt_trace_load), argv); addStmtToIRSB(bb, IRStmt_Dirty(di)); } @@ -47,7 +47,7 @@ static void add_trace_load2(IRSB *bb, IRExpr *addr, Int size, Addr inst_addr, IR mkIRExpr_HWord(inst_addr), val1, val2); IRDirty *di = unsafeIRDirty_0_N(2, "trace_load2", - VG_(fnptr_to_fnentry) (trace_load2), + VG_(fnptr_to_fnentry) (mmt_trace_load2), argv); addStmtToIRSB(bb, IRStmt_Dirty(di)); } @@ -59,7 +59,7 @@ static void add_trace_load4(IRSB *bb, IRExpr *addr, Int size, Addr inst_addr, IR mkIRExpr_HWord(inst_addr), val1, val2, val3, val4); IRDirty *di = unsafeIRDirty_0_N(2, "trace_load4", - VG_(fnptr_to_fnentry) (trace_load4), + VG_(fnptr_to_fnentry) (mmt_trace_load4), argv); addStmtToIRSB(bb, IRStmt_Dirty(di)); } @@ -268,7 +268,7 @@ add_trace_store1(IRSB *bb, IRExpr *addr, Int size, Addr inst_addr, mkIRExpr_HWord(inst_addr), data); IRDirty *di = unsafeIRDirty_0_N(2, "trace_store", - VG_(fnptr_to_fnentry) (trace_store), + VG_(fnptr_to_fnentry) (mmt_trace_store), argv); addStmtToIRSB(bb, IRStmt_Dirty(di)); } @@ -282,7 +282,7 @@ add_trace_store2(IRSB *bb, IRExpr *addr, Int size, Addr inst_addr, data1, data2); IRDirty *di = unsafeIRDirty_0_N(2, "trace_store2", - VG_(fnptr_to_fnentry) (trace_store2), + VG_(fnptr_to_fnentry) (mmt_trace_store2), argv); addStmtToIRSB(bb, IRStmt_Dirty(di)); } @@ -296,7 +296,7 @@ add_trace_store4(IRSB *bb, IRExpr *addr, Addr inst_addr, data1, data2, data3, data4); IRDirty *di = unsafeIRDirty_0_N(2, "trace_store4", - VG_(fnptr_to_fnentry) (trace_store4), + VG_(fnptr_to_fnentry) (mmt_trace_store4), argv); addStmtToIRSB(bb, IRStmt_Dirty(di)); } diff --git a/mmt/mmt_main.c b/mmt/mmt_main.c index 45d06ace..36c70bb4 100644 --- a/mmt/mmt_main.c +++ b/mmt/mmt_main.c @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------*/ -/*--- nvtrace: mmaptracer tool that tracks NVidia ioctls ---*/ -/*--------------------------------------------------------------------*/ - /* Copyright (C) 2006 Dave Airlie Copyright (C) 2007 Wladimir J. van der Laan @@ -32,261 +28,13 @@ */ #include "pub_tool_basics.h" -#include "pub_tool_libcprint.h" -#include "pub_tool_libcassert.h" - -#include "pub_tool_tooliface.h" -#include "pub_tool_debuginfo.h" #include "pub_tool_libcbase.h" -#include "pub_tool_options.h" -#include "pub_tool_machine.h" -#include "pub_tool_threadstate.h" -#include "pub_tool_vki.h" - -#include "pub_tool_vkiscnums.h" -#include "pub_tool_libcfile.h" +#include "pub_tool_libcprint.h" #include "pub_tool_mallocfree.h" -#include "coregrind/pub_core_basics.h" -#include "coregrind/pub_core_libcassert.h" -#include "coregrind/m_syswrap/priv_types_n_macros.h" - -#include <fcntl.h> -#include <string.h> - #include "mmt_nv_ioctl.h" #include "mmt_instrument.h" -#include "mmt_main.h" - -#define MAX_TRACE_FILES 10 - -struct mmt_mmap_data mmt_mmaps[MMT_MAX_REGIONS]; -int mmt_last_region = -1; - -UInt current_item = 1; - -/* Command line options */ -//UInt mmt_clo_offset = (UInt) -1; -static int trace_opens = False; - -static struct trace_file { - const char *path; - fd_set fds; -} trace_files[MAX_TRACE_FILES]; -static int trace_all_files = False; - -static struct mmt_mmap_data *find_mmap(Addr addr) -{ - struct mmt_mmap_data *region = NULL; - int i; - - for (i = 0; i <= mmt_last_region; i++) - { - region = &mmt_mmaps[i]; - if (addr >= region->start && addr < region->end) - return region; - } - - return NULL; -} - -static void mydescribe(Addr inst_addr, char *namestr, int len) -{ -#if 0 - const SegInfo *si; - /* Search for it in segments */ - VG_(snprintf) (namestr, len, "@%08x", inst_addr); - for (si = VG_(next_seginfo) (NULL); - si != NULL; si = VG_(next_seginfo) (si)) - { - Addr base = VG_(seginfo_start) (si); - SizeT size = VG_(seginfo_size) (si); - - if (inst_addr >= base && inst_addr < base + size) - { - const UChar *filename = VG_(seginfo_filename) (si); - VG_(snprintf) (namestr, len, "@%08x (%s:%08x)", inst_addr, - filename, inst_addr - base); - - break; - } - } -#else - VG_(strcpy) (namestr, ""); -#endif - -} - -VG_REGPARM(2) -void trace_store(Addr addr, SizeT size, Addr inst_addr, UWord value) -{ - struct mmt_mmap_data *region; - char valstr[64]; - char namestr[256]; - - region = find_mmap(addr); - if (!region) - return; - - switch (size) - { - case 1: - VG_(sprintf) (valstr, "0x%02lx", value); - break; - case 2: - VG_(sprintf) (valstr, "0x%04lx", value); - break; - case 4: - VG_(sprintf) (valstr, "0x%08lx", value); - break; -#ifdef MMT_64BIT - case 8: - VG_(sprintf) (valstr, "0x%08lx,0x%08lx", value >> 32, value & 0xffffffff); - break; -#endif - default: - return; - } - mydescribe(inst_addr, namestr, 256); - - VG_(message) (Vg_DebugMsg, "w %d:0x%04x, %s %s\n", region->id, (unsigned int)(addr - region->start), valstr, namestr); -} - -VG_REGPARM(2) -void trace_store2(Addr addr, SizeT size, Addr inst_addr, UWord value1, UWord value2) -{ - struct mmt_mmap_data *region; - char valstr[64]; - char namestr[256]; - - region = find_mmap(addr); - if (!region) - return; - - switch (size) - { - case 4: - VG_(sprintf) (valstr, "0x%08lx,0x%08lx", value1, value2); - break; -#ifdef MMT_64BIT - case 8: - VG_(sprintf) (valstr, "0x%08lx,0x%08lx,0x%08lx,0x%08lx", - value1 >> 32, value1 & 0xffffffff, - value2 >> 32, value2 & 0xffffffff); - break; -#endif - default: - return; - } - - mydescribe(inst_addr, namestr, 256); - - VG_(message) (Vg_DebugMsg, "w %d:0x%04x, %s %s\n", region->id, (unsigned int)(addr - region->start), valstr, namestr); -} - -#ifndef MMT_64BIT -VG_REGPARM(2) -void trace_store4(Addr addr, Addr inst_addr, UWord value1, UWord value2, UWord value3, UWord value4) -{ - struct mmt_mmap_data *region; - char valstr[64]; - char namestr[256]; - - region = find_mmap(addr); - if (!region) - return; - - VG_(sprintf) (valstr, "0x%08lx,0x%08lx,0x%08lx,0x%08lx", value1, value2, value3, value4); - mydescribe(inst_addr, namestr, 256); - - VG_(message) (Vg_DebugMsg, "w %d:0x%04x, %s %s\n", region->id, (unsigned int)(addr - region->start), valstr, namestr); -} -#endif - -VG_REGPARM(2) -void trace_load(Addr addr, SizeT size, UInt inst_addr, UWord value) -{ - struct mmt_mmap_data *region; - char valstr[64]; - char namestr[256]; - - region = find_mmap(addr); - if (!region) - return; - - switch (size) - { - case 1: - VG_(sprintf) (valstr, "0x%02lx", value); - break; - case 2: - VG_(sprintf) (valstr, "0x%04lx", value); - break; - case 4: - VG_(sprintf) (valstr, "0x%08lx", value); - break; -#ifdef MMT_64BIT - case 8: - VG_(sprintf) (valstr, "0x%08lx,0x%08lx", value >> 32, value & 0xffffffff); - break; -#endif - default: - return; - } - mydescribe(inst_addr, namestr, 256); - - VG_(message) (Vg_DebugMsg, "r %d:0x%04x, %s %s\n", region->id, (unsigned int)(addr - region->start), valstr, namestr); -} - -VG_REGPARM(2) -void trace_load2(Addr addr, SizeT size, UInt inst_addr, UWord value1, UWord value2) -{ - struct mmt_mmap_data *region; - char valstr[64]; - char namestr[256]; - - region = find_mmap(addr); - if (!region) - return; - - switch (size) - { - case 4: - VG_(sprintf) (valstr, "0x%08lx,0x%08lx", value1, value2); - break; -#ifdef MMT_64BIT - case 8: - VG_(sprintf) (valstr, "0x%08lx,0x%08lx,0x%08lx,0x%08lx", - value1 >> 32, value1 & 0xffffffff, - value2 >> 32, value2 & 0xffffffff); - break; -#endif - default: - return; - } - mydescribe(inst_addr, namestr, 256); - - VG_(message) (Vg_DebugMsg, "r %d:0x%04x, %s %s\n", region->id, (unsigned int)(addr - region->start), valstr, namestr); -} - -#ifndef MMT_64BIT -VG_REGPARM(2) -void trace_load4(Addr addr, SizeT size, UInt inst_addr, UWord value1, UWord value2, UWord value3, UWord value4) -{ - struct mmt_mmap_data *region; - char valstr[64]; - char namestr[256]; - - region = find_mmap(addr); - if (!region) - return; - - VG_(sprintf) (valstr, "0x%08lx,0x%08lx,0x%08lx,0x%08lx", value1, value2, value3, value4); - mydescribe(inst_addr, namestr, 256); - - VG_(message) (Vg_DebugMsg, "r %d:0x%04x, %s %s\n", region->id, (unsigned int)(addr - region->start), valstr, namestr); -} -#endif +#include "mmt_trace.h" #define TF_OPT "--mmt-trace-file=" #define TN_OPT "--mmt-trace-nvidia-ioctls" @@ -297,18 +45,18 @@ void trace_load4(Addr addr, SizeT size, UInt inst_addr, UWord value1, UWord valu static Bool mmt_process_cmd_line_option(Char * arg) { // VG_(printf)("arg: %s\n", arg); - if (VG_(strncmp)(arg, TF_OPT, strlen(TF_OPT)) == 0) + if (VG_(strncmp)(arg, TF_OPT, VG_(strlen(TF_OPT))) == 0) { int i; - for (i = 0; i < MAX_TRACE_FILES; ++i) - if (trace_files[i].path == NULL) + for (i = 0; i < MMT_MAX_TRACE_FILES; ++i) + if (mmt_trace_files[i].path == NULL) break; - if (i == MAX_TRACE_FILES) + if (i == MMT_MAX_TRACE_FILES) { VG_(printf)("too many files to trace\n"); return False; } - trace_files[i].path = VG_(strdup)("mmt.options-parsing", arg + strlen(TF_OPT)); + mmt_trace_files[i].path = VG_(strdup)("mmt.options-parsing", arg + VG_(strlen(TF_OPT))); return True; } else if (VG_(strcmp)(arg, TN_OPT) == 0) @@ -318,12 +66,12 @@ static Bool mmt_process_cmd_line_option(Char * arg) } else if (VG_(strcmp)(arg, TO_OPT) == 0) { - trace_opens = True; + mmt_trace_opens = True; return True; } else if (VG_(strcmp)(arg, TA_OPT) == 0) { - trace_all_files = True; + mmt_trace_all_files = True; return True; } else if (VG_(strcmp)(arg, TM_OPT) == 0) @@ -360,196 +108,6 @@ static void mmt_post_clo_init(void) mmt_nv_ioctl_post_clo_init(); } -static void pre_syscall(ThreadId tid, UInt syscallno, UWord *args, UInt nArgs) -{ - if (syscallno == __NR_ioctl) - mmt_nv_ioctl_pre(args); -} - -void mmt_free_region(int idx) -{ - if (mmt_last_region != idx) - VG_(memmove)(mmt_mmaps + idx, mmt_mmaps + idx + 1, - (mmt_last_region - idx) * sizeof(struct mmt_mmap_data)); - VG_(memset)(&mmt_mmaps[mmt_last_region--], 0, sizeof(struct mmt_mmap_data)); -} - -static void post_open(ThreadId tid, UWord *args, UInt nArgs, SysRes res) -{ - const char *path = (const char *)args[0]; - int i; - - if (trace_opens) - { - int flags = (int)args[1]; - int mode = (int)args[2]; - VG_(message)(Vg_DebugMsg, "sys_open: %s, flags: 0x%x, mode: 0x%x, ret: %ld\n", path, flags, mode, res._val); - } - if (res._isError) - return; - - if (!trace_all_files) - { - for (i = 0; i < MAX_TRACE_FILES; ++i) - { - const char *path2 = trace_files[i].path; - if (path2 != NULL && VG_(strcmp)(path, path2) == 0) - { - FD_SET(res._val, &trace_files[i].fds); -// VG_(message)(Vg_DebugMsg, "fd %ld connected to %s\n", res._val, path); - break; - } - } - } - - mmt_nv_ioctl_post_open(args, res); -} - -static void post_close(ThreadId tid, UWord *args, UInt nArgs, SysRes res) -{ - int fd = (int)args[0]; - int i; - - if (!trace_all_files) - for(i = 0; i < MAX_TRACE_FILES; ++i) - { - if (trace_files[i].path != NULL && FD_ISSET(fd, &trace_files[i].fds)) - { - FD_CLR(fd, &trace_files[i].fds); - break; - } - } - - mmt_nv_ioctl_post_close(args); -} - -static void post_mmap(ThreadId tid, UWord *args, UInt nArgs, SysRes res, int offset_unit) -{ - void *start = (void *)args[0]; - unsigned long len = args[1]; -// unsigned long prot = args[2]; -// unsigned long flags = args[3]; - unsigned long fd = args[4]; - unsigned long offset = args[5]; - int i; - struct mmt_mmap_data *region; - - if (res._isError || (int)fd == -1) - return; - - start = (void *)res._val; - - if (!trace_all_files) - { - for(i = 0; i < MAX_TRACE_FILES; ++i) - { - if (FD_ISSET(fd, &trace_files[i].fds)) - break; - } - if (i == MAX_TRACE_FILES) - { -// VG_(message)(Vg_DebugMsg, "fd %ld not found\n", fd); - return; - } - } - - mmt_nv_ioctl_post_mmap(args, res, offset_unit); - - if (mmt_last_region + 1 >= MMT_MAX_REGIONS) - { - VG_(message)(Vg_UserMsg, "not enough space for new mmap!\n"); - return; - } - - region = &mmt_mmaps[++mmt_last_region]; - - region->fd = fd; - region->id = current_item++; - region->start = (Addr)start; - region->end = (Addr)(((char *)start) + len); - region->offset = offset * offset_unit; - - VG_(message) (Vg_DebugMsg, - "got new mmap at %p, len: 0x%08lx, offset: 0x%llx, serial: %d\n", - (void *)region->start, len, region->offset, region->id); -} - -static void post_munmap(ThreadId tid, UWord *args, UInt nArgs, SysRes res) -{ - void *start = (void *)args[0]; -// unsigned long len = args[1]; - int i; - struct mmt_mmap_data *region; - - if (res._isError) - return; - - for (i = 0; i <= mmt_last_region; ++i) - { - region = &mmt_mmaps[i]; - if (region->start == (Addr)start) - { - VG_(message) (Vg_DebugMsg, - "removed mmap 0x%lx:0x%lx for: %p, len: 0x%08lx, offset: 0x%llx, serial: %d\n", - region->data1, region->data2, (void *)region->start, - region->end - region->start, region->offset, region->id); - mmt_free_region(i); - return; - } - } -} - -static void post_mremap(ThreadId tid, UWord *args, UInt nArgs, SysRes res) -{ - void *start = (void *)args[0]; - unsigned long old_len = args[1]; - unsigned long new_len = args[2]; -// unsigned long flags = args[3]; - int i; - struct mmt_mmap_data *region; - - if (res._isError) - return; - - for (i = 0; i <= mmt_last_region; ++i) - { - region = &mmt_mmaps[i]; - if (region->start == (Addr)start) - { - region->start = (Addr) res._val; - region->end = region->start + new_len; - VG_(message) (Vg_DebugMsg, - "changed mmap 0x%lx:0x%lx from: (address: %p, len: 0x%08lx), to: (address: %p, len: 0x%08lx), offset 0x%llx, serial %d\n", - region->data1, region->data2, - start, old_len, - (void *)region->start, region->end - region->start, - region->offset, region->id); - return; - } - } -} - -static void post_syscall(ThreadId tid, UInt syscallno, UWord *args, - UInt nArgs, SysRes res) -{ - if (syscallno == __NR_ioctl) - mmt_nv_ioctl_post(args); - else if (syscallno == __NR_open) - post_open(tid, args, nArgs, res); - else if (syscallno == __NR_close) - post_close(tid, args, nArgs, res); - else if (syscallno == __NR_mmap) - post_mmap(tid, args, nArgs, res, 1); -#ifndef MMT_64BIT - else if (syscallno == __NR_mmap2) - post_mmap(tid, args, nArgs, res, 4096); -#endif - else if (syscallno == __NR_munmap) - post_munmap(tid, args, nArgs, res); - else if (syscallno == __NR_mremap) - post_mremap(tid, args, nArgs, res); -} - static void mmt_pre_clo_init(void) { int i; @@ -566,10 +124,10 @@ static void mmt_pre_clo_init(void) mmt_print_usage, mmt_print_debug_usage); - VG_(needs_syscall_wrapper) (pre_syscall, post_syscall); + VG_(needs_syscall_wrapper) (mmt_pre_syscall, mmt_post_syscall); - for (i = 0; i < MAX_TRACE_FILES; ++i) - FD_ZERO(&trace_files[i].fds); + for (i = 0; i < MMT_MAX_TRACE_FILES; ++i) + FD_ZERO(&mmt_trace_files[i].fds); mmt_nv_ioctl_pre_clo_init(); } diff --git a/mmt/mmt_main.h b/mmt/mmt_main.h deleted file mode 100644 index d90b0687..00000000 --- a/mmt/mmt_main.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef MMT_MAIN_H_ -#define MMT_MAIN_H_ - -#include "pub_tool_basics.h" - -#ifdef __LP64__ -#define MMT_64BIT -#endif - -#define MMT_MAX_REGIONS 100 - -struct mmt_mmap_data { - Addr start; - Addr end; - int fd; - Off64T offset; - UInt id; - UWord data1; - UWord data2; -}; - -extern struct mmt_mmap_data mmt_mmaps[MMT_MAX_REGIONS]; -extern int mmt_last_region; -extern UInt current_item; - -void mmt_free_region(int idx); - -VG_REGPARM(2) -void trace_store(Addr addr, SizeT size, Addr inst_addr, UWord value); - -VG_REGPARM(2) -void trace_store2(Addr addr, SizeT size, Addr inst_addr, UWord value1, UWord value2); - -#ifndef MMT_64BIT -VG_REGPARM(2) -void trace_store4(Addr addr, Addr inst_addr, UWord value1, UWord value2, UWord value3, UWord value4); -#endif - -VG_REGPARM(2) -void trace_load(Addr addr, SizeT size, UInt inst_addr, UWord value); - -VG_REGPARM(2) -void trace_load2(Addr addr, SizeT size, UInt inst_addr, UWord value1, UWord value2); - -#ifndef MMT_64BIT -VG_REGPARM(2) -void trace_load4(Addr addr, SizeT size, UInt inst_addr, UWord value1, UWord value2, UWord value3, UWord value4); -#endif - - -#endif /* MMT_MAIN_H_ */ diff --git a/mmt/mmt_nv_ioctl.c b/mmt/mmt_nv_ioctl.c index 4e7170ef..19287b1e 100644 --- a/mmt/mmt_nv_ioctl.c +++ b/mmt/mmt_nv_ioctl.c @@ -21,7 +21,7 @@ The GNU General Public License is contained in the file COPYING. */ #include "mmt_nv_ioctl.h" -#include "mmt_main.h" +#include "mmt_trace.h" #include "pub_tool_vki.h" #include "pub_tool_libcprint.h" #include "pub_tool_libcfile.h" @@ -29,8 +29,6 @@ #include "pub_tool_libcproc.h" #include <sys/select.h> -#include <fcntl.h> -#include <string.h> static fd_set nvidiactl_fds; static fd_set nvidia0_fds; @@ -56,7 +54,7 @@ void mmt_nv_ioctl_post_clo_init(void) { if (mmt_trace_marks) { SysRes ff; - ff = VG_(open)("/sys/kernel/debug/tracing/trace_marker", O_WRONLY, 0777); + ff = VG_(open)("/sys/kernel/debug/tracing/trace_marker", VKI_O_WRONLY, 0777); if (ff._isError) { VG_(message) (Vg_UserMsg, "Cannot open marker file!\n"); mmt_trace_marks = 0; @@ -84,7 +82,7 @@ static struct mmt_mmap_data *get_nvidia_mapping(Off64T offset) } region = &mmt_mmaps[++mmt_last_region]; - region->id = current_item++; + region->id = mmt_current_item++; region->fd = 0; region->offset = offset; return region; @@ -349,7 +347,7 @@ void mmt_nv_ioctl_pre(UWord *args) size = ((id & 0x3FFF0000) >> 16) / 4; VG_(sprintf) (line, "pre_ioctl: fd:%d, id:0x%02x (full:0x%x), data: ", fd, id & 0xFF, id); - idx = strlen(line); + idx = VG_(strlen(line)); for (i = 0; i < size; ++i) { @@ -490,7 +488,7 @@ void mmt_nv_ioctl_post(UWord *args) size = ((id & 0x3FFF0000) >> 16) / 4; VG_(sprintf) (line, "post_ioctl: fd:%d, id:0x%02x (full:0x%x), data: ", fd, id & 0xFF, id); - idx = strlen(line); + idx = VG_(strlen(line)); for (i = 0; i < size; ++i) { diff --git a/mmt/mmt_trace.c b/mmt/mmt_trace.c new file mode 100644 index 00000000..2cfd9a1c --- /dev/null +++ b/mmt/mmt_trace.c @@ -0,0 +1,442 @@ +/* + Copyright (C) 2006 Dave Airlie + Copyright (C) 2007 Wladimir J. van der Laan + Copyright (C) 2009 Marcin Slusarz <marcin.slusarz@gmail.com> + + 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 "mmt_trace.h" +#include "mmt_nv_ioctl.h" + +#include "pub_tool_libcbase.h" +#include "pub_tool_libcprint.h" +#include "pub_tool_vkiscnums.h" + +struct mmt_mmap_data mmt_mmaps[MMT_MAX_REGIONS]; +int mmt_last_region = -1; + +UInt mmt_current_item = 1; + +int mmt_trace_opens = False; +struct mmt_trace_file mmt_trace_files[MMT_MAX_TRACE_FILES]; + +int mmt_trace_all_files = False; + +static struct mmt_mmap_data *find_mmap(Addr addr) +{ + struct mmt_mmap_data *region = NULL; + int i; + + for (i = 0; i <= mmt_last_region; i++) + { + region = &mmt_mmaps[i]; + if (addr >= region->start && addr < region->end) + return region; + } + + return NULL; +} + +static void mydescribe(Addr inst_addr, char *namestr, int len) +{ +#if 0 + const SegInfo *si; + /* Search for it in segments */ + VG_(snprintf) (namestr, len, "@%08x", inst_addr); + for (si = VG_(next_seginfo) (NULL); + si != NULL; si = VG_(next_seginfo) (si)) + { + Addr base = VG_(seginfo_start) (si); + SizeT size = VG_(seginfo_size) (si); + + if (inst_addr >= base && inst_addr < base + size) + { + const UChar *filename = VG_(seginfo_filename) (si); + VG_(snprintf) (namestr, len, "@%08x (%s:%08x)", inst_addr, + filename, inst_addr - base); + + break; + } + } +#else + VG_(strcpy) (namestr, ""); +#endif + +} + +VG_REGPARM(2) +void mmt_trace_store(Addr addr, SizeT size, Addr inst_addr, UWord value) +{ + struct mmt_mmap_data *region; + char valstr[64]; + char namestr[256]; + + region = find_mmap(addr); + if (!region) + return; + + switch (size) + { + case 1: + VG_(sprintf) (valstr, "0x%02lx", value); + break; + case 2: + VG_(sprintf) (valstr, "0x%04lx", value); + break; + case 4: + VG_(sprintf) (valstr, "0x%08lx", value); + break; +#ifdef MMT_64BIT + case 8: + VG_(sprintf) (valstr, "0x%08lx,0x%08lx", value >> 32, value & 0xffffffff); + break; +#endif + default: + return; + } + mydescribe(inst_addr, namestr, 256); + + VG_(message) (Vg_DebugMsg, "w %d:0x%04x, %s %s\n", region->id, (unsigned int)(addr - region->start), valstr, namestr); +} + +VG_REGPARM(2) +void mmt_trace_store2(Addr addr, SizeT size, Addr inst_addr, UWord value1, UWord value2) +{ + struct mmt_mmap_data *region; + char valstr[64]; + char namestr[256]; + + region = find_mmap(addr); + if (!region) + return; + + switch (size) + { + case 4: + VG_(sprintf) (valstr, "0x%08lx,0x%08lx", value1, value2); + break; +#ifdef MMT_64BIT + case 8: + VG_(sprintf) (valstr, "0x%08lx,0x%08lx,0x%08lx,0x%08lx", + value1 >> 32, value1 & 0xffffffff, + value2 >> 32, value2 & 0xffffffff); + break; +#endif + default: + return; + } + + mydescribe(inst_addr, namestr, 256); + + VG_(message) (Vg_DebugMsg, "w %d:0x%04x, %s %s\n", region->id, (unsigned int)(addr - region->start), valstr, namestr); +} + +#ifndef MMT_64BIT +VG_REGPARM(2) +void mmt_trace_store4(Addr addr, Addr inst_addr, UWord value1, UWord value2, UWord value3, UWord value4) +{ + struct mmt_mmap_data *region; + char valstr[64]; + char namestr[256]; + + region = find_mmap(addr); + if (!region) + return; + + VG_(sprintf) (valstr, "0x%08lx,0x%08lx,0x%08lx,0x%08lx", value1, value2, value3, value4); + mydescribe(inst_addr, namestr, 256); + + VG_(message) (Vg_DebugMsg, "w %d:0x%04x, %s %s\n", region->id, (unsigned int)(addr - region->start), valstr, namestr); +} +#endif + +VG_REGPARM(2) +void mmt_trace_load(Addr addr, SizeT size, UInt inst_addr, UWord value) +{ + struct mmt_mmap_data *region; + char valstr[64]; + char namestr[256]; + + region = find_mmap(addr); + if (!region) + return; + + switch (size) + { + case 1: + VG_(sprintf) (valstr, "0x%02lx", value); + break; + case 2: + VG_(sprintf) (valstr, "0x%04lx", value); + break; + case 4: + VG_(sprintf) (valstr, "0x%08lx", value); + break; +#ifdef MMT_64BIT + case 8: + VG_(sprintf) (valstr, "0x%08lx,0x%08lx", value >> 32, value & 0xffffffff); + break; +#endif + default: + return; + } + mydescribe(inst_addr, namestr, 256); + + VG_(message) (Vg_DebugMsg, "r %d:0x%04x, %s %s\n", region->id, (unsigned int)(addr - region->start), valstr, namestr); +} + +VG_REGPARM(2) +void mmt_trace_load2(Addr addr, SizeT size, UInt inst_addr, UWord value1, UWord value2) +{ + struct mmt_mmap_data *region; + char valstr[64]; + char namestr[256]; + + region = find_mmap(addr); + if (!region) + return; + + switch (size) + { + case 4: + VG_(sprintf) (valstr, "0x%08lx,0x%08lx", value1, value2); + break; +#ifdef MMT_64BIT + case 8: + VG_(sprintf) (valstr, "0x%08lx,0x%08lx,0x%08lx,0x%08lx", + value1 >> 32, value1 & 0xffffffff, + value2 >> 32, value2 & 0xffffffff); + break; +#endif + default: + return; + } + mydescribe(inst_addr, namestr, 256); + + VG_(message) (Vg_DebugMsg, "r %d:0x%04x, %s %s\n", region->id, (unsigned int)(addr - region->start), valstr, namestr); +} + +#ifndef MMT_64BIT +VG_REGPARM(2) +void mmt_trace_load4(Addr addr, SizeT size, UInt inst_addr, UWord value1, UWord value2, UWord value3, UWord value4) +{ + struct mmt_mmap_data *region; + char valstr[64]; + char namestr[256]; + + region = find_mmap(addr); + if (!region) + return; + + VG_(sprintf) (valstr, "0x%08lx,0x%08lx,0x%08lx,0x%08lx", value1, value2, value3, value4); + mydescribe(inst_addr, namestr, 256); + + VG_(message) (Vg_DebugMsg, "r %d:0x%04x, %s %s\n", region->id, (unsigned int)(addr - region->start), valstr, namestr); +} +#endif + +void mmt_pre_syscall(ThreadId tid, UInt syscallno, UWord *args, UInt nArgs) +{ + if (syscallno == __NR_ioctl) + mmt_nv_ioctl_pre(args); +} + +void mmt_free_region(int idx) +{ + if (mmt_last_region != idx) + VG_(memmove)(mmt_mmaps + idx, mmt_mmaps + idx + 1, + (mmt_last_region - idx) * sizeof(struct mmt_mmap_data)); + VG_(memset)(&mmt_mmaps[mmt_last_region--], 0, sizeof(struct mmt_mmap_data)); +} + +static void post_open(ThreadId tid, UWord *args, UInt nArgs, SysRes res) +{ + const char *path = (const char *)args[0]; + int i; + + if (mmt_trace_opens) + { + int flags = (int)args[1]; + int mode = (int)args[2]; + VG_(message)(Vg_DebugMsg, "sys_open: %s, flags: 0x%x, mode: 0x%x, ret: %ld\n", path, flags, mode, res._val); + } + if (res._isError) + return; + + if (!mmt_trace_all_files) + { + for (i = 0; i < MMT_MAX_TRACE_FILES; ++i) + { + const char *path2 = mmt_trace_files[i].path; + if (path2 != NULL && VG_(strcmp)(path, path2) == 0) + { + FD_SET(res._val, &mmt_trace_files[i].fds); +// VG_(message)(Vg_DebugMsg, "fd %ld connected to %s\n", res._val, path); + break; + } + } + } + + mmt_nv_ioctl_post_open(args, res); +} + +static void post_close(ThreadId tid, UWord *args, UInt nArgs, SysRes res) +{ + int fd = (int)args[0]; + int i; + + if (!mmt_trace_all_files) + for(i = 0; i < MMT_MAX_TRACE_FILES; ++i) + { + if (mmt_trace_files[i].path != NULL && FD_ISSET(fd, &mmt_trace_files[i].fds)) + { + FD_CLR(fd, &mmt_trace_files[i].fds); + break; + } + } + + mmt_nv_ioctl_post_close(args); +} + +static void post_mmap(ThreadId tid, UWord *args, UInt nArgs, SysRes res, int offset_unit) +{ + void *start = (void *)args[0]; + unsigned long len = args[1]; +// unsigned long prot = args[2]; +// unsigned long flags = args[3]; + unsigned long fd = args[4]; + unsigned long offset = args[5]; + int i; + struct mmt_mmap_data *region; + + if (res._isError || (int)fd == -1) + return; + + start = (void *)res._val; + + if (!mmt_trace_all_files) + { + for(i = 0; i < MMT_MAX_TRACE_FILES; ++i) + { + if (FD_ISSET(fd, &mmt_trace_files[i].fds)) + break; + } + if (i == MMT_MAX_TRACE_FILES) + { +// VG_(message)(Vg_DebugMsg, "fd %ld not found\n", fd); + return; + } + } + + mmt_nv_ioctl_post_mmap(args, res, offset_unit); + + if (mmt_last_region + 1 >= MMT_MAX_REGIONS) + { + VG_(message)(Vg_UserMsg, "not enough space for new mmap!\n"); + return; + } + + region = &mmt_mmaps[++mmt_last_region]; + + region->fd = fd; + region->id = mmt_current_item++; + region->start = (Addr)start; + region->end = (Addr)(((char *)start) + len); + region->offset = offset * offset_unit; + + VG_(message) (Vg_DebugMsg, + "got new mmap at %p, len: 0x%08lx, offset: 0x%llx, serial: %d\n", + (void *)region->start, len, region->offset, region->id); +} + +static void post_munmap(ThreadId tid, UWord *args, UInt nArgs, SysRes res) +{ + void *start = (void *)args[0]; +// unsigned long len = args[1]; + int i; + struct mmt_mmap_data *region; + + if (res._isError) + return; + + for (i = 0; i <= mmt_last_region; ++i) + { + region = &mmt_mmaps[i]; + if (region->start == (Addr)start) + { + VG_(message) (Vg_DebugMsg, + "removed mmap 0x%lx:0x%lx for: %p, len: 0x%08lx, offset: 0x%llx, serial: %d\n", + region->data1, region->data2, (void *)region->start, + region->end - region->start, region->offset, region->id); + mmt_free_region(i); + return; + } + } +} + +static void post_mremap(ThreadId tid, UWord *args, UInt nArgs, SysRes res) +{ + void *start = (void *)args[0]; + unsigned long old_len = args[1]; + unsigned long new_len = args[2]; +// unsigned long flags = args[3]; + int i; + struct mmt_mmap_data *region; + + if (res._isError) + return; + + for (i = 0; i <= mmt_last_region; ++i) + { + region = &mmt_mmaps[i]; + if (region->start == (Addr)start) + { + region->start = (Addr) res._val; + region->end = region->start + new_len; + VG_(message) (Vg_DebugMsg, + "changed mmap 0x%lx:0x%lx from: (address: %p, len: 0x%08lx), to: (address: %p, len: 0x%08lx), offset 0x%llx, serial %d\n", + region->data1, region->data2, + start, old_len, + (void *)region->start, region->end - region->start, + region->offset, region->id); + return; + } + } +} + +void mmt_post_syscall(ThreadId tid, UInt syscallno, UWord *args, + UInt nArgs, SysRes res) +{ + if (syscallno == __NR_ioctl) + mmt_nv_ioctl_post(args); + else if (syscallno == __NR_open) + post_open(tid, args, nArgs, res); + else if (syscallno == __NR_close) + post_close(tid, args, nArgs, res); + else if (syscallno == __NR_mmap) + post_mmap(tid, args, nArgs, res, 1); +#ifndef MMT_64BIT + else if (syscallno == __NR_mmap2) + post_mmap(tid, args, nArgs, res, 4096); +#endif + else if (syscallno == __NR_munmap) + post_munmap(tid, args, nArgs, res); + else if (syscallno == __NR_mremap) + post_mremap(tid, args, nArgs, res); +} diff --git a/mmt/mmt_trace.h b/mmt/mmt_trace.h new file mode 100644 index 00000000..777aac3f --- /dev/null +++ b/mmt/mmt_trace.h @@ -0,0 +1,68 @@ +#ifndef MMT_TRACE_H_ +#define MMT_TRACE_H_ + +#include "pub_tool_basics.h" + +#include <sys/select.h> + +#ifdef __LP64__ +#define MMT_64BIT +#endif + +#define MMT_MAX_TRACE_FILES 10 +#define MMT_MAX_REGIONS 100 + +struct mmt_mmap_data { + Addr start; + Addr end; + int fd; + Off64T offset; + UInt id; + UWord data1; + UWord data2; +}; + +struct mmt_trace_file { + const char *path; + fd_set fds; +}; + +extern struct mmt_mmap_data mmt_mmaps[MMT_MAX_REGIONS]; +extern int mmt_last_region; + +extern UInt mmt_current_item; + +extern int mmt_trace_opens; +extern struct mmt_trace_file mmt_trace_files[MMT_MAX_TRACE_FILES]; +extern int mmt_trace_all_files; + +void mmt_free_region(int idx); + +void mmt_pre_syscall(ThreadId tid, UInt syscallno, UWord *args, UInt nArgs); + +void mmt_post_syscall(ThreadId tid, UInt syscallno, UWord *args, UInt nArgs, SysRes res); + +VG_REGPARM(2) +void mmt_trace_store(Addr addr, SizeT size, Addr inst_addr, UWord value); + +VG_REGPARM(2) +void mmt_trace_store2(Addr addr, SizeT size, Addr inst_addr, UWord value1, UWord value2); + +#ifndef MMT_64BIT +VG_REGPARM(2) +void mmt_trace_store4(Addr addr, Addr inst_addr, UWord value1, UWord value2, UWord value3, UWord value4); +#endif + +VG_REGPARM(2) +void mmt_trace_load(Addr addr, SizeT size, UInt inst_addr, UWord value); + +VG_REGPARM(2) +void mmt_trace_load2(Addr addr, SizeT size, UInt inst_addr, UWord value1, UWord value2); + +#ifndef MMT_64BIT +VG_REGPARM(2) +void mmt_trace_load4(Addr addr, SizeT size, UInt inst_addr, UWord value1, UWord value2, UWord value3, UWord value4); +#endif + + +#endif /* MMT_TRACE_H_ */ |