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