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