125 lines
3.6 KiB
Diff
125 lines
3.6 KiB
Diff
diff -rup binutils.orig/bfd/dwarf2.c binutils-2.37/bfd/dwarf2.c
|
|
--- binutils.orig/bfd/dwarf2.c 2022-08-25 17:21:09.023295361 +0200
|
|
+++ binutils-2.37/bfd/dwarf2.c 2022-09-05 14:26:02.396271516 +0200
|
|
@@ -36,6 +36,7 @@
|
|
#include "elf-bfd.h"
|
|
#include "dwarf2.h"
|
|
#include "hashtab.h"
|
|
+#include "splay-tree.h"
|
|
|
|
/* The data in the .debug_line statement prologue looks like this. */
|
|
|
|
@@ -82,6 +83,45 @@ struct adjusted_section
|
|
bfd_vma adj_vma;
|
|
};
|
|
|
|
+struct addr_range
|
|
+{
|
|
+ bfd_byte *start;
|
|
+ bfd_byte *end;
|
|
+};
|
|
+
|
|
+/* Return true if address range do intersect. */
|
|
+
|
|
+static bool
|
|
+addr_range_intersects (struct addr_range *r1, struct addr_range *r2)
|
|
+{
|
|
+ return (r1->start <= r2->start && r2->start < r1->end)
|
|
+ || (r1->start <= (r2->end - 1) && (r2->end - 1) < r1->end);
|
|
+}
|
|
+
|
|
+/* Compare function for splay tree of addr_ranges. */
|
|
+
|
|
+static int
|
|
+splay_tree_compare_addr_range (splay_tree_key xa, splay_tree_key xb)
|
|
+{
|
|
+ struct addr_range *r1 = (struct addr_range *) xa;
|
|
+ struct addr_range *r2 = (struct addr_range *) xb;
|
|
+
|
|
+ if (addr_range_intersects (r1, r2) || addr_range_intersects (r2, r1))
|
|
+ return 0;
|
|
+ else if (r1->end <= r2->start)
|
|
+ return -1;
|
|
+ else
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+/* Splay tree release function for keys (addr_range). */
|
|
+
|
|
+static void
|
|
+splay_tree_free_addr_range (splay_tree_key key)
|
|
+{
|
|
+ free ((struct addr_range *)key);
|
|
+}
|
|
+
|
|
struct dwarf2_debug_file
|
|
{
|
|
/* The actual bfd from which debug info was loaded. Might be
|
|
@@ -147,6 +187,9 @@ struct dwarf2_debug_file
|
|
|
|
/* Hash table to map offsets to decoded abbrevs. */
|
|
htab_t abbrev_offsets;
|
|
+
|
|
+ /* Splay tree to map info_ptr address to compilation units. */
|
|
+ splay_tree comp_unit_tree;
|
|
};
|
|
|
|
struct dwarf2_debug
|
|
@@ -2948,16 +2991,12 @@ find_abstract_instance (struct comp_unit
|
|
else
|
|
{
|
|
/* Check other CUs to see if they contain the abbrev. */
|
|
- struct comp_unit *u;
|
|
-
|
|
- for (u = unit->prev_unit; u != NULL; u = u->prev_unit)
|
|
- if (info_ptr >= u->info_ptr_unit && info_ptr < u->end_ptr)
|
|
- break;
|
|
-
|
|
- if (u == NULL)
|
|
- for (u = unit->next_unit; u != NULL; u = u->next_unit)
|
|
- if (info_ptr >= u->info_ptr_unit && info_ptr < u->end_ptr)
|
|
- break;
|
|
+ struct comp_unit *u = NULL;
|
|
+ struct addr_range range = { info_ptr, info_ptr };
|
|
+ splay_tree_node v = splay_tree_lookup (unit->file->comp_unit_tree,
|
|
+ (splay_tree_key)&range);
|
|
+ if (v != NULL)
|
|
+ u = (struct comp_unit *)v->value;
|
|
|
|
if (attr_ptr->form == DW_FORM_ref_addr)
|
|
while (u == NULL)
|
|
@@ -4837,6 +4876,22 @@ stash_comp_unit (struct dwarf2_debug *st
|
|
info_ptr_unit, offset_size);
|
|
if (each)
|
|
{
|
|
+ if (file->comp_unit_tree == NULL)
|
|
+ file->comp_unit_tree
|
|
+ = splay_tree_new (splay_tree_compare_addr_range,
|
|
+ splay_tree_free_addr_range, NULL);
|
|
+
|
|
+ struct addr_range *r
|
|
+ = (struct addr_range *)bfd_malloc (sizeof (struct addr_range));
|
|
+ r->start = each->info_ptr_unit;
|
|
+ r->end = each->end_ptr;
|
|
+ splay_tree_node v = splay_tree_lookup (file->comp_unit_tree,
|
|
+ (splay_tree_key)r);
|
|
+ if (v != NULL || r->end <= r->start)
|
|
+ abort ();
|
|
+ splay_tree_insert (file->comp_unit_tree, (splay_tree_key)r,
|
|
+ (splay_tree_value)each);
|
|
+
|
|
if (file->all_comp_units)
|
|
file->all_comp_units->prev_unit = each;
|
|
else
|
|
@@ -5288,6 +5343,8 @@ _bfd_dwarf2_cleanup_debug_info (bfd *abf
|
|
free (file->line_table->dirs);
|
|
}
|
|
htab_delete (file->abbrev_offsets);
|
|
+ if (file->comp_unit_tree != NULL)
|
|
+ splay_tree_delete (file->comp_unit_tree);
|
|
|
|
free (file->dwarf_line_str_buffer);
|
|
free (file->dwarf_str_buffer);
|
|
Only in binutils-2.37/bfd: dwarf2.c.orig
|
|
Only in binutils-2.37/bfd: dwarf2.c.rej
|