Commit graph

25 commits

Author SHA1 Message Date
Tom de Vries
aa659cfad6 [gdb/symtab] Handle DW_AT_decl_file with form DW_FORM_implicit_const
With test-case gdb.cp/temargs.exp on target board \
unix/gdb:debug_flags=-gdwarf-5 I run into:
...
(gdb) info addr I^M
ERROR: GDB process no longer exists
GDB process exited with wait status 32286 exp19 0 0 CHILDKILLED SIGABRT SIGABRT
UNRESOLVED: gdb.cp/temargs.exp: test address of I in templ_m
...

This is a regression since commit 529908cbd0 "Remove DW_UNSND".

The problem is that this DW_AT_decl_file:
...
 <1><221>: Abbrev Number: 4 (DW_TAG_structure_type)
    <222>   DW_AT_name        : Base<double, 23, (& a_global), &S::f>
    <226>   DW_AT_byte_size   : 1
    <226>   DW_AT_decl_file   : 1
    <226>   DW_AT_decl_line   : 30
    <227>   DW_AT_sibling     : <0x299>
...
is not read by this code in new_symbol:
....
      attr = dwarf2_attr (die,
                          inlined_func ? DW_AT_call_file : DW_AT_decl_file,
                          cu);
      if (attr != nullptr && attr->form_is_unsigned ())
...
because DW_AT_decl_file has form DW_FORM_implicit_const:
...
   4      DW_TAG_structure_type    [has children]
    DW_AT_name         DW_FORM_strp
    DW_AT_byte_size    DW_FORM_implicit_const: 1
    DW_AT_decl_file    DW_FORM_implicit_const: 1
    DW_AT_decl_line    DW_FORM_data1
    DW_AT_sibling      DW_FORM_ref4
    DW_AT value: 0     DW_FORM value: 0
...
which is a signed LEB128, so attr->form_is_unsigned () returns false.

Fix this by introducing new functions is_nonnegative and as_nonnegative, and
use these instead of form_is_unsigned and as_unsigned.

Tested on x86_64-linux.

gdb/ChangeLog:

2021-02-24  Tom de Vries  <tdevries@suse.de>

	PR symtab/27336
	* dwarf2/attribute.c (attribute::form_is_signed): New function
	factored out of ...
	* dwarf2/attribute.h (attribute::as_signed): ... here.
	(attribute::is_nonnegative, attribute::as_nonnegative): New function.
	(attribute::form_is_signed): Declare.
	* dwarf2/read.c (new_symbol): Use is_nonnegative and as_nonnegative
	for DW_AT_decl_file.
2021-02-24 23:58:42 +01:00
Simon Marchi
b1829e1bf2 gdb/dwarf: few fixes for handling DW_FORM_{rng,loc}listx
We hit an assertion when loading the binary from PR 26813.  When fixing
it, execution goes a up bit further but then hits another assert, and
another, and another.  With these fours fixes, I am able to load the
binary and get to the prompt.  An error is shown (index pointing outside
of the section), because the DW_FORM_rnglistx attribute is not read
correctly, but that one is taken care of by the next patch.

The four fixes are:

- attribute::form_requires_reprocessing needs to handle forms
  DW_FORM_rnglistx and DW_FORM_loclistx, because set_unsigned_reprocess
  is called for them in read_attribute_value.

- read_attribute_reprocess must call set_unsigned for them, not
  set_address.  The parameter of set_address is a CORE_ADDR, meaning
  it's for program addresses.  Post-reprocess, DW_FORM_rnglistx and
  DW_FORM_loclistx are offsets into their respective sections
  (.debug_rnglists and .debug_loclists).  set_unsigned is the current
  attribute value setter that fits the best.  But perhaps we should have
  a setter that takes a sect_offset?

- read_attribute_process must call as_unsigned_reprocess instead of
  as_unsigned to get the pre-reprocess value, otherwise we hit the
  assert inside as_unsigned that makes sure the attribute doesn't need
  reprocessing.

- attribute::set_unsigned needs to clear the requires_reprocessing flag,
  otherwise it stays set when reprocessing DW_FORM_rnglistx and
  DW_FORM_loclistx attributes.

There's another assert that we hit once the next patch is applied, but
since it's in the same vein as the changes in this patch, I included it
in this patch:

- attribute::form_is_unsigned must handle form DW_FORM_loclistx,
  otherwise we hit the assert when trying to call set_unsigned for an
  attribute of this form.  DW_FORM_rnglistx is already handled.

gdb/ChangeLog:

	PR gdb/26813
	* dwarf2/attribute.h (struct attribute) <set_unsigned>: Clear
	requires_reprocessing flag.
	* dwarf2/attribute.c (attribute::form_is_unsigned): Handle
	DW_FORM_loclistx.
	(attribute::form_requires_reprocessing): Handle DW_FORM_rnglistx
	and DW_FORM_loclistx.
	* dwarf2/read.c (read_attribute_reprocess): Use set_unsigned
	instead of set_address for DW_FORM_loclistx and
	DW_FORM_rnglistx.

Change-Id: I06c156fa3913ca98e4e39085f4ef171645b4bc1e
2021-02-02 10:40:51 -05:00
Joel Brobecker
3666a04883 Update copyright year range in all GDB files
This commits the result of running gdb/copyright.py as per our Start
of New Year procedure...

gdb/ChangeLog

        Update copyright year range in copyright header of all GDB files.
2021-01-01 12:12:21 +04:00
Tom Tromey
529908cbd0 Remove DW_UNSND
This removes DW_UNSND, replacing uses with either as_unsigned or
constant_value, depending primarily on whether or not the form is
already known to be appropriate.

gdb/ChangeLog
2020-09-29  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (lookup_dwo_id, get_type_unit_group)
	(read_file_scope, dwarf2_get_pc_bounds)
	(dwarf2_record_block_ranges, dwarf2_add_field, get_alignment)
	(read_structure_type, handle_struct_member_die)
	(read_enumeration_type, read_array_type, read_set_type)
	(read_tag_pointer_type, read_tag_reference_type)
	(read_subroutine_type, read_base_type, read_subrange_type)
	(read_full_die_1, partial_die_info::read)
	(partial_die_info::read, by, new_symbol)
	(dwarf2_const_value_data, dwarf2_const_value_attr)
	(dump_die_shallow, dwarf2_fetch_constant_bytes)
	(prepare_one_comp_unit): Update.
	* dwarf2/attribute.h (DW_UNSND): Remove.
2020-09-29 20:29:07 -06:00
Tom Tromey
c45bc3f8ab Add attribute::as_boolean method
This adds a new attribute::as_boolean method, and updates the reader
to use it.  The main benefit of this change is that now the code will
respect the attribute's form.

gdb/ChangeLog
2020-09-29  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (read_func_scope, prototyped_function_p)
	(read_subroutine_type, partial_die_info::read)
	(dwarf2_flag_true_p, new_symbol, dump_die_shallow)
	(dwarf2_add_member_fn): Update.
	* dwarf2/attribute.h (struct attribute) <as_boolean>: Declare.
	* dwarf2/attribute.c (attribute::as_boolean): New method.
2020-09-29 20:29:07 -06:00
Tom Tromey
23dca5c3d7 Add attribute::as_virtuality method
This adds a new attribute::as_virtuality method and changes the DWARF
reader to use it.  This also ensures that the attibute's form will now
be respected.

gdb/ChangeLog
2020-09-29  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (dwarf2_add_field, dwarf2_add_member_fn): Update.
	* dwarf2/attribute.h (struct attribute) <as_virtuality>: New
	method.
	* dwarf2/attribute.c (attribute::as_virtuality): New method.
2020-09-29 20:29:07 -06:00
Tom Tromey
e8e5c1585d Change is_valid_DW_AT_defaulted to a method on attribute
This changes is_valid_DW_AT_defaulted to be a method on struct attribute.
Now it correctly respects the form of the attribute.

