Removes a use of VEC from dwarf2read.{c,h} and replaces it with
std::vector. As far as possible this is a like for like replacement
with minimal refactoring.
There should be no user visible changes after this commit.
gdb/ChangeLog:
* dwarf2read.c (struct type_unit_group) <tus>: Convert to
std::vector.
(build_type_psymtabs_reader): Update for std::vector.
(build_type_psymtab_dependencies): Likewise.
* dwarf2read.h: Remove use of DEF_VEC_P.
(typedef sig_type_ptr): Delete.
* Handle DW_FORM_strx forms everywhere.
Tested with CC=/usr/bin/gcc (version 8.3.0) against master branch (also with
-gsplit-dwarf and -gdwarf-4 flags) and there was no increase in the set of
tests that fails.
This is part of an effort to support DWARF 5 in gdb.
gdb/ChangeLog:
* dwarf2read.c (skip_one_die): Handle DW_FORM_strx forms.
(dwarf2_string_attr): Likewise.
This parameter is really a boolean, so change the type accordingly
and update the callers.
This is for symbol_set_names, add_psymbol_to_bcache, and
add_psymbol_to_list.
minimal_symbol_reader::record_full was already passing a bool
to symbol_set_names.
gdb/ChangeLog:
2019-09-11 Christian Biesinger <cbiesinger@google.com>
* dbxread.c (read_dbx_symtab): Update.
* dwarf2read.c (load_partial_dies): Update.
* mdebugread.c (parse_partial_symbols): Update.
(handle_psymbol_enumerators): Update.
* psympriv.h (add_psymbol_to_list): Change type of copy_names to bool.
* psymtab.c (add_psymbol_to_bcache): Likewise.
(add_psymbol_to_list): Likewise.
* symtab.c (symbol_set_names): Likewise.
* symtab.h (symbol_set_names): Likewise.
* xcoffread.c (scan_xcoff_symtab): Update.
This patch adds support for Ada to .debug_names. I opted to leave
.gdb_index alone, because in my view it is a defunct format.
gdb/ChangeLog
2019-09-10 Tom Tromey <tromey@adacore.com>
* dwarf-index-write.c (write_psymbols): Extend error message.
(debug_names::insert): Add Ada code.
(debug_names::write_psymbols): Remove Ada check.
(debug_names) <m_string_obstack>: New member.
* dwarf2read.c (gdb_index_symbol_name_matcher): Remove.
(gdb_index_symbol_name_matcher::matches): Remove.
(mapped_index_base::find_name_components_bounds): Add "lang"
parameter.
(mapped_index_base::build_name_components): Also split names
according to Ada syntax.
(dw2_expand_symtabs_matching_symbol): Loop over languages. Change
type of "match_callback".
(check_match, check_find_bounds_finds)
(dw2_expand_symtabs_matching): Update.
(dw2_debug_names_iterator): Add new constructor.
(dw2_debug_names_map_matching_symbols): New function.
(dw2_debug_names_expand_symtabs_matching): Update.
(dwarf2_debug_names_functions): Use
dw2_debug_names_map_matching_symbols.
An internal Ada test case showed that the .debug_names code does not
compute the same list of file names as the partial symbol reader. In
particular, the partial symbol reader uses the DW_AT_name of the CU:
/* Allocate a new partial symbol table structure. */
filename = dwarf2_string_attr (comp_unit_die, DW_AT_name, cu);
if (filename == NULL)
filename = "";
pst = create_partial_symtab (per_cu, filename);
This patch changes the .debug_names reader to follow.
gdb/ChangeLog
2019-09-10 Tom Tromey <tromey@adacore.com>
* dwarf2read.c (dw2_get_file_names_reader): Add the
CU's file name to the results.
gdb/testsuite/ChangeLog
2019-09-10 Tom Tromey <tromey@adacore.com>
* gdb.ada/dgopt.exp: New file.
* gdb.ada/dgopt/x.adb: New file.
This patch further simplifies the map_matching_symbols callback, by
having it take a lookup_name_info rather than a plain string.
gdb/ChangeLog
2019-09-10 Tom Tromey <tromey@adacore.com>
* ada-lang.c (add_nonlocal_symbols): Combine calls to
map_matching_symbols. Update.
* dwarf2read.c (dw2_map_matching_symbols): Update.
* psymtab.c (match_partial_symbol): Change type; update.
(psym_map_matching_symbols): Likewise.
* symfile-debug.c (debug_qf_map_matching_symbols): Change
type; update.
* symfile.h (struct quick_symbol_functions)
<map_matching_symbols>: Change "name" to be a lookup_name_info.
Remove "match".
This changes map_matching_symbols to take a
symbol_found_callback_ftype, rather than separate callback and data
parameters. This enables a future patch to clean up some existing
code so that it can more readily be shared.
gdb/ChangeLog
2019-09-10 Tom Tromey <tromey@adacore.com>
* ada-lang.c (aux_add_nonlocal_symbols): Change type.
(add_nonlocal_symbols): Update.
* dwarf2read.c (dw2_map_matching_symbols): Change type.
* psymtab.c (map_block, psym_map_matching_symbols): Change type.
* symfile-debug.c (debug_qf_map_matching_symbols): Change type.
* symfile.h (struct quick_symbol_functions) <map_matching_symbols>:
Change type of "callback". Remove "data".
* DW_UT_skeleton and DW_UT_split_compile compilation units have dwo ids
to match the compilation unit in the skeleton and .dwo files. The dwo_id is
in the header.
Tested with CC=/usr/bin/gcc (version 8.3.0) against master branch (also with
-gsplit-dwarf and -gdwarf-4 flags) and there was no increase in the set of
tests that fails.
This is part of an effort to support DWARF 5 in gdb.
gdb/ChangeLog:
* dwarf2read.c (comp_unit_head): Update comment.
(dwarf2_dwo_name): New function declaration.
(dwarf_unit_type_name): New function declaration.
(read_comp_unit_head): Add support for new compilation units,
DW_UT_partial, DW_UT_skeleton, DW_UT_split_compile, DW_UT_split_type.
Particularly, DW_UT_skeleton and DW_UT_split_compile have dwo_id
(currently named as "signature") in their header. Also clarify error
messages.
(lookup_dwo_id): New function. Returns the dwo id of the given
compile unit.
(lookup_dwo_unit): Use the new lookup_dwo_id function.
(init_cutu_and_read_dies): Use the new dwarf2_dwo_name and lookup_dwo_id
functions.
(create_dwo_cu_reader): Use the added lookup_dwo_id function.
(dwarf2_dwo_name): Get the dwo name if present.
(dwarf_unit_type_name): Convert DW_UT_* types to string for diagnostic
purposes.
The only two values valid to pass to the block_index parameter of
quick_symbol_functions::lookup_symbol are GLOBAL_BLOCK and STATIC_BLOCK,
part of enum block_enum. Change the type of that parameter to
block_enum.
Change also the block_index field of dw2_symtab_iterator in the same
way.. This makes it consistent with dw2_debug_names_iterator, which
already uses block_enum for its block_index field.
This is a follow-up to this thread:
https://sourceware.org/ml/gdb-patches/2019-08/msg00097.html
gdb/ChangeLog:
* dwarf2read.c (struct dw2_symtab_iterator) <block_index>:
Change type to gdb::optional<block_enum>.
(dw2_symtab_iter_init): Change block_index parameter type
to gdb::optional<block_enum>.
(dw2_lookup_symbol): Change block_index parameter
type to block_enum.c
(dw2_debug_names_lookup_symbol): Likewise.
* psymtab.c (psym_lookup_symbol): Likewise.
* symfile-debug.c (debug_qf_lookup_symbol): Likewise.
* symfile.h (struct quick_symbol_functions) <lookup_symbol>:
Likewise.
In Ada, the programmer can request that a range type with a non-zero
base be stored in the minimal number of bits required for the range.
This is done by biasing the values; so, for example, a range of -7..-4
may be stored as two bits with a bias of -7.
This patch implements this for gdb. It is done by adding a bias to
struct range_bounds and then adjusting a few spots to handle this.
The test case is written to use -fgnat-encodings=minimal, but a future
compiler patch will change the compiler to emit DW_AT_GNU_bias with
-fgnat-encodings=gdb. It seemed good to get the gdb patch in first.
Tested on x86-64 Fedora 29; plus a variety of targets using AdaCore's
internal test suite.
gdb/ChangeLog
2019-09-03 Tom Tromey <tromey@adacore.com>
* ada-valprint.c (ada_val_print_num): Don't recurse for range
types.
(has_negatives): Unbias a range type bound.
* dwarf2read.c (read_subrange_type): Handle DW_AT_GNU_bias.
* gdbtypes.c (operator==): Handle new field.
(create_range_type): Add "bias" parameter.
(create_static_range_type, resolve_dynamic_range): Update.
* gdbtypes.h (struct range_bounds) <bias>: New member.
(create_range_type): Add bias parameter.
* printcmd.c (print_scalar_formatted): Unbias range types.
* value.c (unpack_long): Unbias range types.
(pack_long): Bias range types.
gdb/testsuite/ChangeLog
2019-09-03 Tom Tromey <tromey@adacore.com>
* gdb.ada/bias.exp: New file.
* gdb.ada/bias/bias.adb: New file.
* gdb.ada/print_chars.exp: Add regression test.
* gdb.ada/print_chars/foo.adb (My_Character): New type.
(MC): New variable.
gcc 4.8 (and probably other versions too) doesn't like that the local
variable symbol_linkage has the same name as the enum class defined in
the same context:
CXX dwarf2read.o
/home/smarchi/src/binutils-gdb/gdb/dwarf2read.c: In member function ‘dwarf2_per_cu_data* dw2_debug_names_iterator::next()’:
/home/smarchi/src/binutils-gdb/gdb/dwarf2read.c:5850:22: error: ‘symbol_linkage’ is not a class, namespace, or enumeration
} symbol_linkage = symbol_linkage::unknown;
^
Rename the local variable to avoid this.
This problem was originally reported with the Netbsd builder on the
buildbot, which uses gcc 5.5, I believe. I am not able to test it on
that builder right now, but chances are that the fix will work there
too.
gdb/ChangeLog:
* dwarf2read.c (dw2_debug_names_iterator::next): Rename local
variable symbol_linkage to symbol_linkage_.
gdb::optional<bool> is dangerous, because it's easy to do:
if (opt_bool)
when you actually meant
if (*opt_bool)
or vice-versa. The first checks if the optional is set, the second
checks if the wrapped bool is true.
Replace it with an enum that explicitly defines the three possible
states.
gdb/ChangeLog:
* dwarf2read.c (dw2_debug_names_iterator::next): Use enum to
represent whether the symbol is static, dynamic, or we don't
know.
With target board unix/-fPIE/-pie, we get:
...
FAIL: gdb.dwarf2/varval.exp: print varval2
...
This is due comparing a get_frame_pc result (which includes the for PIE
non-zero relocation offset) with pc_high and pc_low obtained using
get_scope_pc_bounds (which do not include the relocation offset).
Fix this by adjusting pc_high and pc_low with the relocation offset.
Tested on x86_64-linux with target board unix/-fPIE/-pie.
gdb/ChangeLog:
2019-08-09 Tom de Vries <tdevries@suse.de>
PR gdb/24591
* dwarf2read.c (dwarf2_fetch_die_loc_sect_off): Adjust pc_high and
pc_low with relocation offset.
This introduces obstack_strndup and changes gdb to use it.
Note that obstack_strndup works like savestring, and not exactly like
xstrndup. The difference is that obstack_strndup uses the passed-in
length, while xstrndup uses strnlen to choose the length.
gdb/ChangeLog
2019-08-06 Tom Tromey <tom@tromey.com>
* stabsread.c (patch_block_stabs, read_one_struct_field)
(read_enum_type): Use obstack_strndup.
* rust-exp.y (rust_parser::copy_name): Use obstack_strndup.
* gdb_obstack.h (obstack_strndup): Use obstack_strndup.
* dwarf2read.c (guess_full_die_structure_name)
(anonymous_struct_prefix): Use obstack_strndup.
* dbxread.c (cp_set_block_scope): Use obstack_strndup.
* c-exp.y (yylex): Use obstack_strndup.
* ada-exp.y (write_object_renaming, write_ambiguous_var)
(write_var_or_type): Use obstack_strndup.
This adds an obstack_strdup overload that takes a std::string, and
changes a few spots in gdb to use it.
gdb/ChangeLog
2019-08-06 Tom Tromey <tom@tromey.com>
* symfile.c (reread_symbols): Use obstack_strdup.
* stabsread.c (read_type): Use obstack_strdup.
* gdb_obstack.h (obstack_strdup): New overload.
* dwarf2read.c (dwarf2_compute_name, create_dwo_unit_in_dwp_v1)
(create_dwo_unit_in_dwp_v2, build_error_marker_type)
(dwarf2_canonicalize_name): Use obstack_strdup.
* dbxread.c (read_dbx_symtab): Use obstack_strdup.
* cp-support.c (inspect_type, replace_typedefs_qualified_name):
Use obstack_strdup.
This changes gdb to use obstack_strdup when appropriate, rather than
the wordier obstack_copy0.
gdb/ChangeLog
2019-08-06 Tom Tromey <tom@tromey.com>
* xcoffread.c (SYMNAME_ALLOC, process_xcoff_symbol): Use
obstack_strdup.
* typeprint.c (typedef_hash_table::find_global_typedef): Use
obstack_strdup.
* symfile.c (allocate_compunit_symtab): Use obstack_strdup.
* stabsread.c (common_block_start): Use obstack_strdup.
* objfiles.c (set_objfile_main_name, objfile): Use
obstack_strdup.
* namespace.c (add_using_directive): Use obstack_strdup.
* mdebugread.c (parse_symbol, parse_type): Use obstack_strdup.
* jit.c (finalize_symtab): Use obstack_strdup.
* dwarf2read.c (fixup_go_packaging, dwarf2_physname)
(guess_partial_die_structure_name, partial_die_info::fixup)
(dwarf2_name): Use obstack_strdup.
* coffread.c (coff_read_struct_type, coff_read_enum_type): Use
obstack_strdup.
* c-exp.y (scan_macro_expansion): Use obstack_strdup.
* buildsym.c (buildsym_compunit::end_symtab_with_blockvector): Use
obstack_strdup.
* ada-lang.c (ada_decode_symbol): Use obstack_strdup.
With this patch, the help docs now respect 2 invariants:
* The first line of a command help is terminated by a '.' character.
* The last character of a command help is not a newline character.
Note that the changes for the last invariant were done by Tom, as part of :
[PATCH] Remove trailing newlines from help text
https://sourceware.org/ml/gdb-patches/2019-06/msg00050.html
but some occurrences have been re-introduced since then.
Some help docs had to be rephrased/restructured to respect the above
invariants.
Before this patch, print_doc_line was printing the first line
of a command help documentation, but stopping at the first '.'
or ',' character.
This was giving inconsistent results :
* The first line of command helps was sometimes '.' terminated,
sometimes not.
* The first line of command helps was not always designed to be
readable/understandable/unambiguous when stopping at the first
'.' or ',' character.
This e.g. created the following inconsistencies/problems:
< catch exception -- Catch Ada exceptions
< catch handlers -- Catch Ada exceptions
< catch syscall -- Catch system calls by their names
< down-silently -- Same as the `down' command
while the new help is:
> catch exception -- Catch Ada exceptions, when raised.
> catch handlers -- Catch Ada exceptions, when handled.
> catch syscall -- Catch system calls by their names, groups and/or numbers.
> down-silently -- Same as the `down' command, but does not print anything.
Also, the command help doc should not be terminated by a newline
character, but this was not respected by all commands.
The cli-option -OPT framework re-introduced some occurences.
So, the -OPT build help framework was changed to not output newlines at the
end of %OPTIONS% replacement.
This patch changes the help documentations to ensure the 2 invariants
given above.
It implied to slightly rephrase or restructure some help docs.
Based on the above invariants, print_doc_line (called by
'apropos' and 'help' commands to print the first line of a command
help) now outputs the full first line of a command help.
This all results in a lot of small changes in the produced help docs.
There are less code changes than changes in the help docs, as a lot
of docs are produced by some code (e.g. the remote packet usage settings).
gdb/ChangeLog
2019-08-07 Philippe Waroquiers <philippe.waroquiers@skynet.be>
* cli/cli-decode.h (print_doc_line): Add for_value_prefix argument.
* cli/cli-decode.c (print_doc_line): Likewise. It now prints
the full first line, except when FOR_VALUE_PREFIX. In this case,
the trailing '.' is not output, and the first character is uppercased.
(print_help_for_command): Update call to print_doc_line.
(print_doc_of_command): Likewise.
* cli/cli-setshow.c (deprecated_show_value_hack): Likewise.
* cli/cli-option.c (append_indented_doc): Do not append newline.
(build_help_option): Append newline after first appended_indented_doc
only if a second call is done.
(build_help): Append 2 new lines before each option, except the first
one.
* compile/compile.c (_initialize_compile): Add new lines after
%OPTIONS%, when not at the end of the help.
Change help doc or code
producing the help doc to respect the invariants.
* maint-test-options.c (_initialize_maint_test_options): Likewise.
Also removed the new line after 'Options:', as all other commands
do not put an empty line between 'Options:' and the first option.
* printcmd.c (_initialize_printcmd): Likewise.
* stack.c (_initialize_stack): Likewise.
* interps.c (interpreter_exec_cmd): Fix "Usage:" line that was
incorrectly telling COMMAND is optional.
* ada-lang.c (_initialize_ada_language): Change help doc or code
producing the help doc to respect the invariants.
* ada-tasks.c (_initialize_ada_tasks): Likewise.
* breakpoint.c (_initialize_breakpoint): Likewise.
* cli/cli-cmds.c (_initialize_cli_cmds): Likewise.
* cli/cli-logging.c (_initialize_cli_logging): Likewise.
* cli/cli-setshow.c (_initialize_cli_setshow): Likewise.
* cli/cli-style.c (cli_style_option::add_setshow_commands,
_initialize_cli_style): Likewise.
* corelow.c (core_target_info): Likewise.
* dwarf-index-cache.c (_initialize_index_cache): Likewise.
* dwarf2read.c (_initialize_dwarf2_read): Likewise.
* filesystem.c (_initialize_filesystem): Likewise.
* frame.c (_initialize_frame): Likewise.
* gnu-nat.c (add_task_commands): Likewise.
* infcall.c (_initialize_infcall): Likewise.
* infcmd.c (_initialize_infcmd): Likewise.
* interps.c (_initialize_interpreter): Likewise.
* language.c (_initialize_language): Likewise.
* linux-fork.c (_initialize_linux_fork): Likewise.
* maint-test-settings.c (_initialize_maint_test_settings): Likewise.
* maint.c (_initialize_maint_cmds): Likewise.
* memattr.c (_initialize_mem): Likewise.
* printcmd.c (_initialize_printcmd): Likewise.
* python/lib/gdb/function/strfns.py (_MemEq, _StrLen, _StrEq,
_RegEx): Likewise.
* ravenscar-thread.c (_initialize_ravenscar): Likewise.
* record-btrace.c (_initialize_record_btrace): Likewise.
* record-full.c (_initialize_record_full): Likewise.
* record.c (_initialize_record): Likewise.
* regcache-dump.c (_initialize_regcache_dump): Likewise.
* regcache.c (_initialize_regcache): Likewise.
* remote.c (add_packet_config_cmd, init_remote_threadtests,
_initialize_remote): Likewise.
* ser-tcp.c (_initialize_ser_tcp): Likewise.
* serial.c (_initialize_serial): Likewise.
* skip.c (_initialize_step_skip): Likewise.
* source.c (_initialize_source): Likewise.
* stack.c (_initialize_stack): Likewise.
* symfile.c (_initialize_symfile): Likewise.
* symtab.c (_initialize_symtab): Likewise.
* target-descriptions.c (_initialize_target_descriptions): Likewise.
* top.c (init_main): Likewise.
* tracefile-tfile.c (tfile_target_info): Likewise.
* tracepoint.c (_initialize_tracepoint): Likewise.
* tui/tui-win.c (_initialize_tui_win): Likewise.
* utils.c (add_internal_problem_command): Likewise.
* valprint.c (value_print_option_defs): Likewise.
gdb/testsuite/ChangeLog
2019-08-07 Philippe Waroquiers <philippe.waroquiers@skynet.be>
* gdb.base/style.exp: Update tests for help doc new invariants.
* gdb.base/help.exp: Likewise.
While reading that code, I noticed that some variables essentially meant
whether to consider some other variable or not. I think using
gdb::optional (which was not available when this code was written) is
clearer, as it embeds the used/not used predicate directly in the type
of the variable, making it harder to miss.
gdb/ChangeLog:
* dwarf2read.c (struct dw2_symtab_iterator):
<want_specific_block>: Remove.
<block_index>: Change type to gdb::optional.
(dw2_symtab_iter_init): Remove WANT_SPECIFIC_BLOCK parameter,
change type of BLOCK_INDEX parameter to gdb::optional.
(dw2_symtab_iter_next): Re-write in function of gdb::optional.
(dw2_lookup_symbol): Don't pass argument for
WANT_SPECIFIC_BLOCK.
(dw2_expand_symtabs_for_function): Don't pass argument for
WANT_SPECIFIC_BLOCK, pass empty optional for BLOCK_INDEX.
(class dw2_debug_names_iterator)
<dw2_debug_names_iterator>: Remove WANT_SPECIFIC_BLOCK
parameter, change BLOCK_INDEX type to gdb::optional.
<m_want_specific_block>: Remove.
<m_block_index>: Change type to gdb::optional.
(dw2_debug_names_iterator::next): Change type of IS_STATIC to
gdb::optional. Re-write in function of gdb::optional.
(dw2_debug_names_lookup_symbol): Don't pass argument for
WANT_SPECIFIC_BLOCK.
(dw2_debug_names_expand_symtabs_for_function): Don't pass
argument for WANT_SPECIFIC_BLOCK, pass empty optional for
BLOCK_INDEX.
This commit is preparation for the next one, with the aim of better
supporting signed dynamic properties on targets where the address size
specified in the DWARF headers is smaller than a CORE_ADDR, for
example debugging an i386 application on x86-64.
Consider this small Fortran program 'bounds.f90':
program test
integer, allocatable :: array (:)
allocate (array (-5:5))
array(3) = 1
end program test
Compiled with 'gfortran -m32 -g3 -O0 -o bounds bounds.f90'. The DWARF
for 'array' looks like this:
<2><97>: Abbrev Number: 10 (DW_TAG_variable)
<98> DW_AT_name : (indirect string, offset: 0x0): array
<9c> DW_AT_decl_file : 1
<9d> DW_AT_decl_line : 2
<9e> DW_AT_type : <0xaf>
<a2> DW_AT_location : 2 byte block: 91 58 (DW_OP_fbreg: -40)
<2><a5>: Abbrev Number: 11 (DW_TAG_lexical_block)
<a6> DW_AT_low_pc : 0x80485c3
<aa> DW_AT_high_pc : 0x8b
<2><ae>: Abbrev Number: 0
<1><af>: Abbrev Number: 12 (DW_TAG_array_type)
<b0> DW_AT_data_location: 2 byte block: 97 6 (DW_OP_push_object_address; DW_OP_deref)
<b3> DW_AT_allocated : 4 byte block: 97 6 30 2e (DW_OP_push_object_address; DW_OP_deref; DW_OP_lit0; DW_OP_ne)
<b8> DW_AT_type : <0x2a>
<2><bc>: Abbrev Number: 13 (DW_TAG_subrange_type)
<bd> DW_AT_lower_bound : 4 byte block: 97 23 10 6 (DW_OP_push_object_address; DW_OP_plus_uconst: 16; DW_OP_deref)
<c2> DW_AT_upper_bound : 4 byte block: 97 23 14 6 (DW_OP_push_object_address; DW_OP_plus_uconst: 20; DW_OP_deref)
<c7> DW_AT_byte_stride : 6 byte block: 97 23 c 6 34 1e (DW_OP_push_object_address; DW_OP_plus_uconst: 12; DW_OP_deref; DW_OP_lit4; DW_OP_mul)
<2><ce>: Abbrev Number: 0
If we look at the DW_AT_lower_bound attribute, which will become a
dynamic property that GDB evaluates when needed by calling
dwarf2_evaluate_property.
The process of evaluating a dynamic property requires GDB to execute
each DW_OP_* operation, the results of these operations is held on a
stack of 'struct value *'s.
When the entire expression is evaluated the result is on top of the
stack.
If we look at DW_AT_lower_bound then the last operation is
DW_OP_deref, this loads a signed address the size of which matches the
DWARF address size, and so in our i386 on x86-64 situation, the top of
the stack will be a signed 4-byte value.
The problem is how these values are fetched from the stack. Currently
they are always fetched by a call to dwarf_expr_context::fetch_address,
which converts the value to an unsigned value with a length matching
the values current length, before converting to a CORE_ADDR. This
means we loose the signed nature of the property.
I wonder if the best solution for dealing with signed properties will
be to move away from an over reliance on fetch_address, and instead
come up with a new solution that considers the current type of the
value on the stack, and the type that the value needs to become;
basically a solution built around casting rather than assuming we
always want an address.
However, before we can start to even think about moving away from
fetch_address, there is a more urgent issue to fix, which is we don't
currently know what type each property should be. We just hold the
value of the property in a CORE_ADDR as returned by fetch_address, and
rely on higher level code (outside of the DWARF expression evaluation
code) to fix things up for us. This is what this patch aims to
address.
When creating a dynamic property (see attr_to_dynamic_prop in
dwarf2read.c) we can sometimes figure out the type of a property; if
the property is a reference to another DIE then it will have a
DW_AT_type attribute.
However, the DW_AT_lower_bound case above isn't a reference to another
DIE, it's just a DWARF expression. We don't have any indication for
what type the property should have.
Luckily, the DWARF spec helps us out, for the lower and upper bounds
5.13 of the DWARFv5 spec tells us that without any other type
information the bounds are signed integers the same size as a DWARF
address.
It is my belief that we can find a suitable default type for every
dynamic property, either specified explicitly in the DWARF spec, or we
can infer an obvious choice if the spec doesn't help us.
This commit extends the creation of all dynamic properties to include
suggesting a suitable default type, all dynamic properties now always
carry their type around with them.
In later commits we can use this property type to ensure that the
value we extract from the DWARF stack is handled in a suitable manor
to correctly maintain its sign extension.
There should be no user visible changes from this commit. The actual
fix to correctly support negative array bounds will come later.
gdb/ChangeLog:
* dwarf2loc.c (dwarf2_evaluate_property): Update to take account
of changes to field names, and use new is_reference field to
decide if a property is a reference or not.
* dwarf2loc.h (struct dwarf2_locexpr_baton): Add 'is_reference'
field.
(struct dwarf2_property_baton): Update header comment, rename
'referenced_type' to 'property_type' and update comments.
* dwarf2read.c (attr_to_dynamic_prop): Add extra parameter to hold
default property type, store in property baton, update to take
accound of renamed field.
(read_func_scope): Update call to attr_to_dynamic_prop.
(read_array_type): Likewise.
(dwarf2_per_cu_addr_sized_int_type): New function.
(read_subrange_index_type): Move type finding code to
dwarf2_per_cu_addr_sized_int_type.
(read_subrange_type): Update calls to attr_to_dynamic_prop.
(dwarf2_per_cu_addr_type): New function.
(set_die_type): Update calls to attr_to_dynamic_prop.
If a DW_TAG_subrange_type DWARF entry has no DW_AT_type then a default
type based on the size of an address on the current target is assumed.
We store this type as the target type for GDB's range types.
Currently GDB can create ranges for which the target type is VOID,
this is incorrect but seems to cause no problems. I believe the reason
this doesn't cause any issues is because the languages (for example
Ada) that actually make use of a ranges target type also have
compilers that generate DWARF that includes a DW_AT_type attribute.
However, gfortran does not include a DW_AT_type, its DWARF instead
relies on the default target type. This isn't currently a problem for
GDB as gfortran doesn't make use of the target type when printing
subranges, but it shouldn't hurt to fix this issue now.
I've added an assert into create_range_type that will catch this issue
if it comes up again.
This was tested on an x86-64/GNU-Linux machine with both the Ada and
gfortran compilers available with both '--target_board=unix' and
'--target_board=unix/-m32'. There are no user visible changes after
this commit.
gdb/ChangeLog:
* dwarf2read.c (read_subrange_index_type): New function.
(read_subrange_type): Move code into new function and call it.
* gdbtypes.c (create_range_type): Add some asserts.
A static analyzer pointed out that find_vec_in_debug_names will use
the contents of a unique_ptr after it has been destroyed. This patch
fixes the bug by hoisting the declaration into the appropriate
enclosing block.
I'm checking this in as obvious.
gdb/ChangeLog
2019-07-01 Tom Tromey <tromey@adacore.com>
* dwarf2read.c
(dw2_debug_names_iterator::find_vec_in_debug_names): Hoist
declaration of without_params. Fix formatting.
We discovered that the Ada support in gdb depends on the order of the
DW_AT_name and DW_AT_linkage_name attributes in the DWARF. In
particular, if they are emitted in the "wrong" order for some system
symbols, "catch exception" will not work.
This patch fixes this problem by arranging to always prefer the
linkage name if both exist. This seems to be what the full symbol
reader already does -- that is, this is another bug arising from
having two different DWARF readers.
Another possible issue here is that gdb still doesn't really preserve
mangled names properly. There's a PR open about this. However, this
seems to be somewhat involved to fix, which is why this patch
continues to work around the bigger issue.
gdb/ChangeLog
2019-06-28 Tom Tromey <tromey@adacore.com>
* dwarf2read.c (partial_die_info::read): Prefer the linkage name
for Ada.
gdb/testsuite/ChangeLog
2019-06-28 Tom Tromey <tromey@adacore.com>
* gdb.dwarf2/ada-linkage-name.c: New file.
* gdb.dwarf2/ada-linkage-name.exp: New file.
When building gdb on s390x with -m31, we run into this Wformat
warning (which Werror turns into an error):
...
gdb/dwarf2read.c: In function \
'void create_addrmap_from_aranges(dwarf2_per_objfile*, \
dwarf2_section_info*)':
gdb/dwarf2read.c:3277:22: error: format '%zu' expects argument of type \
'size_t', but argument 3 has type 'int' [-Werror=format=]
warning (_("Section .debug_aranges in %s entry at offset %zu "
...
The Wformat warning is triggered in this statement:
...
warning (_("Section .debug_aranges in %s entry at offset %zu "
"length %s exceeds section length %s, "
"ignoring .debug_aranges."),
objfile_name (objfile), entry_addr - section->buffer,
plongest (bytes_read + entry_length),
pulongest (section->size));
...
where 'entry_addr - section->buffer' is of type ptrdiff_t and '%zu' prints an
unsigned with the same size as size_t/ssize_t.
On s390x with -m31, we have:
- size_t : unsigned long int (32-bit)
- ptrdiff_t: int (32-bit)
Wformat warns against this because even though long int and int have the same
size, the types are not compatible.
[ The Wformat warning is to similar to what we would get for x86_64 -m32
(where long and int are also the same size) and:
...
int i;
printf ("%ld", i);
... ]
Fix this by using '%s' and plongest instead of '%zu' to print ptrdiff_t.
Build and reg-tested on x86_64.
gdb/ChangeLog:
2019-06-22 Tom de Vries <tdevries@suse.de>
* dwarf2read.c (create_addrmap_from_aranges)
(read_debug_names_from_section): Print ptrdiff_t using '%s' and plongest
instead of '%zu'.
This patch removes uses of VEC (dwarf2_section_info_def) in favor of
std::vector<dwarf2_section_info>. The conversion is relatively
straightforward, no function changes are intended.
gdb/ChangeLog:
* dwarf2read.h (dwarf2_section_info_def): Remove.
(DEF_VEC_O (dwarf2_section_info_def)): Remove.
* dwarf2read.c (struct dwo_sections) <types>: Change type to
std::vector<dwarf2_section_info>.
(struct dwo_file) <~dwo_file>: Remove.
(dwarf2_per_objfile::~dwarf2_per_objfile): Don't manually free
types field.
(dwarf2_per_objfile::locate_sections): Adjust to std::vector.
(dwarf2_read_debug_names): Likewise.
(create_debug_types_hash_table): Change parameter type to
array_view, adjust code accordingly.
(dwarf2_locate_dwo_sections): Adjust to std::vector.
(partial_die_info::fixup): Likewise.
(determine_prefix): Likewise.
* dwarf-index-write.c (write_psymtabs_to_index): Adjust.
This removes the manual call to gdb_bfd_ref in favor of gdb_bfd_ref_ptr.
gdb/ChangeLog:
* dwarf2read.c (struct dwo_file) <dbfd>: Change type to
gdb_bfd_ref_ptr.
<~dwo_file>: Remove call to gdb_bfd_unref.
(open_and_init_dwo_file): Move gdb_bfd_ref_ptr into dbfd field. Call
gdb_bfd_ref_ptr::get.
This patch changes dwo_file to be allocated/deallocated with new/delete,
so that we can start using C++ features in it, and in struct
dwo_sections.
The free_dwo_file function becomes the destructor of struct dwo_file
(and will disappear in upcoming patches, which will use gdb_bfd_ref_ptr
for dbfd and an std::vector for sections.types).
gdb/ChangeLog:
* dwarf2read.h (struct dwarf2_per_objfile) <dwo_files>: Change
type to htab_up.
* dwarf2read.c (struct dwo_file): Initialize fields.
<~dwo_file>: New.
(free_dwo_file): Remove, move content to ~dwo_file.
(struct dwo_file_deleter): Remove.
(dwo_file_up>: Remove custom deleter.
(free_dwo_files): Remove.
(dwarf2_per_objfile::~dwarf2_per_objfile): Don't explicitly free
dwo_files.
(process_skeletonless_type_units): Call unique_ptr::get.
(allocate_dwo_file_hash_table): Add deleter to created hash
table. Change return type to htab_up.
(lookup_dwo_file_slot): Don't memset dwo_file, call
unique_ptr::get.
(create_dwo_unit_in_dwp_v1): Allocate dwo_file with new.
(create_dwo_unit_in_dwp_v2): Likewise.
(open_and_init_dwo_file): Likewise.
(free_dwo_file_from_slot): Remove.
Use bool instead of char where applicable in dwarf2_section_info.
No functional changes intended.
gdb/ChangeLog:
* dwarf2read.h (struct dwarf2_section_info) <readin,
is_virtual>: Change type to bool.
* dwarf2read.c (dwarf2_read_section, create_dwp_v2_section): Use
true instead of 1.
The test-case varval.exp fails here:
...
FAIL: gdb.dwarf2/varval.exp: print varval2
...
with boards readnow/cc-with-gdb-index/cc-with-debug-names, as well as if gdb
is build with -fsanitize=address -lasan.
The problem is that the abstract_to_concrete map in which we track the
association of abstract to concrete DIEs (for DW_OP_GNU_variable_value
support) has type std::unordered_map<die_info_ptr, std::vector<die_info_ptr>>,
and the die_info_ptrs that we register in the map may be invalid by the time
that we start to lookup DIEs in the map.
Fix this by using the sect_offset instead to identify the DIEs in the map.
Build and tested on x86_64-linux.
gdb/ChangeLog:
2019-06-18 Tom de Vries <tdevries@suse.de>
PR gdb/24515
* dwarf2read.h (abstract_to_concrete): Change type from
std::unordered_map<die_info_ptr, std::vector<die_info_ptr>> to
std::unordered_map<sect_offset, std::vector<sect_offset>>.
* dwarf2read.c (read_variable): Update.
(dwarf2_fetch_die_loc_sect_off): Update.
PR 24445 ("dwz multifile index not written to index cache") exposed the
fact that we are not doing things right when we generate an index for an
object file that has is linked to a dwz file. The same happens whether
the index is generated with the intent of populating the index cache or
using the save gdb-index command.
The problem can be observed when running these tests with the
cc-with-dwz-m board:
FAIL: gdb.base/index-cache.exp: test_cache_enabled_hit: check index-cache stats
FAIL: gdb.dwarf2/gdb-index.exp: index used
FAIL: gdb.dwarf2/gdb-index.exp: index used after symbol reloading
When generating the index for such file and inspecting the CU list of the
resulting index (with readelf --debug-dump=gdb_index), we can see something
like:
CU table:
[ 0] 0x0 - 0xb9
[ 1] 0x0 - 0x44
This is supposed to be a sorted list of the ranges of all CUs in the
file this index represents, so already having some overlap is a red
flag. It turns out that we save the ranges of CUs coming from both the
main file and the dwz file in the same index.
After digging a little bit, it became quite obvious that the index in
the main file should only list the CUs present in the main file, and a
separate index should be generated for the dwz file, listing the CUs
present in that file.
First, that's what happens if you run dwz on a file that already has a
GDB index embedded. Second, dwarf2read.c has code to read an index from
a dwz file. The index in the dwz file is actually required to be
present, if the main file has an index.
So this patch changes write_psymtabs_to_index to generate an index for
the dwz file, if present. That index only contains a CU list, just like
what the dwz tool does when processing a file that already contains an
index.
Some notes about the implementation:
- The file management (creating a temp file, make sure it's
close/removed on error - in the right order) is a bit heavy in
write_psymtabs_to_index, and I needed to add a third file. I factored
this pattern in a separate class, index_wip_file.
- It became a bit tedious to keep the call to assert_file_size in
write_psymtabs_to_index, write_gdbindex would have had to return two
sizes. Instead, I moved the calls to assert_file_size where the file
is written. The downside is that we lose the filename at this point,
but it was only used for the very improbable case of ftell failing, so
I think it's not a problem.
- The actual writing of the index file is factored out to
write_gdbindex_1, so it can be re-used for both index files.
- While the "save gdb-index" command will now write two .gdb-index
files, this patch does not update the gdb-add-index.sh script, this
will come in a later patch.
gdb/ChangeLog:
YYYY-MM-DD Simon Marchi <simon.marchi@efficios.com>
PR gdb/24445
* dwarf-index-write.h (write_psymtabs_to_index): Add
dwz_basename parameter.
* dwarf-index-write.c (write_gdbindex): Move file writing to
write_gdbindex_1. Change return type void.
(assert_file_size): Move up, remove filename parameter.
(write_gdbindex_1): New function.
(write_debug_names): Change return type to void, call
assert_file_size.
(struct index_wip_file): New struct.
(write_psymtabs_to_index): Add dwz_basename parameter. Move
file logic to index_wip_file. Write index for dwz file if
needed.
(save_gdb_index_command): Pass basename of dwz file, if present.
* dwarf-index-cache.c (index_cache::store): Obtain and pass
build-id of dwz file, if present.
* dwarf2read.c (struct dwz_file): Move to dwarf2read.h.
(dwarf2_get_dwz_file): Likewise.
* dwarf2read.h (struct dwz_file): Move from dwarf2read.c.
(dwarf2_get_dwz_file): Likewise.
gdb/testsuite/ChangeLog:
YYYY-MM-DD Tom de Vries <tdevries@suse.de>
PR gdb/24445
* gdb.dwarf2/gdb-index.exp (add_gdb_index): Update dwz file with
generated index.
A name for BLOCK DATA in Fortran is optional. If no name has been
assigned, GDB crashes during read-in of DWARF when BLOCK DATA is
represented via DW_TAG_module. BLOCK DATA is used for one-time
initialization of non-pointer variables in named common blocks.
As of now there is no issue when gfortran is used as DW_TAG_module is
not emitted. However, with Intel ifort the nameless DW_TAG_module is
present and has the following form:
...
<1><dd>: Abbrev Number: 7 (DW_TAG_module)
<de> DW_AT_decl_line : 46
<df> DW_AT_decl_file : 1
<e0> DW_AT_description : (indirect string, offset: 0x110): block
data
<e4> DW_AT_high_pc : 0x402bb7
<ec> DW_AT_low_pc : 0x402bb7
...
The missing name leads to a crash in add_partial_symbol, during length
calculation.
gdb/ChangeLog:
2019-06-11 Bernhard Heckel <bernhard.heckel@intel.com>
* dwarf2read.c (add_partial_symbol): Skip nameless modules.
gdb/testsuite/Changelog:
2019-06-11 Bernhard Heckel <bernhard.heckel@intel.com>
* gdb.fortran/block-data.f: New.
* gdb.fortran/block-data.exp: New.
When compiling gdb with '-lasan -fsanitizer=address' and running tests with:
- export ASAN_OPTIONS="detect_leaks=0:alloc_dealloc_mismatch=0",
- target board cc-with-gdb-index,
- the "[gdb/testsuite] Fix gdb.base/break-probes.exp with native-gdbserver"
commit reverted to avoid running into PR24617,
we get with gdb.arch/amd64-init-x87-values.exp:
...
==31229==ERROR: AddressSanitizer: heap-buffer-overflow on address \
0x62500098c93c at pc 0x000000bcc748 bp 0x7ffe39487660 sp 0x7ffe39487658
READ of size 1 at 0x62500098c93c thread T0
#0 0xbcc747 in cp_find_first_component_aux src/gdb/cp-support.c:999
#1 0xbcc6e9 in cp_find_first_component(char const*) \
src/gdb/cp-support.c:977
#2 0xcc2cf3 in mapped_index_base::build_name_components() \
src/gdb/dwarf2read.c:4499
#3 0xcc3322 in dw2_expand_symtabs_matching_symbol src/gdb/dwarf2read.c:4552
#4 0xcc817f in dw2_expand_symtabs_matching src/gdb/dwarf2read.c:5228
#5 0xfe8f48 in iterate_over_all_matching_symtabs src/gdb/linespec.c:1147
#6 0x1003506 in add_matching_symbols_to_info src/gdb/linespec.c:4413
#7 0xffe21b in find_function_symbols src/gdb/linespec.c:3886
#8 0xffe4a2 in find_linespec_symbols src/gdb/linespec.c:3914
#9 0xfee3ad in linespec_parse_basic src/gdb/linespec.c:1865
#10 0xff5128 in parse_linespec src/gdb/linespec.c:2655
#11 0xff8872 in event_location_to_sals src/gdb/linespec.c:3150
#12 0xff90a8 in decode_line_full(event_location const*, int, \
program_space*, symtab*, int, linespec_result*, \
char const*, char const*) src/gdb/linespec.c:3230
#13 0x9ce449 in parse_breakpoint_sals src/gdb/breakpoint.c:9057
#14 0x9ea022 in create_sals_from_location_default src/gdb/breakpoint.c:13708
#15 0x9e2c1f in bkpt_create_sals_from_location src/gdb/breakpoint.c:12514
#16 0x9cff06 in create_breakpoint(gdbarch*, event_location const*, \
char const*, int, char const*, int, int, bptype, int, \
auto_boolean, breakpoint_ops const*, int, int, int, \
unsigned int) src/gdb/breakpoint.c:9238
#17 0x9d114a in break_command_1 src/gdb/breakpoint.c:9402
#18 0x9d1b60 in break_command(char const*, int) src/gdb/breakpoint.c:9473
#19 0xac96aa in do_const_cfunc src/gdb/cli/cli-decode.c:106
#20 0xad0e5a in cmd_func(cmd_list_element*, char const*, int) \
src/gdb/cli/cli-decode.c:1892
#21 0x15226f6 in execute_command(char const*, int) src/gdb/top.c:630
#22 0xddde37 in command_handler(char const*) src/gdb/event-top.c:586
#23 0xdde7c1 in command_line_handler(std::unique_ptr<char, \
gdb::xfree_deleter<char> >&&) src/gdb/event-top.c:773
#24 0xddc9e8 in gdb_rl_callback_handler src/gdb/event-top.c:217
#25 0x16f2198 in rl_callback_read_char src/readline/callback.c:220
#26 0xddc5a1 in gdb_rl_callback_read_char_wrapper_noexcept \
src/gdb/event-top.c:175
#27 0xddc773 in gdb_rl_callback_read_char_wrapper src/gdb/event-top.c:192
#28 0xddd9f5 in stdin_event_handler(int, void*) src/gdb/event-top.c:514
#29 0xdd7d8f in handle_file_event src/gdb/event-loop.c:731
#30 0xdd8607 in gdb_wait_for_event src/gdb/event-loop.c:857
#31 0xdd629c in gdb_do_one_event() src/gdb/event-loop.c:321
#32 0xdd6344 in start_event_loop() src/gdb/event-loop.c:370
#33 0x10a7715 in captured_command_loop src/gdb/main.c:331
#34 0x10aa548 in captured_main src/gdb/main.c:1173
#35 0x10aa5d8 in gdb_main(captured_main_args*) src/gdb/main.c:1188
#36 0x87bd35 in main src/gdb/gdb.c:32
#37 0x7f16e1434f89 in __libc_start_main (/lib64/libc.so.6+0x20f89)
#38 0x87bb49 in _start (build/gdb/gdb+0x87bb49)
0x62500098c93c is located 0 bytes to the right of 8252-byte region \
[0x62500098a900,0x62500098c93c)
allocated by thread T0 here:
#0 0x7f16e359a600 in malloc (/usr/lib64/libasan.so.5+0xeb600)
#1 0x1742ddf in bfd_malloc src/bfd/libbfd.c:275
#2 0x1738824 in bfd_get_full_section_contents src/bfd/compress.c:253
#3 0xe30044 in gdb_bfd_map_section(bfd_section*, unsigned long*) \
src/gdb/gdb_bfd.c:704
#4 0xcb56bf in dwarf2_read_section(objfile*, dwarf2_section_info*) \
src/gdb/dwarf2read.c:2539
#5 0xd5bcd0 in get_gdb_index_contents_from_section<dwarf2_per_objfile> \
src/gdb/dwarf2read.c:6217
#6 0xd7fc7d in gdb::function_view<gdb::array_view<unsigned char const> \
(...) const src/gdb/common/function-view.h:284
#7 0xd7fddd in gdb::function_view<gdb::array_view<unsigned char const> \
(...) src/gdb/common/function-view.h:278
#8 0xd730cf in gdb::function_view<gdb::array_view<unsigned char const> \
(...) const src/gdb/common/function-view.h:247
#9 0xcbc7ee in dwarf2_read_gdb_index src/gdb/dwarf2read.c:3582
#10 0xcce731 in dwarf2_initialize_objfile(objfile*, dw_index_kind*) \
src/gdb/dwarf2read.c:6297
#11 0xdb88c4 in elf_symfile_read src/gdb/elfread.c:1256
#12 0x141262a in read_symbols src/gdb/symfile.c:798
#13 0x14140a7 in syms_from_objfile_1 src/gdb/symfile.c:1000
#14 0x1414393 in syms_from_objfile src/gdb/symfile.c:1017
#15 0x1414fb7 in symbol_file_add_with_addrs src/gdb/symfile.c:1124
#16 0x14159b7 in symbol_file_add_from_bfd(bfd*, char const*, \
enum_flags<symfile_add_flag>, std::vector<other_sections, \
std::allocator<other_sections> >*, \
enum_flags<objfile_flag>, objfile*) src/gdb/symfile.c:1203
#17 0x1415b6c in symbol_file_add(char const*,
enum_flags<symfile_add_flag>, std::vector<other_sections, \
std::allocator<other_sections> >*, \
enum_flags<objfile_flag>) src/gdb/symfile.c:1216
#18 0x1415f2f in symbol_file_add_main_1 src/gdb/symfile.c:1240
#19 0x1418599 in symbol_file_command(char const*, int) \
src/gdb/symfile.c:1675
#20 0xde2fa6 in file_command src/gdb/exec.c:433
#21 0xac96aa in do_const_cfunc src/gdb/cli/cli-decode.c:106
#22 0xad0e5a in cmd_func(cmd_list_element*, char const*, int) \
src/gdb/cli/cli-decode.c:1892
#23 0x15226f6 in execute_command(char const*, int) src/gdb/top.c:630
#24 0xddde37 in command_handler(char const*) src/gdb/event-top.c:586
#25 0xdde7c1 in command_line_handler(std::unique_ptr<char, \
gdb::xfree_deleter<char> >&&) src/gdb/event-top.c:773
#26 0xddc9e8 in gdb_rl_callback_handler src/gdb/event-top.c:217
#27 0x16f2198 in rl_callback_read_char src/readline/callback.c:220
#28 0xddc5a1 in gdb_rl_callback_read_char_wrapper_noexcept \
src/gdb/event-top.c:175
#29 0xddc773 in gdb_rl_callback_read_char_wrapper src/gdb/event-top.c:192
SUMMARY: AddressSanitizer: heap-buffer-overflow src/gdb/cp-support.c:999 in \
cp_find_first_component_aux
Shadow bytes around the buggy address:
0x0c4a801298d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c4a801298e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c4a801298f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c4a80129900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c4a80129910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c4a80129920: 00 00 00 00 00 00 00[04]fa fa fa fa fa fa fa fa
0x0c4a80129930: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c4a80129940: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c4a80129950: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c4a80129960: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c4a80129970: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==31229==ABORTING
...
The problem happens as follows.
The executable amd64-init-x87-values gets an index (due to target board
cc-with-gdb-index), which looks as follows:
...
Hex dump of section '.gdb_index':
0x00000000 08000000 18000000 28000000 28000000 ........(...(...
0x00000010 3c000000 3c200000 00000000 00000000 <...< ..........
0x00000020 2e000000 00000000 d4004000 00000000 ..........@.....
0x00000030 db004000 00000000 00000000 00000000 ..@.............
0x00000040 00000000 00000000 00000000 00000000 ................
0x00000050 00000000 00000000 00000000 00000000 ................
... more zeroes ...
0x00002010 00000000 00000000 00000000 00000000 ................
0x00002020 00000000 00000000 00000000 00000000 ................
0x00002030 00000000 00000000 00000000 ............
...
The structure of this index is:
...
header : [0x0, 0x18) : size 0x18
culist : [0x18 ,0x28) : size 0x10
typesculist : [0x28, 0x28) : size 0x0
adress area : [0x28, 0x3c) : size 0x14
symbol table : [0x3c, 0x203c) : size 0x2000
constant pool: [0x203c, 0x203c): size 0x0
EOF : 0x203c
...
Note that the symbol table consists entirely of empty slots (where an empty
slot is a pair of 32-bit zeroes), and that the constant pool is empty.
The problem happens here in mapped_index_base::build_name_components:
...
auto count = this->symbol_name_count ();
for (offset_type idx = 0; idx < count; idx++)
{
if (this->symbol_name_slot_invalid (idx))
continue;
const char *name = this->symbol_name_at (idx);
...
when accessing the slot at idx == 0 in the symbol table,
symbol_name_slot_invalid returns false so we calculate name, which is
calculated using 'constant_pool + symbol_table[idx].name', which means we get
name == constant_pool. And given that the constant pool is empty, name now
points past the memory allocated for the index, and when we access name[0] for
the first time in cp_find_first_component_aux, we run into the
heap-buffer-overflow.
Fix this by fixing the definition of symbol_name_slot_invalid:
...
- return bucket.name == 0 && bucket.vec;
+ return bucket.name == 0 && bucket.vec == 0;
...
Tested on x86_64-linux.
gdb/ChangeLog:
2019-06-10 Tom de Vries <tdevries@suse.de>
PR gdb/24618
* dwarf2read.c (struct mapped_index::symbol_name_slot_invalid): Make
sure an empty slot (defined by a 32-bit zero pair) is recognized as
invalid.
DW_AT_main_subprogram is supported in normal mode in read_partial_die, but not
in -readnow mode.
Fix this by adding support for DW_AT_main_subprogram in read_func_scope.
Tested on x86_64-linux with native and RFC target board readnow (
https://sourceware.org/ml/gdb-patches/2019-05/msg00073.html ).
gdb/ChangeLog:
2019-06-10 Tom de Vries <tdevries@suse.de>
PR symtab/16264
PR symtab/24517
* dwarf2read.c (read_func_scope): Handle DW_AT_main_subprogram.
Ref.: https://bugzilla.redhat.com/show_bug.cgi?id=1715008
On commit 7bede82892 ("Don't crash if
dwarf_decode_macro_bytes's 'body' is NULL"), I was too strict when
checking if 'body' is NULL: the check only comprised the case when
'is_define' is true. However, the corruption of .debug_macro by
rpmbuild's "debugedit" also affects the case when 'is_define' is
false, i.e., when the macro is being undefined.
This commit improves the check and covers both cases now. This has
been tested on Fedora 30 with a problematic debuginfo, and I don't see
a segfault anymore.
OK to push?
gdb/ChangeLog:
2019-05-29 Sergio Durigan Junior <sergiodj@redhat.com>
Ref.: https://bugzilla.redhat.com/show_bug.cgi?id=1708192
Ref.: https://bugzilla.redhat.com/show_bug.cgi?id=1715008
* dwarf2read.c (dwarf_decode_macro_bytes): Move check to see if
'body' is NULL to the outter 'if', protecting the '!is_define'
situation as well.
I noticed that the complaint in partial_die_parent_scope was not using
dwarf_tag_name, so I changed that. Then I noticed that dwarf_tag_name
does not show the numeric value for an unrecognized tag, so I changed
that function and all the related functions to do so.
gdb/ChangeLog
2019-05-29 Tom Tromey <tromey@adacore.com>
* dwarf2read.c (partial_die_parent_scope): Call dwarf_tag_name.
(dwarf_unknown): New function.
(dwarf_tag_name, dwarf_attr_name, dwarf_form_name)
(dwarf_type_encoding_name): Use dwarf_unknown.
Adds a constructor to 'struct cu_partial_die_info' and disables the
default constructor, preventing partially initialised instances from
being created.
Update 'find_partial_die' to return a const struct.
Users of 'find_partial_die' are updated to take account of the above
two changes.
There should be no user visible changes after this commit.
gdb/ChangeLog:
* dwarf2read.c (struct cu_partial_die_info): Add constructor,
delete default constructor.
(find_partial_die): Update to return const struct.
(partial_die_parent_scope): Move variable declaration into scope
of its use and change its type to auto.
(guess_partial_die_structure_name): Likewise.
(partial_die_info::fixup): Likewise.
When running gdb using AddressSanitizer, and loading a cc1plus binary built
with profiledbootstrap and -flto, we run into a heap-use-after-free error:
...
$ LD_PRELOAD=/usr/lib64/libasan.so.3 ./gdb -batch cc1plus
==26855==ERROR: AddressSanitizer: heap-use-after-free on address \
0x62100ad8a8b0 at pc 0x7f13803cc9e3 bp 0x7ffe55b0d090 sp 0x7ffe55b0c840
READ of size 47 at 0x62100ad8a8b0 thread T0
#0 0x7f13803cc9e2 (/usr/lib64/libasan.so.3+0x3e9e2)
#1 0x5e7a0d in typename_concat gdb/dwarf2read.c:22661
#2 0x5c6437 in partial_die_full_name gdb/dwarf2read.c:8876
#3 0x5c6555 in add_partial_symbol gdb/dwarf2read.c:8893
#4 0x5c6ecf in add_partial_subprogram gdb/dwarf2read.c:9156
#5 0x5c5e90 in scan_partial_symbols gdb/dwarf2read.c:8668
#6 0x5c6c0a in add_partial_namespace gdb/dwarf2read.c:9081
#7 0x5c5f99 in scan_partial_symbols gdb/dwarf2read.c:8702
#8 0x5c48b6 in process_psymtab_comp_unit_reader gdb/dwarf2read.c:8056
#9 0x5c3c1f in init_cutu_and_read_dies gdb/dwarf2read.c:7689
#10 0x5c4c03 in process_psymtab_comp_unit gdb/dwarf2read.c:8140
#11 0x5c58a2 in dwarf2_build_psymtabs_hard gdb/dwarf2read.c:8500
#12 0x5c0d03 in dwarf2_build_psymtabs(objfile*) gdb/dwarf2read.c:6337
#13 0x612359 in read_psyms gdb/elfread.c:1311
#14 0x798a64 in require_partial_symbols(objfile*, int) gdb/psymtab.c:115
#15 0x867d7b in read_symbols gdb/symfile.c:821
#16 0x8683d9 in syms_from_objfile_1 gdb/symfile.c:1000
#17 0x8684a1 in syms_from_objfile gdb/symfile.c:1017
#18 0x868873 in symbol_file_add_with_addrs gdb/symfile.c:1124
#19 0x868b0a in symbol_file_add_from_bfd(bfd*, char const*, \
enum_flags<symfile_add_flag>, std::vector<other_sections, \
std::allocator<other_sections> >*, \
enum_flags<objfile_flag>, objfile*) gdb/symfile.c:1204
#20 0x868b64 in symbol_file_add(char const*, \
enum_flags<symfile_add_flag>, \
std::vector<other_sections, \
std::allocator<other_sections> >*, \
enum_flags<objfile_flag>) gdb/symfile.c:1217
#21 0x868c39 in symbol_file_add_main_1 gdb/symfile.c:1240
#22 0x868bd0 in symbol_file_add_main(char const*, \
enum_flags<symfile_add_flag>) gdb/symfile.c:1231
#23 0x71f1b2 in symbol_file_add_main_adapter gdb/main.c:395
#24 0x71f10e in catch_command_errors gdb/main.c:372
#25 0x71ff5f in captured_main_1 gdb/main.c:1043
#26 0x72045d in captured_main gdb/main.c:1163
#27 0x7204c8 in gdb_main(captured_main_args*) gdb/main.c:1188
#28 0x40fd7d in main gdb/gdb.c:32
#29 0x7f137e300f49 in __libc_start_main (/lib64/libc.so.6+0x20f49)
#30 0x40fc89 in _start (/data/gdb_versions/devel/build/gdb/gdb+0x40fc89)
0x62100ad8a8b0 is located 944 bytes inside of 4064-byte region \
[0x62100ad8a500,0x62100ad8b4e0)
freed by thread T0 here:
#0 0x7f13804523a0 in __interceptor_free (/usr/lib64/libasan.so.3+0xc43a0)
#1 0x435e44 in xfree<void> gdb/common/common-utils.h:60
#2 0xa82c25 in call_freefun libiberty/obstack.c:103
#3 0xa83098 in _obstack_free libiberty/obstack.c:280
#4 0x4367da in auto_obstack::~auto_obstack() gdb/gdb_obstack.h:101
#5 0x5ed72c in dwarf2_cu::~dwarf2_cu() gdb/dwarf2read.c:25341
#6 0x5fb5bb in std::default_delete<dwarf2_cu>::operator()(dwarf2_cu*) const \
/usr/include/c++/7/bits/unique_ptr.h:78
#7 0x5f7334 in std::unique_ptr<dwarf2_cu, \
std::default_delete<dwarf2_cu> >::~unique_ptr() \
/usr/include/c++/7/bits/unique_ptr.h:268
#8 0x5c3ce5 in init_cutu_and_read_dies gdb/dwarf2read.c:7624
#9 0x5c4c03 in process_psymtab_comp_unit gdb/dwarf2read.c:8140
#10 0x5c58a2 in dwarf2_build_psymtabs_hard gdb/dwarf2read.c:8500
#11 0x5c0d03 in dwarf2_build_psymtabs(objfile*) gdb/dwarf2read.c:6337
#12 0x612359 in read_psyms gdb/elfread.c:1311
#13 0x798a64 in require_partial_symbols(objfile*, int) gdb/psymtab.c:115
#14 0x867d7b in read_symbols gdb/symfile.c:821
#15 0x8683d9 in syms_from_objfile_1 gdb/symfile.c:1000
#16 0x8684a1 in syms_from_objfile gdb/symfile.c:1017
#17 0x868873 in symbol_file_add_with_addrs gdb/symfile.c:1124
#18 0x868b0a in symbol_file_add_from_bfd(bfd*, char const*, \
enum_flags<symfile_add_flag>, std::vector<other_sections, \
std::allocator<other_sections> >*, \
enum_flags<objfile_flag>, objfile*) gdb/symfile.c:1204
#19 0x868b64 in symbol_file_add(char const*, \
enum_flags<symfile_add_flag>, std::vector<other_sections, \
std::allocator<other_sections> >*, \
enum_flags<objfile_flag>) gdb/symfile.c:1217
#20 0x868c39 in symbol_file_add_main_1 gdb/symfile.c:1240
#21 0x868bd0 in symbol_file_add_main(char const*, \
enum_flags<symfile_add_flag>) gdb/symfile.c:1231
#22 0x71f1b2 in symbol_file_add_main_adapter gdb/main.c:395
#23 0x71f10e in catch_command_errors gdb/main.c:372
#24 0x71ff5f in captured_main_1 gdb/main.c:1043
#25 0x72045d in captured_main gdb/main.c:1163
#26 0x7204c8 in gdb_main(captured_main_args*) gdb/main.c:1188
#27 0x40fd7d in main gdb/gdb.c:32
#28 0x7f137e300f49 in __libc_start_main (/lib64/libc.so.6+0x20f49)
previously allocated by thread T0 here:
#0 0x7f13804526b8 in __interceptor_malloc (/usr/lib64/libasan.so.3+0xc46b8)
#1 0x5114b5 in xmalloc gdb/common/common-utils.c:44
#2 0xa82bd5 in call_chunkfun libiberty/obstack.c:94
#3 0xa82eda in _obstack_newchunk libiberty/obstack.c:206
#4 0x477310 in allocate_on_obstack::operator new(unsigned long, obstack*) \
gdb/gdb_obstack.h:117
#5 0x5dea8c in load_partial_dies gdb/dwarf2read.c:18571
#6 0x5c487f in process_psymtab_comp_unit_reader gdb/dwarf2read.c:8054
#7 0x5c3c1f in init_cutu_and_read_dies gdb/dwarf2read.c:7689
#8 0x5c4c03 in process_psymtab_comp_unit gdb/dwarf2read.c:8140
#9 0x5c58a2 in dwarf2_build_psymtabs_hard gdb/dwarf2read.c:8500
#10 0x5c0d03 in dwarf2_build_psymtabs(objfile*) gdb/dwarf2read.c:6337
#11 0x612359 in read_psyms gdb/elfread.c:1311
#12 0x798a64 in require_partial_symbols(objfile*, int) gdb/psymtab.c:115
#13 0x867d7b in read_symbols gdb/symfile.c:821
#14 0x8683d9 in syms_from_objfile_1 gdb/symfile.c:1000
#15 0x8684a1 in syms_from_objfile gdb/symfile.c:1017
#16 0x868873 in symbol_file_add_with_addrs gdb/symfile.c:1124
#17 0x868b0a in symbol_file_add_from_bfd(bfd*, char const*, \
enum_flags<symfile_add_flag>, \
std::vector<other_sections, \
std::allocator<other_sections> >*, \
enum_flags<objfile_flag>, objfile*) gdb/symfile.c:1204
#18 0x868b64 in symbol_file_add(char const*, enum_flags<symfile_add_flag>, \
std::vector<other_sections, \
std::allocator<other_sections> >*, \
enum_flags<objfile_flag>) gdb/symfile.c:1217
#19 0x868c39 in symbol_file_add_main_1 gdb/symfile.c:1240
#20 0x868bd0 in symbol_file_add_main(char const*, \
enum_flags<symfile_add_flag>) gdb/symfile.c:1231
#21 0x71f1b2 in symbol_file_add_main_adapter gdb/main.c:395
#22 0x71f10e in catch_command_errors gdb/main.c:372
#23 0x71ff5f in captured_main_1 gdb/main.c:1043
#24 0x72045d in captured_main gdb/main.c:1163
#25 0x7204c8 in gdb_main(captured_main_args*) gdb/main.c:1188
#26 0x40fd7d in main gdb/gdb.c:32
#27 0x7f137e300f49 in __libc_start_main (/lib64/libc.so.6+0x20f49)
...
This error happens as follows.
The function find_partial_die has a cu argument, but returns a pdi which may
or may not be from that cu:
...
/* Find a partial DIE at OFFSET, which may or may not be in CU,
except in the case of .debug_types DIEs which do not reference
outside their CU (they do however referencing other types via
DW_FORM_ref_sig8). */
static struct partial_die_info *
find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
...
So the pdi returned by find_partial_die here in partial_die_parent_scope may
be from another cu:
...
partial_die_parent_scope (struct partial_die_info *pdi,
struct dwarf2_cu *cu)
{
const char *grandparent_scope;
struct partial_die_info *parent, *real_pdi;
/* We need to look at our parent DIE; if we have a DW_AT_specification,
then this means the parent of the specification DIE. */
real_pdi = pdi;
while (real_pdi->has_specification)
real_pdi = find_partial_die (real_pdi->spec_offset,
real_pdi->spec_is_dwz, cu);
parent = real_pdi->die_parent;
...
in which case both real_pdi and parent will be not from cu, but from another
one, say cu2.
Subsequently, cu's comp_unit_obstack is used to set parent->scope:
...
parent->scope = typename_concat (&cu->comp_unit_obstack,
grandparent_scope,
parent->name, 0, cu);
...
So, we use cu->comp_unit_obstack to assign a value to the scope field of
a pdi belonging to cu2, and when cu is deleted, the scope field points to a
freed value.
Fix this by making find_partial_die return the cu corresponding to the
returned pdi, and handling this at the call sites.
Tested on x86_64-linux.
gdb/ChangeLog:
2019-05-17 Tom de Vries <tdevries@suse.de>
PR gdb/24094
* dwarf2read.c (struct cu_partial_die_info): New struct.
(find_partial_die): Return cu_partial_die_info.
(partial_die_parent_scope, guess_partial_die_structure_name)
(partial_die_info::fixup): Handle new return type of find_partial_die.
Hi,
Ref.: https://bugzilla.redhat.com/show_bug.cgi?id=1708192https://bugzilla.redhat.com/show_bug.cgi?id=1708786
During the Fedora RPM build process, gdb-add-index is invoked to
extract the DWARF index from the binary, and GDB will segfault because
dwarf2read.c:parse_definition_macro's 'body' variable is NULL.
The underlying problem is that Fedora's rpm-build's "debugedit"
program will silently corrupt .debug_macro strings when a binary is
compiled with -g3. This is being taken care of by Mark Wielaard,
here:
https://bugzilla.redhat.com/show_bug.cgi?id=1708786
However, I still feel it's important to make GDB more resilient
against invalid DWARF input, so I'm proposing this rather simple patch
to catch the situation when "body == NULL" (i.e., it's probably been
corrupted) and issue a complaint. This is not a real fix to the
problem, of course, but at least GDB is able to finish without
segfaulting.
OK for master?
gdb/ChangeLog:
2019-05-15 Sergio Durigan Junior <sergiodj@redhat.com>
Ref.: https://bugzilla.redhat.com/show_bug.cgi?id=1708192
* dwarf2read.c (dwarf_decode_macro_bytes): Check whether 'body' is
NULL, and complain if that's the case.
This changes dwarf2_per_objfile to use the type-safe registry API.
This also changes dwarf2_per_objfile not to be allocated on an
obstack. It seemed clearer to me to simply allocate it on the heap;
and I didn't see a drawback from doing so.
gdb/ChangeLog
2019-05-08 Tom Tromey <tom@tromey.com>
* dwarf2read.h (struct dwarf2_per_objfile): Don't inherit from
allocate_on_obstack.
* dwarf2read.c (dwarf2_objfile_data_key): Change type.
(get_dwarf2_per_objfile): Update.
(set_dwarf2_per_objfile): Remove.
(dwarf2_has_info, dwarf2_get_section_info): Update.
(dwarf2_free_objfile): Remove.
(_initialize_dwarf2_read): Update.
Some versions of gcc have a bug that causes
for (struct mumble : something)
... to give a compiler error. We routinely work around this bug in
gdb, but apparently had not done so in a while. This patch fixes the
remaining known cases of this problem.
gdb/ChangeLog
2019-05-03 Sandra Loosemore <sandra@codesourcery.com>
Tom Tromey <tom@tromey.com>
* dictionary.c (collate_pending_symbols_by_language): Remove
"struct" from foreach.
* symtab.c (lookup_global_symbol_from_objfile)
(lookup_symbol_in_objfile_from_linkage_name): Remove "struct" from
foreach.
* ser-tcp.c (net_open): Remove "struct" from foreach.
* objfiles.c (objfile_relocate, objfile_rebase)
(objfile_has_symbols): Remove "struct" from foreach.
* minsyms.c (lookup_minimal_symbol_by_pc_section): Remove "struct"
from foreach.
* dwarf2read.c (handle_struct_member_die): Remove "struct" from
foreach.
* darwin-nat.c (thread_info_from_private_thread_info): Remove
"struct" from foreach.
* ada-lang.c (create_excep_cond_exprs)
(ada_exception_catchpoint_cond_string): Remove "struct" from
foreach.
Dwarf5 defines DW_FORM_strx1 and others, which are similar
to DW_FORM_strx but uses 1-4 bytes unsigned integers. This is
a small step towards supporting dwarf5 in gdb.
PR c++/24470 concerns a crash in dwarf2read.c that occurs with a
particular test case.
The issue turns out to be that process_structure_scope will pass NULL
to symbol_symtab. This happens because new_symbol decided not to
create a symbol for the particular DIE.
This patch fixes the problem by finding another reasonably-appropriate
symtab to use instead; issuing a complaint if one cannot be found for
some reason.
As mentioned in the bug, I think there are other bugs here. For
example, when using "ptype" on the "l" object in the test case, I
think I would expect to see the template parameter. I didn't research
this too closely, since it seemed more important to fix the crash.
Tested on x86-64 Fedora 29.
I'd like to check this in to the 8.3 branch as well.
2019-04-30 Tom Tromey <tromey@adacore.com>
PR c++/24470:
* dwarf2read.c (process_structure_scope): Handle case where type
has template parameters but no symbol was created.
gdb/testsuite/ChangeLog
2019-04-30 Tom Tromey <tromey@adacore.com>
PR c++/24470:
* gdb.cp/temargs.cc: Add test code from PR.
Currently when using $_creal and $_cimag to access the components of a
complex number the types of these components will have C type names
'float', 'double', etc. This is because the components of a complex
number are not given type names in DWARF, so GDB has to pick some
suitable names, and currently we always use the C names.
This commit changes the type names used based on the language, so for
Fortran we will now use the Fortran float types, and so will get the
Fortran float type names 'real', 'real*8', etc.
gdb/ChangeLog:
* dwarf2read.c (dwarf2_init_complex_target_type): Use different
types for Fortran.
gdb/testsuite/ChangeLog:
* gdb.fortran/complex.exp: Expand.
* gdb.fortran/complex.f: Renamed to...
* gdb.fortran/complex.f90: ...this, and extended to add more
complex values.
I noticed that one of the overloads of line_header::file_name_at is
unused. This patch removes it.
gdb/ChangeLog
2019-04-23 Tom Tromey <tromey@adacore.com>
* dwarf2read.c (line_header::file_name_at): Remove unused
overload.
DW_OP_addrx is the new name of DW_OP_GNU_addr_index, and DW_FORM_addrx
is the name of DW_FORM_addr_index in the Dwarf 5 standard. This is a small
step towards supporting Dwarf 5 in gdb.
Note: I could not find any tests specifically for *_GNU_addr_index, and
I did not add any new tests, please advise.