X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fdwarf2read.c;h=4f2f7fb3f9e74bb7984c6f85b3bc89506c73c96e;hb=0fb0cc7590113e9b459dfcc48dc71c9d419d9580;hp=a8d0eca32b7be4b9891fe145a0e6cf02ff4be36e;hpb=0114d6026069970886e2f3ccc1290fbee9f52a8a;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index a8d0eca32b..4f2f7fb3f9 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -1,7 +1,8 @@ /* DWARF 2 debugging format support for GDB. Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + 2004, 2005, 2006, 2007, 2008, 2009 + Free Software Foundation, Inc. Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology, Inc. with support from Florida State University (under contract @@ -141,6 +142,9 @@ typedef struct statement_prologue } _STATEMENT_PROLOGUE; +/* When non-zero, dump DIEs after they are read in. */ +static int dwarf2_die_debug = 0; + /* When set, the file that we're processing is known to have debugging info for C++ namespaces. GCC 3.3.x did not produce this information, but later versions do. */ @@ -231,11 +235,11 @@ asection *dwarf_eh_frame_section; translation, looks like this. */ struct comp_unit_head { - unsigned long length; + unsigned int length; short version; - unsigned int abbrev_offset; unsigned char addr_size; unsigned char signed_addr_p; + unsigned int abbrev_offset; /* Size of file offsets; either 4 or 8. */ unsigned int offset_size; @@ -247,22 +251,9 @@ struct comp_unit_head .debug_info section, for resolving relative reference dies. */ unsigned int offset; - /* Pointer to this compilation unit header in the .debug_info - section. */ - gdb_byte *cu_head_ptr; - - /* Pointer to the first die of this compilation unit. This will be - the first byte following the compilation unit header. */ - gdb_byte *first_die_ptr; - - /* Pointer to the next compilation unit header in the program. */ - struct comp_unit_head *next; - - /* Base address of this compilation unit. */ - CORE_ADDR base_address; - - /* Non-zero if base_address has been set. */ - int base_known; + /* Offset to first die in this cu from the start of the cu. + This will be the first byte following the compilation unit header. */ + unsigned int first_die_offset; }; /* Internal state when decoding a particular compilation unit. */ @@ -271,12 +262,15 @@ struct dwarf2_cu /* The objfile containing this compilation unit. */ struct objfile *objfile; - /* The header of the compilation unit. - - FIXME drow/2003-11-10: Some of the things from the comp_unit_head - should logically be moved to the dwarf2_cu structure. */ + /* The header of the compilation unit. */ struct comp_unit_head header; + /* Base address of this compilation unit. */ + CORE_ADDR base_address; + + /* Non-zero if base_address has been set. */ + int base_known; + struct function_range *first_fn, *last_fn, *cached_fn; /* The language we are debugging. */ @@ -306,7 +300,7 @@ struct dwarf2_cu htab_t partial_dies; /* `.debug_ranges' offset for this `DW_TAG_compile_unit' DIE. */ - unsigned long ranges_offset; + unsigned int ranges_offset; /* Storage for things with the same lifetime as this read-in compilation unit, including partial DIEs. */ @@ -370,13 +364,15 @@ struct dwarf2_per_cu_data { /* The start offset and length of this compilation unit. 2**30-1 bytes should suffice to store the length of any compilation unit - - if it doesn't, GDB will fall over anyway. */ - unsigned long offset; - unsigned long length : 30; + - if it doesn't, GDB will fall over anyway. + NOTE: Unlike comp_unit_head.length, this length includes + initial_length_size. */ + unsigned int offset; + unsigned int length : 30; /* Flag indicating this compilation unit will be read in before any of the current compilation units are processed. */ - unsigned long queued : 1; + unsigned int queued : 1; /* This flag will be set if we need to load absolutely all DIEs for this compilation unit, instead of just the ones we think @@ -523,15 +519,15 @@ struct abbrev_info struct attr_abbrev { - enum dwarf_attribute name; - enum dwarf_form form; + ENUM_BITFIELD(dwarf_attribute) name : 16; + ENUM_BITFIELD(dwarf_form) form : 16; }; /* Attributes have a name and a value */ struct attribute { - enum dwarf_attribute name; - enum dwarf_form form; + ENUM_BITFIELD(dwarf_attribute) name : 16; + ENUM_BITFIELD(dwarf_form) form : 16; union { char *str; @@ -546,10 +542,17 @@ struct attribute /* This data structure holds a complete die structure. */ struct die_info { - enum dwarf_tag tag; /* Tag indicating type of die */ - unsigned int abbrev; /* Abbrev number */ - unsigned int offset; /* Offset in .debug_info section */ - unsigned int num_attrs; /* Number of attributes */ + /* DWARF-2 tag for this DIE. */ + ENUM_BITFIELD(dwarf_tag) tag : 16; + + /* Number of attributes */ + unsigned short num_attrs; + + /* Abbrev number */ + unsigned int abbrev; + + /* Offset in .debug_info section */ + unsigned int offset; /* The dies in a compilation unit form an n-ary tree. PARENT points to this die's parent; CHILD points to the first child of @@ -697,6 +700,13 @@ dwarf2_debug_line_missing_file_complaint (void) _(".debug_line section has line data without a file")); } +static void +dwarf2_debug_line_missing_end_sequence_complaint (void) +{ + complaint (&symfile_complaints, + _(".debug_line section has line program sequence without an end")); +} + static void dwarf2_complex_location_expr_complaint (void) { @@ -767,6 +777,10 @@ static void add_partial_namespace (struct partial_die_info *pdi, static void add_partial_enumeration (struct partial_die_info *enum_pdi, struct dwarf2_cu *cu); +static void add_partial_subprogram (struct partial_die_info *pdi, + CORE_ADDR *lowpc, CORE_ADDR *highpc, + struct dwarf2_cu *cu); + static gdb_byte *locate_pdi_sibling (struct partial_die_info *orig_pdi, gdb_byte *info_ptr, bfd *abfd, @@ -795,7 +809,7 @@ static gdb_byte *read_partial_die (struct partial_die_info *, struct abbrev_info *abbrev, unsigned int, bfd *, gdb_byte *, struct dwarf2_cu *); -static struct partial_die_info *find_partial_die (unsigned long, +static struct partial_die_info *find_partial_die (unsigned int, struct dwarf2_cu *); static void fixup_partial_die (struct partial_die_info *, @@ -823,11 +837,16 @@ static unsigned long read_8_bytes (bfd *, gdb_byte *); static CORE_ADDR read_address (bfd *, gdb_byte *ptr, struct dwarf2_cu *, unsigned int *); -static LONGEST read_initial_length (bfd *, gdb_byte *, - struct comp_unit_head *, unsigned int *); +static LONGEST read_initial_length (bfd *, gdb_byte *, unsigned int *); + +static LONGEST read_checked_initial_length_and_offset + (bfd *, gdb_byte *, const struct comp_unit_head *, + unsigned int *, unsigned int *); static LONGEST read_offset (bfd *, gdb_byte *, const struct comp_unit_head *, - unsigned int *); + unsigned int *); + +static LONGEST read_offset_1 (bfd *, gdb_byte *, unsigned int); static gdb_byte *read_n_bytes (bfd *, gdb_byte *, unsigned int); @@ -949,6 +968,11 @@ static enum dwarf_array_dim_ordering read_array_order (struct die_info *, static struct die_info *read_comp_unit (gdb_byte *, bfd *, struct dwarf2_cu *); +static struct die_info *read_die_and_children_1 (gdb_byte *info_ptr, bfd *abfd, + struct dwarf2_cu *, + gdb_byte **new_info_ptr, + struct die_info *parent); + static struct die_info *read_die_and_children (gdb_byte *info_ptr, bfd *abfd, struct dwarf2_cu *, gdb_byte **new_info_ptr, @@ -986,15 +1010,19 @@ static char *dwarf_cfi_name (unsigned int); static struct die_info *sibling_die (struct die_info *); -static void dump_die (struct die_info *); +static void dump_die_shallow (struct ui_file *, int indent, struct die_info *); -static void dump_die_list (struct die_info *); +static void dump_die_for_error (struct die_info *); + +static void dump_die_1 (struct ui_file *, int level, int max_level, + struct die_info *); + +/*static*/ void dump_die (struct die_info *, int max_level); static void store_in_ref_table (struct die_info *, struct dwarf2_cu *); -static unsigned int dwarf2_get_ref_die_offset (struct attribute *, - struct dwarf2_cu *); +static unsigned int dwarf2_get_ref_die_offset (struct attribute *); static int dwarf2_get_attr_constant_value (struct attribute *, int); @@ -1038,10 +1066,10 @@ static hashval_t partial_die_hash (const void *item); static int partial_die_eq (const void *item_lhs, const void *item_rhs); static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit - (unsigned long offset, struct objfile *objfile); + (unsigned int offset, struct objfile *objfile); static struct dwarf2_per_cu_data *dwarf2_find_comp_unit - (unsigned long offset, struct objfile *objfile); + (unsigned int offset, struct objfile *objfile); static void free_one_comp_unit (void *); @@ -1293,11 +1321,9 @@ dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline) pubnames_ptr = pubnames_buffer; while ((pubnames_ptr - pubnames_buffer) < dwarf2_per_objfile->pubnames_size) { - struct comp_unit_head cu_header; unsigned int bytes_read; - entry_length = read_initial_length (abfd, pubnames_ptr, &cu_header, - &bytes_read); + entry_length = read_initial_length (abfd, pubnames_ptr, &bytes_read); pubnames_ptr += bytes_read; version = read_1_byte (abfd, pubnames_ptr); pubnames_ptr += 1; @@ -1313,6 +1339,18 @@ dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline) } #endif +/* Return TRUE if OFFSET is within CU_HEADER. */ + +static inline int +offset_in_cu_p (const struct comp_unit_head *cu_header, unsigned int offset) +{ + unsigned int bottom = cu_header->offset; + unsigned int top = (cu_header->offset + + cu_header->length + + cu_header->initial_length_size); + return (offset >= bottom && offset < top); +} + /* Read in the comp unit header information from the debug_info at info_ptr. */ @@ -1322,13 +1360,15 @@ read_comp_unit_head (struct comp_unit_head *cu_header, { int signed_addr; unsigned int bytes_read; - cu_header->length = read_initial_length (abfd, info_ptr, cu_header, - &bytes_read); + + cu_header->length = read_initial_length (abfd, info_ptr, &bytes_read); + cu_header->initial_length_size = bytes_read; + cu_header->offset_size = (bytes_read == 4) ? 4 : 8; info_ptr += bytes_read; cu_header->version = read_2_bytes (abfd, info_ptr); info_ptr += 2; cu_header->abbrev_offset = read_offset (abfd, info_ptr, cu_header, - &bytes_read); + &bytes_read); info_ptr += bytes_read; cu_header->addr_size = read_1_byte (abfd, info_ptr); info_ptr += 1; @@ -1337,6 +1377,7 @@ read_comp_unit_head (struct comp_unit_head *cu_header, internal_error (__FILE__, __LINE__, _("read_comp_unit_head: dwarf from non elf file")); cu_header->signed_addr_p = signed_addr; + return info_ptr; } @@ -1493,8 +1534,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) /* Complete the cu_header */ cu.header.offset = beg_of_comp_unit - dwarf2_per_objfile->info_buffer; - cu.header.first_die_ptr = info_ptr; - cu.header.cu_head_ptr = beg_of_comp_unit; + cu.header.first_die_offset = info_ptr - beg_of_comp_unit; cu.list_in_scope = &file_symbols; @@ -1529,7 +1569,9 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) objfile->static_psymbols.next); if (comp_unit_die.dirname) - pst->dirname = xstrdup (comp_unit_die.dirname); + pst->dirname = obsavestring (comp_unit_die.dirname, + strlen (comp_unit_die.dirname), + &objfile->objfile_obstack); pst->read_symtab_private = (char *) this_cu; @@ -1658,8 +1700,7 @@ load_comp_unit (struct dwarf2_per_cu_data *this_cu, struct objfile *objfile) /* Complete the cu_header. */ cu->header.offset = beg_of_comp_unit - dwarf2_per_objfile->info_buffer; - cu->header.first_die_ptr = info_ptr; - cu->header.cu_head_ptr = beg_of_comp_unit; + cu->header.first_die_offset = info_ptr - beg_of_comp_unit; /* Read the abbrevs for this compilation unit into a table. */ dwarf2_read_abbrevs (abfd, cu); @@ -1707,26 +1748,24 @@ create_all_comp_units (struct objfile *objfile) while (info_ptr < dwarf2_per_objfile->info_buffer + dwarf2_per_objfile->info_size) { - struct comp_unit_head cu_header; + unsigned int length, initial_length_size; gdb_byte *beg_of_comp_unit; struct dwarf2_per_cu_data *this_cu; - unsigned long offset; - unsigned int bytes_read; + unsigned int offset; offset = info_ptr - dwarf2_per_objfile->info_buffer; /* Read just enough information to find out where the next compilation unit is. */ - cu_header.initial_length_size = 0; - cu_header.length = read_initial_length (objfile->obfd, info_ptr, - &cu_header, &bytes_read); + length = read_initial_length (objfile->obfd, info_ptr, + &initial_length_size); /* Save the compilation unit for later lookup. */ this_cu = obstack_alloc (&objfile->objfile_obstack, sizeof (struct dwarf2_per_cu_data)); memset (this_cu, 0, sizeof (*this_cu)); this_cu->offset = offset; - this_cu->length = cu_header.length + cu_header.initial_length_size; + this_cu->length = length + initial_length_size; if (n_comp_units == n_allocated) { @@ -1781,21 +1820,7 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc, switch (pdi->tag) { case DW_TAG_subprogram: - if (pdi->has_pc_info) - { - if (pdi->lowpc < *lowpc) - { - *lowpc = pdi->lowpc; - } - if (pdi->highpc > *highpc) - { - *highpc = pdi->highpc; - } - if (!pdi->is_declaration) - { - add_partial_symbol (pdi, cu); - } - } + add_partial_subprogram (pdi, lowpc, highpc, cu); break; case DW_TAG_variable: case DW_TAG_typedef: @@ -2145,6 +2170,51 @@ add_partial_namespace (struct partial_die_info *pdi, scan_partial_symbols (pdi->die_child, lowpc, highpc, cu); } +/* Read a partial die corresponding to a subprogram and create a partial + symbol for that subprogram. When the CU language allows it, this + routine also defines a partial symbol for each nested subprogram + that this subprogram contains. + + DIE my also be a lexical block, in which case we simply search + recursively for suprograms defined inside that lexical block. + Again, this is only performed when the CU language allows this + type of definitions. */ + +static void +add_partial_subprogram (struct partial_die_info *pdi, + CORE_ADDR *lowpc, CORE_ADDR *highpc, + struct dwarf2_cu *cu) +{ + if (pdi->tag == DW_TAG_subprogram) + { + if (pdi->has_pc_info) + { + if (pdi->lowpc < *lowpc) + *lowpc = pdi->lowpc; + if (pdi->highpc > *highpc) + *highpc = pdi->highpc; + if (!pdi->is_declaration) + add_partial_symbol (pdi, cu); + } + } + + if (! pdi->has_children) + return; + + if (cu->language == language_ada) + { + pdi = pdi->die_child; + while (pdi != NULL) + { + fixup_partial_die (pdi, cu); + if (pdi->tag == DW_TAG_subprogram + || pdi->tag == DW_TAG_lexical_block) + add_partial_subprogram (pdi, lowpc, highpc, cu); + pdi = pdi->die_sibling; + } + } +} + /* See if we can figure out if the class lives in a namespace. We do this by looking for a member function; its demangled name will contain namespace info, if there is any. */ @@ -2299,7 +2369,7 @@ skip_one_die (gdb_byte *info_ptr, struct abbrev_info *abbrev, complaint (&symfile_complaints, _("ignoring absolute DW_AT_sibling")); else return dwarf2_per_objfile->info_buffer - + dwarf2_get_ref_die_offset (&attr, cu); + + dwarf2_get_ref_die_offset (&attr); } /* If it isn't DW_AT_sibling, skip this attribute. */ @@ -2562,7 +2632,7 @@ load_full_comp_unit (struct dwarf2_per_cu_data *per_cu, struct objfile *objfile) { bfd *abfd = objfile->obfd; struct dwarf2_cu *cu; - unsigned long offset; + unsigned int offset; gdb_byte *info_ptr; struct cleanup *back_to, *free_cu_cleanup; struct attribute *attr; @@ -2647,22 +2717,22 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu) DW_AT_entry_pc. It's been removed, but GCC still uses this for compilation units with discontinuous ranges. */ - cu->header.base_known = 0; - cu->header.base_address = 0; + cu->base_known = 0; + cu->base_address = 0; attr = dwarf2_attr (cu->dies, DW_AT_entry_pc, cu); if (attr) { - cu->header.base_address = DW_ADDR (attr); - cu->header.base_known = 1; + cu->base_address = DW_ADDR (attr); + cu->base_known = 1; } else { attr = dwarf2_attr (cu->dies, DW_AT_low_pc, cu); if (attr) { - cu->header.base_address = DW_ADDR (attr); - cu->header.base_known = 1; + cu->base_address = DW_ADDR (attr); + cu->base_known = 1; } } @@ -2758,10 +2828,10 @@ process_die (struct die_info *die, struct dwarf2_cu *cu) information contained in these. DW_TAG_imported_declaration dies shouldn't have children; DW_TAG_imported_module dies shouldn't in the C++ case, but conceivably could in the - Fortran case, so we'll have to replace this gdb_assert if - Fortran compilers start generating that info. */ + Fortran case. */ processing_has_namespace_info = 1; - gdb_assert (die->child == NULL); + complaint (&symfile_complaints, _("unsupported tag: '%s'"), + dwarf_tag_name (die->tag)); break; default: new_symbol (die, NULL, cu); @@ -3130,8 +3200,8 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return, CORE_ADDR high = 0; CORE_ADDR baseaddr; - found_base = cu_header->base_known; - base = cu_header->base_address; + found_base = cu->base_known; + base = cu->base_address; if (offset >= dwarf2_per_objfile->ranges_size) { @@ -3292,6 +3362,43 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, return ret; } +/* Assuming that DIE represents a subprogram DIE or a lexical block, get + its low and high PC addresses. Do nothing if these addresses could not + be determined. Otherwise, set LOWPC to the low address if it is smaller, + and HIGHPC to the high address if greater than HIGHPC. */ + +static void +dwarf2_get_subprogram_pc_bounds (struct die_info *die, + CORE_ADDR *lowpc, CORE_ADDR *highpc, + struct dwarf2_cu *cu) +{ + CORE_ADDR low, high; + struct die_info *child = die->child; + + if (dwarf2_get_pc_bounds (die, &low, &high, cu)) + { + *lowpc = min (*lowpc, low); + *highpc = max (*highpc, high); + } + + /* If the language does not allow nested subprograms (either inside + subprograms or lexical blocks), we're done. */ + if (cu->language != language_ada) + return; + + /* Check all the children of the given DIE. If it contains nested + subprograms, then check their pc bounds. Likewise, we need to + check lexical blocks as well, as they may also contain subprogram + definitions. */ + while (child && child->tag) + { + if (child->tag == DW_TAG_subprogram + || child->tag == DW_TAG_lexical_block) + dwarf2_get_subprogram_pc_bounds (child, lowpc, highpc, cu); + child = sibling_die (child); + } +} + /* Get the low and high pc's represented by the scope DIE, and store them in *LOWPC and *HIGHPC. If the correct values can't be determined, set *LOWPC to -1 and *HIGHPC to 0. */ @@ -3318,11 +3425,7 @@ get_scope_pc_bounds (struct die_info *die, { switch (child->tag) { case DW_TAG_subprogram: - if (dwarf2_get_pc_bounds (child, ¤t_low, ¤t_high, cu)) - { - best_low = min (best_low, current_low); - best_high = max (best_high, current_high); - } + dwarf2_get_subprogram_pc_bounds (child, &best_low, &best_high, cu); break; case DW_TAG_namespace: /* FIXME: carlton/2004-01-16: Should we do this for @@ -3398,8 +3501,8 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block, 'baseaddr' argument, which GDB uses to relocate debugging information from a shared library based on the address at which the library was loaded. */ - CORE_ADDR base = cu->header.base_address; - int base_known = cu->header.base_known; + CORE_ADDR base = cu->base_address; + int base_known = cu->base_known; if (offset >= dwarf2_per_objfile->ranges_size) { @@ -3496,7 +3599,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, /* Get type of field. */ fp->type = die_type (die, cu); - FIELD_STATIC_KIND (*fp) = 0; + SET_FIELD_BITPOS (*fp, 0); /* Get bit size of field (zero if none). */ attr = dwarf2_attr (die, DW_AT_bit_size, cu); @@ -3525,10 +3628,8 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, else byte_offset = decode_locdesc (DW_BLOCK (attr), cu); - FIELD_BITPOS (*fp) = byte_offset * bits_per_byte; + SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte); } - else - FIELD_BITPOS (*fp) = 0; attr = dwarf2_attr (die, DW_AT_bit_offset, cu); if (attr) { @@ -3620,10 +3721,9 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, /* C++ base class field. */ attr = dwarf2_attr (die, DW_AT_data_member_location, cu); if (attr) - FIELD_BITPOS (*fp) = (decode_locdesc (DW_BLOCK (attr), cu) - * bits_per_byte); + SET_FIELD_BITPOS (*fp, decode_locdesc (DW_BLOCK (attr), cu) + * bits_per_byte); FIELD_BITSIZE (*fp) = 0; - FIELD_STATIC_KIND (*fp) = 0; FIELD_TYPE (*fp) = die_type (die, cu); FIELD_NAME (*fp) = type_name_no_tag (fp->type); fip->nbaseclasses++; @@ -4048,9 +4148,9 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu) TYPE_LENGTH (type) = 0; } - TYPE_FLAGS (type) |= TYPE_FLAG_STUB_SUPPORTED; + TYPE_STUB_SUPPORTED (type) = 1; if (die_is_declaration (die, cu)) - TYPE_FLAGS (type) |= TYPE_FLAG_STUB; + TYPE_STUB (type) = 1; /* We need to add the type field to the die immediately so we don't infinitely recurse when dealing with pointers to the structure @@ -4240,7 +4340,7 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu) Types. When another package uses such a type, an incomplete DIE may be generated by the compiler. */ if (die_is_declaration (die, cu)) - TYPE_FLAGS (type) |= TYPE_FLAG_STUB; + TYPE_STUB (type) = 1; return set_die_type (die, type, cu); } @@ -4341,9 +4441,8 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu) FIELD_NAME (fields[num_fields]) = SYMBOL_LINKAGE_NAME (sym); FIELD_TYPE (fields[num_fields]) = NULL; - FIELD_BITPOS (fields[num_fields]) = SYMBOL_VALUE (sym); + SET_FIELD_BITPOS (fields[num_fields], SYMBOL_VALUE (sym)); FIELD_BITSIZE (fields[num_fields]) = 0; - FIELD_STATIC_KIND (fields[num_fields]) = 0; num_fields++; } @@ -4362,7 +4461,7 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu) xfree (fields); } if (unsigned_enum) - TYPE_FLAGS (this_type) |= TYPE_FLAG_UNSIGNED; + TYPE_UNSIGNED (this_type) = 1; } new_symbol (die, this_type, cu); @@ -4700,7 +4799,8 @@ read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu) type_flags = gdbarch_address_class_type_flags (gdbarch, byte_size, addr_class); - gdb_assert ((type_flags & ~TYPE_FLAG_ADDRESS_CLASS_ALL) == 0); + gdb_assert ((type_flags & ~TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL) + == 0); type = make_type_with_address_space (type, type_flags); } else if (TYPE_LENGTH (type) != byte_size) @@ -4847,7 +4947,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu) || cu->language == language_cplus || cu->language == language_java || cu->language == language_pascal) - TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED; + TYPE_PROTOTYPED (ftype) = 1; /* Store the calling convention in the type if it's available in the subroutine die. Otherwise set the calling convention to @@ -4870,7 +4970,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu) if (child_die->tag == DW_TAG_formal_parameter) nparams++; else if (child_die->tag == DW_TAG_unspecified_parameters) - TYPE_FLAGS (ftype) |= TYPE_FLAG_VARARGS; + TYPE_VARARGS (ftype) = 1; child_die = sibling_die (child_die); } @@ -5000,7 +5100,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu) TYPE_TARGET_TYPE (type) = target_type; if (name && strcmp (name, "char") == 0) - TYPE_FLAGS (type) |= TYPE_FLAG_NOSIGN; + TYPE_NOSIGN (type) = 1; return set_die_type (die, type, cu); } @@ -5127,6 +5227,27 @@ read_comp_unit (gdb_byte *info_ptr, bfd *abfd, struct dwarf2_cu *cu) return read_die_and_children (info_ptr, abfd, cu, &info_ptr, NULL); } +/* Main entry point for reading a DIE and all children. + Read the DIE and dump it if requested. */ + +static struct die_info * +read_die_and_children (gdb_byte *info_ptr, bfd *abfd, + struct dwarf2_cu *cu, + gdb_byte **new_info_ptr, + struct die_info *parent) +{ + struct die_info *result = read_die_and_children_1 (info_ptr, abfd, cu, + new_info_ptr, parent); + + if (dwarf2_die_debug) + { + fprintf_unfiltered (gdb_stdlog, "Read die from .debug_info:\n"); + dump_die (result, dwarf2_die_debug); + } + + return result; +} + /* Read a single die and all its descendents. Set the die's sibling field to NULL; set other fields in the die correctly, and set all of the descendents' fields correctly. Set *NEW_INFO_PTR to the @@ -5134,10 +5255,10 @@ read_comp_unit (gdb_byte *info_ptr, bfd *abfd, struct dwarf2_cu *cu) is the parent of the die in question. */ static struct die_info * -read_die_and_children (gdb_byte *info_ptr, bfd *abfd, - struct dwarf2_cu *cu, - gdb_byte **new_info_ptr, - struct die_info *parent) +read_die_and_children_1 (gdb_byte *info_ptr, bfd *abfd, + struct dwarf2_cu *cu, + gdb_byte **new_info_ptr, + struct die_info *parent) { struct die_info *die; gdb_byte *cur_ptr; @@ -5186,7 +5307,7 @@ read_die_and_siblings (gdb_byte *info_ptr, bfd *abfd, while (1) { struct die_info *die - = read_die_and_children (cur_ptr, abfd, cu, &cur_ptr, parent); + = read_die_and_children_1 (cur_ptr, abfd, cu, &cur_ptr, parent); if (die == NULL) { @@ -5564,6 +5685,7 @@ load_partial_dies (bfd *abfd, gdb_byte *info_ptr, int building_psymtab, && !is_type_tag_for_partial (abbrev->tag) && abbrev->tag != DW_TAG_enumerator && abbrev->tag != DW_TAG_subprogram + && abbrev->tag != DW_TAG_lexical_block && abbrev->tag != DW_TAG_variable && abbrev->tag != DW_TAG_namespace && abbrev->tag != DW_TAG_member) @@ -5686,9 +5808,14 @@ load_partial_dies (bfd *abfd, gdb_byte *info_ptr, int building_psymtab, sizeof (struct partial_die_info)); /* For some DIEs we want to follow their children (if any). For C - we have no reason to follow the children of structures; for other + we have no reason to follow the children of structures; for other languages we have to, both so that we can get at method physnames - to infer fully qualified class names, and for DW_AT_specification. */ + to infer fully qualified class names, and for DW_AT_specification. + + For Ada, we need to scan the children of subprograms and lexical + blocks as well because Ada allows the definition of nested + entities that could be interesting for the debugger, such as + nested subprograms for instance. */ if (last_die->has_children && (load_all || last_die->tag == DW_TAG_namespace @@ -5697,7 +5824,10 @@ load_partial_dies (bfd *abfd, gdb_byte *info_ptr, int building_psymtab, && (last_die->tag == DW_TAG_class_type || last_die->tag == DW_TAG_interface_type || last_die->tag == DW_TAG_structure_type - || last_die->tag == DW_TAG_union_type)))) + || last_die->tag == DW_TAG_union_type)) + || (cu->language == language_ada + && (last_die->tag == DW_TAG_subprogram + || last_die->tag == DW_TAG_lexical_block)))) { nesting_level++; parent_die = last_die; @@ -5827,7 +5957,7 @@ read_partial_die (struct partial_die_info *part_die, case DW_AT_specification: case DW_AT_extension: part_die->has_specification = 1; - part_die->spec_offset = dwarf2_get_ref_die_offset (&attr, cu); + part_die->spec_offset = dwarf2_get_ref_die_offset (&attr); break; case DW_AT_sibling: /* Ignore absolute siblings, they might point outside of @@ -5836,7 +5966,7 @@ read_partial_die (struct partial_die_info *part_die, complaint (&symfile_complaints, _("ignoring absolute DW_AT_sibling")); else part_die->sibling = dwarf2_per_objfile->info_buffer - + dwarf2_get_ref_die_offset (&attr, cu); + + dwarf2_get_ref_die_offset (&attr); break; case DW_AT_stmt_list: part_die->has_stmt_list = 1; @@ -5883,11 +6013,11 @@ read_partial_die (struct partial_die_info *part_die, || dwarf2_per_objfile->has_section_at_zero)) part_die->has_pc_info = 1; - if (base_address_type != base_address_none && !cu->header.base_known) + if (base_address_type != base_address_none && !cu->base_known) { gdb_assert (part_die->tag == DW_TAG_compile_unit); - cu->header.base_known = 1; - cu->header.base_address = base_address; + cu->base_known = 1; + cu->base_address = base_address; } return info_ptr; @@ -5896,7 +6026,7 @@ read_partial_die (struct partial_die_info *part_die, /* Find a cached partial DIE at OFFSET in CU. */ static struct partial_die_info * -find_partial_die_in_comp_unit (unsigned long offset, struct dwarf2_cu *cu) +find_partial_die_in_comp_unit (unsigned int offset, struct dwarf2_cu *cu) { struct partial_die_info *lookup_die = NULL; struct partial_die_info part_die; @@ -5910,13 +6040,12 @@ find_partial_die_in_comp_unit (unsigned long offset, struct dwarf2_cu *cu) /* Find a partial DIE at OFFSET, which may or may not be in CU. */ static struct partial_die_info * -find_partial_die (unsigned long offset, struct dwarf2_cu *cu) +find_partial_die (unsigned int offset, struct dwarf2_cu *cu) { struct dwarf2_per_cu_data *per_cu = NULL; struct partial_die_info *pd = NULL; - if (offset >= cu->header.offset - && offset < cu->header.offset + cu->header.length) + if (offset_in_cu_p (&cu->header, offset)) { pd = find_partial_die_in_comp_unit (offset, cu); if (pd != NULL) @@ -5952,7 +6081,9 @@ find_partial_die (unsigned long offset, struct dwarf2_cu *cu) dwarf2_read_abbrevs (per_cu->cu->objfile->obfd, per_cu->cu); back_to = make_cleanup (dwarf2_free_abbrev_table, per_cu->cu); } - info_ptr = per_cu->cu->header.first_die_ptr; + info_ptr = (dwarf2_per_objfile->info_buffer + + per_cu->cu->header.offset + + per_cu->cu->header.first_die_offset); abbrev = peek_die_abbrev (info_ptr, &bytes_read, per_cu->cu); info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read, per_cu->cu->objfile->obfd, info_ptr, @@ -5966,7 +6097,7 @@ find_partial_die (unsigned long offset, struct dwarf2_cu *cu) if (pd == NULL) internal_error (__FILE__, __LINE__, - _("could not find partial DIE 0x%lx in cache [from module %s]\n"), + _("could not find partial DIE 0x%x in cache [from module %s]\n"), offset, bfd_get_filename (cu->objfile->obfd)); return pd; } @@ -6324,12 +6455,7 @@ read_address (bfd *abfd, gdb_byte *buf, struct dwarf2_cu *cu, The value returned via bytes_read should be used to increment the relevant pointer after calling read_initial_length(). - - As a side effect, this function sets the fields initial_length_size - and offset_size in cu_header to the values appropriate for the - length field. (The format of the initial length field determines - the width of file offsets to be fetched later with read_offset().) - + [ Note: read_initial_length() and read_offset() are based on the document entitled "DWARF Debugging Information Format", revision 3, draft 8, dated November 19, 2001. This document was obtained @@ -6347,8 +6473,7 @@ read_address (bfd *abfd, gdb_byte *buf, struct dwarf2_cu *cu, ] */ static LONGEST -read_initial_length (bfd *abfd, gdb_byte *buf, struct comp_unit_head *cu_header, - unsigned int *bytes_read) +read_initial_length (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read) { LONGEST length = bfd_get_32 (abfd, buf); @@ -6368,22 +6493,34 @@ read_initial_length (bfd *abfd, gdb_byte *buf, struct comp_unit_head *cu_header, *bytes_read = 4; } - if (cu_header) - { - gdb_assert (cu_header->initial_length_size == 0 - || cu_header->initial_length_size == 4 - || cu_header->initial_length_size == 8 - || cu_header->initial_length_size == 12); + return length; +} - if (cu_header->initial_length_size != 0 - && cu_header->initial_length_size != *bytes_read) - complaint (&symfile_complaints, - _("intermixed 32-bit and 64-bit DWARF sections")); +/* Cover function for read_initial_length. + Returns the length of the object at BUF, and stores the size of the + initial length in *BYTES_READ and stores the size that offsets will be in + *OFFSET_SIZE. + If the initial length size is not equivalent to that specified in + CU_HEADER then issue a complaint. + This is useful when reading non-comp-unit headers. */ - cu_header->initial_length_size = *bytes_read; - cu_header->offset_size = (*bytes_read == 4) ? 4 : 8; - } +static LONGEST +read_checked_initial_length_and_offset (bfd *abfd, gdb_byte *buf, + const struct comp_unit_head *cu_header, + unsigned int *bytes_read, + unsigned int *offset_size) +{ + LONGEST length = read_initial_length (abfd, buf, bytes_read); + gdb_assert (cu_header->initial_length_size == 4 + || cu_header->initial_length_size == 8 + || cu_header->initial_length_size == 12); + + if (cu_header->initial_length_size != *bytes_read) + complaint (&symfile_complaints, + _("intermixed 32-bit and 64-bit DWARF sections")); + + *offset_size = (*bytes_read == 4) ? 4 : 8; return length; } @@ -6393,22 +6530,30 @@ read_initial_length (bfd *abfd, gdb_byte *buf, struct comp_unit_head *cu_header, static LONGEST read_offset (bfd *abfd, gdb_byte *buf, const struct comp_unit_head *cu_header, unsigned int *bytes_read) +{ + LONGEST offset = read_offset_1 (abfd, buf, cu_header->offset_size); + *bytes_read = cu_header->offset_size; + return offset; +} + +/* Read an offset from the data stream. */ + +static LONGEST +read_offset_1 (bfd *abfd, gdb_byte *buf, unsigned int offset_size) { LONGEST retval = 0; - switch (cu_header->offset_size) + switch (offset_size) { case 4: retval = bfd_get_32 (abfd, buf); - *bytes_read = 4; break; case 8: retval = bfd_get_64 (abfd, buf); - *bytes_read = 8; break; default: internal_error (__FILE__, __LINE__, - _("read_offset: bad switch [in module %s]"), + _("read_offset_1: bad switch [in module %s]"), bfd_get_filename (abfd)); } @@ -6446,8 +6591,7 @@ read_indirect_string (bfd *abfd, gdb_byte *buf, const struct comp_unit_head *cu_header, unsigned int *bytes_read_ptr) { - LONGEST str_offset = read_offset (abfd, buf, cu_header, - bytes_read_ptr); + LONGEST str_offset = read_offset (abfd, buf, cu_header, bytes_read_ptr); if (dwarf2_per_objfile->str_buffer == NULL) { @@ -6746,7 +6890,7 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd, struct cleanup *back_to; struct line_header *lh; gdb_byte *line_ptr; - unsigned int bytes_read; + unsigned int bytes_read, offset_size; int i; char *cur_dir, *cur_file; @@ -6773,7 +6917,8 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd, /* Read in the header. */ lh->total_length = - read_initial_length (abfd, line_ptr, &cu->header, &bytes_read); + read_checked_initial_length_and_offset (abfd, line_ptr, &cu->header, + &bytes_read, &offset_size); line_ptr += bytes_read; if (line_ptr + lh->total_length > (dwarf2_per_objfile->line_buffer + dwarf2_per_objfile->line_size)) @@ -6784,8 +6929,8 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd, lh->statement_program_end = line_ptr + lh->total_length; lh->version = read_2_bytes (abfd, line_ptr); line_ptr += 2; - lh->header_length = read_offset (abfd, line_ptr, &cu->header, &bytes_read); - line_ptr += bytes_read; + lh->header_length = read_offset_1 (abfd, line_ptr, offset_size); + line_ptr += offset_size; lh->minimum_instruction_length = read_1_byte (abfd, line_ptr); line_ptr += 1; lh->default_is_stmt = read_1_byte (abfd, line_ptr); @@ -6955,6 +7100,11 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, { op_code = read_1_byte (abfd, line_ptr); line_ptr += 1; + if (line_ptr > line_end) + { + dwarf2_debug_line_missing_end_sequence_complaint (); + break; + } if (op_code >= lh->opcode_base) { @@ -6963,7 +7113,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, address += (adj_opcode / lh->line_range) * lh->minimum_instruction_length; line += lh->line_base + (adj_opcode % lh->line_range); - if (lh->num_file_names < file) + if (lh->num_file_names < file || file == 0) dwarf2_debug_line_missing_file_complaint (); else { @@ -6995,15 +7145,6 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, { case DW_LNE_end_sequence: end_sequence = 1; - - if (lh->num_file_names < file) - dwarf2_debug_line_missing_file_complaint (); - else - { - lh->file_names[file - 1].included_p = 1; - if (!decode_for_pst_p) - record_line (current_subfile, 0, address); - } break; case DW_LNE_set_address: address = read_address (abfd, line_ptr, cu, &bytes_read); @@ -7045,7 +7186,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, } break; case DW_LNS_copy: - if (lh->num_file_names < file) + if (lh->num_file_names < file || file == 0) dwarf2_debug_line_missing_file_complaint (); else { @@ -7083,7 +7224,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; - if (lh->num_file_names < file) + if (lh->num_file_names < file || file == 0) dwarf2_debug_line_missing_file_complaint (); else { @@ -7134,6 +7275,14 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, } } } + if (lh->num_file_names < file || file == 0) + dwarf2_debug_line_missing_file_complaint (); + else + { + lh->file_names[file - 1].included_p = 1; + if (!decode_for_pst_p) + record_line (current_subfile, 0, address); + } } if (decode_for_pst_p) @@ -7721,7 +7870,7 @@ die_type (struct die_info *die, struct dwarf2_cu *cu) type = tag_type_to_type (type_die, cu); if (!type) { - dump_die (type_die); + dump_die_for_error (type_die); error (_("Dwarf Error: Problem turning type die at offset into gdb type [in module %s]"), cu->objfile->name); } @@ -7747,7 +7896,7 @@ die_containing_type (struct die_info *die, struct dwarf2_cu *cu) if (!type) { if (type_die) - dump_die (type_die); + dump_die_for_error (type_die); error (_("Dwarf Error: Problem turning containing type into gdb type [in module %s]"), cu->objfile->name); } @@ -7762,7 +7911,7 @@ tag_type_to_type (struct die_info *die, struct dwarf2_cu *cu) this_type = read_type_die (die, cu); if (!this_type) { - dump_die (die); + dump_die_for_error (die); error (_("Dwarf Error: Cannot find type of die [in module %s]"), cu->objfile->name); } @@ -7944,19 +8093,17 @@ typename_concat (struct obstack *obs, const char *prefix, const char *suffix, else sep = "::"; + if (prefix == NULL) + prefix = ""; + if (suffix == NULL) + suffix = ""; + if (obs == NULL) { char *retval = xmalloc (strlen (prefix) + MAX_SEP_LEN + strlen (suffix) + 1); - retval[0] = '\0'; - - if (prefix) - { - strcpy (retval, prefix); - strcat (retval, sep); - } - if (suffix) - strcat (retval, suffix); - + strcpy (retval, prefix); + strcat (retval, sep); + strcat (retval, suffix); return retval; } else @@ -8357,10 +8504,11 @@ dwarf_attr_name (unsigned attr) return "DW_AT_pure"; case DW_AT_recursive: return "DW_AT_recursive"; -#ifdef MIPS /* SGI/MIPS extensions. */ +#ifdef MIPS /* collides with DW_AT_HP_block_index */ case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde"; +#endif case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin"; case DW_AT_MIPS_tail_loop_begin: @@ -8381,10 +8529,11 @@ dwarf_attr_name (unsigned attr) return "DW_AT_MIPS_clone_origin"; case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines"; -#endif /* HP extensions. */ +#ifndef MIPS /* collides with DW_AT_MIPS_fde */ case DW_AT_HP_block_index: return "DW_AT_HP_block_index"; +#endif case DW_AT_HP_unmodifiable: return "DW_AT_HP_unmodifiable"; case DW_AT_HP_actuals_stmt_list: @@ -8980,38 +9129,52 @@ dwarf_cfi_name (unsigned cfi_opc) #endif static void -dump_die (struct die_info *die) +dump_die_shallow (struct ui_file *f, int indent, struct die_info *die) { unsigned int i; - fprintf_unfiltered (gdb_stderr, "Die: %s (abbrev = %d, offset = %d)\n", + print_spaces (indent, f); + fprintf_unfiltered (f, "Die: %s (abbrev %d, offset 0x%x)\n", dwarf_tag_name (die->tag), die->abbrev, die->offset); - fprintf_unfiltered (gdb_stderr, "\thas children: %s\n", + + if (die->parent != NULL) + { + print_spaces (indent, f); + fprintf_unfiltered (f, " parent at offset: 0x%x\n", + die->parent->offset); + } + + print_spaces (indent, f); + fprintf_unfiltered (f, " has children: %s\n", dwarf_bool_name (die->child != NULL)); - fprintf_unfiltered (gdb_stderr, "\tattributes:\n"); + print_spaces (indent, f); + fprintf_unfiltered (f, " attributes:\n"); + for (i = 0; i < die->num_attrs; ++i) { - fprintf_unfiltered (gdb_stderr, "\t\t%s (%s) ", + print_spaces (indent, f); + fprintf_unfiltered (f, " %s (%s) ", dwarf_attr_name (die->attrs[i].name), dwarf_form_name (die->attrs[i].form)); + switch (die->attrs[i].form) { case DW_FORM_ref_addr: case DW_FORM_addr: - fprintf_unfiltered (gdb_stderr, "address: "); - fputs_filtered (paddress (DW_ADDR (&die->attrs[i])), gdb_stderr); + fprintf_unfiltered (f, "address: "); + fputs_filtered (paddress (DW_ADDR (&die->attrs[i])), f); break; case DW_FORM_block2: case DW_FORM_block4: case DW_FORM_block: case DW_FORM_block1: - fprintf_unfiltered (gdb_stderr, "block: size %d", DW_BLOCK (&die->attrs[i])->size); + fprintf_unfiltered (f, "block: size %d", DW_BLOCK (&die->attrs[i])->size); break; case DW_FORM_ref1: case DW_FORM_ref2: case DW_FORM_ref4: - fprintf_unfiltered (gdb_stderr, "constant ref: %ld (adjusted)", + fprintf_unfiltered (f, "constant ref: 0x%lx (adjusted)", (long) (DW_ADDR (&die->attrs[i]))); break; case DW_FORM_data1: @@ -9020,46 +9183,82 @@ dump_die (struct die_info *die) case DW_FORM_data8: case DW_FORM_udata: case DW_FORM_sdata: - fprintf_unfiltered (gdb_stderr, "constant: %ld", DW_UNSND (&die->attrs[i])); + fprintf_unfiltered (f, "constant: %ld", DW_UNSND (&die->attrs[i])); break; case DW_FORM_string: case DW_FORM_strp: - fprintf_unfiltered (gdb_stderr, "string: \"%s\"", + fprintf_unfiltered (f, "string: \"%s\"", DW_STRING (&die->attrs[i]) ? DW_STRING (&die->attrs[i]) : ""); break; case DW_FORM_flag: if (DW_UNSND (&die->attrs[i])) - fprintf_unfiltered (gdb_stderr, "flag: TRUE"); + fprintf_unfiltered (f, "flag: TRUE"); else - fprintf_unfiltered (gdb_stderr, "flag: FALSE"); + fprintf_unfiltered (f, "flag: FALSE"); break; case DW_FORM_indirect: /* the reader will have reduced the indirect form to the "base form" so this form should not occur */ - fprintf_unfiltered (gdb_stderr, "unexpected attribute form: DW_FORM_indirect"); + fprintf_unfiltered (f, "unexpected attribute form: DW_FORM_indirect"); break; default: - fprintf_unfiltered (gdb_stderr, "unsupported attribute form: %d.", + fprintf_unfiltered (f, "unsupported attribute form: %d.", die->attrs[i].form); + break; } - fprintf_unfiltered (gdb_stderr, "\n"); + fprintf_unfiltered (f, "\n"); } } static void -dump_die_list (struct die_info *die) +dump_die_for_error (struct die_info *die) +{ + dump_die_shallow (gdb_stderr, 0, die); +} + +static void +dump_die_1 (struct ui_file *f, int level, int max_level, struct die_info *die) { - while (die) + int indent = level * 4; + + gdb_assert (die != NULL); + + if (level >= max_level) + return; + + dump_die_shallow (f, indent, die); + + if (die->child != NULL) + { + print_spaces (indent, f); + fprintf_unfiltered (f, " Children:"); + if (level + 1 < max_level) + { + fprintf_unfiltered (f, "\n"); + dump_die_1 (f, level + 1, max_level, die->child); + } + else + { + fprintf_unfiltered (f, " [not printed, max nesting level reached]\n"); + } + } + + if (die->sibling != NULL && level > 0) { - dump_die (die); - if (die->child != NULL) - dump_die_list (die->child); - if (die->sibling != NULL) - dump_die_list (die->sibling); + dump_die_1 (f, level, max_level, die->sibling); } } +/* This is called from the pdie macro in gdbinit.in. + It's not static so gcc will keep a copy callable from gdb. */ + +void +dump_die (struct die_info *die, int max_level) +{ + dump_die_1 (gdb_stdlog, 0, max_level, die); +} + static void store_in_ref_table (struct die_info *die, struct dwarf2_cu *cu) { @@ -9071,7 +9270,7 @@ store_in_ref_table (struct die_info *die, struct dwarf2_cu *cu) } static unsigned int -dwarf2_get_ref_die_offset (struct attribute *attr, struct dwarf2_cu *cu) +dwarf2_get_ref_die_offset (struct attribute *attr) { unsigned int result = 0; @@ -9151,14 +9350,12 @@ follow_die_ref (struct die_info *src_die, struct attribute *attr, struct die_info temp_die; struct dwarf2_cu *target_cu, *cu = *ref_cu; - offset = dwarf2_get_ref_die_offset (attr, cu); + offset = dwarf2_get_ref_die_offset (attr); - if (DW_ADDR (attr) < cu->header.offset - || DW_ADDR (attr) >= cu->header.offset + cu->header.length) + if (! offset_in_cu_p (&cu->header, offset)) { struct dwarf2_per_cu_data *per_cu; - per_cu = dwarf2_find_containing_comp_unit (DW_ADDR (attr), - cu->objfile); + per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile); /* If necessary, add it to the queue and load its DIEs. */ maybe_queue_comp_unit (cu, per_cu); @@ -9913,8 +10110,8 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, don't run off the edge of the section. */ baton->size = dwarf2_per_objfile->loc_size - DW_UNSND (attr); baton->data = dwarf2_per_objfile->loc_buffer + DW_UNSND (attr); - baton->base_address = cu->header.base_address; - if (cu->header.base_known == 0) + baton->base_address = cu->base_address; + if (cu->base_known == 0) complaint (&symfile_complaints, _("Location list used without specifying the CU base address.")); @@ -9994,7 +10191,7 @@ dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *per_cu) DIE at OFFSET. Raises an error on failure. */ static struct dwarf2_per_cu_data * -dwarf2_find_containing_comp_unit (unsigned long offset, +dwarf2_find_containing_comp_unit (unsigned int offset, struct objfile *objfile) { struct dwarf2_per_cu_data *this_cu; @@ -10026,7 +10223,7 @@ dwarf2_find_containing_comp_unit (unsigned long offset, this_cu = dwarf2_per_objfile->all_comp_units[low]; if (low == dwarf2_per_objfile->n_comp_units - 1 && offset >= this_cu->offset + this_cu->length) - error (_("invalid dwarf2 offset %ld"), offset); + error (_("invalid dwarf2 offset %u"), offset); gdb_assert (offset < this_cu->offset + this_cu->length); return this_cu; } @@ -10036,12 +10233,12 @@ dwarf2_find_containing_comp_unit (unsigned long offset, OFFSET. Raises an error on failure. */ static struct dwarf2_per_cu_data * -dwarf2_find_comp_unit (unsigned long offset, struct objfile *objfile) +dwarf2_find_comp_unit (unsigned int offset, struct objfile *objfile) { struct dwarf2_per_cu_data *this_cu; this_cu = dwarf2_find_containing_comp_unit (offset, objfile); if (this_cu->offset != offset) - error (_("no compilation unit with offset %ld."), offset); + error (_("no compilation unit with offset %u."), offset); return this_cu; } @@ -10403,4 +10600,13 @@ caching, which can slow down startup."), show_dwarf2_max_cache_age, &set_dwarf2_cmdlist, &show_dwarf2_cmdlist); + + add_setshow_zinteger_cmd ("dwarf2-die", no_class, &dwarf2_die_debug, _("\ +Set debugging of the dwarf2 DIE reader."), _("\ +Show debugging of the dwarf2 DIE reader."), _("\ +When enabled (non-zero), DIEs are dumped after they are read in.\n\ +The value is the maximum depth to print."), + NULL, + NULL, + &setdebuglist, &showdebuglist); }