gdb/ChangeLog
2020-09-29  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (is_valid_DW_AT_defaulted): Move to attribute.c.
	(dwarf2_add_member_fn): Update.
	* dwarf2/attribute.h (struct attribute) <defaulted>: Declare.
	* dwarf2/attribute.c (attribute::defaulted): New method, from
	is_valid_DW_AT_defaulted.
2020-09-29 20:29:07 -06:00
Tom Tromey
d4df075e8b Add attribute::as_unsigned method
This introduces a new attribute::as_unsigned method and changes a few
spots to use it.

gdb/ChangeLog
2020-09-29  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (dw2_get_file_names_reader)
	(dwarf2_build_include_psymtabs, handle_DW_AT_stmt_list)
	(dwarf2_cu::setup_type_unit_groups, fill_in_loclist_baton)
	(dwarf2_symbol_mark_computed): Use as_unsigned.
	* dwarf2/attribute.h (struct attribute) <as_unsigned>: New
	method.
	<form_is_section_offset>: Update comment.
2020-09-29 20:29:07 -06:00
Tom Tromey
7a5f294dbd Change how reprocessing is done
Currently gdb keeps a vector of attributes that require reprocessing.
However, now that there is a reprocessing flag in the attribute, we
can remove the vector and instead simply loop over attributes a second
time.  Normally there are not many attributes, so this should be
reasonably cheap.

gdb/ChangeLog
2020-09-29  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (skip_one_die): Update.
	(read_full_die_1): Change how reprocessing is done.
	(partial_die_info::read): Update.
	(read_attribute_value): Remove need_reprocess parameter.
	(read_attribute): Likewise.
	* dwarf2/attribute.h (struct attribute) <requires_reprocessing_p>:
	New method.
2020-09-29 20:29:07 -06:00
Tom Tromey
36d378cf86 Remove DW_ADDR
This removes DW_ADDR in favor of accessor methods.

gdb/ChangeLog
2020-09-29  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (read_attribute_reprocess, read_attribute_value)
	(dwarf2_const_value_attr, dump_die_shallow)
	(dwarf2_fetch_constant_bytes): Update.
	* dwarf2/attribute.h (struct attribute) <form_is_ref>: Update
	comment.
	<set_address>: New method.
	(DW_ADDR): Remove.
	* dwarf2/attribute.c (attribute::form_is_ref): Update comment.
	(attribute::as_string, attribute::as_address): Add assert.
2020-09-29 20:29:07 -06:00
Tom Tromey
fe56917a86 Add reprocessing flag to struct attribute
Some forms require "reprocessing" -- a second pass to update their
value appropriately.  In this case, we'll set the unsigned value on
the attribute, and then later set it to the correct value.

To handle this, we introduce a reprocessing flag to attribute.  Then,
we manage this flag to ensure that setting and unsetting is done
properly.

gdb/ChangeLog
2020-09-29  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (read_cutu_die_from_dwo): Use OBSTACK_ZALLOC.
	(read_attribute_reprocess, read_attribute_value): Update.
	(read_attribute): Clear requires_reprocessing.
	* dwarf2/attribute.h (struct attribute) <as_unsigned_reprocess,
	form_requires_reprocessing>: New methods.
	<string_init>: Clear requires_reprocessing.
	<set_unsigned_reprocess>: New method.
	<name>: Shrink by one bit.
	<requires_reprocessing>: New member.
	* dwarf2/attribute.c (attribute::form_requires_reprocessing): New
	method.
2020-09-29 20:29:06 -06:00
Tom Tromey
414ad644a8 Use setter for attribute's unsigned value
This adds form_is_unsigned and an unsigned setter method to struct
attribute, and updates the remaining code.  Now DW_UNSND is no longer
used as an lvalue.

gdb/ChangeLog
2020-09-29  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (read_attribute_value): Update.
	* dwarf2/attribute.h (struct attribute) <form_is_unsigned,
	set_unsigned>: New methods.
	* dwarf2/attribute.c (attribute::form_is_unsigned): New method.
2020-09-29 20:29:06 -06:00
Tom Tromey
1bc397c561 Remove DW_SND
This removes DW_SND in favor of accessors on struct attribute.
These accessors check that the form is appropriate.

