You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
|
|
|
|
1
(12) |
|
2
(6) |
3
(13) |
4
(9) |
5
(6) |
6
(8) |
7
(5) |
8
(5) |
|
9
(15) |
10
(18) |
11
(18) |
12
(18) |
13
(7) |
14
(11) |
15
(6) |
|
16
(12) |
17
(28) |
18
(15) |
19
(12) |
20
(17) |
21
(23) |
22
(10) |
|
23
(9) |
24
(11) |
25
(7) |
26
(21) |
27
(12) |
28
(6) |
29
(6) |
|
30
(8) |
|
|
|
|
|
|
|
From: <sv...@va...> - 2007-09-16 23:30:47
|
Author: sewardj Date: 2007-09-17 00:30:49 +0100 (Mon, 17 Sep 2007) New Revision: 6837 Log: Don't confuse this branch with the trunk. Modified: branches/THRCHECK/configure.in Modified: branches/THRCHECK/configure.in =================================================================== --- branches/THRCHECK/configure.in 2007-09-16 23:30:10 UTC (rev 6836) +++ branches/THRCHECK/configure.in 2007-09-16 23:30:49 UTC (rev 6837) @@ -8,7 +8,7 @@ ##------------------------------------------------------------## # Process this file with autoconf to produce a configure script. -AC_INIT(Valgrind, 3.3.0.SVN, val...@li...) +AC_INIT(Valgrind, 3.3.0.SVN-THRCHECK, val...@li...) AC_CONFIG_SRCDIR(coregrind/m_main.c) AM_CONFIG_HEADER(config.h) AM_INIT_AUTOMAKE |
|
From: <sv...@va...> - 2007-09-16 23:30:10
|
Author: sewardj
Date: 2007-09-17 00:30:10 +0100 (Mon, 17 Sep 2007)
New Revision: 6836
Log:
Rearrange thread checker suppressions for glibc 2.5, and add a bunch more.
Modified:
branches/THRCHECK/glibc-2.5.supp
Modified: branches/THRCHECK/glibc-2.5.supp
===================================================================
--- branches/THRCHECK/glibc-2.5.supp 2007-09-16 23:29:06 UTC (rev 6835)
+++ branches/THRCHECK/glibc-2.5.supp 2007-09-16 23:30:10 UTC (rev 6836)
@@ -217,110 +217,159 @@
##----------------------------------------------------------------------##
# Suppressions for the Thrcheck tool
+###--- ld.so stuff ---###
{
- thrcheck-glibc25-1
+ thrcheck-glibc25-ldso-1
Thrcheck:Race
fun:_dl_lookup_symbol_x
fun:_dl_fixup
fun:_dl_runtime_resolve
}
{
- thrcheck-glibc25-1.1
+ thrcheck-glibc25-ldso-2
Thrcheck:Race
fun:do_lookup_x
fun:_dl_lookup_symbol_x
fun:_dl_fixup
}
{
- thrcheck-glibc25-2
+ thrcheck-glibc25-ldso-3
Thrcheck:Race
+ fun:_dl_map_object_deps
+ fun:dl_open_worker
+ fun:_dl_catch_error
+}
+{
+ thrcheck-glibc25-ldso-4
+ Thrcheck:Race
+ fun:setup_direct
+ fun:_dl_map_object_deps
+ fun:dl_open_worker
+}
+{
+ thrcheck-glibc25-ldso-5
+ Thrcheck:Race
+ fun:_dl_map_object_from_fd
+ fun:_dl_map_object
+ fun:dl_open_worker
+}
+{
+ thrcheck-glibc25-ldso-6
+ Thrcheck:Race
+ fun:_dl_map_object
+ fun:dl_open_worker
+ fun:_dl_catch_error
+}
+
+###--- pthread_join ---###
+{
+ thrcheck-glibc25-pthjoin-1
+ Thrcheck:Race
fun:pthread_join
fun:pthread_join
}
{
- thrcheck-glibc25-3
+ thrcheck-glibc25-pthjoin-2
Thrcheck:Race
fun:__free_tcb
fun:pthread_join
fun:pthread_join
}
+
+###--- IO_file ---###
{
- thrcheck-glibc25-4
+ thrcheck-glibc25-IOfile-1
Thrcheck:Race
fun:_IO_file_xsputn*
fun:vfprintf
fun:*printf
}
{
- thrcheck-glibc25-5
+ thrcheck-glibc25-IOfile-2
Thrcheck:Race
fun:_IO_file_overflow*
fun:_IO_file_xsputn*
fun:*printf
}
{
- thrcheck-glibc25-6
+ thrcheck-glibc25-IOfile-3
Thrcheck:Race
- fun:vfprintf
- fun:printf
-}
-{
- thrcheck-glibc25-7
- Thrcheck:Race
fun:new_do_write
fun:_IO_do_write*
fun:_IO_file_xsputn*
fun:*printf
}
{
- thrcheck-glibc25-7a
+ thrcheck-glibc25-IOfile-4
Thrcheck:Race
fun:new_do_write
fun:_IO_file_xsputn*
fun:*printf
}
{
- thrcheck-glibc25-8
+ thrcheck-glibc25-IOfile-5
Thrcheck:Race
fun:new_do_write
fun:_IO_do_write*
fun:_IO_file_overflow*
fun:_IO_file_xsputn*
}
+
+###--- thread creation ---###
{
- thrcheck-glibc25-9
+ thrcheck-glibc25-creation-1
Thrcheck:Race
fun:start_thread
fun:clone
}
+
+###--- thread exit ---###
{
- thrcheck-glibc25-10
+ thrcheck-glibc25-exit-1
Thrcheck:Race
fun:_dl_fini
fun:exit
}
+###--- pthread_mutex_lock ---###
{
- thrcheck-wrappers-glibc-mutex_lock-1
+ thrcheck-glibc25-pthmxlock-1
Thrcheck:Race
fun:pthread_mutex_lock
fun:pthread_mutex_lock
}
+{
+ thrcheck-glibc25-pthmxlock-2
+ Thrcheck:Race
+ fun:__lll_mutex_lock_wait
+ fun:pthread_mutex_lock
+}
+###--- pthread_mutex_destroy ---###
{
- thrcheck-wrappers-glibc-create-1
+ thrcheck-glibc25-pthmxlock-2
Thrcheck:Race
+ fun:pthread_mutex_destroy
+ fun:pthread_mutex_destroy
+}
+
+###--- pthread_create ---###
+{
+ thrcheck-glibc25-pthcreate-1
+ Thrcheck:Race
fun:pthread_create@@GLIBC_*
fun:pthread_create@*
}
{
- thrcheck-wrappers-glibc-create-2
+ thrcheck-glibc25-pthcreate-2
Thrcheck:Race
fun:do_clone
fun:pthread_create@@GLIBC_*
fun:pthread_create@*
}
+###--- pthread_cond_signal ---###
+#
# This is very ugly. It is needed to suppress errors inside
# NPTL's pthread_cond_signal. Why only one stack frame --
# at least we should see the wrapper calling the real function,
@@ -329,37 +378,116 @@
# stack frame. Therefore it's only one level of unwinding before
# we're back out in user code rather than the 2 levels you'd expect.
{
- thrcheck-wrappers-glibc-cond_sig-1
+ thrcheck-glibc25-condsig-1
Thrcheck:Race
fun:pthread_cond_signal@@GLIBC_2.3.2
}
+###--- pthread_cond_broadcast ---###
# ditto
{
- thrcheck-wrappers-glibc-cond_wait-1
+ thrcheck-glibc25-condbcast-1
Thrcheck:Race
+ fun:pthread_cond_broadcast@@GLIBC_2.3.2
+}
+
+###--- pthread_cond_wait ---###
+# ditto
+{
+ thrcheck-glibc25-pthcondwait-1
+ Thrcheck:Race
fun:pthread_cond_wait@@GLIBC_2.3.2
}
+{
+ thrcheck-glibc25-pthcondwait-2
+ Thrcheck:Race
+ fun:pthread_cond_wait@@GLIBC_*
+ fun:pthread_cond_wait*
+}
+###--- pthread_mutex_trylock ---###
# ditto
{
- thrcheck-wrappers-glibc-mutex_trylock-1
+ thrcheck-glibc25-pthmxtrylock-1
Thrcheck:Race
fun:pthread_mutex_trylock
}
-
+###--- pthread_cond_timedwait ---###
{
- thrcheck-wrappers-glibc-cond_wait-1
+ thrcheck-glibc25-pthmxtimedwait-1
Thrcheck:Race
- fun:pthread_cond_wait@@GLIBC_*
- fun:pthread_cond_wait*
+ fun:pthread_cond_timedwait@@GLIBC_*
+ fun:pthread_cond_timedwait*
}
+{
+ thrcheck-glibc25-pthmxtimedwait-2
+ Thrcheck:Race
+ fun:__lll_mutex_lock_wait
+ fun:pthread_cond_timedwait@@GLIBC_*
+ fun:pthread_cond_timedwait*
+}
+###--- libpthread internal stuff ---###
{
- thrcheck-wrappers-1000
+ thrcheck-glibc25-libpthread-1
Thrcheck:Race
fun:__pthread_mutex_unlock_usercnt
fun:pthread_mutex_unlock
fun:pthread_mutex_unlock
}
+{
+ thrcheck-glibc25-libpthread-2
+ Thrcheck:Race
+ fun:__lll_mutex_unlock_wake
+ fun:_L_mutex_unlock_*
+ fun:__pthread_mutex_unlock_usercnt
+}
+{
+ thrcheck-glibc25-libpthread-3
+ Thrcheck:Race
+ fun:__lll_mutex_lock_wait
+ fun:_L_mutex_lock_*
+ fun:start_thread
+}
+{
+ thrcheck-glibc25-libpthread-4
+ Thrcheck:Race
+ fun:__lll_mutex_lock_wait
+ fun:_L_mutex_lock_*
+ fun:pthread_mutex_lock
+}
+{
+ thrcheck-glibc25-libpthread-5
+ Thrcheck:Race
+ fun:mythread_wrapper
+ fun:start_thread
+}
+{
+ thrcheck-glibc25-libpthread-6
+ Thrcheck:Race
+ fun:__deallocate_stack
+ fun:start_thread
+}
+{
+ thrcheck-glibc25-libpthread-7
+ Thrcheck:Race
+ fun:__deallocate_stack
+ fun:__free_tcb
+ fun:start_thread
+}
+{
+ thrcheck-glibc25-libpthread-8
+ Thrcheck:Race
+ fun:__deallocate_stack
+ fun:pthread_join
+ fun:pthread_join
+}
+
+###--- fork ---###
+{
+ thrcheck-glibc25-fork-1
+ Thrcheck:Race
+ fun:__reclaim_stacks
+ fun:fork
+}
|
|
From: <sv...@va...> - 2007-09-16 23:29:08
|
Author: sewardj
Date: 2007-09-17 00:29:06 +0100 (Mon, 17 Sep 2007)
New Revision: 6835
Log:
lame_strerror: handle ETIMEDOUT
Modified:
branches/THRCHECK/thrcheck/tc_intercepts.c
Modified: branches/THRCHECK/thrcheck/tc_intercepts.c
===================================================================
--- branches/THRCHECK/thrcheck/tc_intercepts.c 2007-09-16 22:43:41 UTC (rev 6834)
+++ branches/THRCHECK/thrcheck/tc_intercepts.c 2007-09-16 23:29:06 UTC (rev 6835)
@@ -118,8 +118,7 @@
threading errors (glibc goes off and does tons of crap w.r.t.
locales etc) */
static char* lame_strerror ( long err )
-{
- switch (err) {
+{ switch (err) {
case EPERM: return "EPERM: Operation not permitted";
case ENOENT: return "ENOENT: No such file or directory";
case ESRCH: return "ESRCH: No such process";
@@ -136,6 +135,7 @@
case EOVERFLOW: return "EOVERFLOW: Value too large "
"for defined data type";
case EBUSY: return "EBUSY: Device or resource busy";
+ case ETIMEDOUT: return "ETIMEDOUT: Connection timed out";
default: return "tc_intercepts.c: lame_strerror(): "
"unhandled case -- please fix me!";
}
|
|
From: <sv...@va...> - 2007-09-16 22:43:47
|
Author: njn
Date: 2007-09-16 23:43:41 +0100 (Sun, 16 Sep 2007)
New Revision: 6834
Log:
A few minor changes.
Modified:
branches/MASSIF2/massif/ms_main.c
branches/MASSIF2/massif/ms_print
Modified: branches/MASSIF2/massif/ms_main.c
===================================================================
--- branches/MASSIF2/massif/ms_main.c 2007-09-16 11:08:56 UTC (rev 6833)
+++ branches/MASSIF2/massif/ms_main.c 2007-09-16 22:43:41 UTC (rev 6834)
@@ -55,8 +55,7 @@
// #3: in-between
// - check every malloc, but not every new_mem_stack
//
-// Separate content from presentation by dumping all results to a file and
-// then post-processing with a separate program, a la Cachegrind?
+// Dumping the results to file:
// - work out the file format (Josef wants Callgrind format, Donna wants
// XML, Nick wants something easy to read in Perl)
// - allow truncation of long fnnames if the exact line number is
@@ -89,6 +88,8 @@
// - better sanity-checking should help this greatly
// 143062 cra massif crashes on app exit with signal 8 SIGFPE
// - occurs with no allocations -- ensure that case works
+// 144453 XXX
+// 146456 XXX
//
// Michael Meeks:
// - wants an interactive way to request a dump (callgrind_control-style)
@@ -110,6 +111,7 @@
// start-up and our first use of it. Could normalise versus our first
// use...
// - could conceivably remove XPts that have their szB reduced to zero.
+// - allow the output file name to be changed
//
// Docs:
// - need to explain that --alloc-fn changed slightly -- now if an entry
@@ -321,23 +323,12 @@
//--- Globals ---//
//------------------------------------------------------------//
-#define FILENAME_LEN 256
-
#define P VG_(printf)
-#define SPRINTF(zz_buf, fmt, args...) \
- do { Int len = VG_(sprintf)(zz_buf, fmt, ## args); \
- VG_(write)(fd, (void*)zz_buf, len); \
- } while (0)
-
-#define BUF_LEN 1024 // general purpose
-static Char buf [BUF_LEN];
-static Char buf2[BUF_LEN];
-
// Make these signed so things are more obvious if they go negative.
static SSizeT sigstacks_szB = 0; // Current signal stacks space sum
static SSizeT heap_szB = 0; // Live heap size
-static SSizeT peak_heap_szB = 0; // XXX: currently unused
+static SSizeT peak_heap_szB = 0; // XXX: currently unused
static SSizeT peak_snapshot_total_szB = 0;
static VgHashTable malloc_list = NULL; // HP_Chunks
@@ -345,7 +336,7 @@
static UInt n_heap_blocks = 0;
// Current directory at startup.
-static Char base_dir[VKI_PATH_MAX];
+static Char base_dir[VKI_PATH_MAX]; // XXX: currently unused
#define MAX_ALLOC_FNS 128 // includes the builtin ones
@@ -356,6 +347,12 @@
// operator new[](unsigned)
// operator new(unsigned, std::nothrow_t const&)
// operator new[](unsigned, std::nothrow_t const&)
+// [Dennis Lubert says these are also necessary on AMD64:
+// "operator new(unsigned long)",
+// "operator new[](unsigned long)",
+// "operator new(unsigned long, std::nothrow_t const&)",
+// "operator new[](unsigned long, std::nothrow_t const&)",
+// ]
// But someone might be interested in seeing them. If they're not, they can
// specify them with --alloc-fn.
static UInt n_alloc_fns = 6;
@@ -688,6 +685,9 @@
// Filter uninteresting entries out of the stack trace. n_ips is
// updated accordingly.
for (i = n_ips-1; i >= 0; i--) {
+ #define BUF_LEN 1024
+ Char buf[BUF_LEN];
+
if (VG_(get_fnname)(ips[i], buf, BUF_LEN)) {
// If it's a main-or-below-main function, we (may) want to
@@ -1388,8 +1388,11 @@
Int depth_str_len,
SizeT curr_heap_szB, SizeT curr_total_szB)
{
+ #define BUF_LEN 1024
Int i;
- Char* ip_desc, *perc;
+ Char* perc;
+ Char ip_desc_array[BUF_LEN];
+ Char* ip_desc = ip_desc_array;
SizeT printed_children_szB = 0;
Int n_sig_children;
Int n_insig_children;
@@ -1397,6 +1400,7 @@
// If the XPt has children, check that the sum of all their sizes equals
// the XPt's size.
+ // XXX: duplicates code from the sanity check?
if (xpt->n_children > 0) {
SizeT children_sum_szB = 0;
for (i = 0; i < xpt->n_children; i++) {
@@ -1425,7 +1429,7 @@
ip_desc =
"(heap allocation functions) malloc/new/new[], --alloc-fns, etc.";
} else {
- ip_desc = VG_(describe_IP)(xpt->ip-1, buf2, BUF_LEN);
+ ip_desc = VG_(describe_IP)(xpt->ip-1, ip_desc, BUF_LEN);
}
perc = make_perc(xpt->curr_szB, curr_total_szB);
P("%sn%d: %ld %s\n", depth_str, n_child_entries, xpt->curr_szB, ip_desc);
@@ -1490,6 +1494,7 @@
}
}
+// XXX: rename
static void write_detailed_snapshots(void)
{
Int i;
Modified: branches/MASSIF2/massif/ms_print
===================================================================
--- branches/MASSIF2/massif/ms_print 2007-09-16 11:08:56 UTC (rev 6833)
+++ branches/MASSIF2/massif/ms_print 2007-09-16 22:43:41 UTC (rev 6834)
@@ -118,7 +118,7 @@
# Input file name
my $input_file = undef;
-# Version number XXX
+# Version number
my $version = "XXX";
# Usage message.
@@ -227,33 +227,70 @@
return equals_num_line($line, $fieldname);
}
+sub is_significant_XPt($$)
+{
+ my ($xpt_szB, $total_szB) = @_;
+ ($xpt_szB <= $total_szB) or die;
+ return ( $xpt_szB * 100 / $total_szB >= $threshold ? 1 : 0 );
+}
+
# Forward declaration, because it's recursive.
sub read_heap_tree($$$$$);
+# Return pair: if the tree was significant, both are zero. If it was
+# insignificant, the first element is 1 and the second is the number of
+# bytes.
sub read_heap_tree($$$$$)
{
- # We precede this node's line with "$this_prefix.$arrow". We precede
- # any children of this node with "$this_prefix$child_midfix$arrow".
+ # Read the line and determine if it is significant.
my ($print, $this_prefix, $child_midfix, $arrow, $mem_total_B) = @_;
my $line = get_line();
(defined $line and $line =~ /^\s*n(\d+):\s*(\d+)(.*)$/)
or die("Line $.: expected a tree node line, got:\n$line\n");
- my $n = $1;
- my $bytes = $2;
- my $details = $3;
- my $perc = 100 * $bytes / $mem_total_B;
- printf("$this_prefix$arrow%05.2f%% (${bytes}B)$details\n", $perc)
- if $print;
- for (my $i = 0; $i < $n; $i++) {
- my $this_prefix2 = $this_prefix . $child_midfix;
+ my $n_children = $1;
+ my $bytes = $2;
+ my $details = $3;
+ my $perc = 100 * $bytes / $mem_total_B;
+ my $is_significant = is_significant_XPt($bytes, $mem_total_B);
+
+ # We precede this node's line with "$this_prefix.$arrow". We precede
+ # any children of this node with "$this_prefix$child_midfix$arrow".
+ if ($print && $is_significant) {
+ printf("$this_prefix$arrow%05.2f%% $is_significant(${bytes}B)$details\n", $perc);
+ }
+
+ # Now read all the children.
+ my $n_insig_children = 0;
+ my $total_insig_children_szB = 0;
+ my $this_prefix2 = $this_prefix . $child_midfix;
+ for (my $i = 0; $i < $n_children; $i++) {
# If child is the last sibling, the midfix is empty.
- my $child_midfix2 = ( $i+1 == $n ? " " : "| " );
- read_heap_tree($print, $this_prefix2, $child_midfix2, "->",
- $mem_total_B);
+ my $child_midfix2 = ( $i+1 == $n_children ? " " : "| " );
+ my ($is_child_insignificant, $child_insig_bytes) =
+ read_heap_tree($print, $this_prefix2, $child_midfix2, "->",
+ $mem_total_B);
+ $n_insig_children += $is_child_insignificant;
+ $total_insig_children_szB += $child_insig_bytes;
}
- # If this node has no children, print an extra empty line.
- if (0 == $n) {
- print("$this_prefix\n") if $print;
+
+ if ($is_significant) {
+ # If this was significant but any children were insignificant, print
+ # an "insignificant" line for them.
+ if ($print && $n_insig_children > 0) {
+ $perc = 100 * $total_insig_children_szB / $mem_total_B;
+ printf("$this_prefix2->%05.2f%% (${total_insig_children_szB}B) ... $n_insig_children insig...\n",
+ $perc);
+ print("$this_prefix2\n");
+ }
+
+ # If this node has no children, print an extra empty line.
+ if ($print && 0 == $n_children) {
+ print("$this_prefix\n");
+ }
+ return (0, 0);
+
+ } else {
+ return (1, $bytes);
}
}
@@ -343,7 +380,7 @@
# Row 0 ([0..GRAPH_X][0]) is the x-axis.
# Column 0 ([0][0..GRAPH_Y]) is the y-axis.
# The rest ([1][1]..[GRAPH_X][GRAPH_Y]) is the usable graph area.
- my $GRAPH_X = 72;
+ my $GRAPH_X = 72; # Make these command-line options
my $GRAPH_Y = 20;
my @graph;
my $x;
|
|
From: <js...@ac...> - 2007-09-16 12:53:12
|
Nightly build on minnie ( SuSE 10.0, ppc32 ) started at 2007-09-16 09:00:01 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 220 tests, 10 stderr failures, 6 stdout failures, 0 posttest failures == memcheck/tests/leak-tree (stderr) memcheck/tests/leakotron (stdout) memcheck/tests/pointer-trace (stderr) memcheck/tests/stack_changes (stderr) memcheck/tests/xml1 (stderr) none/tests/faultstatus (stderr) none/tests/fdleak_cmsg (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) none/tests/ppc32/jm-fp (stdout) none/tests/ppc32/jm-fp (stderr) none/tests/ppc32/round (stdout) none/tests/ppc32/round (stderr) none/tests/ppc32/test_fx (stdout) none/tests/ppc32/test_fx (stderr) none/tests/ppc32/test_gx (stdout) |
|
From: <sv...@va...> - 2007-09-16 11:08:54
|
Author: sewardj
Date: 2007-09-16 12:08:56 +0100 (Sun, 16 Sep 2007)
New Revision: 6833
Log:
Track vex r1789 (add IR notification of hardware bus lock/unlock).
* Remove tool handling of IRStmt_MFence and replace by IRStmt_MBE
* In Thrcheck, generate calls to evim__bus_lock/unlock when
IRStmt_MBE(BusLock/BusUnlock) are observed. This provides at least
partially correct handling for x86/amd64 LOCK prefixed instructions.
Modified:
branches/THRCHECK/cachegrind/cg_main.c
branches/THRCHECK/callgrind/main.c
branches/THRCHECK/lackey/lk_main.c
branches/THRCHECK/memcheck/mc_translate.c
branches/THRCHECK/thrcheck/tc_main.c
branches/THRCHECK/thrcheck/tests/tc08_hbl2.stdout.exp
Modified: branches/THRCHECK/cachegrind/cg_main.c
===================================================================
--- branches/THRCHECK/cachegrind/cg_main.c 2007-09-14 09:06:43 UTC (rev 6832)
+++ branches/THRCHECK/cachegrind/cg_main.c 2007-09-16 11:08:56 UTC (rev 6833)
@@ -952,7 +952,7 @@
case Ist_AbiHint:
case Ist_Put:
case Ist_PutI:
- case Ist_MFence:
+ case Ist_MBE:
break;
case Ist_IMark:
Modified: branches/THRCHECK/callgrind/main.c
===================================================================
--- branches/THRCHECK/callgrind/main.c 2007-09-14 09:06:43 UTC (rev 6832)
+++ branches/THRCHECK/callgrind/main.c 2007-09-16 11:08:56 UTC (rev 6833)
@@ -468,7 +468,7 @@
case Ist_Put:
case Ist_PutI:
- case Ist_MFence:
+ case Ist_MBE:
case Ist_Exit:
break;
Modified: branches/THRCHECK/lackey/lk_main.c
===================================================================
--- branches/THRCHECK/lackey/lk_main.c 2007-09-14 09:06:43 UTC (rev 6832)
+++ branches/THRCHECK/lackey/lk_main.c 2007-09-16 11:08:56 UTC (rev 6833)
@@ -670,7 +670,7 @@
case Ist_AbiHint:
case Ist_Put:
case Ist_PutI:
- case Ist_MFence:
+ case Ist_MBE:
addStmtToIRSB( sbOut, st );
break;
Modified: branches/THRCHECK/memcheck/mc_translate.c
===================================================================
--- branches/THRCHECK/memcheck/mc_translate.c 2007-09-14 09:06:43 UTC (rev 6832)
+++ branches/THRCHECK/memcheck/mc_translate.c 2007-09-16 11:08:56 UTC (rev 6833)
@@ -3290,7 +3290,7 @@
return isBogusAtom(st->Ist.AbiHint.base);
case Ist_NoOp:
case Ist_IMark:
- case Ist_MFence:
+ case Ist_MBE:
return False;
default:
unhandled:
@@ -3470,7 +3470,7 @@
case Ist_NoOp:
case Ist_IMark:
- case Ist_MFence:
+ case Ist_MBE:
break;
case Ist_Dirty:
Modified: branches/THRCHECK/thrcheck/tc_main.c
===================================================================
--- branches/THRCHECK/thrcheck/tc_main.c 2007-09-14 09:06:43 UTC (rev 6832)
+++ branches/THRCHECK/thrcheck/tc_main.c 2007-09-16 11:08:56 UTC (rev 6833)
@@ -3565,6 +3565,35 @@
}
+static void instrument_memory_bus_event ( IRSB* bbOut, IRMBusEvent event )
+{
+ switch (event) {
+ case Imbe_Fence:
+ break; /* not interesting */
+ case Imbe_BusLock:
+ case Imbe_BusUnlock:
+ addStmtToIRSB(
+ bbOut,
+ IRStmt_Dirty(
+ unsafeIRDirty_0_N(
+ 0/*regparms*/,
+ event == Imbe_BusLock ? "evim__bus_lock"
+ : "evim__bus_unlock",
+ VG_(fnptr_to_fnentry)(
+ event == Imbe_BusLock ? &evim__bus_lock
+ : &evim__bus_unlock
+ ),
+ mkIRExprVec_0()
+ )
+ )
+ );
+ break;
+ default:
+ tl_assert(0);
+ }
+ }
+
+
static
IRSB* tc_instrument ( VgCallbackClosure* closure,
IRSB* bbIn,
@@ -3602,12 +3631,15 @@
case Ist_AbiHint:
case Ist_Put:
case Ist_PutI:
- case Ist_MFence:
case Ist_IMark:
case Ist_Exit:
/* None of these can contain any memory references. */
break;
+ case Ist_MBE:
+ instrument_memory_bus_event( bbOut, st->Ist.MBE.event );
+ break;
+
case Ist_Store:
instrument_mem_access(
bbOut,
@@ -3725,7 +3757,7 @@
if (0)
VG_(printf)("SET_MY_PTHREAD_T (tid %d): pthread_t = %p\n", (Int)tid,
(void*)args[1]);
- map_pthread_t_to_Thread_INIT();
+ map_pthread_t_to_Thread_INIT();
my_thr = map_threads_maybe_lookup( tid );
/* This assertion should hold because the map_threads (tid to
Thread*) binding should have been made at the point of
@@ -3762,7 +3794,7 @@
if (0)
VG_(printf)("NOTIFY_JOIN_COMPLETE (tid %d): quitter = %p\n", (Int)tid,
(void*)args[1]);
- map_pthread_t_to_Thread_INIT();
+ map_pthread_t_to_Thread_INIT();
found = TC_(lookupFM)( map_pthread_t_to_Thread,
NULL, (Word*)&thr_q, (Word)args[1] );
/* Can this fail? It would mean that our pthread_join
@@ -3824,7 +3856,7 @@
break;
/* Thread successfully completed pthread_cond_wait, cond=arg[1],
- mutex=arg[2] */
+ mutex=arg[2] */
case _VG_USERREQ__TC_PTHREAD_COND_WAIT_POST:
evim__TC_PTHREAD_COND_WAIT_POST( tid,
(void*)args[1], (void*)args[2] );
Modified: branches/THRCHECK/thrcheck/tests/tc08_hbl2.stdout.exp
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc08_hbl2.stdout.exp 2007-09-14 09:06:43 UTC (rev 6832)
+++ branches/THRCHECK/thrcheck/tests/tc08_hbl2.stdout.exp 2007-09-16 11:08:56 UTC (rev 6833)
@@ -1,10 +1,3 @@
-child: new value 1
-child: new value 2
-child: new value 3
-child: new value 4
-child: new value 5
child: new value 6
-child: new value 7
-child: new value 8
-child: new value 9
child: new value 10
+done, x = 10
|
|
From: <sv...@va...> - 2007-09-16 11:04:32
|
Author: sewardj
Date: 2007-09-16 12:04:24 +0100 (Sun, 16 Sep 2007)
New Revision: 1789
Log:
Changes to facilitate passing x86/amd64 LOCK prefixes through to
Valgrind tools:
* Generalise IRStmt_MFence to IRStmt_MBE ("memory bus event"), so
the IR can carry not only notifications of memory fences, but also
of notional hardware bus locks / unlocks
* Generate these in the amd64->IR front end
* Generate these in the x86->IR front end, and tidy up messy handling
of instruction prefixes in general -- make it a bit more like how the
amd64->IR front end handles prefixes
No equivalent changes to the ppc->IR front ends since the lwarx/stwcx.
methodology for atomic memory changes does not fit this model.
Modified:
branches/THRCHECK/priv/guest-amd64/toIR.c
branches/THRCHECK/priv/guest-ppc/toIR.c
branches/THRCHECK/priv/guest-x86/toIR.c
branches/THRCHECK/priv/host-amd64/isel.c
branches/THRCHECK/priv/host-ppc/isel.c
branches/THRCHECK/priv/host-x86/isel.c
branches/THRCHECK/priv/ir/irdefs.c
branches/THRCHECK/priv/ir/iropt.c
branches/THRCHECK/pub/libvex_ir.h
Modified: branches/THRCHECK/priv/guest-amd64/toIR.c
===================================================================
--- branches/THRCHECK/priv/guest-amd64/toIR.c 2007-09-09 19:38:48 UTC (rev 1788)
+++ branches/THRCHECK/priv/guest-amd64/toIR.c 2007-09-16 11:04:24 UTC (rev 1789)
@@ -1963,7 +1963,7 @@
/*------------------------------------------------------------*/
static
-HChar* sorbTxt ( Prefix pfx )
+HChar* segRegTxt ( Prefix pfx )
{
if (pfx & PFX_CS) return "%cs:";
if (pfx & PFX_DS) return "%ds:";
@@ -2115,7 +2115,7 @@
case 0x00: case 0x01: case 0x02: case 0x03:
/* ! 04 */ /* ! 05 */ case 0x06: case 0x07:
{ UChar rm = toUChar(mod_reg_rm & 7);
- DIS(buf, "%s(%s)", sorbTxt(pfx), nameIRegRexB(8,pfx,rm));
+ DIS(buf, "%s(%s)", segRegTxt(pfx), nameIRegRexB(8,pfx,rm));
*len = 1;
return disAMode_copy2tmp(
handleAddrOverrides(pfx, getIRegRexB(8,pfx,rm)));
@@ -2129,9 +2129,9 @@
{ UChar rm = toUChar(mod_reg_rm & 7);
Long d = getSDisp8(delta);
if (d == 0) {
- DIS(buf, "%s(%s)", sorbTxt(pfx), nameIRegRexB(8,pfx,rm));
+ DIS(buf, "%s(%s)", segRegTxt(pfx), nameIRegRexB(8,pfx,rm));
} else {
- DIS(buf, "%s%lld(%s)", sorbTxt(pfx), d, nameIRegRexB(8,pfx,rm));
+ DIS(buf, "%s%lld(%s)", segRegTxt(pfx), d, nameIRegRexB(8,pfx,rm));
}
*len = 2;
return disAMode_copy2tmp(
@@ -2146,7 +2146,7 @@
/* ! 14 */ case 0x15: case 0x16: case 0x17:
{ UChar rm = toUChar(mod_reg_rm & 7);
Long d = getSDisp32(delta);
- DIS(buf, "%s%lld(%s)", sorbTxt(pfx), d, nameIRegRexB(8,pfx,rm));
+ DIS(buf, "%s%lld(%s)", segRegTxt(pfx), d, nameIRegRexB(8,pfx,rm));
*len = 5;
return disAMode_copy2tmp(
handleAddrOverrides(pfx,
@@ -2164,7 +2164,7 @@
case 0x05:
{ Long d = getSDisp32(delta);
*len = 5;
- DIS(buf, "%s%lld(%%rip)", sorbTxt(pfx), d);
+ DIS(buf, "%s%lld(%%rip)", segRegTxt(pfx), d);
/* We need to know the next instruction's start address.
Try and figure out what it is, record the guess, and ask
the top-level driver logic (bbToIR_AMD64) to check we
@@ -2207,11 +2207,11 @@
if ((!index_is_SP) && (!base_is_BPor13)) {
if (scale == 0) {
- DIS(buf, "%s(%s,%s)", sorbTxt(pfx),
+ DIS(buf, "%s(%s,%s)", segRegTxt(pfx),
nameIRegRexB(8,pfx,base_r),
nameIReg64rexX(pfx,index_r));
} else {
- DIS(buf, "%s(%s,%s,%d)", sorbTxt(pfx),
+ DIS(buf, "%s(%s,%s,%d)", segRegTxt(pfx),
nameIRegRexB(8,pfx,base_r),
nameIReg64rexX(pfx,index_r), 1<<scale);
}
@@ -2227,7 +2227,7 @@
if ((!index_is_SP) && base_is_BPor13) {
Long d = getSDisp32(delta);
- DIS(buf, "%s%lld(,%s,%d)", sorbTxt(pfx), d,
+ DIS(buf, "%s%lld(,%s,%d)", segRegTxt(pfx), d,
nameIReg64rexX(pfx,index_r), 1<<scale);
*len = 6;
return
@@ -2240,7 +2240,7 @@
}
if (index_is_SP && (!base_is_BPor13)) {
- DIS(buf, "%s(%s)", sorbTxt(pfx), nameIRegRexB(8,pfx,base_r));
+ DIS(buf, "%s(%s)", segRegTxt(pfx), nameIRegRexB(8,pfx,base_r));
*len = 2;
return disAMode_copy2tmp(
handleAddrOverrides(pfx, getIRegRexB(8,pfx,base_r)));
@@ -2248,7 +2248,7 @@
if (index_is_SP && base_is_BPor13) {
Long d = getSDisp32(delta);
- DIS(buf, "%s%lld", sorbTxt(pfx), d);
+ DIS(buf, "%s%lld", segRegTxt(pfx), d);
*len = 6;
return disAMode_copy2tmp(
handleAddrOverrides(pfx, mkU64(d)));
@@ -2274,7 +2274,7 @@
Long d = getSDisp8(delta+1);
if (index_r == R_RSP && 0==getRexX(pfx)) {
- DIS(buf, "%s%lld(%s)", sorbTxt(pfx),
+ DIS(buf, "%s%lld(%s)", segRegTxt(pfx),
d, nameIRegRexB(8,pfx,base_r));
*len = 3;
return disAMode_copy2tmp(
@@ -2282,11 +2282,11 @@
binop(Iop_Add64, getIRegRexB(8,pfx,base_r), mkU64(d)) ));
} else {
if (scale == 0) {
- DIS(buf, "%s%lld(%s,%s)", sorbTxt(pfx), d,
+ DIS(buf, "%s%lld(%s,%s)", segRegTxt(pfx), d,
nameIRegRexB(8,pfx,base_r),
nameIReg64rexX(pfx,index_r));
} else {
- DIS(buf, "%s%lld(%s,%s,%d)", sorbTxt(pfx), d,
+ DIS(buf, "%s%lld(%s,%s,%d)", segRegTxt(pfx), d,
nameIRegRexB(8,pfx,base_r),
nameIReg64rexX(pfx,index_r), 1<<scale);
}
@@ -2321,7 +2321,7 @@
Long d = getSDisp32(delta+1);
if (index_r == R_RSP && 0==getRexX(pfx)) {
- DIS(buf, "%s%lld(%s)", sorbTxt(pfx),
+ DIS(buf, "%s%lld(%s)", segRegTxt(pfx),
d, nameIRegRexB(8,pfx,base_r));
*len = 6;
return disAMode_copy2tmp(
@@ -2329,11 +2329,11 @@
binop(Iop_Add64, getIRegRexB(8,pfx,base_r), mkU64(d)) ));
} else {
if (scale == 0) {
- DIS(buf, "%s%lld(%s,%s)", sorbTxt(pfx), d,
+ DIS(buf, "%s%lld(%s,%s)", segRegTxt(pfx), d,
nameIRegRexB(8,pfx,base_r),
nameIReg64rexX(pfx,index_r));
} else {
- DIS(buf, "%s%lld(%s,%s,%d)", sorbTxt(pfx), d,
+ DIS(buf, "%s%lld(%s,%s,%d)", segRegTxt(pfx), d,
nameIRegRexB(8,pfx,base_r),
nameIReg64rexX(pfx,index_r), 1<<scale);
}
@@ -8299,6 +8299,96 @@
}
+/* Helper for deciding whether a given insn (starting at the opcode
+ byte) may validly be used with a LOCK prefix. The following insns
+ may be used with LOCK when their destination operand is in memory.
+ Note, this is slightly too permissive. Oh well. Note also, AFAICS
+ this is exactly the same for both 32-bit and 64-bit mode.
+
+ ADD 80 /0, 81 /0, 83 /0, 00, 01, 02, 03
+ OR 80 /1, 81 /1, 83 /1, 08, 09, 0A, 0B
+ ADC 80 /2, 81 /2, 83 /2, 10, 11, 12, 13
+ SBB 81 /3, 81 /3, 83 /3, 18, 19, 1A, 1B
+ AND 80 /4, 81 /4, 83 /4, 20, 21, 22, 23
+ SUB 80 /5, 81 /5, 83 /5, 28, 29, 2A, 2B
+ XOR 80 /6, 81 /6, 83 /6, 30, 31, 32, 33
+
+ DEC FE /1, FF /1
+ INC FE /0, FF /0
+
+ NEG F6 /3, F7 /3
+ NOT F6 /2, F7 /2
+
+ XCHG 86, 87
+
+ BTC 0F BB, 0F BA /7
+ BTR 0F B3, 0F BA /6
+ BTS 0F AB, 0F BA /5
+
+ CMPXCHG 0F B0, 0F B1
+ CMPXCHG8B 0F C7 /1
+
+ XADD 0F C0, 0F C1
+*/
+static Bool can_be_used_with_LOCK_prefix ( UChar* opc )
+{
+ switch (opc[0]) {
+ case 0x00: case 0x01: case 0x02: case 0x03: return True;
+ case 0x08: case 0x09: case 0x0A: case 0x0B: return True;
+ case 0x10: case 0x11: case 0x12: case 0x13: return True;
+ case 0x18: case 0x19: case 0x1A: case 0x1B: return True;
+ case 0x20: case 0x21: case 0x22: case 0x23: return True;
+ case 0x28: case 0x29: case 0x2A: case 0x2B: return True;
+ case 0x30: case 0x31: case 0x32: case 0x33: return True;
+
+ case 0x80: case 0x81: case 0x83:
+ if (gregLO3ofRM(opc[1]) >= 0 && gregLO3ofRM(opc[1]) <= 6)
+ return True;
+ break;
+
+ case 0xFE: case 0xFF:
+ if (gregLO3ofRM(opc[1]) >= 0 && gregLO3ofRM(opc[1]) <= 1)
+ return True;
+ break;
+
+ case 0xF6: case 0xF7:
+ if (gregLO3ofRM(opc[1]) >= 2 && gregLO3ofRM(opc[1]) <= 3)
+ return True;
+ break;
+
+ case 0x86: case 0x87:
+ return True;
+
+ case 0x0F: {
+ switch (opc[1]) {
+ case 0xBB: case 0xB3: case 0xAB:
+ return True;
+ case 0xBA:
+ if (gregLO3ofRM(opc[2]) >= 5 && gregLO3ofRM(opc[2]) <= 7)
+ return True;
+ break;
+ case 0xB0: case 0xB1:
+ return True;
+ case 0xC7:
+ if (gregLO3ofRM(opc[2]) == 1)
+ return True;
+ break;
+ case 0xC0: case 0xC1:
+ return True;
+ default:
+ break;
+ } /* switch (opc[1]) */
+ break;
+ }
+
+ default:
+ break;
+ } /* switch (opc[0]) */
+
+ return False;
+}
+
+
/*------------------------------------------------------------*/
/*--- Disassemble a single instruction ---*/
/*------------------------------------------------------------*/
@@ -8341,6 +8431,9 @@
/* pfx holds the summary of prefixes. */
Prefix pfx = PFX_EMPTY;
+ /* do we need follow the insn with MBusEvent(BusUnlock) ? */
+ Bool unlock_bus_after_insn = False;
+
/* Set result defaults. */
dres.whatNext = Dis_Continue;
dres.len = 0;
@@ -8477,17 +8570,40 @@
/* Kludge re LOCK prefixes. We assume here that all code generated
by Vex is going to be run in a single-threaded context, in other
words that concurrent executions of Vex-generated translations
- will not happen. That is certainly the case for how the
- Valgrind-3.0 code line uses Vex. Given that assumption, it
- seems safe to ignore LOCK prefixes since there will never be any
- other thread running at the same time as this one. However, at
- least emit a memory fence on the basis that it would at least be
- prudent to flush any memory transactions from this thread as far
- as possible down the memory hierarchy. */
+ will not happen. So we don't need to worry too much about
+ preserving atomicity. However, mark the fact that the notional
+ hardware bus lock is being acquired (and, after the insn,
+ released), so that thread checking tools know this is a locked
+ insn.
+
+ We check for, and immediately reject, (most) inappropriate uses
+ of the LOCK prefix. Later (at decode_failure: and
+ decode_success:), if we've added a BusLock event, then we will
+ follow up with a BusUnlock event. How do we know execution will
+ actually ever get to the BusUnlock event? Because
+ can_be_used_with_LOCK_prefix rejects all control-flow changing
+ instructions.
+
+ One loophole, though: if a LOCK prefix insn (seg)faults, then
+ the BusUnlock event will never be reached. This could cause
+ tools which track bus hardware lock to lose track. Really, we
+ should explicitly release the lock after every insn, but that's
+ obviously way too expensive. Really, any tool which tracks the
+ state of the bus lock needs to ask V's core/tool interface to
+ notify it of signal deliveries. On delivery of SIGSEGV to the
+ guest, the tool will be notified, in which case it should
+ release the bus hardware lock if it is held.
+
+ Note, guest-x86/toIR.c contains identical logic.
+ */
if (pfx & PFX_LOCK) {
- /* vex_printf("vex amd64->IR: ignoring LOCK prefix on: ");
- insn_verbose = True; */
- stmt( IRStmt_MFence() );
+ if (can_be_used_with_LOCK_prefix( (UChar*)&guest_code[delta] )) {
+ stmt( IRStmt_MBE(Imbe_BusLock) );
+ unlock_bus_after_insn = True;
+ DIP("lock ");
+ } else {
+ goto decode_failure;
+ }
}
@@ -9536,7 +9652,7 @@
delta += 3;
/* Insert a memory fence. It's sometimes important that these
are carried through to the generated code. */
- stmt( IRStmt_MFence() );
+ stmt( IRStmt_MBE(Imbe_Fence) );
DIP("sfence\n");
goto decode_success;
}
@@ -10313,7 +10429,7 @@
delta += 3;
/* Insert a memory fence. It's sometimes important that these
are carried through to the generated code. */
- stmt( IRStmt_MFence() );
+ stmt( IRStmt_MBE(Imbe_Fence) );
DIP("%sfence\n", gregLO3ofRM(insn[2])==5 ? "l" : "m");
goto decode_success;
}
@@ -12763,7 +12879,7 @@
assign( addr, handleAddrOverrides(pfx, mkU64(d64)) );
putIRegRAX(sz, loadLE( ty, mkexpr(addr) ));
DIP("mov%c %s0x%llx, %s\n", nameISize(sz),
- sorbTxt(pfx), d64,
+ segRegTxt(pfx), d64,
nameIRegRAX(sz));
break;
@@ -12781,7 +12897,7 @@
assign( addr, handleAddrOverrides(pfx, mkU64(d64)) );
storeLE( mkexpr(addr), getIRegRAX(sz) );
DIP("mov%c %s, %s0x%llx\n", nameISize(sz), nameIRegRAX(sz),
- sorbTxt(pfx), d64);
+ segRegTxt(pfx), d64);
break;
/* XXXX be careful here with moves to AH/BH/CH/DH */
@@ -14136,7 +14252,7 @@
stmt( IRStmt_Dirty(d) );
/* CPUID is a serialising insn. So, just in case someone is
using it as a memory fence ... */
- stmt( IRStmt_MFence() );
+ stmt( IRStmt_MBE(Imbe_Fence) );
DIP("cpuid\n");
break;
}
@@ -14500,6 +14616,8 @@
insn, but nevertheless be paranoid and update it again right
now. */
stmt( IRStmt_Put( OFFB_RIP, mkU64(guest_RIP_curr_instr) ) );
+ if (unlock_bus_after_insn)
+ stmt( IRStmt_MBE(Imbe_BusUnlock) );
jmp_lit(Ijk_NoDecode, guest_RIP_curr_instr);
dres.whatNext = Dis_StopHere;
dres.len = 0;
@@ -14510,6 +14628,8 @@
decode_success:
/* All decode successes end up here. */
DIP("\n");
+ if (unlock_bus_after_insn)
+ stmt( IRStmt_MBE(Imbe_BusUnlock) );
dres.len = (Int)toUInt(delta - delta_start);
return dres;
}
Modified: branches/THRCHECK/priv/guest-ppc/toIR.c
===================================================================
--- branches/THRCHECK/priv/guest-ppc/toIR.c 2007-09-09 19:38:48 UTC (rev 1788)
+++ branches/THRCHECK/priv/guest-ppc/toIR.c 2007-09-16 11:04:24 UTC (rev 1789)
@@ -4816,7 +4816,7 @@
return False;
}
DIP("isync\n");
- stmt( IRStmt_MFence() );
+ stmt( IRStmt_MBE(Imbe_Fence) );
break;
/* X-Form */
@@ -4829,7 +4829,7 @@
}
DIP("eieio\n");
/* Insert a memory fence, just to be on the safe side. */
- stmt( IRStmt_MFence() );
+ stmt( IRStmt_MBE(Imbe_Fence) );
break;
case 0x014: // lwarx (Load Word and Reserve Indexed, PPC32 p458)
@@ -4918,7 +4918,7 @@
DIP("%ssync\n", flag_L == 1 ? "lw" : "");
/* Insert a memory fence. It's sometimes important that these
are carried through to the generated code. */
- stmt( IRStmt_MFence() );
+ stmt( IRStmt_MBE(Imbe_Fence) );
break;
/* 64bit Memsync */
@@ -5662,7 +5662,7 @@
putGST( PPC_GST_TILEN, mkSzImm(ty, lineszB) );
/* be paranoid ... */
- stmt( IRStmt_MFence() );
+ stmt( IRStmt_MBE(Imbe_Fence) );
irsb->jumpkind = Ijk_TInval;
irsb->next = mkSzImm(ty, nextInsnAddr());
Modified: branches/THRCHECK/priv/guest-x86/toIR.c
===================================================================
--- branches/THRCHECK/priv/guest-x86/toIR.c 2007-09-09 19:38:48 UTC (rev 1788)
+++ branches/THRCHECK/priv/guest-x86/toIR.c 2007-09-16 11:04:24 UTC (rev 1789)
@@ -7136,6 +7136,96 @@
}
+/* Helper for deciding whether a given insn (starting at the opcode
+ byte) may validly be used with a LOCK prefix. The following insns
+ may be used with LOCK when their destination operand is in memory.
+ Note, this is slightly too permissive. Oh well. Note also, AFAICS
+ this is exactly the same for both 32-bit and 64-bit mode.
+
+ ADD 80 /0, 81 /0, 83 /0, 00, 01, 02, 03
+ OR 80 /1, 81 /1, 83 /1, 08, 09, 0A, 0B
+ ADC 80 /2, 81 /2, 83 /2, 10, 11, 12, 13
+ SBB 81 /3, 81 /3, 83 /3, 18, 19, 1A, 1B
+ AND 80 /4, 81 /4, 83 /4, 20, 21, 22, 23
+ SUB 80 /5, 81 /5, 83 /5, 28, 29, 2A, 2B
+ XOR 80 /6, 81 /6, 83 /6, 30, 31, 32, 33
+
+ DEC FE /1, FF /1
+ INC FE /0, FF /0
+
+ NEG F6 /3, F7 /3
+ NOT F6 /2, F7 /2
+
+ XCHG 86, 87
+
+ BTC 0F BB, 0F BA /7
+ BTR 0F B3, 0F BA /6
+ BTS 0F AB, 0F BA /5
+
+ CMPXCHG 0F B0, 0F B1
+ CMPXCHG8B 0F C7 /1
+
+ XADD 0F C0, 0F C1
+*/
+static Bool can_be_used_with_LOCK_prefix ( UChar* opc )
+{
+ switch (opc[0]) {
+ case 0x00: case 0x01: case 0x02: case 0x03: return True;
+ case 0x08: case 0x09: case 0x0A: case 0x0B: return True;
+ case 0x10: case 0x11: case 0x12: case 0x13: return True;
+ case 0x18: case 0x19: case 0x1A: case 0x1B: return True;
+ case 0x20: case 0x21: case 0x22: case 0x23: return True;
+ case 0x28: case 0x29: case 0x2A: case 0x2B: return True;
+ case 0x30: case 0x31: case 0x32: case 0x33: return True;
+
+ case 0x80: case 0x81: case 0x83:
+ if (gregOfRM(opc[1]) >= 0 && gregOfRM(opc[1]) <= 6)
+ return True;
+ break;
+
+ case 0xFE: case 0xFF:
+ if (gregOfRM(opc[1]) >= 0 && gregOfRM(opc[1]) <= 1)
+ return True;
+ break;
+
+ case 0xF6: case 0xF7:
+ if (gregOfRM(opc[1]) >= 2 && gregOfRM(opc[1]) <= 3)
+ return True;
+ break;
+
+ case 0x86: case 0x87:
+ return True;
+
+ case 0x0F: {
+ switch (opc[1]) {
+ case 0xBB: case 0xB3: case 0xAB:
+ return True;
+ case 0xBA:
+ if (gregOfRM(opc[2]) >= 5 && gregOfRM(opc[2]) <= 7)
+ return True;
+ break;
+ case 0xB0: case 0xB1:
+ return True;
+ case 0xC7:
+ if (gregOfRM(opc[2]) == 1)
+ return True;
+ break;
+ case 0xC0: case 0xC1:
+ return True;
+ default:
+ break;
+ } /* switch (opc[1]) */
+ break;
+ }
+
+ default:
+ break;
+ } /* switch (opc[0]) */
+
+ return False;
+}
+
+
/*------------------------------------------------------------*/
/*--- Disassemble a single instruction ---*/
/*------------------------------------------------------------*/
@@ -7155,10 +7245,10 @@
IRType ty;
IRTemp addr, t0, t1, t2, t3, t4, t5, t6;
Int alen;
- UChar opc, modrm, abyte;
+ UChar opc, modrm, abyte, pre;
UInt d32;
HChar dis_buf[50];
- Int am_sz, d_sz;
+ Int am_sz, d_sz, n_prefixes;
DisResult dres;
UChar* insn; /* used in SSE decoders */
@@ -7178,6 +7268,12 @@
indicating the prefix. */
UChar sorb = 0;
+ /* Gets set to True if a LOCK prefix is seen. */
+ Bool pfx_lock = False;
+
+ /* do we need follow the insn with MBusEvent(BusUnlock) ? */
+ Bool unlock_bus_after_insn = False;
+
/* Set result defaults. */
dres.whatNext = Dis_Continue;
dres.len = 0;
@@ -7242,103 +7338,129 @@
}
}
- /* Deal with prefixes. */
- /* Skip a LOCK prefix. */
- /* 2005 Jan 06: the following insns are observed to sometimes
- have a LOCK prefix:
- cmpxchgl %ecx,(%edx)
- cmpxchgl %edx,0x278(%ebx) etc
- xchgl %eax, (%ecx)
- xaddl %eax, (%ecx)
- We need to catch any such which appear to be being used as
- a memory barrier, for example lock addl $0,0(%esp)
- and emit an IR MFence construct.
- */
- if (getIByte(delta) == 0xF0) {
-
+ /* Handle a couple of weird-ass NOPs that have been observed in the
+ wild. */
+ {
UChar* code = (UChar*)(guest_code + delta);
-
- /* Various bits of kernel headers use the following as a memory
- barrier. Hence, first emit an MFence and then let the insn
- go through as usual. */
- /* F08344240000: lock addl $0, 0(%esp) */
- if (code[0] == 0xF0 && code[1] == 0x83 && code[2] == 0x44 &&
- code[3] == 0x24 && code[4] == 0x00 && code[5] == 0x00) {
- stmt( IRStmt_MFence() );
+ /* Sun's JVM 1.5.0 uses the following as a NOP:
+ 26 2E 64 65 90 %es:%cs:%fs:%gs:nop */
+ if (code[0] == 0x26 && code[1] == 0x2E && code[2] == 0x64
+ && code[3] == 0x65 && code[4] == 0x90) {
+ DIP("%%es:%%cs:%%fs:%%gs:nop\n");
+ delta += 5;
+ goto decode_success;
}
- else
- if (0) {
- vex_printf("vex x86->IR: ignoring LOCK prefix on: ");
- /* insn_verbose = True; */
+ /* don't barf on recent binutils padding
+ 66 2e 0f 1f 84 00 00 00 00 00 nopw %cs:0x0(%eax,%eax,1) */
+ if (code[0] == 0x66
+ && code[1] == 0x2E && code[2] == 0x0F && code[3] == 0x1F
+ && code[4] == 0x84 && code[5] == 0x00 && code[6] == 0x00
+ && code[7] == 0x00 && code[8] == 0x00 && code[9] == 0x00 ) {
+ DIP("nopw %%cs:0x0(%%eax,%%eax,1)\n");
+ delta += 10;
+ goto decode_success;
}
+ }
- /* In any case, skip the prefix. */
- delta++;
- }
+ /* Normal instruction handling starts here. */
- /* Detect operand-size overrides. It is possible for more than one
- 0x66 to appear. */
- while (getIByte(delta) == 0x66) { sz = 2; delta++; };
-
- /* segment override prefixes come after the operand-size override,
- it seems */
- switch (getIByte(delta)) {
- case 0x3E: /* %DS: */
- case 0x26: /* %ES: */
- /* Sun's JVM 1.5.0 uses the following as a NOP:
- 26 2E 64 65 90 %es:%cs:%fs:%gs:nop */
- {
- UChar* code = (UChar*)(guest_code + delta);
- if (code[0] == 0x26 && code[1] == 0x2E && code[2] == 0x64
- && code[3] == 0x65 && code[4] == 0x90) {
- DIP("%%es:%%cs:%%fs:%%gs:nop\n");
- delta += 5;
- goto decode_success;
- }
- /* else fall through */
- }
- case 0x64: /* %FS: */
- case 0x65: /* %GS: */
- sorb = getIByte(delta); delta++;
- break;
- case 0x2E: /* %CS: */
- /* 2E prefix on a conditional branch instruction is a
- branch-prediction hint, which can safely be ignored. */
- {
+ /* Deal with some but not all prefixes:
+ 66(oso)
+ F0(lock)
+ 2E(cs:) 3E(ds:) 26(es:) 64(fs:) 65(gs:) 36(ss:)
+ Not dealt with (left in place):
+ F2 F3
+ */
+ n_prefixes = 0;
+ while (True) {
+ if (n_prefixes > 7) goto decode_failure;
+ pre = getUChar(delta);
+ switch (pre) {
+ case 0x66:
+ sz = 2;
+ break;
+ case 0xF0:
+ pfx_lock = True;
+ break;
+ case 0x3E: /* %DS: */
+ case 0x26: /* %ES: */
+ case 0x64: /* %FS: */
+ case 0x65: /* %GS: */
+ if (sorb != 0)
+ goto decode_failure; /* only one seg override allowed */
+ sorb = pre;
+ break;
+ case 0x2E: { /* %CS: */
+ /* 2E prefix on a conditional branch instruction is a
+ branch-prediction hint, which can safely be ignored. */
UChar op1 = getIByte(delta+1);
UChar op2 = getIByte(delta+2);
if ((op1 >= 0x70 && op1 <= 0x7F)
|| (op1 == 0xE3)
|| (op1 == 0x0F && op2 >= 0x80 && op2 <= 0x8F)) {
if (0) vex_printf("vex x86->IR: ignoring branch hint\n");
- sorb = getIByte(delta); delta++;
- break;
+ } else {
+ /* All other CS override cases are not handled */
+ goto decode_failure;
}
+ break;
}
- /* don't barf on recent binutils padding
- 66 2e 0f 1f 84 00 00 00 00 00 nopw %cs:0x0(%eax,%eax,1)
- */
- {
- UChar* code = (UChar*)(guest_code + delta);
- if (sz == 2
- && code[-1] == 0x66
- && code[0] == 0x2E && code[1] == 0x0F && code[2] == 0x1F
- && code[3] == 0x84 && code[4] == 0x00 && code[5] == 0x00
- && code[6] == 0x00 && code[7] == 0x00 && code[8] == 0x00 ) {
- DIP("nopw %%cs:0x0(%%eax,%%eax,1)\n");
- delta += 9;
- goto decode_success;
- }
- }
- /* All other CS override cases are not handled */
+ case 0x36: /* %SS: */
+ /* SS override cases are not handled */
+ goto decode_failure;
+ default:
+ goto not_a_prefix;
+ }
+ n_prefixes++;
+ delta++;
+ }
+
+ not_a_prefix:
+
+ /* Now we should be looking at the primary opcode byte or the
+ leading F2 or F3. Check that any LOCK prefix is actually
+ allowed. */
+
+ /* Kludge re LOCK prefixes. We assume here that all code generated
+ by Vex is going to be run in a single-threaded context, in other
+ words that concurrent executions of Vex-generated translations
+ will not happen. So we don't need to worry too much about
+ preserving atomicity. However, mark the fact that the notional
+ hardware bus lock is being acquired (and, after the insn,
+ released), so that thread checking tools know this is a locked
+ insn.
+
+ We check for, and immediately reject, (most) inappropriate uses
+ of the LOCK prefix. Later (at decode_failure: and
+ decode_success:), if we've added a BusLock event, then we will
+ follow up with a BusUnlock event. How do we know execution will
+ actually ever get to the BusUnlock event? Because
+ can_be_used_with_LOCK_prefix rejects all control-flow changing
+ instructions.
+
+ One loophole, though: if a LOCK prefix insn (seg)faults, then
+ the BusUnlock event will never be reached. This could cause
+ tools which track bus hardware lock to lose track. Really, we
+ should explicitly release the lock after every insn, but that's
+ obviously way too expensive. Really, any tool which tracks the
+ state of the bus lock needs to ask V's core/tool interface to
+ notify it of signal deliveries. On delivery of SIGSEGV to the
+ guest, the tool will be notified, in which case it should
+ release the bus hardware lock if it is held.
+
+ Note, guest-amd64/toIR.c contains identical logic.
+ */
+ if (pfx_lock) {
+ if (can_be_used_with_LOCK_prefix( (UChar*)&guest_code[delta] )) {
+ stmt( IRStmt_MBE(Imbe_BusLock) );
+ unlock_bus_after_insn = True;
+ DIP("lock ");
+ } else {
goto decode_failure;
- case 0x36: /* %SS: */
- /* SS override cases are not handled */
- goto decode_failure;
- default:
- break;
+ }
}
+
/* ---------------------------------------------------- */
/* --- The SSE decoder. --- */
/* ---------------------------------------------------- */
@@ -8324,7 +8446,7 @@
delta += 3;
/* Insert a memory fence. It's sometimes important that these
are carried through to the generated code. */
- stmt( IRStmt_MFence() );
+ stmt( IRStmt_MBE(Imbe_Fence) );
DIP("sfence\n");
goto decode_success;
}
@@ -9104,7 +9226,7 @@
delta += 3;
/* Insert a memory fence. It's sometimes important that these
are carried through to the generated code. */
- stmt( IRStmt_MFence() );
+ stmt( IRStmt_MBE(Imbe_Fence) );
DIP("%sfence\n", gregOfRM(insn[2])==5 ? "l" : "m");
goto decode_success;
}
@@ -12699,7 +12821,7 @@
stmt( IRStmt_Dirty(d) );
/* CPUID is a serialising insn. So, just in case someone is
using it as a memory fence ... */
- stmt( IRStmt_MFence() );
+ stmt( IRStmt_MBE(Imbe_Fence) );
DIP("cpuid\n");
break;
}
@@ -13086,6 +13208,8 @@
insn, but nevertheless be paranoid and update it again right
now. */
stmt( IRStmt_Put( OFFB_EIP, mkU32(guest_EIP_curr_instr) ) );
+ if (unlock_bus_after_insn)
+ stmt( IRStmt_MBE(Imbe_BusUnlock) );
jmp_lit(Ijk_NoDecode, guest_EIP_curr_instr);
dres.whatNext = Dis_StopHere;
dres.len = 0;
@@ -13096,7 +13220,8 @@
decode_success:
/* All decode successes end up here. */
DIP("\n");
-
+ if (unlock_bus_after_insn)
+ stmt( IRStmt_MBE(Imbe_BusUnlock) );
dres.len = delta - delta_start;
return dres;
}
Modified: branches/THRCHECK/priv/host-amd64/isel.c
===================================================================
--- branches/THRCHECK/priv/host-amd64/isel.c 2007-09-09 19:38:48 UTC (rev 1788)
+++ branches/THRCHECK/priv/host-amd64/isel.c 2007-09-16 11:04:24 UTC (rev 1789)
@@ -3763,9 +3763,18 @@
}
/* --------- MEM FENCE --------- */
- case Ist_MFence:
- addInstr(env, AMD64Instr_MFence());
- return;
+ case Ist_MBE:
+ switch (stmt->Ist.MBE.event) {
+ case Imbe_Fence:
+ addInstr(env, AMD64Instr_MFence());
+ return;
+ case Imbe_BusLock:
+ case Imbe_BusUnlock:
+ return;
+ default:
+ break;
+ }
+ break;
/* --------- INSTR MARK --------- */
/* Doesn't generate any executable code ... */
Modified: branches/THRCHECK/priv/host-ppc/isel.c
===================================================================
--- branches/THRCHECK/priv/host-ppc/isel.c 2007-09-09 19:38:48 UTC (rev 1788)
+++ branches/THRCHECK/priv/host-ppc/isel.c 2007-09-16 11:04:24 UTC (rev 1789)
@@ -3866,9 +3866,18 @@
}
/* --------- MEM FENCE --------- */
- case Ist_MFence:
- addInstr(env, PPCInstr_MFence());
- return;
+ case Ist_MBE:
+ switch (stmt->Ist.MBE.event) {
+ case Imbe_Fence:
+ addInstr(env, PPCInstr_MFence());
+ return;
+ case Imbe_BusLock:
+ case Imbe_BusUnlock:
+ return;
+ default:
+ break;
+ }
+ break;
/* --------- INSTR MARK --------- */
/* Doesn't generate any executable code ... */
Modified: branches/THRCHECK/priv/host-x86/isel.c
===================================================================
--- branches/THRCHECK/priv/host-x86/isel.c 2007-09-09 19:38:48 UTC (rev 1788)
+++ branches/THRCHECK/priv/host-x86/isel.c 2007-09-16 11:04:24 UTC (rev 1789)
@@ -3802,9 +3802,18 @@
}
/* --------- MEM FENCE --------- */
- case Ist_MFence:
- addInstr(env, X86Instr_MFence(env->hwcaps));
- return;
+ case Ist_MBE:
+ switch (stmt->Ist.MBE.event) {
+ case Imbe_Fence:
+ addInstr(env, X86Instr_MFence(env->hwcaps));
+ return;
+ case Imbe_BusLock:
+ case Imbe_BusUnlock:
+ return;
+ default:
+ break;
+ }
+ break;
/* --------- INSTR MARK --------- */
/* Doesn't generate any executable code ... */
Modified: branches/THRCHECK/priv/ir/irdefs.c
===================================================================
--- branches/THRCHECK/priv/ir/irdefs.c 2007-09-09 19:38:48 UTC (rev 1788)
+++ branches/THRCHECK/priv/ir/irdefs.c 2007-09-16 11:04:24 UTC (rev 1789)
@@ -736,6 +736,16 @@
}
}
+void ppIRMBusEvent ( IRMBusEvent event )
+{
+ switch (event) {
+ case Imbe_Fence: vex_printf("Fence"); break;
+ case Imbe_BusLock: vex_printf("BusLock"); break;
+ case Imbe_BusUnlock: vex_printf("BusUnlock"); break;
+ default: vpanic("ppIRMBusEvent");
+ }
+}
+
void ppIRStmt ( IRStmt* s )
{
if (!s) {
@@ -781,8 +791,9 @@
case Ist_Dirty:
ppIRDirty(s->Ist.Dirty.details);
break;
- case Ist_MFence:
- vex_printf("IR-MFence");
+ case Ist_MBE:
+ vex_printf("IR-");
+ ppIRMBusEvent(s->Ist.MBE.event);
break;
case Ist_Exit:
vex_printf( "if (" );
@@ -1186,12 +1197,12 @@
s->Ist.Dirty.details = d;
return s;
}
-IRStmt* IRStmt_MFence ( void )
+IRStmt* IRStmt_MBE ( IRMBusEvent event )
{
- /* Just use a single static closure. */
- static IRStmt static_closure;
- static_closure.tag = Ist_MFence;
- return &static_closure;
+ IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
+ s->tag = Ist_MBE;
+ s->Ist.MBE.event = event;
+ return s;
}
IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst ) {
IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
@@ -1387,8 +1398,8 @@
deepCopyIRExpr(s->Ist.Store.data));
case Ist_Dirty:
return IRStmt_Dirty(deepCopyIRDirty(s->Ist.Dirty.details));
- case Ist_MFence:
- return IRStmt_MFence();
+ case Ist_MBE:
+ return IRStmt_MBE(s->Ist.MBE.event);
case Ist_Exit:
return IRStmt_Exit(deepCopyIRExpr(s->Ist.Exit.guard),
s->Ist.Exit.jk,
@@ -2021,7 +2032,7 @@
return True;
case Ist_NoOp:
case Ist_IMark:
- case Ist_MFence:
+ case Ist_MBE:
return True;
case Ist_Exit:
return isIRAtom(st->Ist.Exit.guard);
@@ -2196,7 +2207,7 @@
useBeforeDef_Expr(bb,stmt,d->mAddr,def_counts);
break;
case Ist_NoOp:
- case Ist_MFence:
+ case Ist_MBE:
break;
case Ist_Exit:
useBeforeDef_Expr(bb,stmt,stmt->Ist.Exit.guard,def_counts);
@@ -2500,8 +2511,15 @@
bad_dirty:
sanityCheckFail(bb,stmt,"IRStmt.Dirty: ill-formed");
case Ist_NoOp:
- case Ist_MFence:
break;
+ case Ist_MBE:
+ switch (stmt->Ist.MBE.event) {
+ case Imbe_Fence: case Imbe_BusLock: case Imbe_BusUnlock:
+ break;
+ default: sanityCheckFail(bb,stmt,"IRStmt.MBE.event: unknown");
+ break;
+ }
+ break;
case Ist_Exit:
tcExpr( bb, stmt, stmt->Ist.Exit.guard, gWordTy );
if (typeOfIRExpr(tyenv,stmt->Ist.Exit.guard) != Ity_I1)
Modified: branches/THRCHECK/priv/ir/iropt.c
===================================================================
--- branches/THRCHECK/priv/ir/iropt.c 2007-09-09 19:38:48 UTC (rev 1788)
+++ branches/THRCHECK/priv/ir/iropt.c 2007-09-16 11:04:24 UTC (rev 1789)
@@ -442,7 +442,7 @@
addStmtToIRSB(bb, IRStmt_Dirty(d2));
break;
case Ist_NoOp:
- case Ist_MFence:
+ case Ist_MBE:
case Ist_IMark:
addStmtToIRSB(bb, st);
break;
@@ -708,11 +708,12 @@
crude solution is just to flush everything; we could easily
enough do a lot better if needed. */
/* Probably also overly-conservative, but also dump everything
- if we hit a memory fence. Ditto AbiHints.*/
+ if we hit a memory bus event (fence, lock, unlock). Ditto
+ AbiHints.*/
case Ist_AbiHint:
vassert(isIRAtom(st->Ist.AbiHint.base));
/* fall through */
- case Ist_MFence:
+ case Ist_MBE:
case Ist_Dirty:
for (j = 0; j < env->used; j++)
env->inuse[j] = False;
@@ -1760,8 +1761,8 @@
case Ist_NoOp:
return IRStmt_NoOp();
- case Ist_MFence:
- return IRStmt_MFence();
+ case Ist_MBE:
+ return IRStmt_MBE(st->Ist.MBE.event);
case Ist_Exit: {
IRExpr* fcond;
@@ -1967,7 +1968,7 @@
return;
case Ist_NoOp:
case Ist_IMark:
- case Ist_MFence:
+ case Ist_MBE:
return;
case Ist_Exit:
addUses_Expr(set, st->Ist.Exit.guard);
@@ -2535,7 +2536,7 @@
/* ------ BEGIN invalidate aenv bindings ------ */
/* This is critical: remove from aenv any E' -> .. bindings
which might be invalidated by this statement. The only
- vulnerable kind of bindings are the GetIt kind.
+ vulnerable kind of bindings are the GetI kind.
Dirty call - dump (paranoia level -> 2)
Store - dump (ditto)
Put, PutI - dump unless no-overlap is proven (.. -> 1)
@@ -2543,12 +2544,12 @@
to do the no-overlap assessments needed for Put/PutI.
*/
switch (st->tag) {
- case Ist_Dirty: case Ist_Store:
+ case Ist_Dirty: case Ist_Store: case Ist_MBE:
paranoia = 2; break;
case Ist_Put: case Ist_PutI:
paranoia = 1; break;
case Ist_NoOp: case Ist_IMark: case Ist_AbiHint:
- case Ist_WrTmp: case Ist_MFence: case Ist_Exit:
+ case Ist_WrTmp: case Ist_Exit:
paranoia = 0; break;
default:
vpanic("do_cse_BB(1)");
@@ -2963,7 +2964,7 @@
case Ist_IMark:
return False;
- case Ist_MFence:
+ case Ist_MBE:
case Ist_AbiHint:
/* just be paranoid ... these should be rare. */
return True;
@@ -3206,7 +3207,7 @@
switch (st->tag) {
case Ist_NoOp:
case Ist_IMark:
- case Ist_MFence:
+ case Ist_MBE:
break;
case Ist_AbiHint:
deltaIRExpr(st->Ist.AbiHint.base, delta);
@@ -3691,7 +3692,7 @@
return;
case Ist_NoOp:
case Ist_IMark:
- case Ist_MFence:
+ case Ist_MBE:
return;
case Ist_Exit:
aoccCount_Expr(uses, st->Ist.Exit.guard);
@@ -3933,8 +3934,8 @@
return IRStmt_IMark(st->Ist.IMark.addr, st->Ist.IMark.len);
case Ist_NoOp:
return IRStmt_NoOp();
- case Ist_MFence:
- return IRStmt_MFence();
+ case Ist_MBE:
+ return IRStmt_MBE(st->Ist.MBE.event);
case Ist_Dirty:
d = st->Ist.Dirty.details;
d2 = emptyIRDirty();
@@ -4093,11 +4094,11 @@
question is marked as requiring precise
exceptions. */
|| (env[k].doesLoad && stmtPuts)
- /* probably overly conservative: a memory fence
+ /* probably overly conservative: a memory bus event
invalidates absolutely everything, so that all
computation prior to it is forced to complete before
- proceeding with the fence. */
- || st->tag == Ist_MFence
+ proceeding with the event (fence,lock,unlock). */
+ || st->tag == Ist_MBE
/* also be (probably overly) paranoid re AbiHints */
|| st->tag == Ist_AbiHint
);
@@ -4265,7 +4266,7 @@
break;
case Ist_NoOp:
case Ist_IMark:
- case Ist_MFence:
+ case Ist_MBE:
break;
case Ist_Exit:
vassert(isIRAtom(st->Ist.Exit.guard));
Modified: branches/THRCHECK/pub/libvex_ir.h
===================================================================
--- branches/THRCHECK/pub/libvex_ir.h 2007-09-09 19:38:48 UTC (rev 1788)
+++ branches/THRCHECK/pub/libvex_ir.h 2007-09-16 11:04:24 UTC (rev 1789)
@@ -229,8 +229,8 @@
float, or a vector (SIMD) value. */
typedef
enum {
- Ity_INVALID=0x10FFF,
- Ity_I1=0x11000,
+ Ity_INVALID=0x11000,
+ Ity_I1,
Ity_I8,
Ity_I16,
Ity_I32,
@@ -254,8 +254,8 @@
/* IREndness is used in load IRExprs and store IRStmts. */
typedef
enum {
- Iend_LE=22, /* little endian */
- Iend_BE=33 /* big endian */
+ Iend_LE=0x12000, /* little endian */
+ Iend_BE /* big endian */
}
IREndness;
@@ -267,7 +267,7 @@
/* The various kinds of constant. */
typedef
enum {
- Ico_U1=0x12000,
+ Ico_U1=0x13000,
Ico_U8,
Ico_U16,
Ico_U32,
@@ -406,7 +406,7 @@
/* -- Do not change this ordering. The IR generators rely on
(eg) Iop_Add64 == IopAdd8 + 3. -- */
- Iop_INVALID=0x13000,
+ Iop_INVALID=0x14000,
Iop_Add8, Iop_Add16, Iop_Add32, Iop_Add64,
Iop_Sub8, Iop_Sub16, Iop_Sub32, Iop_Sub64,
/* Signless mul. MullS/MullU is elsewhere. */
@@ -884,7 +884,7 @@
in the comments for IRExpr. */
typedef
enum {
- Iex_Binder,
+ Iex_Binder=0x15000,
Iex_Get,
Iex_GetI,
Iex_RdTmp,
@@ -1181,7 +1181,7 @@
*/
typedef
enum {
- Ijk_Boring=0x14000, /* not interesting; just goto next */
+ Ijk_Boring=0x16000, /* not interesting; just goto next */
Ijk_Call, /* guest is doing a call */
Ijk_Ret, /* guest is doing a return */
Ijk_ClientReq, /* do guest client req before continuing */
@@ -1254,7 +1254,7 @@
/* Effects on resources (eg. registers, memory locations) */
typedef
enum {
- Ifx_None = 0x15000, /* no effect */
+ Ifx_None = 0x17000, /* no effect */
Ifx_Read, /* reads the resource */
Ifx_Write, /* writes the resource */
Ifx_Modify, /* modifies the resource */
@@ -1316,6 +1316,19 @@
IRExpr** args );
+/* --------------- Memory Bus Events --------------- */
+
+typedef
+ enum {
+ Imbe_Fence=0x18000,
+ Imbe_BusLock,
+ Imbe_BusUnlock
+ }
+ IRMBusEvent;
+
+extern void ppIRMBusEvent ( IRMBusEvent );
+
+
/* ------------------ Statements ------------------ */
/* The different kinds of statements. Their meaning is explained
@@ -1327,9 +1340,10 @@
they are required by some IR consumers such as tools that
instrument the code.
*/
+
typedef
enum {
- Ist_NoOp,
+ Ist_NoOp=0x19000,
Ist_IMark, /* META */
Ist_AbiHint, /* META */
Ist_Put,
@@ -1337,7 +1351,7 @@
Ist_WrTmp,
Ist_Store,
Ist_Dirty,
- Ist_MFence,
+ Ist_MBE, /* META (maybe) */
Ist_Exit
}
IRStmtTag;
@@ -1452,11 +1466,15 @@
IRDirty* details;
} Dirty;
- /* A memory fence.
- ppIRExpr output: IR-MFence
+ /* A memory bus event - a fence, or acquisition/release of the
+ hardware bus lock. IR optimisation treats all these as fences
+ across which no memory references may be moved.
+ ppIRExpr output: MBusEvent-Fence,
+ MBusEvent-BusLock, MBusEvent-BusUnlock.
*/
struct {
- } MFence;
+ IRMBusEvent event;
+ } MBE;
/* Conditional exit from the middle of an IRSB.
ppIRExpr output: if (<guard>) goto {<jk>} <dst>
@@ -1481,7 +1499,7 @@
extern IRStmt* IRStmt_WrTmp ( IRTemp tmp, IRExpr* data );
extern IRStmt* IRStmt_Store ( IREndness end, IRExpr* addr, IRExpr* data );
extern IRStmt* IRStmt_Dirty ( IRDirty* details );
-extern IRStmt* IRStmt_MFence ( void );
+extern IRStmt* IRStmt_MBE ( IRMBusEvent event );
extern IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst );
/* Deep-copy an IRStmt. */
|
|
From: Tom H. <th...@cy...> - 2007-09-16 02:31:07
|
Nightly build on alvis ( i686, Red Hat 7.3 ) started at 2007-09-16 03:15:02 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 256 tests, 27 stderr failures, 1 stdout failure, 0 posttest failures == memcheck/tests/addressable (stderr) memcheck/tests/badjump (stderr) memcheck/tests/describe-block (stderr) memcheck/tests/erringfds (stderr) memcheck/tests/leak-0 (stderr) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-pool-0 (stderr) memcheck/tests/leak-pool-1 (stderr) memcheck/tests/leak-pool-2 (stderr) memcheck/tests/leak-pool-3 (stderr) memcheck/tests/leak-pool-4 (stderr) memcheck/tests/leak-pool-5 (stderr) memcheck/tests/leak-regroot (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/long_namespace_xml (stderr) memcheck/tests/match-overrun (stderr) memcheck/tests/partial_load_dflt (stderr) memcheck/tests/partial_load_ok (stderr) memcheck/tests/partiallydefinedeq (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/sigkill (stderr) memcheck/tests/stack_changes (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) memcheck/tests/x86/xor-undef-x86 (stderr) memcheck/tests/xml1 (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: Tom H. <th...@cy...> - 2007-09-16 02:23:26
|
Nightly build on dellow ( x86_64, Fedora 7 ) started at 2007-09-16 03:10:05 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 293 tests, 4 stderr failures, 2 stdout failures, 0 posttest failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/scalar (stderr) memcheck/tests/xml1 (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: Tom H. <th...@cy...> - 2007-09-16 02:17:23
|
Nightly build on lloyd ( x86_64, Fedora Core 3 ) started at 2007-09-16 03:05:04 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 293 tests, 6 stderr failures, 1 stdout failure, 0 posttest failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/stack_switch (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) memcheck/tests/xml1 (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: Tom H. <th...@cy...> - 2007-09-16 02:11:12
|
Nightly build on gill ( x86_64, Fedora Core 2 ) started at 2007-09-16 03:00:03 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 295 tests, 6 stderr failures, 1 stdout failure, 0 posttest failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/stack_switch (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) none/tests/fdleak_fcntl (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: <js...@ac...> - 2007-09-16 01:21:37
|
Nightly build on g5 ( SuSE 10.1, ppc970 ) started at 2007-09-16 02:00:01 CEST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 228 tests, 6 stderr failures, 2 stdout failures, 0 posttest failures == memcheck/tests/deep_templates (stdout) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/pointer-trace (stderr) none/tests/faultstatus (stderr) none/tests/fdleak_cmsg (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |