[lldb] DW_OP_bit_piece is rejected for memory location descriptions
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
LLDB rejects `DW_OP_bit_piece` when the preceding location description refers to target memory. [DWARF v5 Section 2.6.1.2](https://dwarfstd.org/doc/DWARF5.pdf) specifies that, for a memory location, `DW_OP_bit_piece` describes bits relative to the address on top of the DWARF stack. LLVM's [location-description stack extension](https://llvm.org/docs/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack.html) likewise defines it as the bit-granular counterpart of `DW_OP_piece`.
This is related to #208888, which covers an empty location being rejected when the stack has no entry. This report covers a different branch: the stack contains a valid `LoadAddress`, but LLDB explicitly rejects it as an address value.
This is also distinct from #203224. That issue is rooted in `DW_OP_implicit_value` representing its payload as `ValueType::HostAddress`, which loses the implicit-storage semantics before piece composition. The expression here contains no `DW_OP_implicit_value`: `DW_OP_breg7 80` correctly produces a genuine `LoadAddress`, and the bug is in `DW_OP_bit_piece` itself rejecting that valid memory source.
## Two Equivalent Cases
These byte-aligned forms describe the same 16 bytes at the same register-relative memory location:
```text
DW_OP_breg7 80
DW_OP_piece 16
```
```text
DW_OP_breg7 80
DW_OP_bit_piece 128, 0
```
GDB evaluates both forms consistently. LLDB evaluates the `DW_OP_piece` form, but rejects the equivalent `DW_OP_bit_piece` form with:
```text
unable to extract DW_OP_bit_piece(bit_size = 128, bit_offset = 0) from an address value.
```
## Source Evidence
In [`DWARFExpression.cpp`](https://github.com/llvm/llvm-project/blob/main/lldb/source/Expression/DWARFExpression.cpp), `DW_OP_breg7 80` produces a genuine target-memory location represented as `ValueType::LoadAddress`. The `DW_OP_bit_piece` handler groups that source with other address kinds and rejects it:
```cpp
case Value::ValueType::FileAddress:
case Value::ValueType::LoadAddress:
case Value::ValueType::HostAddress:
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);
```
By contrast, the byte-granular `Evaluate_DW_OP_piece` path supports `FileAddress` and `LoadAddress` by reading the requested bytes from target memory. A byte-aligned `DW_OP_bit_piece 128, 0` should use the same memory source and cover the same range as `DW_OP_piece 16`, rather than rejecting the location description.
Contributor guide
Research direction
Start in lldb/source/Expression/DWARFExpression.cpp at the DW_OP_bit_piece handler, then compare it with the Evaluate_DW_OP_piece path for FileAddress and LoadAddress values. Check the equivalent DW_OP_breg7 80 expressions and relevant LLDB DWARF expression tests; done means byte-aligned DW_OP_bit_piece reads the same target-memory range as DW_OP_piece without rejecting the LoadAddress.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100