summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Slusarz <marcin.slusarz@gmail.com>2011-09-07 20:17:19 +0200
committerMarcin Slusarz <marcin.slusarz@gmail.com>2011-09-17 22:57:44 +0200
commit6f05aba48d3ab8742d9fd23a04bfdb82b8452051 (patch)
treefb57b63ca638bdf9eadc69ebe72fed706b9f7d69
parent8384a95dd0666bbe4a66a34b7081f0543a850689 (diff)
mmt: move tracing functions to separate file
-rw-r--r--mmt/Makefile.am2
-rw-r--r--mmt/mmt_instrument.c14
-rw-r--r--mmt/mmt_main.c466
-rw-r--r--mmt/mmt_main.h51
-rw-r--r--mmt/mmt_nv_ioctl.c12
-rw-r--r--mmt/mmt_trace.c442
-rw-r--r--mmt/mmt_trace.h68
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_ */