/* Target-dependent mdebug code for the ALPHA architecture.
   Copyright (C) 1993-2022 Free Software Foundation, Inc.

   This file is part of GDB.

   This program 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 of the License, or
   (at your option) any later version.

   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "frame.h"
#include "frame-unwind.h"
#include "frame-base.h"
#include "symtab.h"
#include "gdbcore.h"
#include "block.h"
#include "trad-frame.h"

#include "alpha-tdep.h"
#include "mdebugread.h"
#include "gdbarch.h"

/* FIXME: Some of this code should perhaps be merged with mips.  */

/* *INDENT-OFF* */
/* Layout of a stack frame on the alpha:

		|				|
 pdr members:	|  7th ... nth arg,		|
		|  `pushed' by caller.		|
		|				|
----------------|-------------------------------|<--  old_sp == vfp
   ^  ^  ^  ^	|				|
   |  |  |  |	|				|
   |  |localoff	|  Copies of 1st .. 6th		|
   |  |  |  |	|  argument if necessary.	|
   |  |  |  v	|				|
   |  |  |  ---	|-------------------------------|<-- LOCALS_ADDRESS
   |  |  |      |				|
   |  |  |      |  Locals and temporaries.	|
   |  |  |      |				|
   |  |  |      |-------------------------------|
   |  |  |      |				|
   |-fregoffset	|  Saved float registers.	|
   |  |  |      |  F9				|
   |  |  |      |   .				|
   |  |  |      |   .				|
   |  |  |      |  F2				|
   |  |  v      |				|
   |  |  -------|-------------------------------|
   |  |         |				|
   |  |         |  Saved registers.		|
   |  |         |  S6				|
   |-regoffset	|   .				|
   |  |         |   .				|
   |  |         |  S0				|
   |  |         |  pdr.pcreg			|
   |  v         |				|
   |  ----------|-------------------------------|
   |            |				|
 frameoffset    |  Argument build area, gets	|
   |            |  7th ... nth arg for any	|
   |            |  called procedure.		|
   v            |  				|
   -------------|-------------------------------|<-- sp
		|				|
*/
/* *INDENT-ON* */

#define PROC_LOW_ADDR(proc) ((proc)->pdr.adr)
#define PROC_FRAME_OFFSET(proc) ((proc)->pdr.frameoffset)
#define PROC_FRAME_REG(proc) ((proc)->pdr.framereg)
#define PROC_REG_MASK(proc) ((proc)->pdr.regmask)
#define PROC_FREG_MASK(proc) ((proc)->pdr.fregmask)
#define PROC_REG_OFFSET(proc) ((proc)->pdr.regoffset)
#define PROC_FREG_OFFSET(proc) ((proc)->pdr.fregoffset)
#define PROC_PC_REG(proc) ((proc)->pdr.pcreg)
#define PROC_LOCALOFF(proc) ((proc)->pdr.localoff)

/* Locate the mdebug PDR for the given PC.  Return null if one can't
   be found; you'll have to fall back to other methods in that case.  */

static struct mdebug_extra_func_info *
find_proc_desc (CORE_ADDR pc)
{
  const struct block *b = block_for_pc (pc);
  struct mdebug_extra_func_info *proc_desc = NULL;
  struct symbol *sym = NULL;
  const char *sh_name = NULL;

  if (b)
    {
      CORE_ADDR startaddr;
      find_pc_partial_function (pc, &sh_name, &startaddr, NULL);

      if (startaddr > BLOCK_START (b))
	/* This is the "pathological" case referred to in a comment in
	   print_frame_info.  It might be better to move this check into
	   symbol reading.  */
	sym = NULL;
      else
	sym = lookup_symbol (MDEBUG_EFI_SYMBOL_NAME, b, LABEL_DOMAIN,
			     0).symbol;
    }

  if (sym)
    {
      proc_desc = (struct mdebug_extra_func_info *) sym->value_bytes ();

      /* Correct incorrect setjmp procedure descriptor from the library
	 to make backtrace through setjmp work.  */
      if (proc_desc->pdr.pcreg == 0
	  && strcmp (sh_name, "setjmp") == 0)
	{
	  proc_desc->pdr.pcreg = ALPHA_RA_REGNUM;
	  proc_desc->pdr.regmask = 0x80000000;
	  proc_desc->pdr.regoffset = -4;
	}

      /* If we never found a PDR for this function in symbol reading,
	 then examine prologues to find the information.  */
      if (proc_desc->pdr.framereg == -1)
	proc_desc = NULL;
    }

  return proc_desc;
}

/* Return a non-zero result if the function is frameless; zero otherwise.  */

