DWARF expression for return address


I have an issue with frame unwinding using .eh_frame

The PC for our architecture is a dword pointer. To enable the LLDB frame unwinder to see it as a byte pointer when using CFI, I encoded the return address value in a DWARF expression.

When RA (r3) is in a register the expression is:
DW_CFA_val_expression: r3 (DW_OP_reg3 (r3); DW_OP_lit2; DW_OP_shl)

When RA has been pushed on the stack (r2), the expression is:
DW_CFA_val_expression: r3 (DW_OP_breg2 (r2): -8; DW_OP_deref; DW_OP_lit2; DW_OP_shl)

Up until r217185 the stack unwinding was working fine. But since we resynced our code with the more recent r221593, the return address is not evaluated according to the DWARF expression. The unwinder just uses R3.

(lldb) bt
th1/fr0 requested caller’s saved PC but this UnwindPlan uses a RA reg; getting r3 (3) instead
th1/fr0 supplying caller’s register r3 (3) from the live RegisterContext at frame 0, saved in 3 <<<<<<<<<<<<
th1/fr1 pc = 0x100014
th1/fr0 supplying caller’s saved r2 (2)'s location using eh_frame CFI UnwindPlan
th1/fr0 supplying caller’s register r2 (2) from the stack, saved at CFA plus offset -4
th1/fr1 fp = 0x7fff7f8
th1/fr0 supplying caller’s stack pointer r1 (1) value, computed from CFA
th1/fr1 sp = 0x7fff7d8

Was a bug introduced in LLDB? Or is our use of DWARF expressions to retrieve the return address not “standards compliant”?


I am not sure, you can put a breakpoint in:

DWARFExpression::Evaluate() at DWARFExpression.cpp:1348

And you can step through it to verify.

It will get run in the "if" statement at RegisterContextLLDB.cpp:1445.

Let us know what you find.