/* Inline frame unwinder for GDB.

   Copyright (C) 2008-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 "breakpoint.h"
#include "inline-frame.h"
#include "addrmap.h"
#include "block.h"
#include "frame-unwind.h"
#include "inferior.h"
#include "gdbthread.h"
#include "regcache.h"
#include "symtab.h"
#include "frame.h"
#include "cli/cli-cmds.h"
#include "cli/cli-style.h"
#include <algorithm>

/* We need to save a few variables for every thread stopped at the
   virtual call site of an inlined function.  If there was always a
   "struct thread_info", we could hang it off that; in the mean time,
   keep our own list.  */
struct inline_state
{
  inline_state (thread_info *thread_, int skipped_frames_, CORE_ADDR saved_pc_,
		std::vector<const symbol *> &&function_symbols_)
    : thread (thread_), skipped_frames (skipped_frames_), saved_pc (saved_pc_),
      function_symbols (std::move (function_symbols_))
  {}

  /* The thread this data relates to.  It should be a currently
     stopped thread.  */
  thread_info *thread;

  /* The number of inlined functions we are skipping.  Each of these
     functions can be stepped in to.  */
  int skipped_frames;

  /* This is the PC used when calculating FUNCTION_SYMBOLS; used to check
     whether we have moved to a new location by user request.  If so, we
     invalidate any skipped frames.  */
  CORE_ADDR saved_pc;

  /* The list of all inline functions that start at SAVED_PC, except for
     the last entry which will either be a non-inline function, or an
     inline function that doesn't start at SAVED_PC.  This last entry is
     the function that "contains" all of the earlier functions.

     This list can be empty if SAVED_PC is for a code region which is not
     covered by any function (inline or non-inline).  */
  std::vector<const symbol *> function_symbols;
};

static std::vector<inline_state> inline_states;

/* Locate saved inlined frame state for THREAD, if it exists and is
   valid.  */

static struct inline_state *
find_inline_frame_state (thread_info *thread)
{
  auto state_it = std::find_if (inline_states.begin (), inline_states.end (),
				[thread] (const inline_state &state)
				  {
				    return state.thread == thread;
				  });

  if (state_it == inline_states.end ())
    return nullptr;

  inline_state &state = *state_it;
  struct regcache *regcache = get_thread_regcache (thread);
  CORE_ADDR current_pc = regcache_read_pc (regcache);

  if (current_pc != state.saved_pc)
    {
      /* PC has changed - this context is invalid.  Use the
	 default behavior.  */

      unordered_remove (inline_states, state_it);
      return nullptr;
    }

  return &state;
}

/* See inline-frame.h.  */

void
clear_inline_frame_state (process_stratum_target *target, ptid_t filter_ptid)
{
  gdb_assert (target != NULL);

  if (filter_ptid == minus_one_ptid || filter_ptid.is_pid ())
    {
      auto matcher = [target, &filter_ptid] (const inline_state &state)
	{
	  thread_info *t = state.thread;
	  return (t->inf->process_target () == target
		  && t->ptid.matches (filter_ptid));
	};

      auto it = std::remove_if (inline_states.begin (), inline_states.end (),
				matcher);

      inline_states.erase (it, inline_states.end ());

      return;
    }


  auto matcher = [target, &filter_ptid] (const inline_state &state)
    {
      thread_info *t = state.thread;
      return (t->inf->process_target () == target
	      && filter_ptid == t->ptid);
    };

  auto it = std::find_if (inline_states.begin (), inline_states.end (),
			  matcher);

  if (it != inline_states.end ())
    unordered_remove (inline_states, it);
}

/* See inline-frame.h.  */

void
clear_inline_frame_state (thread_info *thread)
{
  auto it = std::find_if (inline_states.begin (), inline_states.end (),
			  [thread] (const inline_state &state)
			    {
			      return thread == state.thread;
			    });

  if (it != inline_states.end ())
    unordered_remove (inline_states, it);
}

