From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 100527 invoked by alias); 29 Mar 2019 20:00:57 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 100342 invoked by uid 89); 29 Mar 2019 20:00:41 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-22.9 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.1 spammy=arranging, distributed X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 29 Mar 2019 20:00:37 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 6C1AD116EC9; Fri, 29 Mar 2019 16:00:33 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id sxs05SOnLZA1; Fri, 29 Mar 2019 16:00:33 -0400 (EDT) Received: from murgatroyd.Home (174-29-37-56.hlrn.qwest.net [174.29.37.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by rock.gnat.com (Postfix) with ESMTPSA id 1605B116A24; Fri, 29 Mar 2019 16:00:33 -0400 (EDT) From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH] Handle DW_AT_ranges when reading partial symtabs Date: Fri, 29 Mar 2019 20:00:00 -0000 Message-Id: <20190329200030.8368-1-tromey@adacore.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SW-Source: 2019-03/txt/msg00748.txt.bz2 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-03-29 Tom Tromey PR symtab/23331: * dwarf2read.c (partial_die_info::read): Handle DW_AT_ranges. gdb/testsuite/ChangeLog 2019-03-29 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 | 134 +++++++++++++++++++ 6 files changed, 230 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/dwarf2read.c b/gdb/dwarf2read.c index 658c86264bf..a5e953bd427 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/gdb.dwarf2/dw2-ranges-main.c b/gdb/testsuite/gdb.dwarf2/dw2-ranges-main.c new file mode 100644 index 00000000000..35a4d4c07e1 --- /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 00000000000..7d0408a56a9 --- /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 00000000000..eb1130a2238 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.exp @@ -0,0 +1,134 @@ +# 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.20.1