Author: MrEven132
Date: 2026-08-28T18:30:23+08:00
New Revision: dfec0b3ec41f382fa6a5f676bd998315fc71413f

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

LOG: [lldb] Handle implicit values followed by full-width piece operations 
(#219160)

`DW_OP_implicit_value` stores its bytes in a `Value` whose internal type
is `HostAddress`. The `DW_OP_piece` and `DW_OP_bit_piece` evaluators
therefore mistook the backing-buffer address for a memory location and
rejected valid full-width pieces.

Use the saved implicit location-description kind to recognize this
storage representation. Full-width byte pieces and zero-offset
full-width bit pieces now preserve the backing bytes, while genuine host
addresses and partial pieces retain their existing behavior.

Add a unit test for both expressions from the issue.

Fixes #203224

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 d22634d63e875..60577bac07167 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -1183,6 +1183,15 @@ static llvm::Error Evaluate_DW_OP_piece(EvalContext 
&eval_ctx,
       }
     } break;
     case Value::ValueType::HostAddress: {
+      // DW_OP_implicit_value uses a host-address Value to own its bytes. For
+      // a full-width piece, the address is only an implementation detail and
+      // the backing bytes are the value of the piece.
+      if (piece_locdesc == Implicit &&
+          curr_piece_source_value.GetBuffer().GetByteSize() ==
+              piece_byte_size) {
+        curr_piece = curr_piece_source_value;
+        break;
+      }
       return llvm::createStringError(
           "failed to read memory DW_OP_piece(%" PRIu64
           ") from host address 0x%" PRIx64,
@@ -2050,7 +2059,8 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
         return llvm::createStringError(
             "expression stack needs at least 1 item for DW_OP_bit_piece");
       } else {
-        UpdateValueTypeFromLocationDescription(eval_ctx, 
eval_ctx.loc_desc_kind,
+        const LocationDescriptionKind piece_locdesc = eval_ctx.loc_desc_kind;
+        UpdateValueTypeFromLocationDescription(eval_ctx, piece_locdesc,
                                                &stack.back());
         // Reset for the next piece.
         eval_ctx.loc_desc_kind = Memory;
@@ -2073,7 +2083,18 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
 
         case Value::ValueType::FileAddress:
         case Value::ValueType::LoadAddress:
+          return llvm::createStringError(
+              "unable to extract DW_OP_bit_piece(bit_size = %" PRIu64
+              ", bit_offset = %" PRIu64 ") from an address value.",
+              piece_bit_size, piece_bit_offset);
+
         case Value::ValueType::HostAddress:
+          // As above, a full-width DW_OP_implicit_value piece refers to the
+          // backing bytes, not the address of that backing storage.
+          if (piece_locdesc == Implicit && piece_bit_offset == 0 &&
+              piece_bit_size % 8 == 0 &&
+              stack.back().GetBuffer().GetByteSize() == piece_bit_size / 8)
+            break;
           return llvm::createStringError(
               "unable to extract DW_OP_bit_piece(bit_size = %" PRIu64
               ", bit_offset = %" PRIu64 ") from an address value.",

diff  --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp 
b/lldb/unittests/Expression/DWARFExpressionTest.cpp
index aa8e17a88cc34..4b4b911800ae8 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -996,6 +996,17 @@ TEST(DWARFExpression, DW_OP_implicit_value) {
                        llvm::HasValue(0x40302010u));
 }
 
+TEST(DWARFExpression, DW_OP_implicit_value_piece) {
+  const std::vector<uint8_t> expected = {0x9c, 0xee, 0x4c, 0x86};
+
+  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_implicit_value, 4, 0x9c, 0xee, 0x4c,
+                                 0x86, DW_OP_piece, 4}),
+                       ExpectHostAddress(expected));
+  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_implicit_value, 4, 0x9c, 0xee, 0x4c,
+                                 0x86, DW_OP_bit_piece, 32, 0}),
+                       ExpectHostAddress(expected));
+}
+
 TEST(DWARFExpression, DW_OP_unknown) {
   EXPECT_THAT_EXPECTED(
       Evaluate({0xff}),


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

Reply via email to