static void
inline_frame_this_id (const frame_info_ptr &this_frame,
		      void **this_cache,
		      struct frame_id *this_id)
{
  struct symbol *func;

  /* In order to have a stable frame ID for a given inline function,
     we must get the stack / special addresses from the underlying
     real frame's this_id method.  So we must call
     get_prev_frame_always.  Because we are inlined into some
     function, there must be previous frames, so this is safe - as
     long as we're careful not to create any cycles.  See related
     comments in get_prev_frame_always_1.  */
  frame_info_ptr prev_frame = get_prev_frame_always (this_frame);
  if (prev_frame == nullptr)
    error (_("failed to find previous frame when computing inline frame id"));
  *this_id = get_frame_id (prev_frame);

  /* We need a valid frame ID, so we need to be based on a valid
     frame.  FSF submission NOTE: this would be a good assertion to
     apply to all frames, all the time.  That would fix the ambiguity
     of null_frame_id (between "no/any frame" and "the outermost
     frame").  This will take work.  */
  gdb_assert (frame_id_p (*this_id));

  /* Future work NOTE: Alexandre Oliva applied a patch to GCC 4.3
     which generates DW_AT_entry_pc for inlined functions when
     possible.  If this attribute is available, we should use it
     in the frame ID (and eventually, to set breakpoints).  */
  func = get_frame_function (this_frame);
  gdb_assert (func != NULL);
  (*this_id).code_addr = func->value_block ()->entry_pc ();
  (*this_id).artificial_depth++;
}

static struct value *
inline_frame_prev_register (const frame_info_ptr &this_frame, void **this_cache,
			    int regnum)
{
  /* Use get_frame_register_value instead of
     frame_unwind_got_register, to avoid requiring this frame's ID.
     This frame's ID depends on the previous frame's ID (unusual), and
     the previous frame's ID depends on this frame's unwound
     registers.  If unwinding registers from this frame called
     get_frame_id, there would be a loop.

     Do not copy this code into any other unwinder!  Inlined functions
     are special; other unwinders must not have a dependency on the
     previous frame's ID, and therefore can and should use
     frame_unwind_got_register instead.  */
  return get_frame_register_value (this_frame, regnum);
}

/* Check whether we are at an inlining site that does not already
   have an associated frame.  */

static int
inline_frame_sniffer (const struct frame_unwind *self,
		      const frame_info_ptr &this_frame,
		      void **this_cache)
{
  CORE_ADDR this_pc;
  const struct block *frame_block, *cur_block;
  int depth;
  frame_info_ptr next_frame;
  struct inline_state *state = find_inline_frame_state (inferior_thread ());

  this_pc = get_frame_address_in_block (this_frame);
  frame_block = block_for_pc (this_pc);
  if (frame_block == NULL)
    return 0;

  /* Calculate DEPTH, the number of inlined functions at this
     location.  */
  depth = 0;
  cur_block = frame_block;
  while (cur_block->superblock ())
    {
      if (cur_block->inlined_p ())
	depth++;
      else if (cur_block->function () != NULL)
	break;

      cur_block = cur_block->superblock ();
    }

  /* Check how many inlined functions already have frames.  */
  for (next_frame = get_next_frame (this_frame);
       next_frame && get_frame_type (next_frame) == INLINE_FRAME;
       next_frame = get_next_frame (next_frame))
    {
      gdb_assert (depth > 0);
      depth--;
    }

  /* If this is the topmost frame, or all frames above us are inlined,
     then check whether we were requested to skip some frames (so they
     can be stepped into later).  */
  if (state != NULL && state->skipped_frames > 0 && next_frame == NULL)
    {
      gdb_assert (depth >= state->skipped_frames);
      depth -= state->skipped_frames;
    }

  /* If all the inlined functions here already have frames, then pass
     to the normal unwinder for this PC.  */
  if (depth == 0)
    return 0;

  /* If the next frame is an inlined function, but not the outermost, then
     we are the next outer.  If it is not an inlined function, then we
     are the innermost inlined function of a different real frame.  */
  return 1;
}

