Author: sewardj
Date: 2008-02-12 13:54:28 +0000 (Tue, 12 Feb 2008)
New Revision: 7402

Log:

* Describe offsets inside variables in terms of source level types,
  where possible

* Record declaration coordinates of variables and use them in messages



Modified:
   branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c
   branches/DATASYMS/coregrind/m_debuginfo/misc.c
   branches/DATASYMS/coregrind/m_debuginfo/priv_misc.h
   branches/DATASYMS/coregrind/m_debuginfo/priv_storage.h
   branches/DATASYMS/coregrind/m_debuginfo/priv_tytypes.h
   branches/DATASYMS/coregrind/m_debuginfo/readdwarf.c
   branches/DATASYMS/coregrind/m_debuginfo/readdwarf3.c
   branches/DATASYMS/coregrind/m_debuginfo/readelf.c
   branches/DATASYMS/coregrind/m_debuginfo/readstabs.c
   branches/DATASYMS/coregrind/m_debuginfo/storage.c
   branches/DATASYMS/coregrind/m_debuginfo/tytypes.c
   branches/DATASYMS/memcheck/mc_main.c


Modified: branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c 2008-02-11 21:22:15 UTC 
(rev 7401)
+++ branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c 2008-02-12 13:54:28 UTC 
(rev 7402)
@@ -51,8 +51,8 @@
 #include "pub_core_oset.h"
 #include "pub_core_stacktrace.h" // VG_(get_StackTrace)
 #include "priv_misc.h"           /* dinfo_zalloc/free */
+#include "priv_tytypes.h"
 #include "priv_storage.h"
-#include "priv_tytypes.h"
 #include "priv_readdwarf.h"
 #include "priv_readstabs.h"
 #if defined(VGO_linux)
@@ -976,13 +976,13 @@
    GXResult res;
    Bool     show = False;
    vg_assert(var->name);
-   vg_assert(var->typeV);
+   vg_assert(var->type);
    vg_assert(var->gexprV);
-   var_szB = ML_(sizeOfType)(var->typeV);
+   var_szB = ML_(sizeOfType)(var->type);
 
    if (show) {
       VG_(printf)("VVVV: find loc: %s :: ", var->name );
-      ML_(pp_Type_C_ishly)( var->typeV );
+      ML_(pp_Type_C_ishly)( var->type );
       VG_(printf)("\n");
    }
 
@@ -1091,10 +1091,13 @@
          DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j );
          SizeT       offset;
          if (data_address_is_in_var( &offset, var, &regs, data_addr )) {
+            XArray* xa = ML_(describe_type)( var->type, offset );
             VG_(snprintf)(
                dname, (SizeT)n_dname,
-               "Address 0x%lx is %lu bytes inside local var \"%s\"",
-               data_addr, offset, var->name);
+               "Address 0x%lx is %lu bytes inside local var "
+               "\"%s\" (%s) declared at %s:%d",
+               data_addr, offset, var->name, VG_(indexXA)(xa,0),
+               var->fileName ? var->fileName : "(unknown)", var->lineNo );
             dname[n_dname-1] = 0;
             return True;
          }

Modified: branches/DATASYMS/coregrind/m_debuginfo/misc.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/misc.c      2008-02-11 21:22:15 UTC 
(rev 7401)
+++ branches/DATASYMS/coregrind/m_debuginfo/misc.c      2008-02-12 13:54:28 UTC 
(rev 7402)
@@ -54,6 +54,12 @@
 UChar* ML_(dinfo_strdup) ( const UChar* str ) {
    return VG_(arena_strdup)( VG_AR_DINFO, str );
 }
+UChar* ML_(dinfo_memdup)( UChar* mem, UWord nbytes ) {
+   UChar* r = VG_(arena_malloc)( VG_AR_DINFO, nbytes );
+   if (nbytes > 0)
+      VG_(memcpy)( r, mem, nbytes );
+   return r;
+}
 
 /*--------------------------------------------------------------------*/
 /*--- end                                                   misc.c ---*/

Modified: branches/DATASYMS/coregrind/m_debuginfo/priv_misc.h
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/priv_misc.h 2008-02-11 21:22:15 UTC 
(rev 7401)
+++ branches/DATASYMS/coregrind/m_debuginfo/priv_misc.h 2008-02-12 13:54:28 UTC 
(rev 7402)
@@ -50,8 +50,8 @@
 void*  ML_(dinfo_zalloc)( SizeT szB );
 void   ML_(dinfo_free)( void* v );
 UChar* ML_(dinfo_strdup)( const UChar* str );
+UChar* ML_(dinfo_memdup)( UChar* mem, UWord nbytes );
 
