aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Mezentsev <vladimir.mezentsev@oracle.com>2025-04-27 20:28:30 -0700
committerVladimir Mezentsev <vladimir.mezentsev@oracle.com>2025-04-28 23:43:20 -0700
commitb1f0f5b31c414b3445cdcbc5bf9ca31638c7712a (patch)
tree9937a88ac244d4f1d10c57d448a4678fc42f8437
parent82bdc396a40e64ea17acdba072bafbb3f620518f (diff)
downloadbinutils-b1f0f5b31c414b3445cdcbc5bf9ca31638c7712a.zip
binutils-b1f0f5b31c414b3445cdcbc5bf9ca31638c7712a.tar.gz
binutils-b1f0f5b31c414b3445cdcbc5bf9ca31638c7712a.tar.bz2
gprofng not reading references correctly in Dwarf
Fixed as specified in the DWARF standard: The first type of reference can identify any debugging information entry within the containing unit. This type of reference is an offset from the first byte of the compilation header for the compilation unit containing the reference. There are five forms for this type of reference. There are fixed length forms for one, two, four and eight byte offsets (respectively, DW_FORM_ref1, DW_FORM_ref2, DW_FORM_ref4, and DW_FORM_ref8). There is also an unsigned variable length offset encoded form that uses unsigned LEB128 numbers (DW_FORM_ref_udata). gprofng/ChangeLog 2025-04-27 Vladimir Mezentsev <vladimir.mezentsev@oracle.com> * src/DwarfLib.cc (set_die): Handling DWARF references (DW_FORM_ref1, DW_FORM_ref2, DW_FORM_ref4, DW_FORM_ref8, DW_FORM_ref_udata). * src/Dwarf.cc: Likewise.
-rw-r--r--gprofng/src/Dwarf.cc4
-rw-r--r--gprofng/src/DwarfLib.cc14
2 files changed, 9 insertions, 9 deletions
diff --git a/gprofng/src/Dwarf.cc b/gprofng/src/Dwarf.cc
index a613c63..3b3fd63 100644
--- a/gprofng/src/Dwarf.cc
+++ b/gprofng/src/Dwarf.cc
@@ -454,7 +454,7 @@ DwrCU::parseChild (Dwarf_cnt *ctx)
Dwarf_Die next_die;
if (read_ref_attr (DW_AT_sibling, &next_die) == DW_DLV_OK)
{
- next_die_offset = next_die + cu_offset;
+ next_die_offset = next_die;
if (next_die_offset <= debug_infoSec->offset)
{
Dprintf (DEBUG_ERR_MSG, NTXT ("DwrCU::parseChild: next_die(0x%llx) <= debug_infoSec->offset(%llx)\n"),
@@ -723,7 +723,7 @@ DwrCU::read_hwcprof_info (Dwarf_cnt *ctx)
Dwarf_Die next_die;
if (read_ref_attr (DW_AT_sibling, &next_die) == DW_DLV_OK)
{
- next_die_offset = next_die + cu_offset;
+ next_die_offset = next_die;
if (next_die_offset <= debug_infoSec->offset)
next_die_offset = 0;
else if (debug_infoSec->size > next_die_offset)
diff --git a/gprofng/src/DwarfLib.cc b/gprofng/src/DwarfLib.cc
index d399c33..3594c2f 100644
--- a/gprofng/src/DwarfLib.cc
+++ b/gprofng/src/DwarfLib.cc
@@ -1847,7 +1847,7 @@ DwrCU::DwrCU (Dwarf *_dwarf)
(long long) cu_offset, (long long) cu_offset,
(long long) next_cu_offset, (long long) next_cu_offset,
(long long) debug_abbrev_offset, (long long) debug_abbrev_offset,
- (long long) (next_cu_offset - cu_offset),
+ (long long) (next_cu_offset),
(int) version, (int) address_size,
debug_infoSec->fmt64 ? "true" : "false",
debug_infoSec->need_swap_endian ? "true" : "false",
@@ -1945,7 +1945,7 @@ DwrCU::set_die (Dwarf_Die die)
|| debug_infoSec->offset >= debug_infoSec->size)
return DW_DLV_ERROR;
dwrTag.offset = debug_infoSec->offset;
- dwrTag.die = debug_infoSec->offset - cu_offset;
+ dwrTag.die = debug_infoSec->offset;
dwrTag.num = debug_infoSec->GetULEB128_32 ();
if (dwrTag.num == 0)
return DW_DLV_NO_ENTRY;
@@ -1994,19 +1994,19 @@ DwrCU::set_die (Dwarf_Die die)
atf->u.str = debug_infoSec->GetData (atf->len);
break;
case DW_FORM_ref1:
- atf->u.offset = debug_infoSec->Get_8 ();
+ atf->u.offset = debug_infoSec->Get_8 () + cu_offset;
break;
case DW_FORM_ref2:
- atf->u.offset = debug_infoSec->Get_16 ();
+ atf->u.offset = debug_infoSec->Get_16 () + cu_offset;
break;
case DW_FORM_ref4:
- atf->u.offset = debug_infoSec->Get_32 ();
+ atf->u.offset = debug_infoSec->Get_32 () + cu_offset;
break;
case DW_FORM_ref8:
- atf->u.offset = debug_infoSec->Get_64 ();
+ atf->u.offset = debug_infoSec->Get_64 () + cu_offset;
break;
case DW_FORM_ref_udata:
- atf->u.offset = debug_infoSec->GetULEB128 ();
+ atf->u.offset = debug_infoSec->GetULEB128 () + cu_offset;
break;
case DW_FORM_data1:
atf->u.offset = debug_infoSec->Get_8 ();