/* scfi.c - Support for synthesizing DWARF CFI for hand-written asm.
   Copyright (C) 2023 Free Software Foundation, Inc.

   This file is part of GAS, the GNU Assembler.

   GAS is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   GAS is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with GAS; see the file COPYING.  If not, write to the Free
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
   02110-1301, USA.  */

#include "as.h"
#include "scfi.h"
#include "subsegs.h"
#include "scfidw2gen.h"
#include "dw2gencfi.h"

#if defined (TARGET_USE_SCFI) && defined (TARGET_USE_GINSN)

/* Beyond the target defined number of registers to be tracked
   (SCFI_MAX_REG_ID), keep the next register ID, in sequence, for REG_CFA.  */
#define REG_CFA	      (SCFI_MAX_REG_ID+1)
/* Define the total number of registers being tracked.
   Used as index into an array of cfi_reglocS.  Note that a ginsn may carry a
   register number greater than MAX_NUM_SCFI_REGS, e.g., for the ginsns
   corresponding to push fs/gs in AMD64.  */
#define MAX_NUM_SCFI_REGS   (REG_CFA+1)

#define REG_INVALID	    ((unsigned int)-1)

enum cfi_reglocstate
{
  CFI_UNDEFINED,
  CFI_IN_REG,
  CFI_ON_STACK
};

/* Location at which CFI register is saved.

   A CFI register (callee-saved registers, RA/LR) are always an offset from
   the CFA.  REG_CFA itself, however, may have REG_SP or REG_FP as base
   register.  Hence, keep the base reg ID and offset per tracked register.  */

struct cfi_regloc
{
  /* Base reg ID (DWARF register number).  */
  unsigned int base;
  /* Location as offset from the CFA.  */
  offsetT offset;
  /* Current state of the CFI register.  */
  enum cfi_reglocstate state;
};

typedef struct cfi_regloc cfi_reglocS;

struct scfi_op_data
{
  const char *name;
};

typedef struct scfi_op_data scfi_op_dataS;

/* SCFI operation.

   An SCFI operation represents a single atomic change to the SCFI state.
   This can also be understood as an abstraction for what eventually gets
   emitted as a DWARF CFI operation.  */

struct scfi_op
{
  /* An SCFI op updates the state of either the CFA or other tracked
     (callee-saved, REG_SP etc) registers.  'reg' is in the DWARF register
     number space and must be strictly less than MAX_NUM_SCFI_REGS.  */
  unsigned int reg;
  /* Location of the reg.  */
  cfi_reglocS loc;
  /* DWARF CFI opcode.  */
  uint32_t dw2cfi_op;
  /* Some SCFI ops, e.g., for CFI_label, may need to carry additional data.  */
  scfi_op_dataS *op_data;
  /* A linked list.  */
  struct scfi_op *next;
};

/* SCFI State - accumulated unwind information at a PC.

   SCFI state is the accumulated unwind information encompassing:
      - REG_SP, REG_FP,
      - RA, and
      - all callee-saved registers.

    Note that SCFI_MAX_REG_ID is target/ABI dependent and is provided by the
    backends.  The backend must also identify the DWARF register numbers for
    the REG_SP, and REG_FP registers.  */

struct scfi_state
{
  cfi_reglocS regs[MAX_NUM_SCFI_REGS];
  cfi_reglocS scratch[MAX_NUM_SCFI_REGS];
  /* Current stack size.  */
  offsetT stack_size;
  /* Whether the stack size is known.
     Stack size may become untraceable depending on the specific stack
     manipulation machine instruction, e.g., rsp = rsp op reg instruction
     makes the stack size untraceable.  */
  bool traceable_p;
};

/* Initialize a new SCFI op.  */

static scfi_opS *
init_scfi_op (void)
{
  scfi_opS *op = XCNEW (scfi_opS);

  return op;
}

/* Free the SCFI ops, given the HEAD of the list.  */

void
scfi_ops_cleanup (scfi_opS **head)
{
  scfi_opS *op;
  scfi_opS *next;

  if (!head || !*head)
    return;

  op = *head;
  next = op->next;

  while (op)
    {
      free (op->op_data);
      free (op);
      op = next;
      next = op ? op->next : NULL;
    }

  free (head);
}

/* Compare two SCFI states.  */

static int
cmp_scfi_state (scfi_stateS *state1, scfi_stateS *state2)
{
  int ret;

  if (!state1 || !state2)
    return 1;

  /* Skip comparing the scratch[] value of registers.  The user visible
     unwind information is derived from the regs[] from the SCFI state.  */
  ret = memcmp (state1->regs, state2->regs,
		sizeof (cfi_reglocS) * MAX_NUM_SCFI_REGS);

  /* For user functions which perform dynamic stack allocation, after switching
     t REG_FP based CFA tracking, it is perfectly possible to have stack usage
     in some control flows.  Further, the different control flows may even not
     have the same idea of CFA tracking (likely later necessitating generation
     of .cfi_remember_state / .cfi_restore_state pair).  */
  ret |= state1->regs[REG_CFA].base != state2->regs[REG_CFA].base;

  if (!ret && state1->regs[REG_CFA].base == REG_SP)
    ret |= state1->stack_size != state2->stack_size;

  ret |= state1->traceable_p != state2->traceable_p;

  return ret;
}

#if 0
static void
scfi_state_update_reg (scfi_stateS *state, uint32_t dst, uint32_t base,
		       int32_t offset)
{
  if (dst >= MAX_NUM_SCFI_REGS)
    return;

  state->regs[dst].base = base;
  state->regs[dst].offset = offset;
}
#endif

