diff options
author | Marcin Slusarz <marcin.slusarz@gmail.com> | 2012-04-01 22:51:07 +0200 |
---|---|---|
committer | Marcin Slusarz <marcin.slusarz@gmail.com> | 2012-04-01 22:51:07 +0200 |
commit | d23202f0c9ac3980efe932beefe5b6da8e546871 (patch) | |
tree | a17537c88d26aae99e4000093dd87e744b3a8968 | |
parent | 302525b65c21d14d89c813677efa7bcc1ac04b93 (diff) |
mmt: add support for tracing nouveau ioctls
-rw-r--r-- | mmt/Makefile.am | 3 | ||||
-rw-r--r-- | mmt/mmt_main.c | 11 | ||||
-rw-r--r-- | mmt/mmt_nouveau_ioctl.c | 87 | ||||
-rw-r--r-- | mmt/mmt_nouveau_ioctl.h | 15 | ||||
-rw-r--r-- | mmt/mmt_trace.c | 9 |
5 files changed, 123 insertions, 2 deletions
diff --git a/mmt/Makefile.am b/mmt/Makefile.am index 279a1f67..d742e66b 100644 --- a/mmt/Makefile.am +++ b/mmt/Makefile.am @@ -5,7 +5,8 @@ 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_trace.c +MMT_SOURCES_COMMON = mmt_main.c mmt_nv_ioctl.c mmt_instrument.c mmt_trace.c \ + mmt_nouveau_ioctl.c mmt_@VGCONF_ARCH_PRI@_@VGCONF_OS@_SOURCES = \ $(MMT_SOURCES_COMMON) diff --git a/mmt/mmt_main.c b/mmt/mmt_main.c index d86f3033..4ae9dc5a 100644 --- a/mmt/mmt_main.c +++ b/mmt/mmt_main.c @@ -33,6 +33,7 @@ #include "pub_tool_mallocfree.h" #include "mmt_nv_ioctl.h" +#include "mmt_nouveau_ioctl.h" #include "mmt_instrument.h" #include "mmt_trace.h" @@ -41,6 +42,7 @@ #define TO_OPT "--mmt-trace-all-opens" #define TA_OPT "--mmt-trace-all-files" #define TM_OPT "--mmt-trace-marks" +#define TV_OPT "--mmt-trace-nouveau-ioctls" static Bool mmt_process_cmd_line_option(Char * arg) { @@ -79,6 +81,11 @@ static Bool mmt_process_cmd_line_option(Char * arg) mmt_trace_marks = True; return True; } + else if (VG_(strcmp)(arg, TV_OPT) == 0) + { + mmt_trace_nouveau_ioctls = True; + return True; + } return False; } @@ -89,7 +96,8 @@ static void mmt_print_usage(void) " this file (e.g. /dev/nvidia0) (you can pass \n" " this option multiple times)\n"); VG_(printf)(" " TA_OPT " trace loads and store to memory mapped for all files\n"); - VG_(printf)(" " TN_OPT " trace ioctls on /dev/nvidiactl and /dev/nvidia0\n"); + VG_(printf)(" " TN_OPT " trace nvidia ioctls on /dev/nvidiactl and /dev/nvidia0\n"); + VG_(printf)(" " TV_OPT " trace nouveau ioctls on /dev/dri/cardX\n"); VG_(printf)(" " TO_OPT " trace all 'open' syscalls\n"); VG_(printf)(" " TM_OPT " send mmiotrace marks before and after ioctls\n"); } @@ -130,6 +138,7 @@ static void mmt_pre_clo_init(void) FD_ZERO(&mmt_trace_files[i].fds); mmt_nv_ioctl_pre_clo_init(); + mmt_nouveau_ioctl_pre_clo_init(); } VG_DETERMINE_INTERFACE_VERSION(mmt_pre_clo_init) diff --git a/mmt/mmt_nouveau_ioctl.c b/mmt/mmt_nouveau_ioctl.c new file mode 100644 index 00000000..dfe8e877 --- /dev/null +++ b/mmt/mmt_nouveau_ioctl.c @@ -0,0 +1,87 @@ +/* + Copyright (C) 2012 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_nouveau_ioctl.h" +#include "pub_tool_libcbase.h" +#include "pub_tool_libcprint.h" +#include "vki/vki-linux.h" + +#include <sys/select.h> + +static fd_set nouveau_fds; +int mmt_trace_nouveau_ioctls = False; + +void mmt_nouveau_ioctl_post_open(UWord *args, SysRes res) +{ + const char *path = (const char *)args[0]; + + if (mmt_trace_nouveau_ioctls) + { + if (VG_(strncmp)(path, "/dev/dri/card", 13) == 0) + FD_SET(res._val, &nouveau_fds); + } +} + +void mmt_nouveau_ioctl_post_close(UWord *args) +{ + int fd = (int)args[0]; + + if (mmt_trace_nouveau_ioctls) + FD_CLR(fd, &nouveau_fds); +} + +void mmt_nouveau_ioctl_pre(UWord *args) +{ + int fd = args[0]; +// UInt id = args[1]; +// UInt *data = (UInt *) args[2]; + + if (!FD_ISSET(fd, &nouveau_fds)) + return; +} + +void mmt_nouveau_ioctl_post(UWord *args) +{ + int fd = args[0]; + UInt id = args[1]; + void *data = (void *) args[2]; + + if (!FD_ISSET(fd, &nouveau_fds)) + return; + + if (id == VKI_DRM_IOCTL_NOUVEAU_GROBJ_ALLOC) + { + struct vki_drm_nouveau_grobj_alloc *arg = data; + VG_(message) (Vg_DebugMsg, + "create gpu object 0x%08x:0x%08x type 0x%04x (%s)\n", + 0, arg->handle, arg->class, ""); + } + else if (id == VKI_DRM_IOCTL_NOUVEAU_GPUOBJ_FREE) + { + struct vki_drm_nouveau_gpuobj_free *arg = data; + VG_(message) (Vg_DebugMsg, "destroy object 0x%08x:0x%08x\n", 0, arg->handle); + } +} + +void mmt_nouveau_ioctl_pre_clo_init(void) +{ + FD_ZERO(&nouveau_fds); +} diff --git a/mmt/mmt_nouveau_ioctl.h b/mmt/mmt_nouveau_ioctl.h new file mode 100644 index 00000000..c6ed0a30 --- /dev/null +++ b/mmt/mmt_nouveau_ioctl.h @@ -0,0 +1,15 @@ +#ifndef MMT_NOUVEAU_IOCTL_H_ +#define MMT_NOUVEAU_IOCTL_H_ + +#include "pub_tool_basics.h" + +extern int mmt_trace_nouveau_ioctls; + +void mmt_nouveau_ioctl_post_open(UWord *args, SysRes res); +void mmt_nouveau_ioctl_post_close(UWord *args); +void mmt_nouveau_ioctl_pre(UWord *args); +void mmt_nouveau_ioctl_post(UWord *args); +void mmt_nouveau_ioctl_pre_clo_init(void); + + +#endif diff --git a/mmt/mmt_trace.c b/mmt/mmt_trace.c index 820dcf91..20340838 100644 --- a/mmt/mmt_trace.c +++ b/mmt/mmt_trace.c @@ -23,6 +23,7 @@ #include "mmt_trace.h" #include "mmt_nv_ioctl.h" +#include "mmt_nouveau_ioctl.h" #include "pub_tool_libcbase.h" #include "pub_tool_libcprint.h" @@ -1070,7 +1071,10 @@ void mmt_trace_load_4_4_4_4_ia(Addr addr, UWord value1, UWord value2, void mmt_pre_syscall(ThreadId tid, UInt syscallno, UWord *args, UInt nArgs) { if (syscallno == __NR_ioctl) + { mmt_nv_ioctl_pre(args); + mmt_nouveau_ioctl_pre(args); + } } static void post_open(ThreadId tid, UWord *args, UInt nArgs, SysRes res) @@ -1102,6 +1106,7 @@ static void post_open(ThreadId tid, UWord *args, UInt nArgs, SysRes res) } mmt_nv_ioctl_post_open(args, res); + mmt_nouveau_ioctl_post_open(args, res); } static void post_close(ThreadId tid, UWord *args, UInt nArgs, SysRes res) @@ -1120,6 +1125,7 @@ static void post_close(ThreadId tid, UWord *args, UInt nArgs, SysRes res) } mmt_nv_ioctl_post_close(args); + mmt_nouveau_ioctl_post_close(args); } static void post_mmap(ThreadId tid, UWord *args, UInt nArgs, SysRes res, int offset_unit) @@ -1216,7 +1222,10 @@ void mmt_post_syscall(ThreadId tid, UInt syscallno, UWord *args, UInt nArgs, SysRes res) { if (syscallno == __NR_ioctl) + { mmt_nv_ioctl_post(args); + mmt_nouveau_ioctl_post(args); + } else if (syscallno == __NR_open) post_open(tid, args, nArgs, res); else if (syscallno == __NR_close) |