diff options
author | Tom Tromey <tromey@adacore.com> | 2019-03-27 13:21:24 -0600 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2019-04-01 10:36:58 -0600 |
commit | 05caa1d236440cd8967f8804be8dbcf27fb490b6 (patch) | |
tree | be5a159d7aa6d8d434c51aac2951495455e55ffc /gdb | |
parent | 9d1447e09d4aa673826039321163b5a684e8e043 (diff) | |
download | gdb-05caa1d236440cd8967f8804be8dbcf27fb490b6.zip gdb-05caa1d236440cd8967f8804be8dbcf27fb490b6.tar.gz gdb-05caa1d236440cd8967f8804be8dbcf27fb490b6.tar.bz2 |
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 <tromey@adacore.com>
PR symtab/23331:
* dwarf2read.c (partial_die_info::read): Handle DW_AT_ranges.
gdb/testsuite/ChangeLog
2019-04-01 Tom Tromey <tromey@adacore.com>
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.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/dwarf2read.c | 19 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/dw2-ranges-main.c | 19 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.c | 46 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.exp | 138 |
6 files changed, 234 insertions, 0 deletions
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 <tromey@adacore.com> + + PR symtab/23331: + * dwarf2read.c (partial_die_info::read): Handle DW_AT_ranges. + 2019-04-01 Sergio Durigan Junior <sergiodj@redhat.com> Pedro Alves <palves@redhat.com> 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 <tromey@adacore.com> + + 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 <simark@simark.ca> * 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 <http://www.gnu.org/licenses/>. */ + +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 <http://www.gnu.org/licenses/>. */ + +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 <http://www.gnu.org/licenses/>. + +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" |