Mark Wielaard f53174
From 7183a5638e294822bff3f486edce6303d22059ef Mon Sep 17 00:00:00 2001
Mark Wielaard f53174
From: Mark Wielaard <mark@klomp.org>
Mark Wielaard f53174
Date: Thu, 16 Sep 2021 22:01:47 +0200
Mark Wielaard f53174
Subject: [PATCH 1/6] readdwarf3: Skip units without addresses when looking for
Mark Wielaard f53174
 inlined functions
Mark Wielaard f53174
Mark Wielaard f53174
When a unit doesn't cover any addresses skip it because no actual code
Mark Wielaard f53174
will be inside. Also use skip_DIE instead of read_DIE when not parsing
Mark Wielaard f53174
(skipping) children.
Mark Wielaard f53174
---
Mark Wielaard f53174
 coregrind/m_debuginfo/readdwarf3.c | 48 +++++++++++++++++++++++++-----
Mark Wielaard f53174
 1 file changed, 40 insertions(+), 8 deletions(-)
Mark Wielaard f53174
Mark Wielaard f53174
diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c
Mark Wielaard f53174
index 968c37bd6..cf8270c8c 100644
Mark Wielaard f53174
--- a/coregrind/m_debuginfo/readdwarf3.c
Mark Wielaard f53174
+++ b/coregrind/m_debuginfo/readdwarf3.c
Mark Wielaard f53174
@@ -3127,8 +3127,9 @@ static Bool parse_inl_DIE (
Mark Wielaard f53174
 
Mark Wielaard f53174
    UWord saved_die_c_offset  = get_position_of_Cursor( c_die );
Mark Wielaard f53174
 
Mark Wielaard f53174
-   /* Get info about DW_TAG_compile_unit and DW_TAG_partial_unit 'which
Mark Wielaard f53174
-      in theory could also contain inlined fn calls).  */
Mark Wielaard f53174
+   /* Get info about DW_TAG_compile_unit and DW_TAG_partial_unit which in theory
Mark Wielaard f53174
+      could also contain inlined fn calls, if they cover an address range.  */
Mark Wielaard f53174
+   Bool unit_has_addrs = False;
Mark Wielaard f53174
    if (dtag == DW_TAG_compile_unit || dtag == DW_TAG_partial_unit) {
Mark Wielaard f53174
       Bool have_lo    = False;
Mark Wielaard f53174
       Addr ip_lo    = 0;
Mark Wielaard f53174
@@ -3145,7 +3146,10 @@ static Bool parse_inl_DIE (
Mark Wielaard f53174
          if (attr == DW_AT_low_pc && cts.szB > 0) {
Mark Wielaard f53174
             ip_lo   = cts.u.val;
Mark Wielaard f53174
             have_lo = True;
Mark Wielaard f53174
+            unit_has_addrs = True;
Mark Wielaard f53174
          }
Mark Wielaard f53174
+         if (attr == DW_AT_ranges && cts.szB > 0)
Mark Wielaard f53174
+            unit_has_addrs = True;
Mark Wielaard f53174
          if (attr == DW_AT_comp_dir) {
Mark Wielaard f53174
             if (cts.szB >= 0)
Mark Wielaard f53174
                cc->barf("parse_inl_DIE compdir: expecting indirect string");
Mark Wielaard f53174
@@ -3278,9 +3282,10 @@ static Bool parse_inl_DIE (
Mark Wielaard f53174
 
Mark Wielaard f53174
    // Only recursively parse the (possible) children for the DIE which
Mark Wielaard f53174
    // might maybe contain a DW_TAG_inlined_subroutine:
Mark Wielaard f53174
-   return dtag == DW_TAG_lexical_block || dtag == DW_TAG_subprogram
Mark Wielaard f53174
-      || dtag == DW_TAG_inlined_subroutine
Mark Wielaard f53174
-      || dtag == DW_TAG_compile_unit || dtag == DW_TAG_partial_unit;
Mark Wielaard f53174
+   Bool ret = (unit_has_addrs
Mark Wielaard f53174
+               || dtag == DW_TAG_lexical_block || dtag == DW_TAG_subprogram
Mark Wielaard f53174
+               || dtag == DW_TAG_inlined_subroutine);
Mark Wielaard f53174
+   return ret;
Mark Wielaard f53174
 
Mark Wielaard f53174
   bad_DIE:
Mark Wielaard f53174
    dump_bad_die_and_barf("parse_inl_DIE", dtag, posn, level,
Mark Wielaard f53174
@@ -4759,9 +4764,36 @@ static void read_DIE (
Mark Wielaard f53174
          while (True) {
Mark Wielaard f53174
             atag = peek_ULEB128( c );
Mark Wielaard f53174
             if (atag == 0) break;
Mark Wielaard f53174
-            read_DIE( rangestree, tyents, tempvars, gexprs,
Mark Wielaard f53174
-                      typarser, varparser, inlparser,
Mark Wielaard f53174
-                      c, td3, cc, level+1 );
Mark Wielaard f53174
+            if (parse_children) {
Mark Wielaard f53174
+               read_DIE( rangestree, tyents, tempvars, gexprs,
Mark Wielaard f53174
+                         typarser, varparser, inlparser,
Mark Wielaard f53174
+                         c, td3, cc, level+1 );
Mark Wielaard f53174
+            } else {
Mark Wielaard f53174
+               Int skip_level = level + 1;
Mark Wielaard f53174
+               while (True) {
Mark Wielaard f53174
+                  atag = peek_ULEB128( c );
Mark Wielaard f53174
+                  if (atag == 0) {
Mark Wielaard f53174
+                     skip_level--;
Mark Wielaard f53174
+                     if (skip_level == level) break;
Mark Wielaard f53174
+                     /* Eat the terminating zero and continue skipping the
Mark Wielaard f53174
+                        children one level up.  */
Mark Wielaard f53174
+                     atag = get_ULEB128( c );
Mark Wielaard f53174
+                     vg_assert(atag == 0);
Mark Wielaard f53174
+                     continue;
Mark Wielaard f53174
+                  }
Mark Wielaard f53174
+
Mark Wielaard f53174
+                  abbv_code = get_ULEB128( c );
Mark Wielaard f53174
+                  abbv = get_abbv(cc, abbv_code);
Mark Wielaard f53174
+                  sibling = 0;
Mark Wielaard f53174
+                  skip_DIE (&sibling, c, abbv, cc);
Mark Wielaard f53174
+                  if (abbv->has_children) {
Mark Wielaard f53174
+                     if (sibling == 0)
Mark Wielaard f53174
+                        skip_level++;
Mark Wielaard f53174
+                     else
Mark Wielaard f53174
+                        set_position_of_Cursor( c, sibling );
Mark Wielaard f53174
+                  }
Mark Wielaard f53174
+               }
Mark Wielaard f53174
+            }
Mark Wielaard f53174
          }
Mark Wielaard f53174
          /* Now we need to eat the terminating zero */
Mark Wielaard f53174
          atag = get_ULEB128( c );
Mark Wielaard f53174
-- 
Mark Wielaard f53174
2.18.4
Mark Wielaard f53174
Mark Wielaard f53174
From 1597c1139127bb02d49f4711a9c9addd877d17cf Mon Sep 17 00:00:00 2001
Mark Wielaard f53174
From: Mark Wielaard <mark@klomp.org>
Mark Wielaard f53174
Date: Thu, 16 Sep 2021 22:49:41 +0200
Mark Wielaard f53174
Subject: [PATCH 2/6] readdwarf3: Only read line table for units with addresses
Mark Wielaard f53174
 for inlined functions
Mark Wielaard f53174
Mark Wielaard f53174
When parsing DIEs for inlined functions, only read the line table for
Mark Wielaard f53174
units which can actually contain inlined_subroutines.
Mark Wielaard f53174
---
Mark Wielaard f53174
 coregrind/m_debuginfo/readdwarf3.c | 12 +++++++++---
Mark Wielaard f53174
 1 file changed, 9 insertions(+), 3 deletions(-)
Mark Wielaard f53174
Mark Wielaard f53174
diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c
Mark Wielaard f53174
index cf8270c8c..7ece77009 100644
Mark Wielaard f53174
--- a/coregrind/m_debuginfo/readdwarf3.c
Mark Wielaard f53174
+++ b/coregrind/m_debuginfo/readdwarf3.c
Mark Wielaard f53174
@@ -3134,6 +3134,8 @@ static Bool parse_inl_DIE (
Mark Wielaard f53174
       Bool have_lo    = False;
Mark Wielaard f53174
       Addr ip_lo    = 0;
Mark Wielaard f53174
       const HChar *compdir = NULL;
Mark Wielaard f53174
+      Bool has_stmt_list = False;
Mark Wielaard f53174
+      ULong debug_line_offset = 0;
Mark Wielaard f53174
 
Mark Wielaard f53174
       nf_i = 0;
Mark Wielaard f53174
       while (True) {
Mark Wielaard f53174
@@ -3159,15 +3161,19 @@ static Bool parse_inl_DIE (
Mark Wielaard f53174
             ML_(dinfo_free) (str);
Mark Wielaard f53174
          }
Mark Wielaard f53174
          if (attr == DW_AT_stmt_list && cts.szB > 0) {
Mark Wielaard f53174
-            read_filename_table( parser->fndn_ix_Table, compdir,
Mark Wielaard f53174
-                                 cc, cts.u.val, td3 );
Mark Wielaard f53174
+	    has_stmt_list = True;
Mark Wielaard f53174
+            debug_line_offset = cts.u.val;
Mark Wielaard f53174
          }
Mark Wielaard f53174
          if (attr == DW_AT_sibling && cts.szB > 0) {
Mark Wielaard f53174
             parser->sibling = cts.u.val;
Mark Wielaard f53174
          }
Mark Wielaard f53174
       }
Mark Wielaard f53174
-      if (level == 0)
Mark Wielaard f53174
+      if (level == 0) {
Mark Wielaard f53174
          setup_cu_svma (cc, have_lo, ip_lo, td3);
Mark Wielaard f53174
+         if (has_stmt_list && unit_has_addrs)
Mark Wielaard f53174
+            read_filename_table( parser->fndn_ix_Table, compdir,
Mark Wielaard f53174
+                                 cc, debug_line_offset, td3 );
Mark Wielaard f53174
+      }
Mark Wielaard f53174
    }
Mark Wielaard f53174
 
Mark Wielaard f53174
    if (dtag == DW_TAG_inlined_subroutine) {
Mark Wielaard f53174
-- 
Mark Wielaard f53174
2.18.4
Mark Wielaard f53174
Mark Wielaard f53174
From 528a71f95f8eb124ed284f7cff093b3375bca380 Mon Sep 17 00:00:00 2001
Mark Wielaard f53174
From: Mark Wielaard <mark@klomp.org>
Mark Wielaard f53174
Date: Sat, 18 Sep 2021 00:24:38 +0200
Mark Wielaard f53174
Subject: [PATCH 3/6] readdwarf3: Reuse fndn_ix_Table as much as possible
Mark Wielaard f53174
Mark Wielaard f53174
Both the var parser and the inl parser kept a fndn_ix_Table.
Mark Wielaard f53174
Initialize only one per debuginfo read pass and reuse if the stmt offset
Mark Wielaard f53174
is the same as last time (CUs can share the same line table and alt
Mark Wielaard f53174
files do share one for all units).
Mark Wielaard f53174
---
Mark Wielaard f53174
 coregrind/m_debuginfo/readdwarf3.c | 122 +++++++++++++++++------------
Mark Wielaard f53174
 1 file changed, 72 insertions(+), 50 deletions(-)
Mark Wielaard f53174
Mark Wielaard f53174
diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c
Mark Wielaard f53174
index 7ece77009..e63e35788 100644
Mark Wielaard f53174
--- a/coregrind/m_debuginfo/readdwarf3.c
Mark Wielaard f53174
+++ b/coregrind/m_debuginfo/readdwarf3.c
Mark Wielaard f53174
@@ -1801,9 +1801,6 @@ typedef
Mark Wielaard f53174
       Int     *level;  /* D3 DIE levels */
Mark Wielaard f53174
       Bool    *isFunc; /* from DW_AT_subprogram? */
Mark Wielaard f53174
       GExpr  **fbGX;   /* if isFunc, contains the FB expr, else NULL */
Mark Wielaard f53174
-      /* The fndn_ix file name/dirname table.  Is a mapping from dwarf
Mark Wielaard f53174
-         integer index to the index in di->fndnpool. */
Mark Wielaard f53174
-      XArray* /* of UInt* */ fndn_ix_Table;
Mark Wielaard f53174
    }
Mark Wielaard f53174
    D3VarParser;
Mark Wielaard f53174
 
Mark Wielaard f53174
@@ -1817,7 +1814,6 @@ var_parser_init ( D3VarParser *parser )
Mark Wielaard f53174
    parser->level  = NULL;
Mark Wielaard f53174
    parser->isFunc = NULL;
Mark Wielaard f53174
    parser->fbGX = NULL;
Mark Wielaard f53174
-   parser->fndn_ix_Table = NULL;
Mark Wielaard f53174
 }
Mark Wielaard f53174
 
Mark Wielaard f53174
 /* Release any memory hanging off a variable parser object */
Mark Wielaard f53174
@@ -2471,12 +2467,39 @@ static void bad_DIE_confusion(int linenr)
Mark Wielaard f53174
 }
Mark Wielaard f53174
 #define goto_bad_DIE do {bad_DIE_confusion(__LINE__); goto bad_DIE;} while (0)
Mark Wielaard f53174
 
Mark Wielaard f53174
+/* Reset the fndn_ix_Table.  When we come across the top level DIE for a CU we
Mark Wielaard f53174
+   will copy all the file names out of the .debug_line img area and use this
Mark Wielaard f53174
+   table to look up the copies when we later see filename numbers in
Mark Wielaard f53174
+   DW_TAG_variables etc. The table can be be reused between parsers (var and
Mark Wielaard f53174
+   inline) and between CUs. So we keep a copy of the last one parsed. Call
Mark Wielaard f53174
+   reset_fndn_ix_table before reading a new one from a new offset.  */
Mark Wielaard f53174
+static
Mark Wielaard f53174
+void reset_fndn_ix_table (XArray** fndn_ix_Table, ULong *debug_line_offset,
Mark Wielaard f53174
+                          ULong new_offset)
Mark Wielaard f53174
+{
Mark Wielaard f53174
+   vg_assert (new_offset == -1
Mark Wielaard f53174
+              || *debug_line_offset != new_offset);
Mark Wielaard f53174
+   Int size = *fndn_ix_Table == NULL ? 0 : VG_(sizeXA) (*fndn_ix_Table);
Mark Wielaard f53174
+   if (size > 0) {
Mark Wielaard f53174
+      VG_(deleteXA) (*fndn_ix_Table);
Mark Wielaard f53174
+      *fndn_ix_Table = NULL;
Mark Wielaard f53174
+   }
Mark Wielaard f53174
+   if (*fndn_ix_Table == NULL)
Mark Wielaard f53174
+      *fndn_ix_Table = VG_(newXA)( ML_(dinfo_zalloc),
Mark Wielaard f53174
+                                   "di.readdwarf3.reset_ix_table",
Mark Wielaard f53174
+                                   ML_(dinfo_free),
Mark Wielaard f53174
+                                   sizeof(UInt) );
Mark Wielaard f53174
+   *debug_line_offset = new_offset;
Mark Wielaard f53174
+}
Mark Wielaard f53174
+
Mark Wielaard f53174
 __attribute__((noinline))
Mark Wielaard f53174
 static void parse_var_DIE (
Mark Wielaard f53174
    /*MOD*/WordFM* /* of (XArray* of AddrRange, void) */ rangestree,
Mark Wielaard f53174
    /*MOD*/XArray* /* of TempVar* */ tempvars,
Mark Wielaard f53174
    /*MOD*/XArray* /* of GExpr* */ gexprs,
Mark Wielaard f53174
    /*MOD*/D3VarParser* parser,
Mark Wielaard f53174
+   XArray** fndn_ix_Table,
Mark Wielaard f53174
+   ULong *debug_line_offset,
Mark Wielaard f53174
    DW_TAG dtag,
Mark Wielaard f53174
    UWord posn,
Mark Wielaard f53174
    Int level,
Mark Wielaard f53174
@@ -2535,8 +2558,12 @@ static void parse_var_DIE (
Mark Wielaard f53174
             ML_(dinfo_free) (str);
Mark Wielaard f53174
          }
Mark Wielaard f53174
          if (attr == DW_AT_stmt_list && cts.szB > 0) {
Mark Wielaard f53174
-            read_filename_table( parser->fndn_ix_Table, compdir,
Mark Wielaard f53174
-                                 cc, cts.u.val, td3 );
Mark Wielaard f53174
+            if (cts.u.val != *debug_line_offset) {
Mark Wielaard f53174
+               reset_fndn_ix_table( fndn_ix_Table, debug_line_offset,
Mark Wielaard f53174
+                                    cts.u.val );
Mark Wielaard f53174
+               read_filename_table( *fndn_ix_Table, compdir,
Mark Wielaard f53174
+                                    cc, cts.u.val, td3 );
Mark Wielaard f53174
+            }
Mark Wielaard f53174
          }
Mark Wielaard f53174
       }
Mark Wielaard f53174
       if (have_lo && have_hi1 && hiIsRelative)
Mark Wielaard f53174
@@ -2730,8 +2757,8 @@ static void parse_var_DIE (
Mark Wielaard f53174
          if (attr == DW_AT_decl_file && cts.szB > 0) {
Mark Wielaard f53174
             Int ftabIx = (Int)cts.u.val;
Mark Wielaard f53174
             if (ftabIx >= 1
Mark Wielaard f53174
-                && ftabIx < VG_(sizeXA)( parser->fndn_ix_Table )) {
Mark Wielaard f53174
-               fndn_ix = *(UInt*)VG_(indexXA)( parser->fndn_ix_Table, ftabIx );
Mark Wielaard f53174
+                && ftabIx < VG_(sizeXA)( *fndn_ix_Table )) {
Mark Wielaard f53174
+               fndn_ix = *(UInt*)VG_(indexXA)( *fndn_ix_Table, ftabIx );
Mark Wielaard f53174
             }
Mark Wielaard f53174
             if (0) VG_(printf)("XXX filename fndn_ix = %u %s\n", fndn_ix,
Mark Wielaard f53174
                                ML_(fndn_ix2filename) (cc->di, fndn_ix));
Mark Wielaard f53174
@@ -2958,9 +2985,6 @@ static void parse_var_DIE (
Mark Wielaard f53174
 
Mark Wielaard f53174
 typedef
Mark Wielaard f53174
    struct {
Mark Wielaard f53174
-      /* The fndn_ix file name/dirname table.  Is a mapping from dwarf
Mark Wielaard f53174
-         integer index to the index in di->fndnpool. */
Mark Wielaard f53174
-      XArray* /* of UInt* */ fndn_ix_Table;
Mark Wielaard f53174
       UWord sibling; // sibling of the last read DIE (if it has a sibling).
Mark Wielaard f53174
    }
Mark Wielaard f53174
    D3InlParser;
Mark Wielaard f53174
@@ -3113,6 +3137,8 @@ static const HChar* get_inlFnName (Int absori, const CUConst* cc, Bool td3)
Mark Wielaard f53174
 __attribute__((noinline))
Mark Wielaard f53174
 static Bool parse_inl_DIE (
Mark Wielaard f53174
    /*MOD*/D3InlParser* parser,
Mark Wielaard f53174
+   XArray** fndn_ix_Table,
Mark Wielaard f53174
+   ULong *debug_line_offset,
Mark Wielaard f53174
    DW_TAG dtag,
Mark Wielaard f53174
    UWord posn,
Mark Wielaard f53174
    Int level,
Mark Wielaard f53174
@@ -3135,7 +3161,7 @@ static Bool parse_inl_DIE (
Mark Wielaard f53174
       Addr ip_lo    = 0;
Mark Wielaard f53174
       const HChar *compdir = NULL;
Mark Wielaard f53174
       Bool has_stmt_list = False;
Mark Wielaard f53174
-      ULong debug_line_offset = 0;
Mark Wielaard f53174
+      ULong cu_line_offset = 0;
Mark Wielaard f53174
 
Mark Wielaard f53174
       nf_i = 0;
Mark Wielaard f53174
       while (True) {
Mark Wielaard f53174
@@ -3162,7 +3188,7 @@ static Bool parse_inl_DIE (
Mark Wielaard f53174
          }
Mark Wielaard f53174
          if (attr == DW_AT_stmt_list && cts.szB > 0) {
Mark Wielaard f53174
 	    has_stmt_list = True;
Mark Wielaard f53174
-            debug_line_offset = cts.u.val;
Mark Wielaard f53174
+            cu_line_offset = cts.u.val;
Mark Wielaard f53174
          }
Mark Wielaard f53174
          if (attr == DW_AT_sibling && cts.szB > 0) {
Mark Wielaard f53174
             parser->sibling = cts.u.val;
Mark Wielaard f53174
@@ -3170,9 +3196,13 @@ static Bool parse_inl_DIE (
Mark Wielaard f53174
       }
Mark Wielaard f53174
       if (level == 0) {
Mark Wielaard f53174
          setup_cu_svma (cc, have_lo, ip_lo, td3);
Mark Wielaard f53174
-         if (has_stmt_list && unit_has_addrs)
Mark Wielaard f53174
-            read_filename_table( parser->fndn_ix_Table, compdir,
Mark Wielaard f53174
-                                 cc, debug_line_offset, td3 );
Mark Wielaard f53174
+         if (has_stmt_list && unit_has_addrs
Mark Wielaard f53174
+            && *debug_line_offset != cu_line_offset) {
Mark Wielaard f53174
+            reset_fndn_ix_table ( fndn_ix_Table, debug_line_offset,
Mark Wielaard f53174
+                                  cu_line_offset );
Mark Wielaard f53174
+            read_filename_table( *fndn_ix_Table, compdir,
Mark Wielaard f53174
+                                 cc, cu_line_offset, td3 );
Mark Wielaard f53174
+         }
Mark Wielaard f53174
       }
Mark Wielaard f53174
    }
Mark Wielaard f53174
 
Mark Wielaard f53174
@@ -3200,9 +3230,9 @@ static Bool parse_inl_DIE (
Mark Wielaard f53174
          if (attr == DW_AT_call_file && cts.szB > 0) {
Mark Wielaard f53174
             Int ftabIx = (Int)cts.u.val;
Mark Wielaard f53174
             if (ftabIx >= 1
Mark Wielaard f53174
-                && ftabIx < VG_(sizeXA)( parser->fndn_ix_Table )) {
Mark Wielaard f53174
+                && ftabIx < VG_(sizeXA)( *fndn_ix_Table )) {
Mark Wielaard f53174
                caller_fndn_ix = *(UInt*)
Mark Wielaard f53174
-                          VG_(indexXA)( parser->fndn_ix_Table, ftabIx );
Mark Wielaard f53174
+                          VG_(indexXA)( *fndn_ix_Table, ftabIx );
Mark Wielaard f53174
             }
Mark Wielaard f53174
             if (0) VG_(printf)("XXX caller_fndn_ix = %u %s\n", caller_fndn_ix,
Mark Wielaard f53174
                                ML_(fndn_ix2filename) (cc->di, caller_fndn_ix));
Mark Wielaard f53174
@@ -4652,6 +4682,8 @@ static void read_DIE (
Mark Wielaard f53174
    /*MOD*/D3TypeParser* typarser,
Mark Wielaard f53174
    /*MOD*/D3VarParser* varparser,
Mark Wielaard f53174
    /*MOD*/D3InlParser* inlparser,
Mark Wielaard f53174
+   XArray** fndn_ix_Table,
Mark Wielaard f53174
+   ULong *debug_line_offset,
Mark Wielaard f53174
    Cursor* c, Bool td3, CUConst* cc, Int level
Mark Wielaard f53174
 )
Mark Wielaard f53174
 {
Mark Wielaard f53174
@@ -4713,6 +4745,8 @@ static void read_DIE (
Mark Wielaard f53174
                      tempvars,
Mark Wielaard f53174
                      gexprs,
Mark Wielaard f53174
                      varparser,
Mark Wielaard f53174
+                     fndn_ix_Table,
Mark Wielaard f53174
+                     debug_line_offset,
Mark Wielaard f53174
                      (DW_TAG)atag,
Mark Wielaard f53174
                      posn,
Mark Wielaard f53174
                      level,
Mark Wielaard f53174
@@ -4734,6 +4768,8 @@ static void read_DIE (
Mark Wielaard f53174
       inlparser->sibling = 0;
Mark Wielaard f53174
       parse_children = 
Mark Wielaard f53174
          parse_inl_DIE( inlparser,
Mark Wielaard f53174
+                        fndn_ix_Table,
Mark Wielaard f53174
+                        debug_line_offset,
Mark Wielaard f53174
                         (DW_TAG)atag,
Mark Wielaard f53174
                         posn,
Mark Wielaard f53174
                         level,
Mark Wielaard f53174
@@ -4773,6 +4809,7 @@ static void read_DIE (
Mark Wielaard f53174
             if (parse_children) {
Mark Wielaard f53174
                read_DIE( rangestree, tyents, tempvars, gexprs,
Mark Wielaard f53174
                          typarser, varparser, inlparser,
Mark Wielaard f53174
+                         fndn_ix_Table, debug_line_offset,
Mark Wielaard f53174
                          c, td3, cc, level+1 );
Mark Wielaard f53174
             } else {
Mark Wielaard f53174
                Int skip_level = level + 1;
Mark Wielaard f53174
@@ -5006,6 +5043,8 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
    D3TypeParser typarser;
Mark Wielaard f53174
    D3VarParser varparser;
Mark Wielaard f53174
    D3InlParser inlparser;
Mark Wielaard f53174
+   XArray* /* of UInt */ fndn_ix_Table = NULL;
Mark Wielaard f53174
+   ULong debug_line_offset = (ULong) -1;
Mark Wielaard f53174
    Word  i, j, n;
Mark Wielaard f53174
    Bool td3 = di->trace_symtab;
Mark Wielaard f53174
    XArray* /* of TempVar* */ dioff_lookup_tab;
Mark Wielaard f53174
@@ -5145,6 +5184,10 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
                       "Overrun whilst reading alternate .debug_info section" );
Mark Wielaard f53174
          section_size = escn_debug_info_alt.szB;
Mark Wielaard f53174
 
Mark Wielaard f53174
+	 /* Keep track of the last line table we have seen,
Mark Wielaard f53174
+            it might turn up again.  */
Mark Wielaard f53174
+         reset_fndn_ix_table(&fndn_ix_Table, &debug_line_offset, (ULong) -1);
Mark Wielaard f53174
+
Mark Wielaard f53174
          TRACE_D3("\n------ Parsing alternate .debug_info section ------\n");
Mark Wielaard f53174
       } else if (pass == 1) {
Mark Wielaard f53174
          /* Now loop over the Compilation Units listed in the .debug_info
Mark Wielaard f53174
@@ -5155,6 +5198,10 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
                       "Overrun whilst reading .debug_info section" );
Mark Wielaard f53174
          section_size = escn_debug_info.szB;
Mark Wielaard f53174
 
Mark Wielaard f53174
+	 /* Keep track of the last line table we have seen,
Mark Wielaard f53174
+            it might turn up again.  */
Mark Wielaard f53174
+         reset_fndn_ix_table(&fndn_ix_Table, &debug_line_offset, (ULong) -1);
Mark Wielaard f53174
+
Mark Wielaard f53174
          TRACE_D3("\n------ Parsing .debug_info section ------\n");
Mark Wielaard f53174
       } else {
Mark Wielaard f53174
          if (!ML_(sli_is_valid)(escn_debug_types))
Mark Wielaard f53174
@@ -5165,6 +5212,10 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
                       "Overrun whilst reading .debug_types section" );
Mark Wielaard f53174
          section_size = escn_debug_types.szB;
Mark Wielaard f53174
 
Mark Wielaard f53174
+	 /* Keep track of the last line table we have seen,
Mark Wielaard f53174
+            it might turn up again.  */
Mark Wielaard f53174
+         reset_fndn_ix_table(&fndn_ix_Table, &debug_line_offset, (ULong) -1);
Mark Wielaard f53174
+
Mark Wielaard f53174
          TRACE_D3("\n------ Parsing .debug_types section ------\n");
Mark Wielaard f53174
       }
Mark Wielaard f53174
 
Mark Wielaard f53174
@@ -5257,26 +5308,6 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
                            unitary_range_list(0UL, ~0UL),
Mark Wielaard f53174
                            -1, False/*isFunc*/, NULL/*fbGX*/ );
Mark Wielaard f53174
 
Mark Wielaard f53174
-            /* And set up the fndn_ix_Table.  When we come across the top
Mark Wielaard f53174
-               level DIE for this CU (which is what the next call to
Mark Wielaard f53174
-               read_DIE should process) we will copy all the file names out
Mark Wielaard f53174
-               of the .debug_line img area and use this table to look up the
Mark Wielaard f53174
-               copies when we later see filename numbers in DW_TAG_variables
Mark Wielaard f53174
-               etc. */
Mark Wielaard f53174
-            vg_assert(!varparser.fndn_ix_Table );
Mark Wielaard f53174
-            varparser.fndn_ix_Table 
Mark Wielaard f53174
-               = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.5var",
Mark Wielaard f53174
-                             ML_(dinfo_free),
Mark Wielaard f53174
-                             sizeof(UInt) );
Mark Wielaard f53174
-         }
Mark Wielaard f53174
-
Mark Wielaard f53174
-         if (VG_(clo_read_inline_info)) {
Mark Wielaard f53174
-            /* fndn_ix_Table for the inlined call parser */
Mark Wielaard f53174
-            vg_assert(!inlparser.fndn_ix_Table );
Mark Wielaard f53174
-            inlparser.fndn_ix_Table 
Mark Wielaard f53174
-               = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.5inl",
Mark Wielaard f53174
-                             ML_(dinfo_free),
Mark Wielaard f53174
-                             sizeof(UInt) );
Mark Wielaard f53174
          }
Mark Wielaard f53174
 
Mark Wielaard f53174
          /* Now read the one-and-only top-level DIE for this CU. */
Mark Wielaard f53174
@@ -5284,6 +5315,7 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
          read_DIE( rangestree,
Mark Wielaard f53174
                    tyents, tempvars, gexprs,
Mark Wielaard f53174
                    &typarser, &varparser, &inlparser,
Mark Wielaard f53174
+                   &fndn_ix_Table, &debug_line_offset,
Mark Wielaard f53174
                    &info, td3, &cc, 0 );
Mark Wielaard f53174
 
Mark Wielaard f53174
          cu_offset_now = get_position_of_Cursor( &info );
Mark Wielaard f53174
@@ -5328,16 +5360,6 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
             typestack_preen( &typarser, td3, -2 );
Mark Wielaard f53174
          }
Mark Wielaard f53174
 
Mark Wielaard f53174
-         if (VG_(clo_read_var_info)) {
Mark Wielaard f53174
-            vg_assert(varparser.fndn_ix_Table );
Mark Wielaard f53174
-            VG_(deleteXA)( varparser.fndn_ix_Table );
Mark Wielaard f53174
-            varparser.fndn_ix_Table = NULL;
Mark Wielaard f53174
-         }
Mark Wielaard f53174
-         if (VG_(clo_read_inline_info)) {
Mark Wielaard f53174
-            vg_assert(inlparser.fndn_ix_Table );
Mark Wielaard f53174
-            VG_(deleteXA)( inlparser.fndn_ix_Table );
Mark Wielaard f53174
-            inlparser.fndn_ix_Table = NULL;
Mark Wielaard f53174
-         }
Mark Wielaard f53174
          clear_CUConst(&cc);
Mark Wielaard f53174
 
Mark Wielaard f53174
          if (cu_offset_now == section_size)
Mark Wielaard f53174
@@ -5346,6 +5368,8 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
       }
Mark Wielaard f53174
    }
Mark Wielaard f53174
 
Mark Wielaard f53174
+   if (fndn_ix_Table != NULL)
Mark Wielaard f53174
+      VG_(deleteXA)(fndn_ix_Table);
Mark Wielaard f53174
 
Mark Wielaard f53174
    if (VG_(clo_read_var_info)) {
Mark Wielaard f53174
       /* From here on we're post-processing the stuff we got
Mark Wielaard f53174
@@ -5662,8 +5686,6 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
       ML_(dinfo_free)( tyents_to_keep_cache );
Mark Wielaard f53174
       tyents_to_keep_cache = NULL;
Mark Wielaard f53174
 
Mark Wielaard f53174
-      vg_assert( varparser.fndn_ix_Table == NULL );
Mark Wielaard f53174
-
Mark Wielaard f53174
       /* And the signatured type hash.  */
Mark Wielaard f53174
       VG_(HT_destruct) ( signature_types, ML_(dinfo_free) );
Mark Wielaard f53174
 
Mark Wielaard f53174
-- 
Mark Wielaard f53174
2.18.4
Mark Wielaard f53174
Mark Wielaard f53174
From 8548d2e4ca0fb485597ddbf958e2064620ee972a Mon Sep 17 00:00:00 2001
Mark Wielaard f53174
From: Mark Wielaard <mark@klomp.org>
Mark Wielaard f53174
Date: Sat, 18 Sep 2021 03:23:52 +0200
Mark Wielaard f53174
Subject: [PATCH 4/6] readdwarf3: Immediately skip to end of CU when not
Mark Wielaard f53174
 parsing children
Mark Wielaard f53174
Mark Wielaard f53174
---
Mark Wielaard f53174
 coregrind/m_debuginfo/readdwarf3.c | 10 ++++++++++
Mark Wielaard f53174
 1 file changed, 10 insertions(+)
Mark Wielaard f53174
Mark Wielaard f53174
diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c
Mark Wielaard f53174
index e63e35788..b02e23990 100644
Mark Wielaard f53174
--- a/coregrind/m_debuginfo/readdwarf3.c
Mark Wielaard f53174
+++ b/coregrind/m_debuginfo/readdwarf3.c
Mark Wielaard f53174
@@ -4787,6 +4787,16 @@ static void read_DIE (
Mark Wielaard f53174
       vg_assert (inlparser->sibling == 0 || inlparser->sibling == sibling);
Mark Wielaard f53174
    }
Mark Wielaard f53174
 
Mark Wielaard f53174
+   /* Top level CU DIE, but we don't want to read anything else, just skip
Mark Wielaard f53174
+      to the end and return.  */
Mark Wielaard f53174
+   if (level == 0 && !parse_children) {
Mark Wielaard f53174
+      UWord cu_size_including_IniLen = (cc->unit_length
Mark Wielaard f53174
+                                        + (cc->is_dw64 ? 12 : 4));
Mark Wielaard f53174
+      set_position_of_Cursor( c, (cc->cu_start_offset
Mark Wielaard f53174
+                                  + cu_size_including_IniLen));
Mark Wielaard f53174
+      return;
Mark Wielaard f53174
+   }
Mark Wielaard f53174
+
Mark Wielaard f53174
    if (after_die_c_offset > 0) {
Mark Wielaard f53174
       // DIE was read by a parser above, so we know where the DIE ends.
Mark Wielaard f53174
       set_position_of_Cursor( c, after_die_c_offset );
Mark Wielaard f53174
-- 
Mark Wielaard f53174
2.18.4
Mark Wielaard f53174
Mark Wielaard f53174
From 2295d273ee03781f5bf112ccedabcea03ca79bf5 Mon Sep 17 00:00:00 2001
Mark Wielaard f53174
From: Mark Wielaard <mark@klomp.org>
Mark Wielaard f53174
Date: Sat, 18 Sep 2021 22:16:33 +0200
Mark Wielaard f53174
Subject: [PATCH 5/6] readdwarf3: Reuse abbrev if possible between units
Mark Wielaard f53174
Mark Wielaard f53174
Instead of destroying the ht_abbrvs after processing a CU save it
Mark Wielaard f53174
and the offset so it can be reused for the next CU if that happens
Mark Wielaard f53174
to have the same abbrev offset. dwz compressed DWARF often reuse
Mark Wielaard f53174
the same abbrev for multiple CUs.
Mark Wielaard f53174
---
Mark Wielaard f53174
 coregrind/m_debuginfo/readdwarf3.c | 40 ++++++++++++++++++++++--------
Mark Wielaard f53174
 1 file changed, 29 insertions(+), 11 deletions(-)
Mark Wielaard f53174
Mark Wielaard f53174
diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c
Mark Wielaard f53174
index b02e23990..0c86b712e 100644
Mark Wielaard f53174
--- a/coregrind/m_debuginfo/readdwarf3.c
Mark Wielaard f53174
+++ b/coregrind/m_debuginfo/readdwarf3.c
Mark Wielaard f53174
@@ -470,6 +470,7 @@ typedef
Mark Wielaard f53174
       struct _DebugInfo* di;
Mark Wielaard f53174
       /* --- a hash table of g_abbv (i.e. parsed abbreviations) --- */
Mark Wielaard f53174
       VgHashTable *ht_abbvs;
Mark Wielaard f53174
+      ULong debug_abbrev_offset;
Mark Wielaard f53174
 
Mark Wielaard f53174
       /* True if this came from .debug_types; otherwise it came from
Mark Wielaard f53174
          .debug_info.  */
Mark Wielaard f53174
@@ -1101,13 +1102,6 @@ static g_abbv* get_abbv (const CUConst* cc, ULong abbv_code)
Mark Wielaard f53174
    return abbv;
Mark Wielaard f53174
 }
Mark Wielaard f53174
 
Mark Wielaard f53174
-/* Free the memory allocated in CUConst. */
Mark Wielaard f53174
-static void clear_CUConst (CUConst* cc)
Mark Wielaard f53174
-{
Mark Wielaard f53174
-   VG_(HT_destruct) ( cc->ht_abbvs, ML_(dinfo_free));
Mark Wielaard f53174
-   cc->ht_abbvs = NULL;
Mark Wielaard f53174
-}
Mark Wielaard f53174
-
Mark Wielaard f53174
 /* Parse the Compilation Unit header indicated at 'c' and 
Mark Wielaard f53174
    initialise 'cc' accordingly. */
Mark Wielaard f53174
 static __attribute__((noinline))
Mark Wielaard f53174
@@ -1115,6 +1109,8 @@ void parse_CU_Header ( /*OUT*/CUConst* cc,
Mark Wielaard f53174
                        Bool td3,
Mark Wielaard f53174
                        Cursor* c, 
Mark Wielaard f53174
                        DiSlice escn_debug_abbv,
Mark Wielaard f53174
+                       ULong last_debug_abbrev_offset,
Mark Wielaard f53174
+                       VgHashTable *last_ht_abbvs,
Mark Wielaard f53174
 		       Bool type_unit,
Mark Wielaard f53174
                        Bool alt_info )
Mark Wielaard f53174
 {
Mark Wielaard f53174
@@ -1190,7 +1186,15 @@ void parse_CU_Header ( /*OUT*/CUConst* cc,
Mark Wielaard f53174
    cc->debug_abbv.ioff += debug_abbrev_offset;
Mark Wielaard f53174
    cc->debug_abbv.szB  -= debug_abbrev_offset;
Mark Wielaard f53174
 
Mark Wielaard f53174
-   init_ht_abbvs(cc, td3);
Mark Wielaard f53174
+   cc->debug_abbrev_offset = debug_abbrev_offset;
Mark Wielaard f53174
+   if (last_ht_abbvs != NULL
Mark Wielaard f53174
+       && debug_abbrev_offset == last_debug_abbrev_offset) {
Mark Wielaard f53174
+      cc->ht_abbvs = last_ht_abbvs;
Mark Wielaard f53174
+   } else {
Mark Wielaard f53174
+      if (last_ht_abbvs != NULL)
Mark Wielaard f53174
+         VG_(HT_destruct) (last_ht_abbvs, ML_(dinfo_free));
Mark Wielaard f53174
+      init_ht_abbvs(cc, td3);
Mark Wielaard f53174
+   }
Mark Wielaard f53174
 }
Mark Wielaard f53174
 
Mark Wielaard f53174
 /* This represents a single signatured type.  It maps a type signature
Mark Wielaard f53174
@@ -5141,6 +5145,8 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
       TRACE_D3("\n------ Collecting signatures from "
Mark Wielaard f53174
                ".debug_types section ------\n");
Mark Wielaard f53174
 
Mark Wielaard f53174
+      ULong last_debug_abbrev_offset = (ULong) -1;
Mark Wielaard f53174
+      VgHashTable *last_ht_abbvs = NULL;
Mark Wielaard f53174
       while (True) {
Mark Wielaard f53174
          UWord   cu_start_offset, cu_offset_now;
Mark Wielaard f53174
          CUConst cc;
Mark Wielaard f53174
@@ -5149,7 +5155,9 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
          TRACE_D3("\n");
Mark Wielaard f53174
          TRACE_D3("  Compilation Unit @ offset 0x%lx:\n", cu_start_offset);
Mark Wielaard f53174
          /* parse_CU_header initialises the CU's abbv hash table.  */
Mark Wielaard f53174
-         parse_CU_Header( &cc, td3, &info, escn_debug_abbv, True, False );
Mark Wielaard f53174
+         parse_CU_Header( &cc, td3, &info, escn_debug_abbv,
Mark Wielaard f53174
+                          last_debug_abbrev_offset, last_ht_abbvs,
Mark Wielaard f53174
+                          True, False );
Mark Wielaard f53174
 
Mark Wielaard f53174
          /* Needed by cook_die.  */
Mark Wielaard f53174
          cc.types_cuOff_bias = escn_debug_info.szB;
Mark Wielaard f53174
@@ -5163,7 +5171,8 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
          cu_offset_now = (cu_start_offset + cc.unit_length
Mark Wielaard f53174
                           + (cc.is_dw64 ? 12 : 4));
Mark Wielaard f53174
 
Mark Wielaard f53174
-         clear_CUConst ( &cc);
Mark Wielaard f53174
+         last_debug_abbrev_offset = cc.debug_abbrev_offset;
Mark Wielaard f53174
+         last_ht_abbvs = cc.ht_abbvs;
Mark Wielaard f53174
 
Mark Wielaard f53174
          if (cu_offset_now >= escn_debug_types.szB) {
Mark Wielaard f53174
             break;
Mark Wielaard f53174
@@ -5171,6 +5180,8 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
 
Mark Wielaard f53174
          set_position_of_Cursor ( &info, cu_offset_now );
Mark Wielaard f53174
       }
Mark Wielaard f53174
+      if (last_ht_abbvs != NULL)
Mark Wielaard f53174
+         VG_(HT_destruct) (last_ht_abbvs, ML_(dinfo_free));
Mark Wielaard f53174
    }
Mark Wielaard f53174
 
Mark Wielaard f53174
    /* Perform three DIE-reading passes.  The first pass reads DIEs from
Mark Wielaard f53174
@@ -5229,6 +5240,8 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
          TRACE_D3("\n------ Parsing .debug_types section ------\n");
Mark Wielaard f53174
       }
Mark Wielaard f53174
 
Mark Wielaard f53174
+      ULong last_debug_abbrev_offset = (ULong) -1;
Mark Wielaard f53174
+      VgHashTable *last_ht_abbvs = NULL;
Mark Wielaard f53174
       while (True) {
Mark Wielaard f53174
          ULong   cu_start_offset, cu_offset_now;
Mark Wielaard f53174
          CUConst cc;
Mark Wielaard f53174
@@ -5277,9 +5290,11 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
          /* parse_CU_header initialises the CU's hashtable of abbvs ht_abbvs */
Mark Wielaard f53174
          if (pass == 0) {
Mark Wielaard f53174
             parse_CU_Header( &cc, td3, &info, escn_debug_abbv_alt,
Mark Wielaard f53174
+                             last_debug_abbrev_offset, last_ht_abbvs,
Mark Wielaard f53174
                              False, True );
Mark Wielaard f53174
          } else {
Mark Wielaard f53174
             parse_CU_Header( &cc, td3, &info, escn_debug_abbv,
Mark Wielaard f53174
+                             last_debug_abbrev_offset, last_ht_abbvs,
Mark Wielaard f53174
                              pass == 2, False );
Mark Wielaard f53174
          }
Mark Wielaard f53174
          cc.escn_debug_str      = pass == 0 ? escn_debug_str_alt
Mark Wielaard f53174
@@ -5370,12 +5385,15 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
             typestack_preen( &typarser, td3, -2 );
Mark Wielaard f53174
          }
Mark Wielaard f53174
 
Mark Wielaard f53174
-         clear_CUConst(&cc);
Mark Wielaard f53174
+         last_debug_abbrev_offset = cc.debug_abbrev_offset;
Mark Wielaard f53174
+         last_ht_abbvs = cc.ht_abbvs;
Mark Wielaard f53174
 
Mark Wielaard f53174
          if (cu_offset_now == section_size)
Mark Wielaard f53174
             break;
Mark Wielaard f53174
          /* else keep going */
Mark Wielaard f53174
       }
Mark Wielaard f53174
+      if (last_ht_abbvs != NULL)
Mark Wielaard f53174
+         VG_(HT_destruct) (last_ht_abbvs, ML_(dinfo_free));
Mark Wielaard f53174
    }
Mark Wielaard f53174
 
Mark Wielaard f53174
    if (fndn_ix_Table != NULL)
Mark Wielaard f53174
-- 
Mark Wielaard f53174
2.18.4
Mark Wielaard f53174
Mark Wielaard f53174
From 24faa4c59b719c4a4bb2b21c2024ecb52c9be875 Mon Sep 17 00:00:00 2001
Mark Wielaard f53174
From: Mark Wielaard <mark@klomp.org>
Mark Wielaard f53174
Date: Sun, 19 Sep 2021 14:30:19 +0200
Mark Wielaard f53174
Subject: [PATCH 6/6] readdwarf3: Introduce abbv_state to read .debug_abbrev
Mark Wielaard f53174
 more lazily
Mark Wielaard f53174
Mark Wielaard f53174
With the inline parser often a lot of DIEs are skipped, so reading
Mark Wielaard f53174
all abbrevs up front wastes time and memory. A lot of time and memory
Mark Wielaard f53174
can be saved by reading the abbrevs on demand. Do this by introducing
Mark Wielaard f53174
an abbv_state that is used to keep track of the abbrevs already read.
Mark Wielaard f53174
This does technically make the CUConst struct not const.
Mark Wielaard f53174
---
Mark Wielaard f53174
 coregrind/m_debuginfo/readdwarf3.c | 145 +++++++++++++++++------------
Mark Wielaard f53174
 1 file changed, 88 insertions(+), 57 deletions(-)
Mark Wielaard f53174
Mark Wielaard f53174
diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c
Mark Wielaard f53174
index 0c86b712e..4ac23a3c4 100644
Mark Wielaard f53174
--- a/coregrind/m_debuginfo/readdwarf3.c
Mark Wielaard f53174
+++ b/coregrind/m_debuginfo/readdwarf3.c
Mark Wielaard f53174
@@ -415,6 +415,23 @@ typedef
Mark Wielaard f53174
          described by this g_abbv; */
Mark Wielaard f53174
     } g_abbv;
Mark Wielaard f53174
 
Mark Wielaard f53174
+/* Holds information about the .debug_abbrev section for this CU.  The current
Mark Wielaard f53174
+  Cursor into the abbrev section, the known abbrev codes are but into an hash
Mark Wielaard f53174
+  table.  The (starting) offset into the abbrev_offset can be used to check
Mark Wielaard f53174
+  whether the abbv can be shared between CUs.  The done boolean is set when all
Mark Wielaard f53174
+  known codes have been read.  Initialize a new abbv_state with init_ht_abbvs.
Mark Wielaard f53174
+  To read any new abbrev codes not yet in the hash table call find_ht_abbvs
Mark Wielaard f53174
+  (get_abbv will first query the ht_abbvs, then if not done, call
Mark Wielaard f53174
+  find_ht_abbvs).  */
Mark Wielaard f53174
+typedef
Mark Wielaard f53174
+   struct _abbv_state {
Mark Wielaard f53174
+      Cursor c; /* Current cursor into .debug_abbrev.  */
Mark Wielaard f53174
+      VgHashTable *ht_abbvs; /* Hash table mapping codes to abbrevs.  */
Mark Wielaard f53174
+      ULong debug_abbrev_offset; /* Starting offset into .debug_abbrev.  */
Mark Wielaard f53174
+      Bool done; /* Whether there (might) still be new abbrev codes not yet
Mark Wielaard f53174
+                    in the cache.  */
Mark Wielaard f53174
+   } abbv_state;
Mark Wielaard f53174
+
Mark Wielaard f53174
 /* Holds information that is constant through the parsing of a
Mark Wielaard f53174
    Compilation Unit.  This is basically plumbed through to
Mark Wielaard f53174
    everywhere. */
Mark Wielaard f53174
@@ -468,9 +485,9 @@ typedef
Mark Wielaard f53174
       UWord  alt_cuOff_bias;
Mark Wielaard f53174
       /* --- Needed so we can add stuff to the string table. --- */
Mark Wielaard f53174
       struct _DebugInfo* di;
Mark Wielaard f53174
-      /* --- a hash table of g_abbv (i.e. parsed abbreviations) --- */
Mark Wielaard f53174
-      VgHashTable *ht_abbvs;
Mark Wielaard f53174
-      ULong debug_abbrev_offset;
Mark Wielaard f53174
+      /* --- State of the hash table of g_abbv (i.e. parsed abbreviations)
Mark Wielaard f53174
+             technically makes this struct not const.  --- */
Mark Wielaard f53174
+      abbv_state abbv;
Mark Wielaard f53174
 
Mark Wielaard f53174
       /* True if this came from .debug_types; otherwise it came from
Mark Wielaard f53174
          .debug_info.  */
Mark Wielaard f53174
@@ -998,18 +1015,27 @@ get_range_list ( const CUConst* cc,
Mark Wielaard f53174
 #define VARSZ_FORM 0xffffffff
Mark Wielaard f53174
 static UInt get_Form_szB (const CUConst* cc, DW_FORM form );
Mark Wielaard f53174
 
Mark Wielaard f53174
-/* Initialises the hash table of abbreviations.
Mark Wielaard f53174
-   We do a single scan of the abbv slice to parse and
Mark Wielaard f53174
-   build all abbreviations, for the following reasons:
Mark Wielaard f53174
-     * all or most abbreviations will be needed in any case
Mark Wielaard f53174
-       (at least for var-info reading).
Mark Wielaard f53174
-     * re-reading each time an abbreviation causes a lot of calls
Mark Wielaard f53174
-       to get_ULEB128.
Mark Wielaard f53174
-     * a CU should not have many abbreviations. */
Mark Wielaard f53174
-static void init_ht_abbvs (CUConst* cc,
Mark Wielaard f53174
+/* Initialises the hash table of abbreviations.  This only sets up the abbv
Mark Wielaard f53174
+   Cursor and hash table, but does not try to read any abbrevs yes. The actual
Mark Wielaard f53174
+   reading of abbrevs will be done by get_abbv by calling find_ht_abbvs on
Mark Wielaard f53174
+   demand if a requested abbrev code isn't in the hash table yet. When using the
Mark Wielaard f53174
+   inline parser a lot of abbrevs will not be needed so reading everything
Mark Wielaard f53174
+   upfront will often waste time and memory.  */
Mark Wielaard f53174
+static void init_ht_abbvs (CUConst* cc, ULong debug_abbrev_offset,
Mark Wielaard f53174
                            Bool td3)
Mark Wielaard f53174
 {
Mark Wielaard f53174
-   Cursor c;
Mark Wielaard f53174
+   Cursor *c = &cc->abbv.c;
Mark Wielaard f53174
+   init_Cursor( c, cc->debug_abbv, 0, cc->barf,
Mark Wielaard f53174
+               "Overrun whilst parsing .debug_abbrev section(2)" );
Mark Wielaard f53174
+   cc->abbv.ht_abbvs = VG_(HT_construct) ("di.readdwarf3.ht_abbvs");
Mark Wielaard f53174
+   cc->abbv.debug_abbrev_offset = debug_abbrev_offset;
Mark Wielaard f53174
+   cc->abbv.done = False;
Mark Wielaard f53174
+}
Mark Wielaard f53174
+
Mark Wielaard f53174
+static g_abbv *find_ht_abbvs (CUConst* cc, ULong abbv_code,
Mark Wielaard f53174
+                              Bool td3)
Mark Wielaard f53174
+{
Mark Wielaard f53174
+   Cursor *c;
Mark Wielaard f53174
    g_abbv *ta; // temporary abbreviation, reallocated if needed.
Mark Wielaard f53174
    UInt ta_nf_maxE; // max nr of pairs in ta.nf[], doubled when reallocated.
Mark Wielaard f53174
    UInt ta_nf_n;    // nr of pairs in ta->nf that are initialised.
Mark Wielaard f53174
@@ -1020,16 +1046,18 @@ static void init_ht_abbvs (CUConst* cc,
Mark Wielaard f53174
 
Mark Wielaard f53174
    ta_nf_maxE = 10; // starting with enough for 9 pairs+terminating pair.
Mark Wielaard f53174
    ta = ML_(dinfo_zalloc) ("di.readdwarf3.ht_ta_nf", SZ_G_ABBV(ta_nf_maxE));
Mark Wielaard f53174
-   cc->ht_abbvs = VG_(HT_construct) ("di.readdwarf3.ht_abbvs");
Mark Wielaard f53174
 
Mark Wielaard f53174
-   init_Cursor( &c, cc->debug_abbv, 0, cc->barf,
Mark Wielaard f53174
-               "Overrun whilst parsing .debug_abbrev section(2)" );
Mark Wielaard f53174
+   c = &cc->abbv.c;
Mark Wielaard f53174
    while (True) {
Mark Wielaard f53174
-      ta->abbv_code = get_ULEB128( &c );
Mark Wielaard f53174
-      if (ta->abbv_code == 0) break; /* end of the table */
Mark Wielaard f53174
+      ht_ta = NULL;
Mark Wielaard f53174
+      ta->abbv_code = get_ULEB128( c );
Mark Wielaard f53174
+      if (ta->abbv_code == 0) {
Mark Wielaard f53174
+         cc->abbv.done = True;
Mark Wielaard f53174
+         break; /* end of the table */
Mark Wielaard f53174
+      }
Mark Wielaard f53174
 
Mark Wielaard f53174
-      ta->atag = get_ULEB128( &c );
Mark Wielaard f53174
-      ta->has_children = get_UChar( &c );
Mark Wielaard f53174
+      ta->atag = get_ULEB128( c );
Mark Wielaard f53174
+      ta->has_children = get_UChar( c );
Mark Wielaard f53174
       ta_nf_n = 0;
Mark Wielaard f53174
       while (True) {
Mark Wielaard f53174
          if (ta_nf_n >= ta_nf_maxE) {
Mark Wielaard f53174
@@ -1040,10 +1068,10 @@ static void init_ht_abbvs (CUConst* cc,
Mark Wielaard f53174
             VG_(memcpy) (ta, old_ta, SZ_G_ABBV(ta_nf_n));
Mark Wielaard f53174
             ML_(dinfo_free) (old_ta);
Mark Wielaard f53174
          }
Mark Wielaard f53174
-         ta->nf[ta_nf_n].at_name = get_ULEB128( &c );
Mark Wielaard f53174
-         ta->nf[ta_nf_n].at_form = get_ULEB128( &c );
Mark Wielaard f53174
+         ta->nf[ta_nf_n].at_name = get_ULEB128( c );
Mark Wielaard f53174
+         ta->nf[ta_nf_n].at_form = get_ULEB128( c );
Mark Wielaard f53174
          if (ta->nf[ta_nf_n].at_form == DW_FORM_implicit_const)
Mark Wielaard f53174
-            ta->nf[ta_nf_n].at_val = get_SLEB128( &c );
Mark Wielaard f53174
+            ta->nf[ta_nf_n].at_val = get_SLEB128( c );
Mark Wielaard f53174
          if (ta->nf[ta_nf_n].at_name == 0 && ta->nf[ta_nf_n].at_form == 0) {
Mark Wielaard f53174
             ta_nf_n++;
Mark Wielaard f53174
             break; 
Mark Wielaard f53174
@@ -1075,7 +1103,7 @@ static void init_ht_abbvs (CUConst* cc,
Mark Wielaard f53174
 
Mark Wielaard f53174
       ht_ta = ML_(dinfo_zalloc) ("di.readdwarf3.ht_ta", SZ_G_ABBV(ta_nf_n));
Mark Wielaard f53174
       VG_(memcpy) (ht_ta, ta, SZ_G_ABBV(ta_nf_n));
Mark Wielaard f53174
-      VG_(HT_add_node) ( cc->ht_abbvs, ht_ta );
Mark Wielaard f53174
+      VG_(HT_add_node) ( cc->abbv.ht_abbvs, ht_ta );
Mark Wielaard f53174
       if (TD3) {
Mark Wielaard f53174
          TRACE_D3("  Adding abbv_code %lu TAG  %s [%s] nf %u ",
Mark Wielaard f53174
                   ht_ta->abbv_code, ML_(pp_DW_TAG)(ht_ta->atag),
Mark Wielaard f53174
@@ -1086,19 +1114,27 @@ static void init_ht_abbvs (CUConst* cc,
Mark Wielaard f53174
             TRACE_D3("[%u,%u] ", ta->nf[i].skip_szB, ta->nf[i].next_nf);
Mark Wielaard f53174
          TRACE_D3("\n");
Mark Wielaard f53174
       }
Mark Wielaard f53174
+      if (ht_ta->abbv_code == abbv_code)
Mark Wielaard f53174
+         break;
Mark Wielaard f53174
    }
Mark Wielaard f53174
 
Mark Wielaard f53174
    ML_(dinfo_free) (ta);
Mark Wielaard f53174
    #undef SZ_G_ABBV
Mark Wielaard f53174
+
Mark Wielaard f53174
+   return ht_ta;
Mark Wielaard f53174
 }
Mark Wielaard f53174
 
Mark Wielaard f53174
-static g_abbv* get_abbv (const CUConst* cc, ULong abbv_code)
Mark Wielaard f53174
+static g_abbv* get_abbv (CUConst* cc, ULong abbv_code,
Mark Wielaard f53174
+                         Bool td3)
Mark Wielaard f53174
 {
Mark Wielaard f53174
    g_abbv *abbv;
Mark Wielaard f53174
 
Mark Wielaard f53174
-   abbv = VG_(HT_lookup) (cc->ht_abbvs, abbv_code);
Mark Wielaard f53174
+   abbv = VG_(HT_lookup) (cc->abbv.ht_abbvs, abbv_code);
Mark Wielaard f53174
+   if (!abbv && !cc->abbv.done)
Mark Wielaard f53174
+      abbv = find_ht_abbvs (cc, abbv_code, td3);
Mark Wielaard f53174
    if (!abbv)
Mark Wielaard f53174
       cc->barf ("abbv_code not found in ht_abbvs table");
Mark Wielaard f53174
+
Mark Wielaard f53174
    return abbv;
Mark Wielaard f53174
 }
Mark Wielaard f53174
 
Mark Wielaard f53174
@@ -1109,8 +1145,7 @@ void parse_CU_Header ( /*OUT*/CUConst* cc,
Mark Wielaard f53174
                        Bool td3,
Mark Wielaard f53174
                        Cursor* c, 
Mark Wielaard f53174
                        DiSlice escn_debug_abbv,
Mark Wielaard f53174
-                       ULong last_debug_abbrev_offset,
Mark Wielaard f53174
-                       VgHashTable *last_ht_abbvs,
Mark Wielaard f53174
+                       abbv_state last_abbv,
Mark Wielaard f53174
 		       Bool type_unit,
Mark Wielaard f53174
                        Bool alt_info )
Mark Wielaard f53174
 {
Mark Wielaard f53174
@@ -1186,14 +1221,13 @@ void parse_CU_Header ( /*OUT*/CUConst* cc,
Mark Wielaard f53174
    cc->debug_abbv.ioff += debug_abbrev_offset;
Mark Wielaard f53174
    cc->debug_abbv.szB  -= debug_abbrev_offset;
Mark Wielaard f53174
 
Mark Wielaard f53174
-   cc->debug_abbrev_offset = debug_abbrev_offset;
Mark Wielaard f53174
-   if (last_ht_abbvs != NULL
Mark Wielaard f53174
-       && debug_abbrev_offset == last_debug_abbrev_offset) {
Mark Wielaard f53174
-      cc->ht_abbvs = last_ht_abbvs;
Mark Wielaard f53174
+   if (last_abbv.ht_abbvs != NULL
Mark Wielaard f53174
+       && debug_abbrev_offset == last_abbv.debug_abbrev_offset) {
Mark Wielaard f53174
+      cc->abbv = last_abbv;
Mark Wielaard f53174
    } else {
Mark Wielaard f53174
-      if (last_ht_abbvs != NULL)
Mark Wielaard f53174
-         VG_(HT_destruct) (last_ht_abbvs, ML_(dinfo_free));
Mark Wielaard f53174
-      init_ht_abbvs(cc, td3);
Mark Wielaard f53174
+      if (last_abbv.ht_abbvs != NULL)
Mark Wielaard f53174
+         VG_(HT_destruct) (last_abbv.ht_abbvs, ML_(dinfo_free));
Mark Wielaard f53174
+      init_ht_abbvs(cc, debug_abbrev_offset, td3);
Mark Wielaard f53174
    }
Mark Wielaard f53174
 }
Mark Wielaard f53174
 
Mark Wielaard f53174
@@ -3016,7 +3050,7 @@ typedef
Mark Wielaard f53174
    table is kept, while we must handle all abbreviations in all CUs
Mark Wielaard f53174
    referenced by an absori (being a reference to an alt CU, or a previous
Mark Wielaard f53174
    or following CU). */
Mark Wielaard f53174
-static const HChar* get_inlFnName (Int absori, const CUConst* cc, Bool td3)
Mark Wielaard f53174
+static const HChar* get_inlFnName (Int absori, CUConst* cc, Bool td3)
Mark Wielaard f53174
 {
Mark Wielaard f53174
    Cursor c;
Mark Wielaard f53174
    const g_abbv *abbv;
Mark Wielaard f53174
@@ -3072,7 +3106,7 @@ static const HChar* get_inlFnName (Int absori, const CUConst* cc, Bool td3)
Mark Wielaard f53174
                 "Overrun get_inlFnName absori");
Mark Wielaard f53174
 
Mark Wielaard f53174
    abbv_code = get_ULEB128( &c );
Mark Wielaard f53174
-   abbv      = get_abbv ( cc, abbv_code);
Mark Wielaard f53174
+   abbv      = get_abbv ( cc, abbv_code, td3);
Mark Wielaard f53174
    atag      = abbv->atag;
Mark Wielaard f53174
    TRACE_D3(" <get_inlFnName><%lx>: Abbrev Number: %llu (%s)\n",
Mark Wielaard f53174
             posn, abbv_code, ML_(pp_DW_TAG)( atag ) );
Mark Wielaard f53174
@@ -4707,7 +4741,7 @@ static void read_DIE (
Mark Wielaard f53174
    /* --- Deal with this DIE --- */
Mark Wielaard f53174
    posn      = cook_die( cc, get_position_of_Cursor( c ) );
Mark Wielaard f53174
    abbv_code = get_ULEB128( c );
Mark Wielaard f53174
-   abbv = get_abbv(cc, abbv_code);
Mark Wielaard f53174
+   abbv = get_abbv(cc, abbv_code, td3);
Mark Wielaard f53174
    atag      = abbv->atag;
Mark Wielaard f53174
 
Mark Wielaard f53174
    if (TD3) {
Mark Wielaard f53174
@@ -4840,7 +4874,7 @@ static void read_DIE (
Mark Wielaard f53174
                   }
Mark Wielaard f53174
 
Mark Wielaard f53174
                   abbv_code = get_ULEB128( c );
Mark Wielaard f53174
-                  abbv = get_abbv(cc, abbv_code);
Mark Wielaard f53174
+                  abbv = get_abbv(cc, abbv_code, td3);
Mark Wielaard f53174
                   sibling = 0;
Mark Wielaard f53174
                   skip_DIE (&sibling, c, abbv, cc);
Mark Wielaard f53174
                   if (abbv->has_children) {
Mark Wielaard f53174
@@ -5145,8 +5179,9 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
       TRACE_D3("\n------ Collecting signatures from "
Mark Wielaard f53174
                ".debug_types section ------\n");
Mark Wielaard f53174
 
Mark Wielaard f53174
-      ULong last_debug_abbrev_offset = (ULong) -1;
Mark Wielaard f53174
-      VgHashTable *last_ht_abbvs = NULL;
Mark Wielaard f53174
+      abbv_state last_abbv;
Mark Wielaard f53174
+      last_abbv.debug_abbrev_offset = (ULong) -1;
Mark Wielaard f53174
+      last_abbv.ht_abbvs = NULL;
Mark Wielaard f53174
       while (True) {
Mark Wielaard f53174
          UWord   cu_start_offset, cu_offset_now;
Mark Wielaard f53174
          CUConst cc;
Mark Wielaard f53174
@@ -5156,8 +5191,7 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
          TRACE_D3("  Compilation Unit @ offset 0x%lx:\n", cu_start_offset);
Mark Wielaard f53174
          /* parse_CU_header initialises the CU's abbv hash table.  */
Mark Wielaard f53174
          parse_CU_Header( &cc, td3, &info, escn_debug_abbv,
Mark Wielaard f53174
-                          last_debug_abbrev_offset, last_ht_abbvs,
Mark Wielaard f53174
-                          True, False );
Mark Wielaard f53174
+                          last_abbv, True, False );
Mark Wielaard f53174
 
Mark Wielaard f53174
          /* Needed by cook_die.  */
Mark Wielaard f53174
          cc.types_cuOff_bias = escn_debug_info.szB;
Mark Wielaard f53174
@@ -5171,8 +5205,7 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
          cu_offset_now = (cu_start_offset + cc.unit_length
Mark Wielaard f53174
                           + (cc.is_dw64 ? 12 : 4));
Mark Wielaard f53174
 
Mark Wielaard f53174
-         last_debug_abbrev_offset = cc.debug_abbrev_offset;
Mark Wielaard f53174
-         last_ht_abbvs = cc.ht_abbvs;
Mark Wielaard f53174
+         last_abbv = cc.abbv;
Mark Wielaard f53174
 
Mark Wielaard f53174
          if (cu_offset_now >= escn_debug_types.szB) {
Mark Wielaard f53174
             break;
Mark Wielaard f53174
@@ -5180,8 +5213,8 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
 
Mark Wielaard f53174
          set_position_of_Cursor ( &info, cu_offset_now );
Mark Wielaard f53174
       }
Mark Wielaard f53174
-      if (last_ht_abbvs != NULL)
Mark Wielaard f53174
-         VG_(HT_destruct) (last_ht_abbvs, ML_(dinfo_free));
Mark Wielaard f53174
+      if (last_abbv.ht_abbvs != NULL)
Mark Wielaard f53174
+         VG_(HT_destruct) (last_abbv.ht_abbvs, ML_(dinfo_free));
Mark Wielaard f53174
    }
Mark Wielaard f53174
 
Mark Wielaard f53174
    /* Perform three DIE-reading passes.  The first pass reads DIEs from
Mark Wielaard f53174
@@ -5240,8 +5273,9 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
          TRACE_D3("\n------ Parsing .debug_types section ------\n");
Mark Wielaard f53174
       }
Mark Wielaard f53174
 
Mark Wielaard f53174
-      ULong last_debug_abbrev_offset = (ULong) -1;
Mark Wielaard f53174
-      VgHashTable *last_ht_abbvs = NULL;
Mark Wielaard f53174
+      abbv_state last_abbv;
Mark Wielaard f53174
+      last_abbv.debug_abbrev_offset = (ULong) -1;
Mark Wielaard f53174
+      last_abbv.ht_abbvs = NULL;
Mark Wielaard f53174
       while (True) {
Mark Wielaard f53174
          ULong   cu_start_offset, cu_offset_now;
Mark Wielaard f53174
          CUConst cc;
Mark Wielaard f53174
@@ -5290,12 +5324,10 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
          /* parse_CU_header initialises the CU's hashtable of abbvs ht_abbvs */
Mark Wielaard f53174
          if (pass == 0) {
Mark Wielaard f53174
             parse_CU_Header( &cc, td3, &info, escn_debug_abbv_alt,
Mark Wielaard f53174
-                             last_debug_abbrev_offset, last_ht_abbvs,
Mark Wielaard f53174
-                             False, True );
Mark Wielaard f53174
+                             last_abbv, False, True );
Mark Wielaard f53174
          } else {
Mark Wielaard f53174
             parse_CU_Header( &cc, td3, &info, escn_debug_abbv,
Mark Wielaard f53174
-                             last_debug_abbrev_offset, last_ht_abbvs,
Mark Wielaard f53174
-                             pass == 2, False );
Mark Wielaard f53174
+                             last_abbv, pass == 2, False );
Mark Wielaard f53174
          }
Mark Wielaard f53174
          cc.escn_debug_str      = pass == 0 ? escn_debug_str_alt
Mark Wielaard f53174
                                             : escn_debug_str;
Mark Wielaard f53174
@@ -5385,15 +5417,14 @@ void new_dwarf3_reader_wrk (
Mark Wielaard f53174
             typestack_preen( &typarser, td3, -2 );
Mark Wielaard f53174
          }
Mark Wielaard f53174
 
Mark Wielaard f53174
-         last_debug_abbrev_offset = cc.debug_abbrev_offset;
Mark Wielaard f53174
-         last_ht_abbvs = cc.ht_abbvs;
Mark Wielaard f53174
+         last_abbv = cc.abbv;
Mark Wielaard f53174
 
Mark Wielaard f53174
          if (cu_offset_now == section_size)
Mark Wielaard f53174
             break;
Mark Wielaard f53174
          /* else keep going */
Mark Wielaard f53174
       }
Mark Wielaard f53174
-      if (last_ht_abbvs != NULL)
Mark Wielaard f53174
-         VG_(HT_destruct) (last_ht_abbvs, ML_(dinfo_free));
Mark Wielaard f53174
+      if (last_abbv.ht_abbvs != NULL)
Mark Wielaard f53174
+         VG_(HT_destruct) (last_abbv.ht_abbvs, ML_(dinfo_free));
Mark Wielaard f53174
    }
Mark Wielaard f53174
 
Mark Wielaard f53174
    if (fndn_ix_Table != NULL)
Mark Wielaard f53174
-- 
Mark Wielaard f53174
2.18.4
Mark Wielaard f53174