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

Reply via email to