@@ -1610,10 +1610,13 @@ static int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *,
values. */
enum pc_bounds_kind
{
- /* No valid combination of DW_AT_low_pc, DW_AT_high_pc or DW_AT_ranges
- was found. */
+ /* No attribute DW_AT_low_pc, DW_AT_high_pc or DW_AT_ranges was found. */
pc_bounds_not_present,
+ /* Some of the attributes DW_AT_low_pc, DW_AT_high_pc or DW_AT_ranges
+ were present but they do not form a valid range of PC addresses. */
+ pc_bounds_invalid,
+
/* Discontiguous range was found - that is DW_AT_ranges was found. */
pc_bounds_ranges,
@@ -6018,7 +6021,7 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
first_die = load_partial_dies (reader, info_ptr, 1);
scan_partial_symbols (first_die, &lowpc, &highpc,
- has_pc_info == pc_bounds_not_present, cu);
+ has_pc_info <= pc_bounds_invalid, cu);
/* If we didn't find a lowpc, set it to highpc to avoid
complaints from `maint check'. */
@@ -6027,7 +6030,7 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
/* If the compilation unit didn't have an explicit address range,
then use the information extracted from its child dies. */
- if (has_pc_info == pc_bounds_not_present)
+ if (has_pc_info <= pc_bounds_invalid)
{
best_lowpc = lowpc;
best_highpc = highpc;
@@ -11389,7 +11392,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
/* Ignore functions with missing or invalid low and high pc attributes. */
if (dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL)
- == pc_bounds_not_present)
+ <= pc_bounds_invalid)
{
attr = dwarf2_attr (die, DW_AT_external, cu);
if (!attr || !DW_UNSND (attr))
@@ -11551,9 +11554,19 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
as multiple lexical blocks? Handling children in a sane way would
be nasty. Might be easier to properly extend generic blocks to
describe ranges. */
- if (dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL)
- == pc_bounds_not_present)
- return;
+ switch (dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL))
+ {
+ case pc_bounds_not_present:
+ /* DW_TAG_lexical_block has no attributes, process its children as if
+ there was no wrapping by that DW_TAG_lexical_block.
+ GCC does no longer produces such DWARF since GCC r224161. */
+ for (child_die = die->child; child_die && child_die->tag;
+ child_die = sibling_die (child_die))
+ process_die (child_die, cu);
+ return;
+ case pc_bounds_invalid:
+ return;
+ }
lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
highpc = gdbarch_adjust_dwarf2_addr (gdbarch, highpc + baseaddr);
@@ -11763,7 +11776,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
/* DW_AT_entry_pc should be preferred. */
if (dwarf2_get_pc_bounds (target_die, &lowpc, NULL, target_cu, NULL)
- == pc_bounds_not_present)
+ <= pc_bounds_invalid)
complaint (&symfile_complaints,
_("DW_AT_GNU_call_site_target target DIE has invalid "
"low pc, for referencing DIE 0x%x [in module %s]"),
@@ -12040,7 +12053,7 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
/* Get low and high pc attributes from a die. See enum pc_bounds_kind
definition for the return value. *LOWPC and *HIGHPC are set iff
- pc_bounds_not_present is not returned. */
+ neither pc_bounds_not_present nor pc_bounds_invalid are returned. */
static enum pc_bounds_kind
dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
@@ -12051,7 +12064,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
struct attribute *attr_high;
CORE_ADDR low = 0;
CORE_ADDR high = 0;
- enum pc_bounds_kind ret = pc_bounds_not_present;
+ enum pc_bounds_kind ret;
attr_high = dwarf2_attr (die, DW_AT_high_pc, cu);
if (attr_high)
@@ -12066,7 +12079,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
}
else
/* Found high w/o low attribute. */
- return pc_bounds_not_present;
+ return pc_bounds_invalid;
/* Found consecutive range of addresses. */
ret = pc_bounds_high_low;
@@ -12088,15 +12101,17 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
/* Value of the DW_AT_ranges attribute is the offset in the
.debug_ranges section. */
if (!dwarf2_ranges_read (ranges_offset, &low, &high, cu, pst))
- return pc_bounds_not_present;
+ return pc_bounds_invalid;
/* Found discontinuous range of addresses. */
ret = pc_bounds_ranges;
}
+ else
+ return pc_bounds_not_present;
}
/* read_partial_die has also the strict LOW < HIGH requirement. */
if (high <= low)
- return pc_bounds_not_present;
+ return pc_bounds_invalid;
/* When using the GNU linker, .gnu.linkonce. sections are used to
eliminate duplicate copies of functions and vtables and such.
@@ -12107,7 +12122,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
If this is a discarded function, mark the pc bounds as invalid,
so that GDB will ignore it. */
if (low == 0 && !dwarf2_per_objfile->has_section_at_zero)
- return pc_bounds_not_present;
+ return pc_bounds_invalid;
*lowpc = low;
if (highpc)
@@ -12128,8 +12143,7 @@ dwarf2_get_subprogram_pc_bounds (struct die_info *die,
CORE_ADDR low, high;
struct die_info *child = die->child;
- if (dwarf2_get_pc_bounds (die, &low, &high, cu, NULL)
- != pc_bounds_not_present)
+ if (dwarf2_get_pc_bounds (die, &low, &high, cu, NULL) >= pc_bounds_ranges)
{
*lowpc = min (*lowpc, low);
*highpc = max (*highpc, high);
@@ -12167,7 +12181,7 @@ get_scope_pc_bounds (struct die_info *die,
CORE_ADDR current_low, current_high;
if (dwarf2_get_pc_bounds (die, ¤t_low, ¤t_high, cu, NULL)
- != pc_bounds_not_present)
+ >= pc_bounds_ranges)
{
best_low = current_low;
best_high = current_high;
@@ -23,20 +23,14 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug optimize=-O2}]
clean_restart ${testfile}
-# GCC currently is missing a DW_AT_origin attribute in one of the
-# lexical blocks, preventing GDB from creating a symbol for the
-# subprogram we want to break on.
-setup_xfail "*-*-*"
gdb_test "break foo_o224_021.child1.child2" \
"Breakpoint \[0-9\]+ at.*: file .*foo_o224_021.adb, line \[0-9\]+."
gdb_run_cmd
-setup_xfail "*-*-*"
gdb_test "" \
"Breakpoint $decimal, foo_o224_021\\.child1\\.child2 \\(s=\\.\\.\\.\\).*"
set opt_addr_in "($hex in)?"
-setup_xfail "*-*-*"
gdb_test "bt" \
[multi_line "#0 +$opt_addr_in +foo_o224_021\\.child1\\.child2 \\(s=\\.\\.\\.\\).*" \
"#1 +$opt_addr_in +foo_o224_021\\.child1 \\(\\).*" \
@@ -0,0 +1,70 @@
+# Copyright 2016 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.
+if {![dwarf2_support]} {
+ return 0
+}
+
+standard_testfile .S main.c
+
+# Make some DWARF for the test.
+set asm_file [standard_output_file $srcfile]
+Dwarf::assemble $asm_file {
+ cu {} {
+ compile_unit {
+ {low_pc [gdb_target_symbol main] DW_FORM_addr}
+ {high_pc [gdb_target_symbol main]+0x10000 DW_FORM_addr}
+ } {
+ declare_labels integer_label
+
+ integer_label: DW_TAG_base_type {
+ {DW_AT_byte_size 4 DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_signed}
+ {DW_AT_name integer}
+ }
+
+ DW_TAG_subprogram {
+ {name main}
+ {DW_AT_external 1 flag}
+ {low_pc [gdb_target_symbol main] DW_FORM_addr}
+ {high_pc [gdb_target_symbol main]+0x10000 DW_FORM_addr}
+ } {
+ DW_TAG_lexical_block {
+ } {
+ DW_TAG_variable {
+ {DW_AT_name testvar}
+ {DW_AT_type :$integer_label}
+ {DW_AT_external 1 flag}
+ {DW_AT_location {
+ DW_OP_addr [gdb_target_symbol main]
+ } SPECIAL_expr}
+ }
+ }
+ }
+ }
+ }
+}
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} \
+ [list $srcfile2 $asm_file] {nodebug}] } {
+ return -1
+}
+
+runto_main
+
+# FAILing GDB did print: No symbol "testvar" in current context.
+gdb_test "p testvar" { = -?[0-9]+}