const struct frame_unwind inline_frame_unwind = {
  "inline",
  INLINE_FRAME,
  default_frame_unwind_stop_reason,
  inline_frame_this_id,
  inline_frame_prev_register,
  NULL,
  inline_frame_sniffer
};

/* Return non-zero if BLOCK, an inlined function block containing PC,
   has a group of contiguous instructions starting at PC (but not
   before it).  */

static int
block_starting_point_at (CORE_ADDR pc, const struct block *block)
{
  const struct blockvector *bv;
  const struct block *new_block;

  bv = blockvector_for_pc (pc, NULL);
  if (bv->map () == nullptr)
    return 0;

  new_block = (const struct block *) bv->map ()->find (pc - 1);
  if (new_block == NULL)
    return 1;

  if (new_block == block || block->contains (new_block))
    return 0;

  /* The immediately preceding address belongs to a different block,
     which is not a child of this one.  Treat this as an entrance into
     BLOCK.  */
  return 1;
}

/* Loop over the stop chain and determine if execution stopped in an
   inlined frame because of a breakpoint with a user-specified location
   set at FRAME_SYMBOL.  */

static bool
stopped_by_user_bp_inline_frame (const symbol *frame_symbol,
				 bpstat *stop_chain)
{
  for (bpstat *s = stop_chain; s != nullptr; s = s->next)
    {
      struct breakpoint *bpt = s->breakpoint_at;

      if (bpt != NULL
	  && (user_breakpoint_p (bpt) || bpt->type == bp_until))
	{
	  bp_location *loc = s->bp_location_at.get ();
	  enum bp_loc_type t = loc->loc_type;

	  if (t == bp_loc_software_breakpoint
	      || t == bp_loc_hardware_breakpoint)
	    {
	      /* If the location has a function symbol, check whether
		 the frame was for that inlined function.  If it has
		 no function symbol, then assume it is.  I.e., default
		 to presenting the stop at the innermost inline
		 function.  */
	      if (loc->symbol == nullptr
		  || frame_symbol == loc->symbol)
		return true;
	    }
	}
    }

  return false;
}

/* Return a list of all the inline function symbols that start at THIS_PC
   and the symbol for the function which contains all of the inline
   functions.

   The function symbols are ordered such that the most inner function is
   first.

   The returned list can be empty if there are no function at THIS_PC.  Or
   the returned list may have only a single entry if there are no inline
   functions starting at THIS_PC.  */

static std::vector<const symbol *>
gather_inline_frames (CORE_ADDR this_pc)
{
  /* Build the list of inline frames starting at THIS_PC.  After the loop,
     CUR_BLOCK is expected to point at the first function symbol (inlined or
     not) "containing" the inline frames starting at THIS_PC.  */
  const block *cur_block = block_for_pc (this_pc);
  if (cur_block == nullptr)
    return {};

  std::vector<const symbol *> function_symbols;
  while (cur_block != nullptr)
    {
      if (cur_block->inlined_p ())
	{
	  gdb_assert (cur_block->function () != nullptr);

	  /* See comments in inline_frame_this_id about this use
	     of BLOCK_ENTRY_PC.  */
	  if (cur_block->entry_pc () == this_pc
	      || block_starting_point_at (this_pc, cur_block))
	    function_symbols.push_back (cur_block->function ());
	  else
	    break;
	}
      else if (cur_block->function () != nullptr)
	break;

      cur_block = cur_block->superblock ();
    }

  /* If we have a code region for which we have no function blocks,
     possibly due to bad debug, or possibly just when some debug
     information has been stripped, then we can end up in a situation where
     there are global and static blocks for an address, but no function
     blocks.  In this case the early return above will not trigger as we
     will find the static block for THIS_PC, but in the loop above we will
     fail to find any function blocks (inline or non-inline) and so
     CUR_BLOCK will eventually become NULL.  If this happens then
     FUNCTION_SYMBOLS must be empty (as we found no function blocks).

     Otherwise, if we did find a function block, then we should only leave
     the above loop when CUR_BLOCK is pointing to a non-inline function
     that possibly contains some inline functions, or CUR_BLOCK should
     point to an inline function that doesn't start at THIS_PC.  */
  if (cur_block != nullptr)
    {
      gdb_assert (cur_block->function () != nullptr);
      function_symbols.push_back (cur_block->function ());
    }
  else
    gdb_assert (function_symbols.empty ());

  return function_symbols;
}

