[llvm] da0828b - [lldb] Enable support for DWARF64 format handling (#145645)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 1 06:05:43 PDT 2025
Author: Hemang Gadhavi
Date: 2025-07-01T18:35:40+05:30
New Revision: da0828b1e93c0fb6266225d8e6d41b2d9ef1f346
URL: https://github.com/llvm/llvm-project/commit/da0828b1e93c0fb6266225d8e6d41b2d9ef1f346
DIFF: https://github.com/llvm/llvm-project/commit/da0828b1e93c0fb6266225d8e6d41b2d9ef1f346.diff
LOG: [lldb] Enable support for DWARF64 format handling (#145645)
This PR introduces support for the DWARF64 format, enabling handling of
64-bit DWARF sections as defined by the DWARF specification. The update
includes adjustments to header parsing and modification of form values
to accommodate 64-bit offsets and values.
Also Added the testcase to verify the DWARF64 format.
Added:
lldb/unittests/SymbolFile/DWARF/DWARF64UnitTest.cpp
Modified:
lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
lldb/unittests/SymbolFile/DWARF/CMakeLists.txt
llvm/docs/ReleaseNotes.md
Removed:
################################################################################
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index fd3d45cef4c5e..2e98e3c33acaf 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -77,7 +77,9 @@ 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);
+ assert(m_unit);
+ 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:
@@ -119,10 +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
- ref_addr_size = 4;
+ ref_addr_size = m_unit->GetFormParams().getRefAddrByteSize();
m_value.uval = data.GetMaxU64(offset_ptr, ref_addr_size);
break;
case DW_FORM_indirect:
@@ -165,7 +164,7 @@ 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
@@ -175,7 +174,7 @@ static FormSize g_form_sizes[] = {
{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
+ {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,7 +182,7 @@ 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
+ {0, 0}, // 0x1f DW_FORM_line_strp (4 bytes for DWARF32, 8 bytes for DWARF64)
{1, 8}, // 0x20 DW_FORM_ref_sig8
};
@@ -246,13 +245,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
- ref_addr_size = 4;
+ ref_addr_size = unit->GetFormParams().getRefAddrByteSize();
*offset_ptr += ref_addr_size;
return true;
@@ -288,7 +283,9 @@ bool DWARFFormValue::SkipValue(dw_form_t form,
case DW_FORM_sec_offset:
case DW_FORM_strp:
case DW_FORM_line_strp:
- *offset_ptr += 4;
+ assert(unit);
+ 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.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..f55400eeaa448 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -119,6 +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(); }
+ 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..2303f68674e4c
--- /dev/null
+++ b/lldb/unittests/SymbolFile/DWARF/DWARF64UnitTest.cpp
@@ -0,0 +1,86 @@
+//===-- 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
+ - 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
+ - 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);
+
+ DWARFDIE cu_die(unit, cu_entry);
+ auto declaration = cu_die.GetFirstChild();
+ ASSERT_TRUE(declaration.IsValid());
+ ASSERT_EQ(declaration.Tag(), DW_TAG_subprogram);
+}
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 73ae2ee599640..ae4ce9380d491 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -304,6 +304,7 @@ Changes to LLDB
stop reason = SIGSEGV: sent by tkill system call (sender pid=649752, uid=2667987)
```
* ELF Cores can now have their siginfo structures inspected using `thread siginfo`.
+* LLDB now supports the `DWARF64` debugging information format.
### Changes to lldb-dap
More information about the llvm-commits
mailing list