/* Definitions for frame unwinder, for GDB, the GNU debugger.

   Copyright (C) 2003-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 "extract-store-integer.h"
#include "frame.h"
#include "frame-unwind.h"
#include "dummy-frame.h"
#include "inline-frame.h"
#include "value.h"
#include "regcache.h"
#include "gdbsupport/gdb_obstack.h"
#include "target.h"
#include "gdbarch.h"
#include "dwarf2/frame-tailcall.h"
#include "cli/cli-cmds.h"
#include "cli/cli-option.h"
#include "inferior.h"

/* Conversion list between the enum for frame_unwind_class and
   string.  */
static const char * unwind_class_conversion[] =
{
  "GDB",
  "EXTENSION",
  "DEBUGINFO",
  "ARCH",
  nullptr
};

/* Default sniffers, that must always be the first in the unwinder list,
   no matter the architecture.  */
static constexpr std::initializer_list<const frame_unwind *>
  standard_unwinders =
{
  &dummy_frame_unwind,
  /* The DWARF tailcall sniffer must come before the inline sniffer.
     Otherwise, we can end up in a situation where a DWARF frame finds
     tailcall information, but then the inline sniffer claims a frame
     before the tailcall sniffer, resulting in confusion.  This is
     safe to do always because the tailcall sniffer can only ever be
     activated if the newer frame was created using the DWARF
     unwinder, and it also found tailcall information.  */
  &dwarf2_tailcall_frame_unwind,
  &inline_frame_unwind,
};

/* If an unwinder should be prepended to the list, this is the
   index in which it should be inserted.  */
static constexpr int prepend_unwinder_index = standard_unwinders.size ();

static const registry<gdbarch>::key<std::vector<const frame_unwind *>>
     frame_unwind_data;

/* Retrieve the list of frame unwinders available in GDBARCH.
   If this list is empty, it is initialized before being returned.  */
static std::vector<const frame_unwind *> &
get_frame_unwind_table (struct gdbarch *gdbarch)
{
  std::vector<const frame_unwind *> *table = frame_unwind_data.get (gdbarch);
  if (table != nullptr)
    return *table;

  table = new std::vector<const frame_unwind *>;
  table->insert (table->begin (), standard_unwinders.begin (),
		 standard_unwinders.end ());

  frame_unwind_data.set (gdbarch, table);

  return *table;
}

static const char *
frame_unwinder_class_str (frame_unwind_class uclass)
{
  gdb_assert (uclass < UNWIND_CLASS_NUMBER);
  return unwind_class_conversion[uclass];
}

/* Case insensitive search for a frame_unwind_class based on the given
   string.  */
static enum frame_unwind_class
str_to_frame_unwind_class (const char *class_str)
{
  for (int i = 0; i < UNWIND_CLASS_NUMBER; i++)
    {
      if (strcasecmp (unwind_class_conversion[i], class_str) == 0)
	return (frame_unwind_class) i;
    }

  error (_("Unknown frame unwind class: %s"), class_str);
}

void
frame_unwind_prepend_unwinder (struct gdbarch *gdbarch,
				const struct frame_unwind *unwinder)
{
  std::vector<const frame_unwind *> &table = get_frame_unwind_table (gdbarch);

  table.insert (table.begin () + prepend_unwinder_index, unwinder);
}

void
frame_unwind_append_unwinder (struct gdbarch *gdbarch,
			      const struct frame_unwind *unwinder)
{
  get_frame_unwind_table (gdbarch).push_back (unwinder);
}

/* Call SNIFFER from UNWINDER.  If it succeeded set UNWINDER for
   THIS_FRAME and return true.  Otherwise the function keeps THIS_FRAME
   unchanged and returns false.  */

