]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
merge rev 1.28:
authorJulian Seward <jseward@acm.org>
Sat, 12 Oct 2002 18:25:42 +0000 (18:25 +0000)
committerJulian Seward <jseward@acm.org>
Sat, 12 Oct 2002 18:25:42 +0000 (18:25 +0000)
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

vg_symtab2.c

index 2ac975e82cb6ee2686cba1d2cf0dce06582dc960..e8a8f0e3e5ce55bd369325634b84acf10f8df802 100644 (file)
@@ -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;