481 Commits

Author SHA1 Message Date
6ad036d703 Fix handling of DW_AT_data_bit_offset
A newer version of GCC will now emit member locations using just
DW_AT_data_bit_offset, like:

 <3><14fe>: Abbrev Number: 1 (DW_TAG_member)
    <14ff>   DW_AT_name        : (indirect string, offset: 0x215e): nb_bytes
    <1503>   DW_AT_decl_file   : 1
    <1503>   DW_AT_decl_line   : 10
    <1504>   DW_AT_decl_column : 7
    <1505>   DW_AT_type        : <0x150b>
    <1509>   DW_AT_bit_size    : 31
    <150a>   DW_AT_data_bit_offset: 64

whereas earlier versions would emit something like:

 <3><164f>: Abbrev Number: 7 (DW_TAG_member)
    <1650>   DW_AT_name        : (indirect string, offset: 0x218d): nb_bytes
    <1654>   DW_AT_decl_file   : 1
    <1655>   DW_AT_decl_line   : 10
    <1656>   DW_AT_decl_column : 7
    <1657>   DW_AT_type        : <0x165f>
    <165b>   DW_AT_byte_size   : 4
    <165c>   DW_AT_bit_size    : 31
    <165d>   DW_AT_bit_offset  : 1
    <165e>   DW_AT_data_member_location: 8

That is, DW_AT_data_member_location is not emitted any more.  This is
a change due to the switch to DWARF 5 by default.

This change pointed out an existing bug in gdb, namely that the
attr_to_dynamic_prop depends on the presence of
DW_AT_data_member_location.  This patch moves the handling of
DW_AT_data_bit_offset into handle_data_member_location, and updates
attr_to_dynamic_prop to handle this new case.

A new test case is included.  This test fails with GCC 11, but passes
with an earlier version of GCC.
2021-09-24 09:29:09 -06:00
2c71f639a0 [gdb/ada] Handle artificial local symbols
With current master and gcc 7.5.0/8.5.0, we have this timeout:
...
(gdb) print s^M
Multiple matches for s^M
[0] cancel^M
[1] s at src/gdb/testsuite/gdb.ada/interface/foo.adb:20^M
[2] s at src/gdb/testsuite/gdb.ada/interface/foo.adb:?^M
> FAIL: gdb.ada/interface.exp: print s (timeout)
...

[ The FAIL doesn't reproduce with gcc 9.3.1.  This difference in
behaviour bisects to gcc commit d70ba0c10de.

The FAIL with earlier gcc bisects to gdb commit ba8694b650b. ]

The FAIL is caused by gcc generating this debug info describing a named
artificial variable:
...
 <2><1204>: Abbrev Number: 31 (DW_TAG_variable)
    <1205>   DW_AT_name        : s.14
    <1209>   DW_AT_type        : <0x1213>
    <120d>   DW_AT_artificial  : 1
    <120d>   DW_AT_location    : 5 byte block: 91 e0 7d 23 18   \
      (DW_OP_fbreg: -288; DW_OP_plus_uconst: 24)
...

An easy way to fix this would be to simply not put named artificial variables
into the symbol table.  However, that causes regressions for Ada.  It relies
on being able to get the value from such variables, using a named reference.

Fix this instead by marking the symbol as artificial, and:
- ignoring such symbols in ada_resolve_variable, which fixes the FAIL
- ignoring such ada symbols in do_print_variable_and_value, which prevents
  them from showing up in "info locals"

Note that a fix for the latter was submitted here (
https://sourceware.org/pipermail/gdb-patches/2008-January/054994.html ), and
this patch borrows from it.

Tested on x86_64-linux.

Co-Authored-By: Joel Brobecker  <brobecker@adacore.com>

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28180
2021-09-18 09:25:49 +02:00
211aafd18d [gdb/symtab] Fix function range handling in psymtabs
Consider the test-case from this patch.

We run into:
...
(gdb) PASS: gdb.dwarf2/dw2-ranges-psym-warning.exp: continue
bt^M
warning: (Internal error: pc 0x4004b6 in read in psymtab, but not in symtab.)^M
^M
warning: (Internal error: pc 0x4004b6 in read in psymtab, but not in symtab.)^M
^M
warning: (Internal error: pc 0x4004b6 in read in psymtab, but not in symtab.)^M
^M
warning: (Internal error: pc 0x4004b6 in read in psymtab, but not in symtab.)^M
^M
warning: (Internal error: pc 0x4004b6 in read in psymtab, but not in symtab.)^M
^M
warning: (Internal error: pc 0x4004b6 in read in psymtab, but not in symtab.)^M
^M
  read in psymtab, but not in symtab.)^M
^M
)^M
(gdb) FAIL: gdb.dwarf2/dw2-ranges-psym-warning.exp: bt
...

This happens as follows.

The function foo:
...
 <1><31>: Abbrev Number: 4 (DW_TAG_subprogram)
    <33>   DW_AT_name        : foo
    <37>   DW_AT_ranges      : 0x0
...
has these ranges:
...
    00000000 00000000004004c1 00000000004004d2
    00000000 00000000004004ae 00000000004004af
    00000000 <End of list>
...
which have a hole at at [0x4004af,0x4004c1).

However, the address map of the partial symtabs incorrectly maps addresses
in the hole (such as 0x4004b6 in the backtrace) to the foo CU.

The address map of the full symbol table of the foo CU however does not
contain the addresses in the hole, which is what the warning / internal error
complains about.

Fix this by making sure that ranges of functions are read correctly.

The patch adds a bit to struct partial_die_info, in this hole (shown for
x86_64-linux):
...
/*   11: 7   |     4 */    unsigned int canonical_name : 1;
/* XXX  4-byte hole  */
/*   16      |     8 */    const char *raw_name;
...
So there's no increase in size for 64-bit, but AFAIU there will be an increase
for 32-bit.

Tested on x86_64-linux.

gdb/ChangeLog:

2021-08-10  Tom de Vries  <tdevries@suse.de>

	PR symtab/28200
	* dwarf2/read.c (struct partial_die_info): Add has_range_info and
	range_offset field.
	(add_partial_subprogram): Handle pdi->has_range_info.
	(partial_die_info::read): Set pdi->has_range_info.

gdb/testsuite/ChangeLog:

2021-08-10  Tom de Vries  <tdevries@suse.de>

	PR symtab/28200
	* gdb.dwarf2/dw2-ranges-psym-warning-main.c: New test.
	* gdb.dwarf2/dw2-ranges-psym-warning.c: New test.
	* gdb.dwarf2/dw2-ranges-psym-warning.exp: New file.
2021-09-14 14:41:27 +02:00
2762d28853 [gdb/symtab] Fix CU list in .debug_names for dummy CUs
With current trunk and target board cc-with-debug-names we have:
...
(gdb) file dw2-ranges-psym^M
Reading symbols from dw2-ranges-psym...^M
warning: Section .debug_names in dw2-ranges-psym has abbreviation_table of \
  size 1 vs. written as 28, ignoring .debug_names.^M
(gdb) set complaints 0^M
(gdb) FAIL: gdb.dwarf2/dw2-ranges-psym.exp: No complaints
...

The executable has 8 compilation units:
...
$ readelf -wi dw2-ranges-psym | grep @
  Compilation Unit @ offset 0x0:
  Compilation Unit @ offset 0x2e:
  Compilation Unit @ offset 0xa5:
  Compilation Unit @ offset 0xc7:
  Compilation Unit @ offset 0xd2:
  Compilation Unit @ offset 0x145:
  Compilation Unit @ offset 0x150:
  Compilation Unit @ offset 0x308:
...
of which the ones at 0xc7 and 0x145 are dummy CUs (that is, they do not
contain a single DIE), which were added by recent commit 5ef670d81fd
"[gdb/testsuite] Add dummy start and end CUs in dwarf assembly".

The .debug_names section contains this CU table:
...
[  0] 0x0
[  1] 0x2e
[  2] 0xa5
[  3] 0xd2
[  4] 0x150
[  5] 0x308
[  6] 0x1
[  7] 0x0
...
The last two entries are incorrect, and the entries for the dummy CUs are
missing.

The last two entries are incorrect because here in write_debug_names we write
the dimension of the CU list as 8:
...
  /* comp_unit_count - The number of CUs in the CU list.  */
  header.append_uint (4, dwarf5_byte_order,
                     per_objfile->per_bfd->all_comp_units.size ()
                     - per_objfile->per_bfd->tu_stats.nr_tus);
...
while the actual dimension of the CU list is 6.

The discrepancy is caused by this code which skips the dummy CUs:
...
  for (int i = 0; i < per_objfile->per_bfd->all_comp_units.size (); ++i)
    {
      ...
      /* CU of a shared file from 'dwz -m' may be unused by this main
        file.  It may be referenced from a local scope but in such
        case it does not need to be present in .debug_names.  */
      if (psymtab == NULL)
       continue;
...
because they have a null partial symtab.

We can fix this by writing the actual dimension of the CU list, but that still
leaves the dummy CUs out of the CU list.  The purpose of having these is to
delimit the end of preceding CUs.

So, fix this by:
- removing the code that skips the dummy CUs (note that the same change
  was done for .gdb_index in commit efba5c2319d '[gdb/symtab] Handle PU
  without import in "save gdb-index"'.
- verifying that all units are represented in the CU/TU lists
- using the actual CU list size when writing the dimension of the CU list
  (and likewise for the TU list).

Tested on x86_64-linux with native and target board cc-with-debug-names.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28261
2021-09-14 12:57:58 +02:00
34daac4b16 [gdb/symtab] Don't write .gdb_index symbol table with empty entries
When comparing the sizes of the index files generated for shlib
outputs/gdb.dwarf2/dw2-zero-range/shr1.sl, I noticed a large difference
between .debug_names:
...
$ gdb -q -batch $shlib -ex "save gdb-index -dwarf-5 ."
$ du -b -h shr1.sl.debug_names shr1.sl.debug_str
61      shr1.sl.debug_names
0       shr1.sl.debug_str
...
and .gdb_index:
...
$ gdb -q -batch $shlib -ex "save gdb-index ."
$ du -b -h shr1.sl.gdb-index
8.2K    shr1.sl.gdb-index
...

The problem is that the .gdb_index contains a non-empty symbol table with only
empty entries.

Fix this by making the symbol table empty, such that we have instead:
...
$ du -b -h shr1.sl.gdb-index
184     shr1.sl.gdb-index
...

Tested on x86_64-linux.
2021-08-27 17:14:49 +02:00
d58e54bd27 Fix two regressions caused by CU / TU merging
PR symtab/28160 and PR symtab/27893 concern GDB crashes in the test
suite when using the "fission" target board.  They are both caused by
the patches that merge the list of CUs with the list of TUs (and to a
lesser degree by the patches to share DWARF data across objfiles), and
the underlying issue is the same: it turns out that reading a DWO can
cause new type units to be created.  This means that the list of
dwarf2_per_cu_data objects depends on precisely which CUs have been
expanded.  However, because the type units can be created while
expanding a CU means that the vector of CUs can expand while it is
being iterated over -- a classic mistake.  Also, because a TU can be
added later, it means the resize_symtabs approach is incorrect.

This patch fixes resize_symtabs by removing it, and having set_symtab
resize the vector on demand.  It fixes the iteration problem by
introducing a safe (index-based) iterator and changing the relevant
spots to use it.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28160
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=27893
2021-08-24 07:51:46 -06:00
892a1e5303 Fix register regression in DWARF evaluator
On an internal test case, using an arm-elf target, commit ba5bc3e5a92
("Make DWARF evaluator return a single struct value") causes a
regression.  (It doesn't happen for any of the other cross targets
that I test when importing upstream gdb.)

I don't know if there's an upstream gdb test case showing the same
problem... I can only really run native tests with dejagnu AFAIK.

The failure manifests like this:

    Breakpoint 1, file_1.export_1 (param_1=<error reading variable: Unable to access DWARF register number 64>, str=...) at [...]/file_1.adb:5

Whereas when it works it looks like:

    Breakpoint 1, file_1.export_1 (param_1=99.0, str=...) at [...]/file_1.adb:5

The difference is that the new code uses the passed-in gdbarch,
whereas the old code used the frame's gdbarch, when handling
DWARF_VALUE_REGISTER.

This patch restores the use of the frame's arch.
2021-08-16 09:38:15 -06:00
1dd34eff4b Fix Ada regression due to DWARF expression series
Commit 0579205aec4 ("Simplify dwarf_expr_context class interface")
caused a regression in the internal AdaCore test suite.  I didn't try
to reproduce this with the GDB test suite, but the test is identical
to gdb.dwarf2/dynarr-ptr.exp.

The problem is that this change:

 	case DW_OP_push_object_address:
 	  /* Return the address of the object we are currently observing.  */
-	  if (this->data_view.data () == nullptr
-	      && this->obj_address == 0)
+	  if (this->m_addr_info == nullptr)

... slightly changes the logic here.  In particular, it's possible for
the caller to pass in a non-NULL m_addr_info, but one that looks like:

    (top) p *this.m_addr_info
    $15 = {
      type = 0x29b7a70,
      valaddr = {
	m_array = 0x0,
	m_size = 0
      },
      addr = 0,
      next = 0x0
    }

In this case, an additional check is needed.  With the current code,
what happens instead is that the computation computes an incorrect
address -- but one that does not fail in read_memory, due to the
precise memory map of the embedded target in question.

This patch restores the old logic.
2021-08-16 09:38:14 -06:00
2c1db96b66 Ignore .debug_types when reading .debug_aranges
I noticed that the fission-reread.exp test case can cause a complaint
when run with --target_board=cc-with-debug-names:

warning: Section .debug_aranges in [...]/fission-reread has duplicate debug_info_offset 0x0, ignoring .debug_aranges.

The bug here is that this executable has both .debug_info and
.debug_types, and both have a CU at offset 0x0.  This triggers the
duplicate warning.

Because .debug_types doesn't provide any address ranges, these CUs can
be ignored.  That is, this bug turns out to be another regression from
the info/types merger patch.

This patch fixes the problem by having this loop igore type units.
fission-reread.exp is updated to test for the bug.
2021-08-10 15:33:34 -06:00
a8624232b1 Include objfiles.h in a few .c files
I found a few .c files that rely on objfiles.h, but that only include
it indirectly, via dwarf2/read.h -> psympriv.h.  If that include is
removed (something my new DWARF indexer series does), then the build
will break.

It seemed harmless and correct to add these includes now, making the
eventual series a little smaller.
2021-08-08 08:53:17 -06:00
cc6b3d766d [gdb/symtab] Recognize .gdb_index symbol table with empty entries as empty
When reading a .gdb_index that contains a non-empty symbol table with only
empty entries, gdb doesn't recognize it as empty.

Fix this by recognizing that the constant pool is empty, and then setting the
symbol table to empty.

Tested on x86_64-linux.

gdb/ChangeLog:

2021-08-01  Tom de Vries  <tdevries@suse.de>

	PR symtab/28159
	* dwarf2/read.c (read_gdb_index_from_buffer): Handle symbol table
	filled with empty entries.

gdb/testsuite/ChangeLog:

2021-08-01  Tom de Vries  <tdevries@suse.de>

	PR symtab/28159
	* gdb.dwarf2/dw2-zero-range.exp: Remove kfail.
2021-08-06 21:52:41 +02:00
b9f3fbc9f3 [gdb/symtab] Fix zero address complaint for shlib
In PR28004 the following warning / Internal error is reported:
...
$ gdb -q -batch \
    -iex "set sysroot $(pwd -P)/repro" \
    ./repro/gdb \
    ./repro/core \
    -ex bt
  ...
 Program terminated with signal SIGABRT, Aborted.
 #0  0x00007ff8fe8e5d22 in raise () from repro/usr/lib/libc.so.6
 [Current thread is 1 (LWP 1762498)]
 #1  0x00007ff8fe8cf862 in abort () from repro/usr/lib/libc.so.6
 warning: (Internal error: pc 0x7ff8feb2c21d in read in psymtab, \
           but not in symtab.)
 warning: (Internal error: pc 0x7ff8feb2c218 in read in psymtab, \
           but not in symtab.)
  ...
 #2  0x00007ff8feb2c21e in __gnu_debug::_Error_formatter::_M_error() const \
   [clone .cold] (warning: (Internal error: pc 0x7ff8feb2c21d in read in \
   psymtab, but not in symtab.)

) from repro/usr/lib/libstdc++.so.6
...

The warning is about the following:
- in find_pc_sect_compunit_symtab we try to find the address
  (0x7ff8feb2c218 / 0x7ff8feb2c21d) in the symtabs.
- that fails, so we try again in the partial symtabs.
- we find a matching partial symtab
- however, the partial symtab has a full symtab, so
  we should have found a matching symtab in the first step.

The addresses are:
...
(gdb) info sym 0x7ff8feb2c218
__gnu_debug::_Error_formatter::_M_error() const [clone .cold] in \
  section .text of repro/usr/lib/libstdc++.so.6
(gdb) info sym 0x7ff8feb2c21d
__gnu_debug::_Error_formatter::_M_error() const [clone .cold] + 5 in \
  section .text of repro/usr/lib/libstdc++.so.6
...
which correspond to unrelocated addresses 0x9c218 and 0x9c21d:
...
$ nm -C  repro/usr/lib/libstdc++.so.6.0.29 | grep 000000000009c218
000000000009c218 t __gnu_debug::_Error_formatter::_M_error() const \
  [clone .cold]
...
which belong to function __gnu_debug::_Error_formatter::_M_error() in
/build/gcc/src/gcc/libstdc++-v3/src/c++11/debug.cc.

The partial symtab that is found for the addresses is instead the one for
/build/gcc/src/gcc/libstdc++-v3/src/c++98/bitmap_allocator.cc, which is
incorrect.

This happens as follows.

The bitmap_allocator.cc CU has DW_AT_ranges at .debug_rnglist offset 0x4b50:
...
    00004b50 0000000000000000 0000000000000056
    00004b5a 00000000000a4790 00000000000a479c
    00004b64 00000000000a47a0 00000000000a47ac
...

When reading the first range 0x0..0x56, it doesn't trigger the "start address
of zero" complaint here:
...
      /* A not-uncommon case of bad debug info.
         Don't pollute the addrmap with bad data.  */
      if (range_beginning + baseaddr == 0
          && !per_objfile->per_bfd->has_section_at_zero)
        {
          complaint (_(".debug_rnglists entry has start address of zero"
                       " [in module %s]"), objfile_name (objfile));
          continue;
        }
...
because baseaddr != 0, which seems incorrect given that when loading the
shared library individually in gdb (and consequently baseaddr == 0), we do see
the complaint.

Consequently, we run into this case in dwarf2_get_pc_bounds:
...
  if (low == 0 && !per_objfile->per_bfd->has_section_at_zero)
    return PC_BOUNDS_INVALID;
...
which then results in this code in process_psymtab_comp_unit_reader being
called with cu_bounds_kind == PC_BOUNDS_INVALID, which sets the set_addrmap
argument to 1:
...
      scan_partial_symbols (first_die, &lowpc, &highpc,
                            cu_bounds_kind <= PC_BOUNDS_INVALID, cu);
...
and consequently, the CU addrmap gets build using address info from the
functions.

During that process, addrmap_set_empty is called with a range that includes
0x9c218 and 0x9c21d:
...
(gdb) p /x start
$7 = 0x9989c
(gdb) p /x end_inclusive
$8 = 0xb200d
...
but it's called for a function at DIE 0x54153 with DW_AT_ranges at 0x40ae:
...
    000040ae 00000000000b1ee0 00000000000b200e
    000040b9 000000000009989c 00000000000998c4
    000040c3 <End of list>
...
and neither range includes 0x9c218 and 0x9c21d.

This is caused by this code in partial_die_info::read:
...
            if (dwarf2_ranges_read (ranges_offset, &lowpc, &highpc, cu,
                                    nullptr, tag))
             has_pc_info = 1;
...
which pretends that the function is located at addresses 0x9989c..0xb200d,
which is indeed not the case.

This patch fixes the first problem encountered: fix the "start address of
zero" complaint warning by removing the baseaddr part from the condition.
Same for dwarf2_ranges_process.

The effect is that:
- the complaint is triggered, and
- the warning / Internal error is no longer triggered.

This does not fix the observed problem in partial_die_info::read, which is
filed as PR28200.

Tested on x86_64-linux.

Co-Authored-By: Simon Marchi <simon.marchi@polymtl.ca>

gdb/ChangeLog:

2021-07-29  Simon Marchi  <simon.marchi@polymtl.ca>
	    Tom de Vries  <tdevries@suse.de>

	PR symtab/28004
	* gdb/dwarf2/read.c (dwarf2_rnglists_process, dwarf2_ranges_process):
	Fix zero address complaint.
	* gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c: New test.
	* gdb/testsuite/gdb.dwarf2/dw2-zero-range.c: New test.
	* gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp: New file.
2021-08-06 16:44:17 +02:00
70454ee70a Add as_lval argument to expression evaluator
There are cases where the result of the expression evaluation is
expected to be in a form of a value and not location description.

One place that has this requirement is dwarf_entry_parameter_to_value
function, but more are expected in the future. Until now, this
requirement was fulfilled by extending the evaluated expression with
a DW_OP_stack_value operation at the end.

New implementation, introduces a new evaluation argument instead.

	* dwarf2/expr.c (dwarf_expr_context::fetch_result): Add as_lval
	argument.
	(dwarf_expr_context::eval_exp): Add as_lval argument.
	* dwarf2/expr.h (struct dwarf_expr_context): Add as_lval
	argument to fetch_result and eval_exp methods.
	* dwarf2/frame.c (execute_stack_op): Add as_lval argument.
	* dwarf2/loc.c (dwarf_entry_parameter_to_value): Remove
	DWARF expression extension.
	(dwarf2_evaluate_loc_desc_full): Add as_lval argument support.
	(dwarf2_evaluate_loc_desc): Add as_lval argument support.
	(dwarf2_locexpr_baton_eval): Add as_lval argument support.
2021-08-05 16:41:05 +01:00
0579205aec Simplify dwarf_expr_context class interface
Idea of this patch is to get a clean and simple public interface for
the dwarf_expr_context class, looking like:

- constructor,
- destructor,
- push_address method and
- evaluate method.

Where constructor should only ever require a target architecture
information. This information is held in per object file
(dwarf2_per_objfile) structure, so it makes sense to keep that
structure as a constructor argument. It also makes sense to get the
address size from that structure, but unfortunately that interface
doesn't exist at the moment, so the dwarf_expr_context class user
needs to provide that information.

The push_address method is used to push a CORE_ADDR as a value on
top of the DWARF stack before the evaluation. This method can be
later changed to push any struct value object on the stack.

The evaluate method is the method that evaluates a DWARF expression
and provides the evaluation result, in a form of a single struct
value object that describes a location. To do this, the method requires
a context of the evaluation, as well as expected result type
information. If the type information is not provided, the DWARF generic
type will be used instead.

To avoid storing the gdbarch information in the evaluator object, that
information is now always acquired from the per_objfile object.

All data members are now private and only visible to the evaluator
class, so a m_ prefix was added to all of their names to reflect that.
To make this distinction clear, they are also accessed through objects
this pointer, wherever that was not the case before.

gdb/ChangeLog:

	* dwarf2/expr.c (dwarf_expr_context::dwarf_expr_context): Add
	address size argument.
	(dwarf_expr_context::read_mem): Change to use property_addr_info
	structure.
	(dwarf_expr_context::evaluate): New function.
	(dwarf_expr_context::execute_stack_op): Change to use
	property_addr_info structure.
	* dwarf2/expr.h (struct dwarf_expr_context): New evaluate
	declaration. Change eval and fetch_result method to private.
        (dwarf_expr_context::gdbarch): Remove member.
        (dwarf_expr_context::stack): Make private and add m_ prefix.
        (dwarf_expr_context::addr_size): Make private and add
        m_ prefix.
        (dwarf_expr_context::recursion_depth): Make private and add
        m_ prefix.
        (dwarf_expr_context::max_recursion_depth): Make private and
        add m_ prefix.
        (dwarf_expr_context::len): Make private and add m_ prefix.
        (dwarf_expr_context::data): Make private and add m_ prefix.
        (dwarf_expr_context::initialized): Make private and add
        m_ prefix.
        (dwarf_expr_context::pieces): Make private and add m_ prefix.
        (dwarf_expr_context::per_objfile): Make private and add
        m_ prefix.
        (dwarf_expr_context::frame): Make private and add m_ prefix.
        (dwarf_expr_context::per_cu): Make private and add m_ prefix.
        (dwarf_expr_context::addr_info): Make private and add
        m_ prefix.
	* dwarf2/frame.c (execute_stack_op): Change to call evaluate
	method.
	* dwarf2/loc.c (dwarf2_evaluate_loc_desc_full): Change to call
	evaluate method.
	(dwarf2_locexpr_baton_eval): Change to call evaluate method.
2021-08-05 16:40:56 +01:00
ba5bc3e5a9 Make DWARF evaluator return a single struct value
The patch is addressing the issue of class users writing and reading
the internal data of the dwarf_expr_context class.

At this point, all conditions are met for the DWARF evaluator to return
an evaluation result in a form of a single struct value object.

gdb/ChangeLog:

	* dwarf2/expr.c (pieced_value_funcs): Chenge to static
	function.
	(allocate_piece_closure): Change to static function.
	(dwarf_expr_context::fetch_result): New function.
	* dwarf2/expr.h (struct piece_closure): Remove declaration.
	(struct dwarf_expr_context): fetch_result new declaration.
	fetch, fetch_address and fetch_in_stack_memory members move
	to private.
	(allocate_piece_closure): Remove.
	* dwarf2/frame.c (execute_stack_op): Change to use
	fetch_result.
	* dwarf2/loc.c (dwarf2_evaluate_loc_desc_full): Change to use
	fetch_result.
	(dwarf2_locexpr_baton_eval): Change to use fetch_result.
        * dwarf2/loc.h (invalid_synthetic_pointer): Expose function.
2021-08-05 16:40:47 +01:00
f4091d2644 Move piece_closure and its support to expr.c
Following 5 patches series is trying to clean up the interface of the
DWARF expression evaluator class (dwarf_expr_context).

After merging all expression evaluators into one class, the next
logical step is to make a clean user interface for that class. To do
that, we first need to address the issue of class users writing and
reading the internal data of the class directly.

Fixing the case of writing is simple, it makes sense for an evaluator
instance to be per architecture basis. Currently, the best separation
seems to be per object file, so having that data (dwarf2_per_objfile)
as a constructor argument makes sense. It also makes sense to get the
address size from that object file, but unfortunately that interface
does not exist at the moment.

Luckily, address size information is already available to the users
through other means. As a result, the address size also needs to be a
class constructor argument, at least until a better interface for
acquiring that information from an object file is implemented.

The rest of the user written data comes down to a context of an
evaluated expression (compilation unit context, frame context and
passed in buffer context) and a source type information that a result
of evaluating expression is representing. So, it makes sense for all of
these to be arguments of an evaluation method.

To address the problem of reading the dwarf_expr_context class
internal data, we first need to understand why it is implemented that
way?

This is actualy a question of which existing class can be used to
represent both values and a location descriptions and why it is not
used currently?

The answer is in a struct value class/structure, but the problem is
that before the evaluators were merged, only one evaluator had an
infrastructure to resolve composite and implicit pointer location
descriptions.

After the merge, we are now able to use the struct value to represent
any result of the expression evaluation. It also makes sense to move
all infrastructure for those location descriptions to the expr.c file
considering that that is the only place using that infrastructure.

What we are left with in the end is a clean public interface of the
dwarf_expr_context class containing:

- constructor,
- destructor,
- push_address method and
- eval_exp method.

The idea with this particular patch is to move piece_closure structure
and the interface that handles it (lval_funcs) to expr.c file.

While implicit pointer location descriptions are still not useful in
the CFI context (of the AMD's DWARF standard extensions), the composite
location descriptions are certainly necessary to describe a results of
specific compiler optimizations.

Considering that a piece_closure structure is used to represent both,
there was no benefit in splitting them.

gdb/ChangeLog:

	* dwarf2/expr.c (struct piece_closure): Add from loc.c.
	(allocate_piece_closure): Add from loc.c.
	(bits_to_bytes): Add from loc.c.
	(rw_pieced_value): Add from loc.c.
	(read_pieced_value): Add from loc.c.
	(write_pieced_value): Add from loc.c.
	(check_pieced_synthetic_pointer): Add from loc.c.
	(indirect_pieced_value): Add from loc.c.
	(coerce_pieced_ref): Add from loc.c.
	(copy_pieced_value_closure): Add from loc.c.
	(free_pieced_value_closure): Add from loc.c.
	(sect_variable_value): Add from loc.c.
	* dwarf2/loc.c (sect_variable_value): Move to expr.c.
	(struct piece_closure): Move to expr.c.
	(allocate_piece_closure): Move to expr.c.
	(bits_to_bytes): Move to expr.c.
	(rw_pieced_value): Move to expr.c.
	(read_pieced_value): Move to expr.c.
	(write_pieced_value): Move to expr.c.
	(check_pieced_synthetic_pointer): Move to expr.c.
	(indirect_pieced_value): Move to expr.c.
	(coerce_pieced_ref): Move to expr.c.
	(copy_pieced_value_closure): Move to expr.c.
	(free_pieced_value_closure): Move to expr.c.
2021-08-05 16:40:30 +01:00
f9e4ed8baa Merge evaluate_for_locexpr_baton evaluator
The evaluate_for_locexpr_baton is the last derived class from the
dwarf_expr_context class. It's purpose is to support the passed in
buffer functionality.

Although, it is not really necessary to merge this class with it's
base class, doing that simplifies new expression evaluator design.

Considering that this functionality is going around the DWARF standard,
it is also reasonable to expect that with a new evaluator design and
extending the push object address functionality to accept any location
description, there will be no need to support passed in buffers.

Alternatively, it would also makes sense to abstract the interaction
between the evaluator and a given resource in the near future. The
passed in buffer would then be a specialization of that abstraction.

gdb/ChangeLog:

	* dwarf2/expr.c (dwarf_expr_context::read_mem): Merge with
	evaluate_for_locexpr_baton implementation.
	* dwarf2/loc.c (class evaluate_for_locexpr_baton): Remove
	class.
	(evaluate_for_locexpr_baton::read_mem): Move to
	dwarf_expr_context.
	(dwarf2_locexpr_baton_eval): Instantiate dwarf_expr_context
	instead of evaluate_for_locexpr_baton class.
2021-08-05 16:40:26 +01:00
14a62404c9 Remove empty frame and full evaluators
There are no virtual methods that require different specialization in
dwarf_expr_context class. This means that derived classes
dwarf_expr_executor and dwarf_evaluate_loc_desc are not needed any
more.

As a result of this, the  evaluate_for_locexpr_baton class base class
is now the dwarf_expr_context class.

There might be a need for a better class hierarchy when we know more
about the direction of the future DWARF versions and gdb extensions,
but that is out of the scope of this patch series.

gdb/ChangeLog:

	* dwarf2/frame.c (class dwarf_expr_executor): Remove class.
	(execute_stack_op): Instantiate dwarf_expr_context instead of
	dwarf_evaluate_loc_desc class.
	* dwarf2/loc.c (class dwarf_evaluate_loc_desc): Remove class.
	(dwarf2_evaluate_loc_desc_full): Instantiate dwarf_expr_context
	instead of dwarf_evaluate_loc_desc class.
	(struct evaluate_for_locexpr_baton): Derive from
	dwarf_expr_context.
2021-08-05 16:40:17 +01:00
9e739f693f Inline get_reg_value method of dwarf_expr_context
The get_reg_value method is a small function that is only called once,
so it can be inlined to simplify the dwarf_expr_context class.

gdb/ChangeLog:

	* dwarf2/expr.c (dwarf_expr_context::get_reg_value): Remove
	method.
	(dwarf_expr_context::execute_stack_op): Inline get_reg_value
	method.
	* dwarf2/expr.h (dwarf_expr_context::get_reg_value): Remove
	method.
2021-08-05 16:40:12 +01:00
0a2b69d04b Move push_dwarf_reg_entry_value to expr.c
Following the idea of merging the evaluators, the
push_dwarf_reg_entry_value method can be moved from
dwarf_expr_executor and dwarf_evaluate_loc_desc classes
to their base class dwarf_expr_context.

gdb/ChangeLog:

	* dwarf2/expr.c
        (dwarf_expr_context::push_dwarf_reg_entry_value): Move from
	dwarf_evaluate_loc_desc.
	* dwarf2/frame.c
	(dwarf_expr_executor::push_dwarf_reg_entry_value): Remove
	method.
	* dwarf2/loc.c (dwarf_expr_reg_to_entry_parameter): Expose
	function.
	(dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value): Move to
	dwarf_expr_context.
	* dwarf2/loc.h (dwarf_expr_reg_to_entry_parameter): Expose
	function.
2021-08-05 16:40:06 +01:00
3c7c57cdc0 Move read_mem to dwarf_expr_context
Following the idea of merging the evaluators, the read_mem method can
be moved from dwarf_expr_executor and dwarf_evaluate_loc_desc classes
to their base class dwarf_expr_context.

gdb/ChangeLog:

	* dwarf2/expr.c (dwarf_expr_context::read_mem): Move from
	dwarf_evaluate_loc_desc.
	* dwarf2/frame.c (dwarf_expr_executor::read_mem): Remove
	method.
	* dwarf2/loc.c (dwarf_evaluate_loc_desc::read_mem): Move to
	dwarf_expr_context.
2021-08-05 16:39:59 +01:00
73e6b86330 Move get_object_address to dwarf_expr_context
Following the idea of merging the evaluators, the get_object_address
and can be moved from dwarf_expr_executor and dwarf_evaluate_loc_desc
classes to their base class dwarf_expr_context.

gdb/ChangeLog:

	* dwarf2/expr.c (dwarf_expr_context::get_object_address): Move
	from dwarf_evaluate_loc_desc.
	(class dwarf_expr_context): Add object address member to
	dwarf_expr_context.
	* dwarf2/expr.h (dwarf_expr_context::get_frame_pc): Remove
	method.
	* dwarf2/frame.c (dwarf_expr_executor::get_object_address):
	Remove method.
	* dwarf2/loc.c (dwarf_evaluate_loc_desc::get_object_address):
	move to dwarf_expr_context.
	(class dwarf_evaluate_loc_desc): Move object address member to
	dwarf_expr_context.
2021-08-05 16:39:51 +01:00
b6d156edd8 Move dwarf_call to dwarf_expr_context
Following the idea of merging the evaluators, the dwarf_call and
get_frame_pc method can be moved from dwarf_expr_executor and
dwarf_evaluate_loc_desc classes to their base class dwarf_expr_context.
Once this is done, the get_frame_pc can be replace with lambda
function.

gdb/ChangeLog:

	* dwarf2/expr.c (dwarf_expr_context::dwarf_call): Move from
	dwarf_evaluate_loc_desc.
	(dwarf_expr_context::get_frame_pc): Replace with lambda.
	* dwarf2/expr.h (dwarf_expr_context::get_frame_pc): Remove
	method.
	* dwarf2/frame.c (dwarf_expr_executor::dwarf_call): Remove
	method.
	(dwarf_expr_executor::get_frame_pc): Remove method.
	* dwarf2/loc.c (dwarf_evaluate_loc_desc::get_frame_pc): Remove
	method.
	(dwarf_evaluate_loc_desc::dwarf_call): Move to
	dwarf_expr_context.
	(per_cu_dwarf_call): Inline function.
2021-08-05 16:39:43 +01:00
a580d9604b Move compilation unit info to dwarf_expr_context
This patch moves the compilation unit context information and support
from dwarf_expr_executor and dwarf_evaluate_loc_desc to
dwarf_expr_context evaluator. The idea is to report an error when a
given operation requires a compilation unit information to be resolved,
which is not available.

With this change, it also makes sense to always acquire ref_addr_size
information from the compilation unit context, considering that all
DWARF operations that refer to that information require a compilation
unit context to be present during their evaluation.

gdb/ChangeLog:

	* dwarf2/expr.c (ensure_have_per_cu): New function.
	(dwarf_expr_context::dwarf_expr_context): Add compilation unit
	context information.
	(dwarf_expr_context::get_base_type): Move from
	dwarf_evaluate_loc_desc.
	(dwarf_expr_context::get_addr_index): Remove method.
	(dwarf_expr_context::dwarf_variable_value): Remove method.
	(dwarf_expr_context::execute_stack_op): Call compilation unit
	context info check. Inline get_addr_index and
	dwarf_variable_value methods.
	* dwarf2/expr.h (struct dwarf_expr_context): Add compilation
	context info.
        (dwarf_expr_context::get_addr_index): Remove method.
        (dwarf_expr_context::dwarf_variable_value): Remove method.
        (dwarf_expr_context::ref_addr_size): Remove member.
	* dwarf2/frame.c (dwarf_expr_executor::get_addr_index): Remove
	method.
	(dwarf_expr_executor::dwarf_variable_value): Remove method.
	* dwarf2/loc.c (sect_variable_value): Expose function.
	(dwarf_evaluate_loc_desc::get_addr_index): Remove method.
	(dwarf_evaluate_loc_desc::dwarf_variable_value): Remove method.
	(class dwarf_evaluate_loc_desc): Move compilation unit context
	information to dwarf_expr_context class.
	* dwarf2/loc.h (sect_variable_value): Expose function.
2021-08-05 16:39:36 +01:00
6c7779b34b Remove get_frame_cfa from dwarf_expr_context
Following the idea of merging the evaluators, the get_frame_cfa method
can be moved from dwarf_expr_executor and dwarf_evaluate_loc_desc
classes to their base class dwarf_expr_context. Once this is done,
it becomes apparent that the method is only called once and it can be
inlined.

It is also necessary to check if the frame context information was
provided before the DW_OP_call_frame_cfa operation is executed.

gdb/ChangeLog:

	* dwarf2/expr.c (dwarf_expr_context::get_frame_cfa): Remove
	method.
	(dwarf_expr_context::execute_stack_op): Call frame context info
	check for DW_OP_call_frame_cfa. Remove use of get_frame_cfa.
	* dwarf2/expr.h (dwarf_expr_context::get_frame_cfa): Remove
	method.
	* dwarf2/frame.c (dwarf_expr_context::get_frame_cfa): Remove
	method.
	* dwarf2/loc.c (dwarf_expr_context::get_frame_cfa): Remove
	method.
2021-08-05 16:39:27 +01:00
62e37eac1c Move frame context info to dwarf_expr_context
Following 15 patches in this patch series is cleaning up the design of
the DWARF expression evaluator (dwarf_expr_context) to make future
extensions of that evaluator easier and cleaner to implement.

There are three subclasses of the dwarf_expr_context class
(dwarf_expr_executor, dwarf_evaluate_loc_desc and
evaluate_for_locexpr_baton). Here is a short description of each class:

- dwarf_expr_executor is evaluating a DWARF expression in a context
  of a Call Frame Information. The overridden methods of this subclass
  report an error if a specific DWARF operation, represented by that
  method, is not allowed in a CFI context. The source code of this
  subclass lacks the support for composite as well as implicit pointer
  location description.

- dwarf_evaluate_loc_desc can evaluate any expression with no
  restrictions. All of the methods that this subclass overrides are
  actually doing what they are intended to do. This subclass contains
  a full support for all location description types.

- evaluate_for_locexpr_baton subclass is a specialization of the
  dwarf_evaluate_loc_desc subclass and it's function is to add
  support for passed in buffers. This seems to be a way to go around
  the fact that DWARF standard lacks a bit offset support for memory
  location descriptions as well as using any location description for
  the push object address functionality.

It all comes down to this question: what is a function of a DWARF
expression evaluator?

Is it to evaluate the expression in a given context or to check the
correctness of that expression in that context?

Currently, the only reason why there is a dwarf_expr_executor subclass
is to report an invalid DWARF expression in a context of a CFI, but is
that what the evaluator is supposed to do considering that the evaluator
is not tied to a given DWARF version?

There are more and more vendor and GNU extensions that are not part of
the DWARF standard, so is it that impossible to expect that some of the
extensions could actually lift the previously imposed restrictions of
the CFI context? Not to mention that every new DWARF version is lifting
some restrictions anyway.

The thing that makes more sense for an evaluator to do, is to take the
context of an evaluation and checks the requirements of every operation
evaluated against that context. With this approach, the evaluator would
report an error only if parts of the context, necessary for the
evaluation, are missing.

If this approach is taken, then the unification of the
dwarf_evaluate_loc_desc, dwarf_expr_executor and dwarf_expr_context
is the next logical step. This makes a design of the DWARF expression
evaluator cleaner and allows more flexibility when supporting future
vendor and GNU extensions.

Additional benefit here is that now all evaluators have access to all
location description types, which means that a vendor extended CFI
rules could support composite location description as well. This also
means that a new evaluator interface can be changed to return a single
struct value (that describes the result of the evaluation) instead of
a caller poking around the dwarf_expr_context internal data for answers
(like it is done currently).

This patch starts the merging process by moving the frame context
information and support from dwarf_expr_executor and
dwarf_evaluate_loc_desc to dwarf_expr_context evaluator. The idea
is to report an error when a given operation requires a frame
information to be resolved, if that information is not present.

gdb/ChangeLog:

	* dwarf2/expr.c (ensure_have_frame): New function.
	(read_addr_from_reg): Add from frame.c.
	(dwarf_expr_context::dwarf_expr_context): Add frame info to
	dwarf_expr_context.
	(dwarf_expr_context::read_addr_from_reg): Remove.
	(dwarf_expr_context::get_reg_value): Move from
	dwarf_evaluate_loc_desc.
	(dwarf_expr_context::get_frame_base): Move from
	dwarf_evaluate_loc_desc.
	(dwarf_expr_context::execute_stack_op): Call frame context info
	check. Remove use of read_addr_from_reg method.
	* dwarf2/expr.h (struct dwarf_expr_context): Add frame info
	member, read_addr_from_reg, get_reg_value and get_frame_base
	declaration.
	(read_addr_from_reg): Move to expr.c.
	* dwarf2/frame.c (read_addr_from_reg): Move to
	dwarf_expr_context.
	(dwarf_expr_executor::read_addr_from_reg): Remove.
	(dwarf_expr_executor::get_frame_base): Remove.
	(dwarf_expr_executor::get_reg_value): Remove.
	(execute_stack_op): Use read_addr_from_reg function instead of
	read_addr_from_reg method.
	* dwarf2/loc.c (dwarf_evaluate_loc_desc::get_frame_base): Move
	to dwarf_expr_context.
	(dwarf_evaluate_loc_desc::get_reg_value): Move to
	dwarf_expr_context.
	(dwarf_evaluate_loc_desc::read_addr_from_reg): Remove.
	(dwarf2_locexpr_baton_eval):Use read_addr_from_reg function
	instead of read_addr_from_reg method.
2021-08-05 16:39:01 +01:00
fb4cdecb7e Cleanup of the dwarf_expr_context constructor
Move the initial values for dwarf_expr_context class data members
to the class declaration in expr.h.

gdb/ChangeLog:

        * dwarf2/expr.c (dwarf_expr_context::dwarf_expr_context):
        Remove initial data members values.
        * dwarf2/expr.h (dwarf_expr_context): Add initial values
        to the class data members.
2021-08-05 16:38:48 +01:00
183657edcd Replace the symbol needs evaluator with a parser
This patch addresses a design problem with the symbol_needs_eval_context
class. It exposes the problem by introducing two new testsuite test
cases.

To explain the issue, I first need to explain the dwarf_expr_context
class that the symbol_needs_eval_context class derives from.

The intention behind the dwarf_expr_context class is to commonize the
DWARF expression evaluation mechanism for different evaluation
contexts. Currently in gdb, the evaluation context can contain some or
all of the following information: architecture, object file, frame and
compilation unit.

Depending on the information needed to evaluate a given expression,
there are currently three distinct DWARF expression evaluators:

 - Frame: designed to evaluate an expression in the context of a call
   frame information (dwarf_expr_executor class). This evaluator doesn't
   need a compilation unit information.

 - Location description: designed to evaluate an expression in the
   context of a source level information (dwarf_evaluate_loc_desc
   class). This evaluator expects all information needed for the
   evaluation of the given expression to be present.

 - Symbol needs: designed to answer a question about the parts of the
   context information required to evaluate a DWARF expression behind a
   given symbol (symbol_needs_eval_context class). This evaluator
   doesn't need a frame information.

The functional difference between the symbol needs evaluator and the
others is that this evaluator is not meant to interact with the actual
target. Instead, it is supposed to check which parts of the context
information are needed for the given DWARF expression to be evaluated by
the location description evaluator.

The idea is to take advantage of the existing dwarf_expr_context
evaluation mechanism and to fake all required interactions with the
actual target, by returning back dummy values. The evaluation result is
returned as one of three possible values, based on operations found in a
given expression:

- SYMBOL_NEEDS_NONE,
- SYMBOL_NEEDS_REGISTERS and
- SYMBOL_NEEDS_FRAME.

The problem here is that faking results of target interactions can yield
an incorrect evaluation result.

For example, if we have a conditional DWARF expression, where the
condition depends on a value read from an actual target, and the true
branch of the condition requires a frame information to be evaluated,
while the false branch doesn't, fake target reads could conclude that a
frame information is not needed, where in fact it is. This wrong
information would then cause the expression to be actually evaluated (by
the location description evaluator) with a missing frame information.
This would then crash the debugger.

The gdb.dwarf2/symbol_needs_eval_fail.exp test introduces this
scenario, with the following DWARF expression:

                   DW_OP_addr $some_variable
                   DW_OP_deref

                   # conditional jump to DW_OP_bregx
                   DW_OP_bra 4
                   DW_OP_lit0

                   # jump to DW_OP_stack_value
                   DW_OP_skip 3
                   DW_OP_bregx $dwarf_regnum 0
                   DW_OP_stack_value

This expression describes a case where some variable dictates the
location of another variable. Depending on a value of some_variable, the
variable whose location is described by this expression is either read
from a register or it is defined as a constant value 0. In both cases,
the value will be returned as an implicit location description on the
DWARF stack.

Currently, when the symbol needs evaluator fakes a memory read from the
address behind the some_variable variable, the constant value 0 is used
as the value of the variable A, and the check returns the
SYMBOL_NEEDS_NONE result.

This is clearly a wrong result and it causes the debugger to crash.

The scenario might sound strange to some people, but it comes from a
SIMD/SIMT architecture where $some_variable is an execution mask.  In
any case, it is a valid DWARF expression, and GDB shouldn't crash while
evaluating it. Also, a similar example could be made based on a
condition of the frame base value, where if that value is concluded to
be 0, the variable location could be defaulted to a TLS based memory
address.

The gdb.dwarf2/symbol_needs_eval_timeout.exp test introduces a second
scenario. This scenario is a bit more abstract due to the DWARF
assembler lacking the CFI support, but it exposes a different
manifestation of the same problem. Like in the previous scenario, the
DWARF expression used in the test is valid:

                       DW_OP_lit1
                       DW_OP_addr $some_variable
                       DW_OP_deref

                       # jump to DW_OP_fbreg
                       DW_OP_skip 4
                       DW_OP_drop
                       DW_OP_fbreg 0
                       DW_OP_dup
                       DW_OP_lit0
                       DW_OP_eq

                       # conditional jump to DW_OP_drop
                       DW_OP_bra -9
                       DW_OP_stack_value

Similarly to the previous scenario, the location of a variable A is an
implicit location description with a constant value that depends on a
value held by a global variable. The difference from the previous case
is that DWARF expression contains a loop instead of just one branch. The
end condition of that loop depends on the expectation that a frame base
value is never zero. Currently, the act of faking the target reads will
cause the symbol needs evaluator to get stuck in an infinite loop.

Somebody could argue that we could change the fake reads to return
something else, but that would only hide the real problem.

The general impression seems to be that the desired design is to have
one class that deals with parsing of the DWARF expression, while there
are virtual methods that deal with specifics of some operations.

Using an evaluator mechanism here doesn't seem to be correct, because
the act of evaluation relies on accessing the data from the actual
target with the possibility of skipping the evaluation of some parts of
the expression.

To better explain the proposed solution for the issue, I first need to
explain a couple more details behind the current design:

There are multiple places in gdb that handle DWARF expression parsing
for different purposes. Some are in charge of converting the expression
to some other internal representation (decode_location_expression,
disassemble_dwarf_expression and dwarf2_compile_expr_to_ax), some are
analysing the expression for specific information
(compute_stack_depth_worker) and some are in charge of evaluating the
expression in a given context (dwarf_expr_context::execute_stack_op
and decode_locdesc).

The problem is that all those functions have a similar (large) switch
statement that handles each DWARF expression operation. The result of
this is a code duplication and harder maintenance.

As a step into the right direction to solve this problem (at least for
the purpose of a DWARF expression evaluation) the expression parsing was
commonized inside of an evaluator base class (dwarf_expr_context). This
makes sense for all derived classes, except for the symbol needs
evaluator (symbol_needs_eval_context) class.

As described previously the problem with this evaluator is that if the
evaluator is not allowed to access the actual target, it is not really
evaluating.

Instead, the desired function of a symbol needs evaluator seems to fall
more into expression analysis category. This means that a more natural
fit for this evaluator is to be a symbol needs analysis, similar to the
existing compute_stack_depth_worker analysis.

Another problem is that using a heavyweight mechanism of an evaluator
to do an expression analysis seems to be an unneeded overhead. It also
requires a more complicated design of the parent class to support fake
target reads.

The reality is that the whole symbol_needs_eval_context class can be
replaced with a lightweight recursive analysis function, that will give
more correct result without compromising the design of the
dwarf_expr_context class. The analysis treats the expression byte
stream as a DWARF operation graph, where each graph node can be
visited only once and each operation can decide if the frame context
is needed for their evaluation.

The downside of this approach is adding of one more similar switch
statement, but at least this way the new symbol needs analysis will be
a lightweight mechnism and it will provide a correct result for any
given DWARF expression.

A more desired long term design would be to have one class that deals
with parsing of the DWARF expression, while there would be a virtual
methods that deal with specifics of some DWARF operations. Then that
class would be used as a base for all DWARF expression parsing mentioned
at the beginning.

This however, requires a far bigger changes that are out of the scope
of this patch series.

The new analysis requires the DWARF location description for the
argc argument of the main function to change in the assembly file
gdb.python/amd64-py-framefilter-invalidarg.S. Originally, expression
ended with a 0 value byte, which was never reached by the symbol needs
evaluator, because it was detecting a stack underflow when evaluating
the operation before. The new approach does not simulate a DWARF
stack anymore, so the 0 value byte needs to be removed because it
makes the DWARF expression invalid.

gdb/ChangeLog:

        * dwarf2/loc.c (class symbol_needs_eval_context): Remove.
        (dwarf2_get_symbol_read_needs): New function.
        (dwarf2_loc_desc_get_symbol_read_needs): Remove.
        (locexpr_get_symbol_read_needs): Use
        dwarf2_get_symbol_read_needs.

gdb/testsuite/ChangeLog:

        * gdb.python/amd64-py-framefilter-invalidarg.S : Update argc
          DWARF location expression.
        * lib/dwarf.exp (_location): Handle DW_OP_fbreg.
        * gdb.dwarf2/symbol_needs_eval.c: New file.
        * gdb.dwarf2/symbol_needs_eval_fail.exp: New file.
        * gdb.dwarf2/symbol_needs_eval_timeout.exp: New file.
2021-08-05 16:35:02 +01:00
f6c4a82abd gdb: avoid dereferencing empty str_offsets_base optional in dwarf_decode_macros
Since 4d7188abfdf2 ("gdbsupport: add debug assertions in
gdb::optional::get"), some macro-related tests fail on Ubuntu 20.04 with
the system gcc 9.3.0 compiler when building with _GLIBCXX_DEBUG.  For
example, gdb.base/info-macros.exp results in:

   (gdb) break -qualified main
   /home/smarchi/src/binutils-gdb/gdb/../gdbsupport/gdb_optional.h:206: internal-error: T& gdb::optional<T>::get() [with T = long unsigned int]: Assertion `this->has_value ()' failed.

The binary contains DWARF 4 debug info and includes a pre-standard
(pre-DWARF 5) .debug_macro section.  The CU doesn't have a
DW_AT_str_offsets_base attribute (which doesn't exist in DWARF 4).  The
field dwarf2_cu::str_offsets_base is therefore empty.  At
dwarf2/read.c:24138, we unconditionally read the value in the optional,
which triggers the assertion shown above.

The same thing happens when building the test program with DWARF 5 with
the same gcc compiler, as that version of gcc doesn't use indirect
string forms, even with DWARF 5.  So it still doesn't add a
DW_AT_str_offsets_base attribute on the CU.

Fix that by propagating down a gdb::optional<ULONGEST> for the str
offsets base instead of ULONGEST.  That value is only used in
dwarf_decode_macro_bytes, when encountering an "strx" macro operation
(DW_MACRO_define_strx or DW_MACRO_undef_strx).  Add a check there that
we indeed have a value in the optional before reading it.  This is
unlikely to happen, but could happen in theory with an erroneous file
that uses DW_MACRO_define_strx but does not provide a
DW_AT_str_offsets_base (in practice, some things would probably have
failed before and stopped processing of debug info).  I tested the
complaint by inverting the condition and using a clang-compiled binary,
which uses the strx operators.  This is the result:

    During symbol reading: use of DW_MACRO_define_strx with unknown string offsets base [in module /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.base/info-macros/info-macros]

The test now passes cleanly with the setup mentioned above, and the
testsuite looks on par with how it was before 4d7188abfdf2.

Change-Id: I7ebd2724beb7b9b4178872374c2a177aea696e77
2021-08-04 15:26:22 -04:00
d40947728b gdb: fix typo in complaint in dwarf2/macro.c
I saw this complaint when my code had some bug, and spotted the typo.
Fix it, and while at it mention DW_MACRO as well (it would be confusing
to only see DW_MACINFO with a file that uses a DWARF 5 .debug_macro
section).  I contemplated the idea of passing the knowledge of whether
we are dealing with a .debug_macro section or .debug_macinfo section, to
print only the right one.  But in the end, I don't think that trouble is
necessary for a complaint nobody is going to see.

Change-Id: I276ce8da65c3eac5304f64a1e246358ed29cdbbc
2021-08-04 15:26:11 -04:00
ad14ab00eb [gdb/symtab] Fix unhandled dwarf expression opcode with gcc-11 -gdwarf-5
[ I've confused things by forgetting to add -gdwarf-4 in $subject of
commit 0057a7ee0d9 "[gdb/testsuite] Add KFAILs for gdb.ada FAILs with
gcc-11".  So I'm adding here -gdwarf-5 in $subject, even though -gdwarf-5 is
the default for gcc-11.  I keep getting confused because of working with a
system gcc-11 compiler that was patched to switch the default back to
-gdwarf-4. ]

When running test-case gdb.ada/arrayptr.exp with gcc-11 (and default
-gdwarf-5), I run into:
...
(gdb) print pa_ptr.all^M
Unhandled dwarf expression opcode 0xff^M
(gdb) FAIL: gdb.ada/arrayptr.exp: scenario=all: print pa_ptr.all
...

What happens is that pa_ptr:
...
 <2><1523>: Abbrev Number: 3 (DW_TAG_variable)
    <1524>   DW_AT_name        : pa_ptr
    <1529>   DW_AT_type        : <0x14fa>
...
has type:
...
 <2><14fa>: Abbrev Number: 2 (DW_TAG_typedef)
    <14fb>   DW_AT_name        : foo__packed_array_ptr
    <1500>   DW_AT_type        : <0x1504>
 <2><1504>: Abbrev Number: 4 (DW_TAG_pointer_type)
    <1505>   DW_AT_byte_size   : 8
    <1505>   DW_AT_type        : <0x1509>
...
which is a pointer to a subrange:
...
 <2><1509>: Abbrev Number: 12 (DW_TAG_subrange_type)
    <150a>   DW_AT_lower_bound : 0
    <150b>   DW_AT_upper_bound : 0x3fffffffffffffffff
    <151b>   DW_AT_name        : foo__packed_array
    <151f>   DW_AT_type        : <0x15cc>
    <1523>   DW_AT_artificial  : 1
 <1><15cc>: Abbrev Number: 5 (DW_TAG_base_type)
    <15cd>   DW_AT_byte_size   : 16
    <15ce>   DW_AT_encoding    : 7      (unsigned)
    <15cf>   DW_AT_name        : long_long_long_unsigned
    <15d3>   DW_AT_artificial  : 1
...
with upper bound of form DW_FORM_data16.

In gdb/dwarf/attribute.h we have:
...
  /* Return non-zero if ATTR's value falls in the 'constant' class, or
     zero otherwise.  When this function returns true, you can apply
     the constant_value method to it.
     ...
     DW_FORM_data16 is not considered as constant_value cannot handle
     that.  */
  bool form_is_constant () const;
...
so instead we have attribute::form_is_block (DW_FORM_data16) == true.

Then in attr_to_dynamic_prop for the upper bound, we get a PROC_LOCEXPR
instead of a PROP_CONST and end up trying to evaluate the constant
0x3fffffffffffffffff as if it were a locexpr, which causes the
"Unhandled dwarf expression opcode 0xff".

In contrast, with -gdwarf-4 we have:
...
    <164c>   DW_AT_upper_bound : 18 byte block: \
      9e 10 ff ff ff ff ff ff ff ff 3f 0 0 0 0 0 0 0 \
      (DW_OP_implicit_value 16 byte block: \
        ff ff ff ff ff ff ff ff 3f 0 0 0 0 0 0 0 )
...

Fix the dwarf error by translating the DW_FORM_data16 constant into a
PROC_LOCEXPR, effectively by prepending 0x9e 0x10, such that we have same
result as with -gdwarf-4:
...
(gdb) print pa_ptr.all^M
That operation is not available on integers of more than 8 bytes.^M
(gdb) KFAIL: gdb.ada/arrayptr.exp: scenario=all: print pa_ptr.all \
  (PRMS: gdb/20991)
...

Tested on x86_64-linux, with gcc-11 and target board
unix/gdb:debug_flags=-gdwarf-5.

gdb/ChangeLog:

2021-07-25  Tom de Vries  <tdevries@suse.de>

	* dwarf2/read.c (attr_to_dynamic_prop): Handle DW_FORM_data16.
2021-07-28 10:01:05 +02:00
1fd5fd5817 Fix file-name handling regression with DWARF index
When run with the gdb-index or debug-names target boards, dup-psym.exp
fails.  This came up for me because my new DWARF scanner reuses this
part of the existing index code, and so it registers as a regression.
This is PR symtab/25834.

Looking into this, I found that the DWARF index code here is fairly
different from the psymtab code.  I don't think there's a deep reason
for this, and in fact, it seemed to me that the index code could
simply mimic what the psymtab code already does.

That is what this patch implements.  The DW_AT_name and DW_AT_comp_dir
are now stored in the quick file names table.  This may require
allocating a quick file names table even when DW_AT_stmt_list does not
exist.  Then, the functions that work with this data are changed to
use find_source_or_rewrite, just as the psymbol code does.  Finally,
line_header::file_full_name is removed, as it is no longer needed.

Currently, the index maintains a hash table of "quick file names".
The hash table uses a deletion function to free the "real name"
components when necessary.  There's also a second such function to
implement the forget_cached_source_info method.

This bug fix patch will create a quick file name object even when
there is no DW_AT_stmt_list, meaning that the object won't be entered
in the hash table.  So, this patch changes the memory management
approach so that the entries are cleared when the per-BFD object is
destroyed.  (A dwarf2_per_cu_data destructor is not introduced,
because we have been avoiding adding a vtable to that class.)

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=25834
2021-07-17 11:08:18 -06:00
15659f0a4e Check for debug-types in map_symbol_filenames
map_symbol_filenames can skip type units -- in fact I think it has to,
due to the assertion at the top of dw2_get_file_names.  This may be a
regression due to the TU/CU unification patch, I did not check.
2021-07-17 10:41:42 -06:00
e0ec6b1a87 Simplify DWARF file name caching
The DWARF index file name caching code only records when a line table
has been read and the reading failed.  However, the code would be
simpler if it recorded any attempt, which is what this patch
implements.
2021-07-17 10:41:42 -06:00
d030267c9c Simplify file_and_directory storage management
file_and_directory carries a std::string in case the compilation
directory is computed, but a subsequent patch wants to preserve this
string without also having to maintain the storage for it.  So, this
patch arranges for the compilation directory string to be stored in
the per-BFD string bcache instead.
2021-07-17 10:41:42 -06:00
dcce7ec410 Pass file_and_directory through DWARF line-decoding code
This patch removes the redundant "comp_unit" parameter from
compute_include_file_name, and arranges to pass a file_and_directory
object from the readers down to this function.  It also changes the
partial symtab reader to use find_file_and_directory, rather than
reimplement this functionality by hand.
2021-07-17 10:41:42 -06:00
ae9a5dd6ae Rename and refactor psymtab_include_file_name
In order to fix an index-related regression, I want to use
psymtab_include_file_name in the DWARF index file-handling code.  This
patch renames this function and changes it to no longer require a
partial symtab to be passed in.  A subsequent patch will further
refactor this code to remove the redundant parameter (which was always
there but is now more obvious).
2021-07-17 10:41:42 -06:00
4f348ca808 Document quick_symbol_functions::expand_symtabs_matching invariant
While working on my series to replace the DWARF psymbol reader, I
noticed that the expand_symtabs_matching has an undocumented
invariant.  I think that, if this invariant is not followed, then GDB
will crash.  So, this patch documents this in the relevant spots and
introduces some asserts to make it clear.

Regression tested on x86-64 Fedora 32.
2021-07-16 13:54:01 -06:00
81e33ce289 gdb, dwarf: Don't follow the parent of a subprogram to get a prefix.
During prefix resolution, if the parent is a subprogram, there is no need
to go to the parent of the subprogram.  The DIE will be local.

For a program like:
~~~
  class F1
  {
  public:
    int a;
    int
    vvv ()
    {
      class F2
      {
	int f;
      };
      F2 abcd;
      return 1;
    }
  };
~~~

The class F2 should not be seen as a member of F1.

Before:
~~~
(gdb) ptype abcd
type = class F1::F2 {
  private:
    int f;
}
~~~

After:
~~~
(gdb) ptype abcd
type = class F2 {
  private:
    int f;
}
~~~

gdb/ChangeLog:
2021-06-23  Felix Willgerodt  <felix.willgerodt@intel.com>

	* dwarf2/read.c (determine_prefix): Return an empty prefix if the
	parent is a subprogram.

gdb/testsuite/ChangeLog:
2021-06-23  Felix Willgerodt  <felix.willgerodt@intel.com>

	* gdb.cp/nested-class-func-class.cc: New file.
	* gdb.cp/nested-class-func-class.exp: New file.
2021-07-13 15:29:29 +02:00
752e419362 [gdb/symtab] Fix skipping of import of C++ CU
Tom Tromey observed that when changing the language in
gdb.dwarf2/imported-unit-bp.exp from c to c++, the test failed.

This is due to this code in process_imported_unit_die:
...
      /* We're importing a C++ compilation unit with tag DW_TAG_compile_unit
         into another compilation unit, at root level.  Regard this as a hint,
         and ignore it.  */
      if (die->parent && die->parent->parent == NULL
          && per_cu->unit_type == DW_UT_compile
          && per_cu->lang == language_cplus)
        return;
...
which should have a partial symtabs counterpart.

Add the missing counterpart in process_psymtab_comp_unit.

Tested on x86_64-linux (openSUSE Leap 15.2), no regressions for config:
- using default gcc version 7.5.0
  (with 5 unexpected FAILs)
- gcc 10.3.0 and target board
  unix/-flto/-O0/-flto-partition=none/-ffat-lto-objects
  (with 1000 unexpected FAILs)

gdb/ChangeLog:

2021-07-06  Tom de Vries  <tdevries@suse.de>

	* dwarf2/read.c (scan_partial_symbols): Skip top-level imports of
	c++ CU.
	* testsuite/gdb.dwarf2/imported-unit-bp.exp: Moved to ...
	* testsuite/gdb.dwarf2/imported-unit-bp.exp.tcl: ... here.
	* testsuite/gdb.dwarf2/imported-unit-bp-c++.exp: New test.
	* testsuite/gdb.dwarf2/imported-unit-bp-c.exp: New test.
	* testsuite/gdb.dwarf2/imported-unit.exp: Update.
2021-07-06 10:58:43 +02:00
09e2fb720b Simplify debug_names index writing
This changes the .debug_names writer to find the TU indices in the
main loop over all CUs and TUs.  (An earlier patch applied this same
treatment to the .gdb_index writer.)
2021-07-05 12:24:00 -06:00
844a72efbc Simplify gdb_index writing
write_gdbindex writes the CUs first, then walks the signatured type
hash table to write out the TUs.  However, now that CUs and TUs are
unified in the DWARF reader, it's simpler to handle both of these in
the same loop.
2021-07-05 12:23:41 -06:00
870c2204a2 Minor cleanup to addrmap_index_data::previous_valid
This changes addrmap_index_data::previous_valid to a bool, and
initializes it inline.
2021-07-05 11:57:40 -06:00
b5b44b5df0 Fix oddity in write_gdbindex
My recent patch to unify CUs and TUs introduced an oddity in
write_gdbindex.  Here, we pass 'i' to recursively_write_psymbols, but
we must instead pass 'counter', to handle the situation where a TU is
mixed in with the CUs.

I am not sure a test case for this is possible.  I think it can only
happen when using DWARF 5, where a TU appears in .debug_info.
However, this situation is already not handled correctly by
.gdb_index.  I filed a bug about this.
2021-07-05 11:57:14 -06:00
4fabc3a897 Use 'bool' more idiomatically in dwarf_decode_lines
I noticed a couple of spots related to dwarf_decode_lines where the
'include_p' field was not being used idiomatically -- it is of type
bool now, so treat it as such.

gdb/ChangeLog
2021-07-03  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (lnp_state_machine::record_line): Use 'true'.
	(dwarf_decode_lines): Remove '=='.
2021-07-03 11:40:54 -06:00
a154d838a7 gdb: add names to unwinders, add debug messages when looking for unwinder
I wrote this while debugging a problem where the expected unwinder for a
frame wasn't used.  It adds messages to show which unwinders are
considered for a frame, why they are not selected (if an exception is
thrown), and finally which unwinder is selected in the end.

To be able to show a meaningful, human-readable name for the unwinders,
add a "name" field to struct frame_unwind, and update all instances to
include a name.

Here's an example of the output:

    [frame] frame_unwind_find_by_frame: this_frame=0
    [frame] frame_unwind_try_unwinder: trying unwinder "dummy"
    [frame] frame_unwind_try_unwinder: no
    [frame] frame_unwind_try_unwinder: trying unwinder "dwarf2 tailcall"
    [frame] frame_unwind_try_unwinder: no
    [frame] frame_unwind_try_unwinder: trying unwinder "inline"
    [frame] frame_unwind_try_unwinder: no
    [frame] frame_unwind_try_unwinder: trying unwinder "jit"
    [frame] frame_unwind_try_unwinder: no
    [frame] frame_unwind_try_unwinder: trying unwinder "python"
    [frame] frame_unwind_try_unwinder: no
    [frame] frame_unwind_try_unwinder: trying unwinder "amd64 epilogue"
    [frame] frame_unwind_try_unwinder: no
    [frame] frame_unwind_try_unwinder: trying unwinder "i386 epilogue"
    [frame] frame_unwind_try_unwinder: no
    [frame] frame_unwind_try_unwinder: trying unwinder "dwarf2"
    [frame] frame_unwind_try_unwinder: yes

gdb/ChangeLog:

	* frame-unwind.h (struct frame_unwind) <name>: New.  Update
	instances everywhere to include this field.
	* frame-unwind.c (frame_unwind_try_unwinder,
	frame_unwind_find_by_frame): Add debug messages.

Change-Id: I813f17777422425f0d08b22499817b23922e8ddb
2021-06-29 12:05:03 -04:00
fc4d5ebf8f gdb: add new function quick_symbol_functions::has_unexpanded_symbols
Adds a new function to the quick_symbol_functions API to let us know
if there are any unexpanded symbols.  This functionality is required
by a later commit.  After this commit the functionality is unused, and
untested.

The new function objfile::has_unexpanded_symtabs is added to the
symfile-debug.c file which is a little strange, but this
is (currently) where many of the other objfile::* functions (that call
onto the quick_symbol_functions) are defined, so I'm reluctant to
break this pattern.

There should be no user visible changes after this commit.

gdb/ChangeLog:

	* dwarf2/read.c (struct dwarf2_base_index_functions)
	<has_unexpanded_symtabs>: Declare.
	(dwarf2_base_index_functions::has_unexpanded_symtabs): Define new
	function.
	* objfiles.h (struct objfile) <has_unexpanded_symtabs>: Declare.
	* psympriv.h (struct psymbol_functions) <has_unexpanded_symtabs>:
	Declare.
	* psymtab.c (psymbol_functions::has_unexpanded_symtabs): Define
	new function.
	* quick-symbol.h (struct quick_symbol_functions)
	<has_unexpanded_symtabs>: Declare.
	* symfile-debug.c (objfile::has_unexpanded_symtabs): Define new
	function.
2021-06-25 20:54:28 +01:00
3da4c6449b Change how .debug_aranges padding is skipped
When GCC emits .debug_aranges, it adds padding to align the contents
to two times the address size.  GCC has done this for many years --
but there is nothing in the DWARF standard that says this should be
done, and LLVM does not seem to add this padding.

It's simple to detect if the padding exists, though: if the contents
of one .debug_aranges CU (excluding the header) are not a multiple of
the alignment that GCC uses, then anything extra must be padding.

This patch changes gdb to correctly read both styles.  It removes the
requirement that the padding bytes be zero, as this seemed
unnecessarily pedantic to me.

gdb/ChangeLog
2021-06-25  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (create_addrmap_from_aranges): Change padding
	logic.

gdb/testsuite/ChangeLog
2021-06-25  Tom Tromey  <tom@tromey.com>

	* lib/gdb.exp (add_gdb_index, ensure_gdb_index): Add "style"
	parameter.
	* gdb.rust/dwindex.exp: New file.
	* gdb.rust/dwindex.rs: New file.
2021-06-25 12:34:41 -06:00
3e9f1ca148 Remove dwarf2_cu::language
dwarf2_cu has a 'language' value, but dwarf2_per_cu_data also holds a
value of this same type.  There doesn't seem to be any reason to keep
two copies of this value.  This patch removes the field from
dwarf2_cu, and arranges to set the value in the per-CU object instead.

Note that the value must still be set when expanding the full CU.
This is needed because the CUs will not be scanned when a DWARF index
is in use.

gdb/ChangeLog
2021-06-25  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (process_psymtab_comp_unit): Don't set 'lang'.
	(scan_partial_symbols, partial_die_parent_scope)
	(add_partial_symbol, add_partial_subprogram)
	(compute_delayed_physnames, rust_union_quirks)
	(process_full_comp_unit, process_full_type_unit)
	(process_imported_unit_die, process_die, dw2_linkage_name)
	(dwarf2_compute_name, dwarf2_physname, read_import_statement)
	(read_file_scope, queue_and_load_dwo_tu, read_func_scope)
	(read_variable, dwarf2_get_subprogram_pc_bounds)
	(dwarf2_attach_fields_to_type, dwarf2_add_member_fn)
	(dwarf2_attach_fn_fields_to_type)
	(quirk_ada_thick_pointer_struct, read_structure_type)
	(handle_struct_member_die, process_structure_scope)
	(read_array_type, read_array_order, prototyped_function_p)
	(read_subroutine_type, dwarf2_init_complex_target_type)
	(read_base_type, read_subrange_type, read_unspecified_type)
	(load_partial_dies, partial_die_info::fixup, set_cu_language)
	(new_symbol, need_gnat_info, determine_prefix, typename_concat)
	(dwarf2_canonicalize_name, follow_die_offset)
	(prepare_one_comp_unit): Update.
	* dwarf2/cu.c (dwarf2_cu::start_symtab): Update.
2021-06-25 12:23:05 -06:00
bf1dcdb391 Consolidate CU language setting
The DWARF reader currently sets the CU's language in two different
spots.  It is primarily done in prepare_one_comp_unit, but
read_file_scope also checks the producer and may change the language
based on the result.

This patch consolidates all language-setting into
prepare_one_comp_unit.  set_cu_language is renamed and changed not to
set language_defn; instead that is done in prepare_one_comp_unit after
the correct language enum value is chosen.

This fixes a minor latent bug, which is that read_file_scope could set
the language enum value to language_opencl, but then neglected to
reset language_defn in this case.

gdb/ChangeLog
2021-06-25  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (read_file_scope): Don't call set_cu_language.
	(dwarf_lang_to_enum_language): Rename from set_cu_language.  Don't
	set language_defn.  Handle DW_LANG_OpenCL.
	(prepare_one_comp_unit): Check producer and set language_defn.
2021-06-25 12:23:04 -06:00