|
From: <sv...@va...> - 2005-04-22 21:10:33
|
Author: sewardj
Date: 2005-04-22 22:10:28 +0100 (Fri, 22 Apr 2005)
New Revision: 3543
Modified:
trunk/memcheck/mc_main.c
Log:
Tidy up: remove lots of old code, rearrange order of functions
somewhat.
Modified: trunk/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
--- trunk/memcheck/mc_main.c 2005-04-22 20:23:27 UTC (rev 3542)
+++ trunk/memcheck/mc_main.c 2005-04-22 21:10:28 UTC (rev 3543)
@@ -30,31 +30,14 @@
The GNU General Public License is contained in the file COPYING.
*/
=20
-/* TODO urgently
+/* TODO 22 Apr 05
=20
- sanity check:=20
- auxmap only covers address space that the primary doesn't
- auxmap entries non-duplicated (expensive)
- there are no secondary map leaks. this can easily be established
- by counting the number of secmaps issued, and ensuring that
- the same number of pointers-to-secmaps from the main/aux
- primary map can be found
- there is only one pointer to each non-distinguished secmap.
-
- types of helper functions
-
- set_address_range_perms to notice when a distinguished secondary
- will work, and use that (viz, re-implement compression scheme)
-
- profile
-
- reinstate fast-path cases
+ test whether it would be faster, for LOADV4, to check
+ only for 8-byte validity on the fast path
*/
=20
-
#include "mc_include.h"
#include "memcheck.h" /* for client requests */
-//#include "vg_profile.c"
=20
=20
#define EXPECTED_TAKEN(cond) __builtin_expect((cond),1)
@@ -79,6 +62,56 @@
/*--- Basic A/V bitmap representation. ---*/
/*------------------------------------------------------------*/
=20
+/* TODO: fix this comment */
+//zz /* All reads and writes are checked against a memory map, which
+//zz records the state of all memory in the process. The memory map =
is
+//zz organised like this:
+//zz=20
+//zz The top 16 bits of an address are used to index into a top-level
+//zz map table, containing 65536 entries. Each entry is a pointer to=
a
+//zz second-level map, which records the accesibililty and validity
+//zz permissions for the 65536 bytes indexed by the lower 16 bits of =
the
+//zz address. Each byte is represented by nine bits, one indicating
+//zz accessibility, the other eight validity. So each second-level m=
ap
+//zz contains 73728 bytes. This two-level arrangement conveniently
+//zz divides the 4G address space into 64k lumps, each size 64k bytes=
.
+//zz=20
+//zz All entries in the primary (top-level) map must point to a valid
+//zz secondary (second-level) map. Since most of the 4G of address
+//zz space will not be in use -- ie, not mapped at all -- there is a
+//zz distinguished secondary map, which indicates `not addressible an=
d
+//zz not valid' writeable for all bytes. Entries in the primary map =
for
+//zz which the entire 64k is not in use at all point at this
+//zz distinguished map.
+//zz=20
+//zz There are actually 4 distinguished secondaries. These are used =
to
+//zz represent a memory range which is either not addressable (validi=
ty
+//zz doesn't matter), addressable+not valid, addressable+valid.
+//zz=20
+//zz [...] lots of stuff deleted due to out of date-ness
+//zz=20
+//zz As a final optimisation, the alignment and address checks for
+//zz 4-byte loads and stores are combined in a neat way. The primary
+//zz map is extended to have 262144 entries (2^18), rather than 2^16.
+//zz The top 3/4 of these entries are permanently set to the
+//zz distinguished secondary map. For a 4-byte load/store, the
+//zz top-level map is indexed not with (addr >> 16) but instead f(add=
r),
+//zz where
+//zz=20
+//zz f( XXXX XXXX XXXX XXXX ____ ____ ____ __YZ )
+//zz =3D ____ ____ ____ __YZ XXXX XXXX XXXX XXXX or=20
+//zz =3D ____ ____ ____ __ZY XXXX XXXX XXXX XXXX
+//zz=20
+//zz ie the lowest two bits are placed above the 16 high address bits=
.
+//zz If either of these two bits are nonzero, the address is misalign=
ed;
+//zz this will select a secondary map from the upper 3/4 of the prima=
ry
+//zz map. Because this is always the distinguished secondary map, a
+//zz (bogus) address check failure will result. The failure handling
+//zz code can then figure out whether this is a genuine addr check
+//zz failure or whether it is a possibly-legitimate access at a
+//zz misaligned address. =20
+//zz */
+
/* --------------- Basic configuration --------------- */
=20
/* The number of entries in the primary map can be altered. However
@@ -387,248 +420,6 @@
}
=20
=20
-///////////////////////////////////////////////////////////////
-
-
-
-
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-
-//zz #if 0 /* this is the old implementation */
-//zz=20
-//zz=20
-//zz=20
-//zz /*------------------------------------------------------------*/
-//zz /*--- Low-level support for memory checking. ---*/
-//zz /*------------------------------------------------------------*/
-//zz=20
-//zz /* All reads and writes are checked against a memory map, which
-//zz records the state of all memory in the process. The memory map =
is
-//zz organised like this:
-//zz=20
-//zz The top 16 bits of an address are used to index into a top-level
-//zz map table, containing 65536 entries. Each entry is a pointer to=
a
-//zz second-level map, which records the accesibililty and validity
-//zz permissions for the 65536 bytes indexed by the lower 16 bits of =
the
-//zz address. Each byte is represented by nine bits, one indicating
-//zz accessibility, the other eight validity. So each second-level m=
ap
-//zz contains 73728 bytes. This two-level arrangement conveniently
-//zz divides the 4G address space into 64k lumps, each size 64k bytes=
.
-//zz=20
-//zz All entries in the primary (top-level) map must point to a valid
-//zz secondary (second-level) map. Since most of the 4G of address
-//zz space will not be in use -- ie, not mapped at all -- there is a
-//zz distinguished secondary map, which indicates `not addressible an=
d
-//zz not valid' writeable for all bytes. Entries in the primary map =
for
-//zz which the entire 64k is not in use at all point at this
-//zz distinguished map.
-//zz=20
-//zz There are actually 4 distinguished secondaries. These are used =
to
-//zz represent a memory range which is either not addressable (validi=
ty
-//zz doesn't matter), addressable+not valid, addressable+valid.
-//zz=20
-//zz [...] lots of stuff deleted due to out of date-ness
-//zz=20
-//zz As a final optimisation, the alignment and address checks for
-//zz 4-byte loads and stores are combined in a neat way. The primary
-//zz map is extended to have 262144 entries (2^18), rather than 2^16.
-//zz The top 3/4 of these entries are permanently set to the
-//zz distinguished secondary map. For a 4-byte load/store, the
-//zz top-level map is indexed not with (addr >> 16) but instead f(add=
r),
-//zz where
-//zz=20
-//zz f( XXXX XXXX XXXX XXXX ____ ____ ____ __YZ )
-//zz =3D ____ ____ ____ __YZ XXXX XXXX XXXX XXXX or=20
-//zz =3D ____ ____ ____ __ZY XXXX XXXX XXXX XXXX
-//zz=20
-//zz ie the lowest two bits are placed above the 16 high address bits=
.
-//zz If either of these two bits are nonzero, the address is misalign=
ed;
-//zz this will select a secondary map from the upper 3/4 of the prima=
ry
-//zz map. Because this is always the distinguished secondary map, a
-//zz (bogus) address check failure will result. The failure handling
-//zz code can then figure out whether this is a genuine addr check
-//zz failure or whether it is a possibly-legitimate access at a
-//zz misaligned address. =20
-//zz */
-//zz=20
-//zz /*------------------------------------------------------------*/
-//zz /*--- Function declarations. ---*/
-//zz /*------------------------------------------------------------*/
-//zz=20
-//zz static ULong mc_rd_V8_SLOWLY ( Addr a );
-//zz static UInt mc_rd_V4_SLOWLY ( Addr a );
-//zz static UInt mc_rd_V2_SLOWLY ( Addr a );
-//zz static UInt mc_rd_V1_SLOWLY ( Addr a );
-//zz=20
-//zz static void mc_wr_V8_SLOWLY ( Addr a, ULong vbytes );
-//zz static void mc_wr_V4_SLOWLY ( Addr a, UInt vbytes );
-//zz static void mc_wr_V2_SLOWLY ( Addr a, UInt vbytes );
-//zz static void mc_wr_V1_SLOWLY ( Addr a, UInt vbytes );
-//zz=20
-//zz /*------------------------------------------------------------*/
-//zz /*--- Data defns. ---*/
-//zz /*------------------------------------------------------------*/
-//zz=20
-//zz typedef=20
-//zz struct {
-//zz UChar abits[SECONDARY_SIZE/8];
-//zz UChar vbyte[SECONDARY_SIZE];
-//zz }
-//zz SecMap;
-//zz=20
-//zz=20
-//zz static SecMap* primary_map[ /*PRIMARY_SIZE*/ PRIMARY_SIZE*4 ];
-//zz=20
-//zz #define DSM_IDX(a, v) ((((a)&1) << 1) + ((v)&1))
-//zz=20
-//zz /* 4 secondary maps, but one is redundant (because the !addressable=
&&
-//zz valid state is meaningless) */
-//zz static const SecMap distinguished_secondary_maps[4] =3D {
-//zz #define INIT(a, v) \
-//zz [ DSM_IDX(a, v) ] =3D { { [0 ... (SECONDARY_SIZE/8)-1] =3D BIT_E=
XPAND(a) }, \
-//zz { [0 ... SECONDARY_SIZE-1] =3D BIT_EXPAND(a|v) } }
-//zz INIT(VGM_BIT_VALID, VGM_BIT_VALID),
-//zz INIT(VGM_BIT_VALID, VGM_BIT_INVALID),
-//zz INIT(VGM_BIT_INVALID, VGM_BIT_VALID),
-//zz INIT(VGM_BIT_INVALID, VGM_BIT_INVALID),
-//zz #undef INIT
-//zz };
-//zz #define N_SECONDARY_MAPS (sizeof(distinguished_secondary_maps)/size=
of(*distinguished_secondary_maps))
-//zz=20
-//zz #define DSM(a,v) ((SecMap *)&distinguished_secondary_maps[DSM_IDX(=
a, v)])
-//zz=20
-//zz #define DSM_NOTADDR DSM(VGM_BIT_INVALID, VGM_BIT_INVALID)
-//zz #define DSM_ADDR_NOTVALID DSM(VGM_BIT_VALID, VGM_BIT_INVALID)
-//zz #define DSM_ADDR_VALID DSM(VGM_BIT_VALID, VGM_BIT_VALID)
-
-static void init_shadow_memory ( void )
-{
- Int i;
- SecMap* sm;
-
- /* Build the 3 distinguished secondaries */
- tl_assert(VGM_BIT_INVALID =3D=3D 1);
- tl_assert(VGM_BIT_VALID =3D=3D 0);
- tl_assert(VGM_BYTE_INVALID =3D=3D 0xFF);
- tl_assert(VGM_BYTE_VALID =3D=3D 0);
-
- /* Set A invalid, V invalid. */
- sm =3D &sm_distinguished[SM_DIST_NOACCESS];
- for (i =3D 0; i < 65536; i++)
- sm->vbyte[i] =3D VGM_BYTE_INVALID;
- for (i =3D 0; i < 8192; i++)
- sm->abits[i] =3D VGM_BYTE_INVALID;
-
- /* Set A valid, V invalid. */
- sm =3D &sm_distinguished[SM_DIST_ACCESS_UNDEFINED];
- for (i =3D 0; i < 65536; i++)
- sm->vbyte[i] =3D VGM_BYTE_INVALID;
- for (i =3D 0; i < 8192; i++)
- sm->abits[i] =3D VGM_BYTE_VALID;
-
- /* Set A valid, V valid. */
- sm =3D &sm_distinguished[SM_DIST_ACCESS_DEFINED];
- for (i =3D 0; i < 65536; i++)
- sm->vbyte[i] =3D VGM_BYTE_VALID;
- for (i =3D 0; i < 8192; i++)
- sm->abits[i] =3D VGM_BYTE_VALID;
-
- /* Set up the primary map. */
- /* These entries gradually get overwritten as the used address
- space expands. */
- for (i =3D 0; i < N_PRIMARY_MAP; i++)
- primary_map[i] =3D &sm_distinguished[SM_DIST_NOACCESS];
-
- /* auxmap_size =3D auxmap_used =3D 0;=20
- no ... these are statically initialised */
-}
-
-
-//zz /*------------------------------------------------------------*/
-//zz /*--- Basic bitmap management, reading and writing. ---*/
-//zz /*------------------------------------------------------------*/
-//zz=20
-//zz /* Allocate and initialise a secondary map. */
-//zz=20
-//zz static SecMap* alloc_secondary_map ( __attribute__ ((unused))=20
-//zz Char* caller,
-//zz const SecMap *prototype)
-//zz {
-//zz SecMap* map;
-//zz PROF_EVENT(10);
-//zz=20
-//zz map =3D (SecMap *)VG_(shadow_alloc)(sizeof(SecMap));
-//zz=20
-//zz VG_(memcpy)(map, prototype, sizeof(*map));
-//zz=20
-//zz /* VG_(printf)("ALLOC_2MAP(%s)\n", caller ); */
-//zz return map;
-//zz }
-//zz=20
-//zz=20
-//zz /* Basic reading/writing of the bitmaps, for byte-sized accesses. *=
/
-//zz=20
-//zz static __inline__ UChar get_abit ( Addr a )
-//zz {
-//zz SecMap* sm =3D primary_map[PM_IDX(a)];
-//zz UInt sm_off =3D SM_OFF(a);
-//zz PROF_EVENT(20);
-//zz # if 0
-//zz if (IS_DISTINGUISHED_SM(sm))
-//zz VG_(message)(Vg_DebugMsg,=20
-//zz "accessed distinguished 2ndary (A)map! 0x%x\n=
", a);
-//zz # endif
-//zz return BITARR_TEST(sm->abits, sm_off)=20
-//zz ? VGM_BIT_INVALID : VGM_BIT_VALID;
-//zz }
-//zz=20
-//zz static __inline__ UChar get_vbyte ( Addr a )
-//zz {
-//zz SecMap* sm =3D primary_map[PM_IDX(a)];
-//zz UInt sm_off =3D SM_OFF(a);
-//zz PROF_EVENT(21);
-//zz # if 0
-//zz if (IS_DISTINGUISHED_SM(sm))
-//zz VG_(message)(Vg_DebugMsg,=20
-//zz "accessed distinguished 2ndary (V)map! 0x%x\n=
", a);
-//zz # endif
-//zz return sm->vbyte[sm_off];
-//zz }
-//zz=20
-//zz static /* __inline__ */ void set_abit ( Addr a, UChar abit )
-//zz {
-//zz SecMap* sm;
-//zz UInt sm_off;
-//zz PROF_EVENT(22);
-//zz ENSURE_MAPPABLE(a, "set_abit");
-//zz sm =3D primary_map[PM_IDX(a)];
-//zz sm_off =3D SM_OFF(a);
-//zz if (abit)=20
-//zz BITARR_SET(sm->abits, sm_off);
-//zz else
-//zz BITARR_CLEAR(sm->abits, sm_off);
-//zz }
-//zz=20
-//zz static __inline__ void set_vbyte ( Addr a, UChar vbyte )
-//zz {
-//zz SecMap* sm;
-//zz UInt sm_off;
-//zz PROF_EVENT(23);
-//zz ENSURE_MAPPABLE(a, "set_vbyte");
-//zz sm =3D primary_map[PM_IDX(a)];
-//zz sm_off =3D SM_OFF(a);
-//zz sm->vbyte[sm_off] =3D vbyte;
-//zz }
-//zz=20
-//zz=20
//zz /* Reading/writing of the bitmaps, for aligned word-sized accesses.=
*/
//zz=20
//zz static __inline__ UChar get_abits4_ALIGNED ( Addr a )
@@ -870,8 +661,9 @@
# endif
}
=20
-/* Set permissions for address ranges ... */
=20
+/* --- Set permissions for arbitrary address ranges --- */
+
static void mc_make_noaccess ( Addr a, SizeT len )
{
PROF_EVENT(40, "mc_make_noaccess");
@@ -894,6 +686,26 @@
}
=20
=20
+/* --- Block-copy permissions (needed for implementing realloc()). --- *=
/
+
+static void mc_copy_address_range_state ( Addr src, Addr dst, SizeT len =
)
+{
+ SizeT i;
+ UWord abit, vbyte;
+
+ DEBUG("mc_copy_address_range_state\n");
+
+ PROF_EVENT(50, "mc_copy_address_range_state");
+ for (i =3D 0; i < len; i++) {
+ PROF_EVENT(51, "mc_copy_address_range_state(loop)");
+ get_abit_and_vbyte( &abit, &vbyte, src+i );
+ set_abit_and_vbyte( dst+i, abit, vbyte );
+ }
+}
+
+
+/* --- Fast case permission setters, for dealing with stacks. --- */
+
static __inline__
void make_aligned_word32_writable ( Addr aA )
{
@@ -1060,23 +872,7 @@
mc_make_noaccess=20
);
=20
-/* Block-copy permissions (needed for implementing realloc()). */
-static void mc_copy_address_range_state ( Addr src, Addr dst, SizeT len =
)
-{
- SizeT i;
- UWord abit, vbyte;
=20
- DEBUG("mc_copy_address_range_state\n");
-
- PROF_EVENT(50, "mc_copy_address_range_state");
- for (i =3D 0; i < len; i++) {
- PROF_EVENT(51, "mc_copy_address_range_state(loop)");
- get_abit_and_vbyte( &abit, &vbyte, src+i );
- set_abit_and_vbyte( dst+i, abit, vbyte );
- }
-}
-
-
/*------------------------------------------------------------*/
/*--- Checking memory ---*/
/*------------------------------------------------------------*/
@@ -1365,7 +1161,8 @@
=20
=20
/*------------------------------------------------------------*/
-/*--- Functions called directly from generated code. ---*/
+/*--- Functions called directly from generated code: ---*/
+/*--- Load/store handlers. ---*/
/*------------------------------------------------------------*/
=20
/* Types: LOADV4, LOADV2, LOADV1 are:
@@ -1379,27 +1176,6 @@
are a UWord, and for STOREV8 they are a ULong.
*/
=20
-//zz static __inline__ UInt rotateRight16 ( UInt x )
-//zz {
-//zz /* Amazingly, gcc turns this into a single rotate insn. */
-//zz return (x >> 16) | (x << 16);
-//zz }
-//zz=20
-//zz=20
-//zz static __inline__ UInt shiftRight16 ( UInt x )
-//zz {
-//zz return x >> 16;
-//zz }
-//zz=20
-//zz=20
-//zz /* Read/write 1/2/4/8 sized V bytes, and emit an address error if
-//zz needed. */
-//zz=20
-//zz /* MC_(helperc_{LD,ST}V{1,2,4,8}) handle the common case fast.
-//zz Under all other circumstances, it defers to the relevant _SLOWLY
-//zz function, which can handle all situations.
-//zz */
-
/* ------------------------ Size =3D 8 ------------------------ */
=20
VGA_REGPARM(1)
@@ -1407,35 +1183,6 @@
{
PROF_EVENT(70, "helperc_LOADV8");
return mc_LOADVn_slow( a, 8, False/*littleendian*/ );
-//zz # ifdef VG_DEBUG_MEMORY
-//zz return mc_rd_V8_SLOWLY(a);
-//zz # else
-//zz if (VG_IS_8_ALIGNED(a)) {
-//zz UInt sec_no =3D shiftRight16(a) & 0xFFFF;
-//zz SecMap* sm =3D primary_map[sec_no];
-//zz UInt a_off =3D (SM_OFF(a)) >> 3;
-//zz UChar abits =3D sm->abits[a_off];
-//zz if (abits =3D=3D VGM_BYTE_VALID) {
-//zz /* a is 8-aligned, mapped, and addressible. */
-//zz UInt v_off =3D SM_OFF(a);
-//zz /* LITTLE-ENDIAN */
-//zz UInt vLo =3D ((UInt*)(sm->vbyte))[ (v_off >> 2) ];
-//zz UInt vHi =3D ((UInt*)(sm->vbyte))[ (v_off >> 2) + 1 ];
-//zz return ( ((ULong)vHi) << 32 ) | ((ULong)vLo);
-//zz } else {
-//zz return mc_rd_V8_SLOWLY(a);
-//zz }
-//zz }
-//zz else
-//zz if (VG_IS_4_ALIGNED(a)) {
-//zz /* LITTLE-ENDIAN */
-//zz UInt vLo =3D MC_(helperc_LOADV4)(a+0);
-//zz UInt vHi =3D MC_(helperc_LOADV4)(a+4);
-//zz return ( ((ULong)vHi) << 32 ) | ((ULong)vLo);
-//zz }
-//zz else
-//zz return mc_rd_V8_SLOWLY(a);
-//zz # endif
}
=20
VGA_REGPARM(1)
@@ -1443,38 +1190,6 @@
{
PROF_EVENT(71, "helperc_STOREV8");
mc_STOREVn_slow( a, 8, vbytes, False/*littleendian*/ );
-//zz # ifdef VG_DEBUG_MEMORY
-//zz mc_wr_V8_SLOWLY(a, vbytes);
-//zz # else
-//zz if (VG_IS_8_ALIGNED(a)) {
-//zz UInt sec_no =3D shiftRight16(a) & 0xFFFF;
-//zz SecMap* sm =3D primary_map[sec_no];
-//zz UInt a_off =3D (SM_OFF(a)) >> 3;
-//zz if (!IS_DISTINGUISHED_SM(sm) && sm->abits[a_off] =3D=3D VGM_B=
YTE_VALID) {
-//zz /* a is 8-aligned, mapped, and addressible. */
-//zz UInt v_off =3D SM_OFF(a);
-//zz UInt vHi =3D (UInt)(vbytes >> 32);
-//zz UInt vLo =3D (UInt)vbytes;
-//zz /* LITTLE-ENDIAN */
-//zz ((UInt*)(sm->vbyte))[ (v_off >> 2) ] =3D vLo;
-//zz ((UInt*)(sm->vbyte))[ (v_off >> 2) + 1 ] =3D vHi;
-//zz } else {
-//zz mc_wr_V8_SLOWLY(a, vbytes);
-//zz }
-//zz return;
-//zz }
-//zz else
-//zz if (VG_IS_4_ALIGNED(a)) {
-//zz UInt vHi =3D (UInt)(vbytes >> 32);
-//zz UInt vLo =3D (UInt)vbytes;
-//zz /* LITTLE-ENDIAN */
-//zz MC_(helperc_STOREV4)(a+0, vLo);
-//zz MC_(helperc_STOREV4)(a+4, vHi);
-//zz return;
-//zz }
-//zz else
-//zz mc_wr_V8_SLOWLY(a, vbytes);
-//zz # endif
}
=20
/* ------------------------ Size =3D 4 ------------------------ */
@@ -1576,7 +1291,6 @@
# endif
}
=20
-
/* ------------------------ Size =3D 2 ------------------------ */
=20
VGA_REGPARM(1)
@@ -1627,7 +1341,6 @@
# endif
}
=20
-
VGA_REGPARM(2)
void MC_(helperc_STOREV2) ( Addr aA, UWord vbytes )
{
@@ -1671,7 +1384,6 @@
# endif
}
=20
-
/* ------------------------ Size =3D 1 ------------------------ */
=20
VGA_REGPARM(1)
@@ -1766,311 +1478,11 @@
}
=20
=20
-//zz /*------------------------------------------------------------*/
-//zz /*--- Fallback functions to handle cases that the above ---*/
-//zz /*--- VG_(helperc_{LD,ST}V{1,2,4,8}) can't manage. ---*/
-//zz /*------------------------------------------------------------*/
-//zz=20
-//zz /* ------------------------ Size =3D 8 ------------------------ */
-//zz=20
-//zz static ULong mc_rd_V8_SLOWLY ( Addr a )
-//zz {
-//zz Bool a0ok, a1ok, a2ok, a3ok, a4ok, a5ok, a6ok, a7ok;
-//zz UInt vb0, vb1, vb2, vb3, vb4, vb5, vb6, vb7;
-//zz=20
-//zz PROF_EVENT(70);
-//zz=20
-//zz /* First establish independently the addressibility of the 4 byt=
es
-//zz involved. */
-//zz a0ok =3D get_abit(a+0) =3D=3D VGM_BIT_VALID;
-//zz a1ok =3D get_abit(a+1) =3D=3D VGM_BIT_VALID;
-//zz a2ok =3D get_abit(a+2) =3D=3D VGM_BIT_VALID;
-//zz a3ok =3D get_abit(a+3) =3D=3D VGM_BIT_VALID;
-//zz a4ok =3D get_abit(a+4) =3D=3D VGM_BIT_VALID;
-//zz a5ok =3D get_abit(a+5) =3D=3D VGM_BIT_VALID;
-//zz a6ok =3D get_abit(a+6) =3D=3D VGM_BIT_VALID;
-//zz a7ok =3D get_abit(a+7) =3D=3D VGM_BIT_VALID;
-//zz=20
-//zz /* Also get the validity bytes for the address. */
-//zz vb0 =3D (UInt)get_vbyte(a+0);
-//zz vb1 =3D (UInt)get_vbyte(a+1);
-//zz vb2 =3D (UInt)get_vbyte(a+2);
-//zz vb3 =3D (UInt)get_vbyte(a+3);
-//zz vb4 =3D (UInt)get_vbyte(a+4);
-//zz vb5 =3D (UInt)get_vbyte(a+5);
-//zz vb6 =3D (UInt)get_vbyte(a+6);
-//zz vb7 =3D (UInt)get_vbyte(a+7);
-//zz=20
-//zz /* Now distinguish 3 cases */
-//zz=20
-//zz /* Case 1: the address is completely valid, so:
-//zz - no addressing error
-//zz - return V bytes as read from memory
-//zz */
-//zz if (a0ok && a1ok && a2ok && a3ok && a4ok && a5ok && a6ok && a7ok=
) {
-//zz ULong vw =3D VGM_WORD64_INVALID;
-//zz vw <<=3D 8; vw |=3D vb7;
-//zz vw <<=3D 8; vw |=3D vb6;
-//zz vw <<=3D 8; vw |=3D vb5;
-//zz vw <<=3D 8; vw |=3D vb4;
-//zz vw <<=3D 8; vw |=3D vb3;
-//zz vw <<=3D 8; vw |=3D vb2;
-//zz vw <<=3D 8; vw |=3D vb1;
-//zz vw <<=3D 8; vw |=3D vb0;
-//zz return vw;
-//zz }
-//zz=20
-//zz /* Case 2: the address is completely invalid. =20
-//zz - emit addressing error
-//zz - return V word indicating validity. =20
-//zz This sounds strange, but if we make loads from invalid addres=
ses=20
-//zz give invalid data, we also risk producing a number of confusi=
ng
-//zz undefined-value errors later, which confuses the fact that th=
e
-//zz error arose in the first place from an invalid address.=20
-//zz */
-//zz /* VG_(printf)("%p (%d %d %d %d)\n", a, a0ok, a1ok, a2ok, a3ok);=
*/
-//zz if (!MAC_(clo_partial_loads_ok)=20
-//zz || ((a & 7) !=3D 0)
-//zz || (!a0ok && !a1ok && !a2ok && !a3ok && !a4ok && !a5ok && !a=
6ok && !a7ok)) {
-//zz MAC_(record_address_error)( VG_(get_running_tid)(), a, 8, Fal=
se );
-//zz return VGM_WORD64_VALID;
-//zz }
-//zz=20
-//zz /* Case 3: the address is partially valid. =20
-//zz - no addressing error
-//zz - returned V word is invalid where the address is invalid,=20
-//zz and contains V bytes from memory otherwise.=20
-//zz Case 3 is only allowed if MC_(clo_partial_loads_ok) is True
-//zz (which is the default), and the address is 4-aligned. =20
-//zz If not, Case 2 will have applied.
-//zz */
-//zz tl_assert(MAC_(clo_partial_loads_ok));
-//zz {
-//zz ULong vw =3D VGM_WORD64_INVALID;
-//zz vw <<=3D 8; vw |=3D (a7ok ? vb7 : VGM_BYTE_INVALID);
-//zz vw <<=3D 8; vw |=3D (a6ok ? vb6 : VGM_BYTE_INVALID);
-//zz vw <<=3D 8; vw |=3D (a5ok ? vb5 : VGM_BYTE_INVALID);
-//zz vw <<=3D 8; vw |=3D (a4ok ? vb4 : VGM_BYTE_INVALID);
-//zz vw <<=3D 8; vw |=3D (a3ok ? vb3 : VGM_BYTE_INVALID);
-//zz vw <<=3D 8; vw |=3D (a2ok ? vb2 : VGM_BYTE_INVALID);
-//zz vw <<=3D 8; vw |=3D (a1ok ? vb1 : VGM_BYTE_INVALID);
-//zz vw <<=3D 8; vw |=3D (a0ok ? vb0 : VGM_BYTE_INVALID);
-//zz return vw;
-//zz }
-//zz }
-//zz=20
-//zz static void mc_wr_V8_SLOWLY ( Addr a, ULong vbytes )
-//zz {
-//zz /* Check the address for validity. */
-//zz Bool aerr =3D False;
-//zz PROF_EVENT(71);
-//zz=20
-//zz if (get_abit(a+0) !=3D VGM_BIT_VALID) aerr =3D True;
-//zz if (get_abit(a+1) !=3D VGM_BIT_VALID) aerr =3D True;
-//zz if (get_abit(a+2) !=3D VGM_BIT_VALID) aerr =3D True;
-//zz if (get_abit(a+3) !=3D VGM_BIT_VALID) aerr =3D True;
-//zz if (get_abit(a+4) !=3D VGM_BIT_VALID) aerr =3D True;
-//zz if (get_abit(a+5) !=3D VGM_BIT_VALID) aerr =3D True;
-//zz if (get_abit(a+6) !=3D VGM_BIT_VALID) aerr =3D True;
-//zz if (get_abit(a+7) !=3D VGM_BIT_VALID) aerr =3D True;
-//zz=20
-//zz /* Store the V bytes, remembering to do it little-endian-ly. */
-//zz set_vbyte( a+0, vbytes & 0x000000FF ); vbytes >>=3D 8;
-//zz set_vbyte( a+1, vbytes & 0x000000FF ); vbytes >>=3D 8;
-//zz set_vbyte( a+2, vbytes & 0x000000FF ); vbytes >>=3D 8;
-//zz set_vbyte( a+3, vbytes & 0x000000FF ); vbytes >>=3D 8;
-//zz set_vbyte( a+4, vbytes & 0x000000FF ); vbytes >>=3D 8;
-//zz set_vbyte( a+5, vbytes & 0x000000FF ); vbytes >>=3D 8;
-//zz set_vbyte( a+6, vbytes & 0x000000FF ); vbytes >>=3D 8;
-//zz set_vbyte( a+7, vbytes & 0x000000FF );
-//zz=20
-//zz /* If an address error has happened, report it. */
-//zz if (aerr)
-//zz MAC_(record_address_error)( VG_(get_running_tid)(), a, 8, Tru=
e );
-//zz }
-//zz=20
-//zz /* ------------------------ Size =3D 4 ------------------------ */
-//zz=20
-//zz static UInt mc_rd_V4_SLOWLY ( Addr a )
-//zz {
-//zz Bool a0ok, a1ok, a2ok, a3ok;
-//zz UInt vb0, vb1, vb2, vb3;
-//zz=20
-//zz PROF_EVENT(70);
-//zz=20
-//zz /* First establish independently the addressibility of the 4 byt=
es
-//zz involved. */
-//zz a0ok =3D get_abit(a+0) =3D=3D VGM_BIT_VALID;
-//zz a1ok =3D get_abit(a+1) =3D=3D VGM_BIT_VALID;
-//zz a2ok =3D get_abit(a+2) =3D=3D VGM_BIT_VALID;
-//zz a3ok =3D get_abit(a+3) =3D=3D VGM_BIT_VALID;
-//zz=20
-//zz /* Also get the validity bytes for the address. */
-//zz vb0 =3D (UInt)get_vbyte(a+0);
-//zz vb1 =3D (UInt)get_vbyte(a+1);
-//zz vb2 =3D (UInt)get_vbyte(a+2);
-//zz vb3 =3D (UInt)get_vbyte(a+3);
-//zz=20
-//zz /* Now distinguish 3 cases */
-//zz=20
-//zz /* Case 1: the address is completely valid, so:
-//zz - no addressing error
-//zz - return V bytes as read from memory
-//zz */
-//zz if (a0ok && a1ok && a2ok && a3ok) {
-//zz UInt vw =3D VGM_WORD_INVALID;
-//zz vw <<=3D 8; vw |=3D vb3;
-//zz vw <<=3D 8; vw |=3D vb2;
-//zz vw <<=3D 8; vw |=3D vb1;
-//zz vw <<=3D 8; vw |=3D vb0;
-//zz return vw;
-//zz }
-//zz=20
-//zz /* Case 2: the address is completely invalid. =20
-//zz - emit addressing error
-//zz - return V word indicating validity. =20
-//zz This sounds strange, but if we make loads from invalid addres=
ses=20
-//zz give invalid data, we also risk producing a number of confusi=
ng
-//zz undefined-value errors later, which confuses the fact that th=
e
-//zz error arose in the first place from an invalid address.=20
-//zz */
-//zz /* VG_(printf)("%p (%d %d %d %d)\n", a, a0ok, a1ok, a2ok, a3ok);=
*/
-//zz if (!MAC_(clo_partial_loads_ok)=20
-//zz || ((a & 3) !=3D 0)
-//zz || (!a0ok && !a1ok && !a2ok && !a3ok)) {
-//zz MAC_(record_address_error)( VG_(get_running_tid)(), a, 4, Fal=
se );
-//zz return (VGM_BYTE_VALID << 24) | (VGM_BYTE_VALID << 16)=20
-//zz | (VGM_BYTE_VALID << 8) | VGM_BYTE_VALID;
-//zz }
-//zz=20
-//zz /* Case 3: the address is partially valid. =20
-//zz - no addressing error
-//zz - returned V word is invalid where the address is invalid,=20
-//zz and contains V bytes from memory otherwise.=20
-//zz Case 3 is only allowed if MC_(clo_partial_loads_ok) is True
-//zz (which is the default), and the address is 4-aligned. =20
-//zz If not, Case 2 will have applied.
-//zz */
-//zz tl_assert(MAC_(clo_partial_loads_ok));
-//zz {
-//zz UInt vw =3D VGM_WORD_INVALID;
-//zz vw <<=3D 8; vw |=3D (a3ok ? vb3 : VGM_BYTE_INVALID);
-//zz vw <<=3D 8; vw |=3D (a2ok ? vb2 : VGM_BYTE_INVALID);
-//zz vw <<=3D 8; vw |=3D (a1ok ? vb1 : VGM_BYTE_INVALID);
-//zz vw <<=3D 8; vw |=3D (a0ok ? vb0 : VGM_BYTE_INVALID);
-//zz return vw;
-//zz }
-//zz }
-//zz=20
-//zz static void mc_wr_V4_SLOWLY ( Addr a, UInt vbytes )
-//zz {
-//zz /* Check the address for validity. */
-//zz Bool aerr =3D False;
-//zz PROF_EVENT(71);
-//zz=20
-//zz if (get_abit(a+0) !=3D VGM_BIT_VALID) aerr =3D True;
-//zz if (get_abit(a+1) !=3D VGM_BIT_VALID) aerr =3D True;
-//zz if (get_abit(a+2) !=3D VGM_BIT_VALID) aerr =3D True;
-//zz if (get_abit(a+3) !=3D VGM_BIT_VALID) aerr =3D True;
-//zz=20
-//zz /* Store the V bytes, remembering to do it little-endian-ly. */
-//zz set_vbyte( a+0, vbytes & 0x000000FF ); vbytes >>=3D 8;
-//zz set_vbyte( a+1, vbytes & 0x000000FF ); vbytes >>=3D 8;
-//zz set_vbyte( a+2, vbytes & 0x000000FF ); vbytes >>=3D 8;
-//zz set_vbyte( a+3, vbytes & 0x000000FF );
-//zz=20
-//zz /* If an address error has happened, report it. */
-//zz if (aerr)
-//zz MAC_(record_address_error)( VG_(get_running_tid)(), a, 4, Tru=
e );
-//zz }
-//zz=20
-//zz /* ------------------------ Size =3D 2 ------------------------ */
-//zz=20
-//zz static UInt mc_rd_V2_SLOWLY ( Addr a )
-//zz {
-//zz /* Check the address for validity. */
-//zz UInt vw =3D VGM_WORD_INVALID;
-//zz Bool aerr =3D False;
-//zz PROF_EVENT(72);
-//zz=20
-//zz if (get_abit(a+0) !=3D VGM_BIT_VALID) aerr =3D True;
-//zz if (get_abit(a+1) !=3D VGM_BIT_VALID) aerr =3D True;
-//zz=20
-//zz /* Fetch the V bytes, remembering to do it little-endian-ly. */
-//zz vw <<=3D 8; vw |=3D (UInt)get_vbyte(a+1);
-//zz vw <<=3D 8; vw |=3D (UInt)get_vbyte(a+0);
-//zz=20
-//zz /* If an address error has happened, report it. */
-//zz if (aerr) {
-//zz MAC_(record_address_error)( VG_(get_running_tid)(), a, 2, Fal=
se );
-//zz vw =3D (VGM_BYTE_INVALID << 24) | (VGM_BYTE_INVALID << 16)=20
-//zz | (VGM_BYTE_VALID << 8) | (VGM_BYTE_VALID);
-//zz }
-//zz return vw; =20
-//zz }
-//zz=20
-//zz static void mc_wr_V2_SLOWLY ( Addr a, UInt vbytes )
-//zz {
-//zz /* Check the address for validity. */
-//zz Bool aerr =3D False;
-//zz PROF_EVENT(73);
-//zz=20
-//zz if (get_abit(a+0) !=3D VGM_BIT_VALID) aerr =3D True;
-//zz if (get_abit(a+1) !=3D VGM_BIT_VALID) aerr =3D True;
-//zz=20
-//zz /* Store the V bytes, remembering to do it little-endian-ly. */
-//zz set_vbyte( a+0, vbytes & 0x000000FF ); vbytes >>=3D 8;
-//zz set_vbyte( a+1, vbytes & 0x000000FF );
-//zz=20
-//zz /* If an address error has happened, report it. */
-//zz if (aerr)
-//zz MAC_(record_address_error)( VG_(get_running_tid)(), a, 2, Tru=
e );
-//zz }
-//zz=20
-//zz /* ------------------------ Size =3D 1 ------------------------ */
-//zz=20
-//zz static UInt mc_rd_V1_SLOWLY ( Addr a )
-//zz {
-//zz /* Check the address for validity. */
-//zz UInt vw =3D VGM_WORD_INVALID;
-//zz Bool aerr =3D False;
-//zz PROF_EVENT(74);
-//zz=20
-//zz if (get_abit(a+0) !=3D VGM_BIT_VALID) aerr =3D True;
-//zz=20
-//zz /* Fetch the V byte. */
-//zz vw <<=3D 8; vw |=3D (UInt)get_vbyte(a+0);
-//zz=20
-//zz /* If an address error has happened, report it. */
-//zz if (aerr) {
-//zz MAC_(record_address_error)( VG_(get_running_tid)(), a, 1, Fal=
se );
-//zz vw =3D (VGM_BYTE_INVALID << 24) | (VGM_BYTE_INVALID << 16)=20
-//zz | (VGM_BYTE_INVALID << 8) | (VGM_BYTE_VALID);
-//zz }
-//zz return vw; =20
-//zz }
-//zz=20
-//zz static void mc_wr_V1_SLOWLY ( Addr a, UInt vbytes )
-//zz {
-//zz /* Check the address for validity. */
-//zz Bool aerr =3D False;
-//zz PROF_EVENT(75);
-//zz if (get_abit(a+0) !=3D VGM_BIT_VALID) aerr =3D True;
-//zz=20
-//zz /* Store the V bytes, remembering to do it little-endian-ly. */
-//zz set_vbyte( a+0, vbytes & 0x000000FF );
-//zz=20
-//zz /* If an address error has happened, report it. */
-//zz if (aerr)
-//zz MAC_(record_address_error)( VG_(get_running_tid)(), a, 1, Tru=
e );
-//zz }
+/*------------------------------------------------------------*/
+/*--- Functions called directly from generated code: ---*/
+/*--- Value-check failure handlers. ---*/
+/*------------------------------------------------------------*/
=20
-
-/* ---------------------------------------------------------------------
- Called from generated code, or from the assembly helpers.
- Handlers for value check failures.
- ------------------------------------------------------------------ */
-
void MC_(helperc_value_check0_fail) ( void )
{
MC_(record_value_error) ( VG_(get_running_tid)(), 0 );
@@ -2220,10 +1632,57 @@
}
=20
=20
-/* ---------------------------------------------------------------------
- Sanity check machinery (permanently engaged).
- ------------------------------------------------------------------ */
+/*------------------------------------------------------------*/
+/*--- Initialisation ---*/
+/*------------------------------------------------------------*/
=20
+static void init_shadow_memory ( void )
+{
+ Int i;
+ SecMap* sm;
+
+ /* Build the 3 distinguished secondaries */
+ tl_assert(VGM_BIT_INVALID =3D=3D 1);
+ tl_assert(VGM_BIT_VALID =3D=3D 0);
+ tl_assert(VGM_BYTE_INVALID =3D=3D 0xFF);
+ tl_assert(VGM_BYTE_VALID =3D=3D 0);
+
+ /* Set A invalid, V invalid. */
+ sm =3D &sm_distinguished[SM_DIST_NOACCESS];
+ for (i =3D 0; i < 65536; i++)
+ sm->vbyte[i] =3D VGM_BYTE_INVALID;
+ for (i =3D 0; i < 8192; i++)
+ sm->abits[i] =3D VGM_BYTE_INVALID;
+
+ /* Set A valid, V invalid. */
+ sm =3D &sm_distinguished[SM_DIST_ACCESS_UNDEFINED];
+ for (i =3D 0; i < 65536; i++)
+ sm->vbyte[i] =3D VGM_BYTE_INVALID;
+ for (i =3D 0; i < 8192; i++)
+ sm->abits[i] =3D VGM_BYTE_VALID;
+
+ /* Set A valid, V valid. */
+ sm =3D &sm_distinguished[SM_DIST_ACCESS_DEFINED];
+ for (i =3D 0; i < 65536; i++)
+ sm->vbyte[i] =3D VGM_BYTE_VALID;
+ for (i =3D 0; i < 8192; i++)
+ sm->abits[i] =3D VGM_BYTE_VALID;
+
+ /* Set up the primary map. */
+ /* These entries gradually get overwritten as the used address
+ space expands. */
+ for (i =3D 0; i < N_PRIMARY_MAP; i++)
+ primary_map[i] =3D &sm_distinguished[SM_DIST_NOACCESS];
+
+ /* auxmap_size =3D auxmap_used =3D 0;=20
+ no ... these are statically initialised */
+}
+
+
+/*------------------------------------------------------------*/
+/*--- Sanity check machinery (permanently engaged) ---*/
+/*------------------------------------------------------------*/
+
Bool TL_(cheap_sanity_check) ( void )
{
/* nothing useful we can rapidly check */
@@ -2336,16 +1795,6 @@
}
=20
=20
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-
/*------------------------------------------------------------*/
/*--- Command line args ---*/
/*------------------------------------------------------------*/
|