https://github.com/HemangGadhavi updated https://github.com/llvm/llvm-project/pull/145645
>From a85d648ce62b69b870dda306dbdc2d412ed89d33 Mon Sep 17 00:00:00 2001 From: HemangGadhavi <hemang.gadh...@ibm.com> Date: Wed, 25 Jun 2025 02:06:05 -0400 Subject: [PATCH 1/2] [lldb][DWARF64] Enable support for DWARF64 format handling --- .../SymbolFile/DWARF/DWARFFormValue.cpp | 47 ++++++++++++------- .../Plugins/SymbolFile/DWARF/DWARFUnit.cpp | 15 +----- .../Plugins/SymbolFile/DWARF/DWARFUnit.h | 1 + 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp index fd3d45cef4c5e..d0cc5edc6678a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -77,7 +77,10 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data, case DW_FORM_strp: case DW_FORM_line_strp: case DW_FORM_sec_offset: - m_value.uval = data.GetMaxU64(offset_ptr, 4); + if (m_unit->GetFormat() == DwarfFormat::DWARF32) + m_value.uval = data.GetMaxU64(offset_ptr, 4); + else if (m_unit->GetFormat() == DwarfFormat::DWARF64) + m_value.uval = data.GetMaxU64(offset_ptr, 8); break; case DW_FORM_addrx1: case DW_FORM_strx1: @@ -121,8 +124,12 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data, assert(m_unit); if (m_unit->GetVersion() <= 2) ref_addr_size = m_unit->GetAddressByteSize(); - else - ref_addr_size = 4; + else { + if (m_unit->GetFormat() == DwarfFormat::DWARF32) + ref_addr_size = 4; + else if (m_unit->GetFormat() == DwarfFormat::DWARF64) + ref_addr_size = 8; + } m_value.uval = data.GetMaxU64(offset_ptr, ref_addr_size); break; case DW_FORM_indirect: @@ -165,17 +172,18 @@ static FormSize g_form_sizes[] = { {1, 1}, // 0x0b DW_FORM_data1 {1, 1}, // 0x0c DW_FORM_flag {0, 0}, // 0x0d DW_FORM_sdata - {1, 4}, // 0x0e DW_FORM_strp + {0, 0}, // 0x0e DW_FORM_strp (4 bytes for DWARF32, 8 bytes for DWARF64) {0, 0}, // 0x0f DW_FORM_udata {0, 0}, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes // for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later - {1, 1}, // 0x11 DW_FORM_ref1 - {1, 2}, // 0x12 DW_FORM_ref2 - {1, 4}, // 0x13 DW_FORM_ref4 - {1, 8}, // 0x14 DW_FORM_ref8 - {0, 0}, // 0x15 DW_FORM_ref_udata - {0, 0}, // 0x16 DW_FORM_indirect - {1, 4}, // 0x17 DW_FORM_sec_offset + {1, 1}, // 0x11 DW_FORM_ref1 + {1, 2}, // 0x12 DW_FORM_ref2 + {1, 4}, // 0x13 DW_FORM_ref4 + {1, 8}, // 0x14 DW_FORM_ref8 + {0, 0}, // 0x15 DW_FORM_ref_udata + {0, 0}, // 0x16 DW_FORM_indirect + {0, + 0}, // 0x17 DW_FORM_sec_offset (4 bytes for DWARF32, 8 bytes for DWARF64) {0, 0}, // 0x18 DW_FORM_exprloc {1, 0}, // 0x19 DW_FORM_flag_present {0, 0}, // 0x1a DW_FORM_strx (ULEB128) @@ -183,8 +191,8 @@ static FormSize g_form_sizes[] = { {1, 4}, // 0x1c DW_FORM_ref_sup4 {0, 0}, // 0x1d DW_FORM_strp_sup (4 bytes for DWARF32, 8 bytes for DWARF64) {1, 16}, // 0x1e DW_FORM_data16 - {1, 4}, // 0x1f DW_FORM_line_strp - {1, 8}, // 0x20 DW_FORM_ref_sig8 + {0, 0}, // 0x1f DW_FORM_line_strp (4 bytes for DWARF32, 8 bytes for DWARF64) + {1, 8}, // 0x20 DW_FORM_ref_sig8 }; std::optional<uint8_t> DWARFFormValue::GetFixedSize(dw_form_t form, @@ -251,8 +259,12 @@ bool DWARFFormValue::SkipValue(dw_form_t form, // get this wrong if (unit->GetVersion() <= 2) ref_addr_size = unit->GetAddressByteSize(); - else - ref_addr_size = 4; + else { + if (unit->GetFormat() == DwarfFormat::DWARF32) + ref_addr_size = 4; + else if (unit->GetFormat() == DwarfFormat::DWARF64) + ref_addr_size = 8; + } *offset_ptr += ref_addr_size; return true; @@ -288,7 +300,10 @@ bool DWARFFormValue::SkipValue(dw_form_t form, case DW_FORM_sec_offset: case DW_FORM_strp: case DW_FORM_line_strp: - *offset_ptr += 4; + if (unit->GetFormat() == DwarfFormat::DWARF32) + *offset_ptr += 4; + else if (unit->GetFormat() == DwarfFormat::DWARF64) + *offset_ptr += 8; return true; // 4 byte values diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index ffd6f1dd52aff..f216ab13e8936 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -1073,20 +1073,7 @@ const lldb_private::DWARFDataExtractor &DWARFUnit::GetData() const { : m_dwarf.GetDWARFContext().getOrLoadDebugInfoData(); } -uint32_t DWARFUnit::GetHeaderByteSize() const { - switch (m_header.getUnitType()) { - case llvm::dwarf::DW_UT_compile: - case llvm::dwarf::DW_UT_partial: - return GetVersion() < 5 ? 11 : 12; - case llvm::dwarf::DW_UT_skeleton: - case llvm::dwarf::DW_UT_split_compile: - return 20; - case llvm::dwarf::DW_UT_type: - case llvm::dwarf::DW_UT_split_type: - return GetVersion() < 5 ? 23 : 24; - } - llvm_unreachable("invalid UnitType."); -} +uint32_t DWARFUnit::GetHeaderByteSize() const { return m_header.getSize(); } std::optional<uint64_t> DWARFUnit::GetStringOffsetSectionItem(uint32_t index) const { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index c05bba36ed74b..9f53d7dcdef53 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -119,6 +119,7 @@ class DWARFUnit : public DWARFExpression::Delegate, public UserID { // Size of the CU data incl. header but without initial length. dw_offset_t GetLength() const { return m_header.getLength(); } uint16_t GetVersion() const override { return m_header.getVersion(); } + llvm::dwarf::DwarfFormat GetFormat() const { return m_header.getFormat(); } const llvm::DWARFAbbreviationDeclarationSet *GetAbbreviations() const; dw_offset_t GetAbbrevOffset() const; uint8_t GetAddressByteSize() const override { >From 845b1c54f8a4fff6222107d182f4fede7f1da805 Mon Sep 17 00:00:00 2001 From: HemangGadhavi <hemang.gadh...@ibm.com> Date: Fri, 27 Jun 2025 11:12:34 -0400 Subject: [PATCH 2/2] Added testcase for the DWARF64 and review comments --- .../SymbolFile/DWARF/DWARFFormValue.cpp | 47 +++------ .../Plugins/SymbolFile/DWARF/DWARFUnit.h | 4 +- .../unittests/SymbolFile/DWARF/CMakeLists.txt | 1 + .../SymbolFile/DWARF/DWARF64UnitTest.cpp | 96 +++++++++++++++++++ 4 files changed, 115 insertions(+), 33 deletions(-) create mode 100644 lldb/unittests/SymbolFile/DWARF/DWARF64UnitTest.cpp diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp index d0cc5edc6678a..ee362073418ee 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -77,10 +77,9 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data, case DW_FORM_strp: case DW_FORM_line_strp: case DW_FORM_sec_offset: - if (m_unit->GetFormat() == DwarfFormat::DWARF32) - m_value.uval = data.GetMaxU64(offset_ptr, 4); - else if (m_unit->GetFormat() == DwarfFormat::DWARF64) - m_value.uval = data.GetMaxU64(offset_ptr, 8); + assert(m_unit); // Unit must be valid + ref_addr_size = m_unit->GetFormParams().getDwarfOffsetByteSize(); + m_value.uval = data.GetMaxU64(offset_ptr, ref_addr_size); break; case DW_FORM_addrx1: case DW_FORM_strx1: @@ -122,14 +121,7 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data, break; case DW_FORM_ref_addr: assert(m_unit); - if (m_unit->GetVersion() <= 2) - ref_addr_size = m_unit->GetAddressByteSize(); - else { - if (m_unit->GetFormat() == DwarfFormat::DWARF32) - ref_addr_size = 4; - else if (m_unit->GetFormat() == DwarfFormat::DWARF64) - ref_addr_size = 8; - } + ref_addr_size = m_unit->GetFormParams().getRefAddrByteSize(); m_value.uval = data.GetMaxU64(offset_ptr, ref_addr_size); break; case DW_FORM_indirect: @@ -176,12 +168,12 @@ static FormSize g_form_sizes[] = { {0, 0}, // 0x0f DW_FORM_udata {0, 0}, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes // for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later - {1, 1}, // 0x11 DW_FORM_ref1 - {1, 2}, // 0x12 DW_FORM_ref2 - {1, 4}, // 0x13 DW_FORM_ref4 - {1, 8}, // 0x14 DW_FORM_ref8 - {0, 0}, // 0x15 DW_FORM_ref_udata - {0, 0}, // 0x16 DW_FORM_indirect + {1, 1}, // 0x11 DW_FORM_ref1 + {1, 2}, // 0x12 DW_FORM_ref2 + {1, 4}, // 0x13 DW_FORM_ref4 + {1, 8}, // 0x14 DW_FORM_ref8 + {0, 0}, // 0x15 DW_FORM_ref_udata + {0, 0}, // 0x16 DW_FORM_indirect {0, 0}, // 0x17 DW_FORM_sec_offset (4 bytes for DWARF32, 8 bytes for DWARF64) {0, 0}, // 0x18 DW_FORM_exprloc @@ -192,7 +184,7 @@ static FormSize g_form_sizes[] = { {0, 0}, // 0x1d DW_FORM_strp_sup (4 bytes for DWARF32, 8 bytes for DWARF64) {1, 16}, // 0x1e DW_FORM_data16 {0, 0}, // 0x1f DW_FORM_line_strp (4 bytes for DWARF32, 8 bytes for DWARF64) - {1, 8}, // 0x20 DW_FORM_ref_sig8 + {1, 8}, // 0x20 DW_FORM_ref_sig8 }; std::optional<uint8_t> DWARFFormValue::GetFixedSize(dw_form_t form, @@ -254,17 +246,9 @@ bool DWARFFormValue::SkipValue(dw_form_t form, return true; case DW_FORM_ref_addr: - ref_addr_size = 4; assert(unit); // Unit must be valid for DW_FORM_ref_addr objects or we will // get this wrong - if (unit->GetVersion() <= 2) - ref_addr_size = unit->GetAddressByteSize(); - else { - if (unit->GetFormat() == DwarfFormat::DWARF32) - ref_addr_size = 4; - else if (unit->GetFormat() == DwarfFormat::DWARF64) - ref_addr_size = 8; - } + ref_addr_size = unit->GetFormParams().getRefAddrByteSize(); *offset_ptr += ref_addr_size; return true; @@ -300,10 +284,9 @@ bool DWARFFormValue::SkipValue(dw_form_t form, case DW_FORM_sec_offset: case DW_FORM_strp: case DW_FORM_line_strp: - if (unit->GetFormat() == DwarfFormat::DWARF32) - *offset_ptr += 4; - else if (unit->GetFormat() == DwarfFormat::DWARF64) - *offset_ptr += 8; + assert(unit); // Unit must be valid + ref_addr_size = unit->GetFormParams().getDwarfOffsetByteSize(); + *offset_ptr += ref_addr_size; return true; // 4 byte values diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index 9f53d7dcdef53..f55400eeaa448 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -119,7 +119,9 @@ class DWARFUnit : public DWARFExpression::Delegate, public UserID { // Size of the CU data incl. header but without initial length. dw_offset_t GetLength() const { return m_header.getLength(); } uint16_t GetVersion() const override { return m_header.getVersion(); } - llvm::dwarf::DwarfFormat GetFormat() const { return m_header.getFormat(); } + const llvm::dwarf::FormParams &GetFormParams() const { + return m_header.getFormParams(); + } const llvm::DWARFAbbreviationDeclarationSet *GetAbbreviations() const; dw_offset_t GetAbbrevOffset() const; uint8_t GetAddressByteSize() const override { diff --git a/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt b/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt index cf8702209a7c3..eb2e00adba64b 100644 --- a/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt +++ b/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt @@ -6,6 +6,7 @@ add_lldb_unittest(SymbolFileDWARFTests DWARFUnitTest.cpp SymbolFileDWARFTests.cpp XcodeSDKModuleTests.cpp + DWARF64UnitTest.cpp LINK_COMPONENTS Support diff --git a/lldb/unittests/SymbolFile/DWARF/DWARF64UnitTest.cpp b/lldb/unittests/SymbolFile/DWARF/DWARF64UnitTest.cpp new file mode 100644 index 0000000000000..fb56b9dba0d51 --- /dev/null +++ b/lldb/unittests/SymbolFile/DWARF/DWARF64UnitTest.cpp @@ -0,0 +1,96 @@ +//===-- DWARF64UnitTest.cpp--------------------------------------------=---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h" +#include "Plugins/SymbolFile/DWARF/DWARFUnit.h" +#include "TestingSupport/Symbol/YAMLModuleTester.h" + +using namespace lldb_private; +using namespace lldb_private::dwarf; +using namespace lldb_private::plugin::dwarf; + +TEST(DWARF64UnitTest, DWARF64DebugInfoAndCU) { + const char *yamldata = R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_PPC64 +DWARF: + debug_str: + - 'clang version 18.1.8 (clang-18.1.8-1)' + - 'main' + debug_abbrev: + - Table: + - Code: 0x1 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_strp + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_stmt_list + Form: DW_FORM_sec_offset + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data4 + - Code: 0x02 + Tag: DW_TAG_subprogram + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + debug_info: + - Format: DWARF64 + Version: 4 + AbbrOffset: 0x0 + AddrSize: 8 + Entries: + - AbbrCode: 0x1 + Values: + - Value: 0x0 + - Value: 0x04 + - Value: 0x0 + - Value: 0xdeadbeef + - Value: 0xdeadbeef + - AbbrCode: 0x2 + Values: + - Value: 0x1 + - AbbrCode: 0x0 +)"; + + YAMLModuleTester t(yamldata); + auto *symbol_file = + llvm::cast<SymbolFileDWARF>(t.GetModule()->GetSymbolFile()); + DWARFUnit *unit = symbol_file->DebugInfo().GetUnitAtIndex(0); + ASSERT_TRUE(unit); + ASSERT_EQ(unit->GetFormParams().Format, DwarfFormat::DWARF64); + ASSERT_EQ(unit->GetVersion(), 4); + ASSERT_EQ(unit->GetAddressByteSize(), 8); + + DWARFFormValue form_value; + const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE(); + ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit); + ASSERT_EQ(unit->GetProducer(), eProducerClang); + ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus); + auto attrs = cu_entry->GetAttributes(unit, DWARFDebugInfoEntry::Recurse::yes); + attrs.ExtractFormValueAtIndex(2, form_value); // Validate DW_AT_stmt_list + ASSERT_EQ(form_value.Unsigned(), 0UL); + attrs.ExtractFormValueAtIndex(3, form_value); // Validate DW_AT_low_pc + ASSERT_EQ(form_value.Unsigned(), 0xdeadbeef); + attrs.ExtractFormValueAtIndex(4, form_value); // Validate DW_AT_high_pc + ASSERT_EQ(form_value.Unsigned(), 0xdeadbeef); + + DWARFDIE cu_die(unit, cu_entry); + auto declaration = cu_die.GetFirstChild(); + ASSERT_TRUE(declaration.IsValid()); + ASSERT_EQ(declaration.Tag(), DW_TAG_subprogram); +} _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits