Commit Graph

1198 Commits

Author SHA1 Message Date
Tom Tromey
ca19833332 Use gdb set in dwarf2/aranges.c
This changes dwarf2/aranges.c to use gdb::unordered_set.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-03-11 08:40:06 -06:00
Tom Tromey
2609ee6f19 Add string cache and use it in cooked index
The cooked index needs to allocate names in some cases -- when
canonicalizing or when synthesizing Ada package names.  This process
currently uses a vector of unique_ptrs to manage the memory.

Another series I'm writing adds another spot where this allocation
must be done, and examining the result showed that certain names were
allocated multiple times.

To clean this up, this patch introduces a string cache object and
changes the cooked indexer to use it.  I considered using bcache here,
but bcache doesn't work as nicely with string_view -- because bcache
is fundamentally memory-based, a temporary copy of the contents must
be made to ensure that bcache can see the trailing \0.  Furthermore,
writing a custom class lets us avoid another copy when canonicalizing
C++ names.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-03-10 15:05:34 -06:00
Simon Marchi
c19c928f7b Revert past commits
I accidentally pushed my work-in-progress branch... revert that.  Sorry
for the noise :(.

The list of commits reverted are:

    ae2a50a9ae attempt to revamp to the CU/TU list
    e9386435c9 gdb/dwarf: print DWARF CUs/TUs in "maint print objfiles"
    6cbd64aa3e gdb/dwarf: add dwarf_source_language_name
    32a187da76 libiberty: move DW_LANG_* definitions to dwarf2.def
    b3fa38aef5 gdb/dwarf: move index unit vectors to debug names reader and use them
    30ba744189 gdb/dwarf: track comp and type units count
    bedb4e09f2 gdb/dwarf: remove unnecessary braces
    b4f18de12c gdb/dwarf: use ranged for loop in some pots

Change-Id: I80aed2847025f5b15c16c997680783b39858a703
2025-03-10 16:15:42 -04:00
Simon Marchi
ae2a50a9ae attempt to revamp to the CU/TU list
Change-Id: I1c8214413583d540c10c9a2322ef2a21f8bb54e7
2025-03-10 16:09:02 -04:00
Simon Marchi
e9386435c9 gdb/dwarf: print DWARF CUs/TUs in "maint print objfiles"
This was useful to me, to debug some problems.

Before printing cooked index entries, print a list of CUs and TUs.  The
information printed for each is a bit arbitrary, I took a look at the
types and printed what seemed relevant.

An example of output for a CU:

    [0] ((dwarf2_per_cu_data *) 0x50f000007840)
    type:       DW_UT_compile
    offset:     0x0
    size:       0x1bff
    artificial: false
    GDB lang:   c++
    DWARF lang: DW_LANG_C_plus_plus

And for a TU:

    [2] ((signatured_type *) 0x511000040000)
    type:      DW_UT_type
    offset:    0x0
    size:      0x94
    signature: 0x2e966c0dc94b065b

I moved the call to cooked_index_functions::wait before printing the
CU/TU list, otherwise trying to call "maint print objfiles" quickly,
like this, would lead to an internal error:

  $ ./gdb  -nx -q --data-directory=data-directory testsuite/outputs/gdb.dwarf2/struct-with-sig/struct-with-sig -ex "maint print objfiles"

This is because dwarf2_per_cu_data::m_unit_type was not yet set, when
trying to read it.  Waiting for the index to be built ensures that it is
set, since setting the unit type is done as a side-effect somewhere.

Change-Id: Ic810ec3bb4d3f5abb481cf1cee9b2954ff4f0874
2025-03-10 16:09:02 -04:00
Simon Marchi
6cbd64aa3e gdb/dwarf: add dwarf_source_language_name
Add dwarf_source_language_name, to convert a DW_LANG_* constant to
string.  This will be used in a following patch.

Change-Id: I552ebd318e2e770d590de5920edbd0b75075c1b7
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-10 16:09:02 -04:00
Simon Marchi
b3fa38aef5 gdb/dwarf: move index unit vectors to debug names reader and use them
Since these vectors contain the CU and TU lists as found in the
.debug_names header, it seems like they are meant to be used by the
.debug_names reader when handling a DW_IDX_compile_unit or
DW_IDX_type_unit attribute.  The value of the attribute would translate
directly into an index into one of these vectors.

However there's something fishy: it looks like these vectors aren't
actually used in practice.  They are used in the
dwarf2_per_bfd::get_index_{c,t}u methods, which in turn aren't used
anywhere.

The handlers of DW_IDX_compile_unit and DW_IDX_type_unit use the
dwarf2_per_bfd::get_cu method, assuming that all compile units are
placed before type units in the dwarf2_per_bfd::all_units vector.  I see
several problems with that:

 1. I found out [1] that the dwarf2_per_bfd::all_units didn't always
    have the CUs before the TUs.  So indexing dwarf2_per_bfd::all_units
    with that assumption will not work.

 2. The dwarf2_find_containing_comp_unit function assumes an ordering of
    units by section offset (among other criteria) in order to do a
    binary search.  Even though it's probably commonly the case, nothing
    guarantees that the order of CUs and TUs in the .debug_names header
    (which defines the indices used to refer to them) will be sorted by
    section offset.  It's not possible to make
    dwarf2_find_containing_comp_unit (assuming it wants to do a binary
    search by section offset) and the DW_IDX_compile_unit /
    DW_IDX_type_unit handlers use the same vector.

 3. I have not tested this, but in the presence of a dwz supplementary
    file, the .debug_names reader should probably not put the units from
    the main and dwz files in the same vectors to look them up by index.
    Presumably, if both the main and dwz files have a .debug_names
    index, they have distinct CU / TU lists.  So, an CU index of 1 in an
    index entry in the main file would refer to a different CU than an
    index of 1 in an index entry in the dwz file.  The current code
    doesn't seem to account for that, it just indexes
    dwarf2_per_bfd::all_units.

Since those vectors are kind of specific to the .debug_names reader,
move them there, in the mapped_debug_names_reader struct.  Then, update
the handlers of DW_IDX_compile_unit and DW_IDX_type_unit to use them.

[1] https://inbox.sourceware.org/gdb-patches/87a5ab5i5m.fsf@tromey.com/T/#mbdcfe35f94db33e59500eb0d3d225661cab016a4

Change-Id: I3958d70bb3875268143471da745aa09336ab2500
2025-03-10 16:09:02 -04:00
Simon Marchi
30ba744189 gdb/dwarf: track comp and type units count
A subsequent commit will remove the all_comp_units and all_type_units
array views, since the all_units vector will no longer be segmented
between comp and type units.  Some callers still need to know the number
of each kind, so track that separately.

Change-Id: I6ef184767a96e5be095bbf9142aa850adbb083ac
2025-03-10 16:09:02 -04:00
Simon Marchi
bedb4e09f2 gdb/dwarf: remove unnecessary braces
Change-Id: If0b38b860e79771a16ea914af3e337fca0ee3a7d
2025-03-10 16:09:02 -04:00
Simon Marchi
b4f18de12c gdb/dwarf: use ranged for loop in some pots
I noticed that these loops could be written to avoid the iteration
variable `i`.

Change-Id: Ia3717acbbf732f0337870d35ac60fe6400383324
2025-03-10 16:09:02 -04:00
Simon Marchi
f62cf22157 gdb/dwarf: save DWARF version in dwarf2_loclist_baton, remove it from dwarf2_per_cu
When running:

    $ make check TESTS="gdb.cp/cpexprs-debug-types.exp" RUNTESTFLAGS="--target_board=fission"

I get:

    (gdb) break -qualified main
    /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.h:295: internal-error: version: Assertion `m_dwarf_version != 0' failed.

The problem is that dwarf2_per_cu objects created in the
read_cutu_die_from_dwo code path never have their DWARF version set.  A
seemingly obvious solution would be to add a call to
dwarf2_per_cu::set_version in there (there's a patch in the referenced
PR that does that).  However, this comment in
read_comp_units_from_section is a bit scary:

      /* Init this asap, to avoid a data race in the set_version in
	 cutu_reader::cutu_reader (which may be run in parallel for the cooked
	 index case).  */
      this_cu->set_version (cu_header.version);

I don't know if a DWO file can be read while the cooked indexer runs, so
if it would be a problem here, but I prefer to be safe than sorry.  This
patch side-steps the problem by deleting the DWARF version from
dwarf2_per_cu.

The only users of dwarf2_per_cu::version are the loclists callbacks in
`loc.c`.  Add the DWARF version to dwarf2_loclist_baton and modify those
callbacks to get the version from there instead.  Initialize that new
field in fill_in_loclist_baton.

I like this approach because there is no version field that is possibly
unset now.

I wasn't keen on doing this at first because I thought it would waste
space, but the dwarf2_loclist_baton has 7 bytes of padding at the end
anyway, so we might as well use that.

Cc: Ricky Zhou <ricky@rzhou.org>
Cc: Tom de Vries <tdevries@suse.de>
Cc: Tom Tromey <tom@tromey.com>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32309
Change-Id: I30d4ede7d67da5d80ff65c6122f5868e1098ec52
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-10 16:09:01 -04:00
Tom Tromey
c05c9914b1 Use flags enum for cooked_index_entry::full_name
I found a small bug coming from a couple of  recent patches of mine for
cooked_index_entry::full_name.

First, commit aab26529b3 (Add "Ada linkage" mode to
cooked_index_entry::full_name) added a small hack to optionally
compute the Ada linkage name.

Then, commit aab2ac34d7 (Avoid excessive CU expansion on failed
matches) changed the relevant expand_symtabs_matching implementation
to use this feature.

However, the feature was used unconditionally, causing a bad side
effect: the non-canonical name is now used for all languages, not just
Ada.  But, for C++ this is wrong.

Furthermore, consider the declaration of full_name:

   const char *full_name (struct obstack *storage,
			 bool for_main = false,
			 bool for_ada_linkage = false,
 			 const char *default_sep = nullptr) const;

... and then consider this call in cooked_index::dump:

       gdb_printf ("    qualified:  %s\n",
		  entry->full_name (&temp_storage, false, "::"));

Oops!  The "::" is silently converted to 'true' here.

To fix both of these problems, this patch changes full_name to accept
a flags enum rather than booleans.  This avoids the type-safety
problem.

Then, full_name is changed to remove the "Ada" flag when the entry is
not in fact an Ada symbol.

Regression tested on x86-64 Fedora 40.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-03-10 13:40:25 -06:00
Simon Marchi
cc0fdf9861 gdb/dwarf: rename comp_unit_die to top_level_die
The name "comp_unit_die" is a bit misleading, because it can also
represent a type unit (DW_TAG_type_unit).  I think that "top_level_die"
is clear.

Change-Id: Ibaac99897f0ac7499f0f82caeed3385e1e6ee870
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-10 11:28:10 -04:00
Simon Marchi
3f239fd3ff gdb/dwarf: add doc for cutu_reader::is_dummy
Change-Id: Ifb80557187c12822bdea7ad400c32c3dce968a7f
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-10 11:28:10 -04:00
Simon Marchi
86a53c0b2e gdb/dwarf: call other cutu_reader constructor in ensure_lang and dw2_get_file_names
PR 32742 shows this failing:

    $ make check TESTS="gdb.ada/access_to_unbounded_array.exp" RUNTESTFLAGS="--target_board=fission"
    Running /home/simark/src/binutils-gdb/gdb/testsuite/gdb.ada/access_to_unbounded_array.exp ...
    FAIL: gdb.ada/access_to_unbounded_array.exp: scenario=all: gdb_breakpoint: set breakpoint at foo.adb:23 (GDB internal error)

Or, interactively:

    $ ./gdb -q -nx --data-directory=data-directory testsuite/outputs/gdb.ada/access_to_unbounded_array/foo-all -ex 'b foo.adb:23' -batch
    /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:19567: internal-error: set_lang: Assertion `old_value == language_unknown || old_value == language_minimal || old_value == lang' failed.

The symptom is that for a given dwarf2_per_cu, the language gets set
twice.  First, set to `language_ada`, and then, to `language_minimal`.
It's unexpected for the language of a CU to get changed like this.

The CU at offset 0x0 in the main file looks like:

    0x00000000: Compile Unit: length = 0x00000030, format = DWARF32, version = 0x0004, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x00000034)

    0x0000000b: DW_TAG_compile_unit
                  DW_AT_low_pc [DW_FORM_addr]       (0x000000000000339a)
                  DW_AT_high_pc [DW_FORM_data8]     (0x0000000000000432)
                  DW_AT_stmt_list [DW_FORM_sec_offset]      (0x00000000)
                  DW_AT_GNU_dwo_name [DW_FORM_strp] ("b~foo.dwo")
                  DW_AT_comp_dir [DW_FORM_strp]     ("/home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.ada/access_to_unbounded_array")
                  DW_AT_GNU_pubnames [DW_FORM_flag_present] (true)
                  DW_AT_GNU_addr_base [DW_FORM_sec_offset]  (0x00000000)
                  DW_AT_GNU_dwo_id [DW_FORM_data8]  (0x277aee54e7bd47f7)

