llvm / llvm/llvm-project

[lldb] lldb fails to treat `DW_OP_regN` and `DW_OP_regx N` as equivalent register descriptions inside DW_OP_entry_value

Open
#202,842 1 comment 0 reactions 0 assignees View on GitHub
lldb
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.