-
 #endif /* ndef __PRIV_MISC_H */
 
 /*--------------------------------------------------------------------*/

Modified: branches/DATASYMS/coregrind/m_debuginfo/priv_storage.h
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/priv_storage.h      2008-02-11 
21:22:15 UTC (rev 7401)
+++ branches/DATASYMS/coregrind/m_debuginfo/priv_storage.h      2008-02-12 
13:54:28 UTC (rev 7402)
@@ -37,8 +37,8 @@
 /* See comment at top of debuginfo.c for explanation of
    the _svma / _avma / _image / _bias naming scheme.
 */
-/* Note this is not freestanding; needs pub_core_xarray.h to be
-   included before it. */
+/* Note this is not freestanding; needs pub_core_xarray.h and
+   priv_tytypes.h to be included before it. */
 
 #ifndef __PRIV_STORAGE_H
 #define __PRIV_STORAGE_H
@@ -221,9 +221,11 @@
 typedef
    struct {
       UChar* name;   /* freestanding, in AR_DINFO */
-      void*  typeV;  /* FIXME: make this D3Type* */
+      Type*  type;
       void*  gexprV; /* FIXME: make this GExpr* */
       void*  fbGXv;  /* FIXME: make this GExpr*.  SHARED. */
+      UChar* fileName; /* where declared; may be NULL. */
+      Int    lineNo;   /* where declared; may be zero. */
    }
    DiVariable;
 
@@ -409,9 +411,11 @@
                          Addr   aMin,
                          Addr   aMax,
                          UChar* name,
-                         void*  type,  /* actually D3Type* */
+                         Type*  type,
                          void*  gexpr, /* actually GExpr* */
                          void*  fbGXv, /* actually GExpr*.  SHARED. */
+                         UChar* fileName, /* where decl'd - may be NULL */
+                         Int    lineNo, /* where decl'd - may be zero */
                          Bool   show );
 
 /* Canonicalise the tables held by 'di', in preparation for use.  Call

Modified: branches/DATASYMS/coregrind/m_debuginfo/priv_tytypes.h
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/priv_tytypes.h      2008-02-11 
21:22:15 UTC (rev 7401)
+++ branches/DATASYMS/coregrind/m_debuginfo/priv_tytypes.h      2008-02-12 
13:54:28 UTC (rev 7402)
@@ -145,13 +145,16 @@
 /* NOTE: this assumes that the types have all been 'resolved' (that
    is, inter-type references expressed as .debug_info offsets have
    been converted into pointers) */
-void ML_(pp_Type_C_ishly) ( void* /* Type* */ tyV );
+void ML_(pp_Type_C_ishly) ( Type* ty );
 
 /* How big is this type?  (post-resolved only) */
 /* FIXME: check all pointers before dereferencing */
-SizeT ML_(sizeOfType)( void* /* Type */ tyV );
+SizeT ML_(sizeOfType)( Type* ty );
 
+/* Describe where in the type 'offset' falls. */
+XArray* /*UChar*/ ML_(describe_type)( Type* ty, OffT offset );
 
+
 #endif /* ndef __PRIV_TYTYPES_H */
 
 /*--------------------------------------------------------------------*/

Modified: branches/DATASYMS/coregrind/m_debuginfo/readdwarf.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/readdwarf.c 2008-02-11 21:22:15 UTC 
(rev 7401)
+++ branches/DATASYMS/coregrind/m_debuginfo/readdwarf.c 2008-02-12 13:54:28 UTC 
(rev 7402)
@@ -40,6 +40,7 @@
 #include "pub_core_options.h"
 #include "pub_core_xarray.h"
 #include "priv_misc.h"             /* dinfo_zalloc/free/strdup */
+#include "priv_tytypes.h"
 #include "priv_storage.h"
 #include "priv_readdwarf.h"        /* self */
 

Modified: branches/DATASYMS/coregrind/m_debuginfo/readdwarf3.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/readdwarf3.c        2008-02-11 
21:22:15 UTC (rev 7401)
+++ branches/DATASYMS/coregrind/m_debuginfo/readdwarf3.c        2008-02-12 
13:54:28 UTC (rev 7402)
@@ -56,8 +56,8 @@
 #include "pub_core_options.h"
 #include "pub_core_xarray.h"
 #include "priv_misc.h"             /* dinfo_zalloc/free/strdup */
+#include "priv_tytypes.h"
 #include "priv_storage.h"
-#include "priv_tytypes.h"
 #include "priv_d3basics.h"
 #include "priv_readdwarf3.h"       /* self */
 