This refers to the DWO file b~foo.dwo, whose top-level DIE is:

    .debug_info.dwo contents:
    0x00000000: Compile Unit: length = 0x00000b63, format = DWARF32, version = 0x0004, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x00000b67)

    0x0000000b: DW_TAG_compile_unit
                  DW_AT_producer [DW_FORM_GNU_str_index]    ("GNU Ada 14.2.1 20250207 -fgnat-encodings=minimal -gdwarf-4 -fdebug-types-section -fuse-ld=gold -gnatA -gnatWb -gnatiw -gdwarf-4 -gsplit-dwarf -ggnu-pubnames -gnatws -mtune=generic -march=x86-64")
                  DW_AT_language [DW_FORM_data1]    (DW_LANG_Ada95)
                  DW_AT_name [DW_FORM_GNU_str_index]        ("/home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.ada/access_to_unbounded_array/b~foo.adb")
                  DW_AT_comp_dir [DW_FORM_GNU_str_index]    ("/home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.ada/access_to_unbounded_array")
                  DW_AT_GNU_dwo_id [DW_FORM_data8]  (0xdbeffefab180a2cb)

The thing to note is that the language attribute is only present in the
DIE in the DWO file, not on the DIE in the main file.

The first time the language gets set is here:

    #0  dwarf2_per_cu::set_lang (this=0x50f0000044b0, lang=language_ada, dw_lang=DW_LANG_Ada95) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:20788
    #1  0x0000555561666af6 in cutu_reader::prepare_one_comp_unit (this=0x7ffff10bf2b0, cu=0x51700008e000, pretend_language=language_minimal) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:21029
    #2  0x000055556159f740 in cutu_reader::cutu_reader (this=0x7ffff10bf2b0, this_cu=0x50f0000044b0, per_objfile=0x516000066080, abbrev_table=0x510000004640, existing_cu=0x0, skip_partial=false, pretend_language=language_minimal, cache=0x7ffff11b95e0) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:3371
    #3  0x00005555615a547a in process_psymtab_comp_unit (this_cu=0x50f0000044b0, per_objfile=0x516000066080, storage=0x7ffff11b95e0) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:3799
    #4  0x00005555615a9292 in cooked_index_worker_debug_info::process_cus (this=0x51700008dc80, task_number=0, first=std::unique_ptr<dwarf2_per_cu> = {...}, end=std::unique_ptr<dwarf2_per_cu> = {...}) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:4122

