Blob Blame History Raw
--- 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);
    }