@@ -222,12 +222,31 @@
    return result;
 }
 
+/* Assume 'c' points to the start of a string.  Return the absolute
+   address of whatever it points at, and advance it past the
+   terminating zero.  This makes it safe for the caller to then strdup
+   the returned value, since (w.r.t. image overruns) the process of
+   advancing past the terminating zero will already have "vetted" the
+   string. */
+static UChar* get_AsciiZ ( Cursor* c ) {
+   UChar  uc;
+   UChar* res = get_address_of_Cursor(c);
+   do { uc = get_UChar(c); } while (uc != 0);
+   return res;
+}
+
 static ULong peek_ULEB128 ( Cursor* c ) {
    Word here = c->region_next;
    ULong r = get_ULEB128( c );
    c->region_next = here;
    return r;
 }
+static UChar peek_UChar ( Cursor* c ) {
+   Word here = c->region_next;
+   UChar r = get_UChar( c );
+   c->region_next = here;
+   return r;
+}
 
 static ULong get_Dwarfish_UWord ( Cursor* c, Bool is_dw64 ) {
    return is_dw64 ? get_ULong(c) : (ULong) get_UInt(c);
@@ -277,6 +296,9 @@
       /* Where is .debug_loc ? */
       UChar* debug_loc_img;
       UWord  debug_loc_sz;
+      /* Where is .debug_line? */
+      UChar* debug_line_img;
+      UWord  debug_line_sz;
       /* --- a cache for set_abbv_Cursor --- */
       /* abbv_code == (ULong)-1 for an unused entry. */
       struct { ULong abbv_code; UWord posn; } saC_cache[N_ABBV_CACHE];
@@ -456,7 +478,6 @@
  * value is returned and the given pointer is
  * moved past end of leb128 data */
 /* FIXME: duplicated in readdwarf.c */
-#if 0
 static ULong read_leb128U( UChar **data )
 {
   Int len;
@@ -464,7 +485,6 @@
   *data += len;
   return val;
 }
-#endif
 
 /* Same for signed data */
 /* FIXME: duplicated in readdwarf.c */
@@ -494,9 +514,10 @@
 }
 
 
-static
+//static
 GXResult evaluate_Dwarf3_Expr ( UChar* expr, UWord exprszB, 
-                                GExpr* fbGX, RegSummary* regs )
+                                GExpr* fbGX, RegSummary* regs,
+                                Bool push_initial_zero )
 {
 #  define N_EXPR_STACK 20
 
@@ -533,12 +554,16 @@
    GXResult fbval;
    Addr     a1;
    Word     sw1;
+   UWord    uw1;
 
    sp = -1;
    vg_assert(expr);
    vg_assert(exprszB >= 0);
    limit = expr + exprszB;
 
+   if (push_initial_zero)
+      PUSH(0);
+
    while (True) {
 
       vg_assert(sp >= -1 && sp < N_EXPR_STACK);
@@ -584,6 +609,11 @@
             a1 += sw1;
             PUSH( a1 );
             break;
+         case DW_OP_plus_uconst:
+            POP(uw1);
+            uw1 += (UWord)read_leb128U( &expr );
+            PUSH(uw1);
+            break;
          default:
             if (!VG_(clo_xml))
                VG_(message)(Vg_DebugMsg, 
@@ -645,7 +675,8 @@
          vg_assert(aMax == ~(Addr)0);
          /* Assert this is the first guard. */
          vg_assert(nGuards == 1);
-         res = evaluate_Dwarf3_Expr( p, (UWord)nbytes, fbGX, regs );
+         res = evaluate_Dwarf3_Expr( p, (UWord)nbytes, fbGX, regs,
+                                     False/*push_initial_zero*/ );
          /* Now check there are no more guards. */
          p += (UWord)nbytes;
          vg_assert(*p == 1); /*isEnd*/
@@ -653,7 +684,8 @@
       } else {
          if (aMin <= regs->ip && regs->ip <= aMax) {
             /* found a matching range.  Evaluate the expression. */
-            return evaluate_Dwarf3_Expr( p, (UWord)nbytes, fbGX, regs );
+            return evaluate_Dwarf3_Expr( p, (UWord)nbytes, fbGX, regs,
+                                         False/*push_initial_zero*/ );
          }
       }
       /* else keep searching */
@@ -1102,12 +1134,10 @@
          break;
       }
       case DW_FORM_string: {
-         UInt u32;
-         UChar* str = get_address_of_Cursor(c);
-         do { u32 = get_UChar(c); } while (u32 != 0);
+         UChar* str = get_AsciiZ(c);
          TRACE_D3("%s", str);
          *cts = (ULong)(UWord)str;
-         /* strlen is safe because get_UChar already 'vetted' the
+         /* strlen is safe because get_AsciiZ already 'vetted' the
             entire string */
          *ctsMemSzB = 1 + (ULong)VG_(strlen)(str);
          break;
@@ -1162,7 +1192,9 @@
       Type*  typeR;
       GExpr* gexpr; /* for this variable */
       GExpr* fbGX;  /* to find the frame base of the enclosing fn, if
-                        any */
+                       any */
+      UChar* fName; /* declaring file name, or NULL */
+      Int    fLine; /* declaring file line number, or zero */
    }
    TempVar;
 
@@ -1192,6 +1224,9 @@
       Bool    isFunc[N_D3_VAR_STACK]; /* from DW_AT_subprogram? */
       GExpr*  fbGX[N_D3_VAR_STACK];   /* if isFunc, contains the FB
                                          expr, else NULL */
+      /* The file name table.  Is a mapping from integer index to the
+         (permanent) copy of the string, iow a non-img area. */
+      XArray* /* of UChar* */ filenameTable;
    }
    D3VarParser;
 
