From: Julian Seward Date: Sat, 12 Oct 2002 18:25:42 +0000 (+0000) Subject: merge rev 1.28: X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=43f61a6eae9d9ed48151ef1356c05c996ab7033c;p=thirdparty%2Fvalgrind.git merge rev 1.28: Fixes for the DWARF2 reader, from Josef Weidendorfer: Attached patch is for the Dwarf2 source line info reader; For reading, a state machine is used reconstructing source line info while running and reading (see DWARF2 specification, ch. 6.2). The state machine was correct, but the calls to addLineInfo() were wrong: It reported most of the times too small ranges for source code statements, because it used only the diff of the last state machine command instead of the diff to the last statement boundary. Effect: Around 1/3 of all addresses with source line info got unknown location. The patch adds a "last_address" to the state machine to remember the last statement boundary. On reset, it#s initialised to the "invalid" address 0. I hope this is OK (or should we use "(Addr)-1" instead?). The patch now uses the "is_stmt" boolean correctly to only call addLineInfo() if there's a statement boundary (on x86, is_stmt most probably is always true...). git-svn-id: svn://svn.valgrind.org/valgrind/branches/VALGRIND_1_0_BRANCH@1211 --- diff --git a/vg_symtab2.c b/vg_symtab2.c index 2ac975e82c..e8a8f0e3e5 100644 --- a/vg_symtab2.c +++ b/vg_symtab2.c @@ -311,6 +311,11 @@ void addLineInfo ( SegInfo* si, loc.size = (UShort)size; loc.lineno = lineno; loc.fnmoff = fnmoff; + + if (0) VG_(message)(Vg_DebugMsg, + "addLoc: addr %p, size %d, line %d, file %s", + this,size,lineno,&si->strtab[fnmoff]); + addLoc ( si, &loc ); } @@ -901,6 +906,11 @@ enum dwarf_line_number_x_ops typedef struct State_Machine_Registers { Addr address; + /* Holds the address of the last statement boundary. + * We use it to calculate statement lengths. Without it, + * we would need to search backwards for last statement begin + * each time we are emitting a statement with addLineInfo */ + Addr last_address; UInt file; UInt line; UInt column; @@ -950,6 +960,7 @@ void reset_state_machine ( Int is_stmt ) { if (0) VG_(printf)("smr.a := %p (reset)\n", 0 ); state_machine_regs.address = 0; + state_machine_regs.last_address = 0; state_machine_regs.file = 1; state_machine_regs.line = 1; state_machine_regs.column = 0; @@ -984,6 +995,7 @@ int process_extended_line_op( SegInfo *si, UInt** fnames, len += bytes_read; op_code = * data ++; + if (0) VG_(printf)("dwarf2: ext OPC: %d\n", op_code); switch (op_code) { @@ -993,10 +1005,13 @@ int process_extended_line_op( SegInfo *si, UInt** fnames, state_machine_regs.end_sequence = 1; /* JRS: added for compliance with spec; is pointless due to reset_state_machine below */ - addLineInfo (si, (*fnames)[state_machine_regs.file], - si->offset + (state_machine_regs.address - 1), - si->offset + (state_machine_regs.address), - 0, 0); + if (state_machine_regs.is_stmt) { + if (state_machine_regs.last_address) + addLineInfo (si, (*fnames)[state_machine_regs.file], + si->offset + state_machine_regs.last_address, + si->offset + state_machine_regs.address, + state_machine_regs.line, 0); + } reset_state_machine (is_stmt); break; @@ -1090,6 +1105,9 @@ void read_debuginfo_dwarf2 ( SegInfo* si, UChar* dwarf2, Int dwarf2_sz ) info.li_line_range = * ((UChar *)(external->li_line_range)); info.li_opcode_base = * ((UChar *)(external->li_opcode_base)); + if (0) VG_(printf)("dwarf2: line base: %d, range %d, opc base: %d\n", + info.li_line_base, info.li_line_range, info.li_opcode_base); + /* Sign extend the line base field. */ info.li_line_base <<= 24; info.li_line_base >>= 24; @@ -1176,6 +1194,8 @@ void read_debuginfo_dwarf2 ( SegInfo* si, UChar* dwarf2, Int dwarf2_sz ) op_code = * data ++; + if (0) VG_(printf)("dwarf2: OPC: %d\n", op_code); + if (op_code >= info.li_opcode_base) { Int advAddr; @@ -1188,11 +1208,15 @@ void read_debuginfo_dwarf2 ( SegInfo* si, UChar* dwarf2, Int dwarf2_sz ) adv = (op_code % info.li_line_range) + info.li_line_base; if (0) VG_(printf)("1002: si->o %p, smr.a %p\n", si->offset, state_machine_regs.address ); - addLineInfo (si, fnames[state_machine_regs.file], - si->offset + (state_machine_regs.address - - advAddr), - si->offset + (state_machine_regs.address), + if (state_machine_regs.is_stmt) { + /* only add a statement if there was a previous boundary */ + if (state_machine_regs.last_address) + addLineInfo (si, fnames[state_machine_regs.file], + si->offset + state_machine_regs.last_address, + si->offset + state_machine_regs.address, state_machine_regs.line, 0); + state_machine_regs.last_address = state_machine_regs.address; + } state_machine_regs.line += adv; } else switch (op_code) @@ -1206,10 +1230,15 @@ void read_debuginfo_dwarf2 ( SegInfo* si, UChar* dwarf2, Int dwarf2_sz ) case DW_LNS_copy: if (0) VG_(printf)("1002: si->o %p, smr.a %p\n", si->offset, state_machine_regs.address ); - addLineInfo (si, fnames[state_machine_regs.file], - si->offset + state_machine_regs.address, - si->offset + (state_machine_regs.address + 1), + if (state_machine_regs.is_stmt) { + /* only add a statement if there was a previous boundary */ + if (state_machine_regs.last_address) + addLineInfo (si, fnames[state_machine_regs.file], + si->offset + state_machine_regs.last_address, + si->offset + state_machine_regs.address, state_machine_regs.line , 0); + state_machine_regs.last_address = state_machine_regs.address; + } state_machine_regs.basic_block = 0; /* JRS added */ break;