This is the mail archive of the mailing list for the binutils project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] gas: Improve documentation for cfi_remember/restore_state

On Thu, Apr 14, 2016 at 11:23:08AM -0300, Martin Galvan wrote:
> You mean something like:
>     je label
>     popq %rbx
>     .cfi_remember_state
>     .cfi_restore %rbx
>     popq %rbp
>     .cfi_restore %rbp
>     popq %r12
>     .cfi_restore %r12
>     ret
> label:
>     .cfi_restore_state
>     /* Do something else */
> In that case we're using .cfi_restore_state to save us having to use
> multiple CFI directives to recreate the original save locations.

Yes, exactly.  However the above example shows a gcc bug!  Presumably
the cfa is set to rbp, because if the cfa was rsp you'd need cfa
offset adjustment on each pop.  So when rbp is popped, cfa ought to be
set to rsp with an offset, and there be a cfa offset adjustment on the
pop of r12.  The bug would show up if an asynchronous interrupt was
taken after the pop of rbp, and the signal handler wanted to unwind
the stack for some reason.

Hmm, seems like current mainline gcc is buggy in this area on x86_64.
I see this sort of thing around a tail call:
        je      .L4
        popq    %rbp
        .cfi_def_cfa 7, 8
        movl    $1, %edi
        jmp     *%rax
So the cfa is set back to rsp on popping rbp, but there ought to be a
".cfi_restore 6".  Otherwise when an async interrupt hits after the
pop of rbp, the unwinder will load rbp from the stack, which has just
been trashed by the interrupt handler..

It might be better to choose an example from gcc -fomit-frame-pointer
-fasynchronous-unwind-tables code.

Alan Modra
Australia Development Lab, IBM

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]