In this code path (particularly this specific cutu_reader constructir),
the work is done to find and read the DWO file.  So the language is
properly identifier as language_ada, all good so far.

The second time the language gets set is:

    #0  dwarf2_per_cu::set_lang (this=0x50f0000044b0, lang=language_minimal, dw_lang=0) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:20788
    #1  0x0000555561666af6 in cutu_reader::prepare_one_comp_unit (this=0x7ffff0f42730, cu=0x517000091b80, pretend_language=language_minimal) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:21029
    #2  0x00005555615a1822 in cutu_reader::cutu_reader (this=0x7ffff0f42730, this_cu=0x50f0000044b0, per_objfile=0x516000066080, pretend_language=language_minimal, parent_cu=0x0, dwo_file=0x0) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:3464
    #3  0x000055556158c850 in dw2_get_file_names (this_cu=0x50f0000044b0, per_objfile=0x516000066080) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:1956
    #4  0x000055556158f4f5 in dw_expand_symtabs_matching_file_matcher (per_objfile=0x516000066080, file_matcher=...) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:2157
    #5  0x00005555616329e2 in cooked_index_functions::expand_symtabs_matching (this=0x50200002ab50, objfile=0x516000065780, file_matcher=..., lookup_name=0x0, symbol_matcher=..., expansion_notify=..., search_flags=..., domain=..., lang_matcher=...) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:15912
    #6  0x0000555562ca8a14 in objfile::map_symtabs_matching_filename (this=0x516000065780, name=0x50200002ad90 "break pck.adb", real_path=0x0, callback=...) at /home/smarchi/src/binutils-gdb/gdb/symfile-debug.c:207
    #7  0x0000555562d68775 in iterate_over_symtabs (pspace=0x513000005600, name=0x50200002ad90 "break pck.adb", callback=...) at /home/smarchi/src/binutils-gdb/gdb/symtab.c:727

