/* Inline frame unwinder for GDB.

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

#include "defs.h"
#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 <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<symbol *> &&skipped_symbols_)
    : thread (thread_), skipped_frames (skipped_frames_), saved_pc (saved_pc_),
      skipped_symbols (std::move (skipped_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;

  /* Only valid if SKIPPED_FRAMES is non-zero.  This is the PC used
     when calculating SKIPPED_FRAMES; 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;

  /* Only valid if SKIPPED_FRAMES is non-zero.  This is the list of all
     function symbols that have been skipped, from inner most to outer
     most.  It is used to find the call site of the current frame.  */
  std::vector<struct symbol *> skipped_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 (struct frame_info *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.  */
  *this_id = get_frame_id (get_prev_frame_always (this_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 = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (func));
  (*this_id).artificial_depth++;
}

static struct value *
inline_frame_prev_register (struct frame_info *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,
		      struct frame_info *this_frame,
		      void **this_cache)
{
  CORE_ADDR this_pc;
  const struct block *frame_block, *cur_block;
  int depth;
  struct frame_info *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 (BLOCK_SUPERBLOCK (cur_block))
    {
      if (block_inlined_p (cur_block))
	depth++;
      else if (BLOCK_FUNCTION (cur_block) != NULL)
	break;

      cur_block = BLOCK_SUPERBLOCK (cur_block);
    }

  /* 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 (BLOCKVECTOR_MAP (bv) == NULL)
    return 0;

  new_block = (const struct block *) addrmap_find (BLOCKVECTOR_MAP (bv),
						   pc - 1);
  if (new_block == NULL)
    return 1;

  if (new_block == block || contained_in (new_block, 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_BLOCK.  */

static bool
stopped_by_user_bp_inline_frame (const block *frame_block, bpstat stop_chain)
{
  for (bpstat s = stop_chain; s != NULL; 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_block == SYMBOL_BLOCK_VALUE (loc->symbol))
		return true;
	    }
	}
    }

  return false;
}

/* See inline-frame.h.  */

void
skip_inline_frames (thread_info *thread, bpstat stop_chain)
{
  const struct block *frame_block, *cur_block;
  std::vector<struct symbol *> skipped_syms;
  int skip_count = 0;

  /* This function is called right after reinitializing the frame
     cache.  We try not to do more unwinding than absolutely
     necessary, for performance.  */
  CORE_ADDR this_pc = get_frame_pc (get_current_frame ());
  frame_block = block_for_pc (this_pc);

  if (frame_block != NULL)
    {
      cur_block = frame_block;
      while (BLOCK_SUPERBLOCK (cur_block))
	{
	  if (block_inlined_p (cur_block))
	    {
	      /* See comments in inline_frame_this_id about this use
		 of BLOCK_ENTRY_PC.  */
	      if (BLOCK_ENTRY_PC (cur_block) == this_pc
		  || block_starting_point_at (this_pc, cur_block))
		{
		  /* Do not skip the inlined frame if execution
		     stopped in an inlined frame because of a user
		     breakpoint for this inline function.  */
		  if (stopped_by_user_bp_inline_frame (cur_block, stop_chain))
		    break;

		  skip_count++;
		  skipped_syms.push_back (BLOCK_FUNCTION (cur_block));
		}
	      else
		break;
	    }
	  else if (BLOCK_FUNCTION (cur_block) != NULL)
	    break;

	  cur_block = BLOCK_SUPERBLOCK (cur_block);
	}
    }

  gdb_assert (find_inline_frame_state (thread) == NULL);
  inline_states.emplace_back (thread, skip_count, this_pc,
			      std::move (skipped_syms));

  if (skip_count != 0)
    reinit_frame_cache ();
}

/* 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.  */

struct 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 SKIPPED_FRAMES will be greater than zero when we get here.
     We initialise SKIPPED_FRAMES at the same time as we build
     SKIPPED_SYMBOLS, hence it should be true that SKIPPED_FRAMES never
     indexes outside of the SKIPPED_SYMBOLS vector.  */
  gdb_assert (state->skipped_frames > 0);
  gdb_assert (state->skipped_frames <= state->skipped_symbols.size ());
  return state->skipped_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 (struct frame_info *this_frame)
{
  struct frame_info *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;
}
