|
From: <sv...@va...> - 2008-02-12 13:54:44
|
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, ®s, 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;
|