This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH] gas: Improve documentation for cfi_remember/restore_state
- From: Alan Modra <amodra at gmail dot com>
- To: Martin Galvan <martin dot galvan at tallertechnologies dot com>
- Cc: binutils at sourceware dot org, nickc at redhat dot com
- Date: Fri, 15 Apr 2016 08:46:03 +0930
- Subject: Re: [PATCH] gas: Improve documentation for cfi_remember/restore_state
- Authentication-results: sourceware.org; auth=none
- References: <1460584160-17648-1-git-send-email-martin dot galvan at tallertechnologies dot com> <20160414063908 dot GE12302 at bubble dot grove dot modra dot org> <CAOKbPbZNwAJYOn0U5qmkWY0bGb873N1hduPZ0sCfc960zXwvJQ at mail dot gmail dot com>
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_remember_state
.cfi_def_cfa 7, 8
movl $1, %edi
jmp *%rax
.L4:
.cfi_restore_state
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