gdb/ChangeLog
2020-09-29  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (get_alignment, read_array_order)
	(read_attribute_value, dwarf2_const_value_attr)
	(dump_die_shallow, dwarf2_fetch_constant_bytes): Update.
	* dwarf2/attribute.h (struct attribute) <as_signed, set_signed>:
	New methods.
	(DW_SND): Remove.
2020-09-29 20:29:06 -06:00
Tom Tromey
630ed6b975 Remove DW_SIGNATURE
This removes DW_SIGNATURE in favor of methods on struct attribute.  As
usual, the methods check the form, which DW_SIGNATURE did not do.

gdb/ChangeLog
2020-09-29  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (read_attribute_value, lookup_die_type)
	(dump_die_shallow, follow_die_sig, get_DW_AT_signature_type):
	Update.
	* dwarf2/attribute.h (struct attribute) <as_signature,
	set_signature>: New methods.
	(DW_SIGNATURE): Remove.
2020-09-29 20:29:06 -06:00
Tom Tromey
9d2246fce0 Remove DW_BLOCK
This removes the DW_BLOCK accessor in favor of methods on struct
attribute.  The methods, unlike the access, check the form.

Note that DW_FORM_data16 had to be handled by form_is_block, because
in practice that is how we store values of this form.

gdb/ChangeLog
2020-09-29  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (read_call_site_scope)
	(handle_data_member_location, dwarf2_add_member_fn)
	(mark_common_block_symbol_computed, attr_to_dynamic_prop)
	(partial_die_info::read, read_attribute_value)
	(var_decode_location, dwarf2_const_value_attr, dump_die_shallow)
	(dwarf2_fetch_die_loc_sect_off, dwarf2_fetch_constant_bytes)
	(dwarf2_symbol_mark_computed): Update.
	* dwarf2/attribute.h (struct attribute) <as_block, set_block>: New
	methods.
	(DW_BLOCK): Remove.
	* dwarf2/attribute.c (attribute::form_is_block): Add
	DW_FORM_data16.
2020-09-29 20:29:06 -06:00
Tom Tromey
c648120540 Remove DW_STRING and DW_STRING_IS_CANONICAL
This removes DW_STRING and DW_STRING_IS_CANONICAL, replacing them with
accessor methods on struct attribute.  The new code ensures that a
string value will only ever be used when the form allows it.

gdb/ChangeLog
2020-09-29  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (read_cutu_die_from_dwo)
	(read_attribute_reprocess, read_attribute_value, read_attribute)
	(dwarf2_const_value_attr, dwarf2_name, dump_die_shallow)
	(dwarf2_fetch_constant_bytes): Update.
	* dwarf2/attribute.h (struct attribute) <form_is_string>: Declare.
	<set_string_noncanonical, set_string_canonical>: New methods.
	<string_is_canonical>: Update comment.
	<canonical_string_p>: Add assert.
	(DW_STRING, DW_STRING_IS_CANONICAL): Remove.
	* dwarf2/attribute.c (attribute::form_is_string): New method.
	(attribute::string): Use it.
2020-09-29 20:29:06 -06:00
Tom Tromey
3b64bf15bc Remove some uses of DW_STRING_IS_CANONICAL
This removes the rvalue uses of DW_STRING_IS_CANONICAL, replacing them
with an accessor method.

gdb/ChangeLog
2020-09-29  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (anonymous_struct_prefix, dwarf2_name)
	(dump_die_shallow): Use canonical_string_p.
	* dwarf2/attribute.h (struct attribute) <canonical_string_p>: New
	method.
2020-09-29 20:29:06 -06:00
Tom Tromey
95f982e587 Rename struct attribute accessors
This removes the "value_" prefix from the struct value accessors.
This seemed unnecessarily wordy to me.

gdb/ChangeLog
2020-09-29  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (dwarf2_find_base_address, read_call_site_scope)
	(dwarf2_get_pc_bounds, dwarf2_record_block_ranges)
	(partial_die_info::read, dwarf2_string_attr, new_symbol): Update.
	* dwarf2/attribute.h (struct attribute): Rename methods.
	* dwarf2/attribute.c (attribute::as_address): Rename from
	value_as_address.
	(attribute::as_string): Rename from value_as_string.
