From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 94972 invoked by alias); 2 Dec 2018 21:32:17 -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 94958 invoked by uid 89); 2 Dec 2018 21:32:15 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.4 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_SHORT,KAM_STOCKGEN,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=148, REAL, Search, psymtab X-HELO: mail.pl.sii.eu Received: from mail.pl.sii.eu (HELO mail.pl.sii.eu) (91.227.21.9) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 02 Dec 2018 21:32:09 +0000 Received: from localhost (localhost [127.0.0.1]) by mail.pl.sii.eu (Postfix) with ESMTP id 09DEB3727; Sun, 2 Dec 2018 22:32:06 +0100 (CET) Received: from mail.pl.sii.eu ([127.0.0.1]) by localhost (mail.pl.sii.eu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id WUwuGNUW_9w0; Sun, 2 Dec 2018 22:32:05 +0100 (CET) Received: from PRDSWEX16W2.SIIPOLSKA.PL (PRDSWEX16W2.SIIPOLSKA.PL [10.254.15.206]) by mail.pl.sii.eu (Postfix) with ESMTPS id DBB6C3715; Sun, 2 Dec 2018 22:32:05 +0100 (CET) Received: from PRDSWEX16W1.SIIPOLSKA.PL (10.254.15.205) by PRDSWEX16W2.SIIPOLSKA.PL (10.254.15.206) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1531.3; Sun, 2 Dec 2018 22:32:13 +0100 Received: from PRDSWEX16W1.SIIPOLSKA.PL ([fe80::3c9b:ace1:3462:3aae]) by PRDSWEX16W1.SIIPOLSKA.PL ([fe80::3c9b:ace1:3462:3aae%9]) with mapi id 15.01.1531.003; Sun, 2 Dec 2018 22:32:04 +0100 From: =?iso-8859-2?Q?Pawe=B3_W=F3dkowski?= To: Andrew Burgess CC: "gdb-patches@sourceware.org" Subject: Re: [PATCH v2 2/7] Dwarf: Fortran, support DW_TAG_entry_point. Date: Sun, 02 Dec 2018 21:32:00 -0000 Message-ID: References: <1542663530-140490-1-git-send-email-pwodkowski@pl.sii.eu> <1542663530-140490-2-git-send-email-pwodkowski@pl.sii.eu> <20181127220917.GC18841@embecosm.com> Content-Type: text/plain; charset="iso-8859-2" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-SW-Source: 2018-12/txt/msg00017.txt.bz2 On 27.11.2018 23:08, Andrew Burgess wrote: > * Pawel Wodkowski [2018-11-19 22:38:45 +0100]: >=20 >> From: Bernhard Heckel >> >> Fortran provides additional entry-points to an subprogram. >> Those entry-points may have only a subset of parameters >> of the original subprogram as well. >> Add support for parsing DW_TAG_entry_point's for Fortran. >=20 > As with patch #1 it's probably worth documenting which compilers you > see DW_TAG_entry_point in, along with an example of what the generated > DWARF looks like. >=20 > This means that in the future if/when others start to use this DWARF > feature we can figure out which other compilers we need to test. >=20 As I checked gfortran will not generate entry point tags so for now it=20 is only for Intel ifort compiler. The entry-point.f90 example compiled=20 using ifort produce following entry point tag: ... <2><9e>: Abbrev Number: 5 (DW_TAG_entry_point) <9f> DW_AT_decl_line : 35 DW_AT_decl_file : 1 DW_AT_name : foo DW_AT_low_pc : 0x402ba8 ... <3>: Abbrev Number: 4 (DW_TAG_formal_parameter) DW_AT_decl_line : 35 DW_AT_decl_file : 1 DW_AT_type : <0x120> DW_AT_name : l DW_AT_location : 4 byte block: 76 f4 7e 6=20 (DW_OP_breg6 (rbp): -140; DW_OP_deref) ... I will add this to commit message. Thanks Pawel >> >> 2016-06-01 Bernhard Heckel >> >> gdb/Changelog: >> * gdb/dwarf2read.c (add_partial_symbol): Handle DW_TAG_entry_point. >> (add_partial_entry_point): New. >> (add_partial_subprogram): Search for entry_points. >> (process_die): Handle DW_TAG_entry_point. >> (dwarf2_get_pc_bounds): Update low pc from DWARF. >> (load_partial_dies): Save DW_TAG_entry_point's. >> (load_partial_dies): Save DW_TAG_entry_point to hash table. >> (load_partial_dies): Look into child's of DW_TAG_sub_program >> for fortran. >> (new_symbol_full): Process DW_TAG_entry_point. >> (read_type_die_1): Handle DW_TAG_entry_point. >> >> gdb/Testsuite/Changelog: >> * gdb.fortran/entry_point.f90: New. >> * gdb.fortran/entry_point.exp: New. >> --- >> gdb/dwarf2read.c | 98 +++++++++++++++++++++++= +++++++- >> gdb/testsuite/gdb.fortran/entry-point.exp | 70 ++++++++++++++++++++++ >> gdb/testsuite/gdb.fortran/entry-point.f90 | 48 +++++++++++++++ >> 3 files changed, 215 insertions(+), 1 deletion(-) >> create mode 100644 gdb/testsuite/gdb.fortran/entry-point.exp >> create mode 100644 gdb/testsuite/gdb.fortran/entry-point.f90 >> >> diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c >> index 89fd4ae15e80..88e57d7ab68e 100644 >> --- a/gdb/dwarf2read.c >> +++ b/gdb/dwarf2read.c >> @@ -1473,6 +1473,10 @@ static void add_partial_module (struct partial_di= e_info *pdi, CORE_ADDR *lowpc, >> static void add_partial_enumeration (struct partial_die_info *enum_pdi, >> struct dwarf2_cu *cu); >>=20=20=20 >> +static void add_partial_entry_point (struct partial_die_info *pdi, >> + CORE_ADDR *lowpc, CORE_ADDR *highpc, >> + int need_pc, struct dwarf2_cu *cu); >> + >> static void add_partial_subprogram (struct partial_die_info *pdi, >> CORE_ADDR *lowpc, CORE_ADDR *highpc, >> int need_pc, struct dwarf2_cu *cu); >> @@ -8876,6 +8880,32 @@ add_partial_symbol (struct partial_die_info *pdi,= struct dwarf2_cu *cu) >>=20=20=20 >> switch (pdi->tag) >> { >> + case DW_TAG_entry_point: >> + /* Don't know any other language than fortran which is >> + using DW_TAG_entry_point. */ >> + if (cu->language =3D=3D language_fortran) >> + { >=20 > I'm not sure the language check is needed here. The description for > DW_TAG_entry_point in the DWARF spec seems pretty generic. I don't > see how a different language would expect significantly different > results, and so, I would suggest we should just add this as general > purpose code. >=20 >> + addr =3D gdbarch_adjust_dwarf2_addr (gdbarch, pdi->lowpc + baseaddr); >=20 > When compared to DW_TAG_subprogram, this line doesn't include a '- > baseaddr'. I think that deserves a comment explaining why. >=20 >> + /* DW_TAG_entry_point provides an additional entry_point to an >> + existing sub_program. Therefore, we inherit the "external" >> + attribute from the sub_program to which the entry_point >> + belongs to. */ >> + if (pdi->die_parent->is_external) >> + add_psymbol_to_list (actual_name, strlen (actual_name), >> + built_actual_name !=3D nullptr, >> + VAR_DOMAIN, LOC_BLOCK, >> + SECT_OFF_TEXT (objfile), >> + &objfile->global_psymbols, >> + addr, cu->language, objfile); >> + else >> + add_psymbol_to_list (actual_name, strlen (actual_name), >> + built_actual_name !=3D nullptr, >> + VAR_DOMAIN, LOC_BLOCK, >> + SECT_OFF_TEXT (objfile), >> + &objfile->static_psymbols, >> + addr, cu->language, objfile); >=20 > I think these two add_psymbol_to_list calls, and the two for > DW_TAG_subprogram should be factored out. Just my opinion though... >=20 >> + } >> + break; >> case DW_TAG_inlined_subroutine: >> case DW_TAG_subprogram: >> addr =3D (gdbarch_adjust_dwarf2_addr (gdbarch, pdi->lowpc + base= addr) >> @@ -9082,6 +9112,17 @@ add_partial_module (struct partial_die_info *pdi,= CORE_ADDR *lowpc, >> scan_partial_symbols (pdi->die_child, lowpc, highpc, set_addrmap, = cu); >> } >>=20=20=20 >> +static void >> +add_partial_entry_point (struct partial_die_info *pdi, >> + CORE_ADDR *p_lowpc, CORE_ADDR *p_highpc, >> + int set_addrmap, struct dwarf2_cu *cu) >> +{ >> + if (pdi->name =3D=3D nullptr) >> + complaint (_("DW_TAG_entry_point must have a name")); >> + else >> + add_partial_symbol (pdi, cu); >> +} >=20 > This function should have a header comment, however, a quick look at > add_partial_subprogram seems to indicate that at this point GDB is not > complaining, but just ignoring weird looking DWARF. For example this > code in add_partial_subprogram: >=20 > /* Ignore subprogram DIEs that do not have a name, they are > illegal. Do not emit a complaint at this point, we will > do so when we convert this psymtab into a symtab. */ > if (pdi->name) > add_partial_symbol (pdi, cu); >=20 > I think the same logic should apply for DW_TAG_entry_point maybe? So, > add_partial_entry_point is possibly redundant. >=20 >> + >> /* Read a partial die corresponding to a subprogram or an inlined >> subprogram and create a partial symbol for that subprogram. >> When the CU language allows it, this routine also defines a partial >> @@ -9158,6 +9199,16 @@ add_partial_subprogram (struct partial_die_info *= pdi, >> pdi =3D pdi->die_sibling; >> } >> } >> + else if (cu->language =3D=3D language_fortran) >> + { >=20 > Like before, I'm not convinced we should tie this to Fortran... >=20 >> + pdi =3D pdi->die_child; >> + while (pdi !=3D nullptr) >> + { >> + if (pdi->tag =3D=3D DW_TAG_entry_point) >> + add_partial_entry_point (pdi, lowpc, highpc, set_addrmap, cu); >=20 > You can probably just make the add_partial_symbol call directly here > (after a check that pdi->name is not null. >=20 >> + pdi =3D pdi->die_sibling; >> + } >> + } >> } >>=20=20=20 >> /* Read a partial die corresponding to an enumeration type. */ >> @@ -10596,6 +10647,7 @@ process_die (struct die_info *die, struct dwarf2= _cu *cu) >> case DW_TAG_type_unit: >> read_type_unit_scope (die, cu); >> break; >> + case DW_TAG_entry_point: >> case DW_TAG_subprogram: >> case DW_TAG_inlined_subroutine: >> read_func_scope (die, cu); >> @@ -14669,6 +14721,26 @@ dwarf2_get_pc_bounds (struct die_info *die, COR= E_ADDR *lowpc, >> CORE_ADDR high =3D 0; >> enum pc_bounds_kind ret; >>=20=20=20 >> + if (die->tag =3D=3D DW_TAG_entry_point) >> + { >> + /* Entry_point is embedded in an subprogram. Therefore, we can use >> + the highpc from it's enveloping subprogram and get the >> + lowpc from DWARF. */ >> + if (0 =3D=3D dwarf2_get_pc_bounds (die->parent, lowpc, highpc, cu= , pst)) >=20 > Compare to 'PC_BOUNDS_NOT_PRESENT' not 0. >=20 >> + return PC_BOUNDS_NOT_PRESENT; >> + >> + attr =3D dwarf2_attr (die, DW_AT_low_pc, cu); >> + if (!attr) >> + { >> + complaint (_("DW_TAG_entry_point is missing DW_AT_low_pc")); >> + return PC_BOUNDS_NOT_PRESENT; >> + } >> + low =3D attr_value_as_address (attr); >> + *lowpc =3D low; >> + >> + return PC_BOUNDS_HIGH_LOW; >> + } >> + >> attr_high =3D dwarf2_attr (die, DW_AT_high_pc, cu); >> if (attr_high) >> { >> @@ -18399,6 +18471,7 @@ load_partial_dies (const struct die_reader_specs= *reader, >> && !is_type_tag_for_partial (abbrev->tag) >> && abbrev->tag !=3D DW_TAG_constant >> && abbrev->tag !=3D DW_TAG_enumerator >> + && abbrev->tag !=3D DW_TAG_entry_point >> && abbrev->tag !=3D DW_TAG_subprogram >> && abbrev->tag !=3D DW_TAG_inlined_subroutine >> && abbrev->tag !=3D DW_TAG_lexical_block >> @@ -18529,6 +18602,7 @@ load_partial_dies (const struct die_reader_specs= *reader, >>=20=20=20 >> if (load_all >> || abbrev->tag =3D=3D DW_TAG_constant >> + || abbrev->tag =3D=3D DW_TAG_entry_point >> || abbrev->tag =3D=3D DW_TAG_subprogram >> || abbrev->tag =3D=3D DW_TAG_variable >> || abbrev->tag =3D=3D DW_TAG_namespace >> @@ -18570,7 +18644,9 @@ load_partial_dies (const struct die_reader_specs= *reader, >> || last_die->tag =3D=3D DW_TAG_union_type)) >> || (cu->language =3D=3D language_ada >> && (last_die->tag =3D=3D DW_TAG_subprogram >> - || last_die->tag =3D=3D DW_TAG_lexical_block)))) >> + || last_die->tag =3D=3D DW_TAG_lexical_block)) >> + || (cu->language =3D=3D language_fortran >> + && last_die->tag =3D=3D DW_TAG_subprogram))) >> { >> nesting_level++; >> parent_die =3D last_die; >> @@ -21442,6 +21518,25 @@ new_symbol (struct die_info *die, struct type *= type, struct dwarf2_cu *cu, >> SYMBOL_ACLASS_INDEX (sym) =3D LOC_LABEL; >> dw2_add_symbol_to_list (sym, cu->list_in_scope); >> break; >> + case DW_TAG_entry_point: >> + /* Don't know any other language than fortran which is >> + using DW_TAG_entry_point. */ >> + if (cu->language =3D=3D language_fortran) >> + { >> + /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by >> + finish_block. */ >> + SYMBOL_ACLASS_INDEX (sym) =3D LOC_BLOCK; >> + /* DW_TAG_entry_point provides an additional entry_point to an >> + existing sub_program. Therefore, we inherit the "external" >> + attribute from the sub_program to which the entry_point >> + belongs to. */ >> + attr2 =3D dwarf2_attr (die->parent, DW_AT_external, cu); >> + if (attr2 && (DW_UNSND (attr2) !=3D 0)) >> + list_to_add =3D cu->builder->get_global_symbols (); >> + else >> + list_to_add =3D cu->list_in_scope; >> + } >> + break; >> case DW_TAG_subprogram: >> /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by >> finish_block. */ >> @@ -22129,6 +22224,7 @@ read_type_die_1 (struct die_info *die, struct dw= arf2_cu *cu) >> case DW_TAG_enumeration_type: >> this_type =3D read_enumeration_type (die, cu); >> break; >> + case DW_TAG_entry_point: >> case DW_TAG_subprogram: >> case DW_TAG_subroutine_type: >> case DW_TAG_inlined_subroutine: >> diff --git a/gdb/testsuite/gdb.fortran/entry-point.exp b/gdb/testsuite/g= db.fortran/entry-point.exp >> new file mode 100644 >> index 000000000000..a1f3f2bebdb9 >> --- /dev/null >> +++ b/gdb/testsuite/gdb.fortran/entry-point.exp >> @@ -0,0 +1,70 @@ >> +# Copyright 2018 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 . >> + >> +if { [skip_fortran_tests] } { return -1 } >> + >> +standard_testfile .f90 >> +load_lib "fortran.exp" >> + >> +if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug f90}]}= { >> + return -1 >> +} >> + >> +if ![runto MAIN__] then { >> + perror "couldn't run to breakpoint MAIN__" >> + continue >> +} >> + >> +# Test if we can set a breakpoint via entry-point name >> +set ept_name "foo" >> +gdb_breakpoint $ept_name >> +gdb_test "continue" \ >> + [multi_line "Breakpoint $decimal, $ept_name \\(j=3D1, k=3D2, l=3D3,= i1=3D4\\) at .*" \ >> + ".*"] \ >> + "continue to breakpoint: $ept_name" >> + >> +gdb_test "print j" "=3D 1" "print j, entered via $ept_name" >> +gdb_test "print k" "=3D 2" "print k, entered via $ept_name" >> +gdb_test "print l" "=3D 3" "print l, entered via $ept_name" >> +gdb_test "print i1" "=3D 4" "print i1, entered via $ept_name" >> +gdb_test "info args" \ >> + [multi_line "j =3D 1" \ >> + "k =3D 2" \ >> + "l =3D 3" \ >> + "i1 =3D 4"] \ >> + "info args, entered via $ept_name" >> + >> +# Test if we can set a breakpoint via function name >> +set ept_name "bar" >> +gdb_breakpoint $ept_name >> +gdb_test "continue" \ >> + [multi_line "Breakpoint $decimal, $ept_name \\(i=3D4, j=3D5, k=3D6,= i1=3D7\\) at .*" \ >> + ".*"] \ >> + "continue to breakpoint: $ept_name" >> + >> +gdb_test "print i" "=3D 4" "print i, entered via $ept_name" >> +gdb_test "print j" "=3D 5" "print j, entered via $ept_name" >> +gdb_test "print k" "=3D 6" "print k, entered via $ept_name" >> +gdb_test "print i1" "=3D 7" "print i1, entered via $ept_name" >> + >> +set ept_name "tim" >> +gdb_breakpoint $ept_name >> +gdb_test "continue" \ >> + [multi_line "Breakpoint $decimal, $ept_name \\(j=3D1\\) at .*" \ >> + ".*"] \ >> + "continue to breakpoint: $ept_name" >> + >> +gdb_test "print j" "=3D 1" "print j, entered via $ept_name" >> +gdb_test "info args" "j =3D 1" "info args, entered via $ept_name" >> diff --git a/gdb/testsuite/gdb.fortran/entry-point.f90 b/gdb/testsuite/g= db.fortran/entry-point.f90 >> new file mode 100644 >> index 000000000000..cb663b956982 >> --- /dev/null >> +++ b/gdb/testsuite/gdb.fortran/entry-point.f90 >> @@ -0,0 +1,48 @@ >> +! Copyright 2018 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 . >> + >> +program TestEntryPoint >> + >> + call foo(1,2,3,4) >> + call bar(4,5,6,7) >> + call tim(1) >> + >> +end program TestEntryPoint >> + >> + subroutine bar(I,J,K,I1) >> + INTEGER I,J,K,L,I1 >> + INTEGER A >> + REAL C >> + >> + A =3D 0 >> + C =3D 0.0 >> + >> + A =3D I + K + I1 >> + goto 1000 >> + >> + entry foo(J,K,L,I1) >> + A =3D J + K + L + I1 >> + >> +200 C =3D J >> + goto 1000 >> + >> + entry tim(J) >> + goto 200 >> + >> +1000 A =3D C + 1 >> + C =3D J * 1.5 >> + >> + return >> + end subroutine >> --=20 >> 2.7.4 >> >=20 >=20 > Thanks, > Andrew >=20