Here, we use the other cutu_reader constructor, the one that does not
look up the DWO file for the passed CU.  If a DWO file exists for this
CU, the caller is expected to pass it as a parameter.  That cutu_reader
constructor also ends up setting the language of the CU.  But because it
didn't read the DWO file, it didn't figure out the language is
language_ada, so it tries to set the language to the default,
language_minimal.

A question is: why do we end up trying to set the CU's language is this
context.  This is completely unrelated to what we're trying to do, that
is get the file names from the line table.  Setting the language is a
side-effect of just constructing a cutu_reader, which we need to look up
attributes in dw2_get_file_names_reader.  There are probably some
cleanups to be done here, to avoid doing useless work like looking up
and setting the CU's language when all we need is an object to help
reading the DIEs and attributes.  But that is future work.

The same cutu_reader constructor is used in
`dwarf2_per_cu::ensure_lang`.  Since this is the version of cutu_reader
that does not look up the DWO file, it will conclude that the language
is language_minimal and set that as the CU's language.  In other words,
`dwarf2_per_cu::ensure_lang` will get the language wrong, pretty ironic.

Fix this by using the other cutu_reader constructor in those two spots.
Pass `per_objfile->get_cu (this_cu)`, as the `existing_cu` parameter.  I
think this is necessary, because that constructor has an assert to check
that if `existing_cu` is nullptr, then there must not be an existing
`dwarf2_cu` in the per_objfile.