@@ -1309,6 +1344,66 @@
    return gexpr;
 }
 
+
+static 
+void read_filename_table( /*MOD*/D3VarParser* parser,
+                          CUConst* cc, UWord debug_line_offset,
+                          Bool td3 )
+{
+   Cursor c;
+   vg_assert(parser && cc && cc->barf);
+   if ((!cc->debug_line_img) 
+       || cc->debug_line_sz <= debug_line_offset)
+      cc->barf("read_filename_table: .debug_line is missing?");
+
+   init_Cursor( &c, cc->debug_line_img, 
+                cc->debug_line_sz, debug_line_offset, cc->barf, 
+                "Overrun whilst reading .debug_line section(1)" );
+
+   Bool is_dw64;
+   ULong unit_length = get_Initial_Length( &is_dw64, &c, "read_filename_table: 
invalid initial-length field" );
+   UShort version = get_UShort( &c );
+   if (version != 2)
+     cc->barf("read_filename_table: Only DWARF version 2 line info "
+              "is currently supported.");
+   ULong header_length = (ULong)get_Dwarfish_UWord( &c, is_dw64 );
+   UChar minimum_instruction_length = get_UChar( &c );
+   UChar default_is_stmt = get_UChar( &c );
+   Char line_base = (Char)get_UChar( &c );
+   UChar line_range = get_UChar( &c );
+   UChar opcode_base = get_UChar( &c );
+   /* skip over "standard_opcode_lengths" */
+   Word i;
+   for (i = 1; i < (Word)opcode_base; i++)
+     (void)get_UChar( &c );
+
+   /* skip over the directory names table */
+   while (peek_UChar(&c) != 0) {
+     (void)get_AsciiZ(&c);
+   }
+   (void)get_UChar(&c); /* skip terminating zero */
+
+   /* Read and record the file names table */
+   vg_assert(parser->filenameTable);
+   vg_assert( VG_(sizeXA)( parser->filenameTable ) == 0 );
+   /* Add a dummy index-zero entry.  DWARF3 numbers its files
+      from 1, for some reason. */
+   UChar* str = ML_(dinfo_strdup)( "<unknown>" );;
+   VG_(addToXA)( parser->filenameTable, &str );
+   while (peek_UChar(&c) != 0) {
+      str = get_AsciiZ(&c);
+      TRACE_D3("  read_filename_table: %ld %s\n",
+               VG_(sizeXA)(parser->filenameTable), str);
+      str = ML_(dinfo_strdup)( str );
+      VG_(addToXA)( parser->filenameTable, &str );
+      (void)get_ULEB128( &c ); /* skip directory index # */
+      (void)get_ULEB128( &c ); /* skip last mod time */
+      (void)get_ULEB128( &c ); /* file size */
+   }
+   /* We're done!  The rest of it is not interesting. */
+}
+
+
 __attribute__((noinline))
 static void parse_var_DIE ( /*OUT*/TempVar** tempvars,
                             /*OUT*/GExpr** gexprs,
@@ -1355,6 +1450,9 @@
             rangeoff = cts;
             have_range = True;
          }
+         if (attr == DW_AT_stmt_list && ctsSzB > 0) {
+            read_filename_table( parser, cc, (UWord)cts, td3 );
+         }
       }
       /* Now, does this give us an opportunity to find this
          CU's svma? */
@@ -1494,6 +1592,8 @@
       Int    n_attrs     = 0;
       Bool   has_abs_ori = False;
       Bool   declaration = False;