/* Update the SCFI state of REG as available on execution stack at OFFSET
   from REG_CFA (BASE).

   Note that BASE must be REG_CFA, because any other base (REG_SP, REG_FP)
   is by definition transitory in the function.  */

static void
scfi_state_save_reg (scfi_stateS *state, unsigned int reg, unsigned int base,
		     offsetT offset)
{
  if (reg >= MAX_NUM_SCFI_REGS)
    return;

  gas_assert (base == REG_CFA);

  state->regs[reg].base = base;
  state->regs[reg].offset = offset;
  state->regs[reg].state = CFI_ON_STACK;
}

static void
scfi_state_restore_reg (scfi_stateS *state, unsigned int reg)
{
  if (reg >= MAX_NUM_SCFI_REGS)
    return;

  /* Sanity check.  See Rule 4.  */
  gas_assert (state->regs[reg].state == CFI_ON_STACK);
  gas_assert (state->regs[reg].base == REG_CFA);

  /* PS: the register may still be on stack much after the restore.  Reset the
     SCFI state to CFI_UNDEFINED, however, to indicate that the most updated
     source of value is register itself from here onwards.  */
  state->regs[reg].base = 0;
  state->regs[reg].offset = 0;
  state->regs[reg].state = CFI_UNDEFINED;
}

/* Identify if the given GAS instruction GINSN saves a register
   (of interest) on stack.  */

static bool
ginsn_scfi_save_reg_p (ginsnS *ginsn, scfi_stateS *state)
{
  bool save_reg_p = false;
  struct ginsn_src *src;
  struct ginsn_dst *dst;

  src = ginsn_get_src1 (ginsn);
  dst = ginsn_get_dst (ginsn);

  /* The first save to stack of callee-saved register is deemed as
     register save.  */
  if (!ginsn_track_reg_p (ginsn_get_src_reg (src), GINSN_GEN_SCFI)
      || state->regs[ginsn_get_src_reg (src)].state == CFI_ON_STACK)
    return save_reg_p;

  /* A register save insn may be an indirect mov.  */
  if (ginsn->type == GINSN_TYPE_MOV
      && ginsn_get_dst_type (dst) == GINSN_DST_INDIRECT
      && (ginsn_get_dst_reg (dst) == REG_SP
	  || (ginsn_get_dst_reg (dst) == REG_FP
	      && state->regs[REG_CFA].base == REG_FP)))
    save_reg_p = true;
  /* or an explicit store to stack.  */
  else if (ginsn->type == GINSN_TYPE_STORE
	   && ginsn_get_dst_type (dst) == GINSN_DST_INDIRECT
	   && ginsn_get_dst_reg (dst) == REG_SP)
    save_reg_p = true;

  return save_reg_p;
}

/* Identify if the given GAS instruction GINSN restores a register
   (of interest) on stack.  */

static bool
ginsn_scfi_restore_reg_p (ginsnS *ginsn, scfi_stateS *state)
{
  bool restore_reg_p = false;
  struct ginsn_dst *dst;
  struct ginsn_src *src1;

  dst = ginsn_get_dst (ginsn);
  src1 = ginsn_get_src1 (ginsn);

  if (!ginsn_track_reg_p (ginsn_get_dst_reg (dst), GINSN_GEN_SCFI))
    return restore_reg_p;

  /* A register restore insn may be an indirect mov...  */
  if (ginsn->type == GINSN_TYPE_MOV
      && ginsn_get_src_type (src1) == GINSN_SRC_INDIRECT
      && (ginsn_get_src_reg (src1) == REG_SP
	  || (ginsn_get_src_reg (src1) == REG_FP
	      && state->regs[REG_CFA].base == REG_FP)))
    restore_reg_p = true;
  /* ...or an explicit load from stack.  */
  else if (ginsn->type == GINSN_TYPE_LOAD
	   && ginsn_get_src_type (src1) == GINSN_SRC_INDIRECT
	   && ginsn_get_src_reg (src1) == REG_SP)
    restore_reg_p = true;

  return restore_reg_p;
}

/* Append the SCFI operation OP to the list of SCFI operations in the
   given GINSN.  */

static int
ginsn_append_scfi_op (ginsnS *ginsn, scfi_opS *op)
{
  scfi_opS *sop;

  if (!ginsn || !op)
    return 1;

  if (!ginsn->scfi_ops)
    {
      ginsn->scfi_ops = XCNEW (scfi_opS *);
      *ginsn->scfi_ops = op;
    }
  else
    {
      /* Add to tail.  Most ginsns have a single SCFI operation,
	 so this traversal for every insertion is acceptable for now.  */
      sop = *ginsn->scfi_ops;
      while (sop->next)
	sop = sop->next;

      sop->next = op;
    }
  ginsn->num_scfi_ops++;

  return 0;
}

static void
scfi_op_add_def_cfa_reg (scfi_stateS *state, ginsnS *ginsn, unsigned int reg)
{
  scfi_opS *op = NULL;

  state->regs[REG_CFA].base = reg;

  op = init_scfi_op ();

  op->dw2cfi_op = DW_CFA_def_cfa_register;
  op->reg = REG_CFA;
  op->loc = state->regs[REG_CFA];

  ginsn_append_scfi_op (ginsn, op);
}

static void
scfi_op_add_cfa_offset_inc (scfi_stateS *state, ginsnS *ginsn, offsetT num)
{
  scfi_opS *op = NULL;

  state->regs[REG_CFA].offset -= num;

  op = init_scfi_op ();

  op->dw2cfi_op = DW_CFA_def_cfa_offset;
  op->reg = REG_CFA;
  op->loc = state->regs[REG_CFA];

  ginsn_append_scfi_op (ginsn, op);
}