To avoid getting things wrong like this, I think that the second
cutu_reader constructor should be reserved for the spots that do pass a
non-nullptr dwo_file.  The only spot at the moment in
create_cus_hash_table, where we read multiple units from the same DWO
file.  In this context, I guess it makes sense for efficiency to get the
dwo_file once and pass it down to cutu_reader.  For that constructor,
make the parameters non-optional, add "non-nullptr" asserts, and update
the code to assume the passed values are not nullptr.

What I don't know is if this change is problematic thread-wise, if the
functions I have modified to use the other cutu_reader constructor can
be called concurrently in worker threads.  If so, I think it would be
problematic.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32742
Change-Id: I980d16875b9a43ab90e251504714d0d41165c7c8
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-07 21:53:11 -05:00
Tom Tromey
aab2ac34d7 Avoid excessive CU expansion on failed matches
PR symtab/31010 points out that something like "ptype INT" will expand
all CUs in a typical program.  The OP further points out that the
original patch for PR symtab/30520:

    https://sourceware.org/pipermail/gdb-patches/2024-January/205924.html

... did solve the problem, but the patch changed after (my) review and
reintroduced the bug.

In cooked_index_functions::expand_symtabs_matching, the final
component of a split name is compared with the entry's name using the
usual method of calling get_symbol_name_matcher.

This code iterates over languages and tries to split the original name
according to each style.  But, the Ada splitter uses the decoded name
-- "int".  This causes every C or C++ CU to be expanded.

Clearly this is wrong.  And, it seems to me that looping over
languages and trying to guess the splitting style for the input text
is probably bad.  However, fixing the problem is not so easy (again
due to Ada).  I've filed a follow-up bug, PR symtab/32733, for this.

Meanwhile, this patch changes the code to be closer to the
originally-submitted patch.  This works because the comparison is now
done between the full name and the "lookup_name_without_params"
object, which is a less adulterated variant of the original input.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31010
Tested-By: Simon Marchi <simon.marchi@efficios.com>
2025-03-07 17:15:20 -07:00
Simon Marchi
34177f1983 gdb/dwarf: move cooked_indexer to cooked-indexer.{h,c}
Move the cooked_indexer class declaration to a new cooked-indexer.h
file, and the implementation to cooked-indexer.c.

Change-Id: Ibff3b06045b2af65fa9516097acf732d7c2d9414
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-07 09:38:51 -05:00
Simon Marchi
c591185447 gdb/dwarf: move cooked_index_storage to cooked-index-storage.{h,c}
cooked_index_storage is currently declared in `cooked-index.h` and
implemented in `read.c`.  Move all that to new
`cooked-index-storage.{h,c}` files.

Change-Id: I2a07eb446d8a07b15c5664dfe01e3a820cdd45be
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-07 09:37:30 -05:00
Simon Marchi
d991cb7396 gdb/dwarf: move cutu_reader to read.h
In order to move some things outside of read.c, cutu_reader needs to be
in a header file.

Change-Id: Ib26d7949c55867848d109332caf2efb1a6e72923
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-07 09:37:30 -05:00
Tom Tromey
aa24bf2c05 Add support for hierarchical Ada names
In the near future, GNAT will start emitting DWARF names in a more
standard way -- specifically, the package structure will be indicated
by nested DW_TAG_module DIEs and a given entity will be nested in its
package and only have a simple name.

This patch changes gdb to understand this style of naming, while still
supporting the existing GNAT output.

A few special cases are needed.  I've commented them.

The name-computing code for the full DWARF reader is very complicated
-- much too complicated, in my opinion.  There are already several
bugs in bugzilla about this (search for "physname"... but there are
others as well), so I haven't filed any new ones.

When I started this project, I thought it would solve some memory
overuse issues we sometimes see from how the index-sharding code
interacts with the GNAT-specific post-pass.  However, to my surprise,
the Ada code in gdb relies on some details of symbol naming, and so
I've had to add code here to synthesize "linkage" names in some cases.
This is unfortunate, but I think can eventually be fixed; I will file
a bug to track this issue.
2025-03-06 14:17:18 -07:00
Tom Tromey
aab26529b3 Add "Ada linkage" mode to cooked_index_entry::full_name
Unfortunately, due to some details of how the Ada support in gdb
currently works, the DWARF reader will still have to synthesize some
"full name" entries after the cooked index has been constructed.