/* See inline-frame.h.  */

void
skip_inline_frames (thread_info *thread, bpstat *stop_chain)
{
  gdb_assert (find_inline_frame_state (thread) == nullptr);

  CORE_ADDR this_pc = get_frame_pc (get_current_frame ());

  std::vector<const symbol *> function_symbols
    = gather_inline_frames (this_pc);

  /* Figure out how many of the inlined frames to skip.  Do not skip an
     inlined frame (and its callers) if execution stopped because of a user
     breakpoint for this specific function.

     By default, skip all the found inlined frames.

     The last entry in FUNCTION_SYMBOLS is special, this is the function
     which contains all of the inlined functions, we never skip this.  */
  int skipped_frames = 0;

  for (const auto sym : function_symbols)
    {
      if (stopped_by_user_bp_inline_frame (sym, stop_chain)
	  || sym == function_symbols.back ())
	break;

      ++skipped_frames;
    }

  if (skipped_frames > 0)
    reinit_frame_cache ();

  inline_states.emplace_back (thread, skipped_frames, this_pc,
			      std::move (function_symbols));
}

/* Step into an inlined function by unhiding it.  */

void
step_into_inline_frame (thread_info *thread)
{
  inline_state *state = find_inline_frame_state (thread);

  gdb_assert (state != NULL && state->skipped_frames > 0);
  state->skipped_frames--;
  reinit_frame_cache ();
}

/* Return the number of hidden functions inlined into the current
   frame.  */

int
inline_skipped_frames (thread_info *thread)
{
  inline_state *state = find_inline_frame_state (thread);

  if (state == NULL)
    return 0;
  else
    return state->skipped_frames;
}

/* If one or more inlined functions are hidden, return the symbol for
   the function inlined into the current frame.  */

const symbol *
inline_skipped_symbol (thread_info *thread)
{
  inline_state *state = find_inline_frame_state (thread);
  gdb_assert (state != NULL);

  /* This should only be called when we are skipping at least one frame,
     hence FUNCTION_SYMBOLS will contain more than one entry (the last
     entry is the "outer" containing function).

     As we initialise SKIPPED_FRAMES at the same time as we build
     FUNCTION_SYMBOLS it should be true that SKIPPED_FRAMES never indexes
     outside of the FUNCTION_SYMBOLS vector.  */
  gdb_assert (state->function_symbols.size () > 1);
  gdb_assert (state->skipped_frames > 0);
  gdb_assert (state->skipped_frames < state->function_symbols.size ());
  return state->function_symbols[state->skipped_frames - 1];
}

/* Return the number of functions inlined into THIS_FRAME.  Some of
   the callees may not have associated frames (see
   skip_inline_frames).  */

int
frame_inlined_callees (const frame_info_ptr &this_frame)
{
  frame_info_ptr next_frame;
  int inline_count = 0;

  /* First count how many inlined functions at this PC have frames
     above FRAME (are inlined into FRAME).  */
  for (next_frame = get_next_frame (this_frame);
       next_frame && get_frame_type (next_frame) == INLINE_FRAME;
       next_frame = get_next_frame (next_frame))
    inline_count++;

  /* Simulate some most-inner inlined frames which were suppressed, so
     they can be stepped into later.  If we are unwinding already
     outer frames from some non-inlined frame this does not apply.  */
  if (next_frame == NULL)
    inline_count += inline_skipped_frames (inferior_thread ());

  return inline_count;
}