static void
scfi_op_add_cfa_offset_dec (scfi_stateS *state, ginsnS *ginsn, offsetT num)
{
  scfi_opS *op = NULL;

  state->regs[REG_CFA].offset += num;

  op = init_scfi_op ();

  op->dw2cfi_op = DW_CFA_def_cfa_offset;
  op->reg = REG_CFA;
  op->loc = state->regs[REG_CFA];

  ginsn_append_scfi_op (ginsn, op);
}

static void
scfi_op_add_def_cfa (scfi_stateS *state, ginsnS *ginsn, unsigned int reg,
		     offsetT num)
{
  scfi_opS *op = NULL;

  state->regs[REG_CFA].base = reg;
  state->regs[REG_CFA].offset = num;

  op = init_scfi_op ();

  op->dw2cfi_op = DW_CFA_def_cfa;
  op->reg = REG_CFA;
  op->loc = state->regs[REG_CFA];

  ginsn_append_scfi_op (ginsn, op);
}

static void
scfi_op_add_cfi_offset (scfi_stateS *state, ginsnS *ginsn, unsigned int reg)
{
  scfi_opS *op = NULL;

  op = init_scfi_op ();

  op->dw2cfi_op = DW_CFA_offset;
  op->reg = reg;
  op->loc = state->regs[reg];

  ginsn_append_scfi_op (ginsn, op);
}

static void
scfi_op_add_cfa_restore (ginsnS *ginsn, unsigned int reg)
{
  scfi_opS *op = NULL;

  op = init_scfi_op ();

  op->dw2cfi_op = DW_CFA_restore;
  op->reg = reg;
  op->loc.base = REG_INVALID;
  op->loc.offset = 0;

  ginsn_append_scfi_op (ginsn, op);
}

static void
scfi_op_add_cfi_remember_state (ginsnS *ginsn)
{
  scfi_opS *op = NULL;

  op = init_scfi_op ();

  op->dw2cfi_op = DW_CFA_remember_state;

  ginsn_append_scfi_op (ginsn, op);
}

static void
scfi_op_add_cfi_restore_state (ginsnS *ginsn)
{
  scfi_opS *op = NULL;

  op = init_scfi_op ();

  op->dw2cfi_op = DW_CFA_restore_state;

  /* FIXME - add to the beginning of the scfi_ops.  */
  ginsn_append_scfi_op (ginsn, op);
}

void
scfi_op_add_cfi_label (ginsnS *ginsn, const char *name)
{
  scfi_opS *op = NULL;

  op = init_scfi_op ();
  op->dw2cfi_op = CFI_label;
  op->op_data = XCNEW (scfi_op_dataS);
  op->op_data->name = name;

  ginsn_append_scfi_op (ginsn, op);
}

void
scfi_op_add_signal_frame (ginsnS *ginsn)
{
  scfi_opS *op = NULL;

  op = init_scfi_op ();
  op->dw2cfi_op = CFI_signal_frame;

  ginsn_append_scfi_op (ginsn, op);
}

static int
verify_heuristic_traceable_reg_fp (ginsnS *ginsn, scfi_stateS *state)
{
  /* The function uses this variable to issue error to user right away.  */
  int fp_traceable_p = 0;
  enum ginsn_type gtype;
  struct ginsn_src *src1;
  struct ginsn_src *src2;
  struct ginsn_dst *dst;
  unsigned int src1_reg;
  unsigned int dst_reg;
  enum ginsn_src_type src1_type;
  enum ginsn_src_type src2_type;
  enum ginsn_dst_type dst_type;

  gtype = ginsn->type;

  src1 = ginsn_get_src1 (ginsn);
  src2 = ginsn_get_src2 (ginsn);
  dst = ginsn_get_dst (ginsn);

  src1_reg = ginsn_get_src_reg (src1);
  dst_reg = ginsn_get_dst_reg (dst);

  src1_type = ginsn_get_src_type (src1);
  src2_type = ginsn_get_src_type (src2);
  dst_type = ginsn_get_dst_type (dst);

  /* Stack manipulation can be done in a variety of ways.  A program may
     allocate stack statically or may perform dynamic stack allocation in
     the prologue.

     The SCFI machinery in GAS is based on some heuristics:

       - Rule 3 If the base register for CFA tracking is REG_FP, the program
       must not clobber REG_FP, unless it is for switch to REG_SP based CFA
       tracking (via say, a pop %rbp in X86).  */

  /* Check all applicable instructions with dest REG_FP, when the CFA base
     register is REG_FP.  */
  if (state->regs[REG_CFA].base == REG_FP
      && (dst_type == GINSN_DST_REG || dst_type == GINSN_DST_INDIRECT)
      && dst_reg == REG_FP)
    {
      /* Excuse the add/sub with imm usage: They are OK.  */
      if ((gtype == GINSN_TYPE_ADD || gtype == GINSN_TYPE_SUB)
	  && src1_type == GINSN_SRC_REG && src1_reg == REG_FP
	  && src2_type == GINSN_SRC_IMM)
	fp_traceable_p = 0;
      /* REG_FP restore is OK too.  */
      else if (ginsn->type == GINSN_TYPE_LOAD)
	fp_traceable_p = 0;
      /* mov's to memory with REG_FP base do not make REG_FP untraceable.  */
      else if (dst_type == GINSN_DST_INDIRECT
	       && (gtype == GINSN_TYPE_MOV || gtype == GINSN_TYPE_STORE))
	fp_traceable_p = 0;
      /* Manipulations of the values possibly on stack are OK too.  */
      else if ((gtype == GINSN_TYPE_ADD || gtype == GINSN_TYPE_SUB
		|| gtype == GINSN_TYPE_AND)
	       && dst_type == GINSN_DST_INDIRECT)
	fp_traceable_p = 0;
      /* All other ginsns with REG_FP as destination make REG_FP not
	 traceable.  */
      else
	fp_traceable_p = 1;
    }

  if (fp_traceable_p)
    as_bad_where (ginsn->file, ginsn->line,
		  _("SCFI: usage of REG_FP as scratch not supported"));

  return fp_traceable_p;
}

