[PATCH] gprofng not reading references correctly in Dwarf

vladimir.mezentsev@oracle.com vladimir.mezentsev@oracle.com
Mon Apr 28 03:37:03 GMT 2025


From: Vladimir Mezentsev <vladimir.mezentsev@oracle.com>

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.
---
 gprofng/src/Dwarf.cc    |  4 ++--
 gprofng/src/DwarfLib.cc | 14 +++++++-------
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/gprofng/src/Dwarf.cc b/gprofng/src/Dwarf.cc
index a613c63ae2b..3b3fd63d795 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 d399c3356cf..3594c2f9ad5 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 ();
-- 
2.43.5



More information about the Binutils mailing list