/* The 'maint info inline-frames' command.  Takes an optional address
   expression and displays inline frames that start at the given address,
   or at the address of the current thread if no address is given.  */

static void
maintenance_info_inline_frames (const char *arg, int from_tty)
{
  std::optional<std::vector<const symbol *>> local_function_symbols;
  std::vector<const symbol *> *function_symbols;
  int skipped_frames;
  CORE_ADDR addr;

  if (arg == nullptr)
    {
      /* With no argument then the user wants to know about the current
	 inline frame information.  This information is cached per-thread
	 and can be updated as the user steps between inline functions at
	 the current address.  */

      if (inferior_ptid == null_ptid)
	error (_("no inferior thread"));

      thread_info *thread = inferior_thread ();
      auto it = std::find_if (inline_states.begin (), inline_states.end (),
			      [thread] (const inline_state &istate)
			      {
				return thread == istate.thread;
			      });

      /* Stopped threads don't always have cached inline_state
	 information.  We always skip computing the inline_state after a
	 stepi or nexti, but also in some other cases when we can be sure
	 that the inferior isn't at the start of an inlined function.
	 Check out the call to skip_inline_frames in handle_signal_stop
	 for more details.  */
      if (it != inline_states.end ())
	{
	  /* We do have cached inline frame information, use it.  This
	     gives us access to the current skipped_frames count so we can
	     correctly indicate when the inferior is not in the inner most
	     inlined function.  */
	  gdb_printf (_("Cached inline state information for thread %s.\n"),
		      print_thread_id (thread));

	  function_symbols = &it->function_symbols;
	  skipped_frames = it->skipped_frames;
	  addr = it->saved_pc;
	}
      else
	{
	  /* No cached inline frame information, lookup the information for
	     the current address.  */
	  gdb_printf (_("Inline state information for thread %s.\n"),
		      print_thread_id (thread));

	  addr = get_frame_pc (get_current_frame ());
	  local_function_symbols.emplace (gather_inline_frames (addr));

	  function_symbols = &(local_function_symbols.value ());
	  skipped_frames = 0;
	}
    }
  else
    {
      /* If there is an argument then parse it as an address, the user is
	 asking about inline functions that start at the given address.  */

      addr = parse_and_eval_address (arg);
      local_function_symbols.emplace (gather_inline_frames (addr));

      function_symbols = &(local_function_symbols.value ());
      skipped_frames = function_symbols->size () - 1;
    }

  /* The address we're analysing.  */
  gdb_printf (_("program counter = %ps\n"),
	      styled_string (address_style.style (),
			     core_addr_to_string_nz (addr)));

  gdb_printf (_("skipped frames = %d\n"), skipped_frames);

  /* Print the full list of function symbols in STATE.  Highlight the
     current function as indicated by the skipped frames counter.  */
  for (size_t i = 0; i < function_symbols->size (); ++i)
    gdb_printf (_("%c %ps\n"),
		(i == skipped_frames ? '>' : ' '),
		styled_string (function_name_style.style (),
			       (*function_symbols)[i]->print_name ()));
}



void _initialize_inline_frame ();
void
_initialize_inline_frame ()
{
  add_cmd ("inline-frames", class_maintenance, maintenance_info_inline_frames,
	   _("\
Display inline frame information for current thread.\n\
\n\
Usage:\n\
\n\
  maintenance info inline-frames [ADDRESS]\n\
\n\
With no ADDRESS show all inline frames starting at the current program\n\
counter address.  When ADDRESS is given, list all inline frames starting\n\
at ADDRESS.\n\
\n\
The last frame listed might not start at ADDRESS, this is the frame that\n\
contains the other inline frames."),
	   &maintenanceinfolist);
}
