This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] readelf: When highpc is in constant form also print as address.


On Tue, 2013-03-26 at 07:58 +0100, Jan Kratochvil wrote:
> On Mon, 25 Mar 2013 21:23:26 +0100, Mark Wielaard wrote:
> > @@ -5437,7 +5438,19 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
> >        if (cbargs->silent)
> >  	break;
> >  
> > -      if (valuestr == NULL)
> > +      /* When highpc is in constant form it is relative to lowpc.
> > +	 In that case also show the address.  */
> > +      Dwarf_Addr highpc;
> > +      if (attr == DW_AT_high_pc && (dwarf_highpc (cbargs->die, &highpc) == 0))
> > +	{
> > +	  char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
> > +				       highpc - 1, highpc);
> 
> That "- 1" is a bug:
> 
> DWARF-4.0:
> If the value of the DW_AT_high_pc is of class address, it is the relocated
> address of the first location past the last instruction associated with the
> entity; if it is of class constant, the value is an unsigned integer offset
> which when added to the low PC gives the address of the first location past
> the last instruction associated with the entity.

Right, so it isn't a bug, but was a deliberately choice because high_pc
is "one to high". Normally when readelf displays ranges it displays them
"inclusive". That way you get the proper symbols/offsets associated with
the last byte of a code range. Otherwise readelf has to display a symbol
associated with the "next" symbol, if any. If you want "uninterpreted"
values you can always use -N or -U.

But it is inconsistent with how we display high_pc if it is a
DW_FORM_addr, or when it is displayed on its own, not as a
low_pc..high_pc range. So lets go for consistent and always display it
as a "raw" single address instead of a range.

I also fixed the parens issue Roland noticed before pushing the
attached.

Cheers,

Mark
commit a8c7f05cfd03a58821c3da68f3f577c882258674
Author: Mark Wielaard <mjw@redhat.com>
Date:   Mon Mar 25 21:11:53 2013 +0100

    readelf: When highpc is in constant form also print as address.
    
    When highpc is in constant form it is relative to lowpc.  In that case
    also show as address.
    
    Suggested-by: Jan Kratochvil <jan.kratochvil@redhat.com>
    Signed-off-by: Mark Wielaard <mjw@redhat.com>

diff --git a/src/ChangeLog b/src/ChangeLog
index a641d33..24bc6bf 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,10 @@
+2013-03-25  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (attrcb_args): Add Dwarf_Die.
+	(attr_callback): When highpc is in constant form also print as
+	address.
+	(print_debug_units): Set args.die.
+
 2013-03-19  Mark Wielaard  <mjw@redhat.com>
 
 	* readelf.c (print_gdb_index_section): Free format_dwarf_addr results.
diff --git a/src/readelf.c b/src/readelf.c
index 1412bed..6d9db73 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -5242,6 +5242,7 @@ struct attrcb_args
 {
   Dwfl_Module *dwflmod;
   Dwarf *dbg;
+  Dwarf_Die *die;
   int level;
   bool silent;
   unsigned int version;
@@ -5437,7 +5438,19 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
       if (cbargs->silent)
 	break;
 
-      if (valuestr == NULL)
+      /* When highpc is in constant form it is relative to lowpc.
+	 In that case also show the address.  */
+      Dwarf_Addr highpc;
+      if (attr == DW_AT_high_pc && dwarf_highpc (cbargs->die, &highpc) == 0)
+	{
+	  char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
+				       highpc, highpc);
+	  printf ("           %*s%-20s (%s) %" PRIuMAX " (%s)\n",
+		  (int) (level * 2), "", dwarf_attr_name (attr),
+		  dwarf_form_name (form), (uintmax_t) num, a);
+	  free (a);
+	}
+      else if (valuestr == NULL)
 	printf ("           %*s%-20s (%s) %" PRIuMAX "\n",
 		(int) (level * 2), "", dwarf_attr_name (attr),
 		dwarf_form_name (form), (uintmax_t) num);
