/* Target-dependent mdebug code for the ALPHA architecture.
   Copyright (C) 1993-2024 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 "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.  */

/* 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
		|				|
*/

#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 > b->start ())
	/* 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, SEARCH_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 (const frame_info_ptr &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 (const frame_info_ptr &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 (const frame_info_ptr &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,
			    const frame_info_ptr &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 (const frame_info_ptr &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 (const frame_info_ptr &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 (const frame_info_ptr &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 (const frame_info_ptr &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);
}