static int
verify_heuristic_traceable_stack_manipulation (ginsnS *ginsn,
					       scfi_stateS *state)
{
  /* The function uses this variable to issue error to user right away.  */
  int sp_untraceable_p = 0;
  bool possibly_untraceable = false;
  enum ginsn_type gtype;
  struct ginsn_dst *dst;
  struct ginsn_src *src1;
  struct ginsn_src *src2;
  unsigned int src1_reg;
  unsigned int dst_reg;
  enum ginsn_src_type src1_type;
  enum ginsn_src_type src2_type;
  enum ginsn_dst_type dst_type;

  gtype = ginsn->type;

  src1 = ginsn_get_src1 (ginsn);
  src2 = ginsn_get_src2 (ginsn);
  dst = ginsn_get_dst (ginsn);

  src1_reg = ginsn_get_src_reg (src1);
  dst_reg = ginsn_get_dst_reg (dst);

  src1_type = ginsn_get_src_type (src1);
  src2_type = ginsn_get_src_type (src2);
  dst_type = ginsn_get_dst_type (dst);

  /* Stack manipulation can be done in a variety of ways.  A program may
     allocate stack statically in prologue or may need to do dynamic stack
     allocation.

     The SCFI machinery in GAS is based on some heuristics:

       - Rule 1 The base register for CFA tracking may be either REG_SP or
       REG_FP.

       - Rule 2 If the base register for CFA tracking is REG_SP, the precise
       amount of stack usage (and hence, the value of rsp) must be known at
       all times.  */

  if (gtype == GINSN_TYPE_MOV
      && dst_type == GINSN_DST_REG && dst_reg == REG_SP
      /* Exclude mov %rbp, %rsp from this check.  */
      && src1_type == GINSN_SRC_REG && src1_reg != REG_FP)
    {
      /* A previous mov %rsp, %reg must have been seen earlier for this to be
	 an OK for stack manipulation.  */
      if (state->scratch[src1_reg].base != REG_CFA
	  || state->scratch[src1_reg].state != CFI_IN_REG)
	possibly_untraceable = true;
    }
  /* Check add/sub/and insn usage when CFA base register is REG_SP.
     Any stack size manipulation, including stack realignment is not allowed
     if CFA base register is REG_SP.  */
  else if (dst_type == GINSN_DST_REG && dst_reg == REG_SP
	   && (((gtype == GINSN_TYPE_ADD || gtype == GINSN_TYPE_SUB)
		&& src2_type != GINSN_SRC_IMM)
	       || gtype == GINSN_TYPE_AND || gtype == GINSN_TYPE_OTHER))
    possibly_untraceable = true;
  /* If a register save operation is seen when REG_SP is untraceable,
     CFI cannot be synthesized for register saves, hence bail out.  */
  else if (ginsn_scfi_save_reg_p (ginsn, state) && !state->traceable_p)
    {
      sp_untraceable_p = 1;
      /* If, however, the register save is an REG_FP-based, indirect mov
	 like: mov reg, disp(%rbp) and CFA base register is REG_BP,
	 untraceable REG_SP is not a problem.  */
      if (gtype == GINSN_TYPE_MOV && state->regs[REG_CFA].base == REG_FP
	  && dst_type == GINSN_DST_INDIRECT && dst_reg == REG_FP)
	sp_untraceable_p = 0;
    }
  else if (ginsn_scfi_restore_reg_p (ginsn, state) && !state->traceable_p)
    {
      if (gtype == GINSN_TYPE_MOV && dst_type == GINSN_DST_INDIRECT
	  && (src1_reg == REG_SP
	      || (src1_reg == REG_FP && state->regs[REG_CFA].base != REG_FP)))
	sp_untraceable_p = 1;
    }

  if (possibly_untraceable)
    {
      /* See Rule 2.  For SP-based CFA, this makes CFA tracking not possible.
	 Propagate now to caller.  */
      if (state->regs[REG_CFA].base == REG_SP)
	sp_untraceable_p = 1;
      else if (state->traceable_p)
	{
	  /* An extension of Rule 2.
	     For FP-based CFA, this may be a problem *if* certain specific
	     changes to the SCFI state are seen beyond this point, e.g.,
	     register save / restore from stack.  */
	  gas_assert (state->regs[REG_CFA].base == REG_FP);
	  /* Simply make a note in the SCFI state object for now and
	     continue.  Indicate an error when register save / restore
	     for callee-saved registers is seen.  */
	  sp_untraceable_p = 0;
	  state->traceable_p = false;
	}
    }

  if (sp_untraceable_p)
    as_bad_where (ginsn->file, ginsn->line,
		  _("SCFI: unsupported stack manipulation pattern"));

  return sp_untraceable_p;
}

