/* Traditional frame unwind support, for GDB the GNU Debugger.

   Copyright (C) 2003-2021 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/>.  */

#ifndef TRAD_FRAME_H
#define TRAD_FRAME_H

#include "frame.h"		/* For "struct frame_id".  */

struct frame_info;
struct regcache_map_entry;
struct trad_frame_cache;

/* A simple, or traditional frame cache.

   The entire cache is populated in a single pass and then generic
   routines are used to extract the various cache values.  */

struct trad_frame_cache *trad_frame_cache_zalloc (struct frame_info *);

/* This frame's ID.  */
void trad_frame_set_id (struct trad_frame_cache *this_trad_cache,
			struct frame_id this_id);
void trad_frame_get_id (struct trad_frame_cache *this_trad_cache,
			struct frame_id *this_id);
void trad_frame_set_this_base (struct trad_frame_cache *this_trad_cache,
			       CORE_ADDR this_base);
CORE_ADDR trad_frame_get_this_base (struct trad_frame_cache *this_trad_cache);

void trad_frame_set_reg_realreg (struct trad_frame_cache *this_trad_cache,
				 int regnum, int realreg);
void trad_frame_set_reg_addr (struct trad_frame_cache *this_trad_cache,
			      int regnum, CORE_ADDR addr);
void trad_frame_set_reg_regmap (struct trad_frame_cache *this_trad_cache,
				const struct regcache_map_entry *regmap,
				CORE_ADDR addr, size_t size);
void trad_frame_set_reg_value (struct trad_frame_cache *this_cache,
			       int regnum, LONGEST val);

/* Given the cache in THIS_TRAD_CACHE, set the value of REGNUM to the bytes
   contained in BYTES with size SIZE.  */
void trad_frame_set_reg_value_bytes (struct trad_frame_cache *this_trad_cache,
				     int regnum,
				     gdb::array_view<const gdb_byte> bytes);

struct value *trad_frame_get_register (struct trad_frame_cache *this_trad_cache,
				       struct frame_info *this_frame,
				       int regnum);

/* Describes the kind of encoding a stored register has.  */
enum class trad_frame_saved_reg_kind
{
  /* Register value is unknown.  */
  UNKNOWN = 0,
  /* Register value is a constant.  */
  VALUE,
  /* Register value is in another register.  */
  REALREG,
  /* Register value is at an address.  */
  ADDR,
  /* Register value is a sequence of bytes.  */
  VALUE_BYTES
};

/* A struct that describes a saved register in a frame.  */

struct trad_frame_saved_reg
{
  /* Setters */

  /* Encode that the saved register's value is constant VAL in the
     trad-frame.  */
  void set_value (LONGEST val)
  {
    m_kind = trad_frame_saved_reg_kind::VALUE;
    m_reg.value = val;
  }

  /* Encode that the saved register's value is stored in register REALREG.  */
  void set_realreg (int realreg)
  {
    m_kind = trad_frame_saved_reg_kind::REALREG;
    m_reg.realreg = realreg;
  }

  /* Encode that the saved register's value is stored in memory at ADDR.  */
  void set_addr (LONGEST addr)
  {
    m_kind = trad_frame_saved_reg_kind::ADDR;
    m_reg.addr = addr;
  }

  /* Encode that the saved register's value is unknown.  */
  void set_unknown ()
  {
    m_kind = trad_frame_saved_reg_kind::UNKNOWN;
  }

  /* Encode that the saved register's value is stored as a sequence of bytes.
     This is useful when the value is larger than what primitive types
     can hold.  */
  void set_value_bytes (gdb::array_view<const gdb_byte> bytes)
  {
    /* Allocate the space and copy the data bytes.  */
    gdb_byte *data = FRAME_OBSTACK_CALLOC (bytes.size (), gdb_byte);
    memcpy (data, bytes.data (), bytes.size ());

    m_kind = trad_frame_saved_reg_kind::VALUE_BYTES;
    m_reg.value_bytes = data;
  }

  /* Getters */

  LONGEST value () const
  {
    gdb_assert (m_kind == trad_frame_saved_reg_kind::VALUE);
    return m_reg.value;
  }

  int realreg () const
  {
    gdb_assert (m_kind == trad_frame_saved_reg_kind::REALREG);
    return m_reg.realreg;
  }

  LONGEST addr () const
  {
    gdb_assert (m_kind == trad_frame_saved_reg_kind::ADDR);
    return m_reg.addr;
  }

  const gdb_byte *value_bytes () const
  {
    gdb_assert (m_kind == trad_frame_saved_reg_kind::VALUE_BYTES);
    return m_reg.value_bytes;
  }

  /* Convenience functions, return true if the register has been
     encoded as specified.  Return false otherwise.  */
  bool is_value () const
  {
    return m_kind == trad_frame_saved_reg_kind::VALUE;
  }

  bool is_realreg () const
  {
    return m_kind == trad_frame_saved_reg_kind::REALREG;
  }

  bool is_addr () const
  {
    return m_kind == trad_frame_saved_reg_kind::ADDR;
  }

  bool is_unknown () const
  {
    return m_kind == trad_frame_saved_reg_kind::UNKNOWN;
  }

  bool is_value_bytes () const
  {
    return m_kind == trad_frame_saved_reg_kind::VALUE_BYTES;
  }

private:

  trad_frame_saved_reg_kind m_kind;

  union {
    LONGEST value;
    int realreg;
    LONGEST addr;
    const gdb_byte *value_bytes;
  } m_reg;
};

/* Reset the saved regs cache, setting register values to REALREG.  */
void trad_frame_reset_saved_regs (struct gdbarch *gdbarch,
				  trad_frame_saved_reg *regs);

/* Return a freshly allocated (and initialized) trad_frame array.  */
trad_frame_saved_reg *trad_frame_alloc_saved_regs (struct frame_info *);
trad_frame_saved_reg *trad_frame_alloc_saved_regs (struct gdbarch *);

/* Given the trad_frame info, return the location of the specified
   register.  */
struct value *trad_frame_get_prev_register (struct frame_info *this_frame,
					    trad_frame_saved_reg this_saved_regs[],
					    int regnum);

#endif
