diff options
author | Tom de Vries <tdevries@suse.de> | 2024-10-29 10:08:04 +0100 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2024-10-29 10:08:04 +0100 |
commit | 80ac47851105702689004e07952ab6a4c04062b0 (patch) | |
tree | 1746aa8c0b6ff18e7c2ba45cb37a62ccf5521847 | |
parent | b0fdcd470653d10612aad561cc06098d3fa5ba17 (diff) | |
download | binutils-80ac47851105702689004e07952ab6a4c04062b0.zip binutils-80ac47851105702689004e07952ab6a4c04062b0.tar.gz binutils-80ac47851105702689004e07952ab6a4c04062b0.tar.bz2 |
[gdb/symtab] Handle multiple .debug_info sections
When compiling dw2-multiple-debug-info.c using -gdwarf-5
-fdebug-types-section, we end with two .debug_info sections in the object
file:
...
$ g++ gdb.dwarf2/dw2-multiple-debug-info.c -c -g \
-gdwarf-5 \
-fdebug-types-section
$ readelf -WS dw2-multiple-debug-info.o | grep -v RELA | grep .debug_info
[10] .debug_info PROGBITS 0 000128 0000cd 00 GC 0 0 8
[12] .debug_info PROGBITS 0 0001f8 0000ad 00 C 0 0 8
...
One of them contains the CU for dw2-multiple-debug-info.c, the other contains
the TU for the type of variable a.
When trying to print the type of variable a, we get:
...
$ gdb -q -batch dw2-multiple-debug-info.o -ex "ptype a"
'a' has unknown type; cast it to its declared type
...
because the TU hasn't been read.
Fix this by adding support for reading multiple .debug_info sections, similar
to how that is done for multiple .debug_types sections, getting us instead:
...
$ gdb -q -batch dw2-multiple-debug-info.o -ex "ptype a"
type = class sp1::A {
...
}
...
Tested on x86_64-linux.
PR symtab/32223
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32223
-rw-r--r-- | gdb/dwarf2/index-write.c | 3 | ||||
-rw-r--r-- | gdb/dwarf2/read-debug-names.c | 11 | ||||
-rw-r--r-- | gdb/dwarf2/read-gdb-index.c | 11 | ||||
-rw-r--r-- | gdb/dwarf2/read.c | 25 | ||||
-rw-r--r-- | gdb/dwarf2/read.h | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/dw2-multiple-debug-info.c | 40 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/dw2-multiple-debug-info.exp | 36 |
7 files changed, 109 insertions, 19 deletions
diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c index c01e274..1008d19 100644 --- a/gdb/dwarf2/index-write.c +++ b/gdb/dwarf2/index-write.c @@ -1548,6 +1548,9 @@ write_dwarf_index (dwarf2_per_bfd *per_bfd, const char *dir, if (table == nullptr) error (_("Cannot use an index to create the index")); + if (per_bfd->infos.size () > 1) + error (_("Cannot make an index when the file has multiple .debug_info" + " sections")); if (per_bfd->types.size () > 1) error (_("Cannot make an index when the file has multiple .debug_types sections")); diff --git a/gdb/dwarf2/read-debug-names.c b/gdb/dwarf2/read-debug-names.c index eebe5a9..e6f1fce 100644 --- a/gdb/dwarf2/read-debug-names.c +++ b/gdb/dwarf2/read-debug-names.c @@ -690,7 +690,7 @@ check_cus_from_debug_names (dwarf2_per_bfd *per_bfd, const mapped_debug_names_reader &map, const mapped_debug_names_reader &dwz_map) { - if (!check_cus_from_debug_names_list (per_bfd, map, per_bfd->info, + if (!check_cus_from_debug_names_list (per_bfd, map, per_bfd->infos[0], false /* is_dwz */)) return false; @@ -742,15 +742,16 @@ do_dwarf2_read_debug_names (dwarf2_per_objfile *per_objfile) if (map.tu_count != 0) { - /* We can only handle a single .debug_types when we have an - index. */ - if (per_bfd->types.size () > 1) + /* We can only handle a single .debug_info and .debug_types when we have + an index. */ + if (per_bfd->infos.size () > 1 + || per_bfd->types.size () > 1) return false; dwarf2_section_info *section = (per_bfd->types.size () == 1 ? &per_bfd->types[0] - : &per_bfd->info); + : &per_bfd->infos[0]); if (!check_signatured_type_table_from_debug_names (per_objfile, map, section)) diff --git a/gdb/dwarf2/read-gdb-index.c b/gdb/dwarf2/read-gdb-index.c index 701cdec..c0a33a0 100644 --- a/gdb/dwarf2/read-gdb-index.c +++ b/gdb/dwarf2/read-gdb-index.c @@ -497,7 +497,7 @@ create_cus_from_gdb_index (dwarf2_per_bfd *per_bfd, per_bfd->all_units.reserve ((cu_list_elements + dwz_elements) / 2); create_cus_from_gdb_index_list (per_bfd, cu_list, cu_list_elements, - &per_bfd->info, 0); + &per_bfd->infos[0], 0); if (dwz_elements == 0) return; @@ -692,9 +692,10 @@ dwarf2_read_gdb_index if (types_list_elements) { - /* We can only handle a single .debug_types when we have an - index. */ - if (per_bfd->types.size () > 1) + /* We can only handle a single .debug_info and .debug_types when we have + an index. */ + if (per_bfd->infos.size () > 1 + || per_bfd->types.size () > 1) { per_bfd->all_units.clear (); return 0; @@ -703,7 +704,7 @@ dwarf2_read_gdb_index dwarf2_section_info *section = (per_bfd->types.size () == 1 ? &per_bfd->types[0] - : &per_bfd->info); + : &per_bfd->infos[0]); create_signatured_type_table_from_gdb_index (per_bfd, section, types_list, types_list_elements); diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 6ac6f7c..2a29b84 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -1392,8 +1392,11 @@ dwarf2_has_info (struct objfile *objfile, per_objfile = dwarf2_objfile_data_key.emplace (objfile, objfile, per_bfd); } - const bool has_info = (!per_objfile->per_bfd->info.is_virtual - && per_objfile->per_bfd->info.s.section != nullptr + /* Virtual sections are created from DWP files. It's not clear those + can occur here, so perhaps the is_virtual checks here are dead code. */ + const bool has_info = (!per_objfile->per_bfd->infos.empty () + && !per_objfile->per_bfd->infos[0].is_virtual + && per_objfile->per_bfd->infos[0].s.section != nullptr && !per_objfile->per_bfd->abbrev.is_virtual && per_objfile->per_bfd->abbrev.s.section != nullptr); @@ -1436,8 +1439,11 @@ dwarf2_per_bfd::locate_sections (bfd *abfd, asection *sectp, } else if (names.info.matches (sectp->name)) { - this->info.s.section = sectp; - this->info.size = bfd_section_size (sectp); + struct dwarf2_section_info info_section; + memset (&info_section, 0, sizeof (info_section)); + info_section.s.section = sectp; + info_section.size = bfd_section_size (sectp); + this->infos.push_back (info_section); } else if (names.abbrev.matches (sectp->name)) { @@ -1585,7 +1591,9 @@ dwarf2_get_section_info (struct objfile *objfile, void dwarf2_per_bfd::map_info_sections (struct objfile *objfile) { - info.read (objfile); + for (auto §ion : infos) + section.read (objfile); + abbrev.read (objfile); line.read (objfile); str.read (objfile); @@ -5134,9 +5142,10 @@ create_all_units (dwarf2_per_objfile *per_objfile) htab_up types_htab; gdb_assert (per_objfile->per_bfd->all_units.empty ()); - read_comp_units_from_section (per_objfile, &per_objfile->per_bfd->info, - &per_objfile->per_bfd->abbrev, 0, - types_htab, rcuh_kind::COMPILE); + for (dwarf2_section_info §ion : per_objfile->per_bfd->infos) + read_comp_units_from_section (per_objfile, §ion, + &per_objfile->per_bfd->abbrev, 0, + types_htab, rcuh_kind::COMPILE); for (dwarf2_section_info §ion : per_objfile->per_bfd->types) read_comp_units_from_section (per_objfile, §ion, &per_objfile->per_bfd->abbrev, 0, diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h index 728f2b5..6637483 100644 --- a/gdb/dwarf2/read.h +++ b/gdb/dwarf2/read.h @@ -468,7 +468,7 @@ public: the objfile obstack. */ auto_obstack obstack; - dwarf2_section_info info {}; + std::vector<dwarf2_section_info> infos; dwarf2_section_info abbrev {}; dwarf2_section_info line {}; dwarf2_section_info loc {}; diff --git a/gdb/testsuite/gdb.dwarf2/dw2-multiple-debug-info.c b/gdb/testsuite/gdb.dwarf2/dw2-multiple-debug-info.c new file mode 100644 index 0000000..5370a43 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-multiple-debug-info.c @@ -0,0 +1,40 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +namespace sp1 { + class A { + int i; + const int c1 = 1; + const int c2 = 2; + const int c3 = 3; + const int c4 = 4; + const int c5 = 5; + const int c6 = 6; + const int c7 = 7; + const int c8 = 8; + const int c9 = 9; + const int c10 = 10; + }; +} + +sp1::A a; + +int +main (void) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.dwarf2/dw2-multiple-debug-info.exp b/gdb/testsuite/gdb.dwarf2/dw2-multiple-debug-info.exp new file mode 100644 index 0000000..957f41f --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-multiple-debug-info.exp @@ -0,0 +1,36 @@ +# Copyright 2024 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +require dwarf2_support + +standard_testfile .c + +set opts {} +lappend opts debug +lappend opts dwarf5 +lappend opts c++ +lappend opts additional_flags=-fdebug-types-section + +if { [gdb_compile "$srcdir/$subdir/$srcfile" "$binfile" object \ + $opts] != "" } { + return -1 +} + +clean_restart $binfile + +gdb_test "ptype a" "type = class sp1::A .*" |