RE: [PATCH v2] ARM: unwind: improve unwinders for noreturn case

From: David Laight
Date: Thu Mar 21 2024 - 08:57:47 EST


From: Russell King
> Sent: 21 March 2024 12:23
..
> > That might mean you can get the BL in the middle of a function
> > but where the following instruction is for the 'no stack frame'
> > side of the branch.
> > That is very likely to break any stack offset calculations.
>
> No it can't. At any one point in the function, the stack has to be in
> a well defined state, so that access to local variables can work, and
> also the stack can be correctly unwound. If there exists a point in
> the function body which can be reached where the stack could be in two
> different states, then the stack can't be restored to the parent
> context.

Actually you can get there with a function that has a lot of args.
So you can have:
if (...) {
push x
bl func
add %sp, #8
}
code;
which is fine.
But if 'func' is 'noreturn' then the 'add %sp, #8' can be discarded
and then the saved LR is that of 'code' - but the stack offset is wrong.

> > > This is where the problem lies - because the link register value
> > > created by the BL instruction will point to the instruction after the
> > > BL which will _not_ part of the function that invoked the BL. That
> > > will probably cause issues for the ELF unwinder, which means this
> > > issue probably goes beyond _just_ printing the function name.
> >
> > Isn't this already in the unwinder?
> > A BL itself isn't going to fault with PC = next-instruction.
>
> You are missing the fact that the PC can be the saved LR, and thus
> can very well be the next instruction.

A PC from LR will always be the next instruction.
It is only the PC from a fault frame that is the current one.
The unwinder probably need to be told which one it has.
(Or add 4 the fault frame PC so that the unwinder can subtract
4 from it.)

At least (I don't think) there are any functions where the
called code is responsible for removing arguments.
That is a whole different bag of worms.

David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)