static int
alpha_mdebug_frameless (struct mdebug_extra_func_info *proc_desc)
{
  return (PROC_FRAME_REG (proc_desc) == ALPHA_SP_REGNUM
	  && PROC_FRAME_OFFSET (proc_desc) == 0);
}

/* This returns the PC of the first inst after the prologue.  If we can't
   find the prologue, then return 0.  */

static CORE_ADDR
alpha_mdebug_after_prologue (CORE_ADDR pc,
			     struct mdebug_extra_func_info *proc_desc)
{
  if (proc_desc)
    {
      /* If function is frameless, then we need to do it the hard way.  I
	 strongly suspect that frameless always means prologueless...  */
      if (alpha_mdebug_frameless (proc_desc))
	return 0;
    }

  return alpha_after_prologue (pc);
}

/* Return non-zero if we *might* be in a function prologue.  Return zero
   if we are definitively *not* in a function prologue.  */

static int
alpha_mdebug_in_prologue (CORE_ADDR pc,
			  struct mdebug_extra_func_info *proc_desc)
{
  CORE_ADDR after_prologue_pc = alpha_mdebug_after_prologue (pc, proc_desc);
  return (after_prologue_pc == 0 || pc < after_prologue_pc);
}


/* Frame unwinder that reads mdebug PDRs.  */

struct alpha_mdebug_unwind_cache
{
  struct mdebug_extra_func_info *proc_desc;
  CORE_ADDR vfp;
  trad_frame_saved_reg *saved_regs;
};

/* Extract all of the information about the frame from PROC_DESC
   and store the resulting register save locations in the structure.  */

static struct alpha_mdebug_unwind_cache *
alpha_mdebug_frame_unwind_cache (struct frame_info *this_frame, 
				 void **this_prologue_cache)
{
  struct alpha_mdebug_unwind_cache *info;
  struct mdebug_extra_func_info *proc_desc;
  ULONGEST vfp;
  CORE_ADDR pc, reg_position;
  unsigned long mask;
  int ireg, returnreg;

  if (*this_prologue_cache)
    return (struct alpha_mdebug_unwind_cache *) *this_prologue_cache;

  info = FRAME_OBSTACK_ZALLOC (struct alpha_mdebug_unwind_cache);
  *this_prologue_cache = info;
  pc = get_frame_address_in_block (this_frame);

  /* ??? We don't seem to be able to cache the lookup of the PDR
     from alpha_mdebug_frame_p.  It'd be nice if we could change
     the arguments to that function.  Oh well.  */
  proc_desc = find_proc_desc (pc);
  info->proc_desc = proc_desc;
  gdb_assert (proc_desc != NULL);

  info->saved_regs = trad_frame_alloc_saved_regs (this_frame);

  /* The VFP of the frame is at FRAME_REG+FRAME_OFFSET.  */
  vfp = get_frame_register_unsigned (this_frame, PROC_FRAME_REG (proc_desc));
  vfp += PROC_FRAME_OFFSET (info->proc_desc);
  info->vfp = vfp;

  /* Fill in the offsets for the registers which gen_mask says were saved.  */

  reg_position = vfp + PROC_REG_OFFSET (proc_desc);
  mask = PROC_REG_MASK (proc_desc);
  returnreg = PROC_PC_REG (proc_desc);

  /* Note that RA is always saved first, regardless of its actual
     register number.  */
  if (mask & (1 << returnreg))
    {
      /* Clear bit for RA so we don't save it again later.  */
      mask &= ~(1 << returnreg);

      info->saved_regs[returnreg].set_addr (reg_position);
      reg_position += 8;
    }

  for (ireg = 0; ireg <= 31; ++ireg)
    if (mask & (1 << ireg))
      {
	info->saved_regs[ireg].set_addr (reg_position);
	reg_position += 8;
      }

  reg_position = vfp + PROC_FREG_OFFSET (proc_desc);
  mask = PROC_FREG_MASK (proc_desc);

  for (ireg = 0; ireg <= 31; ++ireg)
    if (mask & (1 << ireg))
      {
	info->saved_regs[ALPHA_FP0_REGNUM + ireg].set_addr (reg_position);
	reg_position += 8;
      }

  /* The stack pointer of the previous frame is computed by popping
     the current stack frame.  */
  if (!info->saved_regs[ALPHA_SP_REGNUM].is_addr ())
    info->saved_regs[ALPHA_SP_REGNUM].set_value (vfp);

  return info;
}

/* Given a GDB frame, determine the address of the calling function's
   frame.  This will be used to create a new GDB frame struct.  */

