From 4ca0c5f735adb2d1e2688a1e11b8de1e1ffc488b Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Thu, 22 Jan 2009 13:40:12 +0000 Subject: [PATCH] Don't assume that all global variables are in the data section - we now cope with variables in the text, data, sdata and bss sections. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9021 --- coregrind/m_debuginfo/d3basics.c | 66 ++++++++++++++++++++++----- coregrind/m_debuginfo/debuginfo.c | 26 +++++------ coregrind/m_debuginfo/priv_d3basics.h | 6 +-- coregrind/m_debuginfo/readdwarf.c | 1 + coregrind/m_debuginfo/readdwarf3.c | 1 + coregrind/m_debuginfo/storage.c | 1 + coregrind/m_debuginfo/tytypes.c | 1 + 7 files changed, 75 insertions(+), 27 deletions(-) diff --git a/coregrind/m_debuginfo/d3basics.c b/coregrind/m_debuginfo/d3basics.c index 7f932910e3..17bae438ec 100644 --- a/coregrind/m_debuginfo/d3basics.c +++ b/coregrind/m_debuginfo/d3basics.c @@ -35,6 +35,7 @@ */ #include "pub_core_basics.h" +#include "pub_core_debuginfo.h" #include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_options.h" @@ -45,6 +46,7 @@ #include "priv_misc.h" #include "priv_d3basics.h" /* self */ +#include "priv_storage.h" HChar* ML_(pp_DW_children) ( DW_children hashch ) { @@ -372,7 +374,6 @@ static Long read_leb128S( UChar **data ) return (Long)val; } - /* FIXME: duplicates logic in readdwarf.c: copy_convert_CfiExpr_tree and {FP,SP}_REG decls */ static Bool get_Dwarf_Reg( /*OUT*/Addr* a, Word regno, RegSummary* regs ) @@ -400,12 +401,42 @@ static Bool get_Dwarf_Reg( /*OUT*/Addr* a, Word regno, RegSummary* regs ) return False; } +/* Convert a stated address to an actual address */ +static Bool bias_address( Addr* a, const DebugInfo* di ) +{ + if (di->text_present + && di->text_size > 0 + && *a >= di->text_svma && *a < di->text_svma + di->text_size) { + *a += di->text_bias; + } + else if (di->data_present + && di->data_size > 0 + && *a >= di->data_svma && *a < di->data_svma + di->data_size) { + *a += di->data_bias; + } + else if (di->sdata_present + && di->sdata_size > 0 + && *a >= di->sdata_svma && *a < di->sdata_svma + di->sdata_size) { + *a += di->sdata_bias; + } + else if (di->bss_present + && di->bss_size > 0 + && *a >= di->bss_svma && *a < di->bss_svma + di->bss_size) { + *a += di->bss_bias; + } + else { + return False; + } + + return True; +} + /* Evaluate a standard DWARF3 expression. See detailed description in priv_d3basics.h. */ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB, GExpr* fbGX, RegSummary* regs, - Addr data_bias, + const DebugInfo* di, Bool push_initial_zero ) { # define N_EXPR_STACK 20 @@ -508,14 +539,21 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB, horrible prelinking-induced complications as described in "Comment_Regarding_DWARF3_Text_Biasing" in readdwarf3.c? Currently I don't know. */ - PUSH( *(Addr*)expr + data_bias ); - expr += sizeof(Addr); + a1 = *(Addr*)expr; + if (bias_address(&a1, di)) { + PUSH( a1 ); + expr += sizeof(Addr); + } + else { + FAIL("evaluate_Dwarf3_Expr: DW_OP_addr with address " + "in unknown section"); + } break; case DW_OP_fbreg: if (!fbGX) FAIL("evaluate_Dwarf3_Expr: DW_OP_fbreg with " "no expr for fbreg present"); - fbval = ML_(evaluate_GX)(fbGX, NULL, regs, data_bias); + fbval = ML_(evaluate_GX)(fbGX, NULL, regs, di); /* Convert fbval into something we can use. If we got a Value, no problem. However, as per D3 spec sec 3.3.5 (Low Level Information) sec 2, we could also get a @@ -621,7 +659,7 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB, /* Evaluate a so-called Guarded (DWARF3) expression. See detailed description in priv_d3basics.h. */ GXResult ML_(evaluate_GX)( GExpr* gx, GExpr* fbGX, - RegSummary* regs, Addr data_bias ) + RegSummary* regs, const DebugInfo* di ) { GXResult res; Addr aMin, aMax; @@ -655,7 +693,7 @@ GXResult ML_(evaluate_GX)( GExpr* gx, GExpr* fbGX, /* Assert this is the first guard. */ vg_assert(nGuards == 1); res = ML_(evaluate_Dwarf3_Expr)( - p, (UWord)nbytes, fbGX, regs, data_bias, + p, (UWord)nbytes, fbGX, regs, di, False/*push_initial_zero*/ ); /* Now check there are no more guards. */ p += (UWord)nbytes; @@ -665,7 +703,7 @@ GXResult ML_(evaluate_GX)( GExpr* gx, GExpr* fbGX, if (aMin <= regs->ip && regs->ip <= aMax) { /* found a matching range. Evaluate the expression. */ return ML_(evaluate_Dwarf3_Expr)( - p, (UWord)nbytes, fbGX, regs, data_bias, + p, (UWord)nbytes, fbGX, regs, di, False/*push_initial_zero*/ ); } } @@ -689,7 +727,7 @@ GXResult ML_(evaluate_GX)( GExpr* gx, GExpr* fbGX, * there's more than one subexpression, all of which successfully evaluate to a constant, but they don't all produce the same constant. */ -GXResult ML_(evaluate_trivial_GX)( GExpr* gx, Addr data_bias ) +GXResult ML_(evaluate_trivial_GX)( GExpr* gx, const DebugInfo* di ) { GXResult res; Addr aMin, aMax; @@ -730,8 +768,14 @@ GXResult ML_(evaluate_trivial_GX)( GExpr* gx, Addr data_bias ) /* 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.ul = (ULong)(*(Addr*)(p+1)) + (ULong)data_bias; + Addr a = *(Addr*)(p+1); + if (bias_address(&a, di)) { + thisResult.b = True; + thisResult.ul = (ULong)a; + } + else if (!badness) { + badness = "trivial GExpr denotes constant address in unknown section"; + } } else if (nbytes == 2 + sizeof(Addr) && *p == DW_OP_addr diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index a521a0ee74..03269dfb55 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -1928,7 +1928,7 @@ static Bool data_address_is_in_var ( /*OUT*/PtrdiffT* offset, DiVariable* var, RegSummary* regs, Addr data_addr, - Addr data_bias ) + const DebugInfo* di ) { MaybeULong mul; SizeT var_szB; @@ -1965,7 +1965,7 @@ static Bool data_address_is_in_var ( /*OUT*/PtrdiffT* offset, return False; } - res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, data_bias ); + res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, di ); if (show) { VG_(printf)("VVVV: -> "); @@ -2243,7 +2243,7 @@ Bool consider_vars_in_frame ( /*OUT*/Char* dname1, var->name,arange->aMin,arange->aMax,ip); if (data_address_is_in_var( &offset, di->admin_tyents, var, ®s, - data_addr, di->data_bias )) { + data_addr, di )) { PtrdiffT residual_offset = 0; XArray* described = ML_(describe_type)( &residual_offset, di->admin_tyents, @@ -2342,7 +2342,7 @@ Bool VG_(get_data_description)( /*OUT*/Char* dname1, fail. */ if (data_address_is_in_var( &offset, di->admin_tyents, var, NULL/* RegSummary* */, - data_addr, di->data_bias )) { + data_addr, di )) { PtrdiffT residual_offset = 0; XArray* described = ML_(describe_type)( &residual_offset, di->admin_tyents, @@ -2467,7 +2467,7 @@ Bool VG_(get_data_description)( /*OUT*/Char* dname1, static void analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks, XArray* /* TyEnt */ tyents, - Addr ip, Addr data_bias, DiVariable* var, + Addr ip, const DebugInfo* di, DiVariable* var, Bool arrays_only ) { GXResult res_sp_6k, res_sp_7k, res_fp_6k, res_fp_7k; @@ -2512,22 +2512,22 @@ void analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks, regs.fp = 0; regs.ip = ip; regs.sp = 6 * 1024; - res_sp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, data_bias ); + res_sp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); regs.fp = 0; regs.ip = ip; regs.sp = 7 * 1024; - res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, data_bias ); + res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); regs.fp = 6 * 1024; regs.ip = ip; regs.sp = 0; - res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, data_bias ); + res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); regs.fp = 7 * 1024; regs.ip = ip; regs.sp = 0; - res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, data_bias ); + res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); vg_assert(res_sp_6k.kind == res_sp_7k.kind); vg_assert(res_sp_6k.kind == res_fp_6k.kind); @@ -2549,7 +2549,7 @@ void analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks, if (sp_delta == 1024 && fp_delta == 0) { regs.sp = regs.fp = 0; regs.ip = ip; - res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, data_bias ); + res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); tl_assert(res.kind == GXR_Value); if (debug) VG_(printf)(" %5ld .. %5ld (sp) %s\n", @@ -2568,7 +2568,7 @@ void analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks, if (sp_delta == 0 && fp_delta == 1024) { regs.sp = regs.fp = 0; regs.ip = ip; - res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, data_bias ); + res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); tl_assert(res.kind == GXR_Value); if (debug) VG_(printf)(" %5ld .. %5ld (FP) %s\n", @@ -2698,7 +2698,7 @@ void* /* really, XArray* of StackBlock */ VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n", var->name,arange->aMin,arange->aMax,ip); analyse_deps( res, di->admin_tyents, ip, - di->data_bias, var, arrays_only ); + di, var, arrays_only ); } } @@ -2781,7 +2781,7 @@ void* /* really, XArray* of GlobalBlock */ it. */ if (0) { VG_(printf)("EVAL: "); ML_(pp_GX)(var->gexpr); VG_(printf)("\n"); } - res = ML_(evaluate_trivial_GX)( var->gexpr, di->data_bias ); + res = ML_(evaluate_trivial_GX)( var->gexpr, di ); /* Not a constant address => not interesting */ if (res.kind != GXR_Value) { diff --git a/coregrind/m_debuginfo/priv_d3basics.h b/coregrind/m_debuginfo/priv_d3basics.h index 1113bf064d..1810ca6c2c 100644 --- a/coregrind/m_debuginfo/priv_d3basics.h +++ b/coregrind/m_debuginfo/priv_d3basics.h @@ -621,7 +621,7 @@ void ML_(pp_GXResult) ( GXResult res ); NULL but the frame base is still needed, then evaluation of gx as a whole will fail. */ GXResult ML_(evaluate_GX)( GExpr* gx, GExpr* fbGX, - RegSummary* regs, Addr data_bias ); + RegSummary* regs, const DebugInfo* di ); /* This is a subsidiary of ML_(evaluate_GX), which just evaluates a single standard DWARF3 expression. Conventions w.r.t regs and fbGX @@ -632,7 +632,7 @@ GXResult ML_(evaluate_GX)( GExpr* gx, GExpr* fbGX, recursive. */ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB, GExpr* fbGX, RegSummary* regs, - Addr data_bias, + const DebugInfo* di, Bool push_initial_zero ); /* Evaluate a very simple Guarded (DWARF3) expression. The expression @@ -642,7 +642,7 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB, location is denoted, a frame base expression is required, or the expression is not manifestly a constant. The range of addresses covered by the guard is also ignored. */ -GXResult ML_(evaluate_trivial_GX)( GExpr* gx, Addr data_bias ); +GXResult ML_(evaluate_trivial_GX)( GExpr* gx, const DebugInfo* di ); #endif /* ndef __PRIV_D3BASICS_H */ diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c index de050c7033..a6fe190484 100644 --- a/coregrind/m_debuginfo/readdwarf.c +++ b/coregrind/m_debuginfo/readdwarf.c @@ -34,6 +34,7 @@ */ #include "pub_core_basics.h" +#include "pub_core_debuginfo.h" #include "pub_core_libcbase.h" #include "pub_core_libcassert.h" #include "pub_core_libcprint.h" diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c index 98a9d3378a..055c684c73 100644 --- a/coregrind/m_debuginfo/readdwarf3.c +++ b/coregrind/m_debuginfo/readdwarf3.c @@ -133,6 +133,7 @@ groupies always show up at the top of performance profiles. */ #include "pub_core_basics.h" +#include "pub_core_debuginfo.h" #include "pub_core_libcbase.h" #include "pub_core_libcassert.h" #include "pub_core_libcprint.h" diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c index d705f0d177..7241778b21 100644 --- a/coregrind/m_debuginfo/storage.c +++ b/coregrind/m_debuginfo/storage.c @@ -39,6 +39,7 @@ #include "pub_core_basics.h" #include "pub_core_options.h" /* VG_(clo_verbosity) */ +#include "pub_core_debuginfo.h" #include "pub_core_libcassert.h" #include "pub_core_libcbase.h" #include "pub_core_libcprint.h" diff --git a/coregrind/m_debuginfo/tytypes.c b/coregrind/m_debuginfo/tytypes.c index cfd850b4c6..dd48cf85bc 100644 --- a/coregrind/m_debuginfo/tytypes.c +++ b/coregrind/m_debuginfo/tytypes.c @@ -34,6 +34,7 @@ */ #include "pub_core_basics.h" +#include "pub_core_debuginfo.h" #include "pub_core_libcassert.h" #include "pub_core_libcbase.h" #include "pub_core_libcprint.h" -- 2.47.3