[cfe-dev] A new builtin: __builtin_stack_pointer()

Richard Smith richard at metafoo.co.uk
Sun Nov 10 19:09:06 PST 2013


On Sun, Nov 10, 2013 at 1:46 PM, PaX Team <pageexec at freemail.hu> wrote:

> On 8 Nov 2013 at 17:37, Richard Smith wrote:
>
> > I don't think you've answered my main question: what semantics do you
> want
> > the returned pointer to have (and how can any correct code ever do
> anything
> > with the pointer)? If you just want some approximation of the stack
> pointer
> > to use as a key, __builtin_frame_address seems like it would work.
>
> linux can process IRQs on a separate kernel stack (instead of the normal
> per-process kernel stacks) in order the reduce the chances of kernel stack
> overflows (they're very limited in size). now linux also wants to be able
> to walk across these stacks when producing a diagnostic backtrace (that may
> very well happen while processing an IRQ on its own stack). different archs
> solve this problem of finding one stack from another in different ways.
>
> specifically the i386 kernel (arch/x86/kernel/irq_32.c) saves the 'current
> stack pointer' value somewhere on the IRQ stack (before switching the esp
> register, which is done in asm) and the backtrace code (that loop in
> dump_trace
> in arch/x86/kernel/dumpstack_32.c) 'knows' where to find it and continues
> the trace from this saved stack pointer value. all this logic probably
> breaks
> the standard in a dozen ways so strictly speaking it's nowhere near
> compliant
> but 'it works' (with gcc anyway ;). (as a sidenote, there's more stack
> walking
> code in linux that assumes certain compiler behaviour but let's fix one
> problem
> at a time)
>
> now with that background let me try to answer your questions:
>
> - __builtin_frame_address is indeed good enough for this purpose (and i
> can't
>   find more use of the stack register in C, but maybe Behan knows of more
> where
>   an exact value is important)
>

That seems like a good answer, if it works. It seems like we could choose
to copy everything on the current stack frame into some global storage and
back around any call to __builtin_stack_address, and thus one possible
correct implementation would be to always return the frame pointer.

- the resulting value is expected to be a valid address (at the time it's
> taken)
>   as the kernel *will* dereference it later but there're no other
> requirements.

> Do you *also* need a guarantee that the stack pointer will not change
> > between the call to __builtin_stack_address and the end of the function
> > (except in callees)?
>
> no, it just has to be an address that belongs to the current stack frame
> at the
> time. basically it'll define the start address from which the kernel will
> look
> for certain things (such as code addresses in the hope that saved return
> addresses
> will be found this way) on the stack.
>
> > Can we reorder a call to alloca() past __builtin_stack_address?
> > Can we reorder the initialization of a VLA past a call to
> > __builtin_stack_address? Can the backend choose to perform a stack
> > adjustment afterwards?
>
> yes for all.


Thanks. Seems like the kernel can rely on being able to read through
pointers that used to point to the stack because it knows that the readable
portion of the stack never shrinks, right? (This could go wrong for
programs using segmented stacks.)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20131110/e0f59934/attachment.html>


More information about the cfe-dev mailing list