|
From: <sv...@va...> - 2005-08-23 22:11:32
|
Author: njn
Date: 2005-08-23 23:11:20 +0100 (Tue, 23 Aug 2005)
New Revision: 4480
Log:
Make the allocator's access functions slightly stricter in their
checking of the lo/hi size fields. If we are corrupting the metadata,
this should make it more likely that we get an assertion failure rather
than an outright crash.
Modified:
trunk/coregrind/m_mallocfree.c
Modified: trunk/coregrind/m_mallocfree.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_mallocfree.c 2005-08-23 18:06:01 UTC (rev 4479)
+++ trunk/coregrind/m_mallocfree.c 2005-08-23 22:11:20 UTC (rev 4480)
@@ -170,48 +170,50 @@
return bszB & (~SIZE_T_0x1);
}
=20
-// Set get the lower size field of a block.
+//----------------------------------------------------------------------=
-----
+
+// Get a block's size as stored, ie with the in-use/free attribute.
static __inline__
-SizeT get_bszB_lo ( Block* b )
+SizeT get_bszB_as_is ( Block* b )
{
- return *(SizeT*)&b[0];
+ UByte* b2 =3D (UByte*)b;
+ SizeT bszB_lo =3D *(SizeT*)&b2[0];
+ SizeT bszB_hi =3D *(SizeT*)&b2[mk_plain_bszB(bszB_lo) - sizeof(SizeT)=
];
+ vg_assert2(bszB_lo =3D=3D bszB_hi,=20
+ "Heap block lo/hi size mismatch: lo =3D %llu, hi =3D %llu.\n"
+ "Probably caused by overrunning/underrunning a heap block's bounds=
\n");
+ return bszB_lo;
}
=20
-// Does this block have the in-use attribute?
+// Get a block's plain size, ie. remove the in-use/free attribute.
static __inline__
-Bool is_inuse_block ( Block* b )
+SizeT get_bszB ( Block* b )
{
- SizeT bszB =3D get_bszB_lo(b);
- vg_assert(bszB !=3D 0);
- return (0 !=3D (bszB & SIZE_T_0x1)) ? False : True;
+ return mk_plain_bszB(get_bszB_as_is(b));
}
=20
-// Get the address of the last byte in a block
+// Set the size fields of a block. bszB may have the in-use/free attrib=
ute.
static __inline__
-UByte* last_byte ( Block* b )
+void set_bszB ( Block* b, SizeT bszB )
{
UByte* b2 =3D (UByte*)b;
- return &b2[mk_plain_bszB(get_bszB_lo(b)) - 1];
+ *(SizeT*)&b2[0] =3D bszB;
+ *(SizeT*)&b2[mk_plain_bszB(bszB) - sizeof(SizeT)] =3D bszB;
}
=20
-// Get the upper size field of a block.
-static __inline__
-SizeT get_bszB_hi ( Block* b )
-{
- UByte* lb =3D last_byte(b);
- return *(SizeT*)&lb[-sizeof(SizeT) + 1];
-}
+//----------------------------------------------------------------------=
-----
=20
-// Set the size fields of a block.
+// Does this block have the in-use attribute?
static __inline__
-void set_bszB ( Block* b, SizeT bszB )
+Bool is_inuse_block ( Block* b )
{
- UByte* lb;
- *(SizeT*)&b[0] =3D bszB; // Set lo bszB; must precede last_byte(=
) call
- lb =3D last_byte(b);
- *(SizeT*)&lb[-sizeof(SizeT) + 1] =3D bszB; // Set hi bszB
+ SizeT bszB =3D get_bszB_as_is(b);
+ vg_assert(bszB !=3D 0);
+ return (0 !=3D (bszB & SIZE_T_0x1)) ? False : True;
}
=20
+//----------------------------------------------------------------------=
-----
+
// Return the lower, upper and total overhead in bytes for a block.
// These are determined purely by which arena the block lives in.
static __inline__
@@ -230,6 +232,8 @@
return overhead_szB_lo(a) + overhead_szB_hi(a);
}
=20
+//----------------------------------------------------------------------=
-----
+
// Return the minimum bszB for a block in this arena. Can have zero-len=
gth
// payloads, so it's the size of the admin bytes.
static __inline__
@@ -238,6 +242,8 @@
return overhead_szB(a);
}
=20
+//----------------------------------------------------------------------=
-----
+
// Convert payload size <--> block size (both in bytes).
static __inline__
SizeT pszB_to_bszB ( Arena* a, SizeT pszB )
@@ -251,23 +257,8 @@
return bszB - overhead_szB(a);
}
=20
-// Get a block's size as stored, ie with the in-use/free attribute.
-static __inline__
-SizeT get_bszB_as_is ( Block* b )
-{
- SizeT bszB_lo =3D get_bszB_lo(b);
- SizeT bszB_hi =3D get_bszB_hi(b);
- vg_assert(bszB_lo =3D=3D bszB_hi);
- return bszB_lo;
-}
+//----------------------------------------------------------------------=
-----
=20
-// Get a block's plain size, ie. remove the in-use/free attribute.
-static __inline__
-SizeT get_bszB ( Block* b )
-{
- return mk_plain_bszB(get_bszB_as_is(b));
-}
-
// Get a block's payload size.
static __inline__
SizeT get_pszB ( Arena* a, Block* b )
@@ -275,7 +266,9 @@
return bszB_to_pszB(a, get_bszB(b));
}
=20
-// Given the addr of a block, return the addr of its payload.
+//----------------------------------------------------------------------=
-----
+
+// Given the addr of a block, return the addr of its payload, and vice v=
ersa.
static __inline__
UByte* get_block_payload ( Arena* a, Block* b )
{
@@ -289,6 +282,7 @@
return (Block*)&payload[ -overhead_szB_lo(a) ];
}
=20
+//----------------------------------------------------------------------=
-----
=20
// Set and get the next and previous link fields of a block.
static __inline__
@@ -300,8 +294,8 @@
static __inline__
void set_next_b ( Block* b, Block* next_p )
{
- UByte* lb =3D last_byte(b);
- *(Block**)&lb[-sizeof(SizeT) - sizeof(void*) + 1] =3D next_p;
+ UByte* b2 =3D (UByte*)b;
+ *(Block**)&b2[get_bszB(b) - sizeof(SizeT) - sizeof(void*)] =3D next_p=
;
}
static __inline__
Block* get_prev_b ( Block* b )
@@ -312,10 +306,11 @@
static __inline__
Block* get_next_b ( Block* b )
{=20
- UByte* lb =3D last_byte(b);
- return *(Block**)&lb[-sizeof(SizeT) - sizeof(void*) + 1];
+ UByte* b2 =3D (UByte*)b;
+ return *(Block**)&b2[get_bszB(b) - sizeof(SizeT) - sizeof(void*)];
}
=20
+//----------------------------------------------------------------------=
-----
=20
// Get the block immediately preceding this one in the Superblock.
static __inline__
@@ -326,6 +321,8 @@
return (Block*)&b2[-bszB];
}
=20
+//----------------------------------------------------------------------=
-----
+
// Read and write the lower and upper red-zone bytes of a block.
static __inline__
void set_rz_lo_byte ( Arena* a, Block* b, UInt rz_byteno, UByte v )
@@ -336,8 +333,8 @@
static __inline__
void set_rz_hi_byte ( Arena* a, Block* b, UInt rz_byteno, UByte v )
{
- UByte* lb =3D last_byte(b);
- lb[-sizeof(SizeT) - rz_byteno] =3D v;
+ UByte* b2 =3D (UByte*)b;
+ b2[get_bszB(b) - sizeof(SizeT) - rz_byteno - 1] =3D v;
}
static __inline__
UByte get_rz_lo_byte ( Arena* a, Block* b, UInt rz_byteno )
@@ -348,8 +345,8 @@
static __inline__
UByte get_rz_hi_byte ( Arena* a, Block* b, UInt rz_byteno )
{
- UByte* lb =3D last_byte(b);
- return lb[-sizeof(SizeT) - rz_byteno];
+ UByte* b2 =3D (UByte*)b;
+ return b2[get_bszB(b) - sizeof(SizeT) - rz_byteno - 1];
}
=20
=20
@@ -633,8 +630,8 @@
{
# define BLEAT(str) VG_(printf)("blockSane: fail -- %s\n",str)
UInt i;
- if (get_bszB_lo(b) !=3D get_bszB_hi(b))
- {BLEAT("sizes");return False;}
+ // The lo and hi size fields will be checked (indirectly) by the call
+ // to get_rz_hi_byte().
if (!a->clientmem && is_inuse_block(b)) {
for (i =3D 0; i < a->rz_szB; i++) {
if (get_rz_lo_byte(a, b, i) !=3D=20
|