/* Target-dependent mdebug code for the ALPHA architecture.
   Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
   2003, 2007, 2008, 2009 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 "gdb_assert.h"
#include "gdb_string.h"
#include "trad-frame.h"

#include "alpha-tdep.h"
#include "mdebugread.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)
{
  struct block *b = block_for_pc (pc);
  struct mdebug_extra_func_info *proc_desc = NULL;
  struct symbol *sym = NULL;
  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);
    }

  if (sym)
    {
      proc_desc = (struct mdebug_extra_func_info *) SYMBOL_VALUE (sym);

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

/* 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 (PROC_FRAME_REG (proc_desc) == ALPHA_SP_REGNUM
	  && PROC_FRAME_OFFSET (proc_desc) == 0)
	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;
  struct 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 *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].addr = reg_position;
      reg_position += 8;
    }

  for (ireg = 0; ireg <= 31; ++ireg)
    if (mask & (1 << ireg))
      {
	info->saved_regs[ireg].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].addr = reg_position;
	reg_position += 8;
      }

  /* The stack pointer of the previous frame is computed by popping
     the current stack frame.  */
  if (!trad_frame_addr_p (info->saved_regs, ALPHA_SP_REGNUM))
   trad_frame_set_value (info->saved_regs, ALPHA_SP_REGNUM, 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);
}

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;

  return 1;
}

static const struct frame_unwind alpha_mdebug_frame_unwind = {
  NORMAL_FRAME,
  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;

  return &alpha_mdebug_frame_base;
}


void
alpha_mdebug_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  frame_unwind_append_unwinder (gdbarch, &alpha_mdebug_frame_unwind);
  frame_base_append_sniffer (gdbarch, alpha_mdebug_frame_base_sniffer);
}
