public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: "Paweł Wódkowski" <pwodkowski@pl.sii.eu>
To: Andrew Burgess <andrew.burgess@embecosm.com>
Cc: "gdb-patches@sourceware.org" <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	[thread overview]
Message-ID: <dad43fd80fe04c75a2d19be4eca0fe05@pl.sii.eu> (raw)
In-Reply-To: <20181127220917.GC18841@embecosm.com>

On 27.11.2018 23:08, Andrew Burgess wrote:
> * Pawel Wodkowski <pwodkowski@pl.sii.eu> [2018-11-19 22:38:45 +0100]:
> 
>> From: Bernhard Heckel <bernhard.heckel@intel.com>
>>
>> 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.
> 
> 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.
> 
> 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.
> 

As I checked gfortran will not generate entry point tags so for now it 
is only for Intel ifort compiler. The entry-point.f90 example compiled 
using ifort produce following entry point tag:

...
<2><9e>: Abbrev Number: 5 (DW_TAG_entry_point)
     <9f>   DW_AT_decl_line   : 35
     <a0>   DW_AT_decl_file   : 1
     <a1>   DW_AT_name        : foo
     <a5>   DW_AT_low_pc      : 0x402ba8
...
<3><c9>: Abbrev Number: 4 (DW_TAG_formal_parameter)
     <ca>   DW_AT_decl_line   : 35
     <cb>   DW_AT_decl_file   : 1
     <cc>   DW_AT_type        : <0x120>
     <d0>   DW_AT_name        : l
     <d2>   DW_AT_location    : 4 byte block: 76 f4 7e 6 
(DW_OP_breg6 (rbp): -140; DW_OP_deref)
...

I will add this to commit message.

Thanks
Pawel

