This is the mail archive of the
elfutils-devel@sourceware.org
mailing list for the elfutils project.
Re: [PATCH] readelf: When highpc is in constant form also print as address.
- From: Mark Wielaard <mjw at redhat dot com>
- To: elfutils-devel at lists dot fedorahosted dot org
- Date: Tue, 26 Mar 2013 09:30:03 +0100
- Subject: 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)