Re: A hack for DW_FORM_ref_addr

H. J. Lu
2003-07-31T21:21:21Z

On Thu, Jul 31, 2003 at 02:22:19PM -0400, Daniel Jacobowitz wrote:
> On Thu, Jul 31, 2003 at 09:16:19AM -0700, H. J. Lu wrote:
> > On Wed, Jul 30, 2003 at 10:16:53PM -0700, H. J. Lu wrote:
> > > > >
> > > > > While waiting for your new DWARF reader, I will see how my hack
> > > > > goes :-(.
> > > >
> > > > Since the die table is hashed by offset (isn't it?), presumably very
> > > > badly.
> > >
> > > It is OK for different compilation units within the same .debug_info
> > > section.
> > >
> > >
> >
> > FYI, this is the hack I am going to try.
>
> It may be safe, but it's unacceptable. Take a look at the memory usage
> requirements for -readnow, if libc.so.6 has debugging information.
> You've just eaten probably 200MB of RAM.
>

FYI, this is my updated hack.

H.J.
---
2003-07-31 H.J. Lu <hongjiu.lu@intel.com>

* dwarf2read.c (die_info_list): New structure.
(need_preserve_die_ref_table): New.
(dwarf2_build_psymtabs_hard): Read in all compilation units.
Free die list die reference table is not needed.
(read_comp_unit): Reset die reference table if it is not needed
or abfd is changed
(read_attribute_value): Set need_preserve_die_ref_table to 1
for DW_FORM_ref_addr.

--- gdb/dwarf2read.c.ref_addr 2003-07-31 12:59:31.000000000 -0700
+++ gdb/dwarf2read.c 2003-07-31 14:03:10.000000000 -0700
@@ -325,6 +325,12 @@ struct die_info
struct type *type; /* Cached type information */
};

+struct die_info_list
+{
+ struct die_info *dies;
+ struct die_info_list *next;
+};
+
/* Attributes have a name and a value */
struct attribute
{
@@ -376,6 +382,7 @@ struct dwarf_block
#endif

static struct die_info *die_ref_table[REF_HASH_SIZE];
+static int need_preserve_die_ref_table = -1;

/* Obstack for allocating temporary storage used during symbol reading. */
static struct obstack dwarf2_tmp_obstack;
@@ -1195,6 +1202,8 @@ dwarf2_build_psymtabs_hard (struct objfi
struct partial_symtab *pst;
struct cleanup *back_to;
CORE_ADDR lowpc, highpc;
+ struct die_info *dies;
+ struct die_info_list *dies_list_head, *dies_list_p;

info_ptr = dwarf_info_buffer;
abbrev_ptr = dwarf_abbrev_buffer;
@@ -1230,6 +1239,13 @@ dwarf2_build_psymtabs_hard (struct objfi
obstack_init (&dwarf2_tmp_obstack);
back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);

+ need_preserve_die_ref_table = -1;
+ dies_list_head
+ = (struct die_info_list *) xmalloc (sizeof (struct die_info_list));
+ dies_list_head->dies = NULL;
+ dies_list_head->next = NULL;
+ dies_list_p = dies_list_head;
+
/* Since the objects we're extracting from dwarf_info_buffer vary in
length, only the individual functions to extract them (like
read_comp_unit_head and read_partial_die) can really know whether
@@ -1280,6 +1296,18 @@ dwarf2_build_psymtabs_hard (struct objfi
dwarf2_read_abbrevs (abfd, &cu_header);
make_cleanup (dwarf2_empty_abbrev_table, cu_header.dwarf2_abbrevs);

+ dies = read_comp_unit (info_ptr, abfd, &cu_header);
+ if (dies_list_p->dies != NULL)
+ {
+ struct die_info_list *p = (struct die_info_list *)
+ xmalloc (sizeof (struct die_info_list));
+
+ p->next = NULL;
+ dies_list_p->next = p;
+ dies_list_p = p;
+ }
+ dies_list_p->dies = dies;
+
/* Read the compilation unit die */
info_ptr = read_partial_die (&comp_unit_die, abfd, info_ptr,
&cu_header);
@@ -1349,6 +1377,22 @@ dwarf2_build_psymtabs_hard (struct objfi
info_ptr = beg_of_comp_unit + cu_header.length
+ cu_header.initial_length_size;
}
+
+ if (need_preserve_die_ref_table != 1)
+ {
+ struct die_info_list *next;
+
+ for (dies_list_p = dies_list_head; dies_list_p != NULL;
+ dies_list_p = next)
+ {
+ next = dies_list_p->next;
+ make_cleanup_free_die_list (dies_list_p->dies);
+ free (dies_list_p);
+ }
+
+ need_preserve_die_ref_table = 0;
+ }
+
do_cleanups (back_to);
}

@@ -3653,10 +3697,18 @@ read_comp_unit (char *info_ptr, bfd *abf
struct die_info *first_die, *last_die, *die;
char *cur_ptr;
int nesting_level;
+ static bfd *bfd_die_ref_table;

- /* Reset die reference table; we are
- building new ones now. */
- dwarf2_empty_hash_tables ();
+ if (!bfd_die_ref_table)
+ bfd_die_ref_table = abfd;
+
+ if (need_preserve_die_ref_table == 0
+ || bfd_die_ref_table != abfd)
+ {
+ bfd_die_ref_table = abfd;
+ /* Reset die reference table; we are building new ones now. */
+ dwarf2_empty_hash_tables ();
+ }

cur_ptr = info_ptr;
nesting_level = 0;
@@ -4080,8 +4132,9 @@ read_attribute_value (struct attribute *
attr->form = form;
switch (form)
{
- case DW_FORM_addr:
case DW_FORM_ref_addr:
+ need_preserve_die_ref_table = 1;
+ case DW_FORM_addr:
DW_ADDR (attr) = read_address (abfd, info_ptr, cu_header, &bytes_read);
info_ptr += bytes_read;
break;