>>
>> 2016-06-01  Bernhard Heckel  <bernhard.heckel@intel.com>
>>
>> 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_die_info *pdi, CORE_ADDR *lowpc,
>>   static void add_partial_enumeration (struct partial_die_info *enum_pdi,
>>   				     struct dwarf2_cu *cu);
>>   
>> +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)
>>   
>>     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 == language_fortran)
>> +	{
> 
> 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.
> 
>> +	  addr = gdbarch_adjust_dwarf2_addr (gdbarch, pdi->lowpc + baseaddr);
> 
> When compared to DW_TAG_subprogram, this line doesn't include a '-
> baseaddr'.  I think that deserves a comment explaining why.
> 
>> +	  /* 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 != 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 != nullptr,
>> +				 VAR_DOMAIN, LOC_BLOCK,
>> +				 SECT_OFF_TEXT (objfile),
>> +				 &objfile->static_psymbols,
>> +				 addr, cu->language, objfile);
> 
> I think these two add_psymbol_to_list calls, and the two for
> DW_TAG_subprogram should be factored out.  Just my opinion though...
> 
>> +	}
>> +      break;
>>       case DW_TAG_inlined_subroutine:
>>       case DW_TAG_subprogram:
>>         addr = (gdbarch_adjust_dwarf2_addr (gdbarch, pdi->lowpc + baseaddr)
>> @@ -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);
>>   }
>>   
>> +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 == nullptr)
>> +    complaint (_("DW_TAG_entry_point must have a name"));
>> +  else
>> +    add_partial_symbol (pdi, cu);
>> +}
> 
> 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:
> 
>       /* 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);
> 
> I think the same logic should apply for DW_TAG_entry_point maybe? So,
> add_partial_entry_point is possibly redundant.
> 
>> +
>>   /* 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 = pdi->die_sibling;
>>   	}
>>       }
>> +  else if (cu->language == language_fortran)
>> +    {
> 
> Like before, I'm not convinced we should tie this to Fortran...
> 
>> +      pdi = pdi->die_child;
>> +      while (pdi != nullptr)
>> +	{
>> +	  if (pdi->tag == DW_TAG_entry_point)
>> +	    add_partial_entry_point (pdi, lowpc, highpc, set_addrmap, cu);
> 
> You can probably just make the add_partial_symbol call directly here
> (after a check that pdi->name is not null.
> 
>> +	  pdi = pdi->die_sibling;
>> +	}
>> +    }
>>   }
>>   
>>   /* 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, CORE_ADDR *lowpc,
>>     CORE_ADDR high = 0;
>>     enum pc_bounds_kind ret;
>>   
>> +  if (die->tag == 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 == dwarf2_get_pc_bounds (die->parent, lowpc, highpc, cu, pst))
> 
> Compare to 'PC_BOUNDS_NOT_PRESENT' not 0.
> 
>> +	return PC_BOUNDS_NOT_PRESENT;
>> +
>> +      attr = 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 = attr_value_as_address (attr);
>> +      *lowpc = low;
>> +
>> +      return PC_BOUNDS_HIGH_LOW;
>> +    }
>> +
>>     attr_high = 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 != DW_TAG_constant
>>   	  && abbrev->tag != DW_TAG_enumerator
>> +	  && abbrev->tag != DW_TAG_entry_point
>>   	  && abbrev->tag != DW_TAG_subprogram
>>   	  && abbrev->tag != DW_TAG_inlined_subroutine
>>   	  && abbrev->tag != DW_TAG_lexical_block
>> @@ -18529,6 +18602,7 @@ load_partial_dies (const struct die_reader_specs *reader,
>>   
>>         if (load_all
>>   	  || abbrev->tag == DW_TAG_constant
>> +	  || abbrev->tag == DW_TAG_entry_point
>>   	  || abbrev->tag == DW_TAG_subprogram
>>   	  || abbrev->tag == DW_TAG_variable
>>   	  || abbrev->tag == DW_TAG_namespace
>> @@ -18570,7 +18644,9 @@ load_partial_dies (const struct die_reader_specs *reader,
>>   		      || last_die->tag == DW_TAG_union_type))
>>   	      || (cu->language == language_ada
>>   		  && (last_die->tag == DW_TAG_subprogram
>> -		      || last_die->tag == DW_TAG_lexical_block))))
>> +		      || last_die->tag == DW_TAG_lexical_block))
>> +	      || (cu->language == language_fortran
>> +		  && last_die->tag == DW_TAG_subprogram)))
>>   	{
>>   	  nesting_level++;
>>   	  parent_die = last_die;
>> @@ -21442,6 +21518,25 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
>>   	  SYMBOL_ACLASS_INDEX (sym) = 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 == language_fortran)
>> +	    {
>> +	      /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
>> +		 finish_block.  */
>> +	      SYMBOL_ACLASS_INDEX (sym) = 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 = dwarf2_attr (die->parent, DW_AT_external, cu);
>> +	      if (attr2 && (DW_UNSND (attr2) != 0))
>> +		list_to_add = cu->builder->get_global_symbols ();
>> +	      else
>> +		list_to_add = 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 dwarf2_cu *cu)
>>       case DW_TAG_enumeration_type:
>>         this_type = 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/gdb.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 <http://www.gnu.org/licenses/>.
>> +
>> +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=1, k=2, l=3, i1=4\\) at .*" \
>> +                ".*"] \
>> +    "continue to breakpoint: $ept_name"
>> +
>> +gdb_test "print j" "= 1" "print j, entered via $ept_name"
>> +gdb_test "print k" "= 2" "print k, entered via $ept_name"
>> +gdb_test "print l" "= 3" "print l, entered via $ept_name"
>> +gdb_test "print i1" "= 4" "print i1, entered via $ept_name"
>> +gdb_test "info args" \
>> +  [multi_line "j = 1" \
>> +              "k = 2" \
>> +              "l = 3" \
>> +              "i1 = 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=4, j=5, k=6, i1=7\\) at .*" \
>> +                ".*"] \
>> +    "continue to breakpoint: $ept_name"
>> +
>> +gdb_test "print i" "= 4" "print i, entered via $ept_name"
>> +gdb_test "print j" "= 5" "print j, entered via $ept_name"
>> +gdb_test "print k" "= 6" "print k, entered via $ept_name"
>> +gdb_test "print i1" "= 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=1\\) at .*" \
>> +                ".*"] \
>> +    "continue to breakpoint: $ept_name"
>> +
>> +gdb_test "print j" "= 1" "print j, entered via $ept_name"
>> +gdb_test "info args" "j = 1" "info args, entered via $ept_name"
>> diff --git a/gdb/testsuite/gdb.fortran/entry-point.f90 b/gdb/testsuite/gdb.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 <http://www.gnu.org/licenses/>.
>> +
>> +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 = 0
>> +    C = 0.0
>> +
>> +    A = I + K + I1
>> +    goto 1000
>> +
>> +    entry foo(J,K,L,I1)
>> +    A = J + K + L + I1
>> +
>> +200 C = J
>> +    goto 1000
>> +
>> +    entry tim(J)
>> +    goto 200
>> +
>> +1000 A = C + 1
>> +     C = J * 1.5
>> +
>> +    return
>> +  end subroutine
>> -- 
>> 2.7.4
>>
> 
> 
> Thanks,
> Andrew
> 

  reply	other threads:[~2018-12-02 21:32 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-19 21:40 [PATCH v2 1/7] DWARF: Don't add nameless modules to partial symbol table Pawel Wodkowski
2018-11-19 21:40 ` [PATCH v2 7/7] Fortran: Document scope operator Pawel Wodkowski
2018-11-20  5:01   ` Eli Zaretskii
2018-11-22 16:14     ` Paweł Wódkowski
2018-11-23 10:31       ` Eli Zaretskii
2018-11-19 21:40 ` [PATCH v2 2/7] Dwarf: Fortran, support DW_TAG_entry_point Pawel Wodkowski
2018-11-27 22:09   ` Andrew Burgess
2018-12-02 21:32     ` Paweł Wódkowski [this message]
2018-11-19 21:40 ` [PATCH v2 4/7] Fortran: Ptype, print type extension Pawel Wodkowski
2019-02-01 13:06   ` Andrew Burgess
2018-11-19 21:40 ` [PATCH v2 6/7] Fortran: Nested functions, add scope parameter Pawel Wodkowski
2018-11-19 21:40 ` [PATCH v2 5/7] Fortran: Enable setting breakpoint on nested functions Pawel Wodkowski
2018-11-28 10:32   ` Richard Bunt
2018-12-02 22:16     ` Paweł Wódkowski
2018-11-19 21:40 ` [PATCH v2 3/7] Fortran: Accessing fields of inherited types via fully qualified name Pawel Wodkowski
2018-12-03 13:44   ` Richard Bunt
2018-12-04 21:05     ` Paweł Wódkowski
2018-12-06 15:03       ` Richard Bunt
2018-12-09 20:41         ` Paweł Wódkowski
2019-01-16 11:11           ` Richard Bunt
2019-01-18  8:33             ` Paweł Wódkowski
2019-01-30 11:10               ` Richard Bunt
2019-02-06 12:39                 ` Paweł Wódkowski
2018-11-27 19:35 ` PING Re: [PATCH v2 1/7] DWARF: Don't add nameless modules to partial symbol table Pawel Wodkowski
2018-11-27 20:29 ` Simon Marchi
2018-11-27 21:42 ` Andrew Burgess
2018-12-02 21:01   ` Paweł Wódkowski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=dad43fd80fe04c75a2d19be4eca0fe05@pl.sii.eu \
    --to=pwodkowski@pl.sii.eu \
    --cc=andrew.burgess@embecosm.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).