2020-09-29 20:29:06 -06:00
Tom Tromey
697bba1827 Attribute method inlining
This inlines a couple of methods on struct attribute, improving the
performance of DWARF partial symbol reading.  These methods were
discovered as hot spots using callgrind.

For this patch, and for all the patches in this series, I tested gdb's
performance on three programs:

1. gdb itself -- I built gdb and copied it to /tmp, ensuring that the
   same version was used in all tests.

2. The system libxul.so, the main library of Firefox.  I installed the
   separate debuginfo and ensured that gdb read it.

3. A large-ish Ada program that I happen to have.

I ran gdb 10 times like:

	  /bin/time -f %e \
		    ./gdb/gdb --data-directory ./gdb/data-directory -nx \
		    -iex 'set debug-file-directory /usr/lib/debug' \
		    -batch $X

... where $X was the test executable.  Then I computed the mean time.
This was all done with a standard (-g -O2) build of gdb.

The baseline times were

gdb    1.90
libxul 2.12
Ada    2.61

This patch brings the numbers down to

gdb    1.88
libxul 2.11
Ada    2.60

Not a huge change, but still visible in the results.

gdb/ChangeLog
2020-05-27  Tom Tromey  <tromey@adacore.com>

	* dwarf2/attribute.h (struct attribute) <form_is_ref>: Inline.
	<get_ref_die_offset>: Inline.
	<get_ref_die_offset_complaint>: New method.
	* dwarf2/attribute.c (attribute::form_is_ref): Move to header.
	(attribute::get_ref_die_offset_complaint): Rename from
	get_ref_die_offset.  Just issue complaint.
2020-05-27 11:48:18 -06:00
Tom Tromey
e61108c92d Add attribute::value_as_string method
The full DIE reader checks that an attribute has a "string" form in
some spots, but the partial DIE reader does not.  This patch brings
the two readers in sync for one specific case, namely when examining
the linkage name.  This avoids regressions in an existing DWARF test
case.

A full fix for this problem would be preferable.  An accessor like
DW_STRING should always check the form.  However, I haven't attempted
that in this series.

Also the fact that the partial and full readers can disagree like this
is a design flaw.

gdb/ChangeLog
2020-04-24  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (partial_die_info::read) <case
	DW_AT_linkage_name>: Use value_as_string.
	(dwarf2_string_attr): Use value_as_string.
	* dwarf2/attribute.h (struct attribute) <value_as_string>: Declare
	method.
	* dwarf2/attribute.c (attribute::value_as_string): New method.
2020-04-24 15:35:02 -06:00
Tom Tromey
4d1b9ab645 Fix comment in dwarf2/attribute.h
I noticed that a comment in dwarf2/attribute.h still referred to
dwarf2_get_attr_constant_value.  However, this is now a method on
struct attribute.

gdb/ChangeLog
2020-03-28  Tom Tromey  <tom@tromey.com>

	* dwarf2/attribute.h (struct attribute) <form_is_constant>: Update
	comment.
2020-03-28 09:25:41 -06:00
Tom Tromey
0826b30a9f Change two functions to be methods on struct attribute
This changes dwarf2_get_ref_die_offset and
dwarf2_get_attr_constant_value to be methods on struct attribute.

gdb/ChangeLog
2020-03-26  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (handle_data_member_location, dwarf2_add_field)
	(mark_common_block_symbol_computed, read_tag_string_type)
	(attr_to_dynamic_prop, read_subrange_type): Update.
	(dwarf2_get_ref_die_offset, dwarf2_get_attr_constant_value): Move
	to be methods on struct attribute.
	(skip_one_die, process_imported_unit_die, read_namespace_alias)
	(read_call_site_scope, partial_die_info::read)
	(partial_die_info::read, lookup_die_type, follow_die_ref):
	Update.
	* dwarf2/attribute.c (attribute::get_ref_die_offset): New method,
	from dwarf2_get_ref_die_offset.
	(attribute::constant_value): New method, from
	dwarf2_get_attr_constant_value.
	* dwarf2/attribute.h (struct attribute) <get_ref_die_offset>:
	Declare method.
	<constant_value>: New method.