@@ -5659,6 +5672,7 @@ print_debug_units (Dwfl_Module *dwflmod,
 
       /* Print the attribute values.  */
       args.level = level;
+      args.die = &dies[level];
       (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
 
       /* Make room for the next level's DIE.  */
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 62b589d..3465777 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,7 @@
+2013-03-25  Mark Wielaard  <mjw@redhat.com>
+
+	* run-readelf-dwz-multi.sh: Expect high_pc also as address.
+
 2013-03-20  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
 	* Makefile.am (check_PROGRAMS): Add dwfl-report-elf-align.
diff --git a/tests/run-readelf-dwz-multi.sh b/tests/run-readelf-dwz-multi.sh
index 20c00c5..ca939f3 100755
--- a/tests/run-readelf-dwz-multi.sh
+++ b/tests/run-readelf-dwz-multi.sh
@@ -90,7 +90,7 @@ DWARF section [28] '.debug_info' at offset 0x1078:
            name                 (strp) "main.c"
            comp_dir             (GNU_strp_alt) "/home/mark/src/tests/dwz"
            low_pc               (addr) 0x00000000004006ac <main>
-           high_pc              (udata) 44
+           high_pc              (udata) 44 (0x00000000004006d8)
            stmt_list            (sec_offset) 0
  [    26]    imported_unit
              import               (GNU_ref_alt) [     b]
@@ -105,7 +105,7 @@ DWARF section [28] '.debug_info' at offset 0x1078:
              prototyped           (flag_present) 
              type                 (GNU_ref_alt) [    3e]
              low_pc               (addr) 0x00000000004006ac <main>
-             high_pc              (udata) 44
+             high_pc              (udata) 44 (0x00000000004006d8)
              frame_base           (exprloc) 
               [   0] call_frame_cfa
              GNU_all_tail_call_sites (flag_present) 
@@ -148,7 +148,7 @@ DWARF section [25] '.debug_info' at offset 0x106c:
            name                 (strp) "shared.c"
            comp_dir             (GNU_strp_alt) "/home/mark/src/tests/dwz"
            low_pc               (addr) +0x0000000000000670 <call_foo>
-           high_pc              (udata) 23
+           high_pc              (udata) 23 (+0x0000000000000687)
            stmt_list            (sec_offset) 0
  [    26]    imported_unit
              import               (GNU_ref_alt) [     b]
@@ -160,7 +160,7 @@ DWARF section [25] '.debug_info' at offset 0x106c:
              prototyped           (flag_present) 
              type                 (GNU_ref_alt) [    3e]
              low_pc               (addr) +0x0000000000000670 <call_foo>
-             high_pc              (udata) 23
+             high_pc              (udata) 23 (+0x0000000000000687)
              frame_base           (exprloc) 
               [   0] call_frame_cfa
              GNU_all_call_sites   (flag_present) 
@@ -185,7 +185,7 @@ DWARF section [28] '.debug_info' at offset 0x1088:
            name                 (GNU_strp_alt) "main.c"
            comp_dir             (GNU_strp_alt) "/home/mark/src/tests"
            low_pc               (addr) 0x00000000004004ec <main>
-           high_pc              (udata) 18
+           high_pc              (udata) 18 (0x00000000004004fe)
            stmt_list            (sec_offset) 0
  [    26]    imported_unit
              import               (GNU_ref_alt) [     b]
@@ -197,7 +197,7 @@ DWARF section [28] '.debug_info' at offset 0x1088:
              prototyped           (flag_present) 
              type                 (GNU_ref_alt) [    30]
              low_pc               (addr) 0x00000000004004ec <main>
-             high_pc              (udata) 18
+             high_pc              (udata) 18 (0x00000000004004fe)
              frame_base           (exprloc) 
               [   0] call_frame_cfa
              GNU_all_call_sites   (flag_present) 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]