static int
verify_heuristic_symmetrical_restore_reg (scfi_stateS *state, ginsnS* ginsn)
{
  int sym_restore = true;
  offsetT expected_offset = 0;
  struct ginsn_src *src1;
  struct ginsn_dst *dst;
  unsigned int reg;

  /* Rule 4: Save and Restore of callee-saved registers must be symmetrical.
     It is expected that value of the saved register is restored correctly.
     E.g.,
	push  reg1
	push  reg2
	...
	body of func which uses reg1 , reg2 as scratch,
	and may be even spills them to stack.
	...
	pop   reg2
	pop   reg1
     It is difficult to verify the Rule 4 in all cases.  For the SCFI machinery,
     it is difficult to separate prologue-epilogue from the body of the function

     Hence, the SCFI machinery at this time, should only warn on an asymetrical
     restore.  */
  src1 = ginsn_get_src1 (ginsn);
  dst = ginsn_get_dst (ginsn);
  reg = ginsn_get_dst_reg (dst);

  /* For non callee-saved registers, calling the API is meaningless.  */
  if (!ginsn_track_reg_p (ginsn_get_dst_reg (dst), GINSN_GEN_SCFI))
    return sym_restore;

  /* The register must have been saved on stack, for sure.  */
  gas_assert (state->regs[reg].state == CFI_ON_STACK);
  gas_assert (state->regs[reg].base == REG_CFA);

  if ((ginsn->type == GINSN_TYPE_MOV
       || ginsn->type == GINSN_TYPE_LOAD)
      && ginsn_get_src_type (src1) == GINSN_SRC_INDIRECT
      && (ginsn_get_src_reg (src1) == REG_SP
	  || (ginsn_get_src_reg (src1) == REG_FP
	      && state->regs[REG_CFA].base == REG_FP)))
    {
      /* mov disp(%rsp), reg.  */
      /* mov disp(%rbp), reg.  */
      expected_offset = (((ginsn_get_src_reg (src1) == REG_SP)
			  ? -state->stack_size
			  : state->regs[REG_FP].offset)
			 + ginsn_get_src_disp (src1));
    }

  sym_restore = (expected_offset == state->regs[reg].offset);

  return sym_restore;
}

/* Perform symbolic execution of the GINSN and update its list of scfi_ops.
   scfi_ops are later used to directly generate the DWARF CFI directives.
   Also update the SCFI state object STATE for the caller.  */

