restructure dwarf3 DIE tracing
* add a trace_DIE function
* use it to trace a bad DIE
  and to trace all DIEs that are (maybe) read

(due to the "avoid read twice" optimisation, the tracing was not
so easy to read anymore => add an explicit trace_DIE call at the beginning
of read_DIE)



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14050 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c
index 878c158..cbd46a3 100644
--- a/coregrind/m_debuginfo/readdwarf3.c
+++ b/coregrind/m_debuginfo/readdwarf3.c
@@ -1674,31 +1674,30 @@
    }
 }
 
-__attribute__((noreturn))
-static void dump_bad_die_and_barf(
-   const HChar *whichparser,
+static void trace_DIE(
    DW_TAG dtag,
    UWord posn,
    Int level,
-   Cursor* c_die,  UWord saved_die_c_offset,
+   UWord saved_die_c_offset,
    g_abbv *abbv,
    CUConst* cc)
 {
+   Cursor c;
    FormContents cts;
    UInt nf_i;
    Bool  debug_types_flag;
    Bool  alt_flag;
 
-   set_position_of_Cursor( c_die,  saved_die_c_offset );
    posn = uncook_die( cc, posn, &debug_types_flag, &alt_flag );
-   VG_(printf)(" <%d><%lx>: %s", level, posn, ML_(pp_DW_TAG)( dtag ) );
-   if (debug_types_flag) {
-      VG_(printf)(" (in .debug_types)");
-   }
-   else if (alt_flag) {
-      VG_(printf)(" (in alternate .debug_info)");
-   }
-   VG_(printf)("\n");
+   init_Cursor (&c, 
+                debug_types_flag ? cc->escn_debug_types :
+                alt_flag ? cc->escn_debug_info_alt : cc->escn_debug_info,
+                saved_die_c_offset, cc->barf, 
+                "Overrun trace_DIE");
+   VG_(printf)(" <%d><%lx>: Abbrev Number: %llu (%s)%s%s\n",
+               level, posn, (ULong) abbv->abbv_code, ML_(pp_DW_TAG)( dtag ),
+               debug_types_flag ? " (in .debug_types)" : "",
+               alt_flag ? " (in alternate .debug_info)" : "");
    nf_i = 0;
    while (True) {
       DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
@@ -1707,10 +1706,24 @@
       if (attr == 0 && form == 0) break;
       VG_(printf)("     %18s: ", ML_(pp_DW_AT)(attr));
       /* Get the form contents, so as to print them */
-      get_Form_contents( &cts, cc, c_die, True, form );
+      get_Form_contents( &cts, cc, &c, True, form );
       VG_(printf)("\t\n");
    }
-   VG_(printf)("\n%s:\n", whichparser);
+}
+
+__attribute__((noreturn))
+static void dump_bad_die_and_barf(
+   const HChar *whichparser,
+   DW_TAG dtag,
+   UWord posn,
+   Int level,
+   Cursor* c_die,
+   UWord saved_die_c_offset,
+   g_abbv *abbv,
+   CUConst* cc)
+{
+   trace_DIE (dtag, posn, level, saved_die_c_offset, abbv, cc);
+   VG_(printf)("%s:\n", whichparser);
    cc->barf("confused by the above DIE");
 }
 
@@ -3727,9 +3740,12 @@
    abbv_code = get_ULEB128( c );
    abbv = get_abbv(cc, abbv_code);
    atag      = abbv->atag;
-   TRACE_D3("\n");
-   TRACE_D3(" <%d><%lx>: Abbrev Number: %llu (%s)\n",
-            level, posn, abbv_code, ML_(pp_DW_TAG)( atag ) );
+
+   if (td3) {
+      TRACE_D3("\n");
+      trace_DIE ((DW_TAG)atag, posn, level,
+                 get_position_of_Cursor( c ), abbv, cc);
+   }
 
    if (atag == 0)
       cc->barf("read_DIE: invalid zero tag on DIE");
@@ -3811,6 +3827,7 @@
          At the same time, establish sibling value if the DIE has one. */
       UInt nf_i;
 
+      TRACE_D3("    (skipped DIE)\n");
       nf_i = 0;
       while (True) {
          FormContents cts;
@@ -3818,16 +3835,12 @@
          ULong at_form = abbv->nf[nf_i].at_form;
          nf_i++;
          if (at_name == 0 && at_form == 0) break;
-         TRACE_D3("     %18s: ", ML_(pp_DW_AT)(at_name));
          /* Get the form contents, but ignore them; the only purpose is
-            to print them, if td3 is True, and skip the data. */
-         get_Form_contents( &cts, cc, c, td3, (DW_FORM)at_form );
-         /* Except that we remember if this DIE has a sibling. */
+            to skip the data or get the DIE sibling, if it has one. */
+         get_Form_contents( &cts, cc, c, False /*td3*/, (DW_FORM)at_form );
          if (UNLIKELY(at_name == DW_AT_sibling && cts.szB > 0)) {
             sibling = cts.u.val;
          }
-         TRACE_D3("\t");
-         TRACE_D3("\n");
       }
    }
 
@@ -3849,7 +3862,7 @@
          if (0) TRACE_D3("END children of level %d\n", level);
       } else {
          // We can skip the childrens, by jumping to the sibling
-         TRACE_D3("SKIPPING DIE's children,"
+         TRACE_D3("    SKIPPING DIE's children,"
                   "jumping to sibling <%d><%lx>\n",
                   level, sibling);
          set_position_of_Cursor( c, sibling );