Blame SOURCES/binutils-bfd-DWARF-improvements.patch

669081
diff -rup binutils.orig/bfd/dwarf2.c binutils-2.36.1/bfd/dwarf2.c
669081
--- binutils.orig/bfd/dwarf2.c	2022-04-11 12:06:47.745972052 +0100
669081
+++ binutils-2.36.1/bfd/dwarf2.c	2022-04-11 12:58:03.964445150 +0100
669081
@@ -1484,6 +1484,8 @@ struct funcinfo
669081
   struct arange		arange;
669081
   /* Where the symbol is defined.  */
669081
   asection *		sec;
669081
+  /* The offset of the funcinfo from the start of the unit.  */
669081
+  bfd_uint64_t          unit_offset;
669081
 };
669081
 
669081
 struct lookup_funcinfo
669081
@@ -3304,6 +3306,15 @@ read_rangelist (struct comp_unit *unit,
669081
     return read_rnglists (unit, arange, offset);
669081
 }
669081
 
669081
+static struct funcinfo *
669081
+lookup_func_by_offset (bfd_uint64_t offset, struct funcinfo * table)
669081
+{
669081
+  for (; table != NULL; table = table->prev_func)
669081
+    if (table->unit_offset == offset)
669081
+      return table;
669081
+  return NULL;
669081
+}
669081
+
669081
 static struct varinfo *
669081
 lookup_var_by_offset (bfd_uint64_t offset, struct varinfo * table)
