Author: Yao Qi
Date: 2026-07-06T10:50:24+01:00
New Revision: 8470dfb1e6190cc42c3eb151884533b8b4aba7e6

URL: 
https://github.com/llvm/llvm-project/commit/8470dfb1e6190cc42c3eb151884533b8b4aba7e6
DIFF: 
https://github.com/llvm/llvm-project/commit/8470dfb1e6190cc42c3eb151884533b8b4aba7e6.diff

LOG: [lldb] Guard DW_OP_convert against null DWARF unit and empty stack 
(#207008)

`Evaluate_DW_OP_convert` dereferenced `eval_ctx.dwarf_cu` (the
`DWARFExpression` Delegate) whenever the operand DIE offset was
non-zero,
and unconditionally read `eval_ctx.stack.back()`.  When a DWARF
expression is evaluated without a DWARF unit (as the
lldb-dwarf-expression-fuzzer does), two operand shapes crash:

- `DW_OP_convert` with a non-zero offset calls
  `dwarf_cu->GetDIEBitSizeAndSign(...)` on a null Delegate.
- `DW_OP_convert` with nothing on the stack reads the back of an empty
  vector.

The unit test feeds both with `dwarf_cu == nullptr` and crashes:

```
[ RUN      ] DWARFExpression.DW_OP_convert
 #2 SignalHandler(int, __siginfo*, void*)
 #4 DWARFExpression::Evaluate(...)
 #5 Evaluate(ArrayRef<unsigned char>, ...)
```

(SIGSEGV, the process aborts.)

Bail out with an error when the stack is empty, and when a non-zero DIE
offset is requested without a DWARF unit, instead of crashing.

Extends `DWARFExpression.DW_OP_convert` with these two cases, which
crash
without the fix.

---------

Co-authored-by: Michael Buch <[email protected]>

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 5a3c99caeb1bb..985a2dfecd38f 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -1214,6 +1214,9 @@ static llvm::Error Evaluate_DW_OP_convert(EvalContext 
&eval_ctx,
     if (!bit_size)
       return llvm::createStringError("unspecified architecture");
   } else {
+    if (!eval_ctx.dwarf_cu)
+      return llvm::createStringError(
+          "DW_OP_convert with a DIE offset requires a DWARF unit");
     auto bit_size_sign_or_err =
         eval_ctx.dwarf_cu->GetDIEBitSizeAndSign(relative_die_offset);
     if (!bit_size_sign_or_err)

diff  --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp 
b/lldb/unittests/Expression/DWARFExpressionTest.cpp
index 305c4af2582db..75162ca0b5f3e 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -574,6 +574,19 @@ TEST(DWARFExpression, DW_OP_convert) {
   EXPECT_THAT_ERROR(
       t.Eval({DW_OP_const1s, 'X', DW_OP_convert, 0x1d}).takeError(),
       llvm::Failed());
+
+  // A non-zero DIE offset with no DWARF unit.
+  EXPECT_THAT_ERROR(
+      Evaluate({DW_OP_const1s, 'X', DW_OP_convert, 0x01}, nullptr, nullptr)
+          .takeError(),
+      llvm::FailedWithMessage(
+          "DW_OP_convert with a DIE offset requires a DWARF unit"));
+
+  // DW_OP_convert with an empty stack.
+  EXPECT_THAT_ERROR(
+      Evaluate({DW_OP_convert, 0x00}, nullptr, nullptr).takeError(),
+      llvm::FailedWithMessage("DW_OP_convert needs at least 1 stack entries "
+                              "(stack has 0 entries)"));
 }
 
 TEST(DWARFExpression, DW_OP_stack_value) {


        
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to