* [PATCH] Support for multiple DWARF comp unit headers
@ 2002-07-03 14:18 Petr Sorfa
2002-07-04 20:27 ` Jim Blandy
0 siblings, 1 reply; 5+ messages in thread
From: Petr Sorfa @ 2002-07-03 14:18 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 2324 bytes --]
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.
[-- Attachment #2: multiple_cu_header.patch --]
[-- Type: text/plain, Size: 66114 bytes --]
? 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
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] Support for multiple DWARF comp unit headers
2002-07-03 14:18 [PATCH] Support for multiple DWARF comp unit headers Petr Sorfa
@ 2002-07-04 20:27 ` Jim Blandy
2002-07-05 3:39 ` Daniel Berlin
2002-07-08 9:41 ` Petr Sorfa
0 siblings, 2 replies; 5+ messages in thread
From: Jim Blandy @ 2002-07-04 20:27 UTC (permalink / raw)
To: Petr Sorfa; +Cc: gdb-patches
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
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] Support for multiple DWARF comp unit headers
2002-07-04 20:27 ` Jim Blandy
@ 2002-07-05 3:39 ` Daniel Berlin
2002-07-08 9:41 ` Petr Sorfa
1 sibling, 0 replies; 5+ messages in thread
From: Daniel Berlin @ 2002-07-05 3:39 UTC (permalink / raw)
To: Jim Blandy; +Cc: Petr Sorfa, gdb-patches
On 4 Jul 2002, Jim Blandy wrote:
>
> 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.
They generally aren't.
Two factors:
1. Generation of abbrev tables is usually very optimized.
2. The structure of debug info is fairly regular, it's only the actual
information present in the structure that changes. THus, the abbrev
tables are fairly small.
In fact, i've never seen one that was more than about 150 entries.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] Support for multiple DWARF comp unit headers
2002-07-04 20:27 ` Jim Blandy
2002-07-05 3:39 ` Daniel Berlin
@ 2002-07-08 9:41 ` Petr Sorfa
2002-07-08 10:03 ` Daniel Berlin
1 sibling, 1 reply; 5+ messages in thread
From: Petr Sorfa @ 2002-07-08 9:41 UTC (permalink / raw)
To: Jim Blandy; +Cc: gdb-patches
Hi Jim,
> 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.
Heh, you should have seen the original patch ;o) I've already split this
one. But yes, you are right, this patch is too big, so I will split it
into the smaller patches as you have suggested.
> 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?
A valid point, I can't remember the exact reason for this, but I think
it is to handle and odd case that occurs once in a while. I'll verify
this when I split the patch.
> 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?
I look into this when I do the split.
> 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.
As Daniel pointed out the amount of space taken up by abbrev tables is
fairly tiny, usually you don't get over 15 entries and each entry is
usually less than 8 bytes. Again, I'll verify your observation, but I
think it might be worthwhile to keep it around for future DWARF
compatibility. For instance, an optimization that might be done later is
to only read necessary DWARF info when needed (this is a technique
implemented in a debugger I work with), in this case, hanging on the
abbrev table is a good idea.
Thanks for your great comments, I'll have the patch split and resent
this week. I'll also be sending some other smaller patches for support
of various little DWARF features.
Petr
Thanks
>
> 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
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] Support for multiple DWARF comp unit headers
2002-07-08 9:41 ` Petr Sorfa
@ 2002-07-08 10:03 ` Daniel Berlin
0 siblings, 0 replies; 5+ messages in thread
From: Daniel Berlin @ 2002-07-08 10:03 UTC (permalink / raw)
To: Petr Sorfa; +Cc: Jim Blandy, gdb-patches
> compatibility. For instance, an optimization that might be done later is
> to only read necessary DWARF info when needed (this is a technique
> implemented in a debugger I work with), in this case, hanging on the
> abbrev table is a good idea.
>
> Thanks for your great comments, I'll have the patch split and resent
> this week. I'll also be sending some other smaller patches for support
> of various little DWARF features.
You might save time looking through the mailing list archives.
I've coded most of the features at some time or another, they just
never made it in for various reasons (some my fault, some others).
> Petr
>
> Thanks
>
> >
> > 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
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2002-07-08 16:41 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-07-03 14:18 [PATCH] Support for multiple DWARF comp unit headers Petr Sorfa
2002-07-04 20:27 ` Jim Blandy
2002-07-05 3:39 ` Daniel Berlin
2002-07-08 9:41 ` Petr Sorfa
2002-07-08 10:03 ` Daniel Berlin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox