/* Code dealing with dummy stack frames, for GDB, the GNU debugger.

   Copyright (C) 1986-2020 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 "dummy-frame.h"
#include "regcache.h"
#include "frame.h"
#include "inferior.h"
#include "frame-unwind.h"
#include "command.h"
#include "gdbcmd.h"
#include "observable.h"
#include "gdbthread.h"
#include "infcall.h"
#include "gdbarch.h"

struct dummy_frame_id
{
  /* This frame's ID.  Must match the value returned by
     gdbarch_dummy_id.  */
  struct frame_id id;

  /* The thread this dummy_frame relates to.  */
  thread_info *thread;
};

/* Return whether dummy_frame_id *ID1 and *ID2 are equal.  */

static int
dummy_frame_id_eq (struct dummy_frame_id *id1,
		   struct dummy_frame_id *id2)
{
  return frame_id_eq (id1->id, id2->id) && id1->thread == id2->thread;
}

/* List of dummy_frame destructors.  */

struct dummy_frame_dtor_list
{
  /* Next element in the list or NULL if this is the last element.  */
  struct dummy_frame_dtor_list *next;

  /* If non-NULL, a destructor that is run when this dummy frame is freed.  */
  dummy_frame_dtor_ftype *dtor;

  /* Arbitrary data that is passed to DTOR.  */
  void *dtor_data;
};

/* Dummy frame.  This saves the processor state just prior to setting
   up the inferior function call.  Older targets save the registers
   on the target stack (but that really slows down function calls).  */

struct dummy_frame
{
  struct dummy_frame *next;

  /* An id represents a dummy frame.  */
  struct dummy_frame_id id;

  /* The caller's state prior to the call.  */
  struct infcall_suspend_state *caller_state;

  /* First element of destructors list or NULL if there are no
     destructors registered for this dummy_frame.  */
  struct dummy_frame_dtor_list *dtor_list;
};

static struct dummy_frame *dummy_frame_stack = NULL;

/* Push the caller's state, along with the dummy frame info, onto the
   dummy-frame stack.  */

void
dummy_frame_push (struct infcall_suspend_state *caller_state,
		  const frame_id *dummy_id, thread_info *thread)
{
  struct dummy_frame *dummy_frame;

  dummy_frame = XCNEW (struct dummy_frame);
  dummy_frame->caller_state = caller_state;
  dummy_frame->id.id = (*dummy_id);
  dummy_frame->id.thread = thread;
  dummy_frame->next = dummy_frame_stack;
  dummy_frame_stack = dummy_frame;
}

/* Remove *DUMMY_PTR from the dummy frame stack.  */

static void
remove_dummy_frame (struct dummy_frame **dummy_ptr)
{
  struct dummy_frame *dummy = *dummy_ptr;

  while (dummy->dtor_list != NULL)
    {
      struct dummy_frame_dtor_list *list = dummy->dtor_list;

      dummy->dtor_list = list->next;
      list->dtor (list->dtor_data, 0);
      xfree (list);
    }

  *dummy_ptr = dummy->next;
  discard_infcall_suspend_state (dummy->caller_state);
  xfree (dummy);
}

/* Delete any breakpoint B which is a momentary breakpoint for return from
   inferior call matching DUMMY_VOIDP.  */

static bool
pop_dummy_frame_bpt (struct breakpoint *b, struct dummy_frame *dummy)
{
  if (b->thread == dummy->id.thread->global_num
      && b->disposition == disp_del && frame_id_eq (b->frame_id, dummy->id.id))
    {
      while (b->related_breakpoint != b)
	delete_breakpoint (b->related_breakpoint);

      delete_breakpoint (b);

      /* Stop the traversal.  */
      return true;
    }

  /* Continue the traversal.  */
  return false;
}

/* Pop *DUMMY_PTR, restoring program state to that before the
   frame was created.  */

