Improve the speed of scanning PE binaries for line number information.
authorNick Clifton <nickc@redhat.com>
Wed, 29 Mar 2017 11:27:44 +0000 (12:27 +0100)
committerNick Clifton <nickc@redhat.com>
Wed, 29 Mar 2017 11:27:44 +0000 (12:27 +0100)
PR binutils/18025
* coff-bfd.h (struct coff_section_data): Add new fields:
saved_bias and bias.
* coffgen.c (coff_find_nearest_line_with_names): Cache the bias
computed for PE binaries.
* dwarf2.c (scan_unit_for_symbols): Only warn once about each
missing abbrev.

bfd/ChangeLog
bfd/coff-bfd.h
bfd/coffgen.c
bfd/dwarf2.c

index cf5e76294f7e4b737aeb897e918fb435c51a39bd..42ffd4d6f7ab59f52708789ae6d4397202f46bf4 100644 (file)
@@ -1,3 +1,13 @@
+2017-03-29  Nick Clifton  <nickc@redhat.com>
+
+       PR binutils/18025
+       * coff-bfd.h (struct coff_section_data): Add new fields:
+       saved_bias and bias.
+       * coffgen.c (coff_find_nearest_line_with_names): Cache the bias
+       computed for PE binaries.
+       * dwarf2.c (scan_unit_for_symbols): Only warn once about each
+       missing abbrev.
+
 2017-03-28  Hans-Peter Nilsson  <hp@axis.com>
 
        PR ld/16044
index c76bf3a54be740800da0cbbd41b13e09f7c4b776..97117b397484ed98542569609d410a8e2d648b72 100644 (file)
@@ -50,6 +50,8 @@ struct coff_section_tdata
   /* If this is TRUE, the contents entry may not be freed.  */
   bfd_boolean keep_contents;
   /* Information cached by coff_find_nearest_line.  */
+  bfd_boolean saved_bias;
+  bfd_signed_vma bias;
   bfd_vma offset;
   unsigned int i;
   const char *function;
index 5a61f6dc0d20dcc7d04ceca1b68dc7a9c4023632..3c60ed438f6ca349a35d34c132a91e32643289f7 100644 (file)
@@ -2259,6 +2259,8 @@ coff_find_nearest_line_with_names (bfd *abfd,
                                     &coff_data(abfd)->dwarf2_find_line_info))
     return TRUE;
 
+  sec_data = coff_section_data (abfd, section);
+
   /* If the DWARF lookup failed, but there is DWARF information available
      then the problem might be that the file has been rebased.  This tool
      changes the VMAs of all the sections, but it does not update the DWARF
@@ -2267,8 +2269,26 @@ coff_find_nearest_line_with_names (bfd *abfd,
     {
       bfd_signed_vma bias;
 
-      bias = _bfd_dwarf2_find_symbol_bias (symbols,
-                                          & coff_data (abfd)->dwarf2_find_line_info);
+      /* Create a cache of the result for the next call.  */
+      if (sec_data == NULL && section->owner == abfd)
+       {
+         amt = sizeof (struct coff_section_tdata);
+         section->used_by_bfd = bfd_zalloc (abfd, amt);
+         sec_data = (struct coff_section_tdata *) section->used_by_bfd;
+       }
+
+      if (sec_data != NULL && sec_data->saved_bias)
+       bias = sec_data->saved_bias;
+      else
+       {
+         bias = _bfd_dwarf2_find_symbol_bias (symbols,
+                                              & coff_data (abfd)->dwarf2_find_line_info);
+         if (sec_data)
+           {
+             sec_data->saved_bias = TRUE;
+             sec_data->bias = bias;
+           }
+       }
 
       if (bias
          && _bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section,
@@ -2363,10 +2383,16 @@ coff_find_nearest_line_with_names (bfd *abfd,
        }
     }
 
-  /* Now wander though the raw linenumbers of the section.  */
-  /* If we have been called on this section before, and the offset we
-     want is further down then we can prime the lookup loop.  */
-  sec_data = coff_section_data (abfd, section);
+  if (section->lineno_count == 0)
+    {
+      *functionname_ptr = NULL;
+      *line_ptr = 0;
+      return TRUE;
+    }
+
+  /* Now wander though the raw linenumbers of the section.
+     If we have been called on this section before, and the offset
+     we want is further down then we can prime the lookup loop.  */
   if (sec_data != NULL
       && sec_data->i > 0
       && offset >= sec_data->offset)
@@ -2395,6 +2421,7 @@ coff_find_nearest_line_with_names (bfd *abfd,
              coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym);
              if (coff->symbol.value > offset)
                break;
+
              *functionname_ptr = coff->symbol.name;
              last_value = coff->symbol.value;
              if (coff->native)
@@ -2451,6 +2478,7 @@ coff_find_nearest_line_with_names (bfd *abfd,
       section->used_by_bfd = bfd_zalloc (abfd, amt);
       sec_data = (struct coff_section_tdata *) section->used_by_bfd;
     }
+
   if (sec_data != NULL)
     {
       sec_data->offset = offset;
index 722ee0d9f5501e9c75a7c84b993a5cd8d1cd62b7..132a67492a44788bb52fd0c8d82f3012d43f07d1 100644 (file)
@@ -2738,12 +2738,19 @@ scan_unit_for_symbols (struct comp_unit *unit)
          continue;
        }
 
-      abbrev = lookup_abbrev (abbrev_number,unit->abbrevs);
+      abbrev = lookup_abbrev (abbrev_number, unit->abbrevs);
       if (! abbrev)
        {
-         _bfd_error_handler
-           (_("Dwarf Error: Could not find abbrev number %u."),
-            abbrev_number);
+         static unsigned int previous_failed_abbrev = -1U;
+
+         /* Avoid multiple reports of the same missing abbrev.  */
+         if (abbrev_number != previous_failed_abbrev)
+           {
+             _bfd_error_handler
+               (_("Dwarf Error: Could not find abbrev number %u."),
+                abbrev_number);
+             previous_failed_abbrev = abbrev_number;
+           }
          bfd_set_error (bfd_error_bad_value);
          goto fail;
        }
@@ -2760,7 +2767,7 @@ scan_unit_for_symbols (struct comp_unit *unit)
          func->tag = abbrev->tag;
          func->prev_func = unit->function_table;
          unit->function_table = func;
-      unit->number_of_functions++;
+         unit->number_of_functions++;
          BFD_ASSERT (!unit->cached);
 
          if (func->tag == DW_TAG_inlined_subroutine)
@@ -2785,7 +2792,8 @@ scan_unit_for_symbols (struct comp_unit *unit)
              var->stack = 1;
              var->prev_var = unit->variable_table;
              unit->variable_table = var;
-             BFD_ASSERT (!unit->cached);
+             /* PR 18205: Missing debug information can cause this
+                var to be attached to an already cached unit.  */
            }
 
          /* No inline function in scope at this nesting level.  */