669081
 {
669081
@@ -3317,6 +3328,35 @@ lookup_var_by_offset (bfd_uint64_t offse
669081
   return NULL;
669081
 }
669081
 
669081
+static struct funcinfo *
669081
+reverse_funcinfo_list (struct funcinfo * head)
669081
+{
669081
+  struct funcinfo * rhead;
669081
+  struct funcinfo * temp;
669081
+
669081
+  for (rhead = NULL; head; head = temp)
669081
+    {
669081
+      temp = head->prev_func;
669081
+      head->prev_func = rhead;
669081
+      rhead = head;
669081
+    }
669081
+  return rhead;
669081
+}
669081
+
669081
+static struct varinfo *
669081
+reverse_varinfo_list (struct varinfo * head)
669081
+{
669081
+  struct varinfo * rhead;
669081
+  struct varinfo * temp;
669081
+
669081
+  for (rhead = NULL; head; head = temp)
669081
+    {
669081
+      temp = head->prev_var;
669081
+      head->prev_var = rhead;
669081
+      rhead = head;
669081
+    }
669081
+  return rhead;
669081
+}
669081
 
669081
 /* DWARF2 Compilation unit functions.  */
669081
 
669081
@@ -3334,6 +3374,8 @@ scan_unit_for_symbols (struct comp_unit
669081
     struct funcinfo *func;
669081
   } *nested_funcs;
669081
   int nested_funcs_size;
669081
+  struct funcinfo *last_func;
669081
+  struct varinfo *last_var;
669081
 
669081
   /* Maintain a stack of in-scope functions and inlined functions, which we
669081
      can use to set the caller_func field.  */
669081
@@ -3344,16 +3386,16 @@ scan_unit_for_symbols (struct comp_unit
669081
     return FALSE;
669081
   nested_funcs[nesting_level].func = 0;
669081
 
669081
+  /* PR 27484: We must scan the DIEs twice.  The first time we look for
669081
+     function and variable tags and accumulate them into their respective
669081
+     tables.  The second time through we process the attributes of the
669081
+     functions/variables and augment the table entries.  */
669081
   while (nesting_level >= 0)
669081
     {
669081
       unsigned int abbrev_number, bytes_read, i;
669081
       struct abbrev_info *abbrev;
669081
-      struct attribute attr;
669081
       struct funcinfo *func;
669081
       struct varinfo *var;
669081
-      bfd_vma low_pc = 0;
669081
-      bfd_vma high_pc = 0;
669081
-      bfd_boolean high_pc_relative = FALSE;
669081
       bfd_uint64_t current_offset;
669081
 
669081
       /* PR 17512: file: 9f405d9d.  */
669081
@@ -3400,6 +3442,7 @@ scan_unit_for_symbols (struct comp_unit
669081
 	    goto fail;
669081
 	  func->tag = abbrev->tag;
669081
 	  func->prev_func = unit->function_table;
669081
+	  func->unit_offset = current_offset;
669081
 	  unit->function_table = func;
669081
 	  unit->number_of_functions++;
669081
 	  BFD_ASSERT (!unit->cached);
669081
@@ -3440,6 +3483,111 @@ scan_unit_for_symbols (struct comp_unit
669081
 
669081
       for (i = 0; i < abbrev->num_attrs; ++i)
669081
 	{
669081
+	  struct attribute attr;
669081
+
669081
+	  info_ptr = read_attribute (&attr, &abbrev->attrs[i],
669081
+				     unit, info_ptr, info_ptr_end);
669081
+	  if (info_ptr == NULL)
669081
+	    goto fail;
669081
+	}
669081
+
669081
+      if (abbrev->has_children)
669081
+	{
669081
+	  nesting_level++;
669081
+
669081
+	  if (nesting_level >= nested_funcs_size)
669081
+	    {
669081
+	      struct nest_funcinfo *tmp;
669081
+
669081
+	      nested_funcs_size *= 2;
669081
+	      tmp = (struct nest_funcinfo *)
669081
+		bfd_realloc (nested_funcs,
669081
+			     nested_funcs_size * sizeof (*nested_funcs));
669081
+	      if (tmp == NULL)
669081
+		goto fail;
669081
+	      nested_funcs = tmp;
669081
+	    }
669081
+	  nested_funcs[nesting_level].func = 0;
669081
+	}
669081
+    }
669081
+
669081
+  unit->function_table = reverse_funcinfo_list (unit->function_table);
669081
+  unit->variable_table = reverse_varinfo_list (unit->variable_table);
669081
+
669081
+  /* This is the second pass over the abbrevs.  */      
669081
+  info_ptr = unit->first_child_die_ptr;
669081
+  nesting_level = 0;
669081
+  
669081
+  last_func = NULL;
669081
+  last_var = NULL;
669081
+
669081
+  while (nesting_level >= 0)
669081
+    {
669081
+      unsigned int abbrev_number, bytes_read, i;
669081
+      struct abbrev_info *abbrev;
669081
+      struct attribute attr;
669081
+      struct funcinfo *func;
669081
+      struct varinfo *var;
669081
+      bfd_vma low_pc = 0;
669081
+      bfd_vma high_pc = 0;
669081
+      bfd_boolean high_pc_relative = FALSE;
669081
+      bfd_uint64_t current_offset;
669081
+
669081
+      /* PR 17512: file: 9f405d9d.  */
669081
+      if (info_ptr >= info_ptr_end)
669081
+	goto fail;
669081
+
669081
+      current_offset = info_ptr - unit->info_ptr_unit;
669081
+      abbrev_number = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
669081
+					     FALSE, info_ptr_end);
669081
+      info_ptr += bytes_read;
669081
+
669081
+      if (! abbrev_number)
669081
+	{
669081
+	  nesting_level--;
669081
+	  continue;
669081
+	}
669081
+
669081
+      abbrev = lookup_abbrev (abbrev_number, unit->abbrevs);
669081
+      /* This should have been handled above.  */
669081
+      BFD_ASSERT (abbrev != NULL);
669081
+
669081
+      func = NULL;
669081
+      var = NULL;
669081
+      if (abbrev->tag == DW_TAG_subprogram
669081
+	  || abbrev->tag == DW_TAG_entry_point
669081
+	  || abbrev->tag == DW_TAG_inlined_subroutine)
669081
+	{
669081
+	  if (last_func
669081
+	      && last_func->prev_func
669081
+	      && last_func->prev_func->unit_offset == current_offset)
669081
+	    func = last_func->prev_func;
669081
+	  else
669081
+	    func = lookup_func_by_offset (current_offset, unit->function_table);
669081
+
669081
+	  if (func == NULL)
669081
+	    goto fail;
669081
+
669081
+	  last_func = func;
669081
+	}
669081
+      else if (abbrev->tag == DW_TAG_variable
669081
+	       || abbrev->tag == DW_TAG_member)
669081
+	{
669081
+	  if (last_var
669081
+	      && last_var->prev_var
669081
+	      && last_var->prev_var->unit_offset == current_offset)
669081
+	    var = last_var->prev_var;
669081
+	  else
669081
+	    var = lookup_var_by_offset (current_offset, unit->variable_table);
669081
+
669081
+	  if (var == NULL)
669081
+	    goto fail;
669081
+
669081
+	  last_var = var;
669081
+	}
669081
+
669081
+      for (i = 0; i < abbrev->num_attrs; ++i)
669081
+	{
669081
 	  info_ptr = read_attribute (&attr, &abbrev->attrs[i],
669081
 				     unit, info_ptr, info_ptr_end);
669081
 	  if (info_ptr == NULL)
669081
@@ -3604,6 +3752,9 @@ scan_unit_for_symbols (struct comp_unit
669081
 	    }
669081
 	}
669081
 
669081
+      if (abbrev->has_children)
669081
+	nesting_level++;
669081
+
669081
       if (high_pc_relative)
669081
 	high_pc += low_pc;
669081
 
669081
@@ -3612,27 +3763,11 @@ scan_unit_for_symbols (struct comp_unit
669081
 	  if (!arange_add (unit, &func->arange, low_pc, high_pc))
669081
 	    goto fail;
669081
 	}
669081
-
669081
-      if (abbrev->has_children)
669081
-	{
669081
-	  nesting_level++;
669081
-
669081
-	  if (nesting_level >= nested_funcs_size)
669081
-	    {
669081
-	      struct nest_funcinfo *tmp;
669081
-
669081
-	      nested_funcs_size *= 2;
669081
-	      tmp = (struct nest_funcinfo *)
669081
-		bfd_realloc (nested_funcs,
669081
-			     nested_funcs_size * sizeof (*nested_funcs));
669081
-	      if (tmp == NULL)
669081
-		goto fail;
669081
-	      nested_funcs = tmp;
669081
-	    }
669081
-	  nested_funcs[nesting_level].func = 0;
669081
-	}
669081
     }
669081
 
669081
+  unit->function_table = reverse_funcinfo_list (unit->function_table);
669081
+  unit->variable_table = reverse_varinfo_list (unit->variable_table);
669081
+
669081
   free (nested_funcs);
669081
   return TRUE;
669081
 
669081
@@ -3994,36 +4129,6 @@ comp_unit_find_line (struct comp_unit *u
669081
 					  linenumber_ptr);
669081
 }
669081
 
669081
-static struct funcinfo *
669081
-reverse_funcinfo_list (struct funcinfo *head)
669081
-{
669081
-  struct funcinfo *rhead;
669081
-  struct funcinfo *temp;
669081
-
669081
-  for (rhead = NULL; head; head = temp)
669081
-    {
669081
-      temp = head->prev_func;
669081
-      head->prev_func = rhead;
669081
-      rhead = head;
669081
-    }
669081
-  return rhead;
669081
-}
669081
-
669081
-static struct varinfo *
669081
-reverse_varinfo_list (struct varinfo *head)
669081
-{
669081
-  struct varinfo *rhead;
669081
-  struct varinfo *temp;
669081
-
669081
-  for (rhead = NULL; head; head = temp)
669081
-    {
669081
-      temp = head->prev_var;
669081
-      head->prev_var = rhead;
669081
-      rhead = head;
669081
-    }
669081
-  return rhead;
669081
-}
669081
-
669081
 /* Extract all interesting funcinfos and varinfos of a compilation
669081
    unit into hash tables for faster lookup.  Returns TRUE if no
669081
    errors were enountered; FALSE otherwise.  */