static bool
frame_unwind_try_unwinder (const frame_info_ptr &this_frame, void **this_cache,
			  const struct frame_unwind *unwinder)
{
  int res = 0;

  unsigned int entry_generation = get_frame_cache_generation ();

  frame_prepare_for_sniffer (this_frame, unwinder);

  try
    {
      frame_debug_printf ("trying unwinder \"%s\"", unwinder->name ());
      res = unwinder->sniff (this_frame, this_cache);
    }
  catch (const gdb_exception &ex)
    {
      frame_debug_printf ("caught exception: %s", ex.message->c_str ());

      /* Catch all exceptions, caused by either interrupt or error.
	 Reset *THIS_CACHE, unless something reinitialized the frame
	 cache meanwhile, in which case THIS_FRAME/THIS_CACHE are now
	 dangling.  */
      if (get_frame_cache_generation () == entry_generation)
	{
	  *this_cache = NULL;
	  frame_cleanup_after_sniffer (this_frame);
	}

      if (ex.error == NOT_AVAILABLE_ERROR)
	{
	  /* This usually means that not even the PC is available,
	     thus most unwinders aren't able to determine if they're
	     the best fit.  Keep trying.  Fallback prologue unwinders
	     should always accept the frame.  */
	  return false;
	}
      throw;
    }

  if (res)
    {
      frame_debug_printf ("yes");
      return true;
    }
  else
    {
      frame_debug_printf ("no");
      /* Don't set *THIS_CACHE to NULL here, because sniffer has to do
	 so.  */
      frame_cleanup_after_sniffer (this_frame);
      return false;
    }
  gdb_assert_not_reached ("frame_unwind_try_unwinder");
}

/* Iterate through sniffers for THIS_FRAME frame until one returns with an
   unwinder implementation.  THIS_FRAME->UNWIND must be NULL, it will get set
   by this function.  Possibly initialize THIS_CACHE.  */

void
frame_unwind_find_by_frame (const frame_info_ptr &this_frame, void **this_cache)
{
  FRAME_SCOPED_DEBUG_ENTER_EXIT;
  frame_debug_printf ("this_frame=%d", frame_relative_level (this_frame));

  /* If we see a disabled unwinder, we assume some test is being run on
     GDB, and we don't want to internal_error at the end of this function.  */
  bool seen_disabled_unwinder = false;
  /* Lambda to factor out the logic of checking if an unwinder is enabled,
     testing it and otherwise recording if we saw a disable unwinder.  */
  auto test_unwinder = [&] (const struct frame_unwind *unwinder)
    {
      if (unwinder == nullptr)
	return false;

      if (!unwinder->enabled ())
	{
	  seen_disabled_unwinder = true;
	  return false;
	}

      return frame_unwind_try_unwinder (this_frame,
					this_cache,
					unwinder);
    };

  if (test_unwinder (target_get_unwinder ()))
    return;

  if (test_unwinder (target_get_tailcall_unwinder ()))
    return;

  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  std::vector<const frame_unwind *> &table = get_frame_unwind_table (gdbarch);
  for (const auto &unwinder : table)
    {
      if (test_unwinder (unwinder))
	return;
    }

  if (seen_disabled_unwinder)
    error (_("Required frame unwinder may have been disabled"
	     ", see 'maint info frame-unwinders'"));
  else
    internal_error (_("frame_unwind_find_by_frame failed"));
}

/* A default frame sniffer which always accepts the frame.  Used by
   fallback prologue unwinders.  */

int
default_frame_sniffer (const struct frame_unwind *self,
		       const frame_info_ptr &this_frame,
		       void **this_prologue_cache)
{
  return 1;
}

/* The default frame unwinder stop_reason callback.  */

enum unwind_stop_reason
default_frame_unwind_stop_reason (const frame_info_ptr &this_frame,
				  void **this_cache)
{
  struct frame_id this_id = get_frame_id (this_frame);

  if (this_id == outer_frame_id)
    return UNWIND_OUTERMOST;
  else
    return UNWIND_NO_REASON;
}

/* See frame-unwind.h.  */

CORE_ADDR
default_unwind_pc (struct gdbarch *gdbarch, const frame_info_ptr &next_frame)
{
  int pc_regnum = gdbarch_pc_regnum (gdbarch);
  CORE_ADDR pc = frame_unwind_register_unsigned (next_frame, pc_regnum);
  pc = gdbarch_addr_bits_remove (gdbarch, pc);
  return pc;
}

/* See frame-unwind.h.  */

CORE_ADDR
default_unwind_sp (struct gdbarch *gdbarch, const frame_info_ptr &next_frame)
{
  int sp_regnum = gdbarch_sp_regnum (gdbarch);
  return frame_unwind_register_unsigned (next_frame, sp_regnum);
}

/* Helper functions for value-based register unwinding.  These return
   a (possibly lazy) value of the appropriate type.  */

/* Return a value which indicates that FRAME did not save REGNUM.  */

struct value *
frame_unwind_got_optimized (const frame_info_ptr &frame, int regnum)
{
  struct gdbarch *gdbarch = frame_unwind_arch (frame);
  struct type *type = register_type (gdbarch, regnum);

  return value::allocate_optimized_out (type);
}

