[lldb] lldb fails to treat `DW_OP_regN` and `DW_OP_regx N` as equivalent register descriptions inside DW_OP_entry_value
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
## Summary
[DWARF v5](https://dwarfstd.org/doc/DWARF5.pdf) says that `DW_OP_entry_value` takes a block containing either a DWARF expression or a **register location description** (Sections 2.5.1.7 and 2.6.1.1.3). For the register-description case, the important thing is which register is being described, not which opcode encoding was used to name it. For example, `DW_OP_reg5` and `DW_OP_regx 5` are different opcode encodings of the same register description.
While reviewing [`lldb/source/Expression/DWARFExpression.cpp`](https://github.com/llvm/llvm-project/blob/main/lldb/source/Expression/DWARFExpression.cpp), specifically `Evaluate_DW_OP_entry_value`, I noticed that LLDB searches call-site parameters by first checking that the nested block lengths are the same and then comparing the raw bytes directly with `memcmp(...)`.
That is too strict for register location descriptions inside `DW_OP_entry_value`. Two blocks can name the same register while having different byte encodings, such as `DW_OP_reg5` and `DW_OP_regx 5`.
So the following two expressions are equivalent:
```text
DW_OP_entry_value [DW_OP_reg5]
DW_OP_stack_value
```
```text
DW_OP_entry_value [DW_OP_regx 5]
DW_OP_stack_value
```
They are not two different computations. They are two encodings of the same entry-register description.
## Comparison with GDB
GDB appears to handle this correctly: it treats `DW_OP_reg5` and `DW_OP_regx 5` as the same register description for `DW_OP_entry_value` matching.
LLDB does not appear to do that. As a result, it can fail to match a legal `DW_OP_entry_value` block against the corresponding call-site parameter, even though the two forms name the same DWARF register.
This also matches the implementation strategy difference:
- GDB normalizes the nested block to a DWARF register number before matching
- LLDB appears to require byte-for-byte equality of the nested block
## Potential Fix Direction
Instead of matching the `DW_OP_entry_value` sub-block by raw byte equality, LLDB should normalize the register-description case before matching.
At minimum, `DW_OP_regN` and `DW_OP_regx N` should match as the same register description when they name the same DWARF register number.
There is already related normalization-style logic elsewhere in the same file: `DWARFExpression::MatchesOperand` treats `DW_OP_regN` and `DW_OP_regx N` as the same register operand after decoding the register number. A similar approach for `DW_OP_entry_value` matching may be enough to fix this issue cleanly.
Contributor guide
Research direction
Start in lldb/source/Expression/DWARFExpression.cpp at Evaluate_DW_OP_entry_value, where nested blocks are length-checked and compared with memcmp. Read the related DWARFExpression::MatchesOperand normalization logic and the cited DWARF sections. Done means equivalent DW_OP_regN and DW_OP_regx N descriptions match when they name the same register.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers, devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100