Dwarf3 variable & type reader: use 64-bit numbers throughout to
represent the sizes of types, even on 32-bit hosts, where a type with
a size >= 2^32 is, well, if not meaningless, then at least impossible
to instantiate. This is of course motivated by reality .. on ppc32
SUSE11.0, the debuginfo for glibc-2.8 appears to contain a declaration
amounting to
char __EH_FRAME_BEGIN__ [4294967296]
Really.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@8683 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_debuginfo/d3basics.c b/coregrind/m_debuginfo/d3basics.c
index 9addc39..7f93291 100644
--- a/coregrind/m_debuginfo/d3basics.c
+++ b/coregrind/m_debuginfo/d3basics.c
@@ -696,13 +696,13 @@
UChar uc;
UShort nbytes;
Word i, nGuards;
- MaybeUWord *muw, *muw2;
+ MaybeULong *mul, *mul2;
HChar* badness = NULL;
UChar* p = &gx->payload[0];
XArray* results = VG_(newXA)( ML_(dinfo_zalloc), "di.d3basics.etG.1",
ML_(dinfo_free),
- sizeof(MaybeUWord) );
+ sizeof(MaybeULong) );
uc = *p++; /*biasMe*/
vg_assert(uc == 0 || uc == 1);
@@ -712,7 +712,7 @@
nGuards = 0;
while (True) {
- MaybeUWord thisResult;
+ MaybeULong thisResult;
uc = *p++;
if (uc == 1) /*isEnd*/
break;
@@ -724,14 +724,14 @@
if (0) VG_(printf)(" guard %ld: %#lx %#lx\n",
nGuards, aMin,aMax);
- thisResult.b = False;
- thisResult.w = 0;
+ thisResult.b = False;
+ thisResult.ul = 0;
/* Peer at this particular subexpression, to see if it's
obviously a constant. */
if (nbytes == 1 + sizeof(Addr) && *p == DW_OP_addr) {
- thisResult.b = True;
- thisResult.w = *(Addr*)(p+1) + data_bias;
+ thisResult.b = True;
+ thisResult.ul = (ULong)(*(Addr*)(p+1)) + (ULong)data_bias;
}
else if (nbytes == 2 + sizeof(Addr)
&& *p == DW_OP_addr
@@ -779,8 +779,8 @@
}
for (i = 0; i < nGuards; i++) {
- muw = VG_(indexXA)( results, i );
- if (muw->b == False)
+ mul = VG_(indexXA)( results, i );
+ if (mul->b == False)
break;
}
@@ -795,13 +795,13 @@
/* All the subexpressions produced a constant, but did they all produce
the same one? */
- muw = VG_(indexXA)( results, 0 );
- tl_assert(muw->b == True); /* we just established that all exprs are ok */
+ mul = VG_(indexXA)( results, 0 );
+ tl_assert(mul->b == True); /* we just established that all exprs are ok */
for (i = 1; i < nGuards; i++) {
- muw2 = VG_(indexXA)( results, i );
- tl_assert(muw2->b == True);
- if (muw2->w != muw->w) {
+ mul2 = VG_(indexXA)( results, i );
+ tl_assert(mul2->b == True);
+ if (mul2->ul != mul->ul) {
res.word = (UWord)"trivial GExpr: subexpressions disagree";
VG_(deleteXA)( results );
return res;
@@ -811,7 +811,7 @@
/* Well, we have success. All subexpressions evaluated, and
they all agree. Hurrah. */
res.kind = GXR_Value;
- res.word = muw->w;
+ res.word = (UWord)mul->ul; /* NB: narrowing from ULong */
VG_(deleteXA)( results );
return res;
}
diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c
index 01032e0..c73fba3 100644
--- a/coregrind/m_debuginfo/debuginfo.c
+++ b/coregrind/m_debuginfo/debuginfo.c
@@ -1714,7 +1714,7 @@
Addr data_addr,
Addr data_bias )
{
- MaybeUWord muw;
+ MaybeULong mul;
SizeT var_szB;
GXResult res;
Bool show = False;
@@ -1723,12 +1723,17 @@
vg_assert(var->gexpr);
/* Figure out how big the variable is. */
- muw = ML_(sizeOfType)(tyents, var->typeR);
- /* if this var has a type whose size is unknown, it should never
- have been added. ML_(addVar) should have rejected it. */
- vg_assert(muw.b == True);
+ mul = ML_(sizeOfType)(tyents, var->typeR);
+ /* If this var has a type whose size is unknown, zero, or
+ impossibly large, it should never have been added. ML_(addVar)
+ should have rejected it. */
+ vg_assert(mul.b == True);
+ vg_assert(mul.ul > 0);
+ if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
+ /* After this point, we assume we can truncate mul.ul to a host word
+ safely (without loss of info). */
- var_szB = muw.w;
+ var_szB = (SizeT)mul.ul; /* NB: truncate to host word */
if (show) {
VG_(printf)("VVVV: data_address_%#lx_is_in_var: %s :: ",
@@ -2264,7 +2269,7 @@
{
GXResult res_sp_6k, res_sp_7k, res_fp_6k, res_fp_7k;
RegSummary regs;
- MaybeUWord muw;
+ MaybeULong mul;
Bool isVec;
TyEnt* ty;
@@ -2273,11 +2278,15 @@
VG_(printf)("adeps: var %s\n", var->name );
/* Figure out how big the variable is. */
- muw = ML_(sizeOfType)(tyents, var->typeR);
- /* if this var has a type whose size is unknown or zero, it should
- never have been added. ML_(addVar) should have rejected it. */
- vg_assert(muw.b == True);
- vg_assert(muw.w > 0);
+ mul = ML_(sizeOfType)(tyents, var->typeR);
+ /* If this var has a type whose size is unknown, zero, or
+ impossibly large, it should never have been added. ML_(addVar)
+ should have rejected it. */
+ vg_assert(mul.b == True);
+ vg_assert(mul.ul > 0);
+ if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
+ /* After this point, we assume we can truncate mul.ul to a host word
+ safely (without loss of info). */
/* skip if non-array and we're only interested in arrays */
ty = ML_(TyEnts__index_by_cuOff)( tyents, NULL, var->typeR );
@@ -2341,9 +2350,9 @@
tl_assert(res.kind == GXR_Value);
if (debug)
VG_(printf)(" %5ld .. %5ld (sp) %s\n",
- res.word, res.word + muw.w - 1, var->name);
+ res.word, res.word + ((UWord)mul.ul) - 1, var->name);
block.base = res.word;
- block.szB = muw.w;
+ block.szB = (SizeT)mul.ul;
block.spRel = True;
block.isVec = isVec;
VG_(memset)( &block.name[0], 0, sizeof(block.name) );
@@ -2360,9 +2369,9 @@
tl_assert(res.kind == GXR_Value);
if (debug)
VG_(printf)(" %5ld .. %5ld (FP) %s\n",
- res.word, res.word + muw.w - 1, var->name);
+ res.word, res.word + ((UWord)mul.ul) - 1, var->name);
block.base = res.word;
- block.szB = muw.w;
+ block.szB = (SizeT)mul.ul;
block.spRel = False;
block.isVec = isVec;
VG_(memset)( &block.name[0], 0, sizeof(block.name) );
@@ -2555,7 +2564,7 @@
Bool isVec;
GXResult res;
- MaybeUWord muw;
+ MaybeULong mul;
GlobalBlock gb;
TyEnt* ty;
DiVariable* var = VG_(indexXA)( range->vars, varIx );
@@ -2582,13 +2591,16 @@
if (0) VG_(printf)("%#lx\n", res.word);
/* Figure out how big the variable is. */
- muw = ML_(sizeOfType)(di->admin_tyents, var->typeR);
+ mul = ML_(sizeOfType)(di->admin_tyents, var->typeR);
- /* if this var has a type whose size is unknown or zero,
- it should never have been added. ML_(addVar) should
- have rejected it. */
- vg_assert(muw.b == True);
- vg_assert(muw.w > 0);
+ /* If this var has a type whose size is unknown, zero, or
+ impossibly large, it should never have been added.
+ ML_(addVar) should have rejected it. */
+ vg_assert(mul.b == True);
+ vg_assert(mul.ul > 0);
+ if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
+ /* After this point, we assume we can truncate mul.ul to a
+ host word safely (without loss of info). */
/* skip if non-array and we're only interested in
arrays */
@@ -2610,7 +2622,7 @@
:"??",var->lineNo);
VG_(memset)(&gb, 0, sizeof(gb));
gb.addr = res.word;
- gb.szB = muw.w;
+ gb.szB = (SizeT)mul.ul;
gb.isVec = isVec;
VG_(strncpy)(&gb.name[0], var->name, sizeof(gb.name)-1);
VG_(strncpy)(&gb.soname[0], di->soname, sizeof(gb.soname)-1);
diff --git a/coregrind/m_debuginfo/priv_misc.h b/coregrind/m_debuginfo/priv_misc.h
index caf6db4..6e23e5c 100644
--- a/coregrind/m_debuginfo/priv_misc.h
+++ b/coregrind/m_debuginfo/priv_misc.h
@@ -45,7 +45,7 @@
/* A handy type, a la Haskell's Maybe type. Yes, I know, C sucks.
Been there. Done that. Seen the movie. Got the T-shirt. Etc. */
-typedef struct { UWord w; Bool b; } MaybeUWord;
+typedef struct { ULong ul; Bool b; } MaybeULong;
#endif /* ndef __PRIV_MISC_H */
diff --git a/coregrind/m_debuginfo/priv_tytypes.h b/coregrind/m_debuginfo/priv_tytypes.h
index 598ead6..fd7c359 100644
--- a/coregrind/m_debuginfo/priv_tytypes.h
+++ b/coregrind/m_debuginfo/priv_tytypes.h
@@ -160,7 +160,7 @@
/* How big is this type? If .b in the returned struct is False, the
size is unknown. */
-MaybeUWord ML_(sizeOfType)( XArray* /* of TyEnt */ tyents,
+MaybeULong ML_(sizeOfType)( XArray* /* of TyEnt */ tyents,
UWord cuOff );
/* Describe where in the type 'offset' falls. Caller must
diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c
index 70a7a42..4076d00 100644
--- a/coregrind/m_debuginfo/storage.c
+++ b/coregrind/m_debuginfo/storage.c
@@ -726,6 +726,8 @@
DiVariable var;
Bool all;
TyEnt* ent;
+ MaybeULong mul;
+ HChar* badness;
tl_assert(di && di->admin_tyents);
@@ -789,14 +791,23 @@
/* If the type's size is zero (which can mean unknown size), ignore
it. We will never be able to actually relate a data address to
a data object with zero size, so there's no point in storing
- info on it. */
- if (ML_(sizeOfType)(di->admin_tyents, typeR).b != True) {
+ info on it. On 32-bit platforms, also reject types whose size
+ is 2^32 bytes or large. (It's amazing what junk shows up ..) */
+ mul = ML_(sizeOfType)(di->admin_tyents, typeR);
+
+ badness = NULL;
+ if (mul.b != True)
+ badness = "unknown size";
+ else if (mul.ul == 0)
+ badness = "zero size ";
+ else if (sizeof(void*) == 4 && mul.ul >= (1ULL<<32))
+ badness = "implausibly large";
+
+ if (badness) {
static Int complaints = 10;
if (VG_(clo_verbosity) >= 2 && complaints > 0) {
- VG_(message)(Vg_DebugMsg,
- "warning: addVar: unknown size (%s)",
- name
- );
+ VG_(message)(Vg_DebugMsg, "warning: addVar: %s (%s)",
+ badness, name );
complaints--;
}
return;
diff --git a/coregrind/m_debuginfo/tytypes.c b/coregrind/m_debuginfo/tytypes.c
index a7a6652..1d2f5fe 100644
--- a/coregrind/m_debuginfo/tytypes.c
+++ b/coregrind/m_debuginfo/tytypes.c
@@ -239,10 +239,10 @@
VG_(printf)("enum %s", ent->Te.TyEnum.name);
break;
case Te_TyStOrUn:
- if (!ent->Te.TyStOrUn.name) goto unhandled;
VG_(printf)("%s %s",
ent->Te.TyStOrUn.isStruct ? "struct" : "union",
- ent->Te.TyStOrUn.name);
+ ent->Te.TyStOrUn.name ? ent->Te.TyStOrUn.name
+ : (UChar*)"<anonymous>" );
break;
case Te_TyArray:
ML_(pp_TyEnt_C_ishly)(tyents, ent->Te.TyArray.typeR);
@@ -275,6 +275,9 @@
VG_(printf)("%svoid",
ent->Te.TyVoid.isFake ? "fake" : "");
break;
+ case Te_UNKNOWN:
+ ML_(pp_TyEnt)(ent);
+ break;
default:
goto unhandled;
}
@@ -604,30 +607,30 @@
/* How big is this type? If .b in the returned struct is False, the
size is unknown. */
-static MaybeUWord mk_MaybeUWord_Nothing ( void ) {
- MaybeUWord muw;
- muw.w = 0;
- muw.b = False;
- return muw;
+static MaybeULong mk_MaybeULong_Nothing ( void ) {
+ MaybeULong mul;
+ mul.ul = 0;
+ mul.b = False;
+ return mul;
}
-static MaybeUWord mk_MaybeUWord_Just ( UWord w ) {
- MaybeUWord muw;
- muw.w = w;
- muw.b = True;
- return muw;
+static MaybeULong mk_MaybeULong_Just ( ULong ul ) {
+ MaybeULong mul;
+ mul.ul = ul;
+ mul.b = True;
+ return mul;
}
-static MaybeUWord mul_MaybeUWord ( MaybeUWord muw1, MaybeUWord muw2 ) {
- if (!muw1.b) { vg_assert(muw1.w == 0); return muw1; }
- if (!muw2.b) { vg_assert(muw2.w == 0); return muw2; }
- muw1.w *= muw2.w;
- return muw1;
+static MaybeULong mul_MaybeULong ( MaybeULong mul1, MaybeULong mul2 ) {
+ if (!mul1.b) { vg_assert(mul1.ul == 0); return mul1; }
+ if (!mul2.b) { vg_assert(mul2.ul == 0); return mul2; }
+ mul1.ul *= mul2.ul;
+ return mul1;
}
-MaybeUWord ML_(sizeOfType)( XArray* /* of TyEnt */ tyents,
+MaybeULong ML_(sizeOfType)( XArray* /* of TyEnt */ tyents,
UWord cuOff )
{
Word i;
- MaybeUWord eszB;
+ MaybeULong eszB;
TyEnt* ent = ML_(TyEnts__index_by_cuOff)(tyents, NULL, cuOff);
TyEnt* ent2;
vg_assert(ent);
@@ -635,7 +638,7 @@
switch (ent->tag) {
case Te_TyBase:
vg_assert(ent->Te.TyBase.szB > 0);
- return mk_MaybeUWord_Just( ent->Te.TyBase.szB );
+ return mk_MaybeULong_Just( ent->Te.TyBase.szB );
case Te_TyQual:
return ML_(sizeOfType)( tyents, ent->Te.TyQual.typeR );
case Te_TyTyDef:
@@ -643,23 +646,23 @@
ent->Te.TyTyDef.typeR);
vg_assert(ent2);
if (ent2->tag == Te_UNKNOWN)
- return mk_MaybeUWord_Nothing(); /*UNKNOWN*/
+ return mk_MaybeULong_Nothing(); /*UNKNOWN*/
return ML_(sizeOfType)( tyents, ent->Te.TyTyDef.typeR );
case Te_TyPorR:
vg_assert(ent->Te.TyPorR.szB == 4 || ent->Te.TyPorR.szB == 8);
- return mk_MaybeUWord_Just( ent->Te.TyPorR.szB );
+ return mk_MaybeULong_Just( ent->Te.TyPorR.szB );
case Te_TyStOrUn:
return ent->Te.TyStOrUn.complete
- ? mk_MaybeUWord_Just( ent->Te.TyStOrUn.szB )
- : mk_MaybeUWord_Nothing();
+ ? mk_MaybeULong_Just( ent->Te.TyStOrUn.szB )
+ : mk_MaybeULong_Nothing();
case Te_TyEnum:
- return mk_MaybeUWord_Just( ent->Te.TyEnum.szB );
+ return mk_MaybeULong_Just( ent->Te.TyEnum.szB );
case Te_TyArray:
ent2 = ML_(TyEnts__index_by_cuOff)(tyents, NULL,
ent->Te.TyArray.typeR);
vg_assert(ent2);
if (ent2->tag == Te_UNKNOWN)
- return mk_MaybeUWord_Nothing(); /*UNKNOWN*/
+ return mk_MaybeULong_Nothing(); /*UNKNOWN*/
eszB = ML_(sizeOfType)( tyents, ent->Te.TyArray.typeR );
for (i = 0; i < VG_(sizeXA)( ent->Te.TyArray.boundRs ); i++) {
UWord bo_cuOff
@@ -669,11 +672,11 @@
vg_assert(bo);
vg_assert(bo->tag == Te_Bound);
if (!(bo->Te.Bound.knownL && bo->Te.Bound.knownU))
- return mk_MaybeUWord_Nothing(); /*UNKNOWN*/
- eszB = mul_MaybeUWord(
+ return mk_MaybeULong_Nothing(); /*UNKNOWN*/
+ eszB = mul_MaybeULong(
eszB,
- mk_MaybeUWord_Just( bo->Te.Bound.boundU
- - bo->Te.Bound.boundL + 1 ));
+ mk_MaybeULong_Just( (ULong)(bo->Te.Bound.boundU
+ - bo->Te.Bound.boundL + 1) ));
}
return eszB;
default:
@@ -727,7 +730,7 @@
case Te_TyStOrUn: {
Word i;
GXResult res;
- MaybeUWord muw;
+ MaybeULong mul;
XArray* fieldRs;
UWord fieldR;
TyEnt* field = NULL;
@@ -761,11 +764,11 @@
}
if (res.kind != GXR_Value)
continue;
- muw = ML_(sizeOfType)( tyents, field->Te.Field.typeR );
- if (muw.b != True)
+ mul = ML_(sizeOfType)( tyents, field->Te.Field.typeR );
+ if (mul.b != True)
goto done; /* size of field is unknown (?!) */
offMin = res.word;
- offMax1 = offMin + muw.w;
+ offMax1 = offMin + (OffT)mul.ul;
if (offMin == offMax1)
continue;
vg_assert(offMin < offMax1);
@@ -792,7 +795,7 @@
}
case Te_TyArray: {
- MaybeUWord muw;
+ MaybeULong mul;
UWord size, eszB, ix;
UWord boundR;
TyEnt* elemTy;
@@ -817,10 +820,10 @@
goto done;
size = bound->Te.Bound.boundU - bound->Te.Bound.boundL + 1;
vg_assert(size >= 1);
- muw = ML_(sizeOfType)( tyents, ty->Te.TyArray.typeR );
- if (muw.b != True)
+ mul = ML_(sizeOfType)( tyents, ty->Te.TyArray.typeR );
+ if (mul.b != True)
goto done; /* size of element type not known */
- eszB = muw.w;
+ eszB = mul.ul;
if (eszB == 0) goto done;
ix = offset / eszB;
VG_(addBytesToXA)( xa, "[", 1 );