You can see one particular finding related to this in:

    https://sourceware.org/bugzilla/show_bug.cgi?id=32142

This patch adds a new flag to cooked_index_entry::full_name to enable
the construction of these names.

I hope to redo this part of the Ada support eventually, so that this
code can be removed and the full-name entries simply not created.
2025-03-06 14:17:18 -07:00
Tom Tromey
c70ac07a79 Store new Ada entries in cooked_index_shard::m_entries
handle_gnat_encoded_entry might create synthetic cooked index entries
for Ada packages.  These aren't currently kept in m_entries, but it
seems to me that they should be, particularly because a forthcoming
GNAT will emit explicit DW_TAG_module for these names -- with this
change, the indexes will be roughly equivalent regardless of which
compiler was used.
2025-03-06 14:17:18 -07:00
Tom Tromey
8cf79a0646 Handle DW_TAG_module for Ada
This updates read_module_type to turn DW_TAG_module into a
TYPE_CODE_NAMESPACE when the CU represents Ada code.

Note that the GNAT that generates this isn't generally available yet
and so this shouldn't have an impact on current code.
2025-03-06 14:17:18 -07:00
Tom Tromey
4a4a50517b Add "synthetic" marker for index entries
Currently, gdb will synthesize DW_TAG_module entries for Ada names.
These entries are treated specially by the index writer,

When GNAT starts emitting DW_TAG_module, the special case will be
incorrect, because there will be non-synthetic DW_TAG_module entries
in the index.

This patch arranges to mark the synthetic entries and changes the
index writer to follow.
2025-03-06 14:17:17 -07:00
Tom Tromey
e382ede5ea Use DW_TAG_module for Ada
In GCC we decided to use DW_TAG_module to represent Ada packages, so
make this same decision in gdb.  This also updates tag_matches_domain
to handle this case.
2025-03-06 14:17:17 -07:00
Tom Tromey
5fce64293a Use dwarf2_full_name when computing type names
This changes a few spots in the DWARF reader to use dwarf2_full_name
when computing the name of a type.  This gives the correct name when a
type is nested in a namespace.  This oddity probably wasn't noticed
before because some of the types in question are either normally
anonymous in C++ (e.g, array type) or do not appear in a namespace
(base type).
2025-03-06 14:17:17 -07:00
Simon Marchi
ebb283e4ae gdb/dwarf: remove unnecessary this-> in read.c
I like using `this->` when it's unclear that the method or field
accessed is within the current class, but when accessing a private
member prefixed with `m_`, it's unnecessary, as the prefix makes it
clear.  Remove some instances of it (some coming from the previous
patch, other pre-existing) to de-clutter the code a bit.

Change-Id: Ia83d0bce51d222fa3ac3d756d50170ec6ed12b94
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-06 11:39:00 -05:00
Simon Marchi
f5484e9b6c gdb/dwarf: make all fields of cutu_reader private
Make all fields of cutu_reader private, then add getters for whatever
needs to be accessed outside of cutu_reader.  This should help spot
what's used by cutu_reader itself, and what is used by others.

Change-Id: I71cb73fffa5d70cc9c7fc68bf74db937e84c2db1
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-06 11:39:00 -05:00
Simon Marchi
b8c80caf59 gdb/dwarf: pass dwarf2_cu instead of cutu_reader to two functions
These functions don't need to receive a cutu_reader, they only use it to
obtain the contained dwarf2_cu, so change them to accept a dwarf2_cu.
This helps reduce the creep of cutu_reader a little bit.

Change-Id: Iebb3c4697a4aec638b47423b3ac59077d4fa5090
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-06 11:39:00 -05:00
Simon Marchi
54333345d2 gdb/dwarf: move a bunch of DIE-reading functions to cutu_reader
With the hope of organizing things better and spotting patterns that
could lead to simplification, move all these functions to be methods of
cutu_reader.  At least, this gives a good picture of what the entry
points for DIE and attribute reading are, by looking at what methods are
public.

Right now, my vague understanding of cutu_reader is that it does 3
things:

 - it provides means to navigate and read the DIE tree, abstracting
   things like whether the real content is in a DWO file or not
 - it builds a dwarf2_cu object, for its own use but also for the use of
   the caller
 - it fills in missing details in the passed in dwarf2_per_cu

In the future, I'd like to separate those concerns.  I think that
cutu_reader could retain the first one of those concerns, while the
other two could be done by other classes or functions, perhaps using
cutu_reader under the hood.