static void
alpha_mdebug_frame_this_id (struct frame_info *this_frame,
			    void **this_prologue_cache,
			    struct frame_id *this_id)
{
  struct alpha_mdebug_unwind_cache *info
    = alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache);

  *this_id = frame_id_build (info->vfp, get_frame_func (this_frame));
}

/* Retrieve the value of REGNUM in FRAME.  Don't give up!  */

static struct value *
alpha_mdebug_frame_prev_register (struct frame_info *this_frame,
				  void **this_prologue_cache, int regnum)
{
  struct alpha_mdebug_unwind_cache *info
    = alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache);

  /* The PC of the previous frame is stored in the link register of
     the current frame.  Frob regnum so that we pull the value from
     the correct place.  */
  if (regnum == ALPHA_PC_REGNUM)
    regnum = PROC_PC_REG (info->proc_desc);
  
  return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
}

/* Return a non-zero result if the size of the stack frame exceeds the
   maximum debuggable frame size (512 Kbytes); zero otherwise.  */

static int
alpha_mdebug_max_frame_size_exceeded (struct mdebug_extra_func_info *proc_desc)
{
  /* If frame offset is null, we can be in two cases: either the
     function is frameless (the stack frame is null) or its
     frame exceeds the maximum debuggable frame size (512 Kbytes).  */

  return (PROC_FRAME_OFFSET (proc_desc) == 0
	  && !alpha_mdebug_frameless (proc_desc));
}

static int
alpha_mdebug_frame_sniffer (const struct frame_unwind *self,
			    struct frame_info *this_frame,
			    void **this_cache)
{
  CORE_ADDR pc = get_frame_address_in_block (this_frame);
  struct mdebug_extra_func_info *proc_desc;

  /* If this PC does not map to a PDR, then clearly this isn't an
     mdebug frame.  */
  proc_desc = find_proc_desc (pc);
  if (proc_desc == NULL)
    return 0;

  /* If we're in the prologue, the PDR for this frame is not yet valid.
     Say no here and we'll fall back on the heuristic unwinder.  */
  if (alpha_mdebug_in_prologue (pc, proc_desc))
    return 0;

  /* If the maximum debuggable frame size has been exceeded, the
     proc desc is bogus.  Fall back on the heuristic unwinder.  */
  if (alpha_mdebug_max_frame_size_exceeded (proc_desc))
    return 0;

  return 1;
}

static const struct frame_unwind alpha_mdebug_frame_unwind =
{
  "alpha mdebug",
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  alpha_mdebug_frame_this_id,
  alpha_mdebug_frame_prev_register,
  NULL,
  alpha_mdebug_frame_sniffer
};

static CORE_ADDR
alpha_mdebug_frame_base_address (struct frame_info *this_frame,
				 void **this_prologue_cache)
{
  struct alpha_mdebug_unwind_cache *info
    = alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache);

  return info->vfp;
}

static CORE_ADDR
alpha_mdebug_frame_locals_address (struct frame_info *this_frame,
				   void **this_prologue_cache)
{
  struct alpha_mdebug_unwind_cache *info
    = alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache);

  return info->vfp - PROC_LOCALOFF (info->proc_desc);
}

static CORE_ADDR
alpha_mdebug_frame_args_address (struct frame_info *this_frame,
				 void **this_prologue_cache)
{
  struct alpha_mdebug_unwind_cache *info
    = alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache);

  return info->vfp - ALPHA_NUM_ARG_REGS * 8;
}

static const struct frame_base alpha_mdebug_frame_base = {
  &alpha_mdebug_frame_unwind,
  alpha_mdebug_frame_base_address,
  alpha_mdebug_frame_locals_address,
  alpha_mdebug_frame_args_address
};

static const struct frame_base *
alpha_mdebug_frame_base_sniffer (struct frame_info *this_frame)
{
  CORE_ADDR pc = get_frame_address_in_block (this_frame);
  struct mdebug_extra_func_info *proc_desc;

  /* If this PC does not map to a PDR, then clearly this isn't an
     mdebug frame.  */
  proc_desc = find_proc_desc (pc);
  if (proc_desc == NULL)
    return NULL;

  /* If the maximum debuggable frame size has been exceeded, the
     proc desc is bogus.  Fall back on the heuristic unwinder.  */
  if (alpha_mdebug_max_frame_size_exceeded (proc_desc))
    return 0;

  return &alpha_mdebug_frame_base;
}


void
alpha_mdebug_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  frame_unwind_append_unwinder (gdbarch, &alpha_mdebug_frame_unwind);
  frame_base_append_sniffer (gdbarch, alpha_mdebug_frame_base_sniffer);
}