static int
gen_scfi_ops (ginsnS *ginsn, scfi_stateS *state)
{
  int ret = 0;
  offsetT offset;
  struct ginsn_src *src1;
  struct ginsn_src *src2;
  struct ginsn_dst *dst;
  unsigned int src1_reg;
  unsigned int dst_reg;
  enum ginsn_src_type src1_type;
  enum ginsn_src_type src2_type;
  enum ginsn_dst_type dst_type;

  if (!ginsn || !state)
    ret = 1;

  /* For the first ginsn (of type GINSN_TYPE_SYMBOL) in the gbb, generate
     the SCFI op with DW_CFA_def_cfa.  Note that the register and offset are
     target-specific.  */
  if (GINSN_F_FUNC_BEGIN_P (ginsn))
    {
      scfi_op_add_def_cfa (state, ginsn, REG_SP, SCFI_INIT_CFA_OFFSET);
      state->stack_size += SCFI_INIT_CFA_OFFSET;
      return ret;
    }

  src1 = ginsn_get_src1 (ginsn);
  src2 = ginsn_get_src2 (ginsn);
  dst = ginsn_get_dst (ginsn);

  src1_reg = ginsn_get_src_reg (src1);
  dst_reg = ginsn_get_dst_reg (dst);

  src1_type = ginsn_get_src_type (src1);
  src2_type = ginsn_get_src_type (src2);
  dst_type = ginsn_get_dst_type (dst);

  ret = verify_heuristic_traceable_stack_manipulation (ginsn, state);
  if (ret)
    return ret;

  ret = verify_heuristic_traceable_reg_fp (ginsn, state);
  if (ret)
    return ret;

  switch (dst_type)
    {
    case GINSN_DST_REG:
      switch (ginsn->type)
	{
	case GINSN_TYPE_MOV:
	  if (src1_type == GINSN_SRC_REG && src1_reg == REG_SP
	      && dst_type == GINSN_DST_REG && dst_reg == REG_FP
	      && state->regs[REG_CFA].base == REG_SP)
	    {
	      /* mov %rsp, %rbp.  */
	      scfi_op_add_def_cfa_reg (state, ginsn, dst_reg);
	    }
	  else if (src1_type == GINSN_SRC_REG && src1_reg == REG_FP
		   && dst_type == GINSN_DST_REG && dst_reg == REG_SP
		   && state->regs[REG_CFA].base == REG_FP)
	    {
	      /* mov %rbp, %rsp.  */
	      state->stack_size = -state->regs[REG_FP].offset;
	      scfi_op_add_def_cfa_reg (state, ginsn, dst_reg);
	      state->traceable_p = true;
	    }
	  else if (src1_type == GINSN_SRC_INDIRECT
		   && (src1_reg == REG_SP || src1_reg == REG_FP)
		   && ginsn_track_reg_p (dst_reg, GINSN_GEN_SCFI))
	    {
	      /* mov disp(%rsp), reg.  */
	      /* mov disp(%rbp), reg.  */
	      if (verify_heuristic_symmetrical_restore_reg (state, ginsn))
		{
		  scfi_state_restore_reg (state, dst_reg);
		  scfi_op_add_cfa_restore (ginsn, dst_reg);
		}
	      else
		as_warn_where (ginsn->file, ginsn->line,
			       _("SCFI: asymetrical register restore"));
	    }
	  else if (src1_type == GINSN_SRC_REG && src1_reg == REG_SP
		   && dst_type == GINSN_DST_REG)
	    {
	      /* mov %rsp, %reg.  */
	      /* The value of rsp is taken directly from state->stack_size.
		 IMP: The workflow in gen_scfi_ops must keep it updated.
		 PS: Not taking the value from state->scratch[REG_SP] is
		 intentional.  */
	      state->scratch[dst_reg].base = REG_CFA;
	      state->scratch[dst_reg].offset = -state->stack_size;
	      state->scratch[dst_reg].state = CFI_IN_REG;
	    }
	  else if (src1_type == GINSN_SRC_REG
		   && dst_type == GINSN_DST_REG && dst_reg == REG_SP)
	    {
	      /* mov %reg, %rsp.  */
	      /* Keep the value of REG_SP updated.  */
	      if (state->scratch[src1_reg].state == CFI_IN_REG)
		{
		  state->stack_size = -state->scratch[src1_reg].offset;
		  state->traceable_p = true;
		}
# if 0
	      scfi_state_update_reg (state, ginsn_get_dst_reg (dst),
				     state->scratch[ginsn_get_src_reg (src1)].base,
				     state->scratch[ginsn_get_src_reg (src1)].offset);
#endif

	    }
	  break;
	case GINSN_TYPE_SUB:
	  if (src1_type == GINSN_SRC_REG && src1_reg == REG_SP
	      && dst_type == GINSN_DST_REG && dst_reg == REG_SP
	      && src2_type == GINSN_SRC_IMM)
	    {
	      /* Stack inc/dec offset, when generated due to stack push and pop is
		 target-specific.  Use the value encoded in the ginsn.  */
	      state->stack_size += ginsn_get_src_imm (src2);
	      if (state->regs[REG_CFA].base == REG_SP)
		{
		  /* push reg.  */
		  scfi_op_add_cfa_offset_dec (state, ginsn, ginsn_get_src_imm (src2));
		}
	    }
	  break;
	case GINSN_TYPE_ADD:
	  if (src1_type == GINSN_SRC_REG && src1_reg == REG_SP
	      && dst_type == GINSN_DST_REG && dst_reg == REG_SP
	      && src2_type == GINSN_SRC_IMM)
	    {
	      /* Stack inc/dec offset is target-specific.  Use the value
		 encoded in the ginsn.  */
	      state->stack_size -= ginsn_get_src_imm (src2);
	      /* pop %reg affects CFA offset only if CFA is currently
		 stack-pointer based.  */
	      if (state->regs[REG_CFA].base == REG_SP)
		{
		  scfi_op_add_cfa_offset_inc (state, ginsn, ginsn_get_src_imm (src2));
		}
	    }
	  else if (src1_type == GINSN_SRC_REG && src1_reg == REG_FP
		   && dst_type == GINSN_DST_REG && dst_reg == REG_SP
		   && state->regs[REG_CFA].base == REG_FP)
	    {
	      /* FIXME - what is this for ? */
	      state->stack_size =  0 - (state->regs[REG_FP].offset + ginsn_get_src_imm (src2));
	    }
	  break;
	case GINSN_TYPE_LOAD:
	  /* If this is a load from stack.  */
	  if (src1_type == GINSN_SRC_INDIRECT
	      && ((src1_reg == REG_FP && state->regs[REG_CFA].base == REG_FP)
		  || src1_reg == REG_SP))

	    {
	      /* pop %rbp when CFA tracking is REG_FP based.  */
	      if (dst_reg == REG_FP && state->regs[REG_CFA].base == REG_FP)
		{
		  scfi_op_add_def_cfa_reg (state, ginsn, REG_SP);
		  if (state->regs[REG_CFA].offset != state->stack_size)
		    scfi_op_add_cfa_offset_inc (state, ginsn,
						(state->regs[REG_CFA].offset - state->stack_size));
		}
	      if (ginsn_track_reg_p (dst_reg, GINSN_GEN_SCFI))
		{
		  if (verify_heuristic_symmetrical_restore_reg (state, ginsn))
		    {
		      scfi_state_restore_reg (state, dst_reg);
		      scfi_op_add_cfa_restore (ginsn, dst_reg);
		    }
		  else
		    as_warn_where (ginsn->file, ginsn->line,
				   _("SCFI: asymetrical register restore"));
		}
	    }
	  break;
	default:
	  break;
	}
      break;

    case GINSN_DST_INDIRECT:
      /* Some operations with an indirect access to memory (or even to stack)
	 may still be uninteresting for SCFI purpose (e.g, addl %edx, -32(%rsp)
	 in x86).  In case of x86_64, these can neither be a register
	 save / unsave, nor can alter the stack size.
	 PS: This condition may need to be revisited for other arches.  */
      if (ginsn->type == GINSN_TYPE_ADD || ginsn->type == GINSN_TYPE_SUB
	  || ginsn->type == GINSN_TYPE_AND)
	break;
      gas_assert (ginsn->type == GINSN_TYPE_MOV
		  || ginsn->type == GINSN_TYPE_STORE
		  || ginsn->type == GINSN_TYPE_LOAD);
      /* mov reg, disp(%rbp) */
      /* mov reg, disp(%rsp) */
      if (ginsn_scfi_save_reg_p (ginsn, state))
	{
	  if (dst_reg == REG_SP)
	    {
	      /* mov reg, disp(%rsp) */
	      offset = 0 - state->stack_size + ginsn_get_dst_disp (dst);
	      scfi_state_save_reg (state, src1_reg, REG_CFA, offset);
	      scfi_op_add_cfi_offset (state, ginsn, src1_reg);
	    }
	  else if (dst_reg == REG_FP)
	    {
	      gas_assert (state->regs[REG_CFA].base == REG_FP);
	      /* mov reg, disp(%rbp) */
	      offset = 0 - state->regs[REG_CFA].offset + ginsn_get_dst_disp (dst);
	      scfi_state_save_reg (state, src1_reg, REG_CFA, offset);
	      scfi_op_add_cfi_offset (state, ginsn, src1_reg);
	    }
	}
      break;

    default:
      /* Skip GINSN_DST_UNKNOWN and GINSN_DST_MEM as they are uninteresting
	 currently for SCFI.  */
      break;
    }

  return ret;
}

