This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Support for multiple DWARF comp unit headers


I think this patch is too big to review in one gulp.  Could you break
this up into a succession of smaller patches?  For example, moving the
abbrev tables into the CU header structure could be the first patch;
making it possible to have more than one CU read in at a time would be
the next (even though no code would use more than one yet); and adding
support for DW_FORM_ref_addr could be the last.  Perhaps you can see
finer divisions to make; the finer you can get them, the better.

Why does build_die_ref reject the result from follow_die_ref when its
type isn't filled in?  If the DIE being referred to doesn't represent
a type, won't this cause it to be re-read unnecessarily?

What happens if we hit a DW_FORM_ref_addr pointing to a DIE, and then
later hit a DW_FORM_ref_addr pointing to one of its parents?  Won't we
end up calling find_die_ref twice, and adding the dies in the first
tree to the reference hash table twice?

Just out of curiosity --- after we've built `struct die_info' objects
for a CU, we don't need the abbrev table any more, do we?  I may be
misremembering the way the code behaves, but it seems to me that one
could construct an abbrev table before calling read_comp_unit, and
then throw it away when done.  Perhaps the abbrev tables are not big
enough for this to be worth thinking about.





Petr Sorfa <petrs@caldera.com> writes:

> Hi,
> 
> Patch for supporting multiple DWARF comp unit headers. This is necessary
> for supporting DW_FORM_ref_addr properly when the reference is to a
> compilation unit outside of the current one. The current code only
> supports one comp unit at a time.
> 
> 2002-07-03 Petr Sorfa (petrs@caldera.com)
> 
>         * dwarf2read.c (build_die_ref): New function that builds
>           a new die reference if necessary, will search across
>           multiple comp units to find the reference.
>           (find_die_ref): New function that searches for a die
>           reference for a given comp unit.
>           (find_cu_header_from_begin_offset): New function that
>           searches through a link list of comp unit headers for
>           a comp unit that matches the given offset.
>           (register_cu_header): New function that registers a
>           comp unit header by allocating space for it and
>           adding it to the comp unit header list.
>           (free_cu_header_list): New function that frees up the
>           memory taken up by the list of comp unit headers
>           associated with a process.
>           (dwarf_new_init): New function that initializes DWARF
>           information for a new process.
>           (struct comp_unit_head): Adds several new members
>           to contain fully all the comp unit head's info.
>           (first_cu_header): A new global variable that points
>           to the first comp unit head for the process.
>           (cu_header_offset): Global variable removed, as is now
>           present in each comp unit head.
>           (dwarf_abbrevs): Global variable removed, as is now
>           present in each comp unit head.
>           (dwarf2_read_abbrevs):
>           (dwarf2_empty_abbrev_table):
>           (dwarf2_lookup_abbrev):
>           (dwarf_attr):
>           (die_is_declaration):
>           (read_base_type):
>           (dwarf2_get_pc_bounds):
>           (read_tag_string_type):
>           (dwarf2_linkage_name):
>           (dwarf2_get_ref_die_offset):
>           All of these functions have a new argument added to
>           pass the current comp unit header. All calls to these
>           functions have been updated to handle the additional
>           argument.
> 
>         * elfread.c (elf_new_init): Now calls dwarf_new_init()
>           to initialize DWARF related information for the
>           new process.? err
> ? 1
> Index: dwarf2read.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/dwarf2read.c,v
> retrieving revision 1.60
> diff -c -p -r1.60 dwarf2read.c
> *** dwarf2read.c	22 Jun 2002 00:05:59 -0000	1.60
> --- dwarf2read.c	3 Jul 2002 20:35:37 -0000
> *************** unsigned int dwarf_eh_frame_size;
> *** 162,167 ****
> --- 162,172 ----
>   
>   /* local data types */
>   
> + /* We hold several abbreviation tables at the same time in memory */
> + #ifndef ABBREV_HASH_SIZE
> + #define ABBREV_HASH_SIZE 121
> + #endif
> + 
>   /* The data in a compilation unit header, after target2host
>      translation, looks like this.  */
>   struct comp_unit_head
> *************** struct comp_unit_head
> *** 174,179 ****
> --- 179,193 ----
>       unsigned int offset_size;	/* size of file offsets; either 4 or 8 */
>       unsigned int initial_length_size; /* size of the length field; either
>                                            4 or 12 */
> +     /* New information for the comp unit head so as to keep a list
> +        of available ones for a program. */
> +     unsigned int offset; /* Offset of the cu_header in .debug_info */
> +     char *base_offset; /* Base offset after cu_header into program */
> +     char *begin_offset; /* Base offset of cu_header into program */
> +     struct comp_unit_head *next; /* Next comp unit head in program */
> + 
> +     struct abbrev_info *dwarf2_abbrevs[ABBREV_HASH_SIZE]; /* DWARF abbrev
> +                                                                table */
>     };
>   
>   /* The line number information for a compilation unit (found in the
> *************** struct dwarf_block
> *** 312,327 ****
>       char *data;
>     };
>   
> - /* We only hold one compilation unit's abbrevs in
> -    memory at any one time.  */
> - #ifndef ABBREV_HASH_SIZE
> - #define ABBREV_HASH_SIZE 121
> - #endif
>   #ifndef ATTR_ALLOC_CHUNK
>   #define ATTR_ALLOC_CHUNK 4
>   #endif
>   
> ! static struct abbrev_info *dwarf2_abbrevs[ABBREV_HASH_SIZE];
>   
>   /* A hash table of die offsets for following references.  */
>   #ifndef REF_HASH_SIZE
> --- 326,337 ----
>       char *data;
>     };
>   
>   #ifndef ATTR_ALLOC_CHUNK
>   #define ATTR_ALLOC_CHUNK 4
>   #endif
>   
> ! /* First comp unit head in the program */
> ! struct comp_unit_head *first_cu_header = NULL;
>   
>   /* A hash table of die offsets for following references.  */
>   #ifndef REF_HASH_SIZE
> *************** static struct die_info *die_ref_table[RE
> *** 333,342 ****
>   /* Obstack for allocating temporary storage used during symbol reading.  */
>   static struct obstack dwarf2_tmp_obstack;
>   
> - /* Offset to the first byte of the current compilation unit header,
> -    for resolving relative reference dies. */
> - static unsigned int cu_header_offset;
> - 
>   /* Allocate fields for structs, unions and enums in this size.  */
>   #ifndef DW_FIELD_ALLOC_CHUNK
>   #define DW_FIELD_ALLOC_CHUNK 4
> --- 343,348 ----
> *************** static void psymtab_to_symtab_1 (struct 
> *** 682,692 ****
>   
>   char *dwarf2_read_section (struct objfile *, file_ptr, unsigned int);
>   
> ! static void dwarf2_read_abbrevs (bfd *, unsigned int);
>   
> ! static void dwarf2_empty_abbrev_table (PTR);
>   
> ! static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int);
>   
>   static char *read_partial_die (struct partial_die_info *,
>   			       bfd *, char *,
> --- 688,699 ----
>   
>   char *dwarf2_read_section (struct objfile *, file_ptr, unsigned int);
>   
> ! static void dwarf2_read_abbrevs (bfd *abfd, struct comp_unit_head *cu_header);
>   
> ! static void dwarf2_empty_abbrev_table (struct comp_unit_head *cu_header);
>   
> ! static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int,
> !                                          const struct comp_unit_head *cu_header);
>   
>   static char *read_partial_die (struct partial_die_info *,
>   			       bfd *, char *,
> *************** static long read_signed_leb128 (bfd *, c
> *** 733,741 ****
>   
>   static void set_cu_language (unsigned int);
>   
> ! static struct attribute *dwarf_attr (struct die_info *, unsigned int);
>   
> ! static int die_is_declaration (struct die_info *);
>   
>   static void free_line_header (struct line_header *lh);
>   
> --- 740,750 ----
>   
>   static void set_cu_language (unsigned int);
>   
> ! static struct attribute *dwarf_attr (struct die_info *, unsigned int,
> !                                      const struct comp_unit_head *);
>   
> ! static int die_is_declaration (struct die_info *,
> !                                const struct comp_unit_head *);
>   
>   static void free_line_header (struct line_header *lh);
>   
> *************** static void read_type_die (struct die_in
> *** 778,784 ****
>   static void read_typedef (struct die_info *, struct objfile *,
>   			  const struct comp_unit_head *);
>   
> ! static void read_base_type (struct die_info *, struct objfile *);
>   
>   static void read_file_scope (struct die_info *, struct objfile *,
>   			     const struct comp_unit_head *);
> --- 787,794 ----
>   static void read_typedef (struct die_info *, struct objfile *,
>   			  const struct comp_unit_head *);
>   
> ! static void read_base_type (struct die_info *, struct objfile *,
> !                             const struct comp_unit_head *);
>   
>   static void read_file_scope (struct die_info *, struct objfile *,
>   			     const struct comp_unit_head *);
> *************** static void read_lexical_block_scope (st
> *** 790,796 ****
>   				      const struct comp_unit_head *);
>   
>   static int dwarf2_get_pc_bounds (struct die_info *,
> ! 				 CORE_ADDR *, CORE_ADDR *, struct objfile *);
>   
>   static void dwarf2_add_field (struct field_info *, struct die_info *,
>   			      struct objfile *, const struct comp_unit_head *);
> --- 800,807 ----
>   				      const struct comp_unit_head *);
>   
>   static int dwarf2_get_pc_bounds (struct die_info *,
> ! 				 CORE_ADDR *, CORE_ADDR *, struct objfile *,
> !                                  const struct comp_unit_head *);
>   
>   static void dwarf2_add_field (struct field_info *, struct die_info *,
>   			      struct objfile *, const struct comp_unit_head *);
> *************** static void read_tag_const_type (struct 
> *** 837,843 ****
>   static void read_tag_volatile_type (struct die_info *, struct objfile *,
>   				    const struct comp_unit_head *);
>   
> ! static void read_tag_string_type (struct die_info *, struct objfile *);
>   
>   static void read_subroutine_type (struct die_info *, struct objfile *,
>   				  const struct comp_unit_head *);
> --- 848,855 ----
>   static void read_tag_volatile_type (struct die_info *, struct objfile *,
>   				    const struct comp_unit_head *);
>   
> ! static void read_tag_string_type (struct die_info *, struct objfile *,
> ! 				    const struct comp_unit_head *);
>   
>   static void read_subroutine_type (struct die_info *, struct objfile *,
>   				  const struct comp_unit_head *);
> *************** static struct cleanup *make_cleanup_free
> *** 852,858 ****
>   static void process_die (struct die_info *, struct objfile *,
>   			 const struct comp_unit_head *);
>   
> ! static char *dwarf2_linkage_name (struct die_info *);
>   
>   static char *dwarf_tag_name (unsigned int);
>   
> --- 864,871 ----
>   static void process_die (struct die_info *, struct objfile *,
>   			 const struct comp_unit_head *);
>   
> ! static char *dwarf2_linkage_name (struct die_info *,
> !                                   const struct comp_unit_head *);
>   
>   static char *dwarf_tag_name (unsigned int);
>   
> *************** static void store_in_ref_table (unsigned
> *** 882,893 ****
>   
>   static void dwarf2_empty_hash_tables (void);
>   
> ! static unsigned int dwarf2_get_ref_die_offset (struct attribute *);
>   
>   static struct die_info *follow_die_ref (unsigned int);
>   
>   static struct type *dwarf2_fundamental_type (struct objfile *, int);
>   
>   /* memory allocation interface */
>   
>   static void dwarf2_free_tmp_obstack (PTR);
> --- 895,917 ----
>   
>   static void dwarf2_empty_hash_tables (void);
>   
> ! static unsigned int dwarf2_get_ref_die_offset (struct attribute *,
> !                                                const struct comp_unit_head *);
>   
>   static struct die_info *follow_die_ref (unsigned int);
>   
>   static struct type *dwarf2_fundamental_type (struct objfile *, int);
>   
> + static struct die_info *build_die_ref (struct attribute *, struct objfile *,
> +                                         const struct comp_unit_head *);
> + static struct die_info *find_die_ref (unsigned int target_offset, bfd *abfd,
> +                                       const struct comp_unit_head *cu_header);
> + static struct comp_unit_head *find_cu_header_from_begin_offset (char *);
> + static struct comp_unit_head *find_cu_header (unsigned int);
> + static void register_cu_header (const struct comp_unit_head *);
> + static void free_cu_header_list (void);
> + void dwarf_new_init (void);
> + 
>   /* memory allocation interface */
>   
>   static void dwarf2_free_tmp_obstack (PTR);
> *************** static void dwarf_decode_macros (struct 
> *** 906,911 ****
> --- 930,942 ----
>                                    char *, bfd *, const struct comp_unit_head *,
>                                    struct objfile *);
>   
> + /* Initialize DWARF environment for new binary */
> + void
> + dwarf_new_init (void)
> + {
> +   free_cu_header_list ();
> + }
> + 
>   /* Try to locate the sections we need for DWARF 2 debugging
>      information and return true if we have enough to do something.  */
>   
> *************** dwarf2_build_psymtabs_hard (struct objfi
> *** 1201,1208 ****
>   	  return;
>   	}
>         /* Read the abbrevs for this compilation unit into a table */
> !       dwarf2_read_abbrevs (abfd, cu_header.abbrev_offset);
> !       make_cleanup (dwarf2_empty_abbrev_table, NULL);
>   
>         /* Read the compilation unit die */
>         info_ptr = read_partial_die (&comp_unit_die, abfd, info_ptr,
> --- 1232,1244 ----
>   	  return;
>   	}
>         /* Read the abbrevs for this compilation unit into a table */
> !       dwarf2_read_abbrevs (abfd, &cu_header);
> ! 
> !       cu_header.offset = beg_of_comp_unit - dwarf_info_buffer;
> !       cu_header.base_offset = info_ptr;
> !       cu_header.begin_offset = beg_of_comp_unit;
> ! 
> !       register_cu_header (&cu_header);
>   
>         /* Read the compilation unit die */
>         info_ptr = read_partial_die (&comp_unit_die, abfd, info_ptr,
> *************** dwarf2_build_psymtabs_hard (struct objfi
> *** 1220,1226 ****
>   
>         pst->read_symtab_private = (char *)
>   	obstack_alloc (&objfile->psymbol_obstack, sizeof (struct dwarf2_pinfo));
> !       cu_header_offset = beg_of_comp_unit - dwarf_info_buffer;
>         DWARF_INFO_BUFFER (pst) = dwarf_info_buffer;
>         DWARF_INFO_OFFSET (pst) = beg_of_comp_unit - dwarf_info_buffer;
>         DWARF_ABBREV_BUFFER (pst) = dwarf_abbrev_buffer;
> --- 1256,1262 ----
>   
>         pst->read_symtab_private = (char *)
>   	obstack_alloc (&objfile->psymbol_obstack, sizeof (struct dwarf2_pinfo));
> ! 
>         DWARF_INFO_BUFFER (pst) = dwarf_info_buffer;
>         DWARF_INFO_OFFSET (pst) = beg_of_comp_unit - dwarf_info_buffer;
>         DWARF_ABBREV_BUFFER (pst) = dwarf_abbrev_buffer;
> *************** psymtab_to_symtab_1 (struct partial_symt
> *** 1515,1521 ****
>   {
>     struct objfile *objfile = pst->objfile;
>     bfd *abfd = objfile->obfd;
> !   struct comp_unit_head cu_header;
>     struct die_info *dies;
>     unsigned long offset;
>     CORE_ADDR lowpc, highpc;
> --- 1551,1557 ----
>   {
>     struct objfile *objfile = pst->objfile;
>     bfd *abfd = objfile->obfd;
> !   struct comp_unit_head *cu_header;
>     struct die_info *dies;
>     unsigned long offset;
>     CORE_ADDR lowpc, highpc;
> *************** psymtab_to_symtab_1 (struct partial_symt
> *** 1536,1542 ****
>     dwarf_macinfo_buffer = DWARF_MACINFO_BUFFER (pst);
>     dwarf_macinfo_size = DWARF_MACINFO_SIZE (pst);
>     baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile));
> -   cu_header_offset = offset;
>     info_ptr = dwarf_info_buffer + offset;
>   
>     obstack_init (&dwarf2_tmp_obstack);
> --- 1572,1577 ----
> *************** psymtab_to_symtab_1 (struct partial_symt
> *** 1545,1565 ****
>     buildsym_init ();
>     make_cleanup (really_free_pendings, NULL);
>   
> !   /* read in the comp_unit header  */
> !   info_ptr = read_comp_unit_head (&cu_header, info_ptr, abfd);
>   
> !   /* Read the abbrevs for this compilation unit  */
> !   dwarf2_read_abbrevs (abfd, cu_header.abbrev_offset);
> !   make_cleanup (dwarf2_empty_abbrev_table, NULL);
>   
> !   dies = read_comp_unit (info_ptr, abfd, &cu_header);
>   
>     make_cleanup_free_die_list (dies);
>   
>     /* Do line number decoding in read_file_scope () */
> !   process_die (dies, objfile, &cu_header);
>   
> !   if (!dwarf2_get_pc_bounds (dies, &lowpc, &highpc, objfile))
>       {
>         /* Some compilers don't define a DW_AT_high_pc attribute for
>            the compilation unit.   If the DW_AT_high_pc is missing,
> --- 1580,1603 ----
>     buildsym_init ();
>     make_cleanup (really_free_pendings, NULL);
>   
> !   cu_header = find_cu_header_from_begin_offset (info_ptr);
> ! 
> !   if (cu_header == NULL)
> !     {
> !       error ("Failed to find cu_header at base offset[0x%lx]\n", info_ptr);
> !     }
>   
> !   /* Update the info ptr */
> !   info_ptr = cu_header->base_offset;
>   
> !   dies = read_comp_unit (info_ptr, abfd, cu_header);
>   
>     make_cleanup_free_die_list (dies);
>   
>     /* Do line number decoding in read_file_scope () */
> !   process_die (dies, objfile, cu_header);
>   
> !   if (!dwarf2_get_pc_bounds (dies, &lowpc, &highpc, objfile, cu_header))
>       {
>         /* Some compilers don't define a DW_AT_high_pc attribute for
>            the compilation unit.   If the DW_AT_high_pc is missing,
> *************** psymtab_to_symtab_1 (struct partial_symt
> *** 1574,1580 ****
>   		{
>   		  CORE_ADDR low, high;
>   
> ! 		  if (dwarf2_get_pc_bounds (child_die, &low, &high, objfile))
>   		    {
>   		      highpc = max (highpc, high);
>   		    }
> --- 1612,1619 ----
>   		{
>   		  CORE_ADDR low, high;
>   
> ! 		  if (dwarf2_get_pc_bounds (child_die, &low, &high, objfile,
> !                                             cu_header))
>   		    {
>   		      highpc = max (highpc, high);
>   		    }
> *************** process_die (struct die_info *die, struc
> *** 1649,1659 ****
>         read_tag_reference_type (die, objfile, cu_header);
>         break;
>       case DW_TAG_string_type:
> !       read_tag_string_type (die, objfile);
>         break;
>       case DW_TAG_base_type:
> !       read_base_type (die, objfile);
> !       if (dwarf_attr (die, DW_AT_name))
>   	{
>   	  /* Add a typedef symbol for the base type definition.  */
>   	  new_symbol (die, die->type, objfile, cu_header);
> --- 1688,1698 ----
>         read_tag_reference_type (die, objfile, cu_header);
>         break;
>       case DW_TAG_string_type:
> !       read_tag_string_type (die, objfile, cu_header);
>         break;
>       case DW_TAG_base_type:
> !       read_base_type (die, objfile, cu_header);
> !       if (dwarf_attr (die, DW_AT_name, cu_header))
>   	{
>   	  /* Add a typedef symbol for the base type definition.  */
>   	  new_symbol (die, die->type, objfile, cu_header);
> *************** read_file_scope (struct die_info *die, s
> *** 1690,1696 ****
>     bfd *abfd = objfile->obfd;
>     struct line_header *line_header = 0;
>   
> !   if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
>       {
>         if (die->has_children)
>   	{
> --- 1729,1735 ----
>     bfd *abfd = objfile->obfd;
>     struct line_header *line_header = 0;
>   
> !   if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile, cu_header))
>       {
>         if (die->has_children)
>   	{
> *************** read_file_scope (struct die_info *die, s
> *** 1701,1707 ****
>   		{
>   		  CORE_ADDR low, high;
>   
> ! 		  if (dwarf2_get_pc_bounds (child_die, &low, &high, objfile))
>   		    {
>   		      lowpc = min (lowpc, low);
>   		      highpc = max (highpc, high);
> --- 1740,1747 ----
>   		{
>   		  CORE_ADDR low, high;
>   
> ! 		  if (dwarf2_get_pc_bounds (child_die, &low, &high, objfile,
> !                                             cu_header))
>   		    {
>   		      lowpc = min (lowpc, low);
>   		      highpc = max (highpc, high);
> *************** read_file_scope (struct die_info *die, s
> *** 1719,1730 ****
>     lowpc += baseaddr;
>     highpc += baseaddr;
>   
> !   attr = dwarf_attr (die, DW_AT_name);
>     if (attr)
>       {
>         name = DW_STRING (attr);
>       }
> !   attr = dwarf_attr (die, DW_AT_comp_dir);
>     if (attr)
>       {
>         comp_dir = DW_STRING (attr);
> --- 1759,1770 ----
>     lowpc += baseaddr;
>     highpc += baseaddr;
>   
> !   attr = dwarf_attr (die, DW_AT_name, cu_header);
>     if (attr)
>       {
>         name = DW_STRING (attr);
>       }
> !   attr = dwarf_attr (die, DW_AT_comp_dir, cu_header);
>     if (attr)
>       {
>         comp_dir = DW_STRING (attr);
> *************** read_file_scope (struct die_info *die, s
> *** 1746,1752 ****
>         objfile->ei.entry_file_highpc = highpc;
>       }
>   
> !   attr = dwarf_attr (die, DW_AT_language);
>     if (attr)
>       {
>         set_cu_language (DW_UNSND (attr));
> --- 1786,1792 ----
>         objfile->ei.entry_file_highpc = highpc;
>       }
>   
> !   attr = dwarf_attr (die, DW_AT_language, cu_header);
>     if (attr)
>       {
>         set_cu_language (DW_UNSND (attr));
> *************** read_file_scope (struct die_info *die, s
> *** 1783,1789 ****
>       }
>   
>     /* Decode line number information if present.  */
> !   attr = dwarf_attr (die, DW_AT_stmt_list);
>     if (attr)
>       {
>         unsigned int line_offset = DW_UNSND (attr);
> --- 1823,1829 ----
>       }
>   
>     /* Decode line number information if present.  */
> !   attr = dwarf_attr (die, DW_AT_stmt_list, cu_header);
>     if (attr)
>       {
>         unsigned int line_offset = DW_UNSND (attr);
> *************** read_file_scope (struct die_info *die, s
> *** 1801,1807 ****
>        refers to information in the line number info statement program
>        header, so we can only read it if we've read the header
>        successfully.  */
> !   attr = dwarf_attr (die, DW_AT_macro_info);
>     if (attr)
>       {
>         unsigned int macro_offset = DW_UNSND (attr);
> --- 1841,1847 ----
>        refers to information in the line number info statement program
>        header, so we can only read it if we've read the header
>        successfully.  */
> !   attr = dwarf_attr (die, DW_AT_macro_info, cu_header);
>     if (attr)
>       {
>         unsigned int macro_offset = DW_UNSND (attr);
> *************** read_func_scope (struct die_info *die, s
> *** 1843,1853 ****
>     struct attribute *attr;
>     char *name;
>   
> !   name = dwarf2_linkage_name (die);
>   
>     /* Ignore functions with missing or empty names and functions with
>        missing or invalid low and high pc attributes.  */
> !   if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
>       return;
>   
>     lowpc += baseaddr;
> --- 1883,1894 ----
>     struct attribute *attr;
>     char *name;
>   
> !   name = dwarf2_linkage_name (die, cu_header);
>   
>     /* Ignore functions with missing or empty names and functions with
>        missing or invalid low and high pc attributes.  */
> !   if (name == NULL ||
> !       !dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile, cu_header))
>       return;
>   
>     lowpc += baseaddr;
> *************** read_func_scope (struct die_info *die, s
> *** 1867,1873 ****
>        for DW_OP_fbreg operands in decode_locdesc.  */
>     frame_base_reg = -1;
>     frame_base_offset = 0;
> !   attr = dwarf_attr (die, DW_AT_frame_base);
>     if (attr)
>       {
>         CORE_ADDR addr = decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
> --- 1908,1914 ----
>        for DW_OP_fbreg operands in decode_locdesc.  */
>     frame_base_reg = -1;
>     frame_base_offset = 0;
> !   attr = dwarf_attr (die, DW_AT_frame_base, cu_header);
>     if (attr)
>       {
>         CORE_ADDR addr = decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
> *************** read_lexical_block_scope (struct die_inf
> *** 1917,1923 ****
>     struct die_info *child_die;
>   
>     /* Ignore blocks with missing or invalid low and high pc attributes.  */
> !   if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
>       return;
>     lowpc += baseaddr;
>     highpc += baseaddr;
> --- 1958,1964 ----
>     struct die_info *child_die;
>   
>     /* Ignore blocks with missing or invalid low and high pc attributes.  */
> !   if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile, cu_header))
>       return;
>     lowpc += baseaddr;
>     highpc += baseaddr;
> *************** read_lexical_block_scope (struct die_inf
> *** 1947,1964 ****
>   
>   static int
>   dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, CORE_ADDR *highpc,
> ! 		      struct objfile *objfile)
>   {
>     struct attribute *attr;
>     CORE_ADDR low;
>     CORE_ADDR high;
>   
> !   attr = dwarf_attr (die, DW_AT_low_pc);
>     if (attr)
>       low = DW_ADDR (attr);
>     else
>       return 0;
> !   attr = dwarf_attr (die, DW_AT_high_pc);
>     if (attr)
>       high = DW_ADDR (attr);
>     else
> --- 1988,2006 ----
>   
>   static int
>   dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, CORE_ADDR *highpc,
> ! 		      struct objfile *objfile,
> !                       const struct comp_unit_head *cu_header)
>   {
>     struct attribute *attr;
>     CORE_ADDR low;
>     CORE_ADDR high;
>   
> !   attr = dwarf_attr (die, DW_AT_low_pc, cu_header);
>     if (attr)
>       low = DW_ADDR (attr);
>     else
>       return 0;
> !   attr = dwarf_attr (die, DW_AT_high_pc, cu_header);
>     if (attr)
>       high = DW_ADDR (attr);
>     else
> *************** dwarf2_add_field (struct field_info *fip
> *** 2012,2023 ****
>       new_field->accessibility = DW_ACCESS_private;
>     new_field->virtuality = DW_VIRTUALITY_none;
>   
> !   attr = dwarf_attr (die, DW_AT_accessibility);
>     if (attr)
>       new_field->accessibility = DW_UNSND (attr);
>     if (new_field->accessibility != DW_ACCESS_public)
>       fip->non_public_fields = 1;
> !   attr = dwarf_attr (die, DW_AT_virtuality);
>     if (attr)
>       new_field->virtuality = DW_UNSND (attr);
>   
> --- 2054,2065 ----
>       new_field->accessibility = DW_ACCESS_private;
>     new_field->virtuality = DW_VIRTUALITY_none;
>   
> !   attr = dwarf_attr (die, DW_AT_accessibility, cu_header);
>     if (attr)
>       new_field->accessibility = DW_UNSND (attr);
>     if (new_field->accessibility != DW_ACCESS_public)
>       fip->non_public_fields = 1;
> !   attr = dwarf_attr (die, DW_AT_virtuality, cu_header);
>     if (attr)
>       new_field->virtuality = DW_UNSND (attr);
>   
> *************** dwarf2_add_field (struct field_info *fip
> *** 2028,2034 ****
>         fp->type = die_type (die, objfile, cu_header);
>   
>         /* Get bit size of field (zero if none).  */
> !       attr = dwarf_attr (die, DW_AT_bit_size);
>         if (attr)
>   	{
>   	  FIELD_BITSIZE (*fp) = DW_UNSND (attr);
> --- 2070,2076 ----
>         fp->type = die_type (die, objfile, cu_header);
>   
>         /* Get bit size of field (zero if none).  */
> !       attr = dwarf_attr (die, DW_AT_bit_size, cu_header);
>         if (attr)
>   	{
>   	  FIELD_BITSIZE (*fp) = DW_UNSND (attr);
> *************** dwarf2_add_field (struct field_info *fip
> *** 2039,2045 ****
>   	}
>   
>         /* Get bit offset of field.  */
> !       attr = dwarf_attr (die, DW_AT_data_member_location);
>         if (attr)
>   	{
>   	  FIELD_BITPOS (*fp) =
> --- 2081,2087 ----
>   	}
>   
>         /* Get bit offset of field.  */
> !       attr = dwarf_attr (die, DW_AT_data_member_location, cu_header);
>         if (attr)
>   	{
>   	  FIELD_BITPOS (*fp) =
> *************** dwarf2_add_field (struct field_info *fip
> *** 2047,2053 ****
>   	}
>         else
>   	FIELD_BITPOS (*fp) = 0;
> !       attr = dwarf_attr (die, DW_AT_bit_offset);
>         if (attr)
>   	{
>   	  if (BITS_BIG_ENDIAN)
> --- 2089,2095 ----
>   	}
>         else
>   	FIELD_BITPOS (*fp) = 0;
> !       attr = dwarf_attr (die, DW_AT_bit_offset, cu_header);
>         if (attr)
>   	{
>   	  if (BITS_BIG_ENDIAN)
> *************** dwarf2_add_field (struct field_info *fip
> *** 2070,2076 ****
>   	      int anonymous_size;
>   	      int bit_offset = DW_UNSND (attr);
>   
> ! 	      attr = dwarf_attr (die, DW_AT_byte_size);
>   	      if (attr)
>   		{
>   		  /* The size of the anonymous object containing
> --- 2112,2118 ----
>   	      int anonymous_size;
>   	      int bit_offset = DW_UNSND (attr);
>   
> ! 	      attr = dwarf_attr (die, DW_AT_byte_size, cu_header);
>   	      if (attr)
>   		{
>   		  /* The size of the anonymous object containing
> *************** dwarf2_add_field (struct field_info *fip
> *** 2092,2098 ****
>   	}
>   
>         /* Get name of field.  */
> !       attr = dwarf_attr (die, DW_AT_name);
>         if (attr && DW_STRING (attr))
>   	fieldname = DW_STRING (attr);
>         fp->name = obsavestring (fieldname, strlen (fieldname),
> --- 2134,2140 ----
>   	}
>   
>         /* Get name of field.  */
> !       attr = dwarf_attr (die, DW_AT_name, cu_header);
>         if (attr && DW_STRING (attr))
>   	fieldname = DW_STRING (attr);
>         fp->name = obsavestring (fieldname, strlen (fieldname),
> *************** dwarf2_add_field (struct field_info *fip
> *** 2100,2106 ****
>   
>         /* Change accessibility for artificial fields (e.g. virtual table
>            pointer or virtual base class pointer) to private.  */
> !       if (dwarf_attr (die, DW_AT_artificial))
>   	{
>   	  new_field->accessibility = DW_ACCESS_private;
>   	  fip->non_public_fields = 1;
> --- 2142,2148 ----
>   
>         /* Change accessibility for artificial fields (e.g. virtual table
>            pointer or virtual base class pointer) to private.  */
> !       if (dwarf_attr (die, DW_AT_artificial, cu_header))
>   	{
>   	  new_field->accessibility = DW_ACCESS_private;
>   	  fip->non_public_fields = 1;
> *************** dwarf2_add_field (struct field_info *fip
> *** 2112,2125 ****
>   
>         /* C++ static member.
>   	 Get name of field.  */
> !       attr = dwarf_attr (die, DW_AT_name);
>         if (attr && DW_STRING (attr))
>   	fieldname = DW_STRING (attr);
>         else
>   	return;
>   
>         /* Get physical name.  */
> !       physname = dwarf2_linkage_name (die);
>   
>         SET_FIELD_PHYSNAME (*fp, obsavestring (physname, strlen (physname),
>   					     &objfile->type_obstack));
> --- 2154,2167 ----
>   
>         /* C++ static member.
>   	 Get name of field.  */
> !       attr = dwarf_attr (die, DW_AT_name, cu_header);
>         if (attr && DW_STRING (attr))
>   	fieldname = DW_STRING (attr);
>         else
>   	return;
>   
>         /* Get physical name.  */
> !       physname = dwarf2_linkage_name (die, cu_header);
>   
>         SET_FIELD_PHYSNAME (*fp, obsavestring (physname, strlen (physname),
>   					     &objfile->type_obstack));
> *************** dwarf2_add_field (struct field_info *fip
> *** 2130,2136 ****
>     else if (die->tag == DW_TAG_inheritance)
>       {
>         /* C++ base class field.  */
> !       attr = dwarf_attr (die, DW_AT_data_member_location);
>         if (attr)
>   	FIELD_BITPOS (*fp) = (decode_locdesc (DW_BLOCK (attr), objfile, cu_header)
>   			      * bits_per_byte);
> --- 2172,2178 ----
>     else if (die->tag == DW_TAG_inheritance)
>       {
>         /* C++ base class field.  */
> !       attr = dwarf_attr (die, DW_AT_data_member_location, cu_header);
>         if (attr)
>   	FIELD_BITPOS (*fp) = (decode_locdesc (DW_BLOCK (attr), objfile, cu_header)
>   			      * bits_per_byte);
> *************** dwarf2_add_member_fn (struct field_info 
> *** 2244,2257 ****
>     struct nextfnfield *new_fnfield;
>   
>     /* Get name of member function.  */
> !   attr = dwarf_attr (die, DW_AT_name);
>     if (attr && DW_STRING (attr))
>       fieldname = DW_STRING (attr);
>     else
>       return;
>   
>     /* Get the mangled name.  */
> !   physname = dwarf2_linkage_name (die);
>   
>     /* Look up member function name in fieldlist.  */
>     for (i = 0; i < fip->nfnfields; i++)
> --- 2286,2299 ----
>     struct nextfnfield *new_fnfield;
>   
>     /* Get name of member function.  */
> !   attr = dwarf_attr (die, DW_AT_name, cu_header);
>     if (attr && DW_STRING (attr))
>       fieldname = DW_STRING (attr);
>     else
>       return;
>   
>     /* Get the mangled name.  */
> !   physname = dwarf2_linkage_name (die, cu_header);
>   
>     /* Look up member function name in fieldlist.  */
>     for (i = 0; i < fip->nfnfields; i++)
> *************** dwarf2_add_member_fn (struct field_info 
> *** 2319,2332 ****
>       complain (&dwarf2_missing_member_fn_type_complaint, physname);
>   
>     /* Get fcontext from DW_AT_containing_type if present.  */
> !   if (dwarf_attr (die, DW_AT_containing_type) != NULL)
>       fnp->fcontext = die_containing_type (die, objfile, cu_header);
>   
>     /* dwarf2 doesn't have stubbed physical names, so the setting of is_const
>        and is_volatile is irrelevant, as it is needed by gdb_mangle_name only.  */
>   
>     /* Get accessibility.  */
> !   attr = dwarf_attr (die, DW_AT_accessibility);
>     if (attr)
>       {
>         switch (DW_UNSND (attr))
> --- 2361,2374 ----
>       complain (&dwarf2_missing_member_fn_type_complaint, physname);
>   
>     /* Get fcontext from DW_AT_containing_type if present.  */
> !   if (dwarf_attr (die, DW_AT_containing_type, cu_header) != NULL)
>       fnp->fcontext = die_containing_type (die, objfile, cu_header);
>   
>     /* dwarf2 doesn't have stubbed physical names, so the setting of is_const
>        and is_volatile is irrelevant, as it is needed by gdb_mangle_name only.  */
>   
>     /* Get accessibility.  */
> !   attr = dwarf_attr (die, DW_AT_accessibility, cu_header);
>     if (attr)
>       {
>         switch (DW_UNSND (attr))
> *************** dwarf2_add_member_fn (struct field_info 
> *** 2341,2352 ****
>       }
>   
>     /* Check for artificial methods.  */
> !   attr = dwarf_attr (die, DW_AT_artificial);
>     if (attr && DW_UNSND (attr) != 0)
>       fnp->is_artificial = 1;
>   
>     /* Get index in virtual function table if it is a virtual member function.  */
> !   attr = dwarf_attr (die, DW_AT_vtable_elem_location);
>     if (attr)
>       fnp->voffset = decode_locdesc (DW_BLOCK (attr), objfile, cu_header) + 2;
>   }
> --- 2383,2394 ----
>       }
>   
>     /* Check for artificial methods.  */
> !   attr = dwarf_attr (die, DW_AT_artificial, cu_header);
>     if (attr && DW_UNSND (attr) != 0)
>       fnp->is_artificial = 1;
>   
>     /* Get index in virtual function table if it is a virtual member function.  */
> !   attr = dwarf_attr (die, DW_AT_vtable_elem_location, cu_header);
>     if (attr)
>       fnp->voffset = decode_locdesc (DW_BLOCK (attr), objfile, cu_header) + 2;
>   }
> *************** read_structure_scope (struct die_info *d
> *** 2411,2417 ****
>     type = alloc_type (objfile);
>   
>     INIT_CPLUS_SPECIFIC (type);
> !   attr = dwarf_attr (die, DW_AT_name);
>     if (attr && DW_STRING (attr))
>       {
>         TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
> --- 2453,2459 ----
>     type = alloc_type (objfile);
>   
>     INIT_CPLUS_SPECIFIC (type);
> !   attr = dwarf_attr (die, DW_AT_name, cu_header);
>     if (attr && DW_STRING (attr))
>       {
>         TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
> *************** read_structure_scope (struct die_info *d
> *** 2434,2440 ****
>         TYPE_CODE (type) = TYPE_CODE_CLASS;
>       }
>   
> !   attr = dwarf_attr (die, DW_AT_byte_size);
>     if (attr)
>       {
>         TYPE_LENGTH (type) = DW_UNSND (attr);
> --- 2476,2482 ----
>         TYPE_CODE (type) = TYPE_CODE_CLASS;
>       }
>   
> !   attr = dwarf_attr (die, DW_AT_byte_size, cu_header);
>     if (attr)
>       {
>         TYPE_LENGTH (type) = DW_UNSND (attr);
> *************** read_structure_scope (struct die_info *d
> *** 2449,2455 ****
>        type within the structure itself. */
>     die->type = type;
>   
> !   if (die->has_children && ! die_is_declaration (die))
>       {
>         struct field_info fi;
>         struct die_info *child_die;
> --- 2491,2497 ----
>        type within the structure itself. */
>     die->type = type;
>   
> !   if (die->has_children && ! die_is_declaration (die, cu_header))
>       {
>         struct field_info fi;
>         struct die_info *child_die;
> *************** read_structure_scope (struct die_info *d
> *** 2499,2505 ****
>   	     class itself) which contains the vtable pointer for the current
>   	     class from the DW_AT_containing_type attribute.  */
>   
> ! 	  if (dwarf_attr (die, DW_AT_containing_type) != NULL)
>   	    {
>   	      struct type *t = die_containing_type (die, objfile, cu_header);
>   
> --- 2541,2547 ----
>   	     class itself) which contains the vtable pointer for the current
>   	     class from the DW_AT_containing_type attribute.  */
>   
> ! 	  if (dwarf_attr (die, DW_AT_containing_type, cu_header) != NULL)
>   	    {
>   	      struct type *t = die_containing_type (die, objfile, cu_header);
>   
> *************** read_enumeration (struct die_info *die, 
> *** 2572,2578 ****
>     type = alloc_type (objfile);
>   
>     TYPE_CODE (type) = TYPE_CODE_ENUM;
> !   attr = dwarf_attr (die, DW_AT_name);
>     if (attr && DW_STRING (attr))
>       {
>         TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
> --- 2614,2620 ----
>     type = alloc_type (objfile);
>   
>     TYPE_CODE (type) = TYPE_CODE_ENUM;
> !   attr = dwarf_attr (die, DW_AT_name, cu_header);
>     if (attr && DW_STRING (attr))
>       {
>         TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
> *************** read_enumeration (struct die_info *die, 
> *** 2580,2586 ****
>   					   &objfile->type_obstack);
>       }
>   
> !   attr = dwarf_attr (die, DW_AT_byte_size);
>     if (attr)
>       {
>         TYPE_LENGTH (type) = DW_UNSND (attr);
> --- 2622,2628 ----
>   					   &objfile->type_obstack);
>       }
>   
> !   attr = dwarf_attr (die, DW_AT_byte_size, cu_header);
>     if (attr)
>       {
>         TYPE_LENGTH (type) = DW_UNSND (attr);
> *************** read_enumeration (struct die_info *die, 
> *** 2603,2609 ****
>   	    }
>   	  else
>   	    {
> ! 	      attr = dwarf_attr (child_die, DW_AT_name);
>   	      if (attr)
>   		{
>   		  sym = new_symbol (child_die, type, objfile, cu_header);
> --- 2645,2651 ----
>   	    }
>   	  else
>   	    {
> ! 	      attr = dwarf_attr (child_die, DW_AT_name, cu_header);
>   	      if (attr)
>   		{
>   		  sym = new_symbol (child_die, type, objfile, cu_header);
> *************** read_array_type (struct die_info *die, s
> *** 2698,2704 ****
>   	    }
>   
>   	  index_type = die_type (child_die, objfile, cu_header);
> ! 	  attr = dwarf_attr (child_die, DW_AT_lower_bound);
>   	  if (attr)
>   	    {
>   	      if (attr->form == DW_FORM_sdata)
> --- 2740,2746 ----
>   	    }
>   
>   	  index_type = die_type (child_die, objfile, cu_header);
> ! 	  attr = dwarf_attr (child_die, DW_AT_lower_bound, cu_header);
>   	  if (attr)
>   	    {
>   	      if (attr->form == DW_FORM_sdata)
> *************** read_array_type (struct die_info *die, s
> *** 2725,2731 ****
>   #endif
>   		}
>   	    }
> ! 	  attr = dwarf_attr (child_die, DW_AT_upper_bound);
>   	  if (attr)
>   	    {
>   	      if (attr->form == DW_FORM_sdata)
> --- 2767,2773 ----
>   #endif
>   		}
>   	    }
> ! 	  attr = dwarf_attr (child_die, DW_AT_upper_bound, cu_header);
>   	  if (attr)
>   	    {
>   	      if (attr->form == DW_FORM_sdata)
> *************** read_array_type (struct die_info *die, s
> *** 2788,2794 ****
>        custom vendor extension.  The main difference between a regular
>        array and the vector variant is that vectors are passed by value
>        to functions.  */
> !   attr = dwarf_attr (die, DW_AT_GNU_vector);
>     if (attr)
>       TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
>   
> --- 2830,2836 ----
>        custom vendor extension.  The main difference between a regular
>        array and the vector variant is that vectors are passed by value
>        to functions.  */
> !   attr = dwarf_attr (die, DW_AT_GNU_vector, cu_header);
>     if (attr)
>       TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
>   
> *************** read_common_block (struct die_info *die,
> *** 2809,2815 ****
>     struct symbol *sym;
>     CORE_ADDR base = (CORE_ADDR) 0;
>   
> !   attr = dwarf_attr (die, DW_AT_location);
>     if (attr)
>       {
>         base = decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
> --- 2851,2857 ----
>     struct symbol *sym;
>     CORE_ADDR base = (CORE_ADDR) 0;
>   
> !   attr = dwarf_attr (die, DW_AT_location, cu_header);
>     if (attr)
>       {
>         base = decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
> *************** read_common_block (struct die_info *die,
> *** 2820,2826 ****
>         while (child_die && child_die->tag)
>   	{
>   	  sym = new_symbol (child_die, NULL, objfile, cu_header);
> ! 	  attr = dwarf_attr (child_die, DW_AT_data_member_location);
>   	  if (attr)
>   	    {
>   	      SYMBOL_VALUE_ADDRESS (sym) =
> --- 2862,2868 ----
>         while (child_die && child_die->tag)
>   	{
>   	  sym = new_symbol (child_die, NULL, objfile, cu_header);
> ! 	  attr = dwarf_attr (child_die, DW_AT_data_member_location, cu_header);
>   	  if (attr)
>   	    {
>   	      SYMBOL_VALUE_ADDRESS (sym) =
> *************** read_tag_pointer_type (struct die_info *
> *** 2848,2854 ****
>       }
>   
>     type = lookup_pointer_type (die_type (die, objfile, cu_header));
> !   attr = dwarf_attr (die, DW_AT_byte_size);
>     if (attr)
>       {
>         TYPE_LENGTH (type) = DW_UNSND (attr);
> --- 2890,2896 ----
>       }
>   
>     type = lookup_pointer_type (die_type (die, objfile, cu_header));
> !   attr = dwarf_attr (die, DW_AT_byte_size, cu_header);
>     if (attr)
>       {
>         TYPE_LENGTH (type) = DW_UNSND (attr);
> *************** read_tag_reference_type (struct die_info
> *** 2900,2906 ****
>       }
>   
>     type = lookup_reference_type (die_type (die, objfile, cu_header));
> !   attr = dwarf_attr (die, DW_AT_byte_size);
>     if (attr)
>       {
>         TYPE_LENGTH (type) = DW_UNSND (attr);
> --- 2942,2948 ----
>       }
>   
>     type = lookup_reference_type (die_type (die, objfile, cu_header));
> !   attr = dwarf_attr (die, DW_AT_byte_size, cu_header);
>     if (attr)
>       {
>         TYPE_LENGTH (type) = DW_UNSND (attr);
> *************** read_tag_volatile_type (struct die_info 
> *** 2948,2954 ****
>      attribute to reference it.  */
>   
>   static void
> ! read_tag_string_type (struct die_info *die, struct objfile *objfile)
>   {
>     struct type *type, *range_type, *index_type, *char_type;
>     struct attribute *attr;
> --- 2990,2997 ----
>      attribute to reference it.  */
>   
>   static void
> ! read_tag_string_type (struct die_info *die, struct objfile *objfile,
> !                       const struct comp_unit_head *cu_header)
>   {
>     struct type *type, *range_type, *index_type, *char_type;
>     struct attribute *attr;
> *************** read_tag_string_type (struct die_info *d
> *** 2959,2965 ****
>         return;
>       }
>   
> !   attr = dwarf_attr (die, DW_AT_string_length);
>     if (attr)
>       {
>         length = DW_UNSND (attr);
> --- 3002,3008 ----
>         return;
>       }
>   
> !   attr = dwarf_attr (die, DW_AT_string_length, cu_header);
>     if (attr)
>       {
>         length = DW_UNSND (attr);
> *************** read_tag_string_type (struct die_info *d
> *** 2967,2973 ****
>     else
>       {
>         /* check for the DW_AT_byte_size attribute */
> !       attr = dwarf_attr (die, DW_AT_byte_size);
>         if (attr)
>           {
>             length = DW_UNSND (attr);
> --- 3010,3016 ----
>     else
>       {
>         /* check for the DW_AT_byte_size attribute */
> !       attr = dwarf_attr (die, DW_AT_byte_size, cu_header);
>         if (attr)
>           {
>             length = DW_UNSND (attr);
> *************** read_subroutine_type (struct die_info *d
> *** 3021,3027 ****
>     ftype = lookup_function_type (type);
>   
>     /* All functions in C++ have prototypes.  */
> !   attr = dwarf_attr (die, DW_AT_prototyped);
>     if ((attr && (DW_UNSND (attr) != 0))
>         || cu_language == language_cplus)
>       TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
> --- 3064,3070 ----
>     ftype = lookup_function_type (type);
>   
>     /* All functions in C++ have prototypes.  */
> !   attr = dwarf_attr (die, DW_AT_prototyped, cu_header);
>     if ((attr && (DW_UNSND (attr) != 0))
>         || cu_language == language_cplus)
>       TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
> *************** read_subroutine_type (struct die_info *d
> *** 3060,3066 ****
>   	         parameter for non-static member functions (which is the
>   	         this pointer) as artificial. We pass this information
>   	         to dwarf2_add_member_fn via TYPE_FIELD_ARTIFICIAL.  */
> ! 	      attr = dwarf_attr (child_die, DW_AT_artificial);
>   	      if (attr)
>   		TYPE_FIELD_ARTIFICIAL (ftype, iparams) = DW_UNSND (attr);
>   	      else
> --- 3103,3109 ----
>   	         parameter for non-static member functions (which is the
>   	         this pointer) as artificial. We pass this information
>   	         to dwarf2_add_member_fn via TYPE_FIELD_ARTIFICIAL.  */
> ! 	      attr = dwarf_attr (child_die, DW_AT_artificial, cu_header);
>   	      if (attr)
>   		TYPE_FIELD_ARTIFICIAL (ftype, iparams) = DW_UNSND (attr);
>   	      else
> *************** read_typedef (struct die_info *die, stru
> *** 3085,3091 ****
>   
>     if (!die->type)
>       {
> !       attr = dwarf_attr (die, DW_AT_name);
>         if (attr && DW_STRING (attr))
>   	{
>   	  name = DW_STRING (attr);
> --- 3128,3134 ----
>   
>     if (!die->type)
>       {
> !       attr = dwarf_attr (die, DW_AT_name, cu_header);
>         if (attr && DW_STRING (attr))
>   	{
>   	  name = DW_STRING (attr);
> *************** read_typedef (struct die_info *die, stru
> *** 3099,3105 ****
>      it in the TYPE field of the die.  */
>   
>   static void
> ! read_base_type (struct die_info *die, struct objfile *objfile)
>   {
>     struct type *type;
>     struct attribute *attr;
> --- 3142,3149 ----
>      it in the TYPE field of the die.  */
>   
>   static void
> ! read_base_type (struct die_info *die, struct objfile *objfile,
> !                 const struct comp_unit_head *cu_header)
>   {
>     struct type *type;
>     struct attribute *attr;
> *************** read_base_type (struct die_info *die, st
> *** 3111,3127 ****
>         return;
>       }
>   
> !   attr = dwarf_attr (die, DW_AT_encoding);
>     if (attr)
>       {
>         encoding = DW_UNSND (attr);
>       }
> !   attr = dwarf_attr (die, DW_AT_byte_size);
>     if (attr)
>       {
>         size = DW_UNSND (attr);
>       }
> !   attr = dwarf_attr (die, DW_AT_name);
>     if (attr && DW_STRING (attr))
>       {
>         enum type_code code = TYPE_CODE_INT;
> --- 3155,3171 ----
>         return;
>       }
>   
> !   attr = dwarf_attr (die, DW_AT_encoding, cu_header);
>     if (attr)
>       {
>         encoding = DW_UNSND (attr);
>       }
> !   attr = dwarf_attr (die, DW_AT_byte_size, cu_header);
>     if (attr)
>       {
>         size = DW_UNSND (attr);
>       }
> !   attr = dwarf_attr (die, DW_AT_name, cu_header);
>     if (attr && DW_STRING (attr))
>       {
>         enum type_code code = TYPE_CODE_INT;
> *************** read_comp_unit (char *info_ptr, bfd *abf
> *** 3227,3232 ****
> --- 3271,3416 ----
>     return first_die;
>   }
>   
> + /* Register a cu_header, by making a copy of the header and then
> +    adding it to the cu_header list. */
> + static void
> + register_cu_header (const struct comp_unit_head *cu_header)
> + {
> +   struct comp_unit_head *head;
> + 
> +   head = xmalloc (sizeof (struct comp_unit_head));
> +   memcpy (head, cu_header, sizeof (struct comp_unit_head));
> + 
> +   head->next = first_cu_header;
> +   first_cu_header = head;
> + }
> + 
> + /* Attempt to find matching cu_header from given offset */
> + static struct comp_unit_head *
> + find_cu_header_from_begin_offset (char *begin_offset)
> + {
> +   struct comp_unit_head *cu_header;
> + 
> +   for (cu_header = first_cu_header;
> +        cu_header != NULL;
> +        cu_header = cu_header->next)
> +     {
> +       if (begin_offset == cu_header->begin_offset)
> +         {
> +           return cu_header;
> +         }
> +     }
> + 
> +   /* Failed to find cu_header at the given offset. */
> +   return NULL;
> + }
> + 
> + /* Attempt to find matching cu_header from given offset
> +    within the cu_header range. */
> + static struct comp_unit_head *
> + find_cu_header (unsigned int offset)
> + {
> +   struct comp_unit_head *cu_header;
> + 
> +   for (cu_header = first_cu_header;
> +        cu_header != NULL;
> +        cu_header = cu_header->next)
> +     {
> +       if (offset >= cu_header->offset
> +           && offset < cu_header->offset + cu_header->length)
> +         {
> +           return cu_header;
> +         }
> +     }
> + 
> +   /* Failed to find in cu_header range the given offset. */
> +   return NULL;
> + }
> + 
> + static struct die_info *
> + find_die_ref (unsigned int target_offset, bfd *abfd,
> +               const struct comp_unit_head *cu_header)
> + {
> +   struct die_info *die, *target_die;
> +   char *cur_ptr;
> +   int nesting_level;
> + 
> +   cur_ptr = cu_header->base_offset;
> +   nesting_level = 0;
> +   target_die = NULL;
> +   do
> +     {
> +       cur_ptr = read_full_die (&die, abfd, cur_ptr, cu_header);
> + 
> +       if (die->has_children)
> + 	{
> + 	  nesting_level++;
> + 	}
> +       if (die->tag == 0)
> + 	{
> + 	  nesting_level--;
> + 	}
> + 
> +       die->next = NULL;
> + 
> +       /* Enter die in reference hash table */
> +       store_in_ref_table (die->offset, die);
> + 
> +       if (die->offset == target_offset)
> +         {
> +            /* Found the requested die */
> +           target_die = die;
> +         }
> +     }
> +   while (nesting_level > 0);
> + 
> +   return target_die;
> + }
> + 
> + static struct die_info *
> + build_die_ref (struct attribute *attr, struct objfile *objfile,
> +                const struct comp_unit_head *base_cu_header)
> + {
> +   struct comp_unit_head *cu_header = NULL;
> +   struct die_info *die_ref = NULL;
> +   unsigned int offset = 0;
> + 
> +   /* Get the offset */
> +   offset = dwarf2_get_ref_die_offset (attr, base_cu_header);
> + 
> +   /* If not a DW_FORM_ref_addr, use current settings to return
> +      the offset */
> +   if (attr->form != DW_FORM_ref_addr)
> +     {
> +        return follow_die_ref (offset);
> +     }
> + 
> +   /* Check whether die has been constructed before */
> +   die_ref = follow_die_ref (offset);
> + 
> +   if (die_ref != NULL && die_ref->type != NULL)
> +     {
> +       return die_ref;
> +     }
> + 
> +   /* Find the appropriate cu_header */
> +   cu_header = find_cu_header (offset);
> + 
> +   /* Find the correct die */
> +   die_ref = find_die_ref (offset, objfile->obfd, cu_header);
> + 
> +   /* Make sure that the cu_header has its dwarf abbreviation table */
> +   if (cu_header->dwarf2_abbrevs == NULL)
> +     {
> +       error ("No DWARF abbreviation table for comp unit header");
> +     }
> + 
> +   /* Construct the die's type */
> +   die_type (die_ref, objfile, cu_header);
> + 
> +   return die_ref;
> + }
> + 
>   /* Free a linked list of dies.  */
>   
>   static void
> *************** make_cleanup_free_die_list (struct die_i
> *** 3256,3261 ****
> --- 3440,3464 ----
>     return make_cleanup (do_free_die_list_cleanup, dies);
>   }
>   
> + /* Free linked list of cu_headers */
> + static void
> + free_cu_header_list (void)
> + {
> +   struct comp_unit_head *head = first_cu_header;
> +   struct comp_unit_head *thead;
> + 
> +   while (head != NULL)
> +     {
> +       thead = head;
> +       head = head->next;
> + 
> +       /* empty the abbrev table */
> +       dwarf2_empty_abbrev_table (thead);
> +       xfree (thead);
> +     }
> + 
> +   first_cu_header = NULL;
> + }
>   
>   /* Read the contents of the section at OFFSET and of size SIZE from the
>      object file specified by OBJFILE into the psymbol_obstack and return it.  */
> *************** dwarf2_read_section (struct objfile *obj
> *** 3287,3306 ****
>      in a hash table.  */
>   
>   static void
> ! dwarf2_read_abbrevs (bfd *abfd, unsigned int offset)
>   {
>     char *abbrev_ptr;
>     struct abbrev_info *cur_abbrev;
>     unsigned int abbrev_number, bytes_read, abbrev_name;
>     unsigned int abbrev_form, hash_number;
>   
> !   /* empty the table */
> !   dwarf2_empty_abbrev_table (NULL);
> ! 
> !   abbrev_ptr = dwarf_abbrev_buffer + offset;
>     abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
>     abbrev_ptr += bytes_read;
>   
>     /* loop until we reach an abbrev number of 0 */
>     while (abbrev_number)
>       {
> --- 3490,3510 ----
>      in a hash table.  */
>   
>   static void
> ! dwarf2_read_abbrevs (bfd *abfd, struct comp_unit_head *cu_header)
>   {
>     char *abbrev_ptr;
>     struct abbrev_info *cur_abbrev;
>     unsigned int abbrev_number, bytes_read, abbrev_name;
>     unsigned int abbrev_form, hash_number;
>   
> !   abbrev_ptr = dwarf_abbrev_buffer + cu_header->abbrev_offset;
>     abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
>     abbrev_ptr += bytes_read;
>   
> +   /* Initialize dwarf2 abbrevs */
> +   memset (cu_header->dwarf2_abbrevs, 0,
> +           ABBREV_HASH_SIZE*sizeof (struct abbrev_info *));
> + 
>     /* loop until we reach an abbrev number of 0 */
>     while (abbrev_number)
>       {
> *************** dwarf2_read_abbrevs (bfd *abfd, unsigned
> *** 3336,3343 ****
>   	}
>   
>         hash_number = abbrev_number % ABBREV_HASH_SIZE;
> !       cur_abbrev->next = dwarf2_abbrevs[hash_number];
> !       dwarf2_abbrevs[hash_number] = cur_abbrev;
>   
>         /* Get next abbreviation.
>            Under Irix6 the abbreviations for a compilation unit are not
> --- 3540,3547 ----
>   	}
>   
>         hash_number = abbrev_number % ABBREV_HASH_SIZE;
> !       cur_abbrev->next = cu_header->dwarf2_abbrevs[hash_number];
> !       cu_header->dwarf2_abbrevs[hash_number] = cur_abbrev;
>   
>         /* Get next abbreviation.
>            Under Irix6 the abbreviations for a compilation unit are not
> *************** dwarf2_read_abbrevs (bfd *abfd, unsigned
> *** 3351,3358 ****
>   	break;
>         abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
>         abbrev_ptr += bytes_read;
> !       if (dwarf2_lookup_abbrev (abbrev_number) != NULL)
> ! 	break;
>       }
>   }
>   
> --- 3555,3565 ----
>   	break;
>         abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
>         abbrev_ptr += bytes_read;
> !       if (dwarf2_lookup_abbrev (abbrev_number, cu_header) != NULL)
> !         {
> !           /* Could not find abbrev just created */
> ! 	  break;
> !         }
>       }
>   }
>   
> *************** dwarf2_read_abbrevs (bfd *abfd, unsigned
> *** 3360,3366 ****
>   
>   /* ARGSUSED */
>   static void
> ! dwarf2_empty_abbrev_table (PTR ignore)
>   {
>     int i;
>     struct abbrev_info *abbrev, *next;
> --- 3567,3573 ----
>   
>   /* ARGSUSED */
>   static void
> ! dwarf2_empty_abbrev_table (struct comp_unit_head *cu_header)
>   {
>     int i;
>     struct abbrev_info *abbrev, *next;
> *************** dwarf2_empty_abbrev_table (PTR ignore)
> *** 3368,3374 ****
>     for (i = 0; i < ABBREV_HASH_SIZE; ++i)
>       {
>         next = NULL;
> !       abbrev = dwarf2_abbrevs[i];
>         while (abbrev)
>   	{
>   	  next = abbrev->next;
> --- 3575,3581 ----
>     for (i = 0; i < ABBREV_HASH_SIZE; ++i)
>       {
>         next = NULL;
> !       abbrev = cu_header->dwarf2_abbrevs[i];
>         while (abbrev)
>   	{
>   	  next = abbrev->next;
> *************** dwarf2_empty_abbrev_table (PTR ignore)
> *** 3376,3395 ****
>   	  xfree (abbrev);
>   	  abbrev = next;
>   	}
> !       dwarf2_abbrevs[i] = NULL;
>       }
>   }
>   
>   /* Lookup an abbrev_info structure in the abbrev hash table.  */
>   
>   static struct abbrev_info *
> ! dwarf2_lookup_abbrev (unsigned int number)
>   {
>     unsigned int hash_number;
>     struct abbrev_info *abbrev;
>   
>     hash_number = number % ABBREV_HASH_SIZE;
> !   abbrev = dwarf2_abbrevs[hash_number];
>   
>     while (abbrev)
>       {
> --- 3583,3603 ----
>   	  xfree (abbrev);
>   	  abbrev = next;
>   	}
> !       cu_header->dwarf2_abbrevs[i] = NULL;
>       }
>   }
>   
>   /* Lookup an abbrev_info structure in the abbrev hash table.  */
>   
>   static struct abbrev_info *
> ! dwarf2_lookup_abbrev (unsigned int number,
> !                       const struct comp_unit_head *cu_header)
>   {
>     unsigned int hash_number;
>     struct abbrev_info *abbrev;
>   
>     hash_number = number % ABBREV_HASH_SIZE;
> !   abbrev = cu_header->dwarf2_abbrevs[hash_number];
>   
>     while (abbrev)
>       {
> *************** read_partial_die (struct partial_die_inf
> *** 3421,3427 ****
>     if (!abbrev_number)
>       return info_ptr;
>   
> !   abbrev = dwarf2_lookup_abbrev (abbrev_number);
>     if (!abbrev)
>       {
>         error ("Dwarf Error: Could not find abbrev number %d.", abbrev_number);
> --- 3629,3635 ----
>     if (!abbrev_number)
>       return info_ptr;
>   
> !   abbrev = dwarf2_lookup_abbrev (abbrev_number, cu_header);
>     if (!abbrev)
>       {
>         error ("Dwarf Error: Could not find abbrev number %d.", abbrev_number);
> *************** read_partial_die (struct partial_die_inf
> *** 3484,3490 ****
>   	    complain (&dwarf2_absolute_sibling_complaint);
>   	  else
>   	    part_die->sibling =
> ! 	      dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr);
>   	  break;
>   	default:
>   	  break;
> --- 3692,3698 ----
>   	    complain (&dwarf2_absolute_sibling_complaint);
>   	  else
>   	    part_die->sibling =
> ! 	      dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr, cu_header);
>   	  break;
>   	default:
>   	  break;
> *************** read_partial_die (struct partial_die_inf
> *** 3500,3506 ****
>         char *spec_ptr;
>         int dummy;
>   
> !       spec_ptr = dwarf_info_buffer + dwarf2_get_ref_die_offset (&spec_attr);
>         read_partial_die (&spec_die, abfd, spec_ptr, cu_header);
>         if (spec_die.name)
>   	{
> --- 3708,3715 ----
>         char *spec_ptr;
>         int dummy;
>   
> !       spec_ptr = dwarf_info_buffer + dwarf2_get_ref_die_offset (&spec_attr,
> !                                                                 cu_header);
>         read_partial_die (&spec_die, abfd, spec_ptr, cu_header);
>         if (spec_die.name)
>   	{
> *************** read_full_die (struct die_info **diep, b
> *** 3552,3558 ****
>         return info_ptr;
>       }
>   
> !   abbrev = dwarf2_lookup_abbrev (abbrev_number);
>     if (!abbrev)
>       {
>         error ("Dwarf Error: could not find abbrev number %d.", abbrev_number);
> --- 3761,3767 ----
>         return info_ptr;
>       }
>   
> !   abbrev = dwarf2_lookup_abbrev (abbrev_number, cu_header);
>     if (!abbrev)
>       {
>         error ("Dwarf Error: could not find abbrev number %d.", abbrev_number);
> *************** set_cu_language (unsigned int lang)
> *** 4031,4037 ****
>   /* Return the named attribute or NULL if not there.  */
>   
>   static struct attribute *
> ! dwarf_attr (struct die_info *die, unsigned int name)
>   {
>     unsigned int i;
>     struct attribute *spec = NULL;
> --- 4240,4247 ----
>   /* Return the named attribute or NULL if not there.  */
>   
>   static struct attribute *
> ! dwarf_attr (struct die_info *die, unsigned int name,
> !             const struct comp_unit_head *cu_header)
>   {
>     unsigned int i;
>     struct attribute *spec = NULL;
> *************** dwarf_attr (struct die_info *die, unsign
> *** 4049,4071 ****
>     if (spec)
>       {
>         struct die_info *ref_die =
> !       follow_die_ref (dwarf2_get_ref_die_offset (spec));
>   
>         if (ref_die)
> ! 	return dwarf_attr (ref_die, name);
>       }
>   
>     return NULL;
>   }
>   
>   static int
> ! die_is_declaration (struct die_info *die)
>   {
> !   return (dwarf_attr (die, DW_AT_declaration)
> ! 	  && ! dwarf_attr (die, DW_AT_specification));
>   }
>   
> - 
>   /* Free the line_header structure *LH, and any arrays and strings it
>      refers to.  */
>   static void
> --- 4259,4281 ----
>     if (spec)
>       {
>         struct die_info *ref_die =
> !       follow_die_ref (dwarf2_get_ref_die_offset (spec, cu_header));
>   
>         if (ref_die)
> ! 	return dwarf_attr (ref_die, name, cu_header);
>       }
>   
>     return NULL;
>   }
>   
>   static int
> ! die_is_declaration (struct die_info *die,
> !                     const struct comp_unit_head *cu_header)
>   {
> !   return (dwarf_attr (die, DW_AT_declaration, cu_header)
> ! 	  && ! dwarf_attr (die, DW_AT_specification, cu_header));
>   }
>   
>   /* Free the line_header structure *LH, and any arrays and strings it
>      refers to.  */
>   static void
> *************** new_symbol (struct die_info *die, struct
> *** 4524,4530 ****
>     struct attribute *attr2 = NULL;
>     CORE_ADDR addr;
>   
> !   name = dwarf2_linkage_name (die);
>     if (name)
>       {
>         sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
> --- 4734,4740 ----
>     struct attribute *attr2 = NULL;
>     CORE_ADDR addr;
>   
> !   name = dwarf2_linkage_name (die, cu_header);
>     if (name)
>       {
>         sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
> *************** new_symbol (struct die_info *die, struct
> *** 4542,4548 ****
>   	SYMBOL_TYPE (sym) = type;
>         else
>   	SYMBOL_TYPE (sym) = die_type (die, objfile, cu_header);
> !       attr = dwarf_attr (die, DW_AT_decl_line);
>         if (attr)
>   	{
>   	  SYMBOL_LINE (sym) = DW_UNSND (attr);
> --- 4752,4758 ----
>   	SYMBOL_TYPE (sym) = type;
>         else
>   	SYMBOL_TYPE (sym) = die_type (die, objfile, cu_header);
> !       attr = dwarf_attr (die, DW_AT_decl_line, cu_header);
>         if (attr)
>   	{
>   	  SYMBOL_LINE (sym) = DW_UNSND (attr);
> *************** new_symbol (struct die_info *die, struct
> *** 4559,4565 ****
>         switch (die->tag)
>   	{
>   	case DW_TAG_label:
> ! 	  attr = dwarf_attr (die, DW_AT_low_pc);
>   	  if (attr)
>   	    {
>   	      SYMBOL_VALUE_ADDRESS (sym) = DW_ADDR (attr) + baseaddr;
> --- 4769,4775 ----
>         switch (die->tag)
>   	{
>   	case DW_TAG_label:
> ! 	  attr = dwarf_attr (die, DW_AT_low_pc, cu_header);
>   	  if (attr)
>   	    {
>   	      SYMBOL_VALUE_ADDRESS (sym) = DW_ADDR (attr) + baseaddr;
> *************** new_symbol (struct die_info *die, struct
> *** 4570,4576 ****
>   	  /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
>   	     finish_block.  */
>   	  SYMBOL_CLASS (sym) = LOC_BLOCK;
> ! 	  attr2 = dwarf_attr (die, DW_AT_external);
>   	  if (attr2 && (DW_UNSND (attr2) != 0))
>   	    {
>   	      add_symbol_to_list (sym, &global_symbols);
> --- 4780,4786 ----
>   	  /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
>   	     finish_block.  */
>   	  SYMBOL_CLASS (sym) = LOC_BLOCK;
> ! 	  attr2 = dwarf_attr (die, DW_AT_external, cu_header);
>   	  if (attr2 && (DW_UNSND (attr2) != 0))
>   	    {
>   	      add_symbol_to_list (sym, &global_symbols);
> *************** new_symbol (struct die_info *die, struct
> *** 4589,4609 ****
>   					   TARGET_INT_BIT / HOST_CHAR_BIT, 0,
>   					   "<variable, no debug info>",
>   					   objfile);
> ! 	  attr = dwarf_attr (die, DW_AT_const_value);
>   	  if (attr)
>   	    {
>   	      dwarf2_const_value (attr, sym, objfile, cu_header);
> ! 	      attr2 = dwarf_attr (die, DW_AT_external);
>   	      if (attr2 && (DW_UNSND (attr2) != 0))
>   		add_symbol_to_list (sym, &global_symbols);
>   	      else
>   		add_symbol_to_list (sym, list_in_scope);
>   	      break;
>   	    }
> ! 	  attr = dwarf_attr (die, DW_AT_location);
>   	  if (attr)
>   	    {
> ! 	      attr2 = dwarf_attr (die, DW_AT_external);
>   	      if (attr2 && (DW_UNSND (attr2) != 0))
>   		{
>   		  SYMBOL_VALUE_ADDRESS (sym) =
> --- 4799,4819 ----
>   					   TARGET_INT_BIT / HOST_CHAR_BIT, 0,
>   					   "<variable, no debug info>",
>   					   objfile);
> ! 	  attr = dwarf_attr (die, DW_AT_const_value, cu_header);
>   	  if (attr)
>   	    {
>   	      dwarf2_const_value (attr, sym, objfile, cu_header);
> ! 	      attr2 = dwarf_attr (die, DW_AT_external, cu_header);
>   	      if (attr2 && (DW_UNSND (attr2) != 0))
>   		add_symbol_to_list (sym, &global_symbols);
>   	      else
>   		add_symbol_to_list (sym, list_in_scope);
>   	      break;
>   	    }
> ! 	  attr = dwarf_attr (die, DW_AT_location, cu_header);
>   	  if (attr)
>   	    {
> ! 	      attr2 = dwarf_attr (die, DW_AT_external, cu_header);
>   	      if (attr2 && (DW_UNSND (attr2) != 0))
>   		{
>   		  SYMBOL_VALUE_ADDRESS (sym) =
> *************** new_symbol (struct die_info *die, struct
> *** 4670,4678 ****
>   	         The address of the variable will then be determined from
>   	         the minimal symbol table whenever the variable is
>   	         referenced.  */
> ! 	      attr2 = dwarf_attr (die, DW_AT_external);
>   	      if (attr2 && (DW_UNSND (attr2) != 0)
> ! 		  && dwarf_attr (die, DW_AT_type) != NULL)
>   		{
>   		  SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
>   		  add_symbol_to_list (sym, &global_symbols);
> --- 4880,4888 ----
>   	         The address of the variable will then be determined from
>   	         the minimal symbol table whenever the variable is
>   	         referenced.  */
> ! 	      attr2 = dwarf_attr (die, DW_AT_external, cu_header);
>   	      if (attr2 && (DW_UNSND (attr2) != 0)
> ! 		  && dwarf_attr (die, DW_AT_type, cu_header) != NULL)
>   		{
>   		  SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
>   		  add_symbol_to_list (sym, &global_symbols);
> *************** new_symbol (struct die_info *die, struct
> *** 4680,4686 ****
>   	    }
>   	  break;
>   	case DW_TAG_formal_parameter:
> ! 	  attr = dwarf_attr (die, DW_AT_location);
>   	  if (attr)
>   	    {
>   	      SYMBOL_VALUE (sym) =
> --- 4890,4896 ----
>   	    }
>   	  break;
>   	case DW_TAG_formal_parameter:
> ! 	  attr = dwarf_attr (die, DW_AT_location, cu_header);
>   	  if (attr)
>   	    {
>   	      SYMBOL_VALUE (sym) =
> *************** new_symbol (struct die_info *die, struct
> *** 4710,4716 ****
>   		  SYMBOL_CLASS (sym) = LOC_ARG;
>   		}
>   	    }
> ! 	  attr = dwarf_attr (die, DW_AT_const_value);
>   	  if (attr)
>   	    {
>   	      dwarf2_const_value (attr, sym, objfile, cu_header);
> --- 4920,4926 ----
>   		  SYMBOL_CLASS (sym) = LOC_ARG;
>   		}
>   	    }
> ! 	  attr = dwarf_attr (die, DW_AT_const_value, cu_header);
>   	  if (attr)
>   	    {
>   	      dwarf2_const_value (attr, sym, objfile, cu_header);
> *************** new_symbol (struct die_info *die, struct
> *** 4755,4761 ****
>   	  add_symbol_to_list (sym, list_in_scope);
>   	  break;
>   	case DW_TAG_enumerator:
> ! 	  attr = dwarf_attr (die, DW_AT_const_value);
>   	  if (attr)
>   	    {
>   	      dwarf2_const_value (attr, sym, objfile, cu_header);
> --- 4965,4971 ----
>   	  add_symbol_to_list (sym, list_in_scope);
>   	  break;
>   	case DW_TAG_enumerator:
> ! 	  attr = dwarf_attr (die, DW_AT_const_value, cu_header);
>   	  if (attr)
>   	    {
>   	      dwarf2_const_value (attr, sym, objfile, cu_header);
> *************** die_type (struct die_info *die, struct o
> *** 4880,4886 ****
>     struct die_info *type_die;
>     unsigned int ref;
>   
> !   type_attr = dwarf_attr (die, DW_AT_type);
>     if (!type_attr)
>       {
>         /* A missing DW_AT_type represents a void type.  */
> --- 5090,5096 ----
>     struct die_info *type_die;
>     unsigned int ref;
>   
> !   type_attr = dwarf_attr (die, DW_AT_type, cu_header);
>     if (!type_attr)
>       {
>         /* A missing DW_AT_type represents a void type.  */
> *************** die_type (struct die_info *die, struct o
> *** 4888,4899 ****
>       }
>     else
>       {
> !       ref = dwarf2_get_ref_die_offset (type_attr);
>         type_die = follow_die_ref (ref);
>         if (!type_die)
>   	{
> ! 	  error ("Dwarf Error: Cannot find referent at offset %d.", ref);
> ! 	  return NULL;
>   	}
>       }
>     type = tag_type_to_type (type_die, objfile, cu_header);
> --- 5098,5115 ----
>       }
>     else
>       {
> !       ref = dwarf2_get_ref_die_offset (type_attr, cu_header);
>         type_die = follow_die_ref (ref);
>         if (!type_die)
>   	{
> !           /* Attempt to find the die in another comp unit */
> !           type_die = build_die_ref (type_attr, objfile, cu_header);
> ! 
> !           if (!type_die)
> !             {
> ! 	      error ("Dwarf Error: Cannot find referent at offset %d.", ref);
> ! 	      return NULL;
> !             }
>   	}
>       }
>     type = tag_type_to_type (type_die, objfile, cu_header);
> *************** die_containing_type (struct die_info *di
> *** 4917,4926 ****
>     struct die_info *type_die = NULL;
>     unsigned int ref;
>   
> !   type_attr = dwarf_attr (die, DW_AT_containing_type);
>     if (type_attr)
>       {
> !       ref = dwarf2_get_ref_die_offset (type_attr);
>         type_die = follow_die_ref (ref);
>         if (!type_die)
>   	{
> --- 5133,5142 ----
>     struct die_info *type_die = NULL;
>     unsigned int ref;
>   
> !   type_attr = dwarf_attr (die, DW_AT_containing_type, cu_header);
>     if (type_attr)
>       {
> !       ref = dwarf2_get_ref_die_offset (type_attr, cu_header);
>         type_die = follow_die_ref (ref);
>         if (!type_die)
>   	{
> *************** read_type_die (struct die_info *die, str
> *** 5013,5025 ****
>         read_tag_volatile_type (die, objfile, cu_header);
>         break;
>       case DW_TAG_string_type:
> !       read_tag_string_type (die, objfile);
>         break;
>       case DW_TAG_typedef:
>         read_typedef (die, objfile, cu_header);
>         break;
>       case DW_TAG_base_type:
> !       read_base_type (die, objfile);
>         break;
>       default:
>         complain (&dwarf2_unexpected_tag, dwarf_tag_name (die->tag));
> --- 5229,5241 ----
>         read_tag_volatile_type (die, objfile, cu_header);
>         break;
>       case DW_TAG_string_type:
> !       read_tag_string_type (die, objfile, cu_header);
>         break;
>       case DW_TAG_typedef:
>         read_typedef (die, objfile, cu_header);
>         break;
>       case DW_TAG_base_type:
> !       read_base_type (die, objfile, cu_header);
>         break;
>       default:
>         complain (&dwarf2_unexpected_tag, dwarf_tag_name (die->tag));
> *************** sibling_die (struct die_info *die)
> *** 5183,5196 ****
>   /* Get linkage name of a die, return NULL if not found.  */
>   
>   static char *
> ! dwarf2_linkage_name (struct die_info *die)
>   {
>     struct attribute *attr;
>   
> !   attr = dwarf_attr (die, DW_AT_MIPS_linkage_name);
>     if (attr && DW_STRING (attr))
>       return DW_STRING (attr);
> !   attr = dwarf_attr (die, DW_AT_name);
>     if (attr && DW_STRING (attr))
>       return DW_STRING (attr);
>     return NULL;
> --- 5399,5413 ----
>   /* Get linkage name of a die, return NULL if not found.  */
>   
>   static char *
> ! dwarf2_linkage_name (struct die_info *die,
> !                      const struct comp_unit_head *cu_header)
>   {
>     struct attribute *attr;
>   
> !   attr = dwarf_attr (die, DW_AT_MIPS_linkage_name, cu_header);
>     if (attr && DW_STRING (attr))
>       return DW_STRING (attr);
> !   attr = dwarf_attr (die, DW_AT_name, cu_header);
>     if (attr && DW_STRING (attr))
>       return DW_STRING (attr);
>     return NULL;
> *************** dwarf2_empty_hash_tables (void)
> *** 6043,6049 ****
>   }
>   
>   static unsigned int
> ! dwarf2_get_ref_die_offset (struct attribute *attr)
>   {
>     unsigned int result = 0;
>   
> --- 6260,6267 ----
>   }
>   
>   static unsigned int
> ! dwarf2_get_ref_die_offset (struct attribute *attr,
> !                            const struct comp_unit_head *cu_header)
>   {
>     unsigned int result = 0;
>   
> *************** dwarf2_get_ref_die_offset (struct attrib
> *** 6057,6063 ****
>       case DW_FORM_ref4:
>       case DW_FORM_ref8:
>       case DW_FORM_ref_udata:
> !       result = cu_header_offset + DW_UNSND (attr);
>         break;
>       default:
>         complain (&dwarf2_unsupported_die_ref_attr, dwarf_form_name (attr->form));
> --- 6275,6281 ----
>       case DW_FORM_ref4:
>       case DW_FORM_ref8:
>       case DW_FORM_ref_udata:
> !       result = cu_header->offset + DW_UNSND (attr);
>         break;
>       default:
>         complain (&dwarf2_unsupported_die_ref_attr, dwarf_form_name (attr->form));
> Index: elfread.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/elfread.c,v
> retrieving revision 1.22
> diff -c -p -r1.22 elfread.c
> *** elfread.c	22 Jun 2002 00:05:59 -0000	1.22
> --- elfread.c	3 Jul 2002 20:35:38 -0000
> ***************
> *** 36,41 ****
> --- 36,42 ----
>   #include "demangle.h"
>   
>   extern void _initialize_elfread (void);
> + extern void dwarf_new_init (void);
>   
>   /* The struct elfinfo is available only during ELF symbol table and
>      psymtab reading.  It is destroyed at the completion of psymtab-reading.
> *************** elf_new_init (struct objfile *ignore)
> *** 664,669 ****
> --- 665,671 ----
>   {
>     stabsread_new_init ();
>     buildsym_new_init ();
> +   dwarf_new_init ();
>   }
>   
>   /* Perform any local cleanups required when we are done with a particular


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]