rendered paste bodyFrom 5df135a06dcf52b07412926f1d371cbb5ccb83e5 Mon Sep 17 00:00:00 2001
From: Oliver McFadden <z3ro.geek@gmail.com>
Date: Sat, 7 Jun 2008 09:21:12 +0000
Subject: [PATCH] Added Valgrind-MMT.
---
Makefile.am | 3 +-
configure.in | 3 +
coregrind/m_libcbase.c | 20 ++
coregrind/m_syswrap/syswrap-generic.c | 12 +-
coregrind/m_tooliface.c | 2 +-
coregrind/pub_core_tooliface.h | 2 +-
default.supp | 140 ++++--------
helgrind/hg_main.c | 16 ++-
include/pub_tool_libcbase.h | 1 +
include/pub_tool_options.h | 13 ++
include/pub_tool_tooliface.h | 2 +-
memcheck/mc_main.c | 2 +-
mmt/Makefile.am | 47 ++++
mmt/mmt_main.c | 385 +++++++++++++++++++++++++++++++++
14 files changed, 542 insertions(+), 106 deletions(-)
create mode 100644 mmt/Makefile.am
create mode 100644 mmt/mmt_main.c
diff --git a/Makefile.am b/Makefile.am
index ccdf027..c4142a4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,7 +9,8 @@ TOOLS = memcheck \
massif \
lackey \
none \
- helgrind
+ helgrind \
+ mmt
EXP_TOOLS = exp-omega \
exp-drd
diff --git a/configure.in b/configure.in
index 75cc768..2ebec75 100644
--- a/configure.in
+++ b/configure.in
@@ -1024,6 +1024,9 @@ AC_OUTPUT(
lackey/Makefile
lackey/tests/Makefile
lackey/docs/Makefile
+ mmt/Makefile
+ mmt/tests/Makefile
+ mmt/docs/Makefile
none/Makefile
none/tests/Makefile
none/tests/amd64/Makefile
diff --git a/coregrind/m_libcbase.c b/coregrind/m_libcbase.c
index d895bd3..673a7f1 100644
--- a/coregrind/m_libcbase.c
+++ b/coregrind/m_libcbase.c
@@ -217,6 +217,26 @@ Long VG_(atoll16) ( Char* str )
return VG_(strtoll16)(str, NULL);
}
+Long VG_(strtoll) ( Char* str, Char **endptr, Int base )
+{
+ Bool neg = False;
+ Long n = 0;
+ if (*str == '-') { str++; neg = True; };
+ if (base == 16 && *str == '0' && *(str + 1) == 'x') { str += 2; }
+ while ((*str >= '0' && *str <= '9') || (*str >= 'a' && *str <= 'f')) {
+ n = base * n;
+ if (*str <= '9')
+ n += (*str - '0');
+ else
+ n += (*str - 'a' + 10);
+ str++;
+ }
+ if (neg) n = -n;
+ if (endptr)
+ *endptr = str;
+ return n;
+}
+
Long VG_(atoll36) ( Char* str )
{
return VG_(strtoll36)(str, NULL);
diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c
index 95a6d3f..9d8f1aa 100644
--- a/coregrind/m_syswrap/syswrap-generic.c
+++ b/coregrind/m_syswrap/syswrap-generic.c
@@ -160,7 +160,7 @@ ML_(notify_aspacem_and_tool_of_mmap) ( Addr a, SizeT len, UInt prot,
ww = toBool(prot & VKI_PROT_WRITE);
xx = toBool(prot & VKI_PROT_EXEC);
- VG_TRACK( new_mem_mmap, a, len, rr, ww, xx );
+ VG_TRACK( new_mem_mmap, a, len, offset, rr, ww, xx );
if (d)
VG_(discard_translations)( (Addr64)a, (ULong)len,
@@ -303,7 +303,7 @@ SysRes do_mremap( Addr old_addr, SizeT old_len,
VG_TRACK( copy_mem_remap, old_addr, new_addr,
MIN_SIZET(old_len,new_len) );
if (new_len > old_len)
- VG_TRACK( new_mem_mmap, new_addr+old_len, new_len-old_len,
+ VG_TRACK( new_mem_mmap, new_addr+old_len, new_len-old_len, 0,
old_seg->hasR, old_seg->hasW, old_seg->hasX );
VG_TRACK(die_mem_munmap, old_addr, old_len);
if (d) {
@@ -345,7 +345,7 @@ SysRes do_mremap( Addr old_addr, SizeT old_len,
if (ok && advised == needA) {
ok = VG_(am_extend_map_client)( &d, (NSegment*)old_seg, needL );
if (ok) {
- VG_TRACK( new_mem_mmap, needA, needL,
+ VG_TRACK( new_mem_mmap, needA, needL, 0,
old_seg->hasR,
old_seg->hasW, old_seg->hasX );
if (d)
@@ -366,7 +366,7 @@ SysRes do_mremap( Addr old_addr, SizeT old_len,
VG_TRACK( copy_mem_remap, old_addr, advised,
MIN_SIZET(old_len,new_len) );
if (new_len > old_len)
- VG_TRACK( new_mem_mmap, advised+old_len, new_len-old_len,
+ VG_TRACK( new_mem_mmap, advised+old_len, new_len-old_len, 0,
old_seg->hasR, old_seg->hasW, old_seg->hasX );
VG_TRACK(die_mem_munmap, old_addr, old_len);
if (d) {
@@ -405,7 +405,7 @@ SysRes do_mremap( Addr old_addr, SizeT old_len,
ok = VG_(am_extend_map_client)( &d, (NSegment*)old_seg, needL );
if (!ok)
goto eNOMEM;
- VG_TRACK( new_mem_mmap, needA, needL,
+ VG_TRACK( new_mem_mmap, needA, needL, 0,
old_seg->hasR, old_seg->hasW, old_seg->hasX );
if (d)
VG_(discard_translations)( needA, needL, "do_remap(6)" );
@@ -1694,7 +1694,7 @@ ML_(generic_POST_sys_shmat) ( ThreadId tid,
/* we don't distinguish whether it's read-only or
* read-write -- it doesn't matter really. */
- VG_TRACK( new_mem_mmap, res, segmentSize, True, True, False );
+ VG_TRACK( new_mem_mmap, res, segmentSize, 0, True, True, False );
if (d)
VG_(discard_translations)( (Addr64)res,
(ULong)VG_PGROUNDUP(segmentSize),
diff --git a/coregrind/m_tooliface.c b/coregrind/m_tooliface.c
index 2aa74e9..ee2ca24 100644
--- a/coregrind/m_tooliface.c
+++ b/coregrind/m_tooliface.c
@@ -289,7 +289,7 @@ void VG_(fn)(VG_REGPARM(1) void(*f)(args)) \
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_new_mem_mmap, Addr, SizeT, Off64T, Bool, Bool, Bool)
DEF(track_copy_mem_remap, Addr, Addr, SizeT)
DEF(track_change_mem_mprotect, Addr, SizeT, Bool, Bool, Bool)
diff --git a/coregrind/pub_core_tooliface.h b/coregrind/pub_core_tooliface.h
index 7f77fed..13cb96b 100644
--- a/coregrind/pub_core_tooliface.h
+++ b/coregrind/pub_core_tooliface.h
@@ -164,7 +164,7 @@ typedef struct {
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_new_mem_mmap) (Addr, SizeT, Off64T, Bool, Bool, Bool);
void (*track_copy_mem_remap) (Addr src, Addr dst, SizeT);
void (*track_change_mem_mprotect) (Addr, SizeT, Bool, Bool, Bool);
diff --git a/default.supp b/default.supp
index f1f0cc2..f4d09bf 100644
--- a/default.supp
+++ b/default.supp
@@ -1,6 +1,6 @@
# This is a generated file, composed of the following suppression rules:
#
-# xfree-3.supp xfree-4.supp glibc-2.34567-NPTL-helgrind.supp glibc-2.4.supp
+# xfree-3.supp xfree-4.supp glibc-2.34567-NPTL-helgrind.supp glibc-2.5.supp
#
@@ -1011,118 +1011,74 @@
# and the optional extra info is:
# if Param: name of system call param
-##----------------------------------------------------------------------##
-## Suppressions for Fedora Core 5 on ppc32/amd64 (glibc-2.3.90)
-
{
- Fedora-Core-5-hack1
+ dl-hack1
Memcheck:Cond
fun:_dl_start
fun:_start
}
{
- Fedora-Core-5-hack2
- Memcheck:Cond
- obj:/lib*/ld-2.3.90.so
- obj:/lib*/ld-2.3.90.so
- obj:/lib*/ld-2.3.90.so
- obj:/lib*/ld-2.3.90.so
-}
-
-{
- Fedora-Core-5-hack2a
- Memcheck:Cond
- obj:/lib*/ld-2.4*so
- obj:/lib*/ld-2.4*so
- obj:/lib*/ld-2.4*so
- obj:/lib*/ld-2.4*so
-}
-
-{
- Fedora-Core-5-hack3
+ dl-hack2
Memcheck:Cond
- obj:/lib*/ld-2.3.90.so
- obj:/lib*/ld-2.3.90.so
- obj:/lib*/ld-2.3.90.so
- obj:/lib*/libc-2.3.90.so
-}
-
-{
- Fedora-Core-5-__strcpy_chk-64bit-hack-TODO-fix-this-properly
- Memcheck:Addr8
- fun:__strcpy_chk
- obj:/usr/lib64/libX11.so.6.2.0
- obj:/usr/lib64/libX11.so.6.2.0
+ obj:/lib*/ld-2.5*.so
+ obj:/lib*/ld-2.5*.so
+ obj:/lib*/ld-2.5*.so
+ obj:/lib*/ld-2.5*.so
}
{
- Fedora-Core-5-hack3-ld24
+ dl-hack3
Memcheck:Cond
- obj:/lib*/ld-2.4*so*
- obj:/lib*/ld-2.4*so*
- obj:/lib*/ld-2.4*so*
-}
-
-{
- Fedora-Core-5-yet-another-ppc32-hack
- Memcheck:Addr4
- fun:_wordcopy_fwd_dest_aligned
- fun:mempcpy
- obj:/lib*/libc-2.4*so*
+ obj:/lib*/ld-2.5*so*
+ obj:/lib*/ld-2.5*so*
+ obj:/lib*/ld-2.5*so*
}
##----------------------------------------------------------------------##
{
- glibc-2.3.x-on-SUSE-10.1-(PPC)-1
+ glibc-2.5.x-on-SUSE-10.2-(PPC)-1
Memcheck:Cond
fun:_dl_start_final
fun:_dl_start
fun:_start
}
{
- glibc-2.3.x-on-SUSE-10.1-(PPC)-2a
+ glibc-2.5.x-on-SUSE-10.2-(PPC)-2a
Memcheck:Cond
fun:index
- obj:*ld-2.3.*.so
+ obj:*ld-2.5.*.so
}
{
- glibc-2.3.x-on-SuSE-10.1-(PPC)-2b
+ glibc-2.5.x-on-SuSE-10.2-(PPC)-2b
Memcheck:Addr4
fun:index
fun:expand_dynamic_string_token
}
{
- glibc-2.3.5-on-SuSE-10.1-(PPC)-2c
+ glibc-2.5.5-on-SuSE-10.2-(PPC)-2c
Memcheck:Addr4
fun:index
- obj:*ld-2.3.*.so
+ obj:*ld-2.5.*.so
}
{
glibc-2.3.5-on-SuSE-10.1-(PPC)-3
Memcheck:Addr4
fun:*wordcopy_fwd_dest_aligned*
fun:mem*cpy
- obj:*lib*2.3.*.so
-}
-{
- index-not-intercepted-early-enough-HACK-4
- Memcheck:Cond
- fun:index
- fun:expand_dynamic_string_token
+ obj:*lib*2.5.*.so
}
-
##----------------------------------------------------------------------##
-## Various structure padding things on amd64 SuSE 10.1
+## Various structure padding things on SUSE 10.2
##
{
X11-64bit-padding-1a
Memcheck:Param
write(buf)
fun:__write_nocancel
- obj:/usr/X*/libX11.so*
- obj:/usr/X*/libX11.so*
+ obj:/usr/lib*/libX11.so*
+ obj:/usr/lib*/libX11.so*
fun:X*
}
{
@@ -1130,8 +1086,8 @@
Memcheck:Param
write(buf)
fun:__write_nocancel
- obj:/usr/X*/libX11.so*
- obj:/usr/X*/libX11.so*
+ obj:/usr/lib*/libX11.so*
+ obj:/usr/lib*/libX11.so*
fun:_X*
}
{
@@ -1139,29 +1095,27 @@
Memcheck:Param
write(buf)
fun:__write_nocancel
- obj:/usr/X*/libX11.so*
- obj:/usr/X*/libX11.so*
- obj:/usr/X*/libX11.so*
+ obj:/usr/lib*/libX11.so*
+ obj:/usr/lib*/libX11.so*
+ obj:/usr/lib*/libX11.so*
}
{
X11-64bit-padding-1d
Memcheck:Param
write(buf)
fun:__write_nocancel
- obj:/usr/X*/libICE.so*
- obj:/usr/X*/libICE.so*
- obj:/usr/X*/libICE.so*
+ obj:/usr/lib*/libICE.so*
+ obj:/usr/lib*/libICE.so*
+ obj:/usr/lib*/libICE.so*
}
-
-
{
X11-64bit-padding-2a
Memcheck:Param
writev(vector[...])
fun:do_writev
- obj:/usr/X*/libX11.so*
- obj:/usr/X*/libX11.so*
- obj:/usr/X*/libX11.so*
+ obj:/usr/lib*/libX11.so*
+ obj:/usr/lib*/libX11.so*
+ obj:/usr/lib*/libX11.so*
}
{
X11-64bit-padding-2b
@@ -1169,8 +1123,8 @@
writev(vector[...])
fun:do_writev
fun:writev
- obj:/usr/X*/libX11.so*
- obj:/usr/X*/libX11.so*
+ obj:/usr/lib*/libX11.so*
+ obj:/usr/lib*/libX11.so*
}
{
@@ -1187,9 +1141,9 @@
Memcheck:Param
socketcall.sendto(msg)
fun:__sendto_nocancel
- obj:/*libc-2.4.so
- obj:/*libc-2.4.so
- obj:/*libc-2.4.so
+ obj:/*libc-2.5.so
+ obj:/*libc-2.5.so
+ obj:/*libc-2.5.so
}
{
glibc24-64bit-padding-1c
@@ -1199,7 +1153,7 @@
fun:__nscd_get_map_ref
fun:nscd_get*_r
fun:*nscd*
- obj:/*libc-2.4.so
+ obj:/*libc-2.5.so
}
@@ -1208,9 +1162,9 @@
Memcheck:Param
write(buf)
obj:/*libpthread-2.4.so*
- obj:/usr/X*/libX11.so*
- obj:/usr/X*/libX11.so*
- obj:/usr/X*/libX11.so*
+ obj:/usr/lib*/libX11.so*
+ obj:/usr/lib*/libX11.so*
+ obj:/usr/lib*/libX11.so*
}
{
@@ -1218,18 +1172,18 @@
Memcheck:Param
socketcall.sendto(msg)
fun:send
- obj:/*libc-2.4.so
- obj:/*libc-2.4.so
- obj:/*libc-2.4.so
+ obj:/*libc-2.5.so
+ obj:/*libc-2.5.so
+ obj:/*libc-2.5.so
}
{
X11-64bit-padding-4b
Memcheck:Param
socketcall.send(msg)
fun:send
- obj:/*libc-2.4.so
- obj:/*libc-2.4.so
- obj:/*libc-2.4.so
+ obj:/*libc-2.5.so
+ obj:/*libc-2.5.so
+ obj:/*libc-2.5.so
}
##----------------------------------------------------------------------##
diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c
index f246e66..884e0ce 100644
--- a/helgrind/hg_main.c
+++ b/helgrind/hg_main.c
@@ -5432,7 +5432,7 @@ void evh__new_mem ( Addr a, SizeT len ) {
static
void evh__new_mem_w_perms ( Addr a, SizeT len,
- Bool rr, Bool ww, Bool xx ) {
+ Bool rr, Bool ww, Bool xx ) {
if (SHOW_EVENTS >= 1)
VG_(printf)("evh__new_mem_w_perms(%p, %lu, %d,%d,%d)\n",
(void*)a, len, (Int)rr, (Int)ww, (Int)xx );
@@ -5443,6 +5443,18 @@ void evh__new_mem_w_perms ( Addr a, SizeT len,
}
static
+void evh__new_mem_w_perms_mmap ( Addr a, SizeT len,
+ Off64T offset, Bool rr, Bool ww, Bool xx ) {
+ if (SHOW_EVENTS >= 1)
+ VG_(printf)("evh__new_mem_w_perms_mmap(%p, %lu, %d,%d,%d)\n",
+ (void*)a, len, (Int)rr, (Int)ww, (Int)xx );
+ if (rr || ww || xx)
+ shadow_mem_make_New( get_current_Thread(), a, len );
+ if (len >= SCE_BIGRANGE_T && (clo_sanity_flags & SCE_BIGRANGE))
+ all__sanity_check("evh__new_mem_w_perms_mmap-post");
+}
+
+static
void evh__set_perms ( Addr a, SizeT len,
Bool rr, Bool ww, Bool xx ) {
if (SHOW_EVENTS >= 1)
@@ -8807,7 +8819,7 @@ static void hg_pre_clo_init ( void )
VG_(track_new_mem_startup) ( evh__new_mem_w_perms );
VG_(track_new_mem_stack_signal)( evh__die_mem );
VG_(track_new_mem_brk) ( evh__new_mem );
- VG_(track_new_mem_mmap) ( evh__new_mem_w_perms );
+ VG_(track_new_mem_mmap) ( evh__new_mem_w_perms_mmap );
VG_(track_new_mem_stack) ( evh__new_mem );
// FIXME: surely this isn't thread-aware
diff --git a/include/pub_tool_libcbase.h b/include/pub_tool_libcbase.h
index f262377..dcfa011 100644
--- a/include/pub_tool_libcbase.h
+++ b/include/pub_tool_libcbase.h
@@ -65,6 +65,7 @@ extern double VG_(strtod) ( Char* str, Char** endptr );
extern Long VG_(atoll) ( Char* str ); // base 10
extern Long VG_(atoll16) ( Char* str ); // base 16; leading 0x accepted
+extern Long VG_(strtoll) ( Char* str, Char** endptr, Int base );
extern Long VG_(atoll36) ( Char* str ); // base 36
/* ---------------------------------------------------------------------
diff --git a/include/pub_tool_options.h b/include/pub_tool_options.h
index ed5c37e..338d97d 100644
--- a/include/pub_tool_options.h
+++ b/include/pub_tool_options.h
@@ -60,6 +60,11 @@
if ('\0' != s[0] || (qq_var) != n) VG_(err_bad_option)(qq_arg); \
}
+#define VG_HEX_CLO(qq_arg, qq_option, qq_var) \
+ if (VG_CLO_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=")) { \
+ (qq_var) = (Int)VG_(strtoll)( &qq_arg[ VG_(strlen)(qq_option)+1 ], NULL, 16 ); \
+ }
+
/* Bounded integer arg */
#define VG_BNUM_CLO(qq_arg, qq_option, qq_var, qq_lo, qq_hi) \
if (VG_CLO_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=")) { \
@@ -94,6 +99,14 @@
if ('\0' != s[0]) VG_(err_bad_option)(qq_arg); \
}
+/* Bounded integer arg, given in hex */
+#define VG_BHEX_CLO(qq_arg, qq_option, qq_var, qq_lo, qq_hi) \
+ if (VG_CLO_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=")) { \
+ (qq_var) = (Int)VG_(strtoll)( &qq_arg[ VG_(strlen)(qq_option)+1 ], NULL, 16 ); \
+ if ((qq_var) < (qq_lo)) (qq_var) = (qq_lo); \
+ if ((qq_var) > (qq_hi)) (qq_var) = (qq_hi); \
+ }
+
/* Bool arg whose value is denoted by the exact presence of the given string. */
#define VG_XACT_CLO(qq_arg, qq_option, qq_var) \
if (VG_CLO_STREQ(qq_arg, qq_option)) { \
diff --git a/include/pub_tool_tooliface.h b/include/pub_tool_tooliface.h
index cfc57d7..7564025 100644
--- a/include/pub_tool_tooliface.h
+++ b/include/pub_tool_tooliface.h
@@ -475,7 +475,7 @@ 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,
+void VG_(track_new_mem_mmap) (void(*f)(Addr a, SizeT len, Off64T offset,
Bool rr, Bool ww, Bool xx));
void VG_(track_copy_mem_remap) (void(*f)(Addr from, Addr to, SizeT len));
diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c
index b7e7006..78daaed 100644
--- a/memcheck/mc_main.c
+++ b/memcheck/mc_main.c
@@ -2539,7 +2539,7 @@ void mc_new_mem_startup( Addr a, SizeT len, Bool rr, Bool ww, Bool xx )
}
static
-void mc_new_mem_mmap ( Addr a, SizeT len, Bool rr, Bool ww, Bool xx )
+void mc_new_mem_mmap ( Addr a, SizeT len, Off64T o, Bool rr, Bool ww, Bool xx )
{
MC_(make_mem_defined)(a, len);
}
diff --git a/mmt/Makefile.am b/mmt/Makefile.am
new file mode 100644
index 0000000..e8f7101
--- /dev/null
+++ b/mmt/Makefile.am
@@ -0,0 +1,47 @@
+include $(top_srcdir)/Makefile.tool.am
+
+noinst_PROGRAMS =
+if VGP_X86_LINUX
+noinst_PROGRAMS += mmt-x86-linux
+endif
+if VGP_AMD64_LINUX
+noinst_PROGRAMS += mmt-amd64-linux
+endif
+if VGP_PPC32_LINUX
+noinst_PROGRAMS += mmt-ppc32-linux
+endif
+if VGP_PPC64_LINUX
+noinst_PROGRAMS += mmt-ppc64-linux
+endif
+
+MMT_SOURCES_COMMON = mmt_main.c
+
+mmt_x86_linux_SOURCES = $(MMT_SOURCES_COMMON)
+mmt_x86_linux_CPPFLAGS = $(AM_CPPFLAGS_X86_LINUX)
+mmt_x86_linux_CFLAGS = $(AM_CFLAGS_X86_LINUX)
+mmt_x86_linux_DEPENDENCIES = $(COREGRIND_LIBS_X86_LINUX)
+mmt_x86_linux_LDADD = $(TOOL_LDADD_X86_LINUX)
+mmt_x86_linux_LDFLAGS = $(TOOL_LDFLAGS_X86_LINUX)
+
+mmt_amd64_linux_SOURCES = $(MMT_SOURCES_COMMON)
+mmt_amd64_linux_CPPFLAGS = $(AM_CPPFLAGS_AMD64_LINUX)
+mmt_amd64_linux_CFLAGS = $(AM_CFLAGS_AMD64_LINUX)
+mmt_amd64_linux_DEPENDENCIES = $(COREGRIND_LIBS_AMD64_LINUX)
+mmt_amd64_linux_LDADD = $(TOOL_LDADD_AMD64_LINUX)
+mmt_amd64_linux_LDFLAGS = $(TOOL_LDFLAGS_AMD64_LINUX)
+
+mmt_ppc32_linux_SOURCES = $(MMT_SOURCES_COMMON)
+mmt_ppc32_linux_CPPFLAGS = $(AM_CPPFLAGS_PPC32_LINUX)
+mmt_ppc32_linux_CFLAGS = $(AM_CFLAGS_PPC32_LINUX)
+mmt_ppc32_linux_DEPENDENCIES = $(COREGRIND_LIBS_PPC32_LINUX)
+mmt_ppc32_linux_LDADD = $(TOOL_LDADD_PPC32_LINUX)
+mmt_ppc32_linux_LDFLAGS = $(TOOL_LDFLAGS_PPC32_LINUX)
+
+mmt_ppc64_linux_SOURCES = $(MMT_SOURCES_COMMON)
+mmt_ppc64_linux_CPPFLAGS = $(AM_CPPFLAGS_PPC64_LINUX)
+mmt_ppc64_linux_CFLAGS = $(AM_CFLAGS_PPC64_LINUX)
+mmt_ppc64_linux_DEPENDENCIES = $(COREGRIND_LIBS_PPC64_LINUX)
+mmt_ppc64_linux_LDADD = $(TOOL_LDADD_PPC64_LINUX)
+mmt_ppc64_linux_LDFLAGS = $(TOOL_LDFLAGS_PPC64_LINUX)
+
+mmtincludedir = $(includedir)/valgrind
diff --git a/mmt/mmt_main.c b/mmt/mmt_main.c
new file mode 100644
index 0000000..32bfb7a
--- /dev/null
+++ b/mmt/mmt_main.c
@@ -0,0 +1,385 @@
+/*
+ * vim:sw=3 ts=3 sts=3 noexpandtab
+ */
+
+/*--------------------------------------------------------------------*/
+/*--- mmaptrace: The mmaptracer tool. mmt_main.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2006 Dave Airlie
+
+ 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_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" // VG_(fnptr_to_fnentry)
+
+#define MAX_ITEMS 100
+
+static struct mmt_memmap {
+ Bool initialized;
+ Addr offset;
+ Addr addr;
+ SizeT len;
+} mmt_gpu_reg[MAX_ITEMS];
+
+static UInt current_item;
+
+static struct mmt_op {
+ Addr offset;
+ SizeT size;
+ UInt value;
+ ULong reps;
+ UInt store;
+} last_op;
+
+
+/* Command line options */
+UInt mmt_clo_offset = (UInt) -1;
+
+static struct mmt_memmap *find_mmap(Addr addr)
+{
+ struct mmt_memmap *ptr = NULL;
+ UInt i;
+
+ for (i = 0; i < MAX_ITEMS; i++) {
+ ptr = &mmt_gpu_reg[i];
+
+ if (!ptr->initialized) {
+ /* since we cannot un-init entries in the array,
+ * we can return once we hit the first uninitialized
+ * item -- there can't be initialized items following it.
+ */
+ return NULL;
+ }
+
+ if ((addr > ptr->addr) && (addr < ptr->addr + ptr->len))
+ return ptr;
+ }
+
+ return NULL;
+}
+
+static void
+print_op(void)
+{
+ int i;
+
+ if (last_op.reps > 5) {
+ VG_(printf)(" ... repeated %lu times total\n", last_op.reps);
+ }
+ else {
+ for (i = 0; i < last_op.reps; i++) {
+ VG_(printf)("%s: %p, %d, %p\n", last_op.store ? "store" : "load",
+ last_op.offset, last_op.size, last_op.value);
+ }
+ }
+}
+
+static VG_REGPARM(2) void
+trace_store(Addr addr, SizeT size, UInt value)
+{
+ struct mmt_memmap *ptr;
+
+ ptr = find_mmap(addr);
+ if (!ptr)
+ return;
+
+ if (last_op.offset != (addr - ptr->addr) || last_op.size != size ||
+ last_op.value != value || !last_op.store) {
+ print_op();
+
+ last_op.offset = addr - ptr->addr;
+ last_op.size = size;
+ last_op.value = value;
+ last_op.store = 1;
+ last_op.reps = 1;
+ }
+ else {
+ last_op.reps++;
+
+ if (last_op.reps % 1000 == 0)
+ VG_(printf)(" ... repeating: %d times\n", last_op.reps);
+ if (last_op.reps == ~0UL)
+ VG_(printf)(" ... overflow!\n");
+ }
+}
+
+static VG_REGPARM(2) void
+trace_load(Addr addr, SizeT size)
+{
+ struct mmt_memmap *ptr;
+ UInt value;
+
+ ptr = find_mmap(addr);
+ if (!ptr)
+ return;
+
+ switch (size) {
+ case 1:
+ value = *(UChar*) addr;
+ break;
+ case 2:
+ value = *(UShort*) addr;
+ break;
+ case 4:
+ value = *(UInt*) addr;
+ break;
+ case 8:
+ value = *(ULong*) addr;
+ default:
+ return;
+ }
+
+ if (last_op.offset != (addr - ptr->addr) || last_op.size != size ||
+ last_op.value != value || last_op.store) {
+ print_op();
+
+ last_op.offset = addr - ptr->addr;
+ last_op.size = size;
+ last_op.value = value;
+ last_op.store = 0;
+ last_op.reps = 1;
+ }
+ else {
+ last_op.reps++;
+
+ if (last_op.reps % 1000 == 0)
+ VG_(printf)(" ... repeating: %d times\n", last_op.reps);
+ if (last_op.reps == ~0UL)
+ VG_(printf)(" ... overflow!\n");
+ }
+}
+
+static void
+handle_load(IRSB* bb, IRExpr* addr, Int size)
+{
+ IRExpr** argv = mkIRExprVec_2(addr, mkIRExpr_HWord(size));
+ IRDirty* di = unsafeIRDirty_0_N(2,
+ "trace_load",
+ VG_(fnptr_to_fnentry)(trace_load),
+ argv);
+ addStmtToIRSB(bb, IRStmt_Dirty(di));
+}
+
+static void
+handle_store(IRSB*bb, IRExpr* addr, Int size, IRExpr* data)
+{
+ IRExpr** argv = mkIRExprVec_3(addr, mkIRExpr_HWord(size), data);
+ IRDirty* di = unsafeIRDirty_0_N(2,
+ "trace_store",
+ VG_(fnptr_to_fnentry)(trace_store),
+ argv);
+ addStmtToIRSB(bb, IRStmt_Dirty(di));
+}
+
+static IRSB*
+mmt_instrument(VgCallbackClosure* closure,
+ IRSB* bbIn,
+ VexGuestLayout* layout,
+ VexGuestExtents* vge,
+ IRType gWordTy, IRType hWordTy)
+{
+ IRSB* bbOut;
+ int i = 0;
+
+ if (gWordTy != hWordTy) {
+ /* We don't currently support this case. */
+ VG_(tool_panic)("host/guest word size mismatch");
+ }
+ if (gWordTy != Ity_I32 && gWordTy != Ity_I64) {
+ VG_(tool_panic)("word size must be 32 or 64 bits");
+ }
+
+ /* Set up BB */
+ bbOut = deepCopyIRSBExceptStmts(bbIn);
+
+ /* Copy verbatim any IR preamble preceding the first IMark */
+ while (i < bbIn->stmts_used && bbIn->stmts[i]->tag != Ist_IMark) {
+ addStmtToIRSB(bbOut, bbIn->stmts[i]);
+ i++;
+ }
+
+ for (; i < bbIn->stmts_used; i++) {
+ IRStmt* st = bbIn->stmts[i];
+ IRExpr* data_expr;
+ IRType arg_ty;
+ IRTemp t = IRTemp_INVALID;
+ IRStmt* cast = NULL;
+
+ if (!st)
+ continue;
+
+ if (st->tag == Ist_Store) {
+ arg_ty = typeOfIRExpr(bbIn->tyenv, st->Ist.Store.data);
+
+ data_expr = st->Ist.Store.data;
+
+ /* convert data_expr into a 64 bit value */
+ switch (arg_ty) {
+ case Ity_I8:
+ if (gWordTy == Ity_I32) {
+ t = newIRTemp(bbOut->tyenv, Ity_I32);
+ cast = IRStmt_WrTmp(t, IRExpr_Unop(Iop_8Uto32, data_expr));
+ }
+ else {
+ t = newIRTemp(bbOut->tyenv, Ity_I64);
+ cast = IRStmt_WrTmp(t, IRExpr_Unop(Iop_8Uto64, data_expr));
+ }
+ break;
+ case Ity_I16:
+ if (gWordTy == Ity_I32) {
+ t = newIRTemp(bbOut->tyenv, Ity_I32);
+ cast = IRStmt_WrTmp(t, IRExpr_Unop(Iop_16Uto32, data_expr));
+ }
+ else {
+ t = newIRTemp(bbOut->tyenv, Ity_I64);
+ cast = IRStmt_WrTmp(t, IRExpr_Unop(Iop_16Uto64, data_expr));
+ }
+ break;
+ case Ity_I32:
+ if (gWordTy == Ity_I64) {
+ t = newIRTemp(bbOut->tyenv, Ity_I64);
+ cast = IRStmt_WrTmp(t, IRExpr_Unop(Iop_32Uto64, data_expr));
+ }
+ break;
+ case Ity_I64:
+ if (gWordTy == Ity_I64) {
+ break;
+ }
+ default:
+ /* since we only support stores up to the guest word size, we
+ * will never have to evaluate the data_expr that this case
+ * generates.
+ */
+ if (gWordTy == Ity_I32) {
+ t = newIRTemp(bbOut->tyenv, Ity_I32);
+ cast = IRStmt_WrTmp(t, IRExpr_Const (IRConst_U32 (0)));
+ }
+ else {
+ t = newIRTemp(bbOut->tyenv, Ity_I64);
+ cast = IRStmt_WrTmp(t, IRExpr_Const (IRConst_U64 (0)));
+ }
+ break;
+ }
+
+ if (cast) {
+ addStmtToIRSB(bbOut, cast);
+ data_expr = IRExpr_RdTmp(t);
+ }
+
+ handle_store(bbOut, st->Ist.Store.addr,
+ sizeofIRType(arg_ty), data_expr);
+ } else if (st->tag == Ist_WrTmp) {
+ data_expr = st->Ist.WrTmp.data;
+
+ if (data_expr->tag == Iex_Load) {
+ handle_load(bbOut, data_expr->Iex.Load.addr,
+ sizeofIRType (data_expr->Iex.Load.ty));
+ }
+ }
+
+ addStmtToIRSB(bbOut, st);
+ }
+
+ return bbOut;
+}
+
+static Bool
+mmt_process_cmd_line_option(Char* arg)
+{
+ /* FIXME: make this argument mandatory */
+ VG_BHEX_CLO(arg, "--offset", mmt_clo_offset, 0, 0xffffffff)
+ else
+ return False;
+
+ VG_(message)(Vg_UserMsg, "set offset to %lx\n", mmt_clo_offset);
+
+ return True;
+}
+
+static void
+mmt_print_usage(void)
+{
+ VG_(printf)(" --offset=<number> (number must be in decimal!)\n");
+}
+
+static void
+mmt_print_debug_usage(void)
+{
+}
+
+static void
+mmt_new_mem_mmap(Addr a, SizeT len, Off64T offset, Bool rr, Bool ww, Bool xx)
+{
+ if (offset != mmt_clo_offset)
+ return;
+
+ mmt_gpu_reg[current_item].offset = offset;
+ mmt_gpu_reg[current_item].addr = a;
+ mmt_gpu_reg[current_item].len = len;
+ mmt_gpu_reg[current_item].initialized = True;
+ current_item++;
+
+ VG_(message)(Vg_UserMsg, "got new mmap for %p, len %d, offset %p\n", a, len, offset);
+}
+
+static void
+mmt_fini(Int exitcode)
+{
+}
+
+static void mmt_post_clo_init(void)
+{
+}
+
+static void
+mmt_pre_clo_init(void)
+{
+ VG_(details_name) ("mmaptrace");
+ VG_(details_version) (NULL);
+ VG_(details_description) ("an MMAP tracer");
+ VG_(details_copyright_author)(
+ "Copyright (C) 2006, and GNU GPL'd, by Dave Airlie.");
+ VG_(details_bug_reports_to) (VG_BUGS_TO);
+
+ VG_(basic_tool_funcs) (mmt_post_clo_init,
+ mmt_instrument,
+ mmt_fini);
+
+ VG_(needs_command_line_options)(mmt_process_cmd_line_option,
+ mmt_print_usage,
+ mmt_print_debug_usage);
+
+ VG_(track_new_mem_mmap) (mmt_new_mem_mmap);
+
+ last_op.offset = 0;
+ last_op.size = 0;
+ last_op.value = 0;
+ last_op.store = 0;
+ last_op.reps = 0;
+}
+
+VG_DETERMINE_INTERFACE_VERSION(mmt_pre_clo_init)
--
1.5.4.3