[Lldb-commits] [lldb] 5c39c31 - [lldb] Handle jumping to the end in DW_OP_skip/DW_OP_bra

Andy Yankovsky via lldb-commits lldb-commits at lists.llvm.org
Fri Jul 22 02:22:56 PDT 2022


Author: Andy Yankovsky
Date: 2022-07-22T09:22:40Z
New Revision: 5c39c31a99525630dfe684fed48292a50fd0c3c9

URL: https://github.com/llvm/llvm-project/commit/5c39c31a99525630dfe684fed48292a50fd0c3c9
DIFF: https://github.com/llvm/llvm-project/commit/5c39c31a99525630dfe684fed48292a50fd0c3c9.diff

LOG: [lldb] Handle jumping to the end in DW_OP_skip/DW_OP_bra

DW_OP_skip/DW_OP_bra can move offset to the end of the data, which means that this was the last instruction to execute and the interpreter should terminate.

Reviewed By: labath

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

Added: 
    

Modified: 
    lldb/source/Expression/DWARFExpression.cpp
    lldb/unittests/Expression/DWARFExpressionTest.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 9e6b21fc25ea3..25f6a46d805b7 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -1655,11 +1655,16 @@ bool DWARFExpression::Evaluate(
     case DW_OP_skip: {
       int16_t skip_offset = (int16_t)opcodes.GetU16(&offset);
       lldb::offset_t new_offset = offset + skip_offset;
-      if (opcodes.ValidOffset(new_offset))
+      // New offset can point at the end of the data, in this case we should
+      // terminate the DWARF expression evaluation (will happen in the loop
+      // condition).
+      if (new_offset <= opcodes.GetByteSize())
         offset = new_offset;
       else {
         if (error_ptr)
-          error_ptr->SetErrorString("Invalid opcode offset in DW_OP_skip.");
+          error_ptr->SetErrorStringWithFormatv(
+              "Invalid opcode offset in DW_OP_skip: {0}+({1}) > {2}", offset,
+              skip_offset, opcodes.GetByteSize());
         return false;
       }
     } break;
@@ -1684,11 +1689,16 @@ bool DWARFExpression::Evaluate(
         Scalar zero(0);
         if (tmp.ResolveValue(exe_ctx) != zero) {
           lldb::offset_t new_offset = offset + bra_offset;
-          if (opcodes.ValidOffset(new_offset))
+          // New offset can point at the end of the data, in this case we should
+          // terminate the DWARF expression evaluation (will happen in the loop
+          // condition).
+          if (new_offset <= opcodes.GetByteSize())
             offset = new_offset;
           else {
             if (error_ptr)
-              error_ptr->SetErrorString("Invalid opcode offset in DW_OP_bra.");
+              error_ptr->SetErrorStringWithFormatv(
+                  "Invalid opcode offset in DW_OP_bra: {0}+({1}) > {2}", offset,
+                  bra_offset, opcodes.GetByteSize());
             return false;
           }
         }

diff  --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp b/lldb/unittests/Expression/DWARFExpressionTest.cpp
index 5169e5f9a33ec..06f79186bad76 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -131,6 +131,25 @@ TEST(DWARFExpression, DW_OP_const) {
       llvm::HasValue(0xffff010101010101));
 }
 
+TEST(DWARFExpression, DW_OP_skip) {
+  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const1u, 0x42, DW_OP_skip, 0x02, 0x00,
+                                 DW_OP_const1u, 0xff}),
+                       llvm::HasValue(0x42));
+}
+
+TEST(DWARFExpression, DW_OP_bra) {
+  EXPECT_THAT_EXPECTED(
+      // clang-format off
+      Evaluate({
+        DW_OP_const1u, 0x42,     // push 0x42
+        DW_OP_const1u, 0x1,      // push 0x1
+        DW_OP_bra, 0x02, 0x00,   // if 0x1 > 0, then skip 0x0002 opcodes
+        DW_OP_const1u, 0xff,     // push 0xff
+      }),
+      // clang-format on
+      llvm::HasValue(0x42));
+}
+
 TEST(DWARFExpression, DW_OP_convert) {
   /// Auxiliary debug info.
   const char *yamldata = R"(


        


More information about the lldb-commits mailing list