Change-Id: I04e0d6c864bbc09c7071ac8e9493e1e54c093d68
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-06 11:39:00 -05:00
Simon Marchi
e9c7a91318 gdb/dwarf: add empty lines in cutu_reader::read_cutu_die_from_dwo comment
I find it much more readable this way, with one idea per paragraph.

Change-Id: Ib31b410867c8444e0f3200681881f54f1b8ebea8
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-06 11:39:00 -05:00
Simon Marchi
085002d0dc gdb/dwarf: make init_cu_die_reader a method of cutu_reader
init_cu_die_reader is only used inside cutu_reader, to initialize fields
of cutu_reader, so make it a private method.

Change-Id: Iaa80d4dbb8d0fa35bcac18ee70e147276874cc1b
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-06 11:39:00 -05:00
Simon Marchi
d1a5224cd3 gdb/dwarf: make read_cutu_die_from_dwo a method of cutu_reader
read_cutu_die_from_dwo is only used as a helper to cutu_reader, so make
it a private method of cutu_reader.

Remove the "result_reader" parameter, because it's always "this".

Change-Id: I7df6162137451c160f0e6bf3539569fcb2421eff
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-06 11:39:00 -05:00
Tom Tromey
9d3fbbd4c4 Use "::" as separator for Fortran in cooked index
This teaches cooked_index_entry::full_name that "::" is the separator
for Fortran.  I don't know enough Fortran to write a test case for
this.  However, a different series I am working on has a regression if
this patch is not applied.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-03-06 07:33:28 -07:00
Tom Tromey
6a739b5551 Inconsistent treatment of template parameters in DWARF reader
I noticed that if you hack some clean_restart calls into
paramless.exp, the test will fail.  That is, the test currently relies
on the desired CUs already being expanded when trying to set a
breakpoint -- which is clearly a bug, the CU expansion state should
not affect "break".

I tracked this down to incorrect construction of a lookup_name_info in
cooked_index_functions::expand_symtabs_matching.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32510
Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-03-05 10:12:41 -07:00
Simon Marchi
93258b5fa6 gdb/dwarf: store dwo_file_up in dwo_file_set
Heap-allocated dwo_file objects, stored in dwarf2_per_bfd::dwo_files,
are never freed.  They are created in one of the
create_dwo_unit_in_dwp_* or lookup_dwo_cutu functions.  I confirmed this
by running:

  $ make check TESTS="gdb.cp/anon-ns.exp" RUNTESTFLAGS="--target_board=fission-dwp"
  $ ./gdb -q -nx --data-directory=data-directory testsuite/outputs/gdb.cp/anon-ns/anon-ns -ex "p main" -ex "file" -batch

... and checking the ASan leak report.  I also debugged this invocation
of GDB, placed a breakpoint on ~dwo_file, and didn't see any hit.

Change the dwo_file set to hold dwo_file_up objects.  When the
dwarf2_per_bfd object gets destroyed, dwo_file objects will
automatically get destroyed.  With this change, I see the related leaks
disappear in the ASan leak report, and my ~dwo_file breakpoint gets hit
when debugging GDB.

Change-Id: Icb38539c3f9e553f3625c625a00fc63dd6e9f3c5
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-05 11:58:31 -05:00
Simon Marchi
76ee822b86 gdb/dwarf: make dwarf2_per_bfd::dwo_files a gdb::unordered_set
Change the dwarf2_per_bfd::dwo_files htab to a gdb::unordered_set.

No behavior change expected, except maybe the failure case in
lookup_dwo_cutu.  If open_and_init_dwo_file returns nullptr, the
previous code would leave the slot value empty (nullptr).  Is this
legit?  With the new hash table, the only thing we can do really is not
attempt to insert the nullptr value.

Change-Id: I63992f388b1197e696ded4ea483634e8ae67fce4
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-05 11:58:31 -05:00
Simon Marchi
f99ba1e18d gdb/dwarf: change htabs holding dwo_unit objects to gdb::unordered_set
Change a few occurences of htabs holding `dwo_unit *` values, using
their signature as identity, to gdb::unordered_set.
allocate_dwo_unit_table and allocate_dwp_loaded_cutus_table appeared to
create hash tables with identical behavior, so they both use the same
set type now.

The only expected change in behavior is that when there are multiple
units with the same signature, we will now keep the unit previously in
the set, rather than overwriting it.  But this seems ok, as it's a case
of bad DWARF.

Also, in the complaint in create_debug_type_hash_table, I think we
previously erroneously printed the same sect_off twice.

