From 05caa1d236440cd8967f8804be8dbcf27fb490b6 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 27 Mar 2019 13:21:24 -0600 Subject: [PATCH] Handle DW_AT_ranges when reading partial symtabs add_partial_subprogram does not handle DW_AT_ranges, while the full symtab reader does. This can lead to discrepancies where a function is not put into a partial symtab, and so is not available to "break" and the like -- but is available if the full symtab has somehow been read. This patch fixes the bug by arranging to read DW_AT_ranges when reading partial DIEs. This is PR symtab/23331. The new test case is derived from dw2-ranges-func.exp, which is why I kept the copyright dates. gdb/ChangeLog 2019-04-01 Tom Tromey PR symtab/23331: * dwarf2read.c (partial_die_info::read): Handle DW_AT_ranges. gdb/testsuite/ChangeLog 2019-04-01 Tom Tromey PR symtab/23331: * gdb.dwarf2/dw2-ranges-main.c: New file. * gdb.dwarf2/dw2-ranges-psym.c: New file. * gdb.dwarf2/dw2-ranges-psym.exp: New file. --- gdb/ChangeLog | 5 + gdb/dwarf2read.c | 19 ++++ gdb/testsuite/ChangeLog | 7 ++ gdb/testsuite/gdb.dwarf2/dw2-ranges-main.c | 19 ++++ gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.c | 46 +++++++++ gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.exp | 138 +++++++++++++++++++++++++++ 6 files changed, 234 insertions(+) create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-ranges-main.c create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.c create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.exp diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3de5992..f3f30b1 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2019-04-01 Tom Tromey + + PR symtab/23331: + * dwarf2read.c (partial_die_info::read): Handle DW_AT_ranges. + 2019-04-01 Sergio Durigan Junior Pedro Alves diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 658c862..a5e953b 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -18751,6 +18751,25 @@ partial_die_info::read (const struct die_reader_specs *reader, main_subprogram = DW_UNSND (&attr); break; + case DW_AT_ranges: + { + /* It would be nice to reuse dwarf2_get_pc_bounds here, + but that requires a full DIE, so instead we just + reimplement it. */ + int need_ranges_base = tag != DW_TAG_compile_unit; + unsigned int ranges_offset = (DW_UNSND (&attr) + + (need_ranges_base + ? cu->ranges_base + : 0)); + + /* Value of the DW_AT_ranges attribute is the offset in the + .debug_ranges section. */ + if (dwarf2_ranges_read (ranges_offset, &lowpc, &highpc, cu, + nullptr)) + has_pc_info = 1; + } + break; + default: break; } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 75bb6c6..b429149 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-04-01 Tom Tromey + + PR symtab/23331: + * gdb.dwarf2/dw2-ranges-main.c: New file. + * gdb.dwarf2/dw2-ranges-psym.c: New file. + * gdb.dwarf2/dw2-ranges-psym.exp: New file. + 2019-03-30 Simon Marchi * gdb.base/default.exp: Add values for $_gdb_major and diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ranges-main.c b/gdb/testsuite/gdb.dwarf2/dw2-ranges-main.c new file mode 100644 index 0000000..35a4d4c --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-ranges-main.c @@ -0,0 +1,19 @@ +/* Copyright 2019 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 . */ + +int main () +{ + return 0; +} diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.c b/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.c new file mode 100644 index 0000000..7d0408a --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.c @@ -0,0 +1,46 @@ +/* Copyright 2018-2019 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 . */ + +volatile int e = 0; + +void +baz (void) +{ + asm ("baz_label: .globl baz_label"); +} /* baz end */ + +void +foo_low (void) +{ /* foo_low prologue */ + asm ("foo_low_label: .globl foo_low_label"); + baz (); /* foo_low baz call */ + asm ("foo_low_label2: .globl foo_low_label2"); +} /* foo_low end */ + +void +bar (void) +{ + asm ("bar_label: .globl bar_label"); +} /* bar end */ + +void +foo (void) +{ /* foo prologue */ + asm ("foo_label: .globl foo_label"); + bar (); /* foo bar call */ + asm ("foo_label2: .globl foo_label2"); + if (e) foo_low (); /* foo foo_low call */ + asm ("foo_label3: .globl foo_label3"); +} /* foo end */ diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.exp b/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.exp new file mode 100644 index 0000000..0e9acbf --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.exp @@ -0,0 +1,138 @@ +# Copyright 2018-2019 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 . + +load_lib dwarf.exp + +# Test that psymbols are made when DW_AT_ranges is used. + +# This test can only be run on targets which support DWARF-2 and use gas. +if {![dwarf2_support]} { + unsupported "dwarf2 support required for this test" + return 0 +} + +if [get_compiler_info] { + return -1 +} +if !$gcc_compiled { + unsupported "gcc required for this test" + return 0 +} + +standard_testfile dw2-ranges-main.c dw2-ranges-psym.c dw2-ranges-psym-dw.S + +# We need to know the size of integer and address types in order to +# write some of the debugging info we'd like to generate. +# +# For that, we ask GDB by debugging our test program. Any program +# would do, but since we already have it specifically for this +# testcase, might as well use that. + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + [list ${srcfile} ${srcfile2}]] } { + return -1 +} + +set asm_file [standard_output_file $srcfile3] +Dwarf::assemble $asm_file { + global srcdir subdir srcfile srcfile2 + declare_labels integer_label volatile_label func_ranges_label cu_ranges_label + set int_size [get_sizeof "int" 4] + + # Find start address and length for our functions. + set sources [list ${srcdir}/${subdir}/$srcfile ${srcdir}/${subdir}/$srcfile2] + + lassign [function_range foo $sources] \ + foo_start foo_len + set foo_end "$foo_start + $foo_len" + + lassign [function_range foo_low $sources] \ + foo_low_start foo_low_len + set foo_low_end "$foo_low_start + $foo_low_len" + + lassign [function_range bar $sources] \ + bar_start bar_len + set bar_end "$bar_start + $bar_len" + + lassign [function_range baz $sources] \ + baz_start baz_len + set baz_end "$baz_start + $baz_len" + + cu {} { + compile_unit { + {language @DW_LANG_C} + {name dw-ranges-psym.c} + {low_pc 0 addr} + {ranges ${cu_ranges_label} DW_FORM_sec_offset} + } { + integer_label: DW_TAG_base_type { + {DW_AT_byte_size $int_size DW_FORM_sdata} + {DW_AT_encoding @DW_ATE_signed} + {DW_AT_name integer} + } + volatile_label: DW_TAG_volatile_type { + {type :$integer_label} + } + subprogram { + {external 1 flag} + {name someothername} + {ranges ${func_ranges_label} DW_FORM_sec_offset} + } + subprogram { + {external 1 flag} + {name bar} + {low_pc $bar_start addr} + {high_pc $bar_len DW_FORM_data4} + } + subprogram { + {external 1 flag} + {name baz} + {low_pc $baz_start addr} + {high_pc $baz_len DW_FORM_data4} + } + } + } + + # Generate ranges data. + ranges {is_64 [is_64_target]} { + func_ranges_label: sequence { + {range {$foo_start } $foo_end} + {range {$foo_low_start} $foo_low_end} + } + cu_ranges_label: sequence { + {range {$foo_start } $foo_end} + {range {$foo_low_start} $foo_low_end} + {range {$bar_start} $bar_end} + {range {$baz_start} $baz_end} + } + } +} + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + [list $srcfile $srcfile2 $asm_file] {nodebug}] } { + return -1 +} + +if ![runto_main] { + return -1 +} + +# "someothername" should be put into the partial symbol table, but +# there was a bug causing functions using DW_AT_ranges not to be. +# Note we use a name that is very different from the linkage name, in +# order to not set the breakpoint via minsyms. +gdb_test "break someothername" \ + "Breakpoint.*at.*" \ + "break someothername" -- 2.7.4