On Tue, Sep 25, 2018 at 9:31 AM, Jakub Jelinek <ja...@redhat.com> wrote: > Hi! > > The indirect branch thunks we emit look like: > __x86_indirect_thunk_rax: > .cfi_startproc > call .LIND1 > .LIND0: > pause > lfence > jmp .LIND0 > .LIND1: > mov %rax, (%rsp) > ret > .cfi_endproc > > The problem is that the CFI is incorrect. On the first entry it is correct, > the default is CFA %rsp+8 and rip at cfa-8, before call .LIND1 is executed, > the return address (to whatever called the thunk) is at %rsp+8 like on entry > to any other function. But the call insn pushes a word to the stack, which > we don't want to show up as another caller, and worse is in the mov insn > overwritten with something else. > > The following patch adds .cfi_def_cfa_offset 16 right after the .LIND1 > label, so that the CFI is correct until the end of the thunk. It works > properly also with -fno-dwarf2-cfi-asm. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2018-09-25 Jakub Jelinek <ja...@redhat.com> > > PR target/87414 > * config/i386/i386.c: Include debug.h and dwarf2out.h. > (output_indirect_thunk): Emit DW_CFA_def_cfa_offset after the > call.
LGTM. Thanks, Uros. > --- gcc/config/i386/i386.c.jj 2018-09-24 10:36:54.559016673 +0200 > +++ gcc/config/i386/i386.c 2018-09-24 22:09:48.218211652 +0200 > @@ -89,6 +89,8 @@ along with GCC; see the file COPYING3. > #include "ipa-fnsummary.h" > #include "wide-int-bitmask.h" > #include "tree-vector-builder.h" > +#include "debug.h" > +#include "dwarf2out.h" > > /* This file should be included last. */ > #include "target-def.h" > @@ -10464,6 +10466,23 @@ output_indirect_thunk (unsigned int regn > > ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); > > + /* The above call insn pushed a word to stack. Adjust CFI info. */ > + if (flag_asynchronous_unwind_tables && dwarf2out_do_frame ()) > + { > + if (! dwarf2out_do_cfi_asm ()) > + { > + dw_cfi_ref xcfi = ggc_cleared_alloc<dw_cfi_node> (); > + xcfi->dw_cfi_opc = DW_CFA_advance_loc4; > + xcfi->dw_cfi_oprnd1.dw_cfi_addr = ggc_strdup (indirectlabel2); > + vec_safe_push (cfun->fde->dw_fde_cfi, xcfi); > + } > + dw_cfi_ref xcfi = ggc_cleared_alloc<dw_cfi_node> (); > + xcfi->dw_cfi_opc = DW_CFA_def_cfa_offset; > + xcfi->dw_cfi_oprnd1.dw_cfi_offset = 2 * UNITS_PER_WORD; > + vec_safe_push (cfun->fde->dw_fde_cfi, xcfi); > + dwarf2out_emit_cfi (xcfi); > + } > + > if (regno != INVALID_REGNUM) > { > /* MOV. */ > > Jakub