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
This commit is contained in:
Julian Seward 2008-10-20 16:08:55 +00:00
parent fe266da253
commit 1eceb4282b
6 changed files with 111 additions and 85 deletions

View File

@ -696,13 +696,13 @@ GXResult ML_(evaluate_trivial_GX)( GExpr* gx, Addr data_bias )
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 @@ GXResult ML_(evaluate_trivial_GX)( GExpr* gx, Addr data_bias )
nGuards = 0;
while (True) {
MaybeUWord thisResult;
MaybeULong thisResult;
uc = *p++;
if (uc == 1) /*isEnd*/
break;
@ -724,14 +724,14 @@ GXResult ML_(evaluate_trivial_GX)( GExpr* gx, Addr data_bias )
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 @@ GXResult ML_(evaluate_trivial_GX)( GExpr* gx, Addr data_bias )
}
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 @@ GXResult ML_(evaluate_trivial_GX)( GExpr* gx, Addr data_bias )
/* 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 @@ GXResult ML_(evaluate_trivial_GX)( GExpr* gx, Addr data_bias )
/* 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;
}

View File

@ -1714,7 +1714,7 @@ static Bool data_address_is_in_var ( /*OUT*/UWord* offset,
Addr data_addr,
Addr data_bias )
{
MaybeUWord muw;
MaybeULong mul;
SizeT var_szB;
GXResult res;
Bool show = False;
@ -1723,12 +1723,17 @@ static Bool data_address_is_in_var ( /*OUT*/UWord* offset,
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 @@ void analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks,
{
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 @@ void analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks,
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 @@ void analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks,
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 @@ void analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks,
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 @@ void* /* really, XArray* of GlobalBlock */
Bool isVec;
GXResult res;
MaybeUWord muw;
MaybeULong mul;
GlobalBlock gb;
TyEnt* ty;
DiVariable* var = VG_(indexXA)( range->vars, varIx );
@ -2582,13 +2591,16 @@ void* /* really, XArray* of GlobalBlock */
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 @@ void* /* really, XArray* of GlobalBlock */
:"??",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);

View File

@ -45,7 +45,7 @@ UChar* ML_(dinfo_memdup)( HChar* cc, UChar* str, SizeT nStr );
/* 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 */

View File

@ -160,7 +160,7 @@ void ML_(TyEnt__make_EMPTY) ( TyEnt* te );
/* 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

View File

@ -726,6 +726,8 @@ void ML_(addVar)( struct _DebugInfo* di,
DiVariable var;
Bool all;
TyEnt* ent;
MaybeULong mul;
HChar* badness;
tl_assert(di && di->admin_tyents);
@ -789,14 +791,23 @@ void ML_(addVar)( struct _DebugInfo* di,
/* 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;

View File

@ -239,10 +239,10 @@ void ML_(pp_TyEnt_C_ishly)( XArray* /* of TyEnt */ tyents,
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 @@ void ML_(pp_TyEnt_C_ishly)( XArray* /* of TyEnt */ tyents,
VG_(printf)("%svoid",
ent->Te.TyVoid.isFake ? "fake" : "");
break;
case Te_UNKNOWN:
ML_(pp_TyEnt)(ent);
break;
default:
goto unhandled;
}
@ -604,30 +607,30 @@ void ML_(TyEnt__make_EMPTY) ( TyEnt* te )
/* 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 @@ MaybeUWord ML_(sizeOfType)( XArray* /* of TyEnt */ tyents,
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 @@ MaybeUWord ML_(sizeOfType)( XArray* /* of TyEnt */ tyents,
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 @@ MaybeUWord ML_(sizeOfType)( XArray* /* of TyEnt */ tyents,
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 @@ XArray* /*UChar*/ ML_(describe_type)( /*OUT*/OffT* residual_offset,
case Te_TyStOrUn: {
Word i;
GXResult res;
MaybeUWord muw;
MaybeULong mul;
XArray* fieldRs;
UWord fieldR;
TyEnt* field = NULL;
@ -761,11 +764,11 @@ XArray* /*UChar*/ ML_(describe_type)( /*OUT*/OffT* residual_offset,
}
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 @@ XArray* /*UChar*/ ML_(describe_type)( /*OUT*/OffT* residual_offset,
}
case Te_TyArray: {
MaybeUWord muw;
MaybeULong mul;
UWord size, eszB, ix;
UWord boundR;
TyEnt* elemTy;
@ -817,10 +820,10 @@ XArray* /*UChar*/ ML_(describe_type)( /*OUT*/OffT* residual_offset,
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 );