void expand_all_symtabs (struct objfile *objfile) override;
+ /* A helper function that finds the per-cu object from an "adjusted"
+ PC -- a PC with the base text offset removed. */
+ virtual dwarf2_per_cu_data *find_per_cu (dwarf2_per_bfd *per_bfd,
+ CORE_ADDR adjusted_pc);
+
struct compunit_symtab *find_pc_sect_compunit_symtab
(struct objfile *objfile, struct bound_minimal_symbol msymbol,
- CORE_ADDR pc, struct obj_section *section, int warn_if_readin) override;
+ CORE_ADDR pc, struct obj_section *section, int warn_if_readin)
+ override final;
struct compunit_symtab *find_compunit_symtab_by_address
(struct objfile *objfile, CORE_ADDR address) override
return NULL;
}
+dwarf2_per_cu_data *
+dwarf2_base_index_functions::find_per_cu (dwarf2_per_bfd *per_bfd,
+ CORE_ADDR adjusted_pc)
+{
+ if (per_bfd->index_addrmap == nullptr)
+ return nullptr;
+ return (struct dwarf2_per_cu_data *) addrmap_find (per_bfd->index_addrmap,
+ adjusted_pc);
+}
+
struct compunit_symtab *
dwarf2_base_index_functions::find_pc_sect_compunit_symtab
(struct objfile *objfile,
struct obj_section *section,
int warn_if_readin)
{
- struct dwarf2_per_cu_data *data;
struct compunit_symtab *result;
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
- if (per_objfile->per_bfd->index_addrmap == nullptr)
- return NULL;
CORE_ADDR baseaddr = objfile->text_section_offset ();
- data = ((struct dwarf2_per_cu_data *)
- addrmap_find (per_objfile->per_bfd->index_addrmap,
- pc - baseaddr));
- if (!data)
- return NULL;
+ struct dwarf2_per_cu_data *data = find_per_cu (per_objfile->per_bfd,
+ pc - baseaddr);
+ if (data == nullptr)
+ return nullptr;
if (warn_if_readin && per_objfile->symtab_set_p (data))
warning (_("(Internal error: pc %s in read in CU, but not in symtab.)"),
result = recursively_find_pc_sect_compunit_symtab
(dw2_instantiate_symtab (data, per_objfile, false), pc);
- gdb_assert (result != NULL);
+ if (warn_if_readin && result == nullptr)
+ warning (_("(Error: pc %s in address map, but not in symtab.)"),
+ paddress (objfile->arch (), pc));
+
return result;
}
struct cooked_index_functions : public dwarf2_base_index_functions
{
- struct compunit_symtab *find_pc_sect_compunit_symtab
- (struct objfile *objfile, struct bound_minimal_symbol msymbol,
- CORE_ADDR pc, struct obj_section *section, int warn_if_readin) override;
+ dwarf2_per_cu_data *find_per_cu (dwarf2_per_bfd *per_bfd,
+ CORE_ADDR adjusted_pc) override;
struct compunit_symtab *find_compunit_symtab_by_address
(struct objfile *objfile, CORE_ADDR address) override;
}
};
-struct compunit_symtab *
-cooked_index_functions::find_pc_sect_compunit_symtab
- (struct objfile *objfile,
- struct bound_minimal_symbol msymbol,
- CORE_ADDR pc,
- struct obj_section *section,
- int warn_if_readin)
+dwarf2_per_cu_data *
+cooked_index_functions::find_per_cu (dwarf2_per_bfd *per_bfd,
+ CORE_ADDR adjusted_pc)
{
- dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
- if (per_objfile->per_bfd->index_table == nullptr)
- return nullptr;
-
- CORE_ADDR baseaddr = objfile->text_section_offset ();
cooked_index_vector *table
= (static_cast<cooked_index_vector *>
- (per_objfile->per_bfd->index_table.get ()));
- dwarf2_per_cu_data *per_cu = table->lookup (pc - baseaddr);
- if (per_cu == nullptr)
+ (per_bfd->index_table.get ()));
+ if (table == nullptr)
return nullptr;
-
- if (warn_if_readin && per_objfile->symtab_set_p (per_cu))
- warning (_("(Internal error: pc %s in read in CU, but not in symtab.)"),
- paddress (objfile->arch (), pc));
-
- compunit_symtab *result = (recursively_find_pc_sect_compunit_symtab
- (dw2_instantiate_symtab (per_cu, per_objfile,
- false),
- pc));
- gdb_assert (result != nullptr);
- return result;
+ return table->lookup (adjusted_pc);
}
struct compunit_symtab *
--- /dev/null
+# Copyright (C) 2022 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/>.
+
+# Regression test for the situation where aranges covers an address
+# but the CU does not.
+
+load_lib "dwarf.exp"
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if {![dwarf2_support]} {
+ return 0
+}
+
+standard_testfile main.c cu-no-addrs.S
+
+lassign [function_range main ${srcdir}/${subdir}/${srcfile}] \
+ main_start main_length
+
+# Make some DWARF for the test.
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+ global main_start main_length
+
+ cu {label cu_start} {
+ # The PC range here is intentionally empty -- this was the
+ # trigger for the bug.
+ compile_unit {
+ {language @DW_LANG_C}
+ {DW_AT_low_pc $main_start DW_FORM_addr}
+ {DW_AT_high_pc $main_start DW_FORM_addr}
+ } {
+ DW_TAG_subprogram {
+ {DW_AT_name "main"}
+ {DW_AT_low_pc $main_start DW_FORM_addr}
+ }
+ }
+ }
+
+ aranges {} cu_start {
+ arange {} $main_start $main_length
+ }
+}
+
+if {[prepare_for_testing "failed to prepare" ${testfile} \
+ [list $srcfile $asm_file] {nodebug}]} {
+ return -1
+}
+
+gdb_test "break *$main_start" ".*Breakpoint $decimal at $hex" \
+ "set breakpoint at main address"