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

   Copyright (C) 2003-2025 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,
#if defined(DWARF_FORMAT_AVAILABLE)
  /* 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,
#endif
  &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)
    table = frame_unwind_data.emplace (gdbarch,
				       standard_unwinders.begin (),
				       standard_unwinders.end ());
  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);
}