/* Recursively perform forward flow of the (unwind information) SCFI STATE
   starting at basic block GBB.

   The core of forward flow process takes the SCFI state at the entry of a bb
   and updates it incrementally as per the semantics of each ginsn in the bb.

   Returns error code, if any.  */

static int
forward_flow_scfi_state (gcfgS *gcfg, gbbS *gbb, scfi_stateS *state)
{
  ginsnS *ginsn;
  gbbS *prev_bb;
  gedgeS *gedge = NULL;
  int ret = 0;

  if (gbb->visited)
    {
      /* Check that the SCFI state is the same as previous.  */
      ret = cmp_scfi_state (state, gbb->entry_state);
      if (ret)
	as_bad (_("SCFI: Bad CFI propagation perhaps"));
      return ret;
    }

  gbb->visited = true;

  gbb->entry_state = XCNEW (scfi_stateS);
  memcpy (gbb->entry_state, state, sizeof (scfi_stateS));

  /* Perform symbolic execution of each ginsn in the gbb and update the
     scfi_ops list of each ginsn (and also update the STATE object).   */
  bb_for_each_insn(gbb, ginsn)
    {
      ret = gen_scfi_ops (ginsn, state);
      if (ret)
	goto fail;
    }

  gbb->exit_state = XCNEW (scfi_stateS);
  memcpy (gbb->exit_state, state, sizeof (scfi_stateS));

  /* Forward flow the SCFI state.  Currently, we process the next basic block
     in DFS order.  But any forward traversal order should be fine.  */
  prev_bb = gbb;
  if (gbb->num_out_gedges)
    {
      bb_for_each_edge(gbb, gedge)
	{
	  gbb = gedge->dst_bb;
	  /* Ensure that the state is the one from the exit of the prev bb.  */
	  memcpy (state, prev_bb->exit_state, sizeof (scfi_stateS));
	  if (gbb->visited)
	    {
	      ret = cmp_scfi_state (gbb->entry_state, state);
	      if (ret)
		goto fail;
	    }

	  if (!gedge->visited)
	    {
	      gedge->visited = true;

	      /* Entry SCFI state for the destination bb of the edge is the
		 same as the exit SCFI state of the source bb of the edge.  */
	      memcpy (state, prev_bb->exit_state, sizeof (scfi_stateS));
	      ret = forward_flow_scfi_state (gcfg, gbb, state);
	      if (ret)
		goto fail;
	    }
	}
    }

  return 0;

fail:

  if (gedge)
    gedge->visited = true;
  return 1;
}

static int
backward_flow_scfi_state (const symbolS *func ATTRIBUTE_UNUSED, gcfgS *gcfg)
{
  gbbS **prog_order_bbs;
  gbbS **restore_bbs;
  gbbS *current_bb;
  gbbS *prev_bb;
  gbbS *dst_bb;
  ginsnS *ginsn;
  gedgeS *gedge = NULL;

  int ret = 0;
  uint64_t i, j;

  /* Basic blocks in reverse program order.  */
  prog_order_bbs = XCNEWVEC (gbbS *, gcfg->num_gbbs);
  /* Basic blocks for which CFI remember op needs to be generated.  */
  restore_bbs = XCNEWVEC (gbbS *, gcfg->num_gbbs);

  gcfg_get_bbs_in_prog_order (gcfg, prog_order_bbs);

  i = gcfg->num_gbbs - 1;
  /* Traverse in reverse program order.  */
  while (i > 0)
    {
      current_bb = prog_order_bbs[i];
      prev_bb = prog_order_bbs[i-1];
      if (cmp_scfi_state (prev_bb->exit_state, current_bb->entry_state))
	{
	  /* Candidate for .cfi_restore_state found.  */
	  ginsn = bb_get_first_ginsn (current_bb);
	  scfi_op_add_cfi_restore_state (ginsn);
	  /* Memorize current_bb now to find location for its remember state
	     later.  */
	  restore_bbs[i] = current_bb;
	}
      else
	{
	  bb_for_each_edge (current_bb, gedge)
	    {
	      dst_bb = gedge->dst_bb;
	      for (j = 0; j < gcfg->num_gbbs; j++)
		if (restore_bbs[j] == dst_bb)
		  {
		    ginsn = bb_get_last_ginsn (current_bb);
		    scfi_op_add_cfi_remember_state (ginsn);
		    /* Remove the memorised restore_bb from the list.  */
		    restore_bbs[j] = NULL;
		    break;
		  }
	    }
	}
      i--;
    }

  /* All .cfi_restore_state pseudo-ops must have a corresponding
     .cfi_remember_state by now.  */
  for (j = 0; j < gcfg->num_gbbs; j++)
    if (restore_bbs[j] != NULL)
      {
	ret = 1;
	break;
      }

  free (restore_bbs);
  free (prog_order_bbs);

  return ret;
}

/* Synthesize DWARF CFI for a function.  */