static void
pop_dummy_frame (struct dummy_frame **dummy_ptr)
{
  struct dummy_frame *dummy = *dummy_ptr;

  gdb_assert (dummy->id.thread == inferior_thread ());

  while (dummy->dtor_list != NULL)
    {
      struct dummy_frame_dtor_list *list = dummy->dtor_list;

      dummy->dtor_list = list->next;
      list->dtor (list->dtor_data, 1);
      xfree (list);
    }

  restore_infcall_suspend_state (dummy->caller_state);

  iterate_over_breakpoints ([dummy] (breakpoint* bp)
    {
      return pop_dummy_frame_bpt (bp, dummy);
    });

  /* restore_infcall_control_state frees inf_state,
     all that remains is to pop *dummy_ptr.  */
  *dummy_ptr = dummy->next;
  xfree (dummy);

  /* We've made right mess of GDB's local state, just discard
     everything.  */
  reinit_frame_cache ();
}

/* Look up DUMMY_ID.
   Return NULL if not found.  */

static struct dummy_frame **
lookup_dummy_frame (struct dummy_frame_id *dummy_id)
{
  struct dummy_frame **dp;

  for (dp = &dummy_frame_stack; *dp != NULL; dp = &(*dp)->next)
    {
      if (dummy_frame_id_eq (&(*dp)->id, dummy_id))
	return dp;
    }

  return NULL;
}

/* Find the dummy frame by DUMMY_ID and THREAD, and pop it, restoring
   program state to that before the frame was created.
   On return reinit_frame_cache has been called.
   If the frame isn't found, flag an internal error.  */

void
dummy_frame_pop (frame_id dummy_id, thread_info *thread)
{
  struct dummy_frame **dp;
  struct dummy_frame_id id = { dummy_id, thread };

  dp = lookup_dummy_frame (&id);
  gdb_assert (dp != NULL);

  pop_dummy_frame (dp);
}

/* Find the dummy frame by DUMMY_ID and PTID and drop it.  Do nothing
   if it is not found.  Do not restore its state into inferior, just
   free its memory.  */

void
dummy_frame_discard (struct frame_id dummy_id, thread_info *thread)
{
  struct dummy_frame **dp;
  struct dummy_frame_id id = { dummy_id, thread };

  dp = lookup_dummy_frame (&id);
  if (dp)
    remove_dummy_frame (dp);
}

/* See dummy-frame.h.  */

void
register_dummy_frame_dtor (frame_id dummy_id, thread_info *thread,
			   dummy_frame_dtor_ftype *dtor, void *dtor_data)
{
  struct dummy_frame_id id = { dummy_id, thread };
  struct dummy_frame **dp, *d;
  struct dummy_frame_dtor_list *list;

  dp = lookup_dummy_frame (&id);
  gdb_assert (dp != NULL);
  d = *dp;
  list = XNEW (struct dummy_frame_dtor_list);
  list->next = d->dtor_list;
  d->dtor_list = list;
  list->dtor = dtor;
  list->dtor_data = dtor_data;
}

/* See dummy-frame.h.  */

int
find_dummy_frame_dtor (dummy_frame_dtor_ftype *dtor, void *dtor_data)
{
  struct dummy_frame *d;

  for (d = dummy_frame_stack; d != NULL; d = d->next)
    {
      struct dummy_frame_dtor_list *list;

      for (list = d->dtor_list; list != NULL; list = list->next)
	if (list->dtor == dtor && list->dtor_data == dtor_data)
	  return 1;
    }
  return 0;
}

/* There may be stale dummy frames, perhaps left over from when an uncaught
   longjmp took us out of a function that was called by the debugger.  Clean
   them up at least once whenever we start a new inferior.  */

static void
cleanup_dummy_frames (struct target_ops *target, int from_tty)
{
  while (dummy_frame_stack != NULL)
    remove_dummy_frame (&dummy_frame_stack);
}

/* Return the dummy frame cache, it contains both the ID, and a
   pointer to the regcache.  */
struct dummy_frame_cache
{
  struct frame_id this_id;
  readonly_detached_regcache *prev_regcache;
};