/* Return a value which indicates that FRAME copied REGNUM into
   register NEW_REGNUM.  */

struct value *
frame_unwind_got_register (const frame_info_ptr &frame,
			   int regnum, int new_regnum)
{
  return value_of_register_lazy (get_next_frame_sentinel_okay (frame),
				 new_regnum);
}

/* Return a value which indicates that FRAME saved REGNUM in memory at
   ADDR.  */

struct value *
frame_unwind_got_memory (const frame_info_ptr &frame, int regnum, CORE_ADDR addr)
{
  struct gdbarch *gdbarch = frame_unwind_arch (frame);
  struct value *v = value_at_lazy (register_type (gdbarch, regnum), addr);

  v->set_stack (true);
  return v;
}

/* Return a value which indicates that FRAME's saved version of
   REGNUM has a known constant (computed) value of VAL.  */

struct value *
frame_unwind_got_constant (const frame_info_ptr &frame, int regnum,
			   ULONGEST val)
{
  struct gdbarch *gdbarch = frame_unwind_arch (frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct value *reg_val;

  reg_val = value::zero (register_type (gdbarch, regnum), not_lval);
  store_unsigned_integer (reg_val->contents_writeable ().data (),
			  register_size (gdbarch, regnum), byte_order, val);
  return reg_val;
}

struct value *
frame_unwind_got_bytes (const frame_info_ptr &frame, int regnum,
			gdb::array_view<const gdb_byte> buf)
{
  struct gdbarch *gdbarch = frame_unwind_arch (frame);
  struct value *reg_val;

  reg_val = value::zero (register_type (gdbarch, regnum), not_lval);
  gdb::array_view<gdb_byte> val_contents = reg_val->contents_raw ();

  /* The value's contents buffer is zeroed on allocation so if buf is
     smaller, the remaining space will be filled with zero.

     This can happen when unwinding through signal frames.  For example, if
     an AArch64 program doesn't use SVE, then the Linux kernel will only
     save in the signal frame the first 128 bits of the vector registers,
     which is their minimum size, even if the vector length says they're
     bigger.  */
  gdb_assert (buf.size () <= val_contents.size ());

  memcpy (val_contents.data (), buf.data (), buf.size ());
  return reg_val;
}

/* Return a value which indicates that FRAME's saved version of REGNUM
   has a known constant (computed) value of ADDR.  Convert the
   CORE_ADDR to a target address if necessary.  */

struct value *
frame_unwind_got_address (const frame_info_ptr &frame, int regnum,
			  CORE_ADDR addr)
{
  struct gdbarch *gdbarch = frame_unwind_arch (frame);
  struct value *reg_val;

  reg_val = value::zero (register_type (gdbarch, regnum), not_lval);
  pack_long (reg_val->contents_writeable ().data (),
	     register_type (gdbarch, regnum), addr);
  return reg_val;
}

/* See frame-unwind.h.  */

enum unwind_stop_reason
frame_unwind_legacy::stop_reason (const frame_info_ptr &this_frame,
				  void **this_prologue_cache) const
{
  return m_stop_reason (this_frame, this_prologue_cache);
}

/* See frame-unwind.h.  */

void
frame_unwind_legacy::this_id (const frame_info_ptr &this_frame,
			      void **this_prologue_cache,
			      struct frame_id *id) const
{
  return m_this_id (this_frame, this_prologue_cache, id);
}

/* See frame-unwind.h.  */

struct value *
frame_unwind_legacy::prev_register (const frame_info_ptr &this_frame,
				    void **this_prologue_cache,
				    int regnum) const
{
  return m_prev_register (this_frame, this_prologue_cache, regnum);
}

/* See frame-unwind.h.  */

int
frame_unwind_legacy::sniff (const frame_info_ptr &this_frame,
			    void **this_prologue_cache) const
{
  return m_sniffer (this, this_frame, this_prologue_cache);
}

/* See frame-unwind.h.  */

void
frame_unwind_legacy::dealloc_cache (frame_info *self, void *this_cache) const
{
  if (m_dealloc_cache != nullptr)
    m_dealloc_cache (self, this_cache);
}

/* See frame-unwind.h.  */

struct gdbarch *
frame_unwind_legacy::prev_arch (const frame_info_ptr &this_frame,
				void **this_prologue_cache) const
{
  if (m_prev_arch == nullptr)
    return frame_unwind::prev_arch (this_frame, this_prologue_cache);
  return m_prev_arch (this_frame, this_prologue_cache);
}

/* Implement "maintenance info frame-unwinders" command.  */

static void
maintenance_info_frame_unwinders (const char *args, int from_tty)
{
  gdbarch *gdbarch = current_inferior ()->arch ();
  std::vector<const frame_unwind *> &table = get_frame_unwind_table (gdbarch);

  ui_out *uiout = current_uiout;
  ui_out_emit_table table_emitter (uiout, 4, -1, "FrameUnwinders");
  uiout->table_header (27, ui_left, "name", "Name");
  uiout->table_header (25, ui_left, "type", "Type");
  uiout->table_header (9, ui_left, "class", "Class");
  uiout->table_header (8, ui_left, "enabled", "Enabled");
  uiout->table_body ();

  for (const auto &unwinder : table)
    {
      ui_out_emit_list tuple_emitter (uiout, nullptr);
      uiout->field_string ("name", unwinder->name ());
      uiout->field_string ("type", frame_type_str (unwinder->type ()));
      uiout->field_string ("class", frame_unwinder_class_str (
					unwinder->unwinder_class ()));
      uiout->field_string ("enabled", unwinder->enabled () ? "Y" : "N");
      uiout->text ("\n");
    }
}

/* Options for disabling frame unwinders.  */
struct maint_frame_unwind_options
{
  std::string unwinder_name;
  const char *unwinder_class = nullptr;
  bool all = false;
};

static const gdb::option::option_def maint_frame_unwind_opt_defs[] = {

  gdb::option::flag_option_def<maint_frame_unwind_options> {
    "all",
    [] (maint_frame_unwind_options *opt) { return &opt->all; },
    N_("Change the state of all unwinders")
  },
  gdb::option::string_option_def<maint_frame_unwind_options> {
    "name",
    [] (maint_frame_unwind_options *opt) { return &opt->unwinder_name; },
    nullptr,
    N_("The name of the unwinder to have its state changed")
  },
  gdb::option::enum_option_def<maint_frame_unwind_options> {
    "class",
    unwind_class_conversion,
    [] (maint_frame_unwind_options *opt) { return &opt->unwinder_class; },
    nullptr,
    N_("The class of unwinders to have their states changed")
  }
};

static inline gdb::option::option_def_group
make_frame_unwind_enable_disable_options (maint_frame_unwind_options *opts)
{
  return {{maint_frame_unwind_opt_defs}, opts};
}

/* Helper function to both enable and disable frame unwinders.
   If ENABLE is true, this call will be enabling unwinders,
   otherwise the unwinders will be disabled.  */
static void
enable_disable_frame_unwinders (const char *args, int from_tty, bool enable)
{
  if (args == nullptr)
    {
      if (enable)
	error (_("Specify which frame unwinder(s) should be enabled"));
      else
	error (_("Specify which frame unwinder(s) should be disabled"));
    }

  struct gdbarch* gdbarch = current_inferior ()->arch ();
  std::vector<const frame_unwind *> unwinder_list
    = get_frame_unwind_table (gdbarch);

  maint_frame_unwind_options opts;
  gdb::option::process_options
    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR,
     make_frame_unwind_enable_disable_options (&opts));

  if ((opts.all && !opts.unwinder_name.empty ())
      || (opts.all && opts.unwinder_class != nullptr)
      || (!opts.unwinder_name.empty () && opts.unwinder_class != nullptr))
    error (_("Options are mutually exclusive"));

  /* First see if the user wants to change all unwinders.  */
  if (opts.all)
    {
      for (const frame_unwind *u : unwinder_list)
	u->set_enabled (enable);

      reinit_frame_cache ();
      return;
    }

  /* If user entered a specific unwinder name, handle it here.  If the
     unwinder is already at the expected state, error out.  */
  if (!opts.unwinder_name.empty ())
    {
      bool did_something = false;
      for (const frame_unwind *unwinder : unwinder_list)
	{
	  if (strcasecmp (unwinder->name (),
			  opts.unwinder_name.c_str ()) == 0)
	    {
	      if (unwinder->enabled () == enable)
		{
		  if (unwinder->enabled ())
		    error (_("unwinder %s is already enabled"),
			     unwinder->name ());
		  else
		    error (_("unwinder %s is already disabled"),
			     unwinder->name ());
		}
	      unwinder->set_enabled (enable);

	      did_something = true;
	      break;
	    }
	}
      if (!did_something)
	error (_("couldn't find unwinder named %s"),
	       opts.unwinder_name.c_str ());
    }
  else
    {
      if (opts.unwinder_class == nullptr)
	opts.unwinder_class = args;
      enum frame_unwind_class dclass = str_to_frame_unwind_class
	(opts.unwinder_class);
      for (const frame_unwind *unwinder: unwinder_list)
	{
	  if (unwinder->unwinder_class () == dclass)
	    unwinder->set_enabled (enable);
	}
    }

  reinit_frame_cache ();
}

