now cope with variables in the text, data, sdata and bss sections.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9021
*/
#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"
#include "priv_misc.h"
#include "priv_d3basics.h" /* self */
+#include "priv_storage.h"
HChar* ML_(pp_DW_children) ( DW_children hashch )
{
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 )
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
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
/* 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;
/* 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;
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*/ );
}
}
* 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;
/* 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
DiVariable* var,
RegSummary* regs,
Addr data_addr,
- Addr data_bias )
+ const DebugInfo* di )
{
MaybeULong mul;
SizeT var_szB;
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: -> ");
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,
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,
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;
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);
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",
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",
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 );
}
}
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) {
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
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
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 */
*/
#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"
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"
#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"
*/
#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"