From c764a876984ebfc21f3635693aebeee4e8d9d0f3 Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Fri, 10 Oct 2008 16:15:42 +0000 Subject: [PATCH] * dwarf2read.c (comp_unit_head): Use unsigned int consistently for dwarf section offsets and sizes. (dwarf2_cu): Ditto. (dwarf2_per_cu_data): Ditto. (create_all_comp_units): Change offset to unsigned int. (load_full_comp_unit,find_partial_die_in_comp_unit,find_partial_die, dwarf2_find_containing_comp_unit,dwarf2_find_comp_unit): Ditto. * dwarf2read.c (read_initial_length): Delete cu_header arg. All callers updated. (read_checked_initial_length_and_offset): New function. (read_offset_1): New function. (read_offset): Call it. (dwarf_decode_line_header): Call read_checked_initial_length_and_offset instead of read_initial_length. Call read_offset_1 instead of read_offset. * dwarf2read.c (dwarf2_get_ref_die_offset): Remove unused arg `cu'. All callers updated. * dwarf2read.c (dwarf_attr_name): Unconditionally support all DW_AT_MIPS_* except DW_AT_MIPS_fde which collides with DW_AT_HP_block_index. --- gdb/ChangeLog | 26 ++++++++ gdb/dwarf2read.c | 163 ++++++++++++++++++++++++++--------------------- 2 files changed, 117 insertions(+), 72 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 37295631e50..81370d2a112 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,29 @@ +2008-10-10 Doug Evans + + * dwarf2read.c (comp_unit_head): Use unsigned int consistently + for dwarf section offsets and sizes. + (dwarf2_cu): Ditto. + (dwarf2_per_cu_data): Ditto. + (create_all_comp_units): Change offset to unsigned int. + (load_full_comp_unit,find_partial_die_in_comp_unit,find_partial_die, + dwarf2_find_containing_comp_unit,dwarf2_find_comp_unit): Ditto. + + * dwarf2read.c (read_initial_length): Delete cu_header arg. + All callers updated. + (read_checked_initial_length_and_offset): New function. + (read_offset_1): New function. + (read_offset): Call it. + (dwarf_decode_line_header): Call read_checked_initial_length_and_offset + instead of read_initial_length. Call read_offset_1 instead of + read_offset. + + * dwarf2read.c (dwarf2_get_ref_die_offset): Remove unused arg `cu'. + All callers updated. + + * dwarf2read.c (dwarf_attr_name): Unconditionally support all + DW_AT_MIPS_* except DW_AT_MIPS_fde which collides with + DW_AT_HP_block_index. + 2008-10-10 Pedro Alves * remote.c (remote_start_remote): Always tell the stub if we're in diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index d894696f23a..840077c8766 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -234,7 +234,7 @@ asection *dwarf_eh_frame_section; translation, looks like this. */ struct comp_unit_head { - unsigned long length; + unsigned int length; short version; unsigned char addr_size; unsigned char signed_addr_p; @@ -299,7 +299,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. */ @@ -366,12 +366,12 @@ struct dwarf2_per_cu_data - if it doesn't, GDB will fall over anyway. NOTE: Unlike comp_unit_head.length, this length includes initial_length_size. */ - unsigned long offset; - unsigned long length : 30; + 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 @@ -801,7 +801,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 *, @@ -829,11 +829,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); @@ -1009,8 +1014,7 @@ static void dump_die_1 (struct ui_file *, int level, 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); @@ -1054,10 +1058,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 *); @@ -1309,11 +1313,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; @@ -1350,13 +1352,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; @@ -1365,6 +1369,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; } @@ -1735,26 +1740,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) { @@ -2358,7 +2361,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. */ @@ -2621,7 +2624,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; @@ -5946,7 +5949,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 @@ -5955,7 +5958,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; @@ -6015,7 +6018,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; @@ -6029,7 +6032,7 @@ 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; @@ -6086,7 +6089,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; } @@ -6444,12 +6447,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 @@ -6467,8 +6465,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); @@ -6488,22 +6485,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; } @@ -6513,22 +6522,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)); } @@ -6566,8 +6583,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) { @@ -6866,7 +6882,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; @@ -6893,7 +6909,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)) @@ -6904,8 +6921,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); @@ -8477,10 +8494,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: @@ -8501,10 +8519,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: @@ -9241,7 +9260,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; @@ -9321,7 +9340,7 @@ 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 (! offset_in_cu_p (&cu->header, offset)) { @@ -10162,7 +10181,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; @@ -10194,7 +10213,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; } @@ -10204,12 +10223,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; } -- 2.30.2