int
scfi_synthesize_dw2cfi (const symbolS *func, gcfgS *gcfg, gbbS *root_bb)
{
  int ret;
  scfi_stateS *init_state;

  init_state = XCNEW (scfi_stateS);
  init_state->traceable_p = true;

  /* Traverse the input GCFG and perform forward flow of information.
     Update the scfi_op(s) per ginsn.  */
  ret = forward_flow_scfi_state (gcfg, root_bb, init_state);
  if (ret)
    {
      as_bad (_("SCFI: forward pass failed for func '%s'"), S_GET_NAME (func));
      goto end;
    }

  ret = backward_flow_scfi_state (func, gcfg);
  if (ret)
    {
      as_bad (_("SCFI: backward pass failed for func '%s'"), S_GET_NAME (func));
      goto end;
    }

end:
  free (init_state);
  return ret;
}

static int
handle_scfi_dot_cfi (ginsnS *ginsn)
{
  scfi_opS *op;

  /* Nothing to do.  */
  if (!ginsn->scfi_ops)
    return 0;

  op = *ginsn->scfi_ops;
  if (!op)
    goto bad;

  while (op)
    {
      switch (op->dw2cfi_op)
	{
	case DW_CFA_def_cfa_register:
	  scfi_dot_cfi (DW_CFA_def_cfa_register, op->loc.base, 0, 0, NULL,
			ginsn->sym);
	  break;
	case DW_CFA_def_cfa_offset:
	  scfi_dot_cfi (DW_CFA_def_cfa_offset, op->loc.base, 0,
			op->loc.offset, NULL, ginsn->sym);
	  break;
	case DW_CFA_def_cfa:
	  scfi_dot_cfi (DW_CFA_def_cfa, op->loc.base, 0, op->loc.offset,
			NULL, ginsn->sym);
	  break;
	case DW_CFA_offset:
	  scfi_dot_cfi (DW_CFA_offset, op->reg, 0, op->loc.offset, NULL,
			ginsn->sym);
	  break;
	case DW_CFA_restore:
	  scfi_dot_cfi (DW_CFA_restore, op->reg, 0, 0, NULL, ginsn->sym);
	  break;
	case DW_CFA_remember_state:
	  scfi_dot_cfi (DW_CFA_remember_state, 0, 0, 0, NULL, ginsn->sym);
	  break;
	case DW_CFA_restore_state:
	  scfi_dot_cfi (DW_CFA_restore_state, 0, 0, 0, NULL, ginsn->sym);
	  break;
	case CFI_label:
	  scfi_dot_cfi (CFI_label, 0, 0, 0, op->op_data->name, ginsn->sym);
	  free ((char *) op->op_data->name);
	  break;
	case CFI_signal_frame:
	  scfi_dot_cfi (CFI_signal_frame, 0, 0, 0, NULL, ginsn->sym);
	  break;
	default:
	  goto bad;
	  break;
	}
      op = op->next;
    }

  return 0;
bad:
  as_bad (_("SCFI: Invalid DWARF CFI opcode data"));
  return 1;
}

/* Emit Synthesized DWARF CFI.  */

int
scfi_emit_dw2cfi (const symbolS *func)
{
  struct frch_ginsn_data *frch_gdata;
  ginsnS* ginsn = NULL;

  frch_gdata = frchain_now->frch_ginsn_data;
  ginsn = frch_gdata->gins_rootP;

  while (ginsn)
    {
      switch (ginsn->type)
	{
	  case GINSN_TYPE_SYMBOL:
	    /* .cfi_startproc and .cfi_endproc pseudo-ops.  */
	    if (GINSN_F_FUNC_BEGIN_P (ginsn))
	      {
		scfi_dot_cfi_startproc (frch_gdata->start_addr);
		break;
	      }
	    else if (GINSN_F_FUNC_END_P (ginsn))
	      {
		scfi_dot_cfi_endproc (ginsn->sym);
		break;
	      }
	    /* Fall through.  */
	  case GINSN_TYPE_ADD:
	  case GINSN_TYPE_AND:
	  case GINSN_TYPE_CALL:
	  case GINSN_TYPE_JUMP:
	  case GINSN_TYPE_JUMP_COND:
	  case GINSN_TYPE_MOV:
	  case GINSN_TYPE_LOAD:
	  case GINSN_TYPE_PHANTOM:
	  case GINSN_TYPE_STORE:
	  case GINSN_TYPE_SUB:
	  case GINSN_TYPE_OTHER:
	  case GINSN_TYPE_RETURN:

	    /* For all other SCFI ops, invoke the handler.  */
	    if (ginsn->scfi_ops)
	      handle_scfi_dot_cfi (ginsn);
	    break;

	  default:
	    /* No other GINSN_TYPE_* expected.  */
	    as_bad (_("SCFI: bad ginsn for func '%s'"),
		    S_GET_NAME (func));
	    break;
	}
      ginsn = ginsn->next;
    }
  return 0;
}

#else

int
scfi_emit_dw2cfi (const symbolS *func ATTRIBUTE_UNUSED)
{
  as_bad (_("SCFI: unsupported for target"));
  return 1;
}

int
scfi_synthesize_dw2cfi (const symbolS *func ATTRIBUTE_UNUSED,
			gcfgS *gcfg ATTRIBUTE_UNUSED,
			gbbS *root_bb ATTRIBUTE_UNUSED)
{
  as_bad (_("SCFI: unsupported for target"));
  return 1;
}

#endif  /* defined (TARGET_USE_SCFI) && defined (TARGET_USE_GINSN).  */
