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
(16) |
2
(23) |
3
(15) |
|
4
(19) |
5
(21) |
6
(27) |
7
(18) |
8
(17) |
9
(15) |
10
(11) |
|
11
(9) |
12
(18) |
13
(26) |
14
(28) |
15
(26) |
16
(20) |
17
(27) |
|
18
(16) |
19
(40) |
20
(2) |
21
(11) |
22
(27) |
23
(24) |
24
(16) |
|
25
(10) |
26
(12) |
27
(16) |
28
(7) |
29
(6) |
30
(15) |
31
(5) |
|
From: Julian S. <js...@ac...> - 2005-12-02 23:53:18
|
I was playing around in m_redir.c and wondering about how to know
what to free when, when it occurred to me we could do an old trick
that many do (including OOo 2.0) which is to fill up freed areas
with a bad value (traditionally 0xAA since AAAAAAAA is the sound of
a (32-bit) program dying, I'm told). This then catches some reads
of freed memory. So I added this to m_mallocfree.c:
===================================================================
--- coregrind/m_mallocfree.c (revision 5272)
+++ coregrind/m_mallocfree.c (working copy)
@@ -1070,6 +1070,13 @@
a->bytes_on_loan -= b_pszB;
+ if (aid != VG_AR_CLIENT) {
+ Int i;
+ UChar* p = (UChar*)ptr;
+ for (i = 0; i < b_pszB; i++)
+ p[i] = 0xAA;
+ }
+
// Put this chunk back on a list somewhere.
b_listno = pszB_to_listNo(b_pszB);
mkFreeBlock( a, b, b_bszB, b_listno );
and hey presto:
sewardj@suse10:~/VgTRUNK/trunk$ ./Inst/bin/valgrind ./memcheck/tests/mempool
[.. gets halfway through ..]
--17776-- INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--17776-- si_code=1; Faulting address: 0xAAAAAAA2; sp: 0x622B3E50
valgrind: the 'impossible' happened:
Killed by fatal signal
==17776== at 0xB0016D0F: vgPlain_arena_free (m_mallocfree.c:181)
==17776== by 0xB00176CD: vgPlain_free (m_mallocfree.c:1378)
==17776== by 0xB000DDDB: vgPlain_HT_destruct (m_hashtable.c:242)
==17776== by 0xB000183E: vgMAC_destroy_mempool (mac_malloc_wrappers.c:458)
==17776== by 0xB0006F4E: vgMAC_handle_common_client_requests
(mac_shared.c:1018)
==17776== by 0xB0003D75: mc_handle_client_request (mc_main.c:2501)
Check it out! 0xAAAAAAA2.
I'm also contemplating enabling this (line 1061)
# ifdef DEBUG_MALLOC
vg_assert(blockSane(a, b));
# endif
for non-client frees, in the hope of discovering blocks which V has
overrun the ends, at free-time.
If this doesn't cause noticable slowdowns, do you thing it would be a
safe thing to commit?
J
|
|
From: <sv...@va...> - 2005-12-02 23:09:52
|
Author: njn Date: 2005-12-02 23:09:49 +0000 (Fri, 02 Dec 2005) New Revision: 5274 Log: update Modified: trunk/docs/internals/performance.txt Modified: trunk/docs/internals/performance.txt =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- trunk/docs/internals/performance.txt 2005-12-02 23:08:54 UTC (rev 527= 3) +++ trunk/docs/internals/performance.txt 2005-12-02 23:09:49 UTC (rev 527= 4) @@ -14,7 +14,8 @@ =20 COMPVBITS branch: - Nick converted to compress V bits, initial version saved 0--5% on most - cases, with a 30% improvement on one case which calls + cases, with a 30% improvement on one case (tsim_arch) which calls set_address_range_perms() a lot. +- Nick rewrote set_address_range_perms(), which gained 0--3% typically, + and 22% on tsim_arch. =20 - |
|
From: <sv...@va...> - 2005-12-02 23:08:58
|
Author: njn
Date: 2005-12-02 23:08:54 +0000 (Fri, 02 Dec 2005)
New Revision: 5273
Log:
Rewrote set_address_range_perms(). Improves performance by 0--3% on typi=
cal
programs, and 22% on one unusual program (tsim_arch, which allocates very=
many
8KB objects on the stack).
Also, fixed the sec-maps stats debug output which was showing the wrong
sizes.
Modified:
branches/COMPVBITS/coregrind/pub_core_aspacemgr.h
branches/COMPVBITS/include/pub_tool_aspacemgr.h
branches/COMPVBITS/memcheck/mac_leakcheck.c
branches/COMPVBITS/memcheck/mac_shared.h
branches/COMPVBITS/memcheck/mc_main.c
Modified: branches/COMPVBITS/coregrind/pub_core_aspacemgr.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/COMPVBITS/coregrind/pub_core_aspacemgr.h 2005-12-02 19:30:27=
UTC (rev 5272)
+++ branches/COMPVBITS/coregrind/pub_core_aspacemgr.h 2005-12-02 23:08:54=
UTC (rev 5273)
@@ -232,10 +232,6 @@
extern SysRes VG_(am_munmap_client)( /*OUT*/Bool* need_discard,
Addr start, SizeT length );
=20
-/* Unmap the given address range and update the segment array
- accordingly. This fails if the range isn't valid for valgrind. */
-extern SysRes VG_(am_munmap_valgrind)( Addr start, SizeT length );
-
/* Let (start,len) denote an area within a single Valgrind-owned
segment (anon or file). Change the ownership of [start, start+len)
to the client instead. Fails if (start,len) does not denote a
Modified: branches/COMPVBITS/include/pub_tool_aspacemgr.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/COMPVBITS/include/pub_tool_aspacemgr.h 2005-12-02 19:30:27 U=
TC (rev 5272)
+++ branches/COMPVBITS/include/pub_tool_aspacemgr.h 2005-12-02 23:08:54 U=
TC (rev 5273)
@@ -147,6 +147,10 @@
/* Really just a wrapper around VG_(am_mmap_anon_float_valgrind). */
extern void* VG_(am_shadow_alloc)(SizeT size);
=20
+/* Unmap the given address range and update the segment array
+ accordingly. This fails if the range isn't valid for valgrind. */
+extern SysRes VG_(am_munmap_valgrind)( Addr start, SizeT length );
+
#endif // __PUB_TOOL_ASPACEMGR_H
=20
/*--------------------------------------------------------------------*/
Modified: branches/COMPVBITS/memcheck/mac_leakcheck.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/COMPVBITS/memcheck/mac_leakcheck.c 2005-12-02 19:30:27 UTC (=
rev 5272)
+++ branches/COMPVBITS/memcheck/mac_leakcheck.c 2005-12-02 23:08:54 UTC (=
rev 5273)
@@ -446,7 +446,7 @@
=20
/* Skip invalid chunks */
if (!(*lc_is_within_valid_secondary)(ptr)) {
- ptr =3D VG_ROUNDUP(ptr+1, SECONDARY_SIZE);
+ ptr =3D VG_ROUNDUP(ptr+1, SM_SIZE);
continue;
}
=20
Modified: branches/COMPVBITS/memcheck/mac_shared.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/COMPVBITS/memcheck/mac_shared.h 2005-12-02 19:30:27 UTC (rev=
5272)
+++ branches/COMPVBITS/memcheck/mac_shared.h 2005-12-02 23:08:54 UTC (rev=
5273)
@@ -204,8 +204,8 @@
/* The number of entries in the primary map can be altered. However
we hardwire the assumption that each secondary map covers precisely
64k of address space. */
-#define SECONDARY_SIZE 65536 /* DO NOT CHANGE */
-#define SECONDARY_MASK (SECONDARY_SIZE-1) /* DO NOT CHANGE */
+#define SM_SIZE 65536 /* DO NOT CHANGE */
+#define SM_MASK (SM_SIZE-1) /* DO NOT CHANGE */
=20
//zz #define SECONDARY_SHIFT 16
//zz #define SECONDARY_SIZE (1 << SECONDARY_SHIFT)
Modified: branches/COMPVBITS/memcheck/mc_main.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/COMPVBITS/memcheck/mc_main.c 2005-12-02 19:30:27 UTC (rev 52=
72)
+++ branches/COMPVBITS/memcheck/mc_main.c 2005-12-02 23:08:54 UTC (rev 52=
73)
@@ -56,6 +56,7 @@
#include "mc_include.h"
#include "memcheck.h" /* for client requests */
=20
+// XXX: introduce PM_OFF macro
=20
#define EXPECTED_TAKEN(cond) __builtin_expect((cond),1)
#define EXPECTED_NOT_TAKEN(cond) __builtin_expect((cond),0)
@@ -129,6 +130,7 @@
/* --------------- Stats maps --------------- */
=20
static Int n_secmaps_issued =3D 0;
+static Int n_secmaps_deissued =3D 0;
static ULong n_auxmap_searches =3D 0;
static ULong n_auxmap_cmps =3D 0;
static Int n_sanity_cheap =3D 0;
@@ -182,15 +184,22 @@
#define MC_BITS32_WRITABLE 0x55 // 01_01_01_01b
#define MC_BITS32_READABLE 0xaa // 10_10_10_10b
=20
-#define MC_BITS64_NOACCESS 0x0000 // 00_00_00_00__00_00_00_00b
-#define MC_BITS64_WRITABLE 0x5555 // 01_01_01_01__01_01_01_01b
-#define MC_BITS64_READABLE 0xaaaa // 10_10_10_10__10_10_10_10b
+#define MC_BITS64_NOACCESS 0x0000 // 00_00_00_00b x 2
+#define MC_BITS64_WRITABLE 0x5555 // 01_01_01_01b x 2
+#define MC_BITS64_READABLE 0xaaaa // 10_10_10_10b x 2
=20
=20
#define SM_CHUNKS 16384
#define SM_OFF(aaa) (((aaa) & 0xffff) >> 2)
#define SM_OFF_64(aaa) (((aaa) & 0xffff) >> 3)
=20
+static inline Addr start_of_this_sm ( Addr a ) {
+ return (a & (~SM_MASK));
+}
+static inline Bool is_start_of_sm ( Addr a ) {
+ return (start_of_this_sm(a) =3D=3D a);
+}
+
typedef=20
struct {
UChar vabits32[SM_CHUNKS];
@@ -685,11 +694,12 @@
}
}
=20
-
-static void set_address_range_perms ( Addr a, SizeT len, UWord vabits64,
+static void set_address_range_perms ( Addr a, SizeT lenT, UWord vabits64=
,
UWord dsm_num )
{
- UWord sm_off64;
+ UWord vabits8, sm_off, sm_off64;
+ SizeT lenA, lenB, len_to_next_secmap;
+ Addr aNext;
SecMap* sm;
SecMap** binder;
SecMap* example_dsm;
@@ -701,27 +711,26 @@
vabits64 =3D=3D MC_BITS64_WRITABLE ||
vabits64 =3D=3D MC_BITS64_READABLE);
=20
- if (len =3D=3D 0)
+ if (lenT =3D=3D 0)
return;
=20
- if (len > 100 * 1000 * 1000) {
+ if (lenT > 100 * 1000 * 1000) {
if (VG_(clo_verbosity) > 0 && !VG_(clo_xml)) {
- Char* s =3D NULL; // placate GCC
+ Char* s =3D "unknown???";
if (vabits64 =3D=3D MC_BITS64_NOACCESS) s =3D "noaccess";
if (vabits64 =3D=3D MC_BITS64_WRITABLE) s =3D "writable";
if (vabits64 =3D=3D MC_BITS64_READABLE) s =3D "readable";
VG_(message)(Vg_UserMsg, "Warning: set address range perms: "
- "large range %lu (%s)", len, s);
+ "large range %lu (%s)", lenT, s);
}
}
=20
# if VG_DEBUG_MEMORY >=3D 2
/*------------------ debug-only case ------------------ */
{
- // XXX: Simplest, slow version
UWord vabits8 =3D vabits64 & 0x3;
SizeT i;
- for (i =3D 0; i < len; i++) {
+ for (i =3D 0; i < lenT; i++) {
set_vabits8(aA + i, vabits8);
}
return;
@@ -734,77 +743,176 @@
to use (part of the space-compression scheme). */
example_dsm =3D &sm_distinguished[dsm_num];
=20
- /* Slowly do parts preceding 8-byte alignment. */
- while (len !=3D 0 && !VG_IS_8_ALIGNED(a)) {
- PROF_EVENT(151, "set_address_range_perms-loop1-pre");
- set_vabits8( a, vabits64 & 0x3 );
- a++;
- len--;
- } =20
+ vabits8 =3D vabits64 & 0x3;
+ =20
+ // We have to handle ranges covering various combinations of partial =
and
+ // whole sec-maps. Here is how parts 1, 2 and 3 are used in each cas=
e.
+ // Cases marked with a '*' are common.
+ //
+ // TYPE PARTS USED
+ // ---- ----------
+ // * one partial sec-map (p) 1
+ // - one whole sec-map (P) 2
+ //
+ // * two partial sec-maps (pp) 1,3=20
+ // - one partial, one whole sec-map (pP) 1,2
+ // - one whole, one partial sec-map (Pp) 2,3
+ // - two whole sec-maps (PP) 2,2
+ //
+ // * one partial, one whole, one partial (pPp) 1,2,3
+ // - one partial, two whole (pPP) 1,2,2
+ // - two whole, one partial (PPp) 2,2,3
+ // - three whole (PPP) 2,2,2
+ //
+ // * one partial, N-2 whole, one partial (pP...Pp) 1,2...2,3
+ // - one partial, N-1 whole (pP...PP) 1,2...2,2
+ // - N-1 whole, one partial (PP...Pp) 2,2...2,3
+ // - N whole (PP...PP) 2,2...2,3
=20
- if (len =3D=3D 0)
- return;
+ // Break up total length (lenT) into two parts: length in the first
+ // sec-map (lenA), and the rest (lenB); lenT =3D=3D lenA + lenB.
+ aNext =3D start_of_this_sm(a) + SM_SIZE;
+ len_to_next_secmap =3D aNext - a;
+ if ( lenT <=3D len_to_next_secmap ) {
+ // Range entirely within one sec-map. Covers almost all cases.
+ PROF_EVENT(151, "set_address_range_perms-single-secmap");
+ lenA =3D lenT;
+ lenB =3D 0;
+ } else if (is_start_of_sm(a)) {
+ // Range spans at least one whole sec-map, and starts at the begin=
ning
+ // of a sec-map; skip to Part 2.
+ PROF_EVENT(152, "set_address_range_perms-startof-secmap");
+ lenA =3D 0;
+ lenB =3D lenT;
+ goto part2;
+ } else {
+ // Range spans two or more sec-maps, first one is partial.
+ PROF_EVENT(153, "set_address_range_perms-multiple-secmaps");
+ lenA =3D len_to_next_secmap;
+ lenB =3D lenT - lenA;
+ }
=20
- tl_assert(VG_IS_8_ALIGNED(a) && len > 0);
+ //-------------------------------------------------------------------=
-----
+ // Part 1: Deal with the first sec_map. Most of the time the range w=
ill be
+ // entirely within a sec_map and this part alone will suffice. Also,
+ // doing it this way lets us avoid repeatedly testing for the crossin=
g of
+ // a sec-map boundary within these loops.
+ //-------------------------------------------------------------------=
-----
=20
- /* Now go in steps of 8 bytes. */
+ // If it's distinguished, make it undistinguished if necessary.
binder =3D find_secmap_binder_for_addr(a);
+ if (is_distinguished_sm(*binder)) {
+ if (*binder =3D=3D example_dsm) {
+ // Sec-map already has the V+A bits that we want, so skip.
+ PROF_EVENT(154, "set_address_range_perms-dist-sm1-quick");
+ a =3D aNext;
+ lenA =3D 0;
+ } else {
+ PROF_EVENT(155, "set_address_range_perms-dist-sm1");
+ *binder =3D copy_for_writing(*binder);
+ }
+ }
+ sm =3D *binder;
=20
- while (len >=3D 8) {
- PROF_EVENT(152, "set_address_range_perms-loop8");
+ // 1 byte steps
+ while (True) {
+ if (VG_IS_8_ALIGNED(a)) break;
+ if (lenA < 1) break;
+ PROF_EVENT(156, "set_address_range_perms-loop1a");
+ sm_off =3D SM_OFF(a);
+ insert_vabit8_into_vabits32( a, vabits8, &(sm->vabits32[sm_off]) )=
;
+ a +=3D 1;
+ lenA -=3D 1;
+ }
+ // 8-aligned, 8 byte steps
+ while (True) {
+ if (lenA < 8) break;
+ PROF_EVENT(157, "set_address_range_perms-loop8a");
+ sm_off64 =3D SM_OFF_64(a);
+ ((UShort*)(sm->vabits32))[sm_off64] =3D vabits64;
+ a +=3D 8;
+ lenA -=3D 8;
+ }
+ // 1 byte steps
+ while (True) {
+ if (lenA < 1) break;
+ PROF_EVENT(158, "set_address_range_perms-loop1b");
+ sm_off =3D SM_OFF(a);
+ insert_vabit8_into_vabits32( a, vabits8, &(sm->vabits32[sm_off]) )=
;
+ a +=3D 1;
+ lenA -=3D 1;
+ }
=20
- if ((a & SECONDARY_MASK) =3D=3D 0) {
- /* we just traversed a primary map boundary, so update the bind=
er. */
- binder =3D find_secmap_binder_for_addr(a);
- PROF_EVENT(153, "set_address_range_perms-update-binder");
+ // We've finished the first sec-map. Is that it?
+ if (lenB =3D=3D 0)
+ return;
=20
- /* Space-optimisation. If we are setting the entire
- secondary map, just point this entry at one of our
- distinguished secondaries. However, only do that if it
- already points at a distinguished secondary, since doing
- otherwise would leak the existing secondary. We could do
- better and free up any pre-existing non-distinguished
- secondary at this point, since we are guaranteed that each
- non-dist secondary only has one pointer to it, and we have
- that pointer right here. */
- if (len >=3D SECONDARY_SIZE && is_distinguished_sm(*binder)) {
- PROF_EVENT(154, "set_address_range_perms-entire-secmap");
- *binder =3D example_dsm;
- len -=3D SECONDARY_SIZE;
- a +=3D SECONDARY_SIZE;
- continue;
- }
+ //-------------------------------------------------------------------=
-----
+ // Part 2: Fast-set entire sec-maps at a time.
+ //-------------------------------------------------------------------=
-----
+ part2:
+ // 64KB-aligned, 64KB steps.
+ // Nb: we can reach here with lenB < SM_SIZE
+ while (True) {
+ if (lenB < SM_SIZE) break;
+ tl_assert(is_start_of_sm(a));
+ PROF_EVENT(159, "set_address_range_perms-loop64K");
+ binder =3D find_secmap_binder_for_addr(a);
+ if (!is_distinguished_sm(*binder)) {
+ PROF_EVENT(160, "set_address_range_perms-loop64K-free-dist-sm")=
;
+ // Free the non-distinguished sec-map that we're replacing. Th=
is
+ // case happens moderately often, enough to be worthwhile.
+ VG_(am_munmap_valgrind)((Addr)*binder, sizeof(SecMap));
+ n_secmaps_deissued++; // Needed for the expensive sanity c=
heck
}
-
- /* If the primary is already pointing to a distinguished map
- with the same properties as we're trying to set, then leave
- it that way. Otherwise we have to do some writing. */
- if (*binder !=3D example_dsm) {
- /* Make sure it's OK to write the secondary. */
- if (is_distinguished_sm(*binder)) {
- *binder =3D copy_for_writing(*binder);
- }
- sm =3D *binder;
- sm_off64 =3D SM_OFF_64(a);
- ((UShort*)(sm->vabits32))[sm_off64] =3D vabits64;
- }
-
- a +=3D 8;
- len -=3D 8;
+ // Make the sec-map entry point to the example DSM
+ *binder =3D example_dsm;
+ lenB -=3D SM_SIZE;
+ a +=3D SM_SIZE;
}
=20
- if (len =3D=3D 0)
+ // We've finished the whole sec-maps. Is that it?
+ if (lenB =3D=3D 0)
return;
=20
- tl_assert(VG_IS_8_ALIGNED(a) && len > 0 && len < 8);
+ //-------------------------------------------------------------------=
-----
+ // Part 3: Finish off the final partial sec-map, if necessary.
+ //-------------------------------------------------------------------=
-----
=20
- /* Finish the upper fragment. */
- while (len > 0) {
- PROF_EVENT(155, "set_address_range_perms-loop1-post");
- set_vabits8 ( a, vabits64 & 0x3 );
- a++;
- len--;
- } =20
+ tl_assert(is_start_of_sm(a) && lenB < SM_SIZE);
+
+ // If it's distinguished, make it undistinguished if necessary.
+ binder =3D find_secmap_binder_for_addr(a);
+ if (is_distinguished_sm(*binder)) {
+ if (*binder =3D=3D example_dsm) {
+ // Sec-map already has the V+A bits that we want, so stop.
+ PROF_EVENT(161, "set_address_range_perms-dist-sm2-quick");
+ return;
+ } else {
+ PROF_EVENT(162, "set_address_range_perms-dist-sm2");
+ *binder =3D copy_for_writing(*binder);
+ }
+ }
+ sm =3D *binder;
+
+ // 8-aligned, 8 byte steps
+ while (True) {
+ if (lenB < 8) break;
+ PROF_EVENT(163, "set_address_range_perms-loop8b");
+ sm_off64 =3D SM_OFF_64(a);
+ ((UShort*)(sm->vabits32))[sm_off64] =3D vabits64;
+ a +=3D 8;
+ lenB -=3D 8;
+ }
+ // 1 byte steps
+ while (True) {
+ if (lenB < 1) return;
+ PROF_EVENT(164, "set_address_range_perms-loop1c");
+ sm_off =3D SM_OFF(a);
+ insert_vabit8_into_vabits32( a, vabits8, &(sm->vabits32[sm_off]) )=
;
+ a +=3D 1;
+ lenB -=3D 1;
+ }
}
=20
=20
@@ -2410,7 +2518,7 @@
}
}
=20
- if (n_secmaps_found !=3D n_secmaps_issued)
+ if (n_secmaps_found !=3D (n_secmaps_issued - n_secmaps_deissued))
bad =3D True;
=20
if (bad) {
@@ -2736,13 +2844,11 @@
" memcheck: auxmaps: %lld searches, %lld comparisons",
n_auxmap_searches, n_auxmap_cmps ); =20
VG_(message)(Vg_DebugMsg,
- " memcheck: secondaries: %d issued (%dk, %dM)",
+ " memcheck: secondaries: %d issued (%dk, %dM), %d deissued",
n_secmaps_issued,=20
- n_secmaps_issued * 64,
- n_secmaps_issued / 16 ); =20
- VG_(message)(Vg_DebugMsg,
- " memcheck: sec V bit entries: %d",
- VG_(OSet_Size)(secVBitTable) );
+ n_secmaps_issued * sizeof(SecMap) / 1024,
+ n_secmaps_issued * sizeof(SecMap) / (1024 * 1024),
+ n_secmaps_deissued); =20
=20
n_accessible_dist =3D 0;
for (i =3D 0; i < N_PRIMARY_MAP; i++) {
@@ -2761,9 +2867,12 @@
VG_(message)(Vg_DebugMsg,
" memcheck: secondaries: %d accessible and distinguished (%dk, =
%dM)",
n_accessible_dist,=20
- n_accessible_dist * 64,
- n_accessible_dist / 16 ); =20
+ n_accessible_dist * sizeof(SecMap) / 1024,
+ n_accessible_dist * sizeof(SecMap) / (1024 * 1024) );
=20
+ VG_(message)(Vg_DebugMsg,
+ " memcheck: sec V bit entries: %d",
+ VG_(OSet_Size)(secVBitTable) );
}
=20
if (0) {
|
|
From: Cerion Armour-B. <ce...@op...> - 2005-12-02 19:34:37
|
On Thursday 01 December 2005 09:03, Yao Qi wrote: > jm-insns.c would be more readable if we add Cerion's explanation in the > comment, so I coded a patch. done - r5272. Clarified it some more, hope it makes sense still. C |
|
From: <sv...@va...> - 2005-12-02 19:30:36
|
Author: cerion
Date: 2005-12-02 19:30:27 +0000 (Fri, 02 Dec 2005)
New Revision: 5272
Log:
Added explanation of insn patching used in ppc32 test jm-insns.
Modified:
trunk/none/tests/ppc32/jm-insns.c
Modified: trunk/none/tests/ppc32/jm-insns.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/none/tests/ppc32/jm-insns.c 2005-12-02 16:51:44 UTC (rev 5271)
+++ trunk/none/tests/ppc32/jm-insns.c 2005-12-02 19:30:27 UTC (rev 5272)
@@ -48,8 +48,8 @@
*/
=20
/*
- * Operation details:
- *
+ * Operation details
+ * -----------------
* The 'test' functions (via all_tests[]) are wrappers of single asm ins=
tns
*
* The 'loops' (e.g. int_loops) do the actual work:
@@ -93,6 +93,48 @@
* }
* }
* }
+ *
+ *
+ * Details of intruction patching for immediate operands
+ * -----------------------------------------------------
+ * All the immediate insn test functions are of the form {imm_insn, blr}
+ * In order to patch one of these functions, we simply copy both insns
+ * to a stack buffer, and rewrite the immediate part of imm_insn.
+ * We then execute our stack buffer.
+ * All ppc instructions are 32bits wide, which makes this fairly easy.
+ *
+ * Example:
+ * extern void test_addi (void);
+ * asm(".text\n"
+ * "test_addi:\n"
+ * "\taddi 17, 14, 0\n"
+ * "\tblr\n"
+ * ".previous\n"
+ * );
+ *
+ * We are interested only in:
+ * "\taddi 17, 14, 0\n"
+ * "\tblr\n"
+ *
+ * In a loop test, we may see:
+ * uint32_t func_buf[2]; // our new stack based 'function'
+ * uint32_t *p; // ptr to access insns by idx
+ * for imm... // loop over imm
+ * p =3D (void *)func;
+ * func_buf[1] =3D p[1]; // copy 'blr' to func_buf[1]
+ * patch_op_imm16(func_buf, p, imm); // patched 'addi' -> func_buf[0]
+ * func =3D (void *)func_buf; // ptr to stack based insns
+ * (*func)(); // exec our rewritten code
+ *
+ * patch_op_imm16() itself simply takes the uint32_t insn and overwrites
+ * the immediate field with the new value (which, for 'addi', is the
+ * low 16 bits).
+ *
+ * So in the loop test, if 'imm' is currently 9, and p[0] is:
+ * 0x3A2E0000 =3D> addi 17, 14, 0
+ *
+ * after patch_op_imm16(), func_buf[0] becomes:
+ * 0x3A2E0009 =3D> addi 17, 14, 9
*/
=20
#include <stdint.h>
|
|
From: <sv...@va...> - 2005-12-02 16:51:48
|
Author: sewardj Date: 2005-12-02 16:51:44 +0000 (Fri, 02 Dec 2005) New Revision: 5271 Log: update Modified: trunk/docs/internals/3_1_BUGSTATUS.txt Modified: trunk/docs/internals/3_1_BUGSTATUS.txt =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- trunk/docs/internals/3_1_BUGSTATUS.txt 2005-12-02 16:45:28 UTC (rev 5= 270) +++ trunk/docs/internals/3_1_BUGSTATUS.txt 2005-12-02 16:51:44 UTC (rev 5= 271) @@ -3,7 +3,7 @@ TRUNK 31BRANCH BUG# WHAT =20 v5262 pending n-i-bz fsub 3,3,3 in ppc32 dispatcher doesn't clea= r NaNs -pending pending n-i-bz ppc32: __NR_setpriority (97) +v5270 pending n-i-bz ppc32: __NR_setpriority (97) pending pending 117332 missing line info with icc 8.1 (x86) pending pending 117362 partially defined equality pending pending 117366 amd64: 0xDD 0x7C fnstsw |
|
From: <sv...@va...> - 2005-12-02 16:45:35
|
Author: sewardj
Date: 2005-12-02 16:45:28 +0000 (Fri, 02 Dec 2005)
New Revision: 5270
Log:
ppc32-linux: enable sys_{set,get}priority.
Modified:
trunk/coregrind/m_syswrap/syswrap-ppc32-linux.c
trunk/coregrind/vki_unistd-ppc32-linux.h
Modified: trunk/coregrind/m_syswrap/syswrap-ppc32-linux.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_syswrap/syswrap-ppc32-linux.c 2005-12-02 16:24:14 U=
TC (rev 5269)
+++ trunk/coregrind/m_syswrap/syswrap-ppc32-linux.c 2005-12-02 16:45:28 U=
TC (rev 5270)
@@ -1560,8 +1560,8 @@
GENX_(__NR_fchmod, sys_fchmod), // 94
=20
LINX_(__NR_fchown, sys_fchown16), // 95
-//.. GENX_(__NR_getpriority, sys_getpriority), // 96
-//.. GENX_(__NR_setpriority, sys_setpriority), // 97
+ GENX_(__NR_getpriority, sys_getpriority), // 96
+ GENX_(__NR_setpriority, sys_setpriority), // 97
//.. GENX_(__NR_profil, sys_ni_syscall), // 98
//.. GENXY(__NR_statfs, sys_statfs), // 99
//..=20
Modified: trunk/coregrind/vki_unistd-ppc32-linux.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/vki_unistd-ppc32-linux.h 2005-12-02 16:24:14 UTC (rev=
5269)
+++ trunk/coregrind/vki_unistd-ppc32-linux.h 2005-12-02 16:45:28 UTC (rev=
5270)
@@ -125,8 +125,8 @@
#define __NR_ftruncate 93
#define __NR_fchmod 94
#define __NR_fchown 95
-//#define __NR_getpriority 96
-//#define __NR_setpriority 97
+#define __NR_getpriority 96
+#define __NR_setpriority 97
//#define __NR_profil 98
//#define __NR_statfs 99
//#define __NR_fstatfs 100
|
|
From: <sv...@va...> - 2005-12-02 16:24:19
|
Author: cerion Date: 2005-12-02 16:24:14 +0000 (Fri, 02 Dec 2005) New Revision: 5269 Log: sync bugstatus Modified: trunk/docs/internals/3_1_BUGSTATUS.txt Modified: trunk/docs/internals/3_1_BUGSTATUS.txt =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- trunk/docs/internals/3_1_BUGSTATUS.txt 2005-12-02 16:16:09 UTC (rev 5= 268) +++ trunk/docs/internals/3_1_BUGSTATUS.txt 2005-12-02 16:24:14 UTC (rev 5= 269) @@ -9,5 +9,5 @@ pending pending 117366 amd64: 0xDD 0x7C fnstsw pending pending 117367 amd64: 0xD9 0xF4 fxtract v5256 v5260 117369 amd64: __NR_getpriority (140) -pending pending 117419 ppc32: lfsu f5, -4(r11) +vx1482 pending 117419 ppc32: lfsu f5, -4(r11) pending pending n-i-bz ppc32: jm-insns doesn't do FP tests |
|
From: <sv...@va...> - 2005-12-02 16:16:14
|
Author: cerion Date: 2005-12-02 16:16:09 +0000 (Fri, 02 Dec 2005) New Revision: 5268 Log: update 3_1_BUGSTATUS Modified: trunk/docs/internals/3_1_BUGSTATUS.txt Modified: trunk/docs/internals/3_1_BUGSTATUS.txt =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- trunk/docs/internals/3_1_BUGSTATUS.txt 2005-12-02 15:55:27 UTC (rev 5= 267) +++ trunk/docs/internals/3_1_BUGSTATUS.txt 2005-12-02 16:16:09 UTC (rev 5= 268) @@ -2,7 +2,7 @@ =20 TRUNK 31BRANCH BUG# WHAT =20 -pending pending n-i-bz fsub 3,3,3 in ppc32 dispatcher doesn't clea= r NaNs +v5262 pending n-i-bz fsub 3,3,3 in ppc32 dispatcher doesn't clea= r NaNs pending pending n-i-bz ppc32: __NR_setpriority (97) pending pending 117332 missing line info with icc 8.1 (x86) pending pending 117362 partially defined equality @@ -10,3 +10,4 @@ pending pending 117367 amd64: 0xD9 0xF4 fxtract v5256 v5260 117369 amd64: __NR_getpriority (140) pending pending 117419 ppc32: lfsu f5, -4(r11) +pending pending n-i-bz ppc32: jm-insns doesn't do FP tests |
|
From: <sv...@va...> - 2005-12-02 16:03:58
|
Author: cerion
Date: 2005-12-02 16:03:46 +0000 (Fri, 02 Dec 2005)
New Revision: 1482
Log:
Re-enabled ppc32 frontend floating point load/store single precision insn=
s:
- lfsu, stfsu, stfsux
Note: fp store single precision insns are being rounded twice, giving a l=
oss of precision... this needs some thinking to solve properly...
Modified:
trunk/priv/guest-ppc32/toIR.c
Modified: trunk/priv/guest-ppc32/toIR.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/guest-ppc32/toIR.c 2005-12-02 13:53:39 UTC (rev 1481)
+++ trunk/priv/guest-ppc32/toIR.c 2005-12-02 16:03:46 UTC (rev 1482)
@@ -54,6 +54,12 @@
- lvxl,stvxl: load/store with 'least recently used' hint
- vexptefp, vlogefp
=20
+ Floating Point
+ - Single precision stores are rounded twice - once by F64toF32,
+ and then again by the backend for storeBE( F32 ), giving a loss
+ of precision.
+
+
LIMITATIONS:
=20
Various, including:
@@ -4959,16 +4965,16 @@
putFReg( frD_addr, unop(Iop_F32toF64, loadBE(Ity_F32, mkexpr(EA)))=
);
break;
=20
-//zz case 0x31: // lfsu (Load Float Single with Update, PPC32 p442)
-//zz if (rA_addr =3D=3D 0) {
-//zz vex_printf("dis_fp_load(PPC32)(instr,lfsu)\n");
-//zz return False;
-//zz }
-//zz DIP("lfsu fr%u,%d(r%u)\n", frD_addr, simm16, rA_addr);
-//zz assign( EA, ea_rA_simm(rA_addr, simm16) );
-//zz putFReg( frD_addr, unop(Iop_F32toF64, loadBE(Ity_F32, mkexpr(=
EA))) );
-//zz putIReg( rA_addr, mkexpr(EA) );
-//zz break;
+ case 0x31: // lfsu (Load Float Single with Update, PPC32 p442)
+ if (rA_addr =3D=3D 0) {
+ vex_printf("dis_fp_load(PPC32)(instr,lfsu)\n");
+ return False;
+ }
+ DIP("lfsu fr%u,%d(r%u)\n", frD_addr, simm16, rA_addr);
+ assign( EA, ea_rA_simm(rA_addr, simm16) );
+ putFReg( frD_addr, unop(Iop_F32toF64, loadBE(Ity_F32, mkexpr(EA)))=
);
+ putIReg( rA_addr, mkexpr(EA) );
+ break;
=20
case 0x32: // lfd (Load Float Double, PPC32 p437)
DIP("lfd fr%u,%d(r%u)\n", frD_addr, simm16, rA_addr);
@@ -5078,17 +5084,17 @@
binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) );
break;
=20
-//zz case 0x35: // stfsu (Store Float Single with Update, PPC32 p519)
-//zz if (rA_addr =3D=3D 0) {
-//zz vex_printf("dis_fp_store(PPC32)(instr,stfsu)\n");
-//zz return False;
-//zz }
-//zz DIP("stfsu fr%u,%d(r%u)\n", frS_addr, simm16, rA_addr);
-//zz assign( EA, ea_rA_simm(rA_addr, simm16) );
-//zz storeBE( mkexpr(EA),
-//zz binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS))=
);
-//zz putIReg( rA_addr, mkexpr(EA) );
-//zz break;
+ case 0x35: // stfsu (Store Float Single with Update, PPC32 p519)
+ if (rA_addr =3D=3D 0) {
+ vex_printf("dis_fp_store(PPC32)(instr,stfsu)\n");
+ return False;
+ }
+ DIP("stfsu fr%u,%d(r%u)\n", frS_addr, simm16, rA_addr);
+ assign( EA, ea_rA_simm(rA_addr, simm16) );
+ storeBE( mkexpr(EA),
+ binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) );
+ putIReg( rA_addr, mkexpr(EA) );
+ break;
=20
case 0x36: // stfd (Store Float Double, PPC32 p513)
DIP("stfd fr%u,%d(r%u)\n", frS_addr, simm16, rA_addr);
@@ -5121,17 +5127,17 @@
binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) )=
;
break;
=20
-//zz case 0x2B7: // stfsux (Store Float Single with Update Indexed, PP=
C32 p520)
-//zz if (rA_addr =3D=3D 0) {
-//zz vex_printf("dis_fp_store(PPC32)(instr,stfsux)\n");
-//zz return False;
-//zz }
-//zz DIP("stfsux fr%u,r%u,r%u\n", frS_addr, rA_addr, rB_addr);
-//zz assign( EA, ea_rA_idxd(rA_addr, rB_addr) );
-//zz storeBE( mkexpr(EA),
-//zz binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) =
);
-//zz putIReg( rA_addr, mkexpr(EA) );
-//zz break;
+ case 0x2B7: // stfsux (Store Float Single with Update Indexed, PPC=
32 p520)
+ if (rA_addr =3D=3D 0) {
+ vex_printf("dis_fp_store(PPC32)(instr,stfsux)\n");
+ return False;
+ }
+ DIP("stfsux fr%u,r%u,r%u\n", frS_addr, rA_addr, rB_addr);
+ assign( EA, ea_rA_idxd(rA_addr, rB_addr) );
+ storeBE( mkexpr(EA),
+ binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) )=
;
+ putIReg( rA_addr, mkexpr(EA) );
+ break;
=20
case 0x2D7: // stfdx (Store Float Double Indexed, PPC32 p516)
DIP("stfdx fr%u,r%u,r%u\n", frS_addr, rA_addr, rB_addr);
|
|
From: <sv...@va...> - 2005-12-02 15:55:34
|
Author: cerion
Date: 2005-12-02 15:55:27 +0000 (Fri, 02 Dec 2005)
New Revision: 5267
Log:
Added tests for ppc32 floating point load/stores
- not yet set to run in automated test.
Modified:
trunk/none/tests/ppc32/jm-insns.c
Modified: trunk/none/tests/ppc32/jm-insns.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/none/tests/ppc32/jm-insns.c 2005-12-02 14:28:28 UTC (rev 5266)
+++ trunk/none/tests/ppc32/jm-insns.c 2005-12-02 15:55:27 UTC (rev 5267)
@@ -221,7 +221,29 @@
#define FDPRINTF(fmt, args...) do { } while (0)
#endif
=20
+/* Produce the 64-bit pattern corresponding to the supplied double. */
+static uint64_t double_to_bits ( double d )
+{
+ union { uint64_t i; double d; } u;
+ assert(8 =3D=3D sizeof(uint64_t));
+ assert(8 =3D=3D sizeof(double));
+ assert(8 =3D=3D sizeof(u));
+ u.d =3D d;
+ return u.i;
+}
=20
+#if 0
+static float bits_to_float ( uint32_t i )
+{
+ union { uint32_t i; float f; } u;
+ assert(4 =3D=3D sizeof(uint32_t));
+ assert(4 =3D=3D sizeof(float));
+ assert(4 =3D=3D sizeof(u));
+ u.i =3D i;
+ return u.f;
+}
+#endif
+
#define unused __attribute__ (( unused ))
=20
/* -------------- BEGIN #include "ops-ppc.c" -------------- */
@@ -1745,6 +1767,154 @@
};
#endif /* !defined (NO_FLOAT) */
=20
+
+#if !defined (NO_FLOAT)
+extern void test_lfs (void);
+asm(".text\n"
+ "test_lfs:\n"
+ "\tlfs 17,0(14)\n"
+ "\tblr\n"
+ ".previous\n"
+);
+
+extern void test_lfsu (void);
+asm(".text\n"
+ "test_lfsu:\n"
+ "\tlfsu 17,0(14)\n"
+ "\tblr\n"
+ ".previous\n"
+);
+
+extern void test_lfd (void);
+asm(".text\n"
+ "test_lfd:\n"
+ "\tlfd 17,0(14)\n"
+ "\tblr\n"
+ ".previous\n"
+);
+
+extern void test_lfdu (void);
+asm(".text\n"
+ "test_lfdu:\n"
+ "\tlfdu 17,0(14)\n"
+ "\tblr\n"
+ ".previous\n"
+);
+
+static test_t tests_fld_ops_two_i16[] =3D {
+ { &test_lfs , " lfs", },
+ { &test_lfsu , " lfsu", },
+ { &test_lfd , " lfd", },
+ { &test_lfdu , " lfdu", },
+ { NULL, NULL, },
+};
+#endif /* !defined (NO_FLOAT) */
+
+#if !defined (NO_FLOAT)
+static void test_lfsx (void)
+{
+ __asm__ __volatile__ ("lfsx 17,14,15");
+}
+
+static void test_lfsux (void)
+{
+ __asm__ __volatile__ ("lfsux 17,14,15");
+}
+
+static void test_lfdx (void)
+{
+ __asm__ __volatile__ ("lfdx 17,14,15");
+}
+
+static void test_lfdux (void)
+{
+ __asm__ __volatile__ ("lfdux 17,14,15");
+}
+
+static test_t tests_fld_ops_two[] =3D {
+ { &test_lfsx , " lfsx", },
+ { &test_lfsux , " lfsux", },
+ { &test_lfdx , " lfdx", },
+ { &test_lfdux , " lfdux", },
+ { NULL, NULL, },
+};
+#endif /* !defined (NO_FLOAT) */
+
+#if !defined (NO_FLOAT)
+extern void test_stfs (void);
+asm(".text\n"
+ "test_stfs:\n"
+ "\tstfs 14,0(15)\n"
+ "\tblr\n"
+ ".previous\n"
+);
+
+extern void test_stfsu (void);
+asm(".text\n"
+ "test_stfsu:\n"
+ "\tstfsu 14,0(15)\n"
+ "\tblr\n"
+ ".previous\n"
+);
+
+extern void test_stfd (void);
+asm(".text\n"
+ "test_stfd:\n"
+ "\tstfd 14,0(15)\n"
+ "\tblr\n"
+ ".previous\n"
+);
+
+extern void test_stfdu (void);
+asm(".text\n"
+ "test_stfdu:\n"
+ "\tstfdu 14,0(15)\n"
+ "\tblr\n"
+ ".previous\n"
+);
+
+static test_t tests_fst_ops_three_i16[] =3D {
+// TODO: Fix VEX to stop rounding these twice...
+// { &test_stfs , " stfs", },
+// { &test_stfsu , " stfsu", },
+ { &test_stfd , " stfd", },
+ { &test_stfdu , " stfdu", },
+ { NULL, NULL, },
+};
+#endif /* !defined (NO_FLOAT) */
+
+#if !defined (NO_FLOAT)
+static void test_stfsx (void)
+{
+ __asm__ __volatile__ ("stfsx 14,15,16");
+}
+
+static void test_stfsux (void)
+{
+ __asm__ __volatile__ ("stfsux 14,15,16");
+}
+
+static void test_stfdx (void)
+{
+ __asm__ __volatile__ ("stfdx 14,15,16");
+}
+
+static void test_stfdux (void)
+{
+ __asm__ __volatile__ ("stfdux 14,15,16");
+}
+
+static test_t tests_fst_ops_three[] =3D {
+// TODO: Fix VEX to stop rounding these twice...
+// { &test_stfsx , " stfsx", },
+// { &test_stfsux , " stfsux", },
+ { &test_stfdx , " stfdx", },
+ { &test_stfdux , " stfdux", },
+ { NULL, NULL, },
+};
+#endif /* !defined (NO_FLOAT) */
+
+
#if defined (HAS_ALTIVEC)
static void test_vmhaddshs (void)
{
@@ -3509,7 +3679,7 @@
#endif /* !defined (NO_FLOAT) */
#if !defined (NO_FLOAT)
{
- tests_far_ops_three ,
+ tests_far_ops_three ,
"PPC floating point arith insns\n with three args with flags =
update",
0x01020103,
},
@@ -3563,6 +3733,34 @@
0x01020207,
},
#endif /* !defined (NO_FLOAT) */
+#if !defined (NO_FLOAT)
+ {
+ tests_fld_ops_two_i16 ,
+ "PPC float load insns\n with one register + one 16 bits immed=
iate args with flags update",
+ 0x00020508,
+ },
+#endif /* !defined (NO_FLOAT) */
+#if !defined (NO_FLOAT)
+ {
+ tests_fld_ops_two ,
+ "PPC float load insns with two register args",
+ 0x00020509,
+ },
+#endif /* !defined (NO_FLOAT) */
+#if !defined (NO_FLOAT)
+ {
+ tests_fst_ops_three_i16,
+ "PPC float store insns\n with one register + one 16 bits imme=
diate args with flags update",
+ 0x0002050a,
+ },
+#endif /* !defined (NO_FLOAT) */
+#if !defined (NO_FLOAT)
+ {
+ tests_fst_ops_three ,
+ "PPC float store insns with three register args",
+ 0x0002050b,
+ },
+#endif /* !defined (NO_FLOAT) */
#if defined (HAS_ALTIVEC)
{
tests_aa_ops_three ,
@@ -3725,19 +3923,34 @@
=20
static void build_fargs_table (void)
{
- /* Sign goes from zero to one
- * Exponent goes from 0 to ((1 << 12) - 1)
- * Mantissa goes from 1 to ((1 << 52) - 1)
+ /* Double precision:
+ * Sign goes from zero to one (1 bit)
+ * Exponent goes from 0 to ((1 << 12) - 1) (11 bits)
+ * Mantissa goes from 1 to ((1 << 52) - 1) (52 bits)
* + special values:
- * +0.0 : 0 0x000 0x0000000000000
- * -0.0 : 1 0x000 0x0000000000000
- * +infinity : 0 0x7FF 0x0000000000000
- * -infinity : 1 0x7FF 0x0000000000000
- * +SNaN : 0 0x7FF 0x7FFFFFFFFFFFF
- * -SNaN : 1 0x7FF 0x7FFFFFFFFFFFF
- * +QNaN : 0 0x7FF 0x8000000000000
- * -QNaN : 1 0x7FF 0x8000000000000
+ * +0.0 : 0 0x000 0x0000000000000 =3D> 0x0000000000000000
+ * -0.0 : 1 0x000 0x0000000000000 =3D> 0x8000000000000000
+ * +infinity : 0 0x7FF 0x0000000000000 =3D> 0x7FF0000000000000
+ * -infinity : 1 0x7FF 0x0000000000000 =3D> 0xFFF0000000000000
+ * +QNaN : 0 0x7FF 0x7FFFFFFFFFFFF =3D> 0x7FF7FFFFFFFFFFFF
+ * -QNaN : 1 0x7FF 0x7FFFFFFFFFFFF =3D> 0xFFF7FFFFFFFFFFFF
+ * +SNaN : 0 0x7FF 0x8000000000000 =3D> 0x7FF8000000000000
+ * -SNaN : 1 0x7FF 0x8000000000000 =3D> 0xFFF8000000000000
* (8 values)
+
+ * Ref only:
+ * Single precision
+ * Sign: 1 bit
+ * Exponent: 8 bits
+ * Mantissa: 23 bits
+ * +0.0 : 0 0x00 0x000000 =3D> 0x00000000
+ * -0.0 : 1 0x00 0x000000 =3D> 0x80000000
+ * +infinity : 0 0xFF 0x000000 =3D> 0x7F800000
+ * -infinity : 1 0xFF 0x000000 =3D> 0xFF800000
+ * +QNaN : 0 0xFF 0x3FFFFF =3D> 0x7FBFFFFF
+ * -QNaN : 1 0xFF 0x3FFFFF =3D> 0xFFBFFFFF
+ * +SNaN : 0 0xFF 0x400000 =3D> 0x7FC00000
+ * -SNaN : 1 0xFF 0x400000 =3D> 0xFFC00000
*/
uint64_t mant;
uint16_t exp, e0, e1;
@@ -3805,27 +4018,28 @@
exp =3D 0x7FF;
mant =3D 0x0000000000000ULL;
register_farg(&fargs[i++], s, exp, mant);
- /* +SNaN : 0 0x7FF 0x7FFFFFFFFFFFF */
+ /* +QNaN : 0 0x7FF 0x7FFFFFFFFFFFF */
s =3D 0;
exp =3D 0x7FF;
mant =3D 0x7FFFFFFFFFFFFULL;
register_farg(&fargs[i++], s, exp, mant);
- /* -SNaN : 1 0x7FF 0x7FFFFFFFFFFFF */
+ /* -QNaN : 1 0x7FF 0x7FFFFFFFFFFFF */
s =3D 1;
exp =3D 0x7FF;
mant =3D 0x7FFFFFFFFFFFFULL;
register_farg(&fargs[i++], s, exp, mant);
- /* +QNaN : 0 0x7FF 0x8000000000000 */
+ /* +SNaN : 0 0x7FF 0x8000000000000 */
s =3D 0;
exp =3D 0x7FF;
mant =3D 0x8000000000000ULL;
register_farg(&fargs[i++], s, exp, mant);
- /* -QNaN : 1 0x7FF 0x8000000000000 */
+ /* -SNaN : 1 0x7FF 0x8000000000000 */
s =3D 1;
exp =3D 0x7FF;
mant =3D 0x8000000000000ULL;
register_farg(&fargs[i++], s, exp, mant);
AB_DPRINTF("Registered %d fargs values\n", i);
+
nb_fargs =3D i;
}
=20
@@ -3920,11 +4134,9 @@
vector uint32_t* vfargI =3D (vector uint32_t*)vfarg;
=20
tmp =3D ((uint64_t)s << 31) | ((uint64_t)exp << 23) | mant;
- //float f =3D *(float*)&tmp;
- //*vfarg =3D (vector float){ f,f,f,f };
*vfargI =3D (vector uint32_t){ tmp,tmp,tmp,tmp };
AB_DPRINTF("%d %02x %06x =3D> %08x %0e\n",
- s, exp, mant, *((uint32_t*)&tmp), f);
+ s, exp, mant, *((uint32_t*)&tmp), *(float*)&tmp);
}
=20
static void build_vfargs_table (void)
@@ -5128,12 +5340,12 @@
=20
// +ve d
for (i=3D0; i<nb_iargs; i++) {
- j =3D i * 4; // sizeof(uint32_t)
+ j =3D i * 4; // offset =3D i * sizeof(uint32_=
t)
p =3D (void *)func;
func_buf[1] =3D p[1];
patch_op_imm16(func_buf, p, j);
func =3D (void *)func_buf;
- r14 =3D (uint32_t)&iargs[0];
+ r14 =3D (uint32_t)&iargs[0]; // base reg =3D start of array
=20
/* Save flags */
__asm__ __volatile__ ("mfcr 18");
@@ -5411,7 +5623,7 @@
uint64_t u0, u1, u2, ur;
volatile uint32_t flags, tmpcr, tmpxer;
int i, j, k;
- =20
+
for (i=3D0; i<nb_fargs; i+=3D3) {
for (j=3D0; j<nb_fargs; j+=3D5) {
for (k=3D0; k<nb_fargs; k+=3D7) {
@@ -5421,6 +5633,7 @@
f14 =3D fargs[i];
f15 =3D fargs[j];
f16 =3D fargs[k];
+
/* Save flags */
__asm__ __volatile__ ("mfcr 18");
tmpcr =3D r18;
@@ -5588,6 +5801,251 @@
test_special(special_float_ops, name, func, test_flags);
}
=20
+
+static void test_float_ld_one_reg_imm16 (const char* name,
+ test_func_t func,
+ unused uint32_t test_flags)
+{
+ uint32_t base, func_buf[2], *p;
+ volatile uint32_t flags, xer, tmpcr, tmpxer;
+ volatile double src, res;
+ int i, offs;
+
+ /* offset within [1-nb_fargs:nb_fargs] */
+ for (i=3D1-nb_fargs; i<nb_fargs; i++) {
+ offs =3D i * 8; // offset =3D i * sizeof(double)
+ if (i < 0) {
+ src =3D fargs[nb_fargs-1 + i];
+ base =3D (uint32_t)&fargs[nb_fargs-1];
+ } else {
+ src =3D fargs[i];
+ base =3D (uint32_t)&fargs[0];
+ }
+
+ p =3D (void *)func;
+ func_buf[1] =3D p[1];
+ patch_op_imm16(func_buf, p, offs);
+ func =3D (void *)func_buf;
+
+ // load from fargs[idx] =3D> r14 + offs
+ r14 =3D base;
+
+ /* Save flags */
+ __asm__ __volatile__ ("mfcr 18");
+ tmpcr =3D r18;
+ __asm__ __volatile__ ("mfxer 18");
+ tmpxer =3D r18;
+ =20
+ /* Set up flags for test */
+ r18 =3D 0;
+ __asm__ __volatile__ ("mtcr 18");
+ __asm__ __volatile__ ("mtxer 18");
+ (*func)();
+ __asm__ __volatile__ ("mfcr 18");
+ flags =3D r18;
+ __asm__ __volatile__ ("mfxer 18");
+ xer =3D r18;
+ res =3D f17;
+
+ /* Restore flags */
+ r18 =3D tmpcr;
+ __asm__ __volatile__ ("mtcr 18");
+ r18 =3D tmpxer;
+ __asm__ __volatile__ ("mtxer 18");
+
+ printf("%s %016llx, %4d =3D> %016llx, %08x (%08x %08x)\n",
+ name, double_to_bits(src), offs,
+ double_to_bits(res), r14, flags, xer);
+ }
+ if (verbose) printf("\n");
+}
+
+static void test_float_ld_two_regs (const char* name,
+ test_func_t func,
+ unused uint32_t test_flags)
+{
+ volatile uint32_t base, flags, xer, tmpcr, tmpxer;
+ volatile double src, res;
+ int i;
+ =20
+ /* offset within [1-nb_fargs:nb_fargs] */
+ for (i=3D1-nb_fargs; i<nb_fargs; i++) {
+ r15 =3D i * 8; // offset =3D i * sizeof(double)
+ if (i < 0) { // base reg =3D start of array
+ src =3D fargs[nb_fargs-1 + i];
+ base =3D (uint32_t)&fargs[nb_fargs-1];
+ } else {
+ src =3D fargs[i];
+ base =3D (uint32_t)&fargs[0];
+ }
+
+ r14 =3D base;
+
+ /* Save flags */
+ __asm__ __volatile__ ("mfcr 18");
+ tmpcr =3D r18;
+ __asm__ __volatile__ ("mfxer 18");
+ tmpxer =3D r18;
+ =20
+ /* Set up flags for test */
+ r18 =3D 0;
+ __asm__ __volatile__ ("mtcr 18");
+ __asm__ __volatile__ ("mtxer 18");
+ (*func)();
+ __asm__ __volatile__ ("mfcr 18");
+ flags =3D r18;
+ __asm__ __volatile__ ("mfxer 18");
+ xer =3D r18;
+ res =3D f17;
+
+ /* Restore flags */
+ r18 =3D tmpcr;
+ __asm__ __volatile__ ("mtcr 18");
+ r18 =3D tmpxer;
+ __asm__ __volatile__ ("mtxer 18");
+
+ printf("%s %016llx, %4d =3D> %016llx, %08x (%08x %08x)\n",
+ name, double_to_bits(src), r15,
+ double_to_bits(res), r14, flags, xer);
+ }
+}
+
+static void test_float_st_two_regs_imm16 (const char* name,
+ test_func_t func,
+ unused uint32_t test_flags)
+{
+ uint32_t base, func_buf[2], *p;
+ volatile uint32_t flags, xer, tmpcr, tmpxer;
+ double src, *p_dst;
+ int i, offs;
+ double *fargs_priv;
+ =20
+ // private fargs table to store to
+ fargs_priv =3D malloc(nb_fargs * sizeof(double));
+ =20
+ /* offset within [1-nb_fargs:nb_fargs] */
+ for (i=3D1-nb_fargs; i<nb_fargs; i++) {
+ offs =3D i * 8; // offset =3D i * sizeof(double)
+ if (i < 0) {
+ src =3D fargs [nb_fargs-1 + i];
+ p_dst =3D &fargs_priv[nb_fargs-1 + i];
+ base =3D (uint32_t)&fargs_priv[nb_fargs-1];
+ } else {
+ src =3D fargs [i];
+ p_dst =3D &fargs_priv[i];
+ base =3D (uint32_t)&fargs_priv[0];
+ }
+ *p_dst =3D 0; // clear dst
+
+ p =3D (void *)func;
+ func_buf[1] =3D p[1];
+ patch_op_imm16(func_buf, p, offs);
+ func =3D (void *)func_buf;
+
+ // read from fargs[idx] =3D> f14
+ // store to fargs_priv[idx] =3D> r15 + offs
+ f14 =3D src;
+ r15 =3D base;
+
+ /* Save flags */
+ __asm__ __volatile__ ("mfcr 18");
+ tmpcr =3D r18;
+ __asm__ __volatile__ ("mfxer 18");
+ tmpxer =3D r18;
+ =20
+ /* Set up flags for test */
+ r18 =3D 0;
+ __asm__ __volatile__ ("mtcr 18");
+ __asm__ __volatile__ ("mtxer 18");
+ (*func)();
+ __asm__ __volatile__ ("mfcr 18");
+ flags =3D r18;
+ __asm__ __volatile__ ("mfxer 18");
+ xer =3D r18;
+
+ /* Restore flags */
+ r18 =3D tmpcr;
+ __asm__ __volatile__ ("mtcr 18");
+ r18 =3D tmpxer;
+ __asm__ __volatile__ ("mtxer 18");
+
+ printf("%s %016llx, %4d =3D> %016llx, %08x (%08x %08x)\n",
+ name, double_to_bits(src), offs,
+ double_to_bits(*p_dst), r15, flags, xer);
+ }
+ free(fargs_priv);
+}
+
+static void test_float_st_three_regs (const char* name,
+ test_func_t func,
+ unused uint32_t test_flags)
+{
+ volatile uint32_t base, flags, xer, tmpcr, tmpxer;
+ double src, *p_dst;
+ int i, offs;
+ double *fargs_priv;
+
+ // private fargs table to store to
+ fargs_priv =3D malloc(nb_fargs * sizeof(double));
+ =20
+ // /* offset within [1-nb_fargs:nb_fargs] */
+ // for (i=3D1-nb_fargs; i<nb_fargs; i++) {
+ for (i=3D0; i<nb_fargs; i++) {
+ offs =3D i * 8; // offset =3D i * sizeof(double)
+ if (i < 0) {
+ src =3D fargs [nb_fargs-1 + i];
+ p_dst =3D &fargs_priv[nb_fargs-1 + i];
+ base =3D (uint32_t)&fargs_priv[nb_fargs-1];
+ } else {
+ src =3D fargs [i];
+ p_dst =3D &fargs_priv[i];
+ base =3D (uint32_t)&fargs_priv[0];
+ }
+ *p_dst =3D 0; // clear dst
+
+ f14 =3D src; // read from fargs
+ r15 =3D base; // store to r15 + offs
+ r16 =3D offs;
+
+ /* Save flags */
+ __asm__ __volatile__ ("mfcr 18");
+ tmpcr =3D r18;
+ __asm__ __volatile__ ("mfxer 18");
+ tmpxer =3D r18;
+ =20
+ /* Set up flags for test */
+ r18 =3D 0;
+ __asm__ __volatile__ ("mtcr 18");
+ __asm__ __volatile__ ("mtxer 18");
+ (*func)();
+ __asm__ __volatile__ ("mfcr 18");
+ flags =3D r18;
+ __asm__ __volatile__ ("mfxer 18");
+ xer =3D r18;
+
+ /* Restore flags */
+ r18 =3D tmpcr;
+ __asm__ __volatile__ ("mtcr 18");
+ r18 =3D tmpxer;
+ __asm__ __volatile__ ("mtxer 18");
+
+#if 1
+ printf("%s %016llx (%014e), %4d =3D> %016llx (%014e), %08x (%08x %=
08x)\n",
+ name, double_to_bits(src), src, offs,
+ double_to_bits(*p_dst), *p_dst, r15, flags, xer);
+#else
+ // print single precision result
+ printf("%s %016llx (%014e), %4d =3D> %08x (%f), %08x (%08x %08x)\n=
",
+ name, double_to_bits(src), src, offs,
+ (uint32_t)(double_to_bits(*p_dst) >> 32),
+ bits_to_float( (uint32_t)(double_to_bits(*p_dst) >> 32) ),
+ r15, flags, xer);
+#endif
+ }
+ free(fargs_priv);
+}
+
+
/* Used in do_tests, indexed by flags->nb_args
Elements correspond to enum test_flags::num args
*/
@@ -5599,10 +6057,10 @@
NULL,
NULL,
&test_float_special,
- NULL,
- NULL,
- NULL,
- NULL,
+ &test_float_ld_one_reg_imm16,
+ &test_float_ld_two_regs,
+ &test_float_st_two_regs_imm16,
+ &test_float_st_three_regs,
};
#endif /* !defined (NO_FLOAT) */
=20
|
|
From: <sv...@va...> - 2005-12-02 14:28:34
|
Author: sewardj
Date: 2005-12-02 14:28:28 +0000 (Fri, 02 Dec 2005)
New Revision: 5266
Log:
Initial function wrapping hacks. Note, a work in progress - expect
borkage. Works well enough to intercept pthread_mutex_{lock,unlock}.
- Add a new auxiliary tt/tc structure for unredirected translations.
There's no getting around the problem that in this situation there
are going to have to be two different translations of function=20
wrapper entries -- the redirected and unredirected versions.
- Add a new client request to set this thread's NOREDIR pseudo-reg,
which causes the next entry into a redirected function to branch
to the unredirected version.
- Add scheduler stuff to catch such jumps and run the unredir'd
translations
- Add a couple of pthread-related wrappers for testing, in vg_preloaded.c
=20
Modified:
branches/FNWRAP/coregrind/m_debuginfo/symtab.c
branches/FNWRAP/coregrind/m_errormgr.c
branches/FNWRAP/coregrind/m_main.c
branches/FNWRAP/coregrind/m_scheduler/scheduler.c
branches/FNWRAP/coregrind/m_translate.c
branches/FNWRAP/coregrind/m_transtab.c
branches/FNWRAP/coregrind/pub_core_dispatch_asm.h
branches/FNWRAP/coregrind/pub_core_translate.h
branches/FNWRAP/coregrind/pub_core_transtab.h
branches/FNWRAP/coregrind/vg_preloaded.c
branches/FNWRAP/include/valgrind.h
Modified: branches/FNWRAP/coregrind/m_debuginfo/symtab.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/coregrind/m_debuginfo/symtab.c 2005-12-02 13:29:07 UT=
C (rev 5265)
+++ branches/FNWRAP/coregrind/m_debuginfo/symtab.c 2005-12-02 14:28:28 UT=
C (rev 5266)
@@ -1876,13 +1876,24 @@
table is designed we have no option but to do a complete linear
scan of the table. Returns NULL if not found. */
=20
+static Bool hacky_match ( Char* patt, Char* in_symtab )
+{
+ Int plen =3D VG_(strlen)(patt);
+ Char* p =3D VG_(strstr)(in_symtab, patt);
+ if (p =3D=3D NULL) return False;
+ if (p[plen] =3D=3D 0 || p[plen] =3D=3D '@') return True;
+ return False;
+}
+
Addr VG_(reverse_search_one_symtab) ( const SegInfo* si, const Char* nam=
e )
{
UInt i;
for (i =3D 0; i < si->symtab_used; i++) {
if (0)=20
VG_(printf)("%p %s\n", si->symtab[i].addr, si->symtab[i].name)=
;
- if (0 =3D=3D VG_(strcmp)(name, si->symtab[i].name))
+ // if (0 =3D=3D VG_(strcmp)(name, si->symtab[i].name))
+ // return si->symtab[i].addr;
+ if (hacky_match(name, si->symtab[i].name))
return si->symtab[i].addr;
}
return (Addr)NULL;
Modified: branches/FNWRAP/coregrind/m_errormgr.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/coregrind/m_errormgr.c 2005-12-02 13:29:07 UTC (rev 5=
265)
+++ branches/FNWRAP/coregrind/m_errormgr.c 2005-12-02 14:28:28 UTC (rev 5=
266)
@@ -765,7 +765,8 @@
StackTrace ips =3D VG_(extract_StackTrace)(p_min->where);
VG_(translate) ( 0 /* dummy ThreadId; irrelevant due to debuggi=
ng*/,
ips[0], /*debugging*/True, 0xFE/*verbosity*/,
- /*bbs_done*/0);
+ /*bbs_done*/0,
+ /*allow redir?*/True);
}
=20
p_min->count =3D 1 << 30;
Modified: branches/FNWRAP/coregrind/m_main.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/coregrind/m_main.c 2005-12-02 13:29:07 UTC (rev 5265)
+++ branches/FNWRAP/coregrind/m_main.c 2005-12-02 14:28:28 UTC (rev 5266)
@@ -1826,7 +1826,7 @@
score_cumul, buf_cumul,
score_here, buf_here, tops[r].addr, name );
VG_(printf)("\n");
- VG_(translate)(0, tops[r].addr, True, VG_(clo_profile_flags), 0);
+ VG_(translate)(0, tops[r].addr, True, VG_(clo_profile_flags), 0, T=
rue);
VG_(printf)("=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D=
end BB rank %d "
"=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D=
\n\n", r);
}
Modified: branches/FNWRAP/coregrind/m_scheduler/scheduler.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/coregrind/m_scheduler/scheduler.c 2005-12-02 13:29:07=
UTC (rev 5265)
+++ branches/FNWRAP/coregrind/m_scheduler/scheduler.c 2005-12-02 14:28:28=
UTC (rev 5266)
@@ -580,6 +580,95 @@
=20
=20
/* ---------------------------------------------------------------------
+ Helper stuff for managing no-redirection translations.
+ ------------------------------------------------------------------ */
+
+/* Run a translation. argblock points to 4 UWords, 2 to carry args
+ and 2 to carry results:
+ 0: input: ptr to translation
+ 1: input: ptr to guest state
+ 2: output: next guest PC
+ 3: output: guest state pointer afterwards (=3D=3D thread return co=
de)
+*/
+extern UWord run_a_translation ( UWord* argblock );
+#if defined(VGP_x86_linux)
+asm("\n"
+".text\n"
+"run_a_translation:\n"
+" pushl %esi\n"
+" pushl %edi\n"
+" pushl %ebp\n"
+" pushl %ebx\n"
+
+" movl 20(%esp), %esi\n"
+" movl 4(%esi), %ebp\n"
+" call *0(%esi)\n"
+
+" movl 20(%esp), %esi\n"
+" movl %eax, 8(%esi)\n"
+" movl %ebp, 12(%esi)\n"
+
+" popl %ebx\n"
+" popl %ebp\n"
+" popl %edi\n"
+" popl %esi\n"
+" ret\n"
+".previous\n"
+);
+#else
+# error "Not implemented"
+#endif
+
+
+/* tid just requested a jump to the noredir version of its current
+ program counter. So make up that translation if needed, run it,
+ and return the resulting thread return code. */
+static UInt/*trc*/ handle_noredir_jump ( ThreadId tid )
+{
+ UInt trc;
+ AddrH hcode =3D 0;
+ Addr ip =3D VG_(get_IP)(tid);
+
+ Bool found =3D VG_(search_unredir_transtab)( &hcode, ip );
+ if (!found) {
+ /* Not found; we need to request a translation. */
+ if (VG_(translate)( tid, ip, /*debug*/False, 0/*not verbose*/, bbs=
_done,
+ False/*NO REDIRECTION*/ )) {
+
+ found =3D VG_(search_unredir_transtab)( &hcode, ip );
+ vg_assert2(found, "unredir translation missing after creation?!=
");
+ =20
+ } else {
+ // If VG_(translate)() fails, it's because it had to throw a
+ // signal because the client jumped to a bad address. That
+ // means that either a signal has been set up for delivery,
+ // or the thread has been marked for termination. Either
+ // way, we just need to go back into the scheduler loop.
+ return VG_TRC_BORING;
+ }
+
+ }
+
+ vg_assert(found);
+ vg_assert(hcode !=3D 0);
+=20
+ { UWord argblock[4];
+ argblock[0] =3D (UWord)hcode;
+ argblock[1] =3D (UWord)&VG_(threads)[tid].arch.vex;
+ argblock[2] =3D 0;
+ argblock[3] =3D 0;
+ trc =3D run_a_translation( &argblock[0] );
+ /* store away the guest program counter */
+ VG_(set_IP)( tid, argblock[2] );
+ if (argblock[3] =3D=3D argblock[1])
+ return VG_TRC_BORING;
+ else
+ return (UInt)argblock[3];
+ }
+}
+
+
+/* ---------------------------------------------------------------------
The scheduler proper.
------------------------------------------------------------------ */
=20
@@ -593,7 +682,8 @@
found =3D VG_(search_transtab)( NULL, ip, True/*upd_fast_cache*/ );
if (!found) {
/* Not found; we need to request a translation. */
- if (VG_(translate)( tid, ip, /*debug*/False, 0/*not verbose*/, bbs=
_done )) {
+ if (VG_(translate)( tid, ip, /*debug*/False, 0/*not verbose*/,=20
+ bbs_done, True/*allow redirection*/ )) {
found =3D VG_(search_transtab)( NULL, ip, True );=20
vg_assert2(found, "VG_TRC_INNER_FASTMISS: missing tt_fast entry=
");
=20
@@ -711,7 +801,23 @@
print_sched_event(tid, buf);
}
=20
- switch(trc) {
+ if (trc =3D=3D VEX_TRC_JMP_NOREDIR) {
+ /* If we got a request to run a no-redir version of
+ something, do so now -- handle_noredir_jump just (creates
+ and) runs that one translation. The flip side is that the
+ noredir translation can't itself return another noredir
+ request -- that would be nonsensical. It can, however,
+ return VG_TRC_BORING, which just means keep going as
+ normal. */
+ trc =3D handle_noredir_jump(tid);
+ vg_assert(trc !=3D VEX_TRC_JMP_NOREDIR);
+ }
+
+ switch (trc) {
+ case VG_TRC_BORING:
+ /* no special event, just keep going. */
+ break;
+
case VG_TRC_INNER_FASTMISS:
vg_assert(VG_(dispatch_ctr) > 1);
handle_tt_miss(tid);
@@ -927,6 +1033,14 @@
zztid, O_CLREQ_RET, sizeof(UWord), f); \
} while (0)
=20
+#define SET_CLIENT_NOREDIR(zztid, zzval) \
+ do { VG_(threads)[zztid].arch.vex.guest_NOREDIR =3D 1; \
+ VG_TRACK( post_reg_write, \
+ Vg_CoreClientReq, zztid, \
+ offsetof(VexGuestArchState,guest_NOREDIR), \
+ sizeof(UWord) ); \
+ } while (0)
+
/* ---------------------------------------------------------------------
Handle client requests.
------------------------------------------------------------------ */
@@ -971,6 +1085,11 @@
VG_(printf)("req no =3D 0x%llx, arg =3D %p\n", (ULong)req_no, arg)=
;
switch (req_no) {
=20
+ case VG_USERREQ__SET_NOREDIR:
+ SET_CLIENT_NOREDIR(tid, 1);
+ SET_CLREQ_RETVAL(tid, 0);
+ break;
+
case VG_USERREQ__CLIENT_CALL0: {
UWord (*f)(ThreadId) =3D (void*)arg[1];
if (f =3D=3D NULL)
Modified: branches/FNWRAP/coregrind/m_translate.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/coregrind/m_translate.c 2005-12-02 13:29:07 UTC (rev =
5265)
+++ branches/FNWRAP/coregrind/m_translate.c 2005-12-02 14:28:28 UTC (rev =
5266)
@@ -445,11 +445,12 @@
Addr64 orig_addr,
Bool debugging_translation,
Int debugging_verbosity,
- ULong bbs_done )
+ ULong bbs_done,
+ Bool allow_redirection )
{
Addr64 redir, orig_addr_noredir =3D orig_addr;
Int tmpbuf_used, verbosity, i;
- Bool notrace_until_done, do_self_check;
+ Bool notrace_until_done, do_self_check, did_redirect;
UInt notrace_until_limit =3D 0;
NSegment* seg;
VexArch vex_arch;
@@ -474,7 +475,13 @@
=20
/* Look in the code redirect table to see if we should
translate an alternative address for orig_addr. */
- redir =3D VG_(code_redirect)(orig_addr);
+ if (allow_redirection) {
+ redir =3D VG_(code_redirect)(orig_addr);
+ did_redirect =3D redir !=3D orig_addr;
+ } else {
+ redir =3D orig_addr;
+ did_redirect =3D False;
+ }
=20
if (redir !=3D orig_addr && VG_(clo_verbosity) >=3D 2) {
Bool ok;
@@ -592,7 +599,11 @@
True, /* cleanup after instrumentation */
do_self_check,
NULL,
- verbosity
+ verbosity,
+ /* If this translation started at a redirected address,
+ then we need to ask the JIT to put in the
+ guest_NOREDIR preamble. */
+ did_redirect =20
);
=20
vg_assert(tres =3D=3D VexTransOK);
@@ -621,13 +632,25 @@
// If debugging, don't do anything with the translated block; we
// only did this for the debugging output produced along the way.
if (!debugging_translation) {
- // Note that we use orig_addr_noredir, not orig_addr, which
- // might have been changed by the redirection
- VG_(add_to_transtab)( &vge,
- orig_addr_noredir,
- (Addr)(&tmpbuf[0]),=20
- tmpbuf_used,
- do_self_check );
+
+ if (allow_redirection) {
+ // Put it into the normal TT/TC structures. This is the
+ // normal case.
+
+ // Note that we use orig_addr_noredir, not orig_addr, which
+ // might have been changed by the redirection
+ VG_(add_to_transtab)( &vge,
+ orig_addr_noredir,
+ (Addr)(&tmpbuf[0]),=20
+ tmpbuf_used,
+ do_self_check );
+ } else {
+ VG_(add_to_unredir_transtab)( &vge,
+ orig_addr_noredir,
+ (Addr)(&tmpbuf[0]),=20
+ tmpbuf_used,
+ do_self_check );
+ }
}
=20
VGP_POPCC(VgpTranslate);
Modified: branches/FNWRAP/coregrind/m_transtab.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/coregrind/m_transtab.c 2005-12-02 13:29:07 UTC (rev 5=
265)
+++ branches/FNWRAP/coregrind/m_transtab.c 2005-12-02 14:28:28 UTC (rev 5=
266)
@@ -1203,6 +1203,114 @@
=20
=20
/*------------------------------------------------------------*/
+/*--- AUXILIARY: the unredirected TT/TC ---*/
+/*------------------------------------------------------------*/
+
+/* A very simple translation cache which holds a small number of
+ unredirected translations. This is completely independent of the
+ main tt/tc structures. When unredir_tc or unredir_tt becomes full,
+ both structures are simply dumped and we start over.
+
+ Since these translations are unredirected, the search key is (by
+ definition) the first address entry in the .vge field. */
+
+/* Sized to hold 500 translations each of size 1000 bytes. */
+
+#define UNREDIR_SZB 1000
+
+#define N_UNREDIR_TT 500
+#define N_UNREDIR_TCQ (N_UNREDIR_TT * UNREDIR_SZB / sizeof(ULong))
+
+typedef
+ struct {
+ VexGuestExtents vge;
+ Addr hcode;
+ Bool inUse;
+ }
+ UTCEntry;
+
+static ULong unredir_tc[N_UNREDIR_TCQ] __attribute__((aligned(8)));
+static Int unredir_tc_used;
+static UTCEntry unredir_tt[N_UNREDIR_TT];
+
+
+static void init_unredir_tt_tc ( void )
+{
+ Int i;
+ unredir_tc_used =3D 0;
+ for (i =3D 0; i < N_UNREDIR_TT; i++)
+ unredir_tt[i].inUse =3D False;
+}
+
+/* Add an UNREDIRECTED translation of vge to TT/TC. The translation
+ is temporarily in code[0 .. code_len-1].
+*/
+void VG_(add_to_unredir_transtab)( VexGuestExtents* vge,
+ Addr64 entry,
+ AddrH code,
+ UInt code_len,
+ Bool is_self_checking )
+{
+ Int i, j, code_szQ;
+ HChar *srcP, *dstP;
+
+ /* This is the whole point: it's not redirected! */
+ vg_assert(entry =3D=3D vge->base[0]);
+
+ /* How many unredir_tt slots are needed */ =20
+ code_szQ =3D (code_len + 7) / 8;
+
+ /* Look for an empty unredir_tc slot */
+ for (i =3D 0; i < N_UNREDIR_TT; i++)
+ if (!unredir_tt[i].inUse)
+ break;
+
+ if (i >=3D N_UNREDIR_TT || code_szQ > (N_UNREDIR_TCQ - unredir_tc_use=
d)) {
+ /* It's full; dump everything we currently have */
+ init_unredir_tt_tc();
+ i =3D 0;
+ }
+
+ vg_assert(unredir_tc_used >=3D 0);
+ vg_assert(unredir_tc_used <=3D N_UNREDIR_TCQ);
+ vg_assert(code_szQ > 0);
+ vg_assert(code_szQ + unredir_tc_used <=3D N_UNREDIR_TCQ);
+ vg_assert(i >=3D 0 && i < N_UNREDIR_TT);
+ vg_assert(unredir_tt[i].inUse =3D=3D False);
+
+ dstP =3D (HChar*)&unredir_tc[unredir_tc_used];
+ srcP =3D (HChar*)code;
+ for (j =3D 0; j < code_len; j++)
+ dstP[j] =3D srcP[j];
+
+ unredir_tt[i].inUse =3D True;
+ unredir_tt[i].vge =3D *vge;
+ unredir_tt[i].hcode =3D (Addr)dstP;
+
+ unredir_tc_used +=3D code_szQ;
+ vg_assert(unredir_tc_used >=3D 0);
+ vg_assert(unredir_tc_used <=3D N_UNREDIR_TCQ);
+
+ vg_assert(&dstP[code_len] <=3D (HChar*)&unredir_tc[unredir_tc_used]);
+}
+
+Bool VG_(search_unredir_transtab) ( /*OUT*/AddrH* result,
+ Addr64 guest_addr )
+{
+ Int i;
+ for (i =3D 0; i < N_UNREDIR_TT; i++) {
+ if (!unredir_tt[i].inUse)
+ continue;
+ if (unredir_tt[i].vge.base[0] =3D=3D guest_addr) {
+ *result =3D (AddrH)unredir_tt[i].hcode;
+ return True;
+ }
+ }
+ return False;
+}
+
+
+/*------------------------------------------------------------*/
/*--- Initialisation. ---*/
/*------------------------------------------------------------*/
=20
Modified: branches/FNWRAP/coregrind/pub_core_dispatch_asm.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/coregrind/pub_core_dispatch_asm.h 2005-12-02 13:29:07=
UTC (rev 5265)
+++ branches/FNWRAP/coregrind/pub_core_dispatch_asm.h 2005-12-02 14:28:28=
UTC (rev 5266)
@@ -42,6 +42,7 @@
=20
/* And some more of our own. These must not have the same values as
those from libvex_trc_values.h. (viz, 60 or below is safe). */
+#define VG_TRC_BORING 29 /* no event; just keep going */
#define VG_TRC_INNER_FASTMISS 37 /* TRC only; means fast-cache miss.=
*/
#define VG_TRC_INNER_COUNTERZERO 41 /* TRC only; means bb ctr =3D=3D 0 =
*/
#define VG_TRC_FAULT_SIGNAL 43 /* TRC only; got sigsegv/sigbus */
Modified: branches/FNWRAP/coregrind/pub_core_translate.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/coregrind/pub_core_translate.h 2005-12-02 13:29:07 UT=
C (rev 5265)
+++ branches/FNWRAP/coregrind/pub_core_translate.h 2005-12-02 14:28:28 UT=
C (rev 5266)
@@ -41,7 +41,8 @@
Addr64 orig_addr,
Bool debugging_translation,
Int debugging_verbosity,
- ULong bbs_done );
+ ULong bbs_done,
+ Bool allow_redirection );
=20
#endif // __PUB_CORE_TRANSLATE_H
=20
Modified: branches/FNWRAP/coregrind/pub_core_transtab.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/coregrind/pub_core_transtab.h 2005-12-02 13:29:07 UTC=
(rev 5265)
+++ branches/FNWRAP/coregrind/pub_core_transtab.h 2005-12-02 14:28:28 UTC=
(rev 5266)
@@ -63,6 +63,19 @@
=20
extern UInt VG_(get_bbs_translated) ( void );
=20
+/* Add to / search the auxiliary, small, unredirected translation
+ table. */
+
+extern
+void VG_(add_to_unredir_transtab)( VexGuestExtents* vge,
+ Addr64 entry,
+ AddrH code,
+ UInt code_len,
+ Bool is_self_checking );
+extern=20
+Bool VG_(search_unredir_transtab) ( /*OUT*/AddrH* result,
+ Addr64 guest_addr );
+
// BB profiling stuff
=20
typedef struct _BBProfEntry {
Modified: branches/FNWRAP/coregrind/vg_preloaded.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/coregrind/vg_preloaded.c 2005-12-02 13:29:07 UTC (rev=
5265)
+++ branches/FNWRAP/coregrind/vg_preloaded.c 2005-12-02 14:28:28 UTC (rev=
5266)
@@ -71,3 +71,68 @@
/*--- end ---*/
/*--------------------------------------------------------------------*/
=20
+#define PTH_FUNC(ret_ty, f, args...) \
+ ret_ty VG_REPLACE_FUNCTION(libpthreadZdsoZd0, f)(args); \
+ ret_ty VG_REPLACE_FUNCTION(libpthreadZdsoZd0, f)(args)
+
+#define LIBC_FUNC(ret_ty, f, args...) \
+ ret_ty VG_REPLACE_FUNCTION(libcZdsoZd6, f)(args); \
+ ret_ty VG_REPLACE_FUNCTION(libcZdsoZd6, f)(args)
+
+#include <stdio.h>
+#include <pthread.h>
+
+#if 1
+PTH_FUNC(int, pthread_create, // pthread_create@*
+ pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start) (void *), void *arg)
+{
+ int ret;
+ fprintf(stderr, "<< pthread_create wrapper"); fflush(stderr);
+
+ VALGRIND_SET_NOREDIR;
+ ret =3D pthread_create(thread, attr, start, arg);
+
+ fprintf(stderr, " -> %d >>\n", ret);
+ return ret;
+}
+
+PTH_FUNC(int, pthread_mutex_lock, pthread_mutex_t *mutex)
+{
+ int ret;
+ fprintf(stderr, "<< pthread_mxlock %p", mutex); fflush(stderr);
+
+ VALGRIND_SET_NOREDIR;
+ ret =3D pthread_mutex_lock(mutex);
+
+ fprintf(stderr, " -> %d >>\n", ret);
+ return ret;
+}
+
+PTH_FUNC(int, pthread_mutex_unlock, pthread_mutex_t *mutex)
+{
+ int ret;
+ fprintf(stderr, "<< pthread_mxunlk %p", mutex); fflush(stderr);
+
+ VALGRIND_SET_NOREDIR;
+ ret =3D pthread_mutex_unlock(mutex);
+
+ fprintf(stderr, " -> %d >>\n", ret);
+ return ret;
+}
+
+#endif
+
+#if 0
+LIBC_FUNC(int, fclose, void* f)
+{
+ int ret;
+ fprintf(stderr, "<< fclose(%p)\n", f);
+
+ VALGRIND_SET_NOREDIR;
+ ret =3D fclose(f);
+
+ fprintf(stderr, ">>\n");
+ return ret;
+}
+#endif
Modified: branches/FNWRAP/include/valgrind.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/include/valgrind.h 2005-12-02 13:29:07 UTC (rev 5265)
+++ branches/FNWRAP/include/valgrind.h 2005-12-02 14:28:28 UTC (rev 5266)
@@ -248,6 +248,7 @@
typedef
enum { VG_USERREQ__RUNNING_ON_VALGRIND =3D 0x1001,
VG_USERREQ__DISCARD_TRANSLATIONS =3D 0x1002,
+ VG_USERREQ__SET_NOREDIR =3D 0x1003,
=20
/* These allow any function to be called from the
simulated CPU but run on the real CPU.
@@ -310,6 +311,19 @@
_qzz_addr, _qzz_len, 0, 0); \
}
=20
+/* Sets this thread's guest_NOREDIR register to 1, so that the next
+ entry by this thread into a redirected translation will cause it
+ instead to jump to the non-redirected version. */
+#define VALGRIND_SET_NOREDIR __extension__ \
+ ({unsigned int _qzz_res; \
+ VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \
+ VG_USERREQ__SET_NOREDIR, \
+ 0, 0, 0, 0); \
+ _qzz_res; \
+ })
+
+
+
#ifdef NVALGRIND
=20
#define VALGRIND_PRINTF(...)
|
|
From: <sv...@va...> - 2005-12-02 13:53:53
|
Author: sewardj
Date: 2005-12-02 13:53:39 +0000 (Fri, 02 Dec 2005)
New Revision: 1481
Log:
When requested by Valgrind, put a "no-redirect" test at the start of
translations. This checks a new guest pseudo-register (guest_NOREDIR)
and if non-zero, it causes the translation to exit immediately,
requesting a transfer to a non-redirected version of itself. This is
a minimal hook needed to get from a function's wrapper back to the
original function, without being endlessly diverted to the wrapper.
Currently is inadequate (will go wrong if any other intercepted
function is encountered on the path between f's wrapper and f) but
that can be fixed.
Modified:
branches/FNWRAP/priv/guest-generic/bb_to_IR.c
branches/FNWRAP/priv/guest-generic/bb_to_IR.h
branches/FNWRAP/priv/guest-x86/ghelpers.c
branches/FNWRAP/priv/host-x86/hdefs.c
branches/FNWRAP/priv/ir/irdefs.c
branches/FNWRAP/priv/main/vex_main.c
branches/FNWRAP/pub/libvex.h
branches/FNWRAP/pub/libvex_guest_amd64.h
branches/FNWRAP/pub/libvex_guest_ppc32.h
branches/FNWRAP/pub/libvex_guest_x86.h
branches/FNWRAP/pub/libvex_ir.h
branches/FNWRAP/pub/libvex_trc_values.h
branches/FNWRAP/test_main.c
Modified: branches/FNWRAP/priv/guest-generic/bb_to_IR.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/priv/guest-generic/bb_to_IR.c 2005-12-02 13:30:11 UTC=
(rev 1480)
+++ branches/FNWRAP/priv/guest-generic/bb_to_IR.c 2005-12-02 13:53:39 UTC=
(rev 1481)
@@ -82,13 +82,16 @@
/*IN*/ DisOneInstrFn dis_instr_fn,
/*IN*/ UChar* guest_code,
/*IN*/ Addr64 guest_IP_bbstart,
+ /*IN*/ Addr64 guest_IP_bbstart_noredir,
/*IN*/ Bool (*chase_into_ok)(Addr64),
/*IN*/ Bool host_bigendian,
/*IN*/ VexArchInfo* archinfo_guest,
/*IN*/ IRType guest_word_type,
/*IN*/ Bool do_self_check,
+ /*IN*/ Bool do_noredir_check,
/*IN*/ Int offB_TISTART,
- /*IN*/ Int offB_TILEN )
+ /*IN*/ Int offB_TILEN,
+ /*IN*/ Int offB_NOREDIR )
{
Long delta;
Int i, n_instrs, first_stmt_idx;
@@ -100,6 +103,8 @@
Int selfcheck_idx =3D 0;
IRBB* irbb;
Addr64 guest_IP_curr_instr;
+ IRConst* guest_IP_bbstart_IRConst =3D NULL;
+ IRConst* guest_IP_bbstart_noredir_IRConst =3D NULL;
=20
Bool (*resteerOKfn)(Addr64) =3D NULL;
=20
@@ -131,6 +136,48 @@
delta =3D 0;
n_instrs =3D 0;
=20
+ /* Guest addresses as IRConsts. Used in the two self-checks
+ generated. */
+ if (do_self_check) {
+ guest_IP_bbstart_IRConst
+ =3D guest_word_type=3D=3DIty_I32=20
+ ? IRConst_U32(toUInt(guest_IP_bbstart))
+ : IRConst_U64(guest_IP_bbstart);
+ }
+
+ if (do_noredir_check) {
+ guest_IP_bbstart_noredir_IRConst
+ =3D guest_word_type=3D=3DIty_I32=20
+ ? IRConst_U32(toUInt(guest_IP_bbstart_noredir))
+ : IRConst_U64(guest_IP_bbstart_noredir);
+ }
+
+ /* If asked to make a noredir-check, put it before the self-check.
+ The noredir-check checks whether we should be running code at
+ this guest address at all, whereas the self-check establishes
+ whether the translation is still valid once we've decided we
+ should be here. So the noredir check comes first. */
+ if (do_noredir_check) {
+ IRTemp noredir_tmp =3D newIRTemp(irbb->tyenv, guest_word_type);
+ IRExpr* zero =3D guest_word_type=3D=3DIty_I32=20
+ ? IRExpr_Const(IRConst_U32(0))=20
+ : IRExpr_Const(IRConst_U64(0));
+ IROp cmpNE =3D guest_word_type=3D=3DIty_I32 ? Iop_CmpNE32 : Iop_Cm=
pNE64;
+
+ /* fetch old setting */
+ addStmtToIRBB( irbb,=20
+ IRStmt_Tmp( noredir_tmp,=20
+ IRExpr_Get( offB_NOREDIR, guest_word_type)));
+ /* zero it */
+ addStmtToIRBB( irbb,
+ IRStmt_Put( offB_NOREDIR, zero ));
+ /* exit if it wasn't zero */
+ addStmtToIRBB( irbb,
+ IRStmt_Exit( IRExpr_Binop( cmpNE, IRExpr_Tmp(noredir_tmp), zero=
),
+ Ijk_NoRedir,
+ guest_IP_bbstart_noredir_IRConst ));
+ }
+
/* If asked to make a self-checking translation, leave a 5 spaces
in which to put the check statements. We'll fill them in later
when we know the length and adler32 of the area to check. */
@@ -298,7 +345,6 @@
if (do_self_check) {
=20
UInt len2check, adler32;
- IRConst* guest_IP_bbstart_IRConst;
IRTemp tistart_tmp, tilen_tmp;
=20
vassert(vge->n_used =3D=3D 1);
@@ -308,11 +354,6 @@
=20
adler32 =3D genericg_compute_adler32( (HWord)guest_code, len2check =
);
=20
- guest_IP_bbstart_IRConst
- =3D guest_word_type=3D=3DIty_I32=20
- ? IRConst_U32(toUInt(guest_IP_bbstart))
- : IRConst_U64(guest_IP_bbstart);
-
/* Set TISTART and TILEN. These will describe to the despatcher
the area of guest code to invalidate should we exit with a
self-check failure. */
Modified: branches/FNWRAP/priv/guest-generic/bb_to_IR.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/priv/guest-generic/bb_to_IR.h 2005-12-02 13:30:11 UTC=
(rev 1480)
+++ branches/FNWRAP/priv/guest-generic/bb_to_IR.h 2005-12-02 13:53:39 UTC=
(rev 1481)
@@ -154,13 +154,16 @@
/*IN*/ DisOneInstrFn dis_instr_fn,
/*IN*/ UChar* guest_code,
/*IN*/ Addr64 guest_IP_bbstart,
+ /*IN*/ Addr64 guest_IP_bbstart_noredir,
/*IN*/ Bool (*chase_into_ok)(Addr64),
/*IN*/ Bool host_bigendian,
/*IN*/ VexArchInfo* archinfo_guest,
/*IN*/ IRType guest_word_type,
/*IN*/ Bool do_self_check,
+ /*IN*/ Bool do_noredir_check,
/*IN*/ Int offB_TISTART,
- /*IN*/ Int offB_TILEN );
+ /*IN*/ Int offB_TILEN,
+ /*IN*/ Int offB_NOREDIR );
=20
=20
#endif /* ndef GENERIC_BB_TO_IR_H */
Modified: branches/FNWRAP/priv/guest-x86/ghelpers.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/priv/guest-x86/ghelpers.c 2005-12-02 13:30:11 UTC (re=
v 1480)
+++ branches/FNWRAP/priv/guest-x86/ghelpers.c 2005-12-02 13:53:39 UTC (re=
v 1481)
@@ -2225,6 +2225,8 @@
/* SSE2 has a 'clflush' cache-line-invalidator which uses these. */
vex_state->guest_TISTART =3D 0;
vex_state->guest_TILEN =3D 0;
+
+ vex_state->guest_NOREDIR =3D 0;
}
=20
=20
Modified: branches/FNWRAP/priv/host-x86/hdefs.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/priv/host-x86/hdefs.c 2005-12-02 13:30:11 UTC (rev 14=
80)
+++ branches/FNWRAP/priv/host-x86/hdefs.c 2005-12-02 13:53:39 UTC (rev 14=
81)
@@ -2165,6 +2165,9 @@
case Ijk_TInval:
*p++ =3D 0xBD;
p =3D emit32(p, VEX_TRC_JMP_TINVAL); break;
+ case Ijk_NoRedir:
+ *p++ =3D 0xBD;
+ p =3D emit32(p, VEX_TRC_JMP_NOREDIR); break;
case Ijk_Sys_sysenter:
*p++ =3D 0xBD;
p =3D emit32(p, VEX_TRC_JMP_SYS_SYSENTER); break;
Modified: branches/FNWRAP/priv/ir/irdefs.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/priv/ir/irdefs.c 2005-12-02 13:30:11 UTC (rev 1480)
+++ branches/FNWRAP/priv/ir/irdefs.c 2005-12-02 13:53:39 UTC (rev 1481)
@@ -679,6 +679,7 @@
case Ijk_NoDecode: vex_printf("NoDecode"); break;
case Ijk_MapFail: vex_printf("MapFail"); break;
case Ijk_TInval: vex_printf("Invalidate"); break;
+ case Ijk_NoRedir: vex_printf("NoRedir"); break;
case Ijk_Sys_syscall: vex_printf("Sys_syscall"); break;
case Ijk_Sys_int32: vex_printf("Sys_int32"); break;
case Ijk_Sys_int128: vex_printf("Sys_int128"); break;
Modified: branches/FNWRAP/priv/main/vex_main.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/priv/main/vex_main.c 2005-12-02 13:30:11 UTC (rev 148=
0)
+++ branches/FNWRAP/priv/main/vex_main.c 2005-12-02 13:53:39 UTC (rev 148=
1)
@@ -207,7 +207,9 @@
/* IN: optionally, an access check function for guest code. */
Bool (*byte_accessible) ( Addr64 ),
/* IN: debug: trace vex activity at various points */
- Int traceflags
+ Int traceflags,
+ /* IN: should this translation do a check of guest_NOREDIR ? */
+ Bool do_noredir_check
)
{
/* This the bundle of functions we need to do the back-end stuff
@@ -235,7 +237,7 @@
HInstrArray* vcode;
HInstrArray* rcode;
Int i, j, k, out_used, guest_sizeB;
- Int offB_TISTART, offB_TILEN;
+ Int offB_TISTART, offB_TILEN, offB_NOREDIR;
UChar insn_bytes[32];
IRType guest_word_type;
IRType host_word_type;
@@ -259,6 +261,7 @@
host_word_type =3D Ity_INVALID;
offB_TISTART =3D 0;
offB_TILEN =3D 0;
+ offB_NOREDIR =3D 0;
=20
vex_traceflags =3D traceflags;
=20
@@ -342,12 +345,14 @@
guest_layout =3D &x86guest_layout;
offB_TISTART =3D offsetof(VexGuestX86State,guest_TISTART);
offB_TILEN =3D offsetof(VexGuestX86State,guest_TILEN);
+ offB_NOREDIR =3D offsetof(VexGuestX86State,guest_NOREDIR);
vassert(archinfo_guest->subarch =3D=3D VexSubArchX86_sse0
|| archinfo_guest->subarch =3D=3D VexSubArchX86_sse1
|| archinfo_guest->subarch =3D=3D VexSubArchX86_sse2);
vassert(0 =3D=3D sizeof(VexGuestX86State) % 8);
vassert(sizeof( ((VexGuestX86State*)0)->guest_TISTART ) =3D=3D =
4);
- vassert(sizeof( ((VexGuestX86State*)0)->guest_TILEN ) =3D=3D 4)=
;
+ vassert(sizeof( ((VexGuestX86State*)0)->guest_TILEN ) =3D=3D =
4);
+ vassert(sizeof( ((VexGuestX86State*)0)->guest_NOREDIR ) =3D=3D =
4);
break;
=20
case VexArchAMD64:
@@ -359,10 +364,12 @@
guest_layout =3D &amd64guest_layout;
offB_TISTART =3D offsetof(VexGuestAMD64State,guest_TISTART)=
;
offB_TILEN =3D offsetof(VexGuestAMD64State,guest_TILEN);
+ offB_NOREDIR =3D offsetof(VexGuestAMD64State,guest_NOREDIR)=
;
vassert(archinfo_guest->subarch =3D=3D VexSubArch_NONE);
vassert(0 =3D=3D sizeof(VexGuestAMD64State) % 8);
vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TISTART ) =3D=3D=
8);
- vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TILEN ) =3D=3D =
8);
+ vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TILEN ) =3D=3D=
8);
+ vassert(sizeof( ((VexGuestAMD64State*)0)->guest_NOREDIR ) =3D=3D=
8);
break;
=20
case VexArchARM:
@@ -374,6 +381,7 @@
guest_layout =3D &armGuest_layout;
offB_TISTART =3D 0; /* hack ... arm has bitrot */
offB_TILEN =3D 0; /* hack ... arm has bitrot */
+ offB_NOREDIR =3D 0; /* hack ... arm has bitrot */
vassert(archinfo_guest->subarch =3D=3D VexSubArchARM_v4);
break;
=20
@@ -386,12 +394,14 @@
guest_layout =3D &ppc32Guest_layout;
offB_TISTART =3D offsetof(VexGuestPPC32State,guest_TISTART)=
;
offB_TILEN =3D offsetof(VexGuestPPC32State,guest_TILEN);
+ offB_NOREDIR =3D offsetof(VexGuestPPC32State,guest_NOREDIR)=
;
vassert(archinfo_guest->subarch =3D=3D VexSubArchPPC32_I
|| archinfo_guest->subarch =3D=3D VexSubArchPPC32_FI
|| archinfo_guest->subarch =3D=3D VexSubArchPPC32_VFI);
vassert(0 =3D=3D sizeof(VexGuestPPC32State) % 8);
vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TISTART ) =3D=3D=
4);
- vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TILEN ) =3D=3D =
4);
+ vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TILEN ) =3D=3D=
4);
+ vassert(sizeof( ((VexGuestPPC32State*)0)->guest_NOREDIR ) =3D=3D=
4);
break;
=20
default:
@@ -417,13 +427,16 @@
disInstrFn,
guest_bytes,=20
guest_bytes_addr,
+ guest_bytes_addr_noredir,
chase_into_ok,
host_is_bigendian,
archinfo_guest,
guest_word_type,
do_self_check,
+ do_noredir_check,
offB_TISTART,
- offB_TILEN );
+ offB_TILEN,
+ offB_NOREDIR );
=20
vexAllocSanityCheck();
=20
Modified: branches/FNWRAP/pub/libvex.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/pub/libvex.h 2005-12-02 13:30:11 UTC (rev 1480)
+++ branches/FNWRAP/pub/libvex.h 2005-12-02 13:53:39 UTC (rev 1481)
@@ -337,7 +337,9 @@
/* IN: optionally, an access check function for guest code. */
Bool (*byte_accessible) ( Addr64 ),
/* IN: debug: trace vex activity at various points */
- Int traceflags
+ Int traceflags,
+ /* IN: should this translation do a check of guest_NOREDIR ? */
+ Bool do_noredir_check
);
=20
/* A subtlety re interaction between self-checking translations and
@@ -399,6 +401,12 @@
guest code, translations of which are to be invalidated, back to
the despatcher. Both pseudo-regs must have size equal to the guest
word size.
+
+ The architecture must contain a third pseudo-register,
+ guest_NOREDIR, which is guest-word-sized. This is tested and
+ zeroed at the start of translations of redirected blocks (under
+ LibVEX's client's control), and the block immediately exited if it
+ is set.
*/
#endif /* ndef __LIBVEX_H */
=20
Modified: branches/FNWRAP/pub/libvex_guest_amd64.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/pub/libvex_guest_amd64.h 2005-12-02 13:30:11 UTC (rev=
1480)
+++ branches/FNWRAP/pub/libvex_guest_amd64.h 2005-12-02 13:53:39 UTC (rev=
1481)
@@ -145,6 +145,11 @@
ULong guest_TISTART;
ULong guest_TILEN;
=20
+ /* Affects behaviour on entry to redirected translations: if
+ nonzero, will cause an immediate exit and attempt to execute
+ the non-redirected version instead. Is almost always zero. */
+ ULong guest_NOREDIR;
+
/* Padding to make it have an 8-aligned size */
/* UInt padding; */
}
Modified: branches/FNWRAP/pub/libvex_guest_ppc32.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/pub/libvex_guest_ppc32.h 2005-12-02 13:30:11 UTC (rev=
1480)
+++ branches/FNWRAP/pub/libvex_guest_ppc32.h 2005-12-02 13:53:39 UTC (rev=
1481)
@@ -199,14 +199,19 @@
/* Emulation warnings */
/* 940 */ UInt guest_EMWARN;
=20
- /* For icbi: record start and length of area to invalidate */
- /* 944 */ UInt guest_TISTART;
- /* 948 */ UInt guest_TILEN;
-
/* For lwarx/stwcx.: 0 =3D=3D no reservation exists, non-0 =3D=3D =
a
reservation exists. */
- /* 952 */ UInt guest_RESVN;
+ /* 944 */ UInt guest_RESVN;
=20
+ /* For icbi: record start and length of area to invalidate */
+ /* 948 */ UInt guest_TISTART;
+ /* 952 */ UInt guest_TILEN;
+
+ /* Affects behaviour on entry to redirected translations: if
+ nonzero, will cause an immediate exit and attempt to execute
+ the non-redirected version instead. Is almost always zero. */
+ /* 956 */ UInt guest_NOREDIR;
+
/* Padding to make it have an 8-aligned size */
UInt padding;
}
Modified: branches/FNWRAP/pub/libvex_guest_x86.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/pub/libvex_guest_x86.h 2005-12-02 13:30:11 UTC (rev 1=
480)
+++ branches/FNWRAP/pub/libvex_guest_x86.h 2005-12-02 13:53:39 UTC (rev 1=
481)
@@ -218,8 +218,13 @@
UInt guest_TISTART;
UInt guest_TILEN;
=20
+ /* Affects behaviour on entry to redirected translations: if
+ nonzero, will cause an immediate exit and attempt to execute
+ the non-redirected version instead. Is almost always zero. */
+ UInt guest_NOREDIR;
+
/* Padding to make it have an 8-aligned size */
- /* UInt padding; */
+ UInt padding;
}
VexGuestX86State;
=20
Modified: branches/FNWRAP/pub/libvex_ir.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/pub/libvex_ir.h 2005-12-02 13:30:11 UTC (rev 1480)
+++ branches/FNWRAP/pub/libvex_ir.h 2005-12-02 13:53:39 UTC (rev 1481)
@@ -853,6 +853,7 @@
Ijk_NoDecode, /* next instruction cannot be decoded */
Ijk_MapFail, /* Vex-provided address translation failed */
Ijk_TInval, /* Invalidate translations before continuing. =
*/
+ Ijk_NoRedir, /* Jump to un-redirected guest addr */
/* Unfortunately, various guest-dependent syscall kinds. They
all mean: do a syscall before continuing. */
Ijk_Sys_syscall, /* amd64 'syscall', ppc32 'sc' */
Modified: branches/FNWRAP/pub/libvex_trc_values.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/pub/libvex_trc_values.h 2005-12-02 13:30:11 UTC (rev =
1480)
+++ branches/FNWRAP/pub/libvex_trc_values.h 2005-12-02 13:53:39 UTC (rev =
1481)
@@ -58,6 +58,7 @@
=20
#define VEX_TRC_JMP_TINVAL 61 /* invalidate translations before
continuing */
+#define VEX_TRC_JMP_NOREDIR 81 /* jump to undirected guest addr */
#define VEX_TRC_JMP_EMWARN 63 /* deliver emulation warning before
continuing */
#define VEX_TRC_JMP_CLIENTREQ 65 /* do a client req before continuing =
*/
Modified: branches/FNWRAP/test_main.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/test_main.c 2005-12-02 13:30:11 UTC (rev 1480)
+++ branches/FNWRAP/test_main.c 2005-12-02 13:53:39 UTC (rev 1481)
@@ -169,7 +169,8 @@
#endif
False, /* do_self_check ? */
NULL, /* access checker */
- TEST_FLAGS=20
+ TEST_FLAGS,
+ False /* do_noredir_check */
);
=20
if (tres !=3D VexTransOK)
|
|
From: <sv...@va...> - 2005-12-02 13:30:25
|
Author: sewardj Date: 2005-12-02 13:30:11 +0000 (Fri, 02 Dec 2005) New Revision: 1480 Log: A branch to play around with function wrapping. Copy of trunk r1479. Added: branches/FNWRAP/ Copied: branches/FNWRAP (from rev 1479, trunk) |
|
From: <sv...@va...> - 2005-12-02 13:29:32
|
Author: sewardj Date: 2005-12-02 13:29:07 +0000 (Fri, 02 Dec 2005) New Revision: 5265 Log: Swizzle external. Modified: branches/FNWRAP/ Property changes on: branches/FNWRAP ___________________________________________________________________ Name: svn:externals - VEX svn://svn.valgrind.org/vex/trunk + VEX svn://svn.valgrind.org/vex/branches/FNWRAP |
|
From: <sv...@va...> - 2005-12-02 13:26:34
|
Author: sewardj Date: 2005-12-02 13:26:13 +0000 (Fri, 02 Dec 2005) New Revision: 5264 Log: A branch to play around with function wrapping. Copy of trunk r5263. Added: branches/FNWRAP/ Copied: branches/FNWRAP (from rev 5263, trunk) |
|
From: <js...@ac...> - 2005-12-02 03:57:25
|
Nightly build on phoenix ( SuSE 10.0 ) started at 2005-12-02 03:30:01 GMT Checking out vex source tree ... done Building vex ... done Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 208 tests, 5 stderr failures, 1 stdout failure ================= memcheck/tests/leak-tree (stderr) memcheck/tests/stack_switch (stderr) memcheck/tests/x86/scalar (stderr) none/tests/mremap2 (stdout) none/tests/x86/faultstatus (stderr) none/tests/x86/int (stderr) |
|
From: <js...@ac...> - 2005-12-02 03:47:00
|
Nightly build on g5 ( YDL 4.0, ppc970 ) started at 2005-12-02 04:40:00 CET Checking out vex source tree ... done Building vex ... done Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 175 tests, 14 stderr failures, 0 stdout failures ================= memcheck/tests/badjump (stderr) memcheck/tests/badjump2 (stderr) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/partiallydefinedeq (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/supp1 (stderr) memcheck/tests/supp_unknown (stderr) memcheck/tests/toobig-allocs (stderr) memcheck/tests/xml1 (stderr) massif/tests/toobig-allocs (stderr) none/tests/faultstatus (stderr) none/tests/fdleak_cmsg (stderr) none/tests/mremap (stderr) |
|
From: Tom H. <to...@co...> - 2005-12-02 03:46:11
|
Nightly build on dunsmere ( athlon, Fedora Core 4 ) started at 2005-12-02 03:30:06 GMT 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 == 210 tests, 7 stderr failures, 1 stdout failure ================= memcheck/tests/leak-tree (stderr) memcheck/tests/mempool (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/stack_switch (stderr) memcheck/tests/x86/scalar (stderr) none/tests/mremap2 (stdout) none/tests/x86/faultstatus (stderr) none/tests/x86/int (stderr) |
|
From: Tom H. <th...@cy...> - 2005-12-02 03:29:49
|
Nightly build on alvis ( i686, Red Hat 7.3 ) started at 2005-12-02 03:15:04 GMT 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 == 209 tests, 17 stderr failures, 1 stdout failure ================= memcheck/tests/addressable (stderr) memcheck/tests/describe-block (stderr) memcheck/tests/erringfds (stderr) memcheck/tests/leak-0 (stderr) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-regroot (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/leakotron (stdout) memcheck/tests/match-overrun (stderr) memcheck/tests/mempool (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) none/tests/x86/faultstatus (stderr) none/tests/x86/int (stderr) |
|
From: Tom H. <th...@cy...> - 2005-12-02 03:25:48
|
Nightly build on dellow ( x86_64, Fedora Core 4 ) started at 2005-12-02 03:10:20 GMT 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 == 227 tests, 4 stderr failures, 1 stdout failure ================= memcheck/tests/x86/scalar (stderr) none/tests/amd64/faultstatus (stderr) none/tests/mremap2 (stdout) none/tests/x86/faultstatus (stderr) none/tests/x86/int (stderr) |
|
From: Tom H. <th...@cy...> - 2005-12-02 03:21:30
|
Nightly build on gill ( x86_64, Fedora Core 2 ) started at 2005-12-02 03:00:04 GMT 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 == 227 tests, 5 stderr failures, 0 stdout failures ================= memcheck/tests/pointer-trace (stderr) none/tests/amd64/faultstatus (stderr) none/tests/fdleak_fcntl (stderr) none/tests/x86/faultstatus (stderr) none/tests/x86/int (stderr) |
|
From: Tom H. <th...@cy...> - 2005-12-02 03:21:23
|
Nightly build on aston ( x86_64, Fedora Core 3 ) started at 2005-12-02 03:05:13 GMT 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 == 227 tests, 5 stderr failures, 1 stdout failure ================= memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) none/tests/amd64/faultstatus (stderr) none/tests/mremap2 (stdout) none/tests/x86/faultstatus (stderr) none/tests/x86/int (stderr) |