static int
dummy_frame_sniffer (const struct frame_unwind *self,
		     struct frame_info *this_frame,
		     void **this_prologue_cache)
{
  /* When unwinding a normal frame, the stack structure is determined
     by analyzing the frame's function's code (be it using brute force
     prologue analysis, or the dwarf2 CFI).  In the case of a dummy
     frame, that simply isn't possible.  The PC is either the program
     entry point, or some random address on the stack.  Trying to use
     that PC to apply standard frame ID unwind techniques is just
     asking for trouble.  */
  
  /* Don't bother unless there is at least one dummy frame.  */
  if (dummy_frame_stack != NULL)
    {
      struct dummy_frame *dummyframe;
      /* Use an architecture specific method to extract this frame's
	 dummy ID, assuming it is a dummy frame.  */
      struct frame_id this_id
	= gdbarch_dummy_id (get_frame_arch (this_frame), this_frame);
      struct dummy_frame_id dummy_id = { this_id, inferior_thread () };

      /* Use that ID to find the corresponding cache entry.  */
      for (dummyframe = dummy_frame_stack;
	   dummyframe != NULL;
	   dummyframe = dummyframe->next)
	{
	  if (dummy_frame_id_eq (&dummyframe->id, &dummy_id))
	    {
	      struct dummy_frame_cache *cache;

	      cache = FRAME_OBSTACK_ZALLOC (struct dummy_frame_cache);
	      cache->prev_regcache = get_infcall_suspend_state_regcache
						   (dummyframe->caller_state);
	      cache->this_id = this_id;
	      (*this_prologue_cache) = cache;
	      return 1;
	    }
	}
    }
  return 0;
}

/* Given a call-dummy dummy-frame, return the registers.  Here the
   register value is taken from the local copy of the register buffer.  */

static struct value *
dummy_frame_prev_register (struct frame_info *this_frame,
			   void **this_prologue_cache,
			   int regnum)
{
  struct dummy_frame_cache *cache
    = (struct dummy_frame_cache *) *this_prologue_cache;
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct value *reg_val;

  /* The dummy-frame sniffer always fills in the cache.  */
  gdb_assert (cache != NULL);

  /* Describe the register's location.  Generic dummy frames always
     have the register value in an ``expression''.  */
  reg_val = value_zero (register_type (gdbarch, regnum), not_lval);

  /* Use the regcache_cooked_read() method so that it, on the fly,
     constructs either a raw or pseudo register from the raw
     register cache.  */
  cache->prev_regcache->cooked_read (regnum,
				     value_contents_writeable (reg_val));
  return reg_val;
}

/* Assuming that THIS_FRAME is a dummy, return its ID.  That ID is
   determined by examining the NEXT frame's unwound registers using
   the method dummy_id().  As a side effect, THIS dummy frame's
   dummy cache is located and saved in THIS_PROLOGUE_CACHE.  */

static void
dummy_frame_this_id (struct frame_info *this_frame,
		     void **this_prologue_cache,
		     struct frame_id *this_id)
{
  /* The dummy-frame sniffer always fills in the cache.  */
  struct dummy_frame_cache *cache
    = (struct dummy_frame_cache *) *this_prologue_cache;

  gdb_assert (cache != NULL);
  (*this_id) = cache->this_id;
}

const struct frame_unwind dummy_frame_unwind =
{
  DUMMY_FRAME,
  default_frame_unwind_stop_reason,
  dummy_frame_this_id,
  dummy_frame_prev_register,
  NULL,
  dummy_frame_sniffer,
};

/* See dummy-frame.h.  */

struct frame_id
default_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
{
  CORE_ADDR sp, pc;

  sp = get_frame_sp (this_frame);
  pc = get_frame_pc (this_frame);
  return frame_id_build (sp, pc);
}

static void
fprint_dummy_frames (struct ui_file *file)
{
  struct dummy_frame *s;

  for (s = dummy_frame_stack; s != NULL; s = s->next)
    {
      gdb_print_host_address (s, file);
      fprintf_unfiltered (file, ":");
      fprintf_unfiltered (file, " id=");
      fprint_frame_id (file, s->id.id);
      fprintf_unfiltered (file, ", ptid=%s",
			  target_pid_to_str (s->id.thread->ptid).c_str ());
      fprintf_unfiltered (file, "\n");
    }
}

static void
maintenance_print_dummy_frames (const char *args, int from_tty)
{
  if (args == NULL)
    fprint_dummy_frames (gdb_stdout);
  else
    {
      stdio_file file;

      if (!file.open (args, "w"))
	perror_with_name (_("maintenance print dummy-frames"));
      fprint_dummy_frames (&file);
    }
}

void
_initialize_dummy_frame (void)
{
  add_cmd ("dummy-frames", class_maintenance, maintenance_print_dummy_frames,
	   _("Print the contents of the internal dummy-frame stack."),
	   &maintenanceprintlist);

  gdb::observers::inferior_created.attach (cleanup_dummy_frames);
}
