[Lldb-commits] [lldb] [llvm] [lldb] Use llvm::DWARFExpression::iterator in DWARFExpression::Evaluate (PR #190556)

Shivam Kunwar via lldb-commits lldb-commits at lists.llvm.org
Sun Apr 5 23:46:00 PDT 2026


================
@@ -2233,31 +2230,55 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
         return llvm::createStringError("DW_OP_GNU_const_index found without a "
                                        "compile unit being specified");
       }
-      uint64_t index = opcodes.GetULEB128(&offset);
+      uint64_t index = op->getRawOperand(0);
       lldb::addr_t value = dwarf_cu->ReadAddressFromDebugAddrSection(index);
       stack.push_back(Scalar(value));
     } break;
 
     case DW_OP_GNU_entry_value:
     case DW_OP_entry_value: {
+      const uint64_t block_size = op->getRawOperand(0);
+      uint64_t block_offset = op->getEndOffset();
+
+      llvm::Error error = llvm::Error::success();
+      llvm::ArrayRef<uint8_t> block_data = llvm::arrayRefFromStringRef(
+          expr_data.getBytes(&block_offset, block_size, &error));
+
+      if (error)
+        return error;
+
       if (llvm::Error err = Evaluate_DW_OP_entry_value(stack, exe_ctx, reg_ctx,
-                                                       opcodes, offset, log))
+                                                       block_data, log))
         return llvm::createStringError(
             "could not evaluate DW_OP_entry_value: %s",
             llvm::toString(std::move(err)).c_str());
-      break;
+
+      op = op.skipBytes(block_size);
+      continue;
     }
 
     default:
       if (dwarf_cu) {
-        if (dwarf_cu->ParseVendorDWARFOpcode(op, opcodes, offset, reg_ctx,
+        const uint64_t operands_offset = op_offset + 1;
+        uint64_t offset = operands_offset; // Updated by the callee.
+        if (dwarf_cu->ParseVendorDWARFOpcode(opcode, expr_data, offset, reg_ctx,
                                              reg_kind, stack)) {
-          break;
+          // This is a little tricky. If LLVM knows about this vendor-specific
+          // operation, `getEndOffset()` points past its last operand. If LLVM
+          // knows nothing about this operation, `getEndOffset()` points to its
+          // opcode. In both cases `offset` will point to the next operation,
+          // but we can't use it directly because the only available mutating
+          // method of `iterator` (not counting `operator++`) is `skipBytes()`.
+          // So we calculate the offset and pass it to `skipBytes()`.
+          uint64_t offset_to_next_op = offset - op->getEndOffset();
----------------
phyBrackets wrote:

Worth an assertion that `offset >= op->getEndOffset()`

https://github.com/llvm/llvm-project/pull/190556


More information about the lldb-commits mailing list