This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [RFA] misc dwarf2 cleanup
- From: "Doug Evans" <dje at google dot com>
- To: gdb-patches at sourceware dot org
- Date: Wed, 8 Oct 2008 08:37:04 -0700
- Subject: Re: [RFA] misc dwarf2 cleanup
- References: <20080929204513.D47831C78E0@localhost>
Ping.
One question I have is it seems dwarf2_cu.has_form_ref_addr is never
used. More cleanups to come I guess.
On Mon, Sep 29, 2008 at 1:45 PM, Doug Evans <dje@google.com> wrote:
> Hi. This patch makes four changes to dwarf2read.c:
>
> 1) Use unsigned int consistently for dwarf section offsets and sizes.
> Daniel suggested dwarf_off_t but I went with unsigned int for now.
> It's a _far_ smaller change, and since the type is internal to
> dwarf2read.c making more extensive changes didn't seem compelling
> (at least at this point in time).
>
> 2) Make read_initial_length do only that: read the initial length and
> not also modify cu_header.
> I added a new function read_checked_initial_length_and_offset
> for dwarf_decode_line_header.
>
> 3) Remove unused arg `cu' from dwarf2_get_ref_die_offset.
>
> 4) Unconditionally support DW_AT_MIPS_* in pretty printing.
> [except DW_AT_MIPS_fde which collides with DW_AT_HP_block_index]
> DW_AT_MIPS_linkage_name was showing up as unknown.
> I realize we want it to go away, but while it's there pretty-printers
> should handle it.
>
> Ok to check in?
>
> 2008-09-29 Doug Evans <dje@google.com>
>
> * 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.
>
> Index: dwarf2read.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/dwarf2read.c,v
> retrieving revision 1.284
> diff -u -p -u -p -r1.284 dwarf2read.c
> --- dwarf2read.c 23 Sep 2008 17:36:51 -0000 1.284
> +++ dwarf2read.c 29 Sep 2008 20:43:08 -0000
> @@ -231,7 +231,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;
> @@ -296,7 +296,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. */
> @@ -361,12 +361,12 @@ 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;
> + 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
> @@ -796,7 +796,7 @@ static gdb_byte *read_partial_die (struc
> 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 *,
> @@ -824,11 +824,16 @@ static unsigned long read_8_bytes (bfd *
> 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);
>
> @@ -994,8 +999,7 @@ static void dump_die_list (struct die_in
> 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);
>
> @@ -1039,10 +1043,10 @@ static hashval_t partial_die_hash (const
> 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 *);
>
> @@ -1294,11 +1298,9 @@ dwarf2_build_psymtabs_easy (struct objfi
> 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;
> @@ -1323,13 +1325,15 @@ read_comp_unit_head (struct comp_unit_he
> {
> 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;
> @@ -1338,6 +1342,7 @@ read_comp_unit_head (struct comp_unit_he
> internal_error (__FILE__, __LINE__,
> _("read_comp_unit_head: dwarf from non elf file"));
> cu_header->signed_addr_p = signed_addr;
> +
> return info_ptr;
> }
>
> @@ -1708,26 +1713,24 @@ create_all_comp_units (struct objfile *o
>
> 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)
> {
> @@ -2331,7 +2334,7 @@ skip_one_die (gdb_byte *info_ptr, struct
> 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. */
> @@ -2594,7 +2597,7 @@ load_full_comp_unit (struct dwarf2_per_c
> {
> 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;
> @@ -5869,7 +5872,7 @@ read_partial_die (struct partial_die_inf
> 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
> @@ -5878,7 +5881,7 @@ read_partial_die (struct partial_die_inf
> 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;
> @@ -5938,7 +5941,7 @@ read_partial_die (struct partial_die_inf
> /* 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;
> @@ -5952,7 +5955,7 @@ find_partial_die_in_comp_unit (unsigned
> /* 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;
> @@ -6010,7 +6013,7 @@ find_partial_die (unsigned long offset,
>
> 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;
> }
> @@ -6368,12 +6371,7 @@ read_address (bfd *abfd, gdb_byte *buf,
>
> 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
> @@ -6391,8 +6389,7 @@ read_address (bfd *abfd, gdb_byte *buf,
> ] */
>
> 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);
>
> @@ -6412,22 +6409,34 @@ read_initial_length (bfd *abfd, gdb_byte
> *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;
> }
>
> @@ -6438,21 +6447,29 @@ 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));
> }
>
> @@ -6490,8 +6507,7 @@ read_indirect_string (bfd *abfd, gdb_byt
> 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)
> {
> @@ -6790,7 +6806,7 @@ dwarf_decode_line_header (unsigned int o
> 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;
>
> @@ -6817,7 +6833,8 @@ dwarf_decode_line_header (unsigned int o
>
> /* 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))
> @@ -6828,8 +6845,8 @@ dwarf_decode_line_header (unsigned int o
> 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);
> @@ -8401,10 +8418,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:
> @@ -8425,10 +8443,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:
> @@ -9115,7 +9134,7 @@ store_in_ref_table (struct die_info *die
> }
>
> 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;
>
> @@ -9195,7 +9214,7 @@ follow_die_ref (struct die_info *src_die
> 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)
> @@ -10038,7 +10057,7 @@ dwarf2_per_cu_addr_size (struct dwarf2_p
> 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;
> @@ -10070,7 +10089,7 @@ dwarf2_find_containing_comp_unit (unsign
> 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;
> }
> @@ -10080,12 +10099,12 @@ dwarf2_find_containing_comp_unit (unsign
> 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;
> }
>
>