Age | Commit message (Collapse) | Author | Files | Lines |
|
This changes the psymtab_discarder to not assume that partial symtabs
are attached to the objfile. Instead, a psymtab_storage object is
passed directly to it.
gdb/ChangeLog
2021-03-20 Tom Tromey <tom@tromey.com>
* psympriv.h (psymtab_discarder): Take psymtab_storage parameter.
(~psymtab_discarder, keep): Update.
<m_objfile>: Remove.
<m_partial_symtabs>: New member.
* dwarf2/read.c (dwarf2_build_psymtabs): Update.
|
|
This changes quick_symbol_functions to be a base class with pure
virtual methods, rather than a struct holding function pointers.
Then, objfile is changed to hold a unique_ptr to an instance of this
class.
struct psymbol_functions is put into psympriv.h, and not psymtab.c,
because that is convenient later in the series.
gdb/ChangeLog
2021-03-20 Tom Tromey <tom@tromey.com>
* psympriv.h (struct psymbol_functions): New.
* symfile.c (syms_from_objfile_1, reread_symbols): Update.
* symfile-debug.c (objfile::find_compunit_symtab_by_address)
(objfile::lookup_global_symbol_language): Update.
* quick-symbol.h (struct quick_symbol_functions): Convert function
pointers to methods. Add virtual destructor.
(quick_symbol_functions_up): New typedef.
* psymtab.h (psym_functions, dwarf2_gdb_index_functions)
(dwarf2_debug_names_functions): Don't declare.
(make_psymbol_functions): Declare.
* psymtab.c (psymbol_functions::map_symtabs_matching_filename)
(psymbol_functions::find_pc_sect_compunit_symtab)
(psymbol_functions::lookup_symbol)
(psymbol_functions::lookup_global_symbol_language)
(psymbol_functions::find_last_source_symtab)
(psymbol_functions::forget_cached_source_info)
(psymbol_functions::print_stats, psymbol_functions::dump)
(psymbol_functions::expand_symtabs_for_function)
(psymbol_functions::expand_all_symtabs)
(psymbol_functions::expand_symtabs_with_fullname)
(psymbol_functions::map_symbol_filenames)
(psymbol_functions::map_matching_symbols)
(psymbol_functions::expand_symtabs_matching)
(psymbol_functions::has_symbols)
(psymbol_functions::find_compunit_symtab_by_address): Rename.
(psym_functions): Remove.
(make_psymbol_functions): New function.
* objfiles.h (struct objfile) <qf>: Change type.
* elfread.c (elf_symfile_read): Update.
* dwarf2/read.c (struct dwarf2_base_index_functions)
(struct dwarf2_gdb_index, struct dwarf2_debug_names_index): New.
(make_dwarf_gdb_index, make_dwarf_debug_names): New functions.
(dwarf2_base_index_functions::find_last_source_symtab)
(dwarf2_base_index_functions::forget_cached_source_info)
(dwarf2_base_index_functions::map_symtabs_matching_filename)
(dwarf2_gdb_index::lookup_symbol)
(dwarf2_base_index_functions::print_stats)
(dwarf2_gdb_index::dump)
(dwarf2_gdb_index::expand_symtabs_for_function)
(dwarf2_base_index_functions::expand_all_symtabs)
(dwarf2_base_index_functions::expand_symtabs_with_fullname):
Rename.
(dwarf2_gdb_index::map_matching_symbols): New method.
(dwarf2_gdb_index::expand_symtabs_matching): New method.
(dwarf2_base_index_functions::find_pc_sect_compunit_symtab)
(dwarf2_base_index_functions::map_symbol_filenames)
(dwarf2_base_index_functions::has_symbols): Rename.
(dwarf2_gdb_index_functions): Remove.
(dwarf2_debug_names_index::lookup_symbol)
(dwarf2_debug_names_index::dump)
(dwarf2_debug_names_index::expand_symtabs_for_function)
(dwarf2_debug_names_index::map_matching_symbols)
(dwarf2_debug_names_index::expand_symtabs_matching): Rename.
(dwarf2_debug_names_functions): Remove.
* dwarf2/public.h (make_dwarf_gdb_index, make_dwarf_debug_names):
Declare.
|
|
This changes objfile::has_partial_symbols and
quick_symbol_functions::has_symbols to return bool.
gdb/ChangeLog
2021-03-20 Tom Tromey <tom@tromey.com>
* objfiles.h (struct objfile) <has_partial_symbols>: Return bool.
* symfile.h (struct quick_symbol_functions) <has_symbols>: Return
bool.
* symfile-debug.c (debug_qf_has_symbols): Return bool.
* psymtab.c (psym_has_symbols): Return bool.
* objfiles.c (objfile::has_partial_symbols): Return bool.
* dwarf2/read.c (dw2_has_symbols): Return bool.
|
|
This changes objfile_has_partial_symbols to be a method on objfile.
There are some other functions that could benefit from this sort of
change, but this was the only one that was relevant to this series.
gdb/ChangeLog
2021-03-20 Tom Tromey <tom@tromey.com>
* symfile.c (read_symbols): Update.
* objfiles.h (struct objfile) <has_partial_symbols>: New method.
(objfile_has_partial_symbols): Don't declare.
* objfiles.c (objfile::has_partial_symbols): Rename from
objfile_has_partial_symbols.
(objfile_has_symbols, have_partial_symbols): Update.
* elfread.c (elf_symfile_read): Update.
* dwarf2/read.c (dwarf2_has_info): Update.
* coffread.c (coff_symfile_read): Update.
|
|
This moves some more DWARF code out of symfile.h and into a new
header, dwarf2/public.h. This header is intended to describe the
public API of the DWARF reader.
gdb/ChangeLog
2021-03-20 Tom Tromey <tom@tromey.com>
* coffread.c: Include dwarf2/public.h.
* dwarf2/frame.c: Include dwarf2/public.h.
* dwarf2/index-write.h: Include dwarf2/public.h, not symfile.h.
* dwarf2/public.h: New file.
* dwarf2/read.c: Include dwarf2/public.h.
* elfread.c: Include dwarf2/public.h.
* machoread.c: Include dwarf2/public.h.
* symfile.h (dwarf2_has_info, enum dw_index_kind)
(dwarf2_initialize_objfile, dwarf2_build_psymtabs)
(dwarf2_build_frame_info): Move to dwarf2/public.h.
* xcoffread.c: Include dwarf2/public.h.
|
|
This moves a bit of the DWARF-specific code out of symfile.h and into
dwarf2/read.h.
gdb/ChangeLog
2021-03-20 Tom Tromey <tom@tromey.com>
* symfile.h (enum dwarf2_section_enum)
(dwarf2_get_section_info): Move to dwarf2/read.h.
* dwarf2/read.h (enum dwarf2_section_enum)
(dwarf2_get_section_info): Move from symfile.h.
|
|
I noticed that dwarf_unit_type_name is nearly identical to
get_DW_UT_name from libiberty; but rather than simply replacing it, it
seemed better to have it work like the other DWARF constant
stringification functions -- return a string showing unrecognized
numeric forms rather than nullptr. (The previous code did include
numeric values for the recognized constants, but this seems to be not
that useful to me.)
2021-03-18 Tom Tromey <tromey@adacore.com>
* dwarf2/stringify.c (dwarf_unit_type_name): New function. Use
get_DW_UT_name.
* dwarf2/stringify.h (dwarf_unit_type_name): Declare.
* dwarf2/comp-unit.c (dwarf_unit_type_name): Remove.
|
|
This printout in create_debug_type_hash_table has an unexpected colon at
the end, remove it:
[dwarf-read] create_debug_type_hash_table: Reading .debug_info for /home/simark/build/binutils-gdb/gdb/a.out:
gdb/ChangeLog:
* dwarf2/read.c (create_debug_type_hash_table): Remove colon at
end of debug print.
Change-Id: I2d707248249daf4d8b6fa8e7064acdc56c90f2dd
|
|
I added these printouts while working on 27541. I won't have a fix for
that right now, but I thought that it would be useful to merge them
upstream, as they help understand what happens in that function.
gdb/ChangeLog:
* dwarf2/read.c (dwarf2_initialize_objfile): Add debug prints.
Change-Id: I790c0d53383327038cb5dd705f74c8c978e0a7ec
|
|
I noticed that this parameter was unused, remove it.
gdb/ChangeLog:
* dwarf2/read.c (dw2_get_file_names_reader): Remove info_ptr
parameter, adjust caller.
Change-Id: I2a741766a0c658c22c512590aeffdd07391c869c
|
|
read_attribute_value has a local cu_header variable, but then some
spots in the function use cu->header instead. It seems better to me
to prefer the local everywhere, so this patch makes this change.
gdb/ChangeLog
2021-03-14 Tom Tromey <tom@tromey.com>
* dwarf2/read.c (read_attribute_value): Use cu_header
consistently.
|
|
For an experiment I'm working on, it would be convenient if
die_reader_specs::cu could be NULL. This is fairly involved to
implement, but I did notice one spot that could conveniently be
updated. While making this trivial change, I also noticed a small,
related formatting error.
2021-03-14 Tom Tromey <tom@tromey.com>
* dwarf2/read.c (struct die_reader_specs) <abfd>: Fix formatting.
(peek_die_abbrev): Use reader.abfd.
|
|
I noticed that nothing in dwarf2/read.c sets
dwarf2_per_cu_data::m_header_read_in. This patch adds the appropriate
assignment.
gdb/ChangeLog
2021-03-14 Tom Tromey <tom@tromey.com>
* dwarf2/read.c (dwarf2_per_cu_data::get_header): Set
m_header_read_in.
|
|
This changes abbrev_table::lookup_abbrev to return a pointer to const,
then fixes up the affected code.
gdb/ChangeLog
2021-03-13 Tom Tromey <tom@tromey.com>
* dwarf2/read.c (struct partial_die_info): Update.
(peek_die_abbrev, skip_children, skip_one_die, read_full_die_1)
(load_partial_dies, partial_die_info::partial_die_info): Update.
* dwarf2/abbrev.h (lookup_abbrev): Constify.
|
|
abbrev_table::read has a workaround for Irix 6. The last release of
Irix was in 2006, and (according to Wikipedia) hardware produced after
2007 cannot run Irix. I think this workaround can safely be retired.
gdb/ChangeLog
2021-03-13 Tom Tromey <tom@tromey.com>
* dwarf2/abbrev.c (abbrev_table::read): Remove Irix 6 workaround.
|
|
This moves dwarf2_get_dwz_file and some helper code to dwarf2/dwz.h.
The main benefit of this is just shrinking dwarf2/read.c a little bit.
gdb/ChangeLog
2021-03-06 Tom Tromey <tom@tromey.com>
* dwarf2/sect-names.h (dwarf2_elf_names): Declare.
* dwarf2/read.h (dwarf2_get_dwz_file): Move to dwz.h.
* dwarf2/read.c (dwarf2_elf_names): No longer static.
(locate_dwz_sections, dwz_search_other_debugdirs)
(dwarf2_get_dwz_file): Move to dwz.c.
* dwarf2/dwz.h (dwarf2_get_dwz_file): Move declaration from
read.h.
* dwarf2/dwz.c (locate_dwz_sections, dwz_search_other_debugdirs)
(dwarf2_get_dwz_file): Move from read.c.
|
|
If DWARF contains a reference to a "dwz" file, but there is no
.gnu_debugaltlink section, then gdb will crash. This happens because
dwarf2_get_dwz_file will return NULL, but some callers do not expect
this.
This patch changes dwarf2_get_dwz_file so that callers can require a
dwz file. Then, it updates the callers that are attempting to process
references to the dwz file to require one.
This includes a new testcase. The dwarf.exp changes don't handle the
new forms exactly correctly -- they are only handled well enough to
let this test case complete.
gdb/ChangeLog
2021-03-06 Tom Tromey <tom@tromey.com>
* dwarf2/read.h (dwarf2_get_dwz_file): Add 'require' parameter.
* dwarf2/read.c (dwarf2_get_dwz_file): Add 'require' parameter.
(get_abbrev_section_for_cu, read_attribute_value)
(get_debug_line_section): Update.
* dwarf2/macro.c (dwarf_decode_macro_bytes): Update.
gdb/testsuite/ChangeLog
2021-03-06 Tom Tromey <tom@tromey.com>
* lib/dwarf.exp (_handle_DW_FORM): Treat DW_FORM_GNU_ref_alt and
DW_FORM_GNU_strp_alt like DW_FORM_sec_offset.
* gdb.dwarf2/dwznolink.exp: New file.
|
|
This replaces section_is_p with a method on dwarf2_section_names.
gdb/ChangeLog
2021-03-06 Tom Tromey <tom@tromey.com>
* dwarf2/sect-names.h (struct dwarf2_section_names) <matches>: New
method.
* dwarf2/read.c (section_is_p): Remove.
(dwarf2_per_bfd::locate_sections)
(dwarf2_per_bfd::locate_sections, locate_dwz_sections)
(locate_v1_virtual_dwo_sections, dwarf2_locate_dwo_sections)
(dwarf2_locate_common_dwp_sections)
(dwarf2_locate_v2_dwp_sections, dwarf2_locate_v5_dwp_sections):
Update.
|
|
This creates a new file, dwarf2/sect-names.h, and moves some
DWARF-specific type definitions from symfile.h into it.
gdb/ChangeLog
2021-03-06 Tom Tromey <tom@tromey.com>
* xcoffread.c: Include sect-names.h.
* symfile.h (struct dwarf2_section_names, struct
dwarf2_debug_sections): Move to dwarf2/sect-names.h.
* dwarf2/sect-names.h: New file, from symfile.h.
* dwarf2/read.c: Include sect-names.h.
|
|
Currently, and abbrev_info points to a separately allocated array of
attr_abbrev objects. This array is constructed in a temporary vector,
then copied to the abbrev table's obstack.
This patch changes abbrev_info to use the struct hack to store the
objects directly, and changes abbrev_table::read to avoid an extra
copy when allocating, using the "growing objects" capability of
obstacks.
This saves a bit of space, and also perhaps a little time.
2021-03-06 Tom Tromey <tom@tromey.com>
* dwarf2/read.c (read_attribute): Make 'abbrev' const.
* dwarf2/abbrev.c (abbrev_table::alloc_abbrev): Remove.
(abbrev_table::read): Update.
* dwarf2/abbrev.h (struct attr_abbrev): Move earlier.
(struct abbrev_info): Reformat.
<attrs>: Now an array.
(struct abbrev_table) <alloc_abbrev>: Remove.
|
|
gdb currently supports two different styles of fixed-point. The
original style, where fixed point types are "GNAT encoded", is handled
primarily in the Ada code. The newer style, encoded using DWARF, is
handled by the core of gdb.
This patch changes gdb to read the GNAT encodings in the DWARF reader
as well. This removes some code and unifies the two paths. As a
result, GNAT-encoded fixed-point now works a bit better.
One possible drawback of this change is that, if someone uses stabs,
then fixed-point might now stop working. I consider stabs to be fully
obsolete, though, so I don't intend to address this.
gdb/ChangeLog
2021-03-02 Tom Tromey <tromey@adacore.com>
* ada-lang.c (cast_from_gnat_encoded_fixed_point_type)
(cast_to_gnat_encoded_fixed_point_type): Remove.
(ada_value_cast, ada_evaluate_subexp): Update.
(gnat_encoded_fixed_point_type_info)
(ada_is_gnat_encoded_fixed_point_type)
(gnat_encoded_fixed_point_delta)
(gnat_encoded_fixed_point_scaling_factor): Remove.
* ada-lang.h (ada_is_gnat_encoded_fixed_point_type)
(gnat_encoded_fixed_point_delta)
(gnat_encoded_fixed_point_scaling_factor): Don't declare.
* ada-typeprint.c (print_gnat_encoded_fixed_point_type): Remove.
(ada_print_type): Update.
* ada-valprint.c (ada_value_print_num): Update.
* dwarf2/read.c (ada_get_gnat_encoded_number)
(ada_get_gnat_encoded_ratio): New functions.
(finish_fixed_point_type): Use them. Add parameters.
(GNAT_FIXED_POINT_SUFFIX): New define.
(gnat_encoded_fixed_point_type_info): New function.
(read_base_type): Handle gnat encodings.
gdb/testsuite/ChangeLog
2021-03-02 Tom Tromey <tromey@adacore.com>
* gdb.ada/fixed_points.exp: Remove most special cases for minimal
encodings.
|
|
When running test-case gdb.dwarf2/fission-mix.exp using gcc-11 (and using the
tentative fix for PR27353 to get past that assertion failure), I run into:
...
(gdb) file fission-mix^M
Reading symbols from fission-mix...^M
Dwarf Error: wrong unit_type in compilation unit header \
(is DW_UT_split_compile (0x05), should be DW_UT_type (0x02)) \
[in module fission-mix2.dwo]^M
(No debugging symbols found in fission-mix)^M
...
The compilation unit that is complained about is:
...
Contents of the .debug_info.dwo section (loaded from fission-mix2.dwo):
Compilation Unit @ offset 0x0:
Length: 0x57 (32-bit)
Version: 5
Unit Type: DW_UT_split_compile (5)
Abbrev Offset: 0x0
Pointer Size: 8
DWO ID: 0x3e3930d3cc1805df
<0><14>: Abbrev Number: 1 (DW_TAG_compile_unit)
...
And the dwarf error is triggered here in read_comp_unit_head:
...
case DW_UT_split_compile:
if (section_kind != rcuh_kind::COMPILE)
error (_("Dwarf Error: wrong unit_type in compilation unit header "
"(is %s, should be %s) [in module %s]"),
dwarf_unit_type_name (cu_header->unit_type),
dwarf_unit_type_name (DW_UT_type), filename);
break;
...
due to passing rcuh_kind::TYPE here in open_and_init_dwo_file:
...
create_debug_type_hash_table (per_objfile, dwo_file.get (),
&dwo_file->sections.info, dwo_file->tus,
rcuh_kind::TYPE);
...
Fix this by changing the section_kind argument to create_debug_type_hash_table
to rcuh_kind::COMPILE, to reflect that we're passing &dwo_file->sections.info
rather than &dwo_file->sections.types.
Tested on x86_64-linux.
gdb/ChangeLog:
2021-02-25 Tom de Vries <tdevries@suse.de>
PR symtab/27354
* dwarf2/read.c (open_and_init_dwo_file): Use rcuh_kind::COMPILE as
section_kind for &dwo_file->sections.info.
|
|
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 529908cbd0a "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.
|
|
As described in the log of patch "gdb/dwarf: add assertion in
maybe_queue_comp_unit", it would happen that a call to
maybe_queue_comp_unit would enqueue a CU in the to-expand queue while
nothing up the stack was processing the queue. This is not desirable,
as items are then left lingering in the queue when we exit the
dwarf2/read code. This is an inconsistent state.
The normal case of using the queue is when we go through
dw2_do_instantiate_symtab and process_queue. As depended-on CUs are
found, they get added to the queue. process_queue expands CUs until the
queue is empty.
To catch these cases where things are enqueued while nothing up the
stack is processing the queue, change dwarf2_per_bfd::queue to be an
optional. The optional is instantiated in dwarf2_queue_guard, just
before where we call process_queue. In the dwarf2_queue_guard
destructor, the optional gets reset. Therefore, the queue object is
instantiated only when something up the stack is handling it. If
another entry point tries to enqueue a CU for expansion, an assertion
will fail and we know we have something to fix.
dwarf2_queue_guard sounds like the good place for this, as it's
currently responsible for making sure the queue gets cleared if we exit
due to an error.
This also allows asserting that when age_comp_units or remove_all_cus
run, the queue is not instantiated, and gives us one more level of
assurance that we won't free the DIEs of a CU that is in the
CUs-to-expand queue.
gdb/ChangeLog:
PR gdb/26828
* dwarf2/read.c (dwarf2_queue_guard) <dwarf2_queue_guard>:
Instantiate queue.
(~dwarf2_queue_guard): Clear queue.
(queue_comp_unit): Assert that queue is
instantiated.
(process_queue): Adjust.
* dwarf2/read.h (struct dwarf2_per_bfd) <queue>: Make optional.
Change-Id: I8fe3d77845bb4ad3d309eac906acebe79d9f0a9d
|
|
The previous commit log described how items could be left lingering in
the dwarf2_per_bfd::queue and how that could cause trouble.
This patch fixes the issue by changing maybe_queue_comp_unit so that it
doesn't put a CU in the to-expand queue if that CU is already expanded.
This will make it so that when dwarf2_fetch_die_type_sect_off calls
follow_die_offset and maybe_queue_comp_unit, it won't enqueue the target
CU, because it will see the CU is already expanded.
This assumes that if a CU is dwarf2_fetch_die_type_sect_off's target CU,
it will have previously been expanded. I think it is the case, but I
can't be 100% sure. If that's not true, the assertions added in the
following patch will catch it, and it means we'll have to re-think a bit
more how things work (it wouldn't be well handled at all today anyway).
This fixes something else in maybe_queue_comp_unit that looks wrong.
Imagine the DIEs of a CU are loaded in memory, but that CU is not
expanded. In that case, maybe_queue_comp_unit will use this early
return:
/* If the compilation unit is already loaded, just mark it as
used. */
dwarf2_cu *cu = per_objfile->get_cu (per_cu);
if (cu != nullptr)
{
cu->last_used = 0;
return 0;
}
... so the CU won't be queued for expansion. Whether the DIEs of a CU
are loaded in memory and whether that CU is expanded are two orthogonal
things, but that function appears to mix them. So, move the queuing
above that check / early return, so that if the CU's DIEs are loaded in
memory but the CU is not expanded yet, it gets enqueued.
I tried to improve maybe_queue_comp_unit's documentation to clarify what
the return value means. By clarifying this, I noticed that two callers
(follow_die_offset and follow_die_sig_1) access the CU's DIEs after
calling maybe_queue_comp_unit, only relying on maybe_queue_comp_unit's
return value to tell whether DIEs need to be loaded first or not. As
explained in the new comment, this is problematic:
maybe_queue_comp_unit's return value doesn't tell whether DIEs are
currently loaded, it means whether maybe_queue_comp_unit requires the
caller to load them. If the CU is already expanded but the DIEs to have
been freed, maybe_queue_comp_unit returns 0, meaning "I don't need you
to load the DIEs". So if these two functions (follow_die_offset and
follow_die_sig_1) need to access the DIEs in any case, for their own
usage, they should make sure to load them if they are not loaded
already. I therefore added an extra check to the condition they use,
making it so they will always load the DIEs if they aren't already.
From what I found, other callers don't care for the CU's DIEs, they call
maybe_queue_comp_unit to ensure the CU gets expanded eventually, but
don't care for it after that.
gdb/ChangeLog:
PR gdb/26828
* dwarf2/read.c (maybe_queue_comp_unit): Check if CU is expanded
to decide whether or not to enqueue it for expansion.
(follow_die_offset, follow_die_sig_1): Ensure we load the DIEs
after calling maybe_queue_comp_unit.
Change-Id: Id98c6b60669f4b4b21b9be16d0518fc62bdf686a
|
|
When running test-case gdb.dwarf2/fission-mix.exp using gcc-11, I run into:
...
(gdb) file fission-mix^M
Reading symbols from fission-mix...^M
src/gdb/dwarf2/attribute.h:258: internal-error: \
void attribute::set_unsigned_reprocess(ULONGEST): \
Assertion `form_requires_reprocessing ()' failed.^M
...
This happens when calling set_unsigned_reprocess on an attribute with form
DW_FORM_strx. The assert triggers because DW_FORM_strx is not listed in
form_requires_reprocessing.
Fix this by adding DW_FORM_strx in form_requires_reprocessing.
Tested on x86_64-linux.
gdb/ChangeLog:
2021-02-11 Tom de Vries <tdevries@suse.de>
PR symtab/27353
* dwarf2/attribute.c (attribute::form_requires_reprocessing):
Return true for DW_FORM_strx.
|
|
Delete two more symbol/section related macros. This time it's
SYMBOL_SECTION and MSYMBOL_SECTION.
As with general_symbol_info::m_name it is not currently possible to
make general_symbol_info::m_section private as general_symbol_info
must remain a POD type.
But other than failing to make the new m_section private, this change
does what you'd expect, adds a get and set member function and updates
all users to use the new functions instead of the previous wrapper
macros.
There should be no user visible change after this commit.
gdb/ChangeLog:
* coff-pe-read.c (add_pe_forwarded_sym): Make use of section_index
and set_section_index member functions where appropriate.
* coffread.c (coff_symtab_read): Likewise.
(process_coff_symbol): Likewise.
* ctfread.c (set_symbol_address): Likewise.
* dwarf2/read.c (add_partial_symbol): Likewise.
(var_decode_location): Likewise.
* language.c: Likewise.
* minsyms.c (minimal_symbol_reader::record_full): Likewise.
(compact_minimal_symbols): Likewise.
(minimal_symbol_upper_bound): Likewise.
* objfiles.c (relocate_one_symbol): Likewise.
* psympriv.h (partial_symbol::obj_section): Likewise.
(partial_symbol::address): Likewise.
* psymtab.c (partial_symtab::add_psymbol): Likewise.
* stabsread.c (scan_file_globals): Likewise.
* symmisc.c (dump_msymbols): Likewise.
* symtab.c (general_symbol_info::obj_section): Likewise.
(fixup_section): Likewise.
(get_msymbol_address): Likewise.
* symtab.h (general_symbol_info::section): Rename to...
(general_symbol_info::m_section): ...this.
(general_symbol_info::set_section_index): New member function.
(general_symbol_info::section_index): Likewise.
(SYMBOL_SECTION): Delete.
(MSYMBOL_VALUE_ADDRESS): Make use of section_index and
set_section_index member functions where appropriate.
(MSYMBOL_SECTION): Delete.
(symbol::symbol): Update to initialize 'm_section'.
* xcoffread.c (read_xcoff_symtab): Make use of set_section_index.
(process_xcoff_symbol): Likewise.
|
|
When running test-case gdb.fortran/function-calls.exp with target board
unix/gdb:debug_flags=-gdwarf-5, I run into:
...
(gdb) PASS: gdb.fortran/function-calls.exp: \
p derived_types_and_module_calls::pass_cart(c)
p derived_types_and_module_calls::pass_cart_nd(c_nd)^M
^M
Program received signal SIGSEGV, Segmentation fault.^M
0x0000000000400f73 in derived_types_and_module_calls::pass_cart_nd \
(c=<error reading variable: Cannot access memory at address 0xc>) at \
function-calls.f90:130^M
130 pass_cart_nd = ubound(c%d,1,4)^M
The program being debugged was signaled while in a function called from GDB.^M
GDB has restored the context to what it was before the call.^M
To change this behavior use "set unwindonsignal off".^M
Evaluation of the expression containing the function^M
(derived_types_and_module_calls::pass_cart_nd) will be abandoned.^M
(gdb) FAIL: gdb.fortran/function-calls.exp: p
...
The problem originates in read_array_type, when reading a DW_TAG_array_type
with a dwarf-5 DW_TAG_generic_subrange child. This is not supported, and the
fallout of this is that rather than constructing a new array type, the code
proceeds to modify the element type.
Fix this conservatively by issuing a complaint and bailing out in
read_array_type when not being able to construct an array type, such that we
have:
...
(gdb) maint expand-symtabs function-calls.f90^M
During symbol reading: unable to find array range \
- DIE at 0xe1e [in module function-calls]^M
During symbol reading: unable to find array range \
- DIE at 0xe1e [in module function-calls]^M
(gdb) KFAIL: gdb.fortran/function-calls.exp: no complaints in srcfile \
(PRMS: symtab/27388)
...
Tested on x86_64-linux.
gdb/ChangeLog:
2021-02-09 Tom de Vries <tdevries@suse.de>
PR symtab/27341
* dwarf2/read.c (read_array_type): Return NULL when not being able to
construct an array type. Add assert to ensure that element_type is
not being modified.
gdb/testsuite/ChangeLog:
2021-02-09 Tom de Vries <tdevries@suse.de>
PR symtab/27341
* lib/gdb.exp (with_complaints): New proc, factored out of ...
(gdb_load_no_complaints): ... here.
* gdb.fortran/function-calls.exp: Add test-case.
|
|
When running test-case gdb.cp/cpexprs-debug-types.exp with target board
unix/gdb:debug_flags=-gdwarf-5, I run into:
...
(gdb) file cpexprs-debug-types^M
Reading symbols from cpexprs-debug-types...^M
ERROR: Couldn't load cpexprs-debug-types into GDB (eof).
ERROR: Couldn't send delete breakpoints to GDB.
ERROR: GDB process no longer exists
GDB process exited with wait status 23054 exp9 0 0 CHILDKILLED SIGABRT SIGABRT
...
We're running into this abort in process_psymtab_comp_unit:
...
switch (reader.comp_unit_die->tag)
{
case DW_TAG_compile_unit:
this_cu->unit_type = DW_UT_compile;
break;
case DW_TAG_partial_unit:
this_cu->unit_type = DW_UT_partial;
break;
default:
abort ();
}
...
because reader.comp_unit_die->tag == DW_TAG_type_unit.
Fix this by adding a DW_TAG_type_unit case.
Tested on x86_64-linux.
gdb/ChangeLog:
2021-02-05 Tom de Vries <tdevries@suse.de>
PR symtab/27333
* dwarf2/read.c (process_psymtab_comp_unit): Handle DW_TAG_type_unit.
|
|
When running test-case gdb.dwarf2/clang-debug-names.exp, I run into the
following warning:
...
(gdb) file clang-debug-names^M
Reading symbols from clang-debug-names...^M
warning: Section .debug_aranges in clang-debug-names has duplicate \
debug_info_offset 0xc7, ignoring .debug_aranges.^M
...
This is caused by a missing return in commit 3ee6bb113af "[gdb/symtab] Fix
incomplete CU list assert in .debug_names".
Fix this by adding the missing return, such that we have instead this warning:
...
(gdb) file clang-debug-names^M
Reading symbols from clang-debug-names...^M
warning: Section .debug_aranges in clang-debug-names \
entry at offset 0 debug_info_offset 0 does not exists, \
ignoring .debug_aranges.^M
...
which is a known problem filed as PR25969 - "Ignoring .debug_aranges with
clang .debug_names".
Tested on x86_64-linux.
gdb/ChangeLog:
2021-02-05 Tom de Vries <tdevries@suse.de>
PR symtab/27307
* dwarf2/read.c (create_cus_from_debug_names_list): Add missing
return.
gdb/testsuite/ChangeLog:
2021-02-05 Tom de Vries <tdevries@suse.de>
PR symtab/27307
* gdb.dwarf2/clang-debug-names.exp: Check file command warnings.
|
|
Fix indentation in !map.augmentation_is_gdb part of
create_cus_from_debug_names_list.
gdb/ChangeLog:
2021-02-05 Tom de Vries <tdevries@suse.de>
* dwarf2/read.c (create_cus_from_debug_names_list): Fix indentation.
|
|
I think it's wrong that read_loclist_index and read_rnglist_index return
a CORE_ADDR. A CORE_ADDR is an address in the program. These functions
return offset in sections (.debug_loclists and .debug_rnglists). I
think sect_offset is more appropriate.
I'm wondering if struct attribute should have a "set_sect_offset"
method, that takes a sect_offset parameter, or if it's better to be
left as a simple "unsigned".
gdb/ChangeLog:
* dwarf2/read.c (read_loclist_index, read_rnglist_index): Return
a sect_offset.
(read_attribute_reprocess): Adjust.
Change-Id: I0e22e0864130fb490072b41ae099762918b8ad4d
|
|
Consider the test case added in this patch. It defines a compilation
unit with a DW_AT_rnglists_base attribute (used for attributes of form
DW_FORM_rnglistx), but also uses DW_AT_ranges of form
DW_FORM_sec_offset:
0x00000027: DW_TAG_compile_unit
DW_AT_ranges [DW_FORM_sec_offset] (0x0000004c
[0x0000000000005000, 0x0000000000006000))
DW_AT_rnglists_base [DW_FORM_sec_offset] (0x00000044)
The DW_AT_rnglists_base does not play a role in reading the DW_AT_ranges of
form DW_FORM_sec_offset, but it should also not do any harm.
This case is currently not handled correctly by GDB. This is not
something that a compiler is likely to emit, but in my opinion there's
no reason why GDB should fail reading it.
The problem is that in partial_die_info::read and a few other places
where the same logic is replicated, the cu->ranges_base value,
containing the DW_AT_rnglists_base value, is wrongfully added to the
DW_AT_ranges value.
It is quite messy how to decide whether cu->ranges_base should be added
to the attribute's value or not. But to summarize, the only time we
want to add it is when the attribute comes from a pre-DWARF 5 split unit
file (a .dwo) [1]. In this case, the DW_AT_ranges attribute from the
split unit file will have form DW_FORM_sec_offset, pointing somewhere in
the linked file's .debug_ranges section. *But* it's not a "true"
DW_FORM_sec_offset, in that it's an offset relative to the beginning of
that CU's contribution in the section, not relative to the beginning of
the section. So in that case, and only that case, do we want to add the
ranges base value, which we found from the DW_AT_GNU_ranges_base
attribute on the skeleton unit.
Almost all instances of the DW_AT_ranges attribute will be found in the
split unit (on DW_TAG_subprogram, for example), and therefore need to
have the ranges base added. However, the DW_TAG_compile_unit DIE in the
skeleton may also have a DW_AT_ranges attribute. For that one, the
ranges base must not be added. Once the DIEs have been loaded in GDB,
however, the distinction between what's coming from the skeleton and
what's coming from the split unit is not clear. It is all merged in one
big happy tree. So how do we know if a given attribute comes from the
split unit or not?
We use the fact that in pre-DWARF 5 split DWARF, DW_AT_ranges is found
on the skeleton's DW_TAG_compile_unit (in the linked file) and never in
the split unit's DW_TAG_compile_unit. This is why you have this in
partial_die_info::read:
int need_ranges_base = (tag != DW_TAG_compile_unit
&& attr.form != DW_FORM_rnglistx);
However, with the corner case described above (where we have a
DW_AT_rnglists_base attribute and a DW_AT_ranges attribute of form
DW_FORM_sec_offset) the condition gets it wrong when it encounters an
attribute like DW_TAG_subprogram with a DW_AT_ranges attribute of
DW_FORM_sec_offset form: it thinks that it is necessary to add the base,
when it reality it is not.
The problem boils down to failing to differentiate these cases:
- a DW_AT_ranges attribute of form DW_FORM_sec_offset in a
pre-DWARF 5 split unit (in which case we need to add the base)
- a DW_AT_ranges attribute of form DW_FORM_sec_offset in a DWARF 5
non-split unit (in which case we must not add the base)
What makes it unnecessarily complex is that the cu->ranges_base field is
overloaded, used to hold the pre-DWARF 5, non-standard
DW_AT_GNU_ranges_base and the DWARF 5 DW_AT_rnglists_base. In reality,
these two are called "bases" but are not the same thing. The result is
that we need twisted conditions to try to determine whether or not we
should add the base to the attribute's value.
To fix it, split the field in two distinct fields. I renamed everything
related to the "old" ranges base to "gnu_ranges_base", to make it clear
that it's about the non-standard, pre-DWARF 5 thing. And everything
related to the DWARF 5 thing gets renamed "rnglists". I think it
becomes much easier to reason this way.
The issue described above gets fixed by the fact that the
DW_AT_rnglists_base value does not end up in cu->gnu_ranges_base, so
cu->gnu_ranges_base stays 0. The condition to determine whether
gnu_ranges_base should be added can therefore be simplified back to:
tag != DW_TAG_compile_unit
... as it was before rnglistx support was added.
Extend the gdb.dwarf2/rnglists-sec-offset.exp to cover this case. I
also extended the test case for loclists similarly, just to see if there
would be some similar problem. There wasn't, but I think it's not a bad
idea to test that case for loclists as well, so I left it in the patch.
[1] https://gcc.gnu.org/wiki/DebugFission
gdb/ChangeLog:
* dwarf2/die.h (struct die_info) <ranges_base>: Split in...
<gnu_ranges_base>: ... this...
<rnglists_base>: ... and this.
* dwarf2/read.c (struct dwarf2_cu) <ranges_base>: Split in...
<gnu_ranges_base>: ... this...
<rnglists_base>: ... and this.
(read_cutu_die_from_dwo): Adjust
(dwarf2_get_pc_bounds): Adjust
(dwarf2_record_block_ranges): Adjust.
(read_full_die_1): Adjust
(partial_die_info::read): Adjust.
(read_rnglist_index): Adjust.
gdb/testsuite/ChangeLog:
* gdb.dwarf2/rnglists-sec-offset.exp: Add test for DW_AT_ranges
of DW_FORM_sec_offset form plus DW_AT_rnglists_base attribute.
* gdb.dwarf2/loclists-sec-offset.exp: Add test for
DW_AT_location of DW_FORM_sec_offset plus DW_AT_loclists_base
attribute
Change-Id: Icd109038634b75d0e6e9d7d1dcb62fb9eb951d83
|
|
When loading the binary from PR 26813 in GDB, we get:
DW_FORM_rnglistx index pointing outside of .debug_rnglists offset array [in module /home/simark/build/binutils-gdb/gdb/MagicPurse]
... and the symbols fail to load.
In read_rnglist_index and read_loclist_index, we read the header
(documented in sections 7.28 and 7.29 of DWARF 5) of the CU's
contribution to the .debug_rnglists / .debug_loclists sections to
validate that the index we want to read makes sense. However, we always
read the header at the beginning of the section, rather than the header
for the contribution from which we want to read the index.
To illustrate, here's what the binary from PR 26813 contains. There are
two compile units:
0x0000000c: DW_TAG_compile_unit 1
DW_AT_ranges [DW_FORM_rnglistx]: 0x0
DW_AT_rnglists_base [DW_FORM_sec_offset]: 0xC
0x00003ec9: DW_TAG_compile_unit 2
DW_AT_ranges [DW_FORM_rnglistx]: 0xB
DW_AT_rnglists_base [DW_FORM_sec_offset]: 0x85
The layout of the .debug_rnglists is the following:
[0x00, 0x0B]: header for CU 1's contribution
[0x0C, 0x0F]: list of offsets for CU 1 (1 element)
[0x10, 0x78]: range lists data for CU 1
[0x79, 0x84]: header for CU 2's contribution
[0x85, 0xB4]: list of offsets for CU 2 (12 elements)
[0xB5, 0xBD7]: range lists data for CU 2
The DW_AT_rnglists_base attrbute points to the beginning of the list of
offsets for that CU, relative to the start of the .debug_rnglists
section. That's right after the header for that contribution.
When we try to read the DW_AT_ranges attribute for CU 2,
read_rnglist_index reads the header for CU 1 instead of the one for CU
2. Since there's only one element in CU 1's offset list, it believes
(wrongfully) that the index 0xB is out of range.
Fix it by reading the header just before where DW_AT_rnglists_base
points to. With this patch, I am able to load GDB built with clang-11
and -gdwarf-5 in itself, with and without -readnow.
gdb/ChangeLog:
PR gdb/26813
* dwarf2/read.c (read_loclists_rnglists_header): Add
header_offset parameter and use it.
(read_loclist_index): Read header of the current contribution,
not the one at the beginning of the section.
(read_rnglist_index): Likewise.
Change-Id: Ie53ff8251af8c1556f0a83a31aa8572044b79e3d
|
|
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
|
|
In read_rnglist_index and read_loclist_index, we check that both the
start and end of the offset that we read from the offset table are
within the section. I think it's unecessary to do both: if the end of
the offset is within the section, then surely the start of the offset is
within it.
Remove the check for the start of the offset in both functions.
gdb/ChangeLog:
* dwarf2/read.c (read_loclist_index): Remove bound check for
start of offset.
(read_rnglist_index): Likewise.
Change-Id: I7b57ddf4f8a8a28971738f0e3f3af62108f9e19a
|
|
read_rnglist_index has a bound check to make sure that we don't go past
the end of the section while reading the offset, but read_loclist_index
doesn't. Add it to read_loclist_index.
gdb/ChangeLog:
* dwarf2/read.c (read_loclist_index): Add bound check for the end
of the offset.
Change-Id: Ic4b55c88860fdc3e007740949c78ec84cdb4da60
|
|
I think this check in read_rnglist_index is wrong:
/* Validate that reading won't go beyond the end of the section. */
if (start_offset + cu->header.offset_size > rnglist_base + section->size)
error (_("Reading DW_FORM_rnglistx index beyond end of"
".debug_rnglists section [in module %s]"),
objfile_name (objfile));
The addition `rnglist_base + section->size` doesn't make sense.
rnglist_base is an offset into `section`, so it doesn't make sense to
add it to `section`'s size. `start_offset` also is an offset into
`section`, so we should just compare it to just `section->size`.
gdb/ChangeLog:
* dwarf2/read.c (read_rnglist_index): Fix bound check.
Change-Id: If0ff7c73f4f80f79aac447518f4e8f131f2db8f2
|
|
Unlike read_rnglists_index, read_loclist_index uses complaints when it
detects an inconsistency (a DW_FORM_loclistx value without a
.debug_loclists section or an offset outside of the section). I really
think they should be errors, since there's no point in continuing if
this situation happens, we will likely segfault or read garbage.
gdb/ChangeLog:
* dwarf2/read.c (read_loclist_index): Change complaints into
errors.
Change-Id: Ic3a1cf6e682d47cb6e739dd76fd7ca5be2637e10
|
|
When running test-case gdb.dwarf2/fission-reread.exp with target board
cc-with-gdb-index, we run into an abort during the generation of the gdb-index
by cc-with-tweaks.sh:
...
build/gdb/testsuite/cache/gdb.sh: line 1: 27275 Aborted (core dumped)
...
This can be reproduced on the command line like this:
...
$ gdb -batch ./outputs/gdb.dwarf2/fission-reread/fission-reread \
-ex 'save gdb-index ./outputs/gdb.dwarf2/fission-reread'
warning: Could not find DWO TU fission-reread.dwo(0x9022f1ceac7e8b19) \
referenced by TU at offset 0x0 [in module fission-reread]
warning: Could not find DWO CU fission-reread.dwo(0x807060504030201) \
referenced by CU at offset 0x561 [in module fission-reread]
Aborted (core dumped)
...
The abort is a segfault due to a using a nullptr psymtab in
write_one_signatured_type.
The problem is that we're trying to write index entries for the type unit
with signature:
...
(gdb) p /x entry->signature
$2 = 0x9022f1ceac7e8b19
...
which is a skeleton type unit:
...
Contents of the .debug_types section:
Compilation Unit @ offset 0x0:
Length: 0x4a (32-bit)
Version: 4
Abbrev Offset: 0x165
Pointer Size: 4
Signature: 0x9022f1ceac7e8b19
Type Offset: 0x0
<0><17>: Abbrev Number: 2 (DW_TAG_type_unit)
<18> DW_AT_comp_dir : /tmp/src/gdb/testsuite
<2f> DW_AT_GNU_dwo_name: fission-reread.dwo
<42> DW_AT_GNU_pubnames: 0x0
<46> DW_AT_GNU_pubtypes: 0x0
<4a> DW_AT_GNU_addr_base: 0x0
...
referring to a .dwo file, but as the warnings show, the .dwo file is not
found.
Fix this by skipping the type unit in write_one_signatured_type if
psymtab == nullptr.
Tested on x86_64-linux.
gdb/ChangeLog:
2021-02-02 Tom de Vries <tdevries@suse.de>
PR symtab/24620
* dwarf2/index-write.c (write_one_signatured_type): Skip if
psymtab == nullptr.
gdb/testsuite/ChangeLog:
2021-02-02 Tom de Vries <tdevries@suse.de>
PR symtab/24620
* gdb.dwarf2/fission-reread.exp: Add test-case.
|
|
While looking into a failure in gdb.go/package.exp with gcc-11, I noticed that
gdb shows some complaints when loading the executable (also with gcc-10, where
the test-case passes):
...
$ gdb -batch -iex "set complaints 100" package.10 -ex start
During symbol reading: Attribute value is not a constant (DW_FORM_sec_offset)
Temporary breakpoint 1 at 0x402ae6: file gdb.go/package1.go, line 8.
During symbol reading: Attribute value is not a constant (DW_FORM_sec_offset)
During symbol reading: Invalid .debug_rnglists data (no base address)
...
Fix this by using as_unsigned () to read DW_AT_ranges in the partial DIE
reader, similar to how that is done in dwarf2_get_pc_bounds.
Tested on x86_64-linux.
gdb/ChangeLog:
2021-01-25 Bernd Edlinger <bernd.edlinger@hotmail.de>
Simon Marchi <simon.marchi@polymtl.ca>
Tom de Vries <tdevries@suse.de>
* dwarf2/read.c (partial_die_info::read): Use as_unsigned () for
DW_AT_ranges.
gdb/testsuite/ChangeLog:
2021-01-25 Tom de Vries <tdevries@suse.de>
* gdb.dwarf2/dw2-ranges-psym.exp (gdb_load_no_complaints): New proc.
* lib/gdb.exp: Use gdb_load_no_complaints.
|
|
A recent version of GCC changed how fixed-point types are described.
For example, a denominator in one test case now looks like:
GNU_denominator (exprloc)
[ 0] implicit_value: 16 byte block: 00 00 b8 9d 0d 69 55 a0 01 00 00 00 00 00 00 00
... the difference being that this now uses exprloc and emits a
DW_OP_implicit_value for the 16-byte block. (DWARF 5 still uses
DW_FORM_data16.)
This change was made here:
https://gcc.gnu.org/pipermail/gcc-patches/2020-December/560897.html
This patch updates gdb to handle this situation.
Note that, before GCC 11, this test would not give the same answer.
Earlier versions of GCC fell back to GNAT encodings for this case.
gdb/ChangeLog
2021-01-25 Tom Tromey <tromey@adacore.com>
* dwarf2/read.c (get_mpz): New function.
(get_dwarf2_rational_constant): Use it.
gdb/testsuite/ChangeLog
2021-01-25 Tom Tromey <tromey@adacore.com>
* gdb.ada/fixed_points.exp: Add regression test.
* gdb.ada/fixed_points/fixed_points.adb (FP5_Var): New variable.
* gdb.ada/fixed_points/pck.adb (Delta5, FP5_Type): New.
|
|
This changes the GDB compile code to use std::vector<bool> when
computing which registers are used. This is a bit more idiomatic, but
the main benefit is that it also adds some checking when the libstd++
debug mode is enabled.
2021-01-23 Tom Tromey <tom@tromey.com>
* symtab.h (struct symbol_computed_ops) <generate_c_location>:
Change type of "registers_used".
* dwarf2/loc.h (dwarf2_compile_property_to_c): Update.
* dwarf2/loc.c (dwarf2_compile_property_to_c)
(locexpr_generate_c_location, loclist_generate_c_location): Change
type of "registers_used".
* compile/compile.h (compile_dwarf_expr_to_c)
(compile_dwarf_bounds_to_c): Update.
* compile/compile-loc2c.c (pushf_register_address)
(pushf_register, do_compile_dwarf_expr_to_c)
(compile_dwarf_expr_to_c, compile_dwarf_bounds_to_c): Change type
of "registers_used".
* compile/compile-c.h (generate_c_for_variable_locations):
Update.
* compile/compile-c-symbols.c (generate_vla_size)
(generate_c_for_for_one_variable): Change type of
"registers_used".
(generate_c_for_variable_locations): Return std::vector.
* compile/compile-c-support.c (generate_register_struct): Change
type of "registers_used".
(compute): Update.
|
|
The symptom that leads to this is the crash described in PR 26828:
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:23478:25: runtime error: member access within null pointer of type 'struct dwarf2_cu'
The line of the crash is the following, in follow_die_offset:
if (target_cu != cu)
target_cu->ancestor = cu; <--- HERE
The line that assign nullptr to `target_cu` is the `per_objfile->get_cu`
call after having called maybe_queue_comp_unit:
/* If necessary, add it to the queue and load its DIEs. */
if (maybe_queue_comp_unit (cu, per_cu, per_objfile, cu->language))
load_full_comp_unit (per_cu, per_objfile, per_objfile->get_cu (per_cu),
false, cu->language);
target_cu = per_objfile->get_cu (per_cu); <--- HERE
Some background: there is an invariant, documented in
maybe_queue_comp_unit's doc, that if a CU is queued for expansion
(present in dwarf2_per_bfd::queue), then its DIEs are loaded in memory.
"its DIEs are loaded in memory" is a synonym for saying that a dwarf2_cu
object exists for this CU. Yet another way to say it is that
`per_objfile->get_cu (per_cu)` returns something not nullptr for that
CU.
The crash documented in PR 26828 triggers some hard-to-reproduce
sequence that ends up violating the invariant:
- dwarf2_fetch_die_type_sect_off gets called for a DIE in CU A
- The DIE in CU A requires some DIE in CU B
- follow_die_offset calls maybe_queue_comp_unit. maybe_queue_comp_unit
sees CU B is not queued and its DIEs are not loaded, so it enqueues it
and returns 1 to its caller - meaning "the DIEs are not loaded, you
should load them" - prompting follow_die_offset to load the DIEs by
calling load_full_comp_unit
- Note that CU B is enqueued by maybe_queue_comp_unit even if it has
already been expanded. It's a bit useless (and causes trouble, see
next patch), but that's how it works right now.
- Since we entered the dwarf2/read code through
dwarf2_fetch_die_type_sect_off, nothing processes the queue, so we
exit the dwarf2/read code with CU B still lingering in the queue.
- dwarf2_fetch_die_type_sect_off gets called for a DIE in CU A, again
- The DIE in CU A requires some DIE in CU B, again
- This time, maybe_queue_comp_unit sees that CU B is in the queue.
Because of the invariant that if a CU is in the queue, its DIEs are
loaded in the memory, it returns 0 to its caller, meaning "you don't
need to load the DIEs!".
- That happens to be true, so everything is fine for now.
- Time passes, some things call dwarf2_per_objfile::age_comp_units
enough so that CU B's age becomes past the dwarf_max_cache_age
threshold. age_comp_units proceeds to free CU B's DIEs. Remember
that CU B is still lingering in the queue (oops, the invariant just
got violated).
- dwarf2_fetch_die_type_sect_off gets called for a DIE in CU A, again
- The DIE in CU A requires some DIE in CU B, again
- maybe_queue_comp_unit sees that CU B is in the queue, so returns to
its caller "you don't need to load the DIEs!". However, we know at
this point this is false.
- follow_die_offset doesn't load the DIEs and tries to obtain the DIEs for
CU B:
target_cu = per_objfile->get_cu (per_cu);
But since they are not loaded, target_cu is nullptr, and we get the
crash mentioned above a few lines after that.
This patch adds an assertions in maybe_queue_comp_unit to verify the
invariant, to make sure it doesn't return a falsehood to its caller.
The current patch doesn't fix the issue (the next patch does), but it
makes it so we catch the problem earlier and get this assertion failure
instead of a segmentation fault:
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:9100: internal-error:
int maybe_queue_comp_unit(dwarf2_cu*, dwarf2_per_cu_data*, dwarf2_per_objfile*, language):
Assertion `per_objfile->get_cu (per_cu) != nullptr' failed.
gdb/ChangeLog:
PR gdb/26828
* dwarf2/read.c (maybe_queue_comp_unit): Add assertion.
Change-Id: I4e51bd7bd58773f9fadf480179cbc4bae61508fe
|
|
This patch adds some logging that helped me diagnose the problems fixed
later in this series. I'm thinking that if it helped me now, it could
help somebody else (or myself) in the future, so I might as well add
them for real.
They can happen quite frequently and be noisy, so I used
dwarf_read_debug_printf_v for them, which means they'll only print if
`set debug dwarf-read` is >= 2.
gdb/ChangeLog:
* dwarf2/read.c (follow_die_offset): Add logging.
(dwarf2_per_objfile::age_comp_units): Add logging.
Change-Id: I7483c0b05c37bc9710b9b5d40e272935bc010863
|
|
This patch converts the most obvious functions from gdb/frame.h to use
the gdb::array_view abstraction. I've converted the ones that used buffer +
length.
There are others using only the buffer, with an implicit size. I did not
touch those for now. But it would be nice to pass the size for safety.
Tested with --enable-targets=all on Ubuntu 18.04/20.04 aarch64-linux.
gdb/ChangeLog
2021-01-19 Luis Machado <luis.machado@linaro.org>
* frame.h (get_frame_register_bytes): Pass a gdb::array_view instead
of buffer + length.
(put_frame_register_bytes): Likewise.
Adjust documentation.
(get_frame_memory): Pass a gdb::array_view instead of buffer + length.
(safe_frame_unwind_memory): Likewise.
* frame.c (get_frame_register_bytes, put_frame_register_bytes)
(get_frame_memory, safe_frame_unwind_memory): Adjust to use
gdb::array_view.
* amd64-fbsd-tdep.c (amd64fbsd_sigtramp_p): Likewise.
* amd64-linux-tdep.c (amd64_linux_sigtramp_start): Likewise.
* amd64-obsd-tdep.c (amd64obsd_sigtramp_p): Likewise.
* arc-linux-tdep.c (arc_linux_is_sigtramp): Likewise.
* cris-tdep.c (cris_sigtramp_start, cris_rt_sigtramp_start): Likewise.
* dwarf2/loc.c (rw_pieced_value): Likewise.
* hppa-tdep.c (hppa_frame_cache): Likewise.
* i386-fbsd-tdep.c (i386fbsd_sigtramp_p): Likewise.
* i386-gnu-tdep.c (i386_gnu_sigtramp_start): Likewise.
* i386-linux-tdep.c (i386_linux_sigtramp_start)
(i386_linux_rt_sigtramp_start): Likewise.
* i386-obsd-tdep.c (i386obsd_sigtramp_p): Likewise.
* i386-tdep.c (i386_register_to_value): Likewise.
* i387-tdep.c (i387_register_to_value): Likewise.
* ia64-tdep.c (ia64_register_to_value): Likewise.
* m32r-linux-tdep.c (m32r_linux_sigtramp_start)
(m32r_linux_rt_sigtramp_start): Likewise.
* m68k-linux-tdep.c (m68k_linux_pc_in_sigtramp): Likewise.
* m68k-tdep.c (m68k_register_to_value): Likewise.
* mips-tdep.c (mips_register_to_value)
(mips_value_to_register): Likewise.
* ppc-fbsd-tdep.c (ppcfbsd_sigtramp_frame_sniffer)
(ppcfbsd_sigtramp_frame_cache): Likewise.
* ppc-obsd-tdep.c (ppcobsd_sigtramp_frame_sniffer)
(ppcobsd_sigtramp_frame_cache): Likewise.
* rs6000-tdep.c (rs6000_in_function_epilogue_frame_p)
(rs6000_register_to_value): Likewise.
* tilegx-tdep.c (tilegx_analyze_prologue): Likewise.
* tramp-frame.c (tramp_frame_start): Likewise.
* valops.c (value_assign): Likewise.
|
|
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.
|
|
The function c_printchar is called from two places; it provides the
implementation of language_defn::printchar and it is called from
dwarf2_compute_name.
It would be nice to rename c_printchar as language_defn::printchar and
so avoid the trampoline.
To achieve this, instead of calling c_printchar directly from the
DWARF code, I lookup the C++ language object and call the printchar
member function.
In a later commit I can then rename c_printchar.
There should be no user visible changes after this commit.
gdb/ChangeLog:
* dwarf2/read.c (dwarf2_compute_name): Call methods on C++
language object instead of calling global functions directly.
|
|
To handle thick pointers with -fgnat-encodings=minimal, gdb will
rewrite the underlying array type to remove the bounds. However, if
the same DWARF type is used both for a thick pointer and for an
ordinary array, this will have the side effect of removing the bounds
from the array. This breaks the printing of objects of this type.
This patch fixes the problem by copying the array type, its range, and
its bounds.
gdb/ChangeLog
2020-12-14 Tom Tromey <tromey@adacore.com>
* dwarf2/read.c (rewrite_array_type): New function.
(quirk_ada_thick_pointer_struct): Use rewrite_array_type.
gdb/testsuite/ChangeLog
2020-12-14 Tom Tromey <tromey@adacore.com>
* gdb.dwarf2/ada-thick-pointer.exp: New file.
|
|
The same pattern happens often to define a "debug_printf" macro:
#define displaced_debug_printf(fmt, ...) \
do \
{ \
if (debug_displaced) \
debug_prefixed_printf ("displaced", __func__, fmt, ##__VA_ARGS__); \
} \
while (0)
Move this pattern behind a helper macro, debug_prefixed_printf_cond and
update the existing macros to use it.
gdb/ChangeLog:
* displaced-stepping.h (displaced_debug_printf): Use
debug_prefixed_printf_cond.
* dwarf2/read.c (dwarf_read_debug_printf): Likewise.
(dwarf_read_debug_printf_v): Likewise.
* infrun.h (infrun_debug_printf): Likewise.
* linux-nat.c (linux_nat_debug_printf): Likewise.
gdbsupport/ChangeLog:
* common-debug.h (debug_prefixed_printf_cond): New.
* event-loop.h (event_loop_debug_printf): Use
debug_prefixed_printf_cond.
Change-Id: I1ff48b98b8d1cc405d1c7e8da8ceadf4e3a17f99
|