+      Int    lineNo      = 0;
+      UChar* fileName    = NULL;
       while (True) {
          DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
          DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
@@ -1525,6 +1625,19 @@
          if (attr == DW_AT_declaration && ctsSzB > 0 && cts > 0) {
             declaration = True;
          }
+         if (attr == DW_AT_decl_line && ctsSzB > 0) {
+            lineNo = (Int)cts;
+         }
+         if (attr == DW_AT_decl_file && ctsSzB > 0) {
+            Int ftabIx = (Int)cts;
+            if (ftabIx >= 1
+                && ftabIx < VG_(sizeXA)( parser->filenameTable )) {
+               fileName = *(UChar**)
+                          VG_(indexXA)( parser->filenameTable, ftabIx );
+               vg_assert(fileName);
+            }
+            if (0) VG_(printf)("XXX filename = %s\n", fileName);
+         }
       }
       /* We'll collect it if it has a type and a location.  Doesn't
          even have to have a name. */
@@ -1589,6 +1702,8 @@
             tv->typeR = typeR;
             tv->gexpr = gexpr;
             tv->fbGX  = fbGX;
+            tv->fName = fileName;
+            tv->fLine = lineNo;
             tv->next  = *tempvars;
             *tempvars = tv;
          }
@@ -2107,7 +2222,9 @@
             field->typeR = (Type*)(UWord)cts;
          }
          if (attr == DW_AT_data_member_location && ctsMemSzB > 0) {
-           expr = ML_(new_D3Expr)( (UChar*)(UWord)cts, (UWord)ctsMemSzB );
+            UChar* copy = ML_(dinfo_memdup)( (UChar*)(UWord)cts, 
+                                             (UWord)ctsMemSzB );
+            expr = ML_(new_D3Expr)( copy, (UWord)ctsMemSzB );
          }
       }
       /* Do we have a plausible parent? */
@@ -2727,6 +2844,10 @@
    Bool td3 = di->trace_symtab;
 
 #if 0
+   /* This doesn't work properly because it assumes all entries are
+      packed end to end, with no holes.  But that doesn't always
+      appear to be the case, so it loses sync.  And the D3 spec
+      doesn't appear to require a no-hole situation either. */
    /* Display .debug_loc */
    Addr  dl_base;
    UWord dl_offset;
@@ -2915,6 +3036,8 @@
       cu_start_offset = get_position_of_Cursor( &info );
       TRACE_D3("\n");
       TRACE_D3("  Compilation Unit @ offset 0x%lx:\n", cu_start_offset);
+      /* parse_CU_header initialises the CU's set_abbv_Cursor cache
+         (saC_cache) */
       parse_CU_Header( &cc, td3, &info,
                        (UChar*)debug_abbv_img, debug_abbv_sz );
       cc.debug_str_img    = debug_str_img;
@@ -2923,6 +3046,8 @@
       cc.debug_ranges_sz  = debug_ranges_sz;
       cc.debug_loc_img    = debug_loc_img;
       cc.debug_loc_sz     = debug_loc_sz;
+      cc.debug_line_img   = debug_line_img;
+      cc.debug_line_sz    = debug_line_sz;
       cc.cu_start_offset  = cu_start_offset;
       /* The CU's svma can be deduced by looking at the AT_low_pc
          value in the top level TAG_compile_unit, which is the topmost
@@ -2939,6 +3064,18 @@
                      unitary_range_list(0UL, ~0UL),
                      -1, False/*isFunc*/, NULL/*fbGX*/ );
 
