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 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_debuginfo/d3basics.c b/coregrind/m_debuginfo/d3basics.c
index 9addc39..7f93291 100644
--- a/coregrind/m_debuginfo/d3basics.c
+++ b/coregrind/m_debuginfo/d3basics.c
@@ -696,13 +696,13 @@
    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 @@
 
    nGuards = 0;
    while (True) {
-      MaybeUWord thisResult;
+      MaybeULong thisResult;
       uc = *p++;
       if (uc == 1) /*isEnd*/
          break;
@@ -724,14 +724,14 @@
       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 @@
    }
 
    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 @@
 
    /* 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 @@
    /* 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 01032e0..c73fba3 100644
--- a/coregrind/m_debuginfo/debuginfo.c
+++ b/coregrind/m_debuginfo/debuginfo.c
@@ -1714,7 +1714,7 @@
                                      Addr          data_addr,
                                      Addr          data_bias )
 {
-   MaybeUWord muw;
+   MaybeULong mul;
    SizeT      var_szB;
    GXResult   res;
    Bool       show = False;
@@ -1723,12 +1723,17 @@
    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);
+   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 = muw.w;
+   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 @@
 {
    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 @@
       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 @@
          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 @@
          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 @@
 
             Bool        isVec;
             GXResult    res;
-            MaybeUWord  muw;
+            MaybeULong  mul;
             GlobalBlock gb;
             TyEnt*      ty;
             DiVariable* var = VG_(indexXA)( range->vars, varIx );
@@ -2582,13 +2591,16 @@
             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 @@
                                              :"??",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 caf6db4..6e23e5c 100644
--- a/coregrind/m_debuginfo/priv_misc.h
+++ b/coregrind/m_debuginfo/priv_misc.h
@@ -45,7 +45,7 @@
 
 /* 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 598ead6..fd7c359 100644
--- a/coregrind/m_debuginfo/priv_tytypes.h
+++ b/coregrind/m_debuginfo/priv_tytypes.h
@@ -160,7 +160,7 @@
 /* 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 70a7a42..4076d00 100644
--- a/coregrind/m_debuginfo/storage.c
+++ b/coregrind/m_debuginfo/storage.c
@@ -726,6 +726,8 @@
    DiVariable var;
    Bool       all;
    TyEnt*     ent;
+   MaybeULong mul;
+   HChar*     badness;
 
    tl_assert(di && di->admin_tyents);
 
@@ -789,14 +791,23 @@
    /* 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 a7a6652..1d2f5fe 100644
--- a/coregrind/m_debuginfo/tytypes.c
+++ b/coregrind/m_debuginfo/tytypes.c
@@ -239,10 +239,10 @@
          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*)"<anonymous>" );
          break;
       case Te_TyArray:
          ML_(pp_TyEnt_C_ishly)(tyents, ent->Te.TyArray.typeR);
@@ -275,6 +275,9 @@
          VG_(printf)("%svoid",
                      ent->Te.TyVoid.isFake ? "fake" : "");
          break;
+      case Te_UNKNOWN:
+         ML_(pp_TyEnt)(ent);
+         break;
       default:
          goto unhandled;
    }
@@ -604,30 +607,30 @@
 /* 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 @@
    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 @@
                                             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 @@
             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 @@
          case Te_TyStOrUn: {
             Word       i;
             GXResult   res;
-            MaybeUWord muw;
+            MaybeULong mul;
             XArray*    fieldRs;
             UWord      fieldR;
             TyEnt*     field = NULL;
@@ -761,11 +764,11 @@
                }
                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 @@
          }
 
          case Te_TyArray: {
-            MaybeUWord muw;
+            MaybeULong mul;
             UWord      size, eszB, ix;
             UWord      boundR;
             TyEnt*     elemTy;
@@ -817,10 +820,10 @@
                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 );