|
From: <sv...@va...> - 2005-07-23 17:14:18
|
Author: sewardj
Date: 2005-07-23 18:14:03 +0100 (Sat, 23 Jul 2005)
New Revision: 4232
Log:
When canonicalising CFI information, truncate overlapping address
ranges and remove zero-length entries. If these appear it's because
the generating compiler has created invalid CFI info. Nevertheless we
should handle this robustly. This fixes a bug reported by Bill
Hoover.
Modified:
trunk/coregrind/m_debuginfo/symtab.c
Modified: trunk/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
--- trunk/coregrind/m_debuginfo/symtab.c 2005-07-23 11:36:03 UTC (rev 423=
1)
+++ trunk/coregrind/m_debuginfo/symtab.c 2005-07-23 17:14:03 UTC (rev 423=
2)
@@ -838,15 +838,22 @@
static
void canonicaliseCfiSI ( SegInfo* si )
{
- Int i;
+ Int i, j;
const Addr minAddr =3D 0;
const Addr maxAddr =3D ~minAddr;
=20
+ /* Note: take care in here. si->cfisi can be NULL, in which
+ case _used and _size fields will be zero. */
+ if (si->cfisi =3D=3D NULL) {
+ vg_assert(si->cfisi_used =3D=3D 0);
+ vg_assert(si->cfisi_size =3D=3D 0);
+ }
+
/* Set cfisi_minaddr and cfisi_maxaddr to summarise the entire
address range contained in cfisi[0 .. cfisi_used-1]. */
si->cfisi_minaddr =3D maxAddr;=20
si->cfisi_maxaddr =3D minAddr;
- for (i =3D 0; i < si->cfisi_used; i++) {
+ for (i =3D 0; i < (Int)si->cfisi_used; i++) {
Addr here_min =3D si->cfisi[i].base;
Addr here_max =3D si->cfisi[i].base + si->cfisi[i].len - 1;
if (here_min < si->cfisi_minaddr)
@@ -863,8 +870,32 @@
/* Sort the cfisi array by base address. */
VG_(ssort)(si->cfisi, si->cfisi_used, sizeof(*si->cfisi), compare_Cfi=
SI);
=20
+ /* If two adjacent entries overlap, truncate the first. */
+ for (i =3D 0; i < (Int)si->cfisi_used-1; i++) {
+ if (si->cfisi[i].base + si->cfisi[i].len > si->cfisi[i+1].base) {
+ Int new_len =3D si->cfisi[i+1].base - si->cfisi[i].base;
+ /* how could it be otherwise? The entries are sorted by the
+ .base field. */ =20
+ vg_assert(new_len >=3D 0);
+ vg_assert(new_len <=3D si->cfisi[i].len);
+ si->cfisi[i].len =3D new_len;
+ }
+ }
+
+ /* Zap any zero-sized entries resulting from the truncation
+ process. */
+ j =3D 0;
+ for (i =3D 0; i < (Int)si->cfisi_used; i++) {
+ if (si->cfisi[i].len > 0) {
+ si->cfisi[j] =3D si->cfisi[i];
+ j++;
+ }
+ }
+ /* VG_(printf)("XXXXXXXXXXXXX %d %d\n", si->cfisi_used, j); */
+ si->cfisi_used =3D j;
+
/* Ensure relevant postconditions hold. */
- for (i =3D 0; i < si->cfisi_used; i++) {
+ for (i =3D 0; i < (Int)si->cfisi_used; i++) {
/* No zero-length ranges. */
vg_assert(si->cfisi[i].len > 0);
/* Makes sense w.r.t. summary address range */
|