From: Julian Seward Date: Mon, 20 Oct 2008 16:08:55 +0000 (+0000) Subject: Dwarf3 variable & type reader: use 64-bit numbers throughout to X-Git-Tag: svn/VALGRIND_3_4_0~211 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1eceb4282ba99f02f7015685a3e8e7c397e1171e;p=thirdparty%2Fvalgrind.git 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 --- diff --git a/coregrind/m_debuginfo/d3basics.c b/coregrind/m_debuginfo/d3basics.c index 9addc39509..7f932910e3 100644 --- a/coregrind/m_debuginfo/d3basics.c +++ b/coregrind/m_debuginfo/d3basics.c @@ -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; } diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index 01032e013c..c73fba37ea 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -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); - - var_szB = muw.w; + 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 = (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); diff --git a/coregrind/m_debuginfo/priv_misc.h b/coregrind/m_debuginfo/priv_misc.h index caf6db44ff..6e23e5cb6e 100644 --- a/coregrind/m_debuginfo/priv_misc.h +++ b/coregrind/m_debuginfo/priv_misc.h @@ -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 */ diff --git a/coregrind/m_debuginfo/priv_tytypes.h b/coregrind/m_debuginfo/priv_tytypes.h index 598ead659a..fd7c359347 100644 --- a/coregrind/m_debuginfo/priv_tytypes.h +++ b/coregrind/m_debuginfo/priv_tytypes.h @@ -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 diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c index 70a7a421be..4076d00345 100644 --- a/coregrind/m_debuginfo/storage.c +++ b/coregrind/m_debuginfo/storage.c @@ -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; diff --git a/coregrind/m_debuginfo/tytypes.c b/coregrind/m_debuginfo/tytypes.c index a7a665256f..1d2f5fefbf 100644 --- a/coregrind/m_debuginfo/tytypes.c +++ b/coregrind/m_debuginfo/tytypes.c @@ -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*)"" ); 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 );