llvm / llvm/llvm-project

[lldb] DW_OP_stack_value materializes register location descriptions as values instead of rejecting them

Open
#209,451 1 comment 0 reactions 0 assignees View on GitHub
accepts-invalid lldb
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

LLDB accepts `DW_OP_stack_value` when the top stack entry is a register location description produced by `DW_OP_regN` or `DW_OP_regx`.

Under LLVM's [location-description stack extension](https://llvm.org/docs/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack.html#a-2-5-4), `DW_OP_reg*` pushes a register location description, while `DW_OP_stack_value` pops an entry that **"must be a value."** The extension defines no implicit conversion from a register location description to a value. Register contents can be obtained as a value through `DW_OP_deref*` or `DW_OP_regval_type`; `DW_OP_breg*` is available when the register contents are instead used to form an address.

This is related to the register-location arithmetic issue (#203186), but it reaches a different missing precondition: no arithmetic operation is involved here; `DW_OP_stack_value` itself accepts the wrong stack-entry kind.

For a top-frame register location:

```text
DW_OP_reg6
DW_OP_stack_value
```

This expression should be rejected because `DW_OP_stack_value` requires a value.

## Source Evidence

In [`DWARFExpression.cpp`](https://github.com/llvm/llvm-project/blob/main/lldb/source/Expression/DWARFExpression.cpp), the `DW_OP_reg*` handler records `Register` location state but represents the location using the eagerly read register contents:

```cpp
eval_ctx.loc_desc_kind = Register;
...
ReadRegisterValueAsScalar(..., tmp);
stack.push_back(tmp);
```

`DW_OP_stack_value` then overwrites the location state and forces that payload to `Scalar` without checking that its input was a value:

```cpp
case DW_OP_stack_value:
eval_ctx.loc_desc_kind = Implicit;
stack.back().SetValueType(Value::ValueType::Scalar);
break;
```

The eager register payload is an implementation detail of the register location description. Treating it as the input value silently performs a register-location-to-value conversion that the extension does not define.

Contributor guide

Open the contributing guide

Research direction

Start in lldb/source/Expression/DWARFExpression.cpp, reading the DW_OP_reg* and DW_OP_stack_value handlers and the surrounding location-description state. Exercise the shown DW_OP_reg6 followed by DW_OP_stack_value expression through LLDB's existing DWARF expression testing entry points; done means register location descriptions are rejected by DW_OP_stack_value while valid value inputs remain accepted.

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.