Fix DW_OP_convert to resolve the CU relative offset correctly.
authorGreg Clayton <gclayton@fb.com>
Fri, 9 Sep 2022 23:45:33 +0000 (16:45 -0700)
committerGreg Clayton <gclayton@fb.com>
Mon, 12 Sep 2022 23:53:19 +0000 (16:53 -0700)
Debugging some DWARF5 binaries was causing errors to appear when DWARFExpression::Evaluate was called:

    error: GetDIE for DIE 0x31 is outside of its CU 0x123450

The issue is in the DWARF expression evaluator. Fixed with this.

Differential Revision: https://reviews.llvm.org/D133623

lldb/source/Expression/DWARFExpression.cpp
lldb/unittests/Expression/DWARFExpressionTest.cpp
lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.cpp
lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.h

index 283e040..8e9c868 100644 (file)
@@ -2374,9 +2374,11 @@ bool DWARFExpression::Evaluate(
           return false;
         }
       } else {
-        // Retrieve the type DIE that the value is being converted to.
+        // Retrieve the type DIE that the value is being converted to. This
+        // offset is compile unit relative so we need to fix it up.
+        const uint64_t abs_die_offset = die_offset +  dwarf_cu->GetOffset();
         // FIXME: the constness has annoying ripple effects.
-        DWARFDIE die = const_cast<DWARFUnit *>(dwarf_cu)->GetDIE(die_offset);
+        DWARFDIE die = const_cast<DWARFUnit *>(dwarf_cu)->GetDIE(abs_die_offset);
         if (!die) {
           if (error_ptr)
             error_ptr->SetErrorString("Cannot resolve DW_OP_convert type DIE");
index 2678db9..8d23f1c 100644 (file)
@@ -61,6 +61,9 @@ static llvm::Expected<Scalar> Evaluate(llvm::ArrayRef<uint8_t> expr,
 
 class DWARFExpressionTester : public YAMLModuleTester {
 public:
+  DWARFExpressionTester(llvm::StringRef yaml_data, size_t cu_index) :
+      YAMLModuleTester(yaml_data, cu_index) {}
+
   using YAMLModuleTester::YAMLModuleTester;
   llvm::Expected<Scalar> Eval(llvm::ArrayRef<uint8_t> expr) {
     return ::Evaluate(expr, m_module_sp, m_dwarf_unit);
@@ -179,6 +182,17 @@ DWARF:
   debug_info:
     - Version:         4
       AddrSize:        8
+      AbbrevTableID:   0
+      AbbrOffset:      0x0
+      Entries:
+        - AbbrCode:        0x00000001
+          Values:
+            - Value:           0x000000000000000C
+        - AbbrCode:        0x00000000
+    - Version:         4
+      AddrSize:        8
+      AbbrevTableID:   0
+      AbbrOffset:      0x0
       Entries:
         - AbbrCode:        0x00000001
           Values:
@@ -214,14 +228,16 @@ DWARF:
             - Value:           0x000000000000000b # DW_ATE_numeric_string
             - Value:           0x0000000000000001
         - AbbrCode:        0x00000000
+
 )";
+  // Compile unit relative offsets to each DW_TAG_base_type
   uint8_t offs_uint32_t = 0x0000000e;
   uint8_t offs_uint64_t = 0x00000011;
   uint8_t offs_sint64_t = 0x00000014;
   uint8_t offs_uchar = 0x00000017;
   uint8_t offs_schar = 0x0000001a;
 
-  DWARFExpressionTester t(yamldata);
+  DWARFExpressionTester t(yamldata, /*cu_index=*/1);
   ASSERT_TRUE((bool)t.GetDwarfUnit());
 
   // Constant is given as little-endian.
index 15db624..14e7c7d 100644 (file)
@@ -14,7 +14,7 @@
 
 using namespace lldb_private;
 
-YAMLModuleTester::YAMLModuleTester(llvm::StringRef yaml_data) {
+YAMLModuleTester::YAMLModuleTester(llvm::StringRef yaml_data, size_t cu_index) {
   llvm::Expected<TestFile> File = TestFile::fromYaml(yaml_data);
   EXPECT_THAT_EXPECTED(File, llvm::Succeeded());
   m_file = std::move(*File);
@@ -22,5 +22,5 @@ YAMLModuleTester::YAMLModuleTester(llvm::StringRef yaml_data) {
   m_module_sp = std::make_shared<Module>(m_file->moduleSpec());
   auto &symfile = *llvm::cast<SymbolFileDWARF>(m_module_sp->GetSymbolFile());
 
-  m_dwarf_unit = symfile.DebugInfo().GetUnitAtIndex(0);
+  m_dwarf_unit = symfile.DebugInfo().GetUnitAtIndex(cu_index);
 }
index 60715ab..1b1bf22 100644 (file)
@@ -33,7 +33,7 @@ protected:
 
 public:
   /// Parse the debug info sections from the YAML description.
-  YAMLModuleTester(llvm::StringRef yaml_data);
+  YAMLModuleTester(llvm::StringRef yaml_data, size_t cu_index = 0);
   DWARFUnit *GetDwarfUnit() const { return m_dwarf_unit; }
   lldb::ModuleSP GetModule() const { return m_module_sp; }
 };