+      /* And set up the file name table.  When we come across the top
+         level DIE for this CU (which is what the next call to
+         read_DIE should process) we will copy all the file names out
+         of the .debug_line img area and use this table to look up the
+         copies when we later see filename numbers in DW_TAG_variables
+         etc. */
+      vg_assert(!varparser.filenameTable );
+      varparser.filenameTable 
+         = VG_(newXA)( ML_(dinfo_zalloc), ML_(dinfo_free),
+                       sizeof(UChar*) );
+      vg_assert(varparser.filenameTable );
+
       /* Now read the one-and-only top-level DIE for this CU. */
       vg_assert(varparser.sp == 0);
       read_DIE( &admin, &tempvars, &gexprs, &typarser, &varparser,
@@ -2964,6 +3101,10 @@
 
       TRACE_D3("set_abbv_Cursor cache: %lu queries, %lu misses\n",
                cc.saC_cache_queries, cc.saC_cache_misses);
+
+      vg_assert(varparser.filenameTable );
+      VG_(deleteXA)( varparser.filenameTable );
+      varparser.filenameTable = NULL;
    }
 
    /* Put the type entry list the right way round.  Not strictly
@@ -3030,6 +3171,9 @@
          } else {
             VG_(printf)("  FrB=none\n");
          }
+         VG_(printf)("  declared at: %s:%d\n",
+                     varp->fName ? varp->fName : (UChar*)"(null)",
+                     varp->fLine );
          VG_(printf)("\n");
       }
 
@@ -3056,7 +3200,8 @@
                 varp->pcMin + (varp->level==0 ? 0 : di->text_bias),
                 varp->pcMax + (varp->level==0 ? 0 : di->text_bias), 
                 varp->name, (void*)varp->typeR,
-                varp->gexpr, varp->fbGX, td3 
+                varp->gexpr, varp->fbGX,
+                varp->fName, varp->fLine, td3 
          );
       ML_(dinfo_free)(varp);
    }

Modified: branches/DATASYMS/coregrind/m_debuginfo/readelf.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/readelf.c   2008-02-11 21:22:15 UTC 
(rev 7401)
+++ branches/DATASYMS/coregrind/m_debuginfo/readelf.c   2008-02-12 13:54:28 UTC 
(rev 7402)
@@ -47,6 +47,7 @@
 #include "pub_core_tooliface.h"    /* VG_(needs) */
 #include "pub_core_xarray.h"
 #include "priv_misc.h"             /* dinfo_zalloc/free/strdup */
+#include "priv_tytypes.h"
 #include "priv_storage.h"
 #include "priv_readelf.h"          /* self */
 #include "priv_readdwarf.h"        /* 'cos ELF contains DWARF */

Modified: branches/DATASYMS/coregrind/m_debuginfo/readstabs.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/readstabs.c 2008-02-11 21:22:15 UTC 
(rev 7401)
+++ branches/DATASYMS/coregrind/m_debuginfo/readstabs.c 2008-02-12 13:54:28 UTC 
(rev 7402)
@@ -40,6 +40,7 @@
 #include "pub_core_libcprint.h"
 #include "pub_core_xarray.h"
 #include "priv_misc.h"             /* dinfo_zalloc/free/strdup */
+#include "priv_tytypes.h"
 #include "priv_storage.h"
 #include "priv_readstabs.h"        /* self */
 

Modified: branches/DATASYMS/coregrind/m_debuginfo/storage.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/storage.c   2008-02-11 21:22:15 UTC 
(rev 7401)
+++ branches/DATASYMS/coregrind/m_debuginfo/storage.c   2008-02-12 13:54:28 UTC 
(rev 7402)
@@ -45,13 +45,13 @@
 #include "pub_core_xarray.h"
 #include "pub_core_oset.h"
 
+#include "priv_tytypes.h"
 #include "priv_storage.h"      /* self */
 
 //FIXME: get rid of this
 #include "priv_readdwarf3.h"  // ML_(pp_GX)
 
 #include "priv_misc.h"         /* dinfo_zalloc/free/strdup */
-#include "priv_tytypes.h"
 
 
 /*------------------------------------------------------------*/
@@ -573,9 +573,11 @@
                   Addr   aMin,
                   Addr   aMax,
                   UChar* name,
-                  void*  typeV,  /* actually D3Type* */
+                  Type*  type,
                   void*  gexprV, /* actually GExpr* */
                   void*  fbGXv,  /* actually GExpr*.  SHARED. */
+                  UChar* fileName, /* where decl'd - may be NULL */
+                  Int    lineNo, /* where decl'd - may be zero */
                   Bool   show )
 {
    OSet* /* of DiAddrRange */ inner;
@@ -585,7 +587,7 @@
    if (0) {
       VG_(printf)("  ML_(addVar): level %d  %p-%p  %s :: ",
                   level, aMin, aMax, name );
-      ML_(pp_Type_C_ishly)( typeV );
+      ML_(pp_Type_C_ishly)( type );
       VG_(printf)("\n  Var=");
       ML_(pp_GX)(gexprV);
       VG_(printf)("\n");
@@ -602,7 +604,7 @@
    vg_assert(level >= 0);
    vg_assert(aMin <= aMax);
    vg_assert(name);
-   vg_assert(typeV);
+   vg_assert(type);
    vg_assert(gexprV);
 
    if (!di->varinfo) {
@@ -629,10 +631,12 @@
       or create one if not present. */
    /* DiAddrRange* */ range = find_or_create_arange( inner, aMin, aMax );
    /* DiVariable var; */
-   var.name   = name;
-   var.typeV  = typeV;
-   var.gexprV = gexprV;
-   var.fbGXv  = fbGXv;
+   var.name     = name;
+   var.type     = type;
+   var.gexprV   = gexprV;
+   var.fbGXv    = fbGXv;
+   var.fileName = fileName;
+   var.lineNo   = lineNo;
    vg_assert(range);
    vg_assert(range->vars);
    vg_assert(range->aMin == aMin);

Modified: branches/DATASYMS/coregrind/m_debuginfo/tytypes.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/tytypes.c   2008-02-11 21:22:15 UTC 
(rev 7401)
+++ branches/DATASYMS/coregrind/m_debuginfo/tytypes.c   2008-02-12 13:54:28 UTC 
(rev 7402)
@@ -35,11 +35,18 @@
 
 #include "pub_core_basics.h"
 #include "pub_core_libcassert.h"
+#include "pub_core_libcbase.h"
 #include "pub_core_libcprint.h"
 #include "pub_core_xarray.h"   /* to keep priv_tytypes.h happy */
 #include "priv_misc.h"         /* dinfo_zalloc/free/strdup */
 #include "priv_tytypes.h"      /* self */
 
+///////////////// HACK - get rid of this
+#include "priv_readdwarf3.h"  // GXResult
+GXResult evaluate_Dwarf3_Expr ( UChar* expr, UWord exprszB, 
+                                GExpr* fbGX, RegSummary* regs,
+                                Bool push_initial_zero );
+/////////////////
 
 TyAdmin* ML_(new_TyAdmin) ( UWord cuOff, TyAdmin* next ) {
    TyAdmin* admin = ML_(dinfo_zalloc)( sizeof(TyAdmin) );
@@ -212,10 +219,8 @@
 /* NOTE: this assumes that the types have all been 'resolved' (that
    is, inter-type references expressed as .debug_info offsets have
    been converted into pointers) */
-void ML_(pp_Type_C_ishly) ( void* /* Type* */ tyV )
+void ML_(pp_Type_C_ishly) ( Type* ty )
 {
-   Type* ty = (Type*)tyV;
-
    switch (ty->tag) {
       case Ty_Base:
          if (!ty->Ty.Base.name) goto unhandled;
@@ -278,11 +283,10 @@
 
 /* How big is this type?  (post-resolved only) */
 /* FIXME: check all pointers before dereferencing */
-SizeT ML_(sizeOfType)( void* /* Type */ tyV )
+SizeT ML_(sizeOfType)( Type* ty )
 {
-   SizeT   eszB;
-   Word    i;
-   Type* ty = (Type*)tyV;
+   SizeT eszB;
+   Word  i;
    switch (ty->tag) {
       case Ty_Base:
          return ty->Ty.Base.szB;
@@ -314,12 +318,143 @@
          return eszB;
       default:
          VG_(printf)("ML_(sizeOfType): unhandled: ");
-         ML_(pp_Type)(tyV);
+         ML_(pp_Type)(ty);
          VG_(printf)("\n");
          vg_assert(0);
    }
 }
 
+
+static void copy_bytes_into_XA ( XArray* /* of UChar */ xa, 
+                                 void* bytes, Word nbytes ) {
+   Word i;
+   for (i = 0; i < nbytes; i++)
+      VG_(addToXA)( xa, & ((UChar*)bytes)[i] );
+}
+static void copy_UWord_into_XA ( XArray* /* of UChar */ xa,
+                                 UWord uw ) {
+   UChar buf[32];
+   VG_(memset)(buf, 0, sizeof(buf));
+   VG_(sprintf)(buf, "%lu", uw);
+   copy_bytes_into_XA( xa, buf, VG_(strlen)(buf));
+}
+
+
+XArray* /*UChar*/ ML_(describe_type)( Type* ty, OffT offset )
+{
+   XArray* xa = VG_(newXA)( ML_(dinfo_zalloc), ML_(dinfo_free),
+                            sizeof(UChar) );
+   vg_assert(xa);
+
+   while (True) {
+      vg_assert(ty);
+
+      switch (ty->tag) {
+
+         case Ty_Base:
+            goto done;
+
+         case Ty_StOrUn: {
+            Word     i;
+            GXResult res;
+            TyField  *field = NULL, *fields;
+            SizeT    offMin = 0, offMax1 = 0;
+            if (!ty->Ty.StOrUn.isStruct) goto done;
+            fields = ty->Ty.StOrUn.fields;
+            if ((!fields) || VG_(sizeXA)(fields) == 0) goto done;
+            for (i = 0; i < VG_(sizeXA)( fields ); i++ ) {
+               field = *(TyField**)VG_(indexXA)( fields, i );
+               vg_assert(field);
+               vg_assert(field->loc);
+               res = evaluate_Dwarf3_Expr(
+                       field->loc->bytes, field->loc->nbytes,
+                       NULL/*fbGX*/, NULL/*RegSummary*/,
+                       True/*push_initial_zero*/ );
+               if (0) VG_(printf)("QQQ %lu %s\n", res.res,res.failure);
+               if (res.failure)
+                  continue;
+               offMin = res.res;
+               offMax1 = offMin + ML_(sizeOfType)( field->typeR );
+               if (offMin == offMax1)
+                  continue;
+               vg_assert(offMin < offMax1);
+               if (offset >= offMin && offset < offMax1)
+                  break;
+            }
+            /* Did we find a suitable field? */
+            vg_assert(i >= 0 && i <= VG_(sizeXA)( fields ));
+            if (i == VG_(sizeXA)( fields ))
+               goto done; /* No.  Give up. */
+            /* Yes.  'field' is it. */
+            if (!field->name) goto done;
+            copy_bytes_into_XA( xa, ".", 1 );
+            copy_bytes_into_XA( xa, field->name,
+                                VG_(strlen)(field->name) );
+            offset -= offMin;
+            ty = field->typeR;
+            if (!ty) goto done;
+            /* keep going; look inside the field. */
+            break;
+         }
+
+         case Ty_Array: {
+            TyBounds* bounds;
+            UWord size, eszB, ix;
+            /* Just deal with the simple, common C-case: 1-D array,
+               zero based, known size. */
+            if (!(ty->Ty.Array.typeR && ty->Ty.Array.bounds))
+               goto done;
+            if (VG_(sizeXA)( ty->Ty.Array.bounds ) != 1) goto done;
+            bounds = *(TyBounds**)VG_(indexXA)( ty->Ty.Array.bounds, 0 );
+            vg_assert(bounds);
+            vg_assert(bounds->magic == TyBounds_MAGIC);
+            if (!(bounds->knownL && bounds->knownU && bounds->boundL == 0
+                  && bounds->boundU >= bounds->boundL))
+               goto done;
+            size = bounds->boundU - bounds->boundL + 1;
+            vg_assert(size >= 1);
+            eszB = ML_(sizeOfType)( ty->Ty.Array.typeR );
+            if (eszB == 0) goto done;
+            ix = offset / eszB;
+            copy_bytes_into_XA( xa, "[", 1 );
+            copy_UWord_into_XA( xa, ix );
+            copy_bytes_into_XA( xa, "]", 1 );
+            ty = ty->Ty.Array.typeR;
+            offset -= ix * eszB;
+            /* keep going; look inside the array element. */
+            break;
+         }
+
+         case Ty_Qual: {
+            if (!ty->Ty.Qual.typeR) goto done;
+            ty = ty->Ty.Qual.typeR;
+            break;
+         }
+
+         case Ty_TyDef: {
+            if (!ty->Ty.TyDef.typeR) goto done;
+            ty = ty->Ty.TyDef.typeR;
+            break;
+         }
+
+         default: {
+            VG_(printf)("ML_(describe_type): unhandled: ");
+            ML_(pp_Type)(ty);
+            VG_(printf)("\n");
+            vg_assert(0);
+         }
+      }
+   }
+
+  done:
+   if (offset > 0) {
+      copy_bytes_into_XA( xa, " +", 2 );
+      copy_UWord_into_XA( xa, offset );
+   }
+   copy_bytes_into_XA( xa, "\0", 1 );
+   return xa;
+}
+
 /*--------------------------------------------------------------------*/
 /*--- end                                                tytypes.c ---*/
 /*--------------------------------------------------------------------*/

Modified: branches/DATASYMS/memcheck/mc_main.c
===================================================================
--- branches/DATASYMS/memcheck/mc_main.c        2008-02-11 21:22:15 UTC (rev 
7401)
+++ branches/DATASYMS/memcheck/mc_main.c        2008-02-12 13:54:28 UTC (rev 
7402)
@@ -2664,19 +2664,19 @@
       // In a global .data symbol.  This holds the first 63 chars of
       // the variable's (zero terminated), plus an offset.
       struct {
-         Char name[64];
+         Char name[128];
          OffT offset;
       } DataSym;
 
       // Is described by Dwarf debug info.  Arbitrary string.
       struct {
-         Char descr[64];
+         Char descr[128];
       } Variable;
 
       // Could only narrow it down to be the PLT/GOT/etc of a given
       // object.  Better than nothing, perhaps.
       struct {
-         Char       objname[64];
+         Char       objname[128];
          VgSectKind kind;
       } SectKind;
 


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Valgrind-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/valgrind-developers

Reply via email to