/* Completer for the "maint frame-unwinder enable|disable" commands.  */

static void
enable_disable_frame_unwinders_completer (struct cmd_list_element *ignore,
					  completion_tracker &tracker,
					  const char *text,
					  const char * /*word*/)
{
  maint_frame_unwind_options opts;
  const auto group = make_frame_unwind_enable_disable_options (&opts);

  const char *start = text;
  if (gdb::option::complete_options
      (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group))
    return;

  /* Only complete a class name as a stand-alone operand when no options
     are given.  */
  if (start == text)
    complete_on_enum (tracker, unwind_class_conversion, text, text);
  return;
}

/* Implement "maint frame-unwinder disable" command.  */
static void
maintenance_disable_frame_unwinders (const char *args, int from_tty)
{
  enable_disable_frame_unwinders (args, from_tty, false);
}

/* Implement "maint frame-unwinder enable" command.  */
static void
maintenance_enable_frame_unwinders (const char *args, int from_tty)
{
  enable_disable_frame_unwinders (args, from_tty, true);
}

void _initialize_frame_unwind ();
void
_initialize_frame_unwind ()
{
  /* Add "maint info frame-unwinders".  */
  add_cmd ("frame-unwinders",
	   class_maintenance,
	   maintenance_info_frame_unwinders,
	   _("\
List the frame unwinders currently in effect.\n\
Unwinders are listed starting with the highest priority."),
	   &maintenanceinfolist);

  /* Add "maint frame-unwinder disable/enable".  */
  static struct cmd_list_element *maint_frame_unwinder;

  add_basic_prefix_cmd ("frame-unwinder", class_maintenance,
			_("Commands handling frame unwinders."),
			&maint_frame_unwinder, 0, &maintenancelist);

  cmd_list_element *c
    = add_cmd ("disable", class_maintenance, maintenance_disable_frame_unwinders,
	       _("\
Disable one or more frame unwinder(s).\n\
Usage: maint frame-unwinder disable [-all | -name NAME | [-class] CLASS]\n\
\n\
These are the meanings of the options:\n\
\t-all    - All available unwinders will be disabled\n\
\t-name   - NAME is the exact name of the frame unwinder to be disabled\n\
\t-class  - CLASS is the class of unwinders to be disabled. Valid classes are:\n\
\t\tGDB       - Unwinders added by GDB core;\n\
\t\tEXTENSION - Unwinders added by extension languages;\n\
\t\tDEBUGINFO - Unwinders that handle debug information;\n\
\t\tARCH      - Unwinders that use architecture-specific information;\n\
\n\
UNWINDER and NAME are case insensitive."),
	       &maint_frame_unwinder);
  set_cmd_completer_handle_brkchars (c,
				     enable_disable_frame_unwinders_completer);

  c =
    add_cmd ("enable", class_maintenance, maintenance_enable_frame_unwinders,
	     _("\
Enable one or more frame unwinder(s).\n\
Usage: maint frame-unwinder enable [-all | -name NAME | [-class] CLASS]\n\
\n\
These are the meanings of the options:\n\
\t-all    - All available unwinders will be enabled\n\
\t-name   - NAME is the exact name of the frame unwinder to be enabled\n\
\t-class  - CLASS is the class of unwinders to be enabled. Valid classes are:\n\
\t\tGDB       - Unwinders added by GDB core;\n\
\t\tEXTENSION - Unwinders added by extension languages;\n\
\t\tDEBUGINFO - Unwinders that handle debug information;\n\
\t\tARCH      - Unwinders that use architecture-specific information;\n\
\n\
UNWINDER and NAME are case insensitive."),
	     &maint_frame_unwinder);
  set_cmd_completer_handle_brkchars (c,
				     enable_disable_frame_unwinders_completer);
}
