[lldb-dev] Unwinding call frames with separated data and return address stacks

Thomas Goodfellow via lldb-dev lldb-dev at lists.llvm.org
Thu Mar 14 01:01:31 PDT 2019

Hi Pavel

Thanks for that very useful notion - adding a fake stack pointer to
the target was indeed the least-intrusive approach (I had tried the
RestoreType approach suggested by Jason and it seemed likely to work
but required backporting 7.0 fixes into the regrettably-6.0-based

I suspect it may be a mild guideline for avoiding further pain on this
unconventional target: when necessary use the platform emulation to
fake its being conventional.


On Tue, 5 Mar 2019 at 12:55, Pavel Labath <pavel at labath.sk> wrote:
> On 04/03/2019 11:46, Thomas Goodfellow via lldb-dev 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
> > stack?
> >
> I'm not sure I fully understood your setup, but it seems to me that this
> could be easily fixed if, in addition to the "fake" memory map, you
> could provide a fake "stack pointer" register which points to it.
> Then, it should be possible to express the unwind info in regular
> debug_frame syntax:
> previous_IP := [ fake_SP ]
> previous_fake_SP := fake_SP +/- sizeof(IP)
> regards,
> pavel

More information about the lldb-dev mailing list