1194 lines
50 KiB
Diff
1194 lines
50 KiB
Diff
|
--- valgrind-3.4.0.vanilla/coregrind/m_debuginfo/d3basics.c 2009-01-02 19:40:41.000000000 +0100
|
||
|
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_debuginfo/d3basics.c 2009-01-27 16:32:54.000000000 +0100
|
||
|
@@ -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,52 @@ static Bool get_Dwarf_Reg( /*OUT*/Addr*
|
||
|
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->rodata_present
|
||
|
+ && di->rodata_size > 0
|
||
|
+ && *a >= di->rodata_svma && *a < di->rodata_svma + di->rodata_size) {
|
||
|
+ *a += di->rodata_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 if (di->sbss_present
|
||
|
+ && di->sbss_size > 0
|
||
|
+ && *a >= di->sbss_svma && *a < di->sbss_svma + di->sbss_size) {
|
||
|
+ *a += di->sbss_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 +549,21 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh
|
||
|
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 +669,7 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh
|
||
|
/* 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 +703,7 @@ GXResult ML_(evaluate_GX)( GExpr* gx, GE
|
||
|
/* 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 +713,7 @@ GXResult ML_(evaluate_GX)( GExpr* gx, GE
|
||
|
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*/ );
|
||
|
}
|
||
|
}
|
||
|
@@ -688,8 +736,11 @@ GXResult ML_(evaluate_GX)( GExpr* gx, GE
|
||
|
* any of the subexpressions do not produce a manifest constant
|
||
|
* 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 )
|
||
|
+ JRS 23Jan09: the special-casing in this function is a nasty kludge.
|
||
|
+ Really it ought to be pulled out and turned into a general
|
||
|
+ constant- expression evaluator.
|
||
|
+*/
|
||
|
+GXResult ML_(evaluate_trivial_GX)( GExpr* gx, const DebugInfo* di )
|
||
|
{
|
||
|
GXResult res;
|
||
|
Addr aMin, aMax;
|
||
|
@@ -699,7 +750,7 @@ GXResult ML_(evaluate_trivial_GX)( GExpr
|
||
|
MaybeULong *mul, *mul2;
|
||
|
|
||
|
HChar* badness = NULL;
|
||
|
- UChar* p = &gx->payload[0];
|
||
|
+ UChar* p = &gx->payload[0]; /* must remain unsigned */
|
||
|
XArray* results = VG_(newXA)( ML_(dinfo_zalloc), "di.d3basics.etG.1",
|
||
|
ML_(dinfo_free),
|
||
|
sizeof(MaybeULong) );
|
||
|
@@ -730,12 +781,41 @@ GXResult ML_(evaluate_trivial_GX)( GExpr
|
||
|
/* 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;
|
||
|
+ /* DW_OP_addr a */
|
||
|
+ 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 (1)";
|
||
|
+ }
|
||
|
}
|
||
|
- else if (nbytes == 2 + sizeof(Addr)
|
||
|
- && *p == DW_OP_addr
|
||
|
- && *(p + 1 + sizeof(Addr)) == DW_OP_GNU_push_tls_address) {
|
||
|
+ else
|
||
|
+ if (nbytes == 1 + sizeof(Addr) + 1 + 1
|
||
|
+ /* 11 byte block: 3 c0 b6 2b 0 0 0 0 0 23 4
|
||
|
+ (DW_OP_addr: 2bb6c0; DW_OP_plus_uconst: 4)
|
||
|
+ This is really a nasty kludge - only matches if the
|
||
|
+ trailing ULEB denotes a number in the range 0 .. 127
|
||
|
+ inclusive. */
|
||
|
+ && p[0] == DW_OP_addr
|
||
|
+ && p[1 + sizeof(Addr)] == DW_OP_plus_uconst
|
||
|
+ && p[1 + sizeof(Addr) + 1] < 0x80 /*1-byte ULEB*/) {
|
||
|
+ Addr a = *(Addr*)&p[1];
|
||
|
+ if (bias_address(&a, di)) {
|
||
|
+ thisResult.b = True;
|
||
|
+ thisResult.ul = (ULong)a + (ULong)p[1 + sizeof(Addr) + 1];
|
||
|
+ } else {
|
||
|
+ if (!badness)
|
||
|
+ badness = "trivial GExpr denotes constant address "
|
||
|
+ "in unknown section (2)";
|
||
|
+ }
|
||
|
+ }
|
||
|
+ else
|
||
|
+ if (nbytes == 2 + sizeof(Addr)
|
||
|
+ && *p == DW_OP_addr
|
||
|
+ && *(p + 1 + sizeof(Addr)) == DW_OP_GNU_push_tls_address) {
|
||
|
if (!badness)
|
||
|
badness = "trivial GExpr is DW_OP_addr plus trailing junk";
|
||
|
}
|
||
|
--- valgrind-3.4.0.vanilla/coregrind/m_debuginfo/debuginfo.c 2009-01-02 19:40:41.000000000 +0100
|
||
|
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_debuginfo/debuginfo.c 2009-01-27 16:32:54.000000000 +0100
|
||
|
@@ -1036,7 +1036,17 @@ static void search_all_symtabs ( Addr pt
|
||
|
(di->bss_present
|
||
|
&& di->bss_size > 0
|
||
|
&& di->bss_avma <= ptr
|
||
|
- && ptr < di->bss_avma + di->bss_size);
|
||
|
+ && ptr < di->bss_avma + di->bss_size)
|
||
|
+ ||
|
||
|
+ (di->sbss_present
|
||
|
+ && di->sbss_size > 0
|
||
|
+ && di->sbss_avma <= ptr
|
||
|
+ && ptr < di->sbss_avma + di->sbss_size)
|
||
|
+ ||
|
||
|
+ (di->rodata_present
|
||
|
+ && di->rodata_size > 0
|
||
|
+ && di->rodata_avma <= ptr
|
||
|
+ && ptr < di->rodata_avma + di->rodata_size);
|
||
|
}
|
||
|
|
||
|
if (!inRange) continue;
|
||
|
@@ -1064,6 +1074,7 @@ static void search_all_loctabs ( Addr pt
|
||
|
DebugInfo* di;
|
||
|
for (di = debugInfo_list; di != NULL; di = di->next) {
|
||
|
if (di->text_present
|
||
|
+ && di->text_size > 0
|
||
|
&& di->text_avma <= ptr
|
||
|
&& ptr < di->text_avma + di->text_size) {
|
||
|
lno = ML_(search_one_loctab) ( di, ptr );
|
||
|
@@ -1250,6 +1261,7 @@ Bool VG_(get_objname) ( Addr a, Char* bu
|
||
|
expect this to produce a result. */
|
||
|
for (di = debugInfo_list; di != NULL; di = di->next) {
|
||
|
if (di->text_present
|
||
|
+ && di->text_size > 0
|
||
|
&& di->text_avma <= a
|
||
|
&& a < di->text_avma + di->text_size) {
|
||
|
VG_(strncpy_safely)(buf, di->filename, nbuf);
|
||
|
@@ -1288,6 +1300,7 @@ DebugInfo* VG_(find_seginfo) ( Addr a )
|
||
|
DebugInfo* di;
|
||
|
for (di = debugInfo_list; di != NULL; di = di->next) {
|
||
|
if (di->text_present
|
||
|
+ && di->text_size > 0
|
||
|
&& di->text_avma <= a
|
||
|
&& a < di->text_avma + di->text_size) {
|
||
|
return di;
|
||
|
@@ -1928,7 +1941,7 @@ static Bool data_address_is_in_var ( /*O
|
||
|
DiVariable* var,
|
||
|
RegSummary* regs,
|
||
|
Addr data_addr,
|
||
|
- Addr data_bias )
|
||
|
+ const DebugInfo* di )
|
||
|
{
|
||
|
MaybeULong mul;
|
||
|
SizeT var_szB;
|
||
|
@@ -1965,7 +1978,7 @@ static Bool data_address_is_in_var ( /*O
|
||
|
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 +2256,7 @@ Bool consider_vars_in_frame ( /*OUT*/Cha
|
||
|
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 )) {
|
||
|
OffT residual_offset = 0;
|
||
|
XArray* described = ML_(describe_type)( &residual_offset,
|
||
|
di->admin_tyents,
|
||
|
@@ -2342,7 +2355,7 @@ Bool VG_(get_data_description)( /*OUT*/C
|
||
|
fail. */
|
||
|
if (data_address_is_in_var( &offset, di->admin_tyents, var,
|
||
|
NULL/* RegSummary* */,
|
||
|
- data_addr, di->data_bias )) {
|
||
|
+ data_addr, di )) {
|
||
|
OffT residual_offset = 0;
|
||
|
XArray* described = ML_(describe_type)( &residual_offset,
|
||
|
di->admin_tyents,
|
||
|
@@ -2467,7 +2480,7 @@ Bool VG_(get_data_description)( /*OUT*/C
|
||
|
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 +2525,22 @@ void analyse_deps ( /*MOD*/XArray* /* of
|
||
|
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 +2562,7 @@ void analyse_deps ( /*MOD*/XArray* /* of
|
||
|
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 +2581,7 @@ void analyse_deps ( /*MOD*/XArray* /* of
|
||
|
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 +2711,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 +2794,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) {
|
||
|
@@ -2939,6 +2952,7 @@ const HChar* VG_(pp_SectKind)( VgSectKin
|
||
|
case Vg_SectGOT: return "GOT";
|
||
|
case Vg_SectPLT: return "PLT";
|
||
|
case Vg_SectOPD: return "OPD";
|
||
|
+ case Vg_SectGOTPLT: return "GOTPLT";
|
||
|
default: vg_assert(0);
|
||
|
}
|
||
|
}
|
||
|
@@ -2989,6 +3003,12 @@ VgSectKind VG_(seginfo_sect_kind)( /*OUT
|
||
|
res = Vg_SectBSS;
|
||
|
break;
|
||
|
}
|
||
|
+ if (di->sbss_present
|
||
|
+ && di->sbss_size > 0
|
||
|
+ && a >= di->sbss_avma && a < di->sbss_avma + di->sbss_size) {
|
||
|
+ res = Vg_SectBSS;
|
||
|
+ break;
|
||
|
+ }
|
||
|
if (di->plt_present
|
||
|
&& di->plt_size > 0
|
||
|
&& a >= di->plt_avma && a < di->plt_avma + di->plt_size) {
|
||
|
--- valgrind-3.4.0.vanilla/coregrind/m_debuginfo/priv_d3basics.h 2009-01-02 19:40:41.000000000 +0100
|
||
|
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_debuginfo/priv_d3basics.h 2009-01-27 16:32:54.000000000 +0100
|
||
|
@@ -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, GE
|
||
|
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) ( UCh
|
||
|
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 */
|
||
|
|
||
|
--- valgrind-3.4.0.vanilla/coregrind/m_debuginfo/priv_storage.h 2009-01-02 19:40:41.000000000 +0100
|
||
|
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_debuginfo/priv_storage.h 2009-01-27 16:32:54.000000000 +0100
|
||
|
@@ -366,12 +366,24 @@ struct _DebugInfo {
|
||
|
Addr sdata_avma;
|
||
|
SizeT sdata_size;
|
||
|
OffT sdata_bias;
|
||
|
+ /* .rodata */
|
||
|
+ Bool rodata_present;
|
||
|
+ Addr rodata_svma;
|
||
|
+ Addr rodata_avma;
|
||
|
+ SizeT rodata_size;
|
||
|
+ OffT rodata_bias;
|
||
|
/* .bss */
|
||
|
Bool bss_present;
|
||
|
Addr bss_svma;
|
||
|
Addr bss_avma;
|
||
|
SizeT bss_size;
|
||
|
OffT bss_bias;
|
||
|
+ /* .sbss */
|
||
|
+ Bool sbss_present;
|
||
|
+ Addr sbss_svma;
|
||
|
+ Addr sbss_avma;
|
||
|
+ SizeT sbss_size;
|
||
|
+ OffT sbss_bias;
|
||
|
/* .plt */
|
||
|
Bool plt_present;
|
||
|
Addr plt_avma;
|
||
|
--- valgrind-3.4.0.vanilla/coregrind/m_debuginfo/readdwarf3.c 2009-01-02 19:40:41.000000000 +0100
|
||
|
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_debuginfo/readdwarf3.c 2009-01-27 16:32:54.000000000 +0100
|
||
|
@@ -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"
|
||
|
@@ -386,7 +387,12 @@ typedef
|
||
|
Bool is_dw64;
|
||
|
/* Which DWARF version ? (2 or 3) */
|
||
|
UShort version;
|
||
|
- /* Length of this Compilation Unit, excluding its Header */
|
||
|
+ /* Length of this Compilation Unit, as stated in the
|
||
|
+ .unit_length :: InitialLength field of the CU Header.
|
||
|
+ However, this size (as specified by the D3 spec) does not
|
||
|
+ include the size of the .unit_length field itself, which is
|
||
|
+ either 4 or 12 bytes (32-bit or 64-bit Dwarf3). That value
|
||
|
+ can be obtained through the expression ".is_dw64 ? 12 : 4". */
|
||
|
ULong unit_length;
|
||
|
/* Offset of start of this unit in .debug_info */
|
||
|
UWord cu_start_offset;
|
||
|
@@ -412,6 +418,9 @@ typedef
|
||
|
/* Where is .debug_line? */
|
||
|
UChar* debug_line_img;
|
||
|
UWord debug_line_sz;
|
||
|
+ /* Where is .debug_info? */
|
||
|
+ UChar* debug_info_img;
|
||
|
+ UWord debug_info_sz;
|
||
|
/* --- Needed so we can add stuff to the string table. --- */
|
||
|
struct _DebugInfo* di;
|
||
|
/* --- a cache for set_abbv_Cursor --- */
|
||
|
@@ -895,7 +904,8 @@ void parse_CU_Header ( /*OUT*/CUConst* c
|
||
|
|
||
|
/* address size. If this isn't equal to the host word size, just
|
||
|
give up. This makes it safe to assume elsewhere that
|
||
|
- DW_FORM_addr can be treated as a host word. */
|
||
|
+ DW_FORM_addr and DW_FORM_ref_addr can be treated as a host
|
||
|
+ word. */
|
||
|
address_size = get_UChar( c );
|
||
|
if (address_size != sizeof(void*))
|
||
|
cc->barf( "parse_CU_Header: invalid address_size" );
|
||
|
@@ -1077,12 +1087,43 @@ void get_Form_contents ( /*OUT*/ULong* c
|
||
|
*ctsSzB = sizeof(UWord);
|
||
|
TRACE_D3("0x%lx", (UWord)*cts);
|
||
|
break;
|
||
|
+
|
||
|
+ case DW_FORM_ref_addr:
|
||
|
+ /* We make the same word-size assumption as DW_FORM_addr. */
|
||
|
+ /* What does this really mean? From D3 Sec 7.5.4,
|
||
|
+ description of "reference", it would appear to reference
|
||
|
+ some other DIE, by specifying the offset from the
|
||
|
+ beginning of a .debug_info section. The D3 spec mentions
|
||
|
+ that this might be in some other shared object and
|
||
|
+ executable. But I don't see how the name of the other
|
||
|
+ object/exe is specified.
|
||
|
+
|
||
|
+ At least for the DW_FORM_ref_addrs created by icc11, the
|
||
|
+ references seem to be within the same object/executable.
|
||
|
+ So for the moment we merely range-check, to see that they
|
||
|
+ actually do specify a plausible offset within this
|
||
|
+ object's .debug_info, and return the value unchanged.
|
||
|
+ */
|
||
|
+ *cts = (ULong)(UWord)get_UWord(c);
|
||
|
+ *ctsSzB = sizeof(UWord);
|
||
|
+ TRACE_D3("0x%lx", (UWord)*cts);
|
||
|
+ if (0) VG_(printf)("DW_FORM_ref_addr 0x%lx\n", (UWord)*cts);
|
||
|
+ if (/* the following 2 are surely impossible, but ... */
|
||
|
+ cc->debug_info_img == NULL || cc->debug_info_sz == 0
|
||
|
+ || *cts >= (ULong)cc->debug_info_sz) {
|
||
|
+ /* Hmm. Offset is nonsensical for this object's .debug_info
|
||
|
+ section. Be safe and reject it. */
|
||
|
+ cc->barf("get_Form_contents: DW_FORM_ref_addr points "
|
||
|
+ "outside .debug_info");
|
||
|
+ }
|
||
|
+ break;
|
||
|
+
|
||
|
case DW_FORM_strp: {
|
||
|
/* this is an offset into .debug_str */
|
||
|
UChar* str;
|
||
|
UWord uw = (UWord)get_Dwarfish_UWord( c, cc->is_dw64 );
|
||
|
if (cc->debug_str_img == NULL || uw >= cc->debug_str_sz)
|
||
|
- cc->barf("read_and_show_Form: DW_FORM_strp "
|
||
|
+ cc->barf("get_Form_contents: DW_FORM_strp "
|
||
|
"points outside .debug_str");
|
||
|
/* FIXME: check the entire string lies inside debug_str,
|
||
|
not just the first byte of it. */
|
||
|
@@ -1143,8 +1184,9 @@ void get_Form_contents ( /*OUT*/ULong* c
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
- VG_(printf)("get_Form_contents: unhandled %d (%s)\n",
|
||
|
- form, ML_(pp_DW_FORM)(form));
|
||
|
+ VG_(printf)(
|
||
|
+ "get_Form_contents: unhandled %d (%s) at <%lx>\n",
|
||
|
+ form, ML_(pp_DW_FORM)(form), get_position_of_Cursor(c));
|
||
|
c->barf("get_Form_contents: unhandled DW_FORM");
|
||
|
}
|
||
|
}
|
||
|
@@ -2178,14 +2220,13 @@ static void parse_type_DIE ( /*MOD*/XArr
|
||
|
typeE.Te.TyPorR.typeR = D3_FAKEVOID_CUOFF;
|
||
|
typeE.Te.TyPorR.isPtr = dtag == DW_TAG_pointer_type
|
||
|
|| dtag == DW_TAG_ptr_to_member_type;
|
||
|
- /* Pointer types don't *have* to specify their size, in which
|
||
|
- case we assume it's a machine word. But if they do specify
|
||
|
- it, it must be a machine word :-) This probably assumes that
|
||
|
- the word size of the Dwarf3 we're reading is the same size as
|
||
|
- that on the machine. gcc appears to give a size whereas icc9
|
||
|
- doesn't. */
|
||
|
- if (typeE.Te.TyPorR.isPtr)
|
||
|
- typeE.Te.TyPorR.szB = sizeof(Word);
|
||
|
+ /* These three type kinds don't *have* to specify their size, in
|
||
|
+ which case we assume it's a machine word. But if they do
|
||
|
+ specify it, it must be a machine word :-) This probably
|
||
|
+ assumes that the word size of the Dwarf3 we're reading is the
|
||
|
+ same size as that on the machine. gcc appears to give a size
|
||
|
+ whereas icc9 doesn't. */
|
||
|
+ typeE.Te.TyPorR.szB = sizeof(UWord);
|
||
|
while (True) {
|
||
|
DW_AT attr = (DW_AT) get_ULEB128( c_abbv );
|
||
|
DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
|
||
|
@@ -2200,7 +2241,7 @@ static void parse_type_DIE ( /*MOD*/XArr
|
||
|
}
|
||
|
}
|
||
|
/* Do we have something that looks sane? */
|
||
|
- if (typeE.Te.TyPorR.szB != sizeof(Word))
|
||
|
+ if (typeE.Te.TyPorR.szB != sizeof(UWord))
|
||
|
goto bad_DIE;
|
||
|
else
|
||
|
goto acquire_Type;
|
||
|
@@ -2230,9 +2271,14 @@ static void parse_type_DIE ( /*MOD*/XArr
|
||
|
typeE.Te.TyEnum.szB = cts;
|
||
|
}
|
||
|
}
|
||
|
+
|
||
|
+ if (!typeE.Te.TyEnum.name)
|
||
|
+ typeE.Te.TyEnum.name
|
||
|
+ = ML_(dinfo_strdup)( "di.readdwarf3.pTD.enum_type.3",
|
||
|
+ "<anon_enum_type>" );
|
||
|
+
|
||
|
/* Do we have something that looks sane? */
|
||
|
- if (typeE.Te.TyEnum.szB == 0 /* we must know the size */
|
||
|
- /* But the name can be present, or not */)
|
||
|
+ if (typeE.Te.TyEnum.szB == 0 /* we must know the size */)
|
||
|
goto bad_DIE;
|
||
|
/* On't stack! */
|
||
|
typestack_push( cc, parser, td3, &typeE, level );
|
||
|
@@ -3367,12 +3413,30 @@ void new_dwarf3_reader_wrk (
|
||
|
while (True) {
|
||
|
UWord cu_start_offset, cu_offset_now;
|
||
|
CUConst cc;
|
||
|
+ /* It may be that the stated size of this CU is larger than the
|
||
|
+ amount of stuff actually in it. icc9 seems to generate CUs
|
||
|
+ thusly. We use these variables to figure out if this is
|
||
|
+ indeed the case, and if so how many bytes we need to skip to
|
||
|
+ get to the start of the next CU. Not skipping those bytes
|
||
|
+ causes us to misidentify the start of the next CU, and it all
|
||
|
+ goes badly wrong after that (not surprisingly). */
|
||
|
+ UWord cu_size_including_IniLen, cu_amount_used;
|
||
|
|
||
|
/* It seems icc9 finishes the DIE info before debug_info_sz
|
||
|
bytes have been used up. So be flexible, and declare the
|
||
|
sequence complete if there is not enough remaining bytes to
|
||
|
hold even the smallest conceivable CU header. (11 bytes I
|
||
|
reckon). */
|
||
|
+ /* JRS 23Jan09: I suspect this is no longer necessary now that
|
||
|
+ the code below contains a 'while (cu_amount_used <
|
||
|
+ cu_size_including_IniLen ...' style loop, which skips over
|
||
|
+ any leftover bytes at the end of a CU in the case where the
|
||
|
+ CU's stated size is larger than its actual size (as
|
||
|
+ determined by reading all its DIEs). However, for prudence,
|
||
|
+ I'll leave the following test in place. I can't see that a
|
||
|
+ CU header can be smaller than 11 bytes, so I don't think
|
||
|
+ there's any harm possible through the test -- it just adds
|
||
|
+ robustness. */
|
||
|
Word avail = get_remaining_length_Cursor( &info );
|
||
|
if (avail < 11) {
|
||
|
if (avail > 0)
|
||
|
@@ -3408,6 +3472,8 @@ void new_dwarf3_reader_wrk (
|
||
|
cc.debug_loc_sz = debug_loc_sz;
|
||
|
cc.debug_line_img = debug_line_img;
|
||
|
cc.debug_line_sz = debug_line_sz;
|
||
|
+ cc.debug_info_img = debug_info_img;
|
||
|
+ cc.debug_info_sz = debug_info_sz;
|
||
|
cc.cu_start_offset = cu_start_offset;
|
||
|
cc.di = di;
|
||
|
/* The CU's svma can be deduced by looking at the AT_low_pc
|
||
|
@@ -3446,10 +3512,36 @@ void new_dwarf3_reader_wrk (
|
||
|
&info, td3, &cc, 0 );
|
||
|
|
||
|
cu_offset_now = get_position_of_Cursor( &info );
|
||
|
+
|
||
|
+ if (0) VG_(printf)("Travelled: %lu size %llu\n",
|
||
|
+ cu_offset_now - cc.cu_start_offset,
|
||
|
+ cc.unit_length + (cc.is_dw64 ? 12 : 4));
|
||
|
+
|
||
|
+ /* How big the CU claims it is .. */
|
||
|
+ cu_size_including_IniLen = cc.unit_length + (cc.is_dw64 ? 12 : 4);
|
||
|
+ /* .. vs how big we have found it to be */
|
||
|
+ cu_amount_used = cu_offset_now - cc.cu_start_offset;
|
||
|
+
|
||
|
if (1) TRACE_D3("offset now %ld, d-i-size %ld\n",
|
||
|
cu_offset_now, debug_info_sz);
|
||
|
if (cu_offset_now > debug_info_sz)
|
||
|
barf("toplevel DIEs beyond end of CU");
|
||
|
+
|
||
|
+ /* If the CU is bigger than it claims to be, we've got a serious
|
||
|
+ problem. */
|
||
|
+ if (cu_amount_used > cu_size_including_IniLen)
|
||
|
+ barf("CU's actual size appears to be larger than it claims it is");
|
||
|
+
|
||
|
+ /* If the CU is smaller than it claims to be, we need to skip some
|
||
|
+ bytes. Loop updates cu_offset_new and cu_amount_used. */
|
||
|
+ while (cu_amount_used < cu_size_including_IniLen
|
||
|
+ && get_remaining_length_Cursor( &info ) > 0) {
|
||
|
+ if (0) VG_(printf)("SKIP\n");
|
||
|
+ (void)get_UChar( &info );
|
||
|
+ cu_offset_now = get_position_of_Cursor( &info );
|
||
|
+ cu_amount_used = cu_offset_now - cc.cu_start_offset;
|
||
|
+ }
|
||
|
+
|
||
|
if (cu_offset_now == debug_info_sz)
|
||
|
break;
|
||
|
|
||
|
--- valgrind-3.4.0.vanilla/coregrind/m_debuginfo/readdwarf.c 2009-01-02 19:40:41.000000000 +0100
|
||
|
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_debuginfo/readdwarf.c 2009-01-27 16:32:54.000000000 +0100
|
||
|
@@ -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"
|
||
|
@@ -2554,6 +2555,16 @@ static Int dwarfexpr_to_dag ( UnwindCont
|
||
|
VG_(printf)("DW_OP_breg%d: %ld", reg, sw);
|
||
|
break;
|
||
|
|
||
|
+ case DW_OP_reg0 ... DW_OP_reg31:
|
||
|
+ /* push: reg */
|
||
|
+ reg = (Int)opcode - (Int)DW_OP_reg0;
|
||
|
+ vg_assert(reg >= 0 && reg <= 31);
|
||
|
+ ix = ML_(CfiExpr_DwReg)( dst, reg );
|
||
|
+ PUSH(ix);
|
||
|
+ if (ddump_frames)
|
||
|
+ VG_(printf)("DW_OP_reg%d", reg);
|
||
|
+ break;
|
||
|
+
|
||
|
case DW_OP_plus_uconst:
|
||
|
uw = read_leb128U( &expr );
|
||
|
PUSH( ML_(CfiExpr_Const)( dst, uw ) );
|
||
|
@@ -2573,6 +2584,15 @@ static Int dwarfexpr_to_dag ( UnwindCont
|
||
|
VG_(printf)("DW_OP_const4s: %ld", sw);
|
||
|
break;
|
||
|
|
||
|
+ case DW_OP_const1s:
|
||
|
+ /* push: 8-bit signed immediate */
|
||
|
+ sw = read_le_s_encoded_literal( expr, 1 );
|
||
|
+ expr += 1;
|
||
|
+ PUSH( ML_(CfiExpr_Const)( dst, (UWord)sw ) );
|
||
|
+ if (ddump_frames)
|
||
|
+ VG_(printf)("DW_OP_const1s: %ld", sw);
|
||
|
+ break;
|
||
|
+
|
||
|
case DW_OP_minus:
|
||
|
op = Cop_Sub; opname = "minus"; goto binop;
|
||
|
case DW_OP_plus:
|
||
|
--- valgrind-3.4.0.vanilla/coregrind/m_debuginfo/readelf.c 2009-01-02 19:40:41.000000000 +0100
|
||
|
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_debuginfo/readelf.c 2009-01-27 16:32:54.000000000 +0100
|
||
|
@@ -36,6 +36,7 @@
|
||
|
|
||
|
#include "pub_core_basics.h"
|
||
|
#include "pub_core_vki.h"
|
||
|
+#include "pub_core_debuginfo.h"
|
||
|
#include "pub_core_libcbase.h"
|
||
|
#include "pub_core_libcprint.h"
|
||
|
#include "pub_core_libcassert.h"
|
||
|
@@ -219,7 +220,7 @@ Bool get_elf_symbol_info (
|
||
|
)
|
||
|
{
|
||
|
Bool plausible, is_in_opd;
|
||
|
- Bool in_text, in_data, in_sdata, in_bss;
|
||
|
+ Bool in_text, in_data, in_sdata, in_rodata, in_bss, in_sbss;
|
||
|
|
||
|
/* Set defaults */
|
||
|
*sym_name_out = sym_name;
|
||
|
@@ -276,12 +277,26 @@ Bool get_elf_symbol_info (
|
||
|
*is_text_out = False;
|
||
|
*sym_avma_out += di->sdata_bias;
|
||
|
} else
|
||
|
+ if (di->rodata_present
|
||
|
+ && di->rodata_size > 0
|
||
|
+ && sym_svma >= di->rodata_svma
|
||
|
+ && sym_svma < di->rodata_svma + di->rodata_size) {
|
||
|
+ *is_text_out = False;
|
||
|
+ *sym_avma_out += di->rodata_bias;
|
||
|
+ } else
|
||
|
if (di->bss_present
|
||
|
&& di->bss_size > 0
|
||
|
&& sym_svma >= di->bss_svma
|
||
|
&& sym_svma < di->bss_svma + di->bss_size) {
|
||
|
*is_text_out = False;
|
||
|
*sym_avma_out += di->bss_bias;
|
||
|
+ } else
|
||
|
+ if (di->sbss_present
|
||
|
+ && di->sbss_size > 0
|
||
|
+ && sym_svma >= di->sbss_svma
|
||
|
+ && sym_svma < di->sbss_svma + di->sbss_size) {
|
||
|
+ *is_text_out = False;
|
||
|
+ *sym_avma_out += di->sbss_bias;
|
||
|
} else {
|
||
|
/* Assume it's in .text. Is this a good idea? */
|
||
|
*is_text_out = True;
|
||
|
@@ -450,12 +465,24 @@ Bool get_elf_symbol_info (
|
||
|
&& !(*sym_avma_out + *sym_size_out <= di->sdata_avma
|
||
|
|| *sym_avma_out >= di->sdata_avma + di->sdata_size);
|
||
|
|
||
|
+ in_rodata
|
||
|
+ = di->rodata_present
|
||
|
+ && di->rodata_size > 0
|
||
|
+ && !(*sym_avma_out + *sym_size_out <= di->rodata_avma
|
||
|
+ || *sym_avma_out >= di->rodata_avma + di->rodata_size);
|
||
|
+
|
||
|
in_bss
|
||
|
= di->bss_present
|
||
|
&& di->bss_size > 0
|
||
|
&& !(*sym_avma_out + *sym_size_out <= di->bss_avma
|
||
|
|| *sym_avma_out >= di->bss_avma + di->bss_size);
|
||
|
|
||
|
+ in_sbss
|
||
|
+ = di->sbss_present
|
||
|
+ && di->sbss_size > 0
|
||
|
+ && !(*sym_avma_out + *sym_size_out <= di->sbss_avma
|
||
|
+ || *sym_avma_out >= di->sbss_avma + di->sbss_size);
|
||
|
+
|
||
|
|
||
|
if (*is_text_out) {
|
||
|
/* This used to reject any symbol falling outside the text
|
||
|
@@ -479,9 +506,9 @@ Bool get_elf_symbol_info (
|
||
|
return False;
|
||
|
}
|
||
|
} else {
|
||
|
- if (!(in_data || in_sdata || in_bss)) {
|
||
|
+ if (!(in_data || in_sdata || in_rodata || in_bss || in_sbss)) {
|
||
|
TRACE_SYMTAB(
|
||
|
- "ignore -- %#lx .. %#lx outside .data / .sdata / .bss svma ranges\n",
|
||
|
+ "ignore -- %#lx .. %#lx outside .data / .sdata / .rodata / .bss / .sbss svma ranges\n",
|
||
|
*sym_avma_out, *sym_avma_out + *sym_size_out);
|
||
|
return False;
|
||
|
}
|
||
|
@@ -955,15 +982,6 @@ static void* INDEX_BIS ( void* base, Wor
|
||
|
return (void*)( ((UChar*)base) + idx * scale );
|
||
|
}
|
||
|
|
||
|
-static Addr round_Addr_upwards ( Addr a, UInt align )
|
||
|
-{
|
||
|
- if (align > 0) {
|
||
|
- vg_assert(-1 != VG_(log2)(align));
|
||
|
- a = VG_ROUNDUP(a, align);
|
||
|
- }
|
||
|
- return a;
|
||
|
-}
|
||
|
-
|
||
|
|
||
|
/* Find the file offset corresponding to SVMA by using the program
|
||
|
headers. This is taken from binutils-2.17/binutils/readelf.c
|
||
|
@@ -1027,15 +1045,13 @@ Bool ML_(read_elf_debug_info) ( struct _
|
||
|
UWord shdr_ent_szB = 0;
|
||
|
UChar* shdr_strtab_img = NULL;
|
||
|
|
||
|
- /* To do with figuring out where .sbss is relative to .bss. A
|
||
|
- kludge at the best of times. */
|
||
|
- SizeT sbss_size;
|
||
|
- Addr sbss_svma;
|
||
|
- UInt bss_align;
|
||
|
- UInt sbss_align;
|
||
|
- UInt data_align;
|
||
|
- SizeT bss_totsize;
|
||
|
- Addr gen_bss_lowest_svma;
|
||
|
+ /* SVMAs covered by rx and rw segments and corresponding bias. */
|
||
|
+ Addr rx_svma_base = 0;
|
||
|
+ Addr rx_svma_limit = 0;
|
||
|
+ OffT rx_bias = 0;
|
||
|
+ Addr rw_svma_base = 0;
|
||
|
+ Addr rw_svma_limit = 0;
|
||
|
+ OffT rw_bias = 0;
|
||
|
|
||
|
vg_assert(di);
|
||
|
vg_assert(di->have_rx_map == True);
|
||
|
@@ -1203,6 +1219,22 @@ Bool ML_(read_elf_debug_info) ( struct _
|
||
|
goto out;
|
||
|
}
|
||
|
prev_svma = phdr->p_vaddr;
|
||
|
+ if (rx_svma_limit == 0
|
||
|
+ && phdr->p_offset >= di->rx_map_foff
|
||
|
+ && phdr->p_offset < di->rx_map_foff + di->rx_map_size
|
||
|
+ && phdr->p_offset + phdr->p_filesz <= di->rx_map_foff + di->rx_map_size) {
|
||
|
+ rx_svma_base = phdr->p_vaddr;
|
||
|
+ rx_svma_limit = phdr->p_vaddr + phdr->p_memsz;
|
||
|
+ rx_bias = di->rx_map_avma - di->rx_map_foff + phdr->p_offset - phdr->p_vaddr;
|
||
|
+ }
|
||
|
+ else if (rw_svma_limit == 0
|
||
|
+ && phdr->p_offset >= di->rw_map_foff
|
||
|
+ && phdr->p_offset < di->rw_map_foff + di->rw_map_size
|
||
|
+ && phdr->p_offset + phdr->p_filesz <= di->rw_map_foff + di->rw_map_size) {
|
||
|
+ rw_svma_base = phdr->p_vaddr;
|
||
|
+ rw_svma_limit = phdr->p_vaddr + phdr->p_memsz;
|
||
|
+ rw_bias = di->rw_map_avma - di->rw_map_foff + phdr->p_offset - phdr->p_vaddr;
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
/* Try to get the soname. If there isn't one, use "NONE".
|
||
|
@@ -1254,14 +1286,8 @@ Bool ML_(read_elf_debug_info) ( struct _
|
||
|
di->soname = "NONE";
|
||
|
}
|
||
|
|
||
|
- /*SizeT*/ sbss_size = 0;
|
||
|
- /*Addr */ sbss_svma = 0;
|
||
|
- /*UInt */ bss_align = 0;
|
||
|
- /*UInt */ sbss_align = 0;
|
||
|
-
|
||
|
- /* UInt */ data_align = 0;
|
||
|
- /* SizeT */ bss_totsize = 0;
|
||
|
- /* Addr */ gen_bss_lowest_svma = ~((Addr)0);
|
||
|
+ vg_assert(rx_svma_limit != 0);
|
||
|
+ vg_assert(rw_svma_limit != 0);
|
||
|
|
||
|
/* Now read the section table. */
|
||
|
TRACE_SYMTAB("\n");
|
||
|
@@ -1270,9 +1296,13 @@ Bool ML_(read_elf_debug_info) ( struct _
|
||
|
TRACE_SYMTAB("rx: at %#lx are mapped foffsets %ld .. %ld\n",
|
||
|
di->rx_map_avma,
|
||
|
di->rx_map_foff, di->rx_map_foff + di->rx_map_size - 1 );
|
||
|
+ TRACE_SYMTAB("rx: contains svmas %#lx .. %#lx with bias %#lx\n",
|
||
|
+ rx_svma_base, rx_svma_limit - 1, rx_bias );
|
||
|
TRACE_SYMTAB("rw: at %#lx are mapped foffsets %ld .. %ld\n",
|
||
|
di->rw_map_avma,
|
||
|
di->rw_map_foff, di->rw_map_foff + di->rw_map_size - 1 );
|
||
|
+ TRACE_SYMTAB("rw: contains svmas %#lx .. %#lx with bias %#lx\n",
|
||
|
+ rw_svma_base, rw_svma_limit - 1, rw_bias );
|
||
|
|
||
|
for (i = 0; i < shdr_nent; i++) {
|
||
|
ElfXX_Shdr* shdr = INDEX_BIS( shdr_img, i, shdr_ent_szB );
|
||
|
@@ -1282,10 +1312,8 @@ Bool ML_(read_elf_debug_info) ( struct _
|
||
|
UWord size = shdr->sh_size;
|
||
|
UInt alyn = shdr->sh_addralign;
|
||
|
Bool bits = !(shdr->sh_type == SHT_NOBITS);
|
||
|
- Bool inrx = foff >= di->rx_map_foff
|
||
|
- && foff < di->rx_map_foff + di->rx_map_size;
|
||
|
- Bool inrw = foff >= di->rw_map_foff
|
||
|
- && foff < di->rw_map_foff + di->rw_map_size;
|
||
|
+ Bool inrx = svma >= rx_svma_base && svma < rx_svma_limit;
|
||
|
+ Bool inrw = svma >= rw_svma_base && svma < rw_svma_limit;
|
||
|
|
||
|
TRACE_SYMTAB(" [sec %2ld] %s %s al%2u foff %6ld .. %6ld "
|
||
|
" svma %p name \"%s\"\n",
|
||
|
@@ -1313,17 +1341,17 @@ Bool ML_(read_elf_debug_info) ( struct _
|
||
|
goto out; \
|
||
|
} while (0)
|
||
|
|
||
|
- /* Find avma-s for: .text .data .sdata .bss .plt .got .opd
|
||
|
+ /* Find avma-s for: .text .data .sdata .rodata .bss .sbss .plt .got .opd
|
||
|
and .eh_frame */
|
||
|
|
||
|
- /* Accept .text where mapped as rx (code) */
|
||
|
+ /* Accept .text where mapped as rx (code), even if zero-sized */
|
||
|
if (0 == VG_(strcmp)(name, ".text")) {
|
||
|
- if (inrx && size > 0 && !di->text_present) {
|
||
|
+ if (inrx && size >= 0 && !di->text_present) {
|
||
|
di->text_present = True;
|
||
|
di->text_svma = svma;
|
||
|
- di->text_avma = di->rx_map_avma + foff - di->rx_map_foff;
|
||
|
+ di->text_avma = svma + rx_bias;
|
||
|
di->text_size = size;
|
||
|
- di->text_bias = di->text_avma - svma;
|
||
|
+ di->text_bias = rx_bias;
|
||
|
TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n",
|
||
|
di->text_svma,
|
||
|
di->text_svma + di->text_size - 1);
|
||
|
@@ -1339,13 +1367,11 @@ Bool ML_(read_elf_debug_info) ( struct _
|
||
|
/* Accept .data where mapped as rw (data), even if zero-sized */
|
||
|
if (0 == VG_(strcmp)(name, ".data")) {
|
||
|
if (inrw && size >= 0 && !di->data_present) {
|
||
|
- if (alyn > data_align)
|
||
|
- data_align = alyn;
|
||
|
di->data_present = True;
|
||
|
di->data_svma = svma;
|
||
|
- di->data_avma = di->rw_map_avma + foff - di->rw_map_foff;
|
||
|
+ di->data_avma = svma + rw_bias;
|
||
|
di->data_size = size;
|
||
|
- di->data_bias = di->data_avma - svma;
|
||
|
+ di->data_bias = rw_bias;
|
||
|
TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n",
|
||
|
di->data_svma,
|
||
|
di->data_svma + di->data_size - 1);
|
||
|
@@ -1361,13 +1387,11 @@ Bool ML_(read_elf_debug_info) ( struct _
|
||
|
/* Accept .sdata where mapped as rw (data) */
|
||
|
if (0 == VG_(strcmp)(name, ".sdata")) {
|
||
|
if (inrw && size > 0 && !di->sdata_present) {
|
||
|
- if (alyn > data_align)
|
||
|
- data_align = alyn;
|
||
|
di->sdata_present = True;
|
||
|
di->sdata_svma = svma;
|
||
|
- di->sdata_avma = di->rw_map_avma + foff - di->rw_map_foff;
|
||
|
+ di->sdata_avma = svma + rw_bias;
|
||
|
di->sdata_size = size;
|
||
|
- di->sdata_bias = di->sdata_avma - svma;
|
||
|
+ di->sdata_bias = rw_bias;
|
||
|
TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n",
|
||
|
di->sdata_svma,
|
||
|
di->sdata_svma + di->sdata_size - 1);
|
||
|
@@ -1380,20 +1404,34 @@ Bool ML_(read_elf_debug_info) ( struct _
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+ /* Accept .rodata where mapped as rx (data), even if zero-sized */
|
||
|
+ if (0 == VG_(strcmp)(name, ".rodata")) {
|
||
|
+ if (inrx && size >= 0 && !di->rodata_present) {
|
||
|
+ di->rodata_present = True;
|
||
|
+ di->rodata_svma = svma;
|
||
|
+ di->rodata_avma = svma + rx_bias;
|
||
|
+ di->rodata_size = size;
|
||
|
+ di->rodata_bias = rx_bias;
|
||
|
+ TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n",
|
||
|
+ di->rodata_svma,
|
||
|
+ di->rodata_svma + di->rodata_size - 1);
|
||
|
+ TRACE_SYMTAB("acquiring .rodata avma = %#lx .. %#lx\n",
|
||
|
+ di->rodata_avma,
|
||
|
+ di->rodata_avma + di->rodata_size - 1);
|
||
|
+ TRACE_SYMTAB("acquiring .rodata bias = %#lx\n", di->rodata_bias);
|
||
|
+ } else {
|
||
|
+ BAD(".rodata");
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
/* Accept .bss where mapped as rw (data), even if zero-sized */
|
||
|
if (0 == VG_(strcmp)(name, ".bss")) {
|
||
|
if (inrw && size >= 0 && !di->bss_present) {
|
||
|
- bss_totsize += round_Addr_upwards(size, alyn);
|
||
|
- if (svma < gen_bss_lowest_svma)
|
||
|
- gen_bss_lowest_svma = svma;
|
||
|
- TRACE_SYMTAB("increasing total bss-like size to %ld\n",
|
||
|
- bss_totsize);
|
||
|
di->bss_present = True;
|
||
|
di->bss_svma = svma;
|
||
|
- di->bss_avma = di->rw_map_avma + foff - di->rw_map_foff;
|
||
|
+ di->bss_avma = svma + rw_bias;
|
||
|
di->bss_size = size;
|
||
|
- di->bss_bias = di->bss_avma - svma;
|
||
|
- bss_align = alyn;
|
||
|
+ di->bss_bias = rw_bias;
|
||
|
TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
|
||
|
di->bss_svma,
|
||
|
di->bss_svma + di->bss_size - 1);
|
||
|
@@ -1413,7 +1451,6 @@ Bool ML_(read_elf_debug_info) ( struct _
|
||
|
di->bss_avma = 0;
|
||
|
di->bss_size = 0;
|
||
|
di->bss_bias = 0;
|
||
|
- bss_align = 0;
|
||
|
if (!VG_(clo_xml)) {
|
||
|
VG_(message)(Vg_UserMsg, "Warning: the following file's .bss is "
|
||
|
"mapped r-x only - ignoring .bss syms");
|
||
|
@@ -1423,14 +1460,13 @@ Bool ML_(read_elf_debug_info) ( struct _
|
||
|
}
|
||
|
} else
|
||
|
|
||
|
- if ((!inrw) && (!inrx) && size > 0 && !di->bss_present) {
|
||
|
+ if ((!inrw) && (!inrx) && size >= 0 && !di->bss_present) {
|
||
|
/* File contains a .bss, but it didn't get mapped. Ignore. */
|
||
|
di->bss_present = False;
|
||
|
di->bss_svma = 0;
|
||
|
di->bss_avma = 0;
|
||
|
di->bss_size = 0;
|
||
|
di->bss_bias = 0;
|
||
|
- bss_align = 0;
|
||
|
} else {
|
||
|
BAD(".bss");
|
||
|
}
|
||
|
@@ -1438,38 +1474,29 @@ Bool ML_(read_elf_debug_info) ( struct _
|
||
|
|
||
|
/* Accept .sbss where mapped as rw (data) */
|
||
|
if (0 == VG_(strcmp)(name, ".sbss")) {
|
||
|
- if (inrw && size > 0 && sbss_size == 0) {
|
||
|
- bss_totsize += round_Addr_upwards(size, alyn);
|
||
|
- if (svma < gen_bss_lowest_svma)
|
||
|
- gen_bss_lowest_svma = svma;
|
||
|
- TRACE_SYMTAB("increasing total bss-like size to %ld\n",
|
||
|
- bss_totsize);
|
||
|
- sbss_size = size;
|
||
|
- sbss_svma = svma;
|
||
|
- sbss_align = alyn;
|
||
|
+ if (inrw && size > 0 && !di->sbss_present) {
|
||
|
+ di->sbss_present = True;
|
||
|
+ di->sbss_svma = svma;
|
||
|
+ di->sbss_avma = svma + rw_bias;
|
||
|
+ di->sbss_size = size;
|
||
|
+ di->sbss_bias = rw_bias;
|
||
|
+ TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
|
||
|
+ di->sbss_svma,
|
||
|
+ di->sbss_svma + di->sbss_size - 1);
|
||
|
+ TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
|
||
|
+ di->sbss_avma,
|
||
|
+ di->sbss_avma + di->sbss_size - 1);
|
||
|
+ TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
|
||
|
} else {
|
||
|
BAD(".sbss");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- /* Accept .dynbss where mapped as rw (data) */
|
||
|
- if (0 == VG_(strcmp)(name, ".dynbss")) {
|
||
|
- if (inrw && size > 0 /* && sbss_size == 0*/) {
|
||
|
- bss_totsize += round_Addr_upwards(size, alyn);
|
||
|
- if (svma < gen_bss_lowest_svma)
|
||
|
- gen_bss_lowest_svma = svma;
|
||
|
- TRACE_SYMTAB("increasing total bss-like size to %ld\n",
|
||
|
- bss_totsize);
|
||
|
- } else {
|
||
|
- BAD(".dynbss");
|
||
|
- }
|
||
|
- }
|
||
|
-
|
||
|
/* Accept .got where mapped as rw (data) */
|
||
|
if (0 == VG_(strcmp)(name, ".got")) {
|
||
|
if (inrw && size > 0 && !di->got_present) {
|
||
|
di->got_present = True;
|
||
|
- di->got_avma = di->rw_map_avma + foff - di->rw_map_foff;
|
||
|
+ di->got_avma = svma + rw_bias;
|
||
|
di->got_size = size;
|
||
|
TRACE_SYMTAB("acquiring .got avma = %#lx\n", di->got_avma);
|
||
|
} else {
|
||
|
@@ -1481,7 +1508,7 @@ Bool ML_(read_elf_debug_info) ( struct _
|
||
|
if (0 == VG_(strcmp)(name, ".got.plt")) {
|
||
|
if (inrw && size > 0 && !di->gotplt_present) {
|
||
|
di->gotplt_present = True;
|
||
|
- di->gotplt_avma = di->rw_map_avma + foff - di->rw_map_foff;
|
||
|
+ di->gotplt_avma = svma + rw_bias;
|
||
|
di->gotplt_size = size;
|
||
|
TRACE_SYMTAB("acquiring .got.plt avma = %#lx\n", di->gotplt_avma);
|
||
|
} else if (size != 0) {
|
||
|
@@ -1495,7 +1522,7 @@ Bool ML_(read_elf_debug_info) ( struct _
|
||
|
if (0 == VG_(strcmp)(name, ".plt")) {
|
||
|
if (inrx && size > 0 && !di->plt_present) {
|
||
|
di->plt_present = True;
|
||
|
- di->plt_avma = di->rx_map_avma + foff - di->rx_map_foff;
|
||
|
+ di->plt_avma = svma + rx_bias;
|
||
|
di->plt_size = size;
|
||
|
TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
|
||
|
} else {
|
||
|
@@ -1507,7 +1534,7 @@ Bool ML_(read_elf_debug_info) ( struct _
|
||
|
if (0 == VG_(strcmp)(name, ".plt")) {
|
||
|
if (inrw && size > 0 && !di->plt_present) {
|
||
|
di->plt_present = True;
|
||
|
- di->plt_avma = di->rw_map_avma + foff - di->rw_map_foff;
|
||
|
+ di->plt_avma = svma + rw_bias;
|
||
|
di->plt_size = size;
|
||
|
TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
|
||
|
} else {
|
||
|
@@ -1519,7 +1546,7 @@ Bool ML_(read_elf_debug_info) ( struct _
|
||
|
if (0 == VG_(strcmp)(name, ".plt")) {
|
||
|
if (inrw && size > 0 && !di->plt_present) {
|
||
|
di->plt_present = True;
|
||
|
- di->plt_avma = di->rw_map_avma + foff - di->rw_map_foff;
|
||
|
+ di->plt_avma = svma + rw_bias;
|
||
|
di->plt_size = size;
|
||
|
TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
|
||
|
} else
|
||
|
@@ -1542,7 +1569,7 @@ Bool ML_(read_elf_debug_info) ( struct _
|
||
|
if (0 == VG_(strcmp)(name, ".opd")) {
|
||
|
if (inrw && size > 0 && !di->opd_present) {
|
||
|
di->opd_present = True;
|
||
|
- di->opd_avma = di->rw_map_avma + foff - di->rw_map_foff;
|
||
|
+ di->opd_avma = svma + rw_bias;
|
||
|
di->opd_size = size;
|
||
|
TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di->opd_avma);
|
||
|
} else {
|
||
|
@@ -1556,13 +1583,13 @@ Bool ML_(read_elf_debug_info) ( struct _
|
||
|
if (0 == VG_(strcmp)(name, ".eh_frame")) {
|
||
|
if (inrx && size > 0 && !di->ehframe_present) {
|
||
|
di->ehframe_present = True;
|
||
|
- di->ehframe_avma = di->rx_map_avma + foff - di->rx_map_foff;
|
||
|
+ di->ehframe_avma = svma + rx_bias;
|
||
|
di->ehframe_size = size;
|
||
|
TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n", di->ehframe_avma);
|
||
|
} else
|
||
|
if (inrw && size > 0 && !di->ehframe_present) {
|
||
|
di->ehframe_present = True;
|
||
|
- di->ehframe_avma = di->rw_map_avma + foff - di->rw_map_foff;
|
||
|
+ di->ehframe_avma = svma + rw_bias;
|
||
|
di->ehframe_size = size;
|
||
|
TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n", di->ehframe_avma);
|
||
|
} else {
|
||
|
@@ -1574,24 +1601,6 @@ Bool ML_(read_elf_debug_info) ( struct _
|
||
|
|
||
|
}
|
||
|
|
||
|
- /* Kludge: ignore all previous computations for .bss avma range,
|
||
|
- and simply assume that .bss immediately follows .data/.sdata.*/
|
||
|
- if (1) {
|
||
|
- SizeT data_al = round_Addr_upwards(di->data_avma, data_align)
|
||
|
- - di->data_avma;
|
||
|
- TRACE_SYMTAB("data_al = %ld\n", data_al);
|
||
|
- bss_totsize += data_al;
|
||
|
- di->bss_svma = gen_bss_lowest_svma;
|
||
|
- di->bss_size = bss_totsize;
|
||
|
- di->bss_avma = di->data_avma + (di->bss_svma - di->data_svma);
|
||
|
- di->bss_bias = di->data_bias;
|
||
|
- TRACE_SYMTAB("kludged .bss svma = %#lx .. %#lx\n",
|
||
|
- di->bss_svma, di->bss_svma + di->bss_size - 1);
|
||
|
- TRACE_SYMTAB("kludged .bss avma = %#lx .. %#lx\n",
|
||
|
- di->bss_avma, di->bss_avma + di->bss_size - 1);
|
||
|
- TRACE_SYMTAB("kludged .bss bias = %#lx\n", di->bss_bias);
|
||
|
- }
|
||
|
-
|
||
|
if (0) VG_(printf)("YYYY text_: avma %#lx size %ld bias %#lx\n",
|
||
|
di->text_avma, di->text_size, di->text_bias);
|
||
|
|
||
|
--- valgrind-3.4.0.vanilla/coregrind/m_debuginfo/readxcoff.c 2009-01-02 19:40:41.000000000 +0100
|
||
|
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_debuginfo/readxcoff.c 2009-01-27 16:32:54.000000000 +0100
|
||
|
@@ -58,6 +58,7 @@
|
||
|
#include "pub_core_xarray.h"
|
||
|
#include "priv_misc.h"
|
||
|
#include "priv_tytypes.h"
|
||
|
+#include "pub_tool_debuginfo.h"
|
||
|
#include "priv_d3basics.h"
|
||
|
#include "priv_storage.h"
|
||
|
#include "priv_readxcoff.h" /* self */
|
||
|
--- valgrind-3.4.0.vanilla/coregrind/m_debuginfo/storage.c 2009-01-02 19:40:41.000000000 +0100
|
||
|
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_debuginfo/storage.c 2009-01-27 16:32:54.000000000 +0100
|
||
|
@@ -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"
|
||
|
--- valgrind-3.4.0.vanilla/coregrind/m_debuginfo/tytypes.c 2009-01-02 19:40:41.000000000 +0100
|
||
|
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_debuginfo/tytypes.c 2009-01-27 16:32:54.000000000 +0100
|
||
|
@@ -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"
|
||
|
--- valgrind-3.4.0.vanilla/coregrind/m_machine.c 2009-01-02 19:40:44.000000000 +0100
|
||
|
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_machine.c 2009-01-27 16:32:56.000000000 +0100
|
||
|
@@ -35,7 +35,8 @@
|
||
|
#include "pub_core_libcbase.h"
|
||
|
#include "pub_core_machine.h"
|
||
|
#include "pub_core_cpuid.h"
|
||
|
-#include "pub_core_libcsignal.h" // for ppc32 messing with SIGILL
|
||
|
+#include "pub_core_libcsignal.h" // for ppc32 messing with SIGILL
|
||
|
+#include "pub_core_debuglog.h"
|
||
|
|
||
|
|
||
|
#define INSTR_PTR(regs) ((regs).vex.VG_INSTR_PTR)
|