diff --git a/valgrind-3.4.0-cachegrind-improvements.patch b/valgrind-3.4.0-cachegrind-improvements.patch index 4b0f3f6..ec8eaca 100644 --- a/valgrind-3.4.0-cachegrind-improvements.patch +++ b/valgrind-3.4.0-cachegrind-improvements.patch @@ -50,7 +50,7 @@ - for (i = 0; i < c->sets * c->assoc; i++) - c->tags[i] = 0; + c->tags = VG_(calloc)("cg.sim.ci.1", -+ sizeof(UWord), c->sets * c->assoc); ++ sizeof(UWord), sets * c->assoc); } /* This is done as a macro rather than by passing in the cache_t2 as an diff --git a/valgrind-3.4.0-debug.patch b/valgrind-3.4.0-debug.patch new file mode 100644 index 0000000..2c423cb --- /dev/null +++ b/valgrind-3.4.0-debug.patch @@ -0,0 +1,1193 @@ +--- 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", ++ "" ); ++ + /* 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) diff --git a/valgrind-3.4.0-newbu.patch b/valgrind-3.4.0-newbu.patch new file mode 100644 index 0000000..0953cb1 --- /dev/null +++ b/valgrind-3.4.0-newbu.patch @@ -0,0 +1,68 @@ +--- valgrind-3.4.0/Makefile.am.jj 2009-01-02 13:40:45.000000000 -0500 ++++ valgrind-3.4.0/Makefile.am 2009-02-09 07:40:21.140994000 -0500 +@@ -209,26 +209,26 @@ valt_load_address_x86_linux.lds: Makefil + $(CC) @FLAG_M32@ -Wl,--verbose -nostdlib 2>&1 | sed \ + -e '1,/^=====\+$$/d' \ + -e '/^=====\+$$/,/.\*/d' \ +- -e '/\. = 0x[0-9A-Fa-f]\+ + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \ ++ -e '/\. = \(0x[0-9A-Fa-f]\+\|SEGMENT_START("[^"]\+", 0x[0-9A-Fa-f]\+)\) + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \ + || rm -f $@ + + valt_load_address_amd64_linux.lds: Makefile + $(CC) -m64 -Wl,--verbose -nostdlib 2>&1 | sed \ + -e '1,/^=====\+$$/d' \ + -e '/^=====\+$$/,/.\*/d' \ +- -e '/\. = 0x[0-9A-Fa-f]\+ + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \ ++ -e '/\. = \(0x[0-9A-Fa-f]\+\|SEGMENT_START("[^"]\+", 0x[0-9A-Fa-f]\+)\) + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \ + || rm -f $@ + + valt_load_address_ppc32_linux.lds: Makefile + $(CC) @FLAG_M32@ -Wl,--verbose -nostdlib 2>&1 | sed \ + -e '1,/^=====\+$$/d' \ + -e '/^=====\+$$/,/.\*/d' \ +- -e '/\. = 0x[0-9A-Fa-f]\+ + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \ ++ -e '/\. = \(0x[0-9A-Fa-f]\+\|SEGMENT_START("[^"]\+", 0x[0-9A-Fa-f]\+)\) + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \ + || rm -f $@ + + valt_load_address_ppc64_linux.lds: Makefile + $(CC) -m64 -Wl,--verbose -nostdlib 2>&1 | sed \ + -e '1,/^=====\+$$/d' \ + -e '/^=====\+$$/,/.\*/d' \ +- -e '/\. = 0x[0-9A-Fa-f]\+ + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \ ++ -e '/\. = \(0x[0-9A-Fa-f]\+\|SEGMENT_START("[^"]\+", 0x[0-9A-Fa-f]\+)\) + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \ + || rm -f $@ +--- valgrind-3.4.0/Makefile.in.jj 2009-01-02 13:50:00.000000000 -0500 ++++ valgrind-3.4.0/Makefile.in 2009-02-09 07:41:28.439218000 -0500 +@@ -946,28 +946,28 @@ valt_load_address_x86_linux.lds: Makefil + $(CC) @FLAG_M32@ -Wl,--verbose -nostdlib 2>&1 | sed \ + -e '1,/^=====\+$$/d' \ + -e '/^=====\+$$/,/.\*/d' \ +- -e '/\. = 0x[0-9A-Fa-f]\+ + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \ ++ -e '/\. = \(0x[0-9A-Fa-f]\+\|SEGMENT_START("[^"]\+", 0x[0-9A-Fa-f]\+)\) + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \ + || rm -f $@ + + valt_load_address_amd64_linux.lds: Makefile + $(CC) -m64 -Wl,--verbose -nostdlib 2>&1 | sed \ + -e '1,/^=====\+$$/d' \ + -e '/^=====\+$$/,/.\*/d' \ +- -e '/\. = 0x[0-9A-Fa-f]\+ + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \ ++ -e '/\. = \(0x[0-9A-Fa-f]\+\|SEGMENT_START("[^"]\+", 0x[0-9A-Fa-f]\+)\) + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \ + || rm -f $@ + + valt_load_address_ppc32_linux.lds: Makefile + $(CC) @FLAG_M32@ -Wl,--verbose -nostdlib 2>&1 | sed \ + -e '1,/^=====\+$$/d' \ + -e '/^=====\+$$/,/.\*/d' \ +- -e '/\. = 0x[0-9A-Fa-f]\+ + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \ ++ -e '/\. = \(0x[0-9A-Fa-f]\+\|SEGMENT_START("[^"]\+", 0x[0-9A-Fa-f]\+)\) + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \ + || rm -f $@ + + valt_load_address_ppc64_linux.lds: Makefile + $(CC) -m64 -Wl,--verbose -nostdlib 2>&1 | sed \ + -e '1,/^=====\+$$/d' \ + -e '/^=====\+$$/,/.\*/d' \ +- -e '/\. = 0x[0-9A-Fa-f]\+ + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \ ++ -e '/\. = \(0x[0-9A-Fa-f]\+\|SEGMENT_START("[^"]\+", 0x[0-9A-Fa-f]\+)\) + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \ + || rm -f $@ + # Tell versions [3.59,3.63) of GNU make to not export all variables. + # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/valgrind-3.4.0-power5+-6.patch b/valgrind-3.4.0-power5+-6.patch index 48f884d..07a010c 100644 --- a/valgrind-3.4.0-power5+-6.patch +++ b/valgrind-3.4.0-power5+-6.patch @@ -8,7 +8,7 @@ #define MASK_VSCR_VALID 0x00010001 -@@ -2142,7 +2143,7 @@ static IRExpr* /* ::Ity_I32 */ getGST_ma +@@ -2149,7 +2150,7 @@ static IRExpr* /* ::Ity_I32 */ getGST_ma /* We're only keeping track of the rounding mode, so if the mask isn't asking for this, just return 0x0 */ @@ -17,7 +17,7 @@ assign( val, IRExpr_Get( OFFB_FPROUND, Ity_I32 ) ); } else { assign( val, mkU32(0x0) ); -@@ -2271,7 +2272,7 @@ static void putGST_masked ( PPC_GST reg, +@@ -2278,7 +2279,7 @@ static void putGST_masked ( PPC_GST reg, switch (reg) { case PPC_GST_FPSCR: { /* Allow writes to Rounding Mode */ @@ -26,7 +26,7 @@ /* construct new fpround from new and old values as per mask: new fpround = (src & (3 & mask)) | (fpround & (3 & ~mask)) */ stmt( -@@ -2279,11 +2280,11 @@ static void putGST_masked ( PPC_GST reg, +@@ -2286,11 +2287,11 @@ static void putGST_masked ( PPC_GST reg, OFFB_FPROUND, binop( Iop_Or32, @@ -40,7 +40,7 @@ ) ) ) -@@ -3224,6 +3225,48 @@ static Bool dis_int_logic ( UInt theInst +@@ -3231,6 +3232,48 @@ static Bool dis_int_logic ( UInt theInst // TODO: alternatively: assign(rA, verbose_Clz64(rS)); break; @@ -89,7 +89,7 @@ default: vex_printf("dis_int_logic(ppc)(opc2)\n"); return False; -@@ -6533,6 +6576,45 @@ static Bool dis_fp_round ( UInt theInstr +@@ -6556,6 +6599,45 @@ static Bool dis_fp_round ( UInt theInstr binop(Iop_I64toF64, rm, mkexpr(r_tmp64)) ); break; @@ -135,7 +135,7 @@ default: vex_printf("dis_fp_round(ppc)(opc2)\n"); return False; -@@ -9139,6 +9221,10 @@ DisResult disInstr_PPC_WRK ( +@@ -9224,6 +9306,10 @@ DisResult disInstr_PPC_WRK ( case 0x32E: // fctid case 0x32F: // fctidz case 0x34E: // fcfid @@ -145,8 +145,8 @@ + case 0x1E8: // frim (Power5+) if (dis_fp_round(theInstr)) goto decode_success; goto decode_failure; - -@@ -9216,6 +9302,10 @@ DisResult disInstr_PPC_WRK ( + +@@ -9310,6 +9396,10 @@ DisResult disInstr_PPC_WRK ( if (dis_int_arith( theInstr )) goto decode_success; goto decode_failure; @@ -157,7 +157,7 @@ default: break; // Fall through... } -@@ -9234,6 +9324,7 @@ DisResult disInstr_PPC_WRK ( +@@ -9328,6 +9418,7 @@ DisResult disInstr_PPC_WRK ( case 0x11C: case 0x3BA: case 0x39A: // eqv, extsb, extsh case 0x1DC: case 0x07C: case 0x1BC: // nand, nor, or case 0x19C: case 0x13C: // orc, xor diff --git a/valgrind.spec b/valgrind.spec index af21673..0b60f6d 100644 --- a/valgrind.spec +++ b/valgrind.spec @@ -1,13 +1,14 @@ Summary: Tool for finding memory management bugs in programs Name: valgrind Version: 3.4.0 -Release: 2 +Release: 3 Epoch: 1 Source0: http://www.valgrind.org/downloads/valgrind-%{version}.tar.bz2 Patch1: valgrind-3.4.0-cachegrind-improvements.patch Patch2: valgrind-3.4.0-pkg-config.patch -Patch3: valgrind-3.4.0-power5+-6.patch -Patch4: valgrind-3.4.0-openat.patch +Patch3: valgrind-3.4.0-openat.patch +Patch4: valgrind-3.4.0-newbu.patch +Patch5: valgrind-3.4.0-debug.patch License: GPLv2 URL: http://www.valgrind.org/ Group: Development/Debuggers @@ -65,6 +66,7 @@ or valgrind plugins. %patch2 -p1 %patch3 -p1 %patch4 -p1 +%patch5 -p1 %build %ifarch x86_64 ppc64 @@ -127,6 +129,8 @@ ln -sf ../../lib/valgrind/%{valsecarch}-linux $RPM_BUILD_ROOT%{_libdir}/valgrind %endif %endif +rm -f $RPM_BUILD_ROOT%{_libdir}/valgrind/*.supp.in + %clean rm -rf $RPM_BUILD_ROOT @@ -141,7 +145,6 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/valgrind/%{valsecarch}-linux %endif %{_libdir}/valgrind/%{valarch}-linux/*[^a] -%{_libdir}/valgrind/%{valarch}-linux/*[^.]a %{_libdir}/valgrind/*.supp %{_mandir}/man1/valgrind* @@ -154,7 +157,7 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/pkgconfig/* %changelog -* Sat Feb 7 2009 Jakub Jelinek 3.4.0-2 +* Tue Feb 9 2009 Jakub Jelinek 3.4.0-3 - update to 3.4.0 * Wed Apr 16 2008 Jakub Jelinek 3.3.0-3