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

Reply via email to