Change-Id: I57739977735ee1fd5c7b754107f5624f0621baa5
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-05 11:58:31 -05:00
Simon Marchi
a433a6f8bc gdb/dwarf: remove unused local variable in create_debug_type_hash_table
Change-Id: I40679fbe32a8a1a9cced085532c83f06affc294c
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-05 11:58:31 -05:00
Simon Marchi
3791225096 gdb/dwarf: remove unnecessary parameters to create_{cus,debug_type}_hash_table
In create_cus_hash_table, we can get the section and hash table from the
dwo_file directly.

In create_debug_type_hash_table, we can get the hash table from the
dwo_file directly - the section varies.

Change-Id: I1d5ef49df98fe2620e12b83484b28cd7398f24ae
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-05 11:58:31 -05:00
Simon Marchi
559e8b4a19 gdb/dwarf: remove die_reader_specs
die_reader_specs is a relic of some past design, today it only serves as
(useless) a base class for cutu_reader.  Remove it and move all its
fields to cutu_reader.

Change-Id: I5d55018eb8c6e0b828ef5d2f6d09b2047d1a5912
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-05 11:58:31 -05:00
Simon Marchi
e6170d789a gdb/dwarf: remove unnecessary parameter of create_cus_hash_table
We can use `cu->per_objfile` instead of passing down a
dwarf2_per_objfile explicitly.

Change-Id: Ie1fd93d9e7a74d09b857f1f0909d7441b79ed893
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-05 11:58:31 -05:00
Simon Marchi
20c09c608f gdb/dwarf: remove unnecessary local variable in dw2_get_file_names_reader
It seems like the lh_cu variable is not necessary, we can just use
this_cu.

Change-Id: Ic2ed6ee82faf1fb5d340cd92dc8ef15434b20cb8
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-05 11:58:31 -05:00
Tom Tromey
4ad3a0115d Create dwarf2/parent-map.c
This creates a new file, dwarf2/parent-map.c, to hold some code
related to parent maps.  This helps shrink read.c a bit.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-03-05 08:03:23 -07:00
Tom Tromey
c3bdc2348f Dump debug names index
This changes the .debug_names reader to dump the contents of the
index.  This follows what the cooked index does, and also fixes a
couple of test failures when run with the debug-names board:
forward-spec-inter-cu.exp and backward-spec-inter-cu.exp.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-03-05 08:00:07 -07:00
Simon Marchi
6625c32600 gdb/dwarf: pass is_dwz to dwarf2_per_cu constructor
It is always known at construction time whether a dwarf2_per_cu is
built to represent a unit from a dwz file or not, so pass that
information through the constructor.

Change-Id: I278c1894ed606451aad02e830085190bb724c473
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-04 10:41:54 -05:00
Simon Marchi
66195fe109 gdb/dwarf: make dwarf2_get_dwz_file a method of dwarf2_per_bfd
dwarf2_get_dwz_file looks more or less like a simple getter of
dwarf2_per_bfd::dwz_file, so make it into a method.

I typically avoid the `get_` prefix for getters, but that would conflict
with the field name here.

Change-Id: Idd0d5b1bd3813babf438b20aac514b19c77cfc18
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-04 10:41:54 -05:00
Simon Marchi
121efb593c gdb/dwarf: remove create_cu_from_index_list
I noticed that create_cu_from_index_list is only used in
read-gdb-index.c, so I started by moving it there.  But given that this
function is use at only one spot and doesn't do much, I opted to inline
its code in the caller instead.

Change-Id: Iebe0dc20d345fa70a2f11aa9ff1a04fe26a31407
Approved-By: Tom Tromey <tom@tromey.com>
2025-03-04 10:41:54 -05:00
Tom Tromey
e578bccf57 Obvious comment fix in cooked-index.h
I noticed that cooked-index.h still refers to a vector of parent maps,
but the code itself actually uses a parent_map here.
2025-03-03 18:35:41 -07:00
Tom Tromey
268c8bda25 Add language to type unit in debug-names-tu.exp.tcl
I think debug-names-tu.exp.tcl only passes by accident -- the type
unit does not have a language, which gdb essentially requires.

This isn't noticeable right now because the type unit in question is
expanded in one phase and then the symbol found in another.  However,
I'm working on a series that would regress this.

This patch partially fixes the problem by correcting the test case,
adding the language to the TU.

Hoewver, it then goes a bit further and arranges for this information
not to be written to .debug_names.  Whether or not a type should be
considered "static" seems like something that is purely internal to
gdb, so this patch has the entry-creation function apply the
appropriate transform.

It also may make sense to change the "debug_names" proc in the test
suite to process attributes more like the ordinary "cu" proc does.
2025-03-03 14:16:44 -07:00