--- valgrind/coregrind/m_debuginfo/tytypes.c.jj 2009-10-14 15:00:07.000000000 +0200 +++ valgrind/coregrind/m_debuginfo/tytypes.c 2009-10-14 16:28:39.000000000 +0200 @@ -98,10 +98,15 @@ void ML_(pp_TyEnt)( TyEnt* te ) te->Te.Atom.value, te->Te.Atom.name); break; case Te_Field: - VG_(printf)("Te_Field(ty=0x%05lx,nLoc=%lu,loc=%p,\"%s\")", - te->Te.Field.typeR, te->Te.Field.nLoc, - te->Te.Field.loc, - te->Te.Field.name ? te->Te.Field.name : (UChar*)""); + if (te->Te.Field.nLoc == -1) + VG_(printf)("Te_Field(ty=0x%05lx,pos.offset=%ld,\"%s\")", + te->Te.Field.typeR, te->Te.Field.pos.offset, + te->Te.Field.name ? te->Te.Field.name : (UChar*)""); + else + VG_(printf)("Te_Field(ty=0x%05lx,nLoc=%lu,pos.loc=%p,\"%s\")", + te->Te.Field.typeR, te->Te.Field.nLoc, + te->Te.Field.pos.loc, + te->Te.Field.name ? te->Te.Field.name : (UChar*)""); break; case Te_Bound: VG_(printf)("Te_Bound["); @@ -476,7 +481,9 @@ Word ML_(TyEnt__cmp_by_all_except_cuOff) if (r != 0) return r; r = UWord__cmp(te1->Te.Field.nLoc, te2->Te.Field.nLoc); if (r != 0) return r; - r = Bytevector__cmp(te1->Te.Field.loc, te2->Te.Field.loc, + if (te1->Te.Field.nLoc == -1) + return Long__cmp(te1->Te.Field.pos.offset, te2->Te.Field.pos.offset); + r = Bytevector__cmp(te1->Te.Field.pos.loc, te2->Te.Field.pos.loc, te1->Te.Field.nLoc); return r; case Te_Bound: @@ -568,7 +575,8 @@ void ML_(TyEnt__make_EMPTY) ( TyEnt* te break; case Te_Field: if (te->Te.Field.name) ML_(dinfo_free)(te->Te.Field.name); - if (te->Te.Field.loc) ML_(dinfo_free)(te->Te.Field.loc); + if (te->Te.Field.nLoc > 0 && te->Te.Field.pos.loc) + ML_(dinfo_free)(te->Te.Field.pos.loc); break; case Te_Bound: break; @@ -747,24 +755,30 @@ XArray* /*UChar*/ ML_(describe_type)( /* field = ML_(TyEnts__index_by_cuOff)(tyents, NULL, fieldR); vg_assert(field); vg_assert(field->tag == Te_Field); - vg_assert(field->Te.Field.loc); - vg_assert(field->Te.Field.nLoc > 0); - /* Re data_bias in this call, we should really send in - a legitimate value. But the expression is expected - to be a constant expression, evaluation of which - will not need to use DW_OP_addr and hence we can - avoid the trouble of plumbing the data bias through - to this point (if, indeed, it has any meaning; from - which DebugInfo would we take the data bias? */ - res = ML_(evaluate_Dwarf3_Expr)( - field->Te.Field.loc, field->Te.Field.nLoc, - NULL/*fbGX*/, NULL/*RegSummary*/, - 0/*data_bias*/, - True/*push_initial_zero*/); - if (0) { - VG_(printf)("QQQ "); - ML_(pp_GXResult)(res); - VG_(printf)("\n"); + vg_assert(field->Te.Field.nLoc < 0 + || (field->Te.Field.nLoc > 0 + && field->Te.Field.pos.loc)); + if (field->Te.Field.nLoc == -1) { + res.kind = GXR_Addr; + res.word = field->Te.Field.pos.offset; + } else { + /* Re data_bias in this call, we should really send in + a legitimate value. But the expression is expected + to be a constant expression, evaluation of which + will not need to use DW_OP_addr and hence we can + avoid the trouble of plumbing the data bias through + to this point (if, indeed, it has any meaning; from + which DebugInfo would we take the data bias? */ + res = ML_(evaluate_Dwarf3_Expr)( + field->Te.Field.pos.loc, field->Te.Field.nLoc, + NULL/*fbGX*/, NULL/*RegSummary*/, + 0/*data_bias*/, + True/*push_initial_zero*/); + if (0) { + VG_(printf)("QQQ "); + ML_(pp_GXResult)(res); + VG_(printf)("\n"); + } } if (res.kind != GXR_Addr) continue; --- valgrind/coregrind/m_debuginfo/priv_tytypes.h.jj 2009-08-19 15:37:44.000000000 +0200 +++ valgrind/coregrind/m_debuginfo/priv_tytypes.h 2009-10-14 15:49:52.000000000 +0200 @@ -78,8 +78,13 @@ typedef struct { UChar* name; /* in mallocville */ UWord typeR; /* should be Te_TyXXXX */ - UChar* loc; /* location expr, in mallocville */ - UWord nLoc; /* number of bytes in .loc */ + union { + UChar* loc; /* location expr, in mallocville */ + Word offset; /* or offset from the beginning of containing + entity */ + } pos; + Word nLoc; /* number of bytes in .pos.loc if >= 0, or -1 + if .pos.offset should be used instead */ Bool isStruct; } Field; struct { --- valgrind/coregrind/m_debuginfo/readdwarf3.c.jj 2009-08-19 15:37:44.000000000 +0200 +++ valgrind/coregrind/m_debuginfo/readdwarf3.c 2009-10-14 16:25:51.000000000 +0200 @@ -2356,9 +2356,16 @@ static void parse_type_DIE ( /*MOD*/XArr if (attr == DW_AT_type && ctsSzB > 0) { fieldE.Te.Field.typeR = (UWord)cts; } - if (attr == DW_AT_data_member_location && ctsMemSzB > 0) { + /* There are 2 different cases for DW_AT_data_member_location. + If it is a constant class attribute, it contains byte offset + from the beginning of the containing entity. + Otherwise it is a location expression. */ + if (attr == DW_AT_data_member_location && ctsSzB > 0) { + fieldE.Te.Field.nLoc = -1; + fieldE.Te.Field.pos.offset = cts; + } else if (attr == DW_AT_data_member_location && ctsMemSzB > 0) { fieldE.Te.Field.nLoc = (UWord)ctsMemSzB; - fieldE.Te.Field.loc + fieldE.Te.Field.pos.loc = ML_(dinfo_memdup)( "di.readdwarf3.ptD.member.2", (UChar*)(UWord)cts, (SizeT)fieldE.Te.Field.nLoc ); @@ -2385,13 +2392,14 @@ static void parse_type_DIE ( /*MOD*/XArr vg_assert(fieldE.Te.Field.name); if (fieldE.Te.Field.typeR == D3_INVALID_CUOFF) goto bad_DIE; - if (fieldE.Te.Field.loc) { + if (fieldE.Te.Field.nLoc) { if (!parent_is_struct) { /* If this is a union type, pretend we haven't seen the data member location expression, as it is by definition redundant (it must be zero). */ - ML_(dinfo_free)(fieldE.Te.Field.loc); - fieldE.Te.Field.loc = NULL; + if (fieldE.Te.Field.nLoc > 0) + ML_(dinfo_free)(fieldE.Te.Field.pos.loc); + fieldE.Te.Field.pos.loc = NULL; fieldE.Te.Field.nLoc = 0; } /* Record this child in the parent */ @@ -2616,10 +2624,10 @@ static void parse_type_DIE ( /*MOD*/XArr /* For union members, Expr should be absent */ if (0) VG_(printf)("YYYY Acquire Field\n"); vg_assert(fieldE.tag == Te_Field); - vg_assert( (fieldE.Te.Field.nLoc > 0 && fieldE.Te.Field.loc != NULL) - || (fieldE.Te.Field.nLoc == 0 && fieldE.Te.Field.loc == NULL) ); + vg_assert(fieldE.Te.Field.nLoc <= 0 || fieldE.Te.Field.pos.loc != NULL); + vg_assert(fieldE.Te.Field.nLoc != 0 || fieldE.Te.Field.pos.loc == NULL); if (fieldE.Te.Field.isStruct) { - vg_assert(fieldE.Te.Field.nLoc > 0); + vg_assert(fieldE.Te.Field.nLoc != 0); } else { vg_assert(fieldE.Te.Field.nLoc == 0); }