[lldb-dev] Unwinding call frames with separated data and return address stacks
Jason Molenda via lldb-dev
lldb-dev at lists.llvm.org
Mon Mar 4 13:05:51 PST 2019
Hi Tom, interesting problem you're working on there.
I'm not sure any of the DWARF expression operators would work here. You want to have an expression that works for a given frame, saying "to find the caller's pc value, look at the saved-pc stack, third entry from the bottom of that stack." But that would require generating a different DWARF expression for the frame each time it shows up in a backtrace - which is unlike lldb's normal design of having an UnwindPlan for a function which is computed once and reused for the duration of the debug session.
I supposed you could add a user-defined DW_OP which means "get the current stack frame number" and then have your expression deref the emulated saved-pc stack to get the value?
lldb uses an intermediate representation of unwind information (UnwindPlan) which will use a DWARF expression, but you could also add an entry to UnwindPlan::Row::RegisterLocation::RestoreType which handled this, I suppose.
> On Mar 4, 2019, at 2:46 AM, Thomas Goodfellow via lldb-dev <lldb-dev at lists.llvm.org> wrote:
> I'm adding LLDB support for an unconventional platform which uses two
> stacks: one purely for return addresses and another for frame context
> (spilled registers, local variables, etc). There is no explicit link
> between the two stacks, i.e. the frame context doesn't include any
> pointer or index to identify the return address: the epilog for a
> subroutine amounts to unwinding the frame context then finally popping
> the top return address from the return stack. It has some resemblance
> to the Intel CET scheme of shadow stacks, but without the primary
> stack having a copy of the return address.
> I can extend the emulation of the platform to better support LLDB. For
> example while the real hardware platform provides no access to the
> return address stack the emulation can expose it in the memory map,
> provide an additional debug register for querying it, etc, which DWARF
> expressions could then extract return addresses from. However doing
> this seems to require knowing the frame number and I haven't found a
> way of doing this (a pseudo-register manipulated by DWARF expressions
> worked but needed some LLDB hacks to sneak it through the existing
> link register handling, also seemed likely to be unstable against LLDB
> implementation changes)
> Is there a way to access the call frame number (or a reliable proxy)
> from a DWARF expression? Or an existing example of unwinding a shadow
> lldb-dev mailing list
> lldb-dev at lists.llvm.org
More information about the lldb-dev