From: Vladimir Mezentsev Date: Mon, 28 Apr 2025 03:28:30 +0000 (-0700) Subject: gprofng not reading references correctly in Dwarf X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b1f0f5b31c414b3445cdcbc5bf9ca31638c7712a;p=thirdparty%2Fbinutils-gdb.git 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 * 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. --- 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 ();