2020-03-26 09:28:28 -06:00
Tom Tromey
4fc6c0d534 Change attr_form_is_block to be a method
This changes attr_form_is_block to be a method.  This is done
separately because, unlike the other attribute functions,
attr_form_is_block had special handling for the case where the
argument was NULL.  This required auditing each call site; in most
cases, NULL was already ruled out, but in a few spots, an additional
check was needed.

gdb/ChangeLog
2020-02-08  Tom Tromey  <tom@tromey.com>

	* dwarf2read.c (read_call_site_scope)
	(handle_data_member_location, dwarf2_add_member_fn)
	(mark_common_block_symbol_computed, read_common_block)
	(attr_to_dynamic_prop, partial_die_info::read)
	(var_decode_location, dwarf2_fetch_die_loc_sect_off)
	(dwarf2_symbol_mark_computed, set_die_type): Update.
	* dwarf2/attribute.h (struct attribute) <form_is_block>: Declare
	method.
	(attr_form_is_block): Don't declare.
	* dwarf2/attribute.c (attribute::form_is_block): Now a method.

Change-Id: Idfb290c61d738301ab991666f43e0b9cf577b2ae
2020-02-08 13:40:57 -07:00
Tom Tromey
cd6c91b4f8 Change some attribute functions to be methods
This changes most of the attribute-related functions to be methods.
(attr_form_is_block changed in a subsequent patch.)

gdb/ChangeLog
2020-02-08  Tom Tromey  <tom@tromey.com>

	* dwarf2read.c (dwarf2_find_base_address, )
	(read_call_site_scope, rust_containing_type)
	(dwarf2_get_pc_bounds, dwarf2_record_block_ranges)
	(handle_data_member_location, dwarf2_add_member_fn)
	(get_alignment, read_structure_type, process_structure_scope)
	(mark_common_block_symbol_computed, read_common_block)
	(read_tag_string_type, attr_to_dynamic_prop, read_subrange_type)
	(partial_die_info::read, read_attribute_value, new_symbol)
	(lookup_die_type, dwarf2_get_ref_die_offset)
	(dwarf2_get_attr_constant_value, follow_die_ref_or_sig)
	(dwarf2_fetch_die_loc_sect_off, get_DW_AT_signature_type)
	(dwarf2_symbol_mark_computed): Update.
	* dwarf2/attribute.h (struct attribute) <value_as_address,
	form_is_section_offset, form_is_constant, form_is_ref>: Declare
	methods.
	(value_as_address, attr_form_is_section_offset)
	(attr_form_is_constant, attr_form_is_ref): Don't declare.
	* dwarf2/attribute.c (attribute::value_as_address)
	(attribute::form_is_section_offset, attribute::form_is_constant)
	(attribute::form_is_ref): Now methods.

Change-Id: I320dad13002c59b848dc86c39d5d7111c8a15bdc
2020-02-08 13:40:56 -07:00
Tom Tromey
162dce5526 Create dwarf2/attribute.[ch]
This moves the attribute-related code out of dwarf2read.c and into the
new files dwarf2/attribute.[ch].

gdb/ChangeLog
2020-02-08  Tom Tromey  <tom@tromey.com>

	* dwarf2read.c (struct attribute, DW_STRING)
	(DW_STRING_IS_CANONICAL, DW_UNSND, DW_BLOCK, DW_SND, DW_ADDR)
	(DW_SIGNATURE, struct dwarf_block, attr_value_as_address)
	(attr_form_is_block, attr_form_is_section_offset)
	(attr_form_is_constant, attr_form_is_ref): Move.
	* dwarf2/attribute.h: New file.
	* dwarf2/attribute.c: New file, from dwarf2read.c.
	* Makefile.in (COMMON_SFILES): Add dwarf2/attribute.c.

Change-Id: I1ea4c146256a1b9e38b66f1c605d782a14eeded7
2020-02-08 13:40:56 -07:00