/* Python interface to finish breakpoints

   Copyright (C) 2011-2015 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 "python-internal.h"
#include "breakpoint.h"
#include "frame.h"
#include "gdbthread.h"
#include "arch-utils.h"
#include "language.h"
#include "observer.h"
#include "inferior.h"
#include "block.h"

/* Function that is called when a Python finish bp is found out of scope.  */
static char * const outofscope_func = "out_of_scope";

/* struct implementing the gdb.FinishBreakpoint object by extending
   the gdb.Breakpoint class.  */
struct finish_breakpoint_object
{
  /* gdb.Breakpoint base class.  */
  gdbpy_breakpoint_object py_bp;
  /* gdb.Type object of the value return by the breakpointed function.
     May be NULL if no debug information was available or return type
     was VOID.  */
  PyObject *return_type;
  /* gdb.Value object of the function finished by this breakpoint.  Will be
     NULL if return_type is NULL.  */
  PyObject *function_value;
  /* When stopped at this FinishBreakpoint, gdb.Value object returned by
     the function; Py_None if the value is not computable; NULL if GDB is
     not stopped at a FinishBreakpoint.  */
  PyObject *return_value;
};

static PyTypeObject finish_breakpoint_object_type
    CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("finish_breakpoint_object");

/* Python function to get the 'return_value' attribute of
   FinishBreakpoint.  */

static PyObject *
bpfinishpy_get_returnvalue (PyObject *self, void *closure)
{
  struct finish_breakpoint_object *self_finishbp =
      (struct finish_breakpoint_object *) self;

  if (!self_finishbp->return_value)
    Py_RETURN_NONE;

  Py_INCREF (self_finishbp->return_value);
  return self_finishbp->return_value;
}

/* Deallocate FinishBreakpoint object.  */

static void
bpfinishpy_dealloc (PyObject *self)
{
  struct finish_breakpoint_object *self_bpfinish =
        (struct finish_breakpoint_object *) self;

  Py_XDECREF (self_bpfinish->function_value);
  Py_XDECREF (self_bpfinish->return_type);
  Py_XDECREF (self_bpfinish->return_value);
}

/* Triggered when gdbpy_should_stop is about to execute the `stop' callback
   of the gdb.FinishBreakpoint object BP_OBJ.  Will compute and cache the
   `return_value', if possible.  */

void
bpfinishpy_pre_stop_hook (struct gdbpy_breakpoint_object *bp_obj)
{
  struct finish_breakpoint_object *self_finishbp =
        (struct finish_breakpoint_object *) bp_obj;
  volatile struct gdb_exception except;

  /* Can compute return_value only once.  */
  gdb_assert (!self_finishbp->return_value);

  if (!self_finishbp->return_type)
    return;

  TRY_CATCH (except, RETURN_MASK_ALL)
    {
      struct value *function =
        value_object_to_value (self_finishbp->function_value);
      struct type *value_type =
        type_object_to_type (self_finishbp->return_type);
      struct value *ret = get_return_value (function, value_type);

      if (ret)
        {
          self_finishbp->return_value = value_to_value_object (ret);
          if (!self_finishbp->return_value)
              gdbpy_print_stack ();
        }
      else
        {
          Py_INCREF (Py_None);
          self_finishbp->return_value = Py_None;
        }
    }
  if (except.reason < 0)
    {
      gdbpy_convert_exception (except);
      gdbpy_print_stack ();
    }
}

/* Triggered when gdbpy_should_stop has triggered the `stop' callback
   of the gdb.FinishBreakpoint object BP_OBJ.  */

void
bpfinishpy_post_stop_hook (struct gdbpy_breakpoint_object *bp_obj)
{
  volatile struct gdb_exception except;

  TRY_CATCH (except, RETURN_MASK_ALL)
    {
      /* Can't delete it here, but it will be removed at the next stop.  */
      disable_breakpoint (bp_obj->bp);
      gdb_assert (bp_obj->bp->disposition == disp_del);
    }
  if (except.reason < 0)
    {
      gdbpy_convert_exception (except);
      gdbpy_print_stack ();
    }
}

/* Python function to create a new breakpoint.  */

static int
bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
{
  static char *keywords[] = { "frame", "internal", NULL };
  struct finish_breakpoint_object *self_bpfinish =
      (struct finish_breakpoint_object *) self;
  int type = bp_breakpoint;
  PyObject *frame_obj = NULL;
  int thread;
  struct frame_info *frame = NULL; /* init for gcc -Wall */
  struct frame_info *prev_frame = NULL;
  struct frame_id frame_id;
  PyObject *internal = NULL;
  int internal_bp = 0;
  CORE_ADDR finish_pc, pc;
  volatile struct gdb_exception except;
  char *addr_str, small_buf[100];
  struct symbol *function;

  if (!PyArg_ParseTupleAndKeywords (args, kwargs, "|OO", keywords,
                                    &frame_obj, &internal))
    return -1;

  TRY_CATCH (except, RETURN_MASK_ALL)
    {
      /* Default frame to newest frame if necessary.  */
      if (frame_obj == NULL)
	frame = get_current_frame ();
      else
	frame = frame_object_to_frame_info (frame_obj);

      if (frame == NULL)
	{
	  PyErr_SetString (PyExc_ValueError,
			   _("Invalid ID for the `frame' object."));
	}
      else
	{
	  prev_frame = get_prev_frame (frame);
	  if (prev_frame == 0)
	    {
	      PyErr_SetString (PyExc_ValueError,
			       _("\"FinishBreakpoint\" not "
				 "meaningful in the outermost "
				 "frame."));
	    }
	  else if (get_frame_type (prev_frame) == DUMMY_FRAME)
	    {
	      PyErr_SetString (PyExc_ValueError,
			       _("\"FinishBreakpoint\" cannot "
				 "be set on a dummy frame."));
	    }
	  else
	    {
	      frame_id = get_frame_id (prev_frame);
	      if (frame_id_eq (frame_id, null_frame_id))
		PyErr_SetString (PyExc_ValueError,
				 _("Invalid ID for the `frame' object."));
	    }
	}
    }
  if (except.reason < 0)
    {
      gdbpy_convert_exception (except);
      return -1;
    }
  else if (PyErr_Occurred ())
    return -1;

  thread = pid_to_thread_id (inferior_ptid);
  if (thread == 0)
    {
      PyErr_SetString (PyExc_ValueError,
                       _("No thread currently selected."));
      return -1;
    }

  if (internal)
    {
      internal_bp = PyObject_IsTrue (internal);
      if (internal_bp == -1)
        {
          PyErr_SetString (PyExc_ValueError,
                           _("The value of `internal' must be a boolean."));
          return -1;
        }
    }

  /* Find the function we will return from.  */
  self_bpfinish->return_type = NULL;
  self_bpfinish->function_value = NULL;

  TRY_CATCH (except, RETURN_MASK_ALL)
    {
      if (get_frame_pc_if_available (frame, &pc))
        {
          function = find_pc_function (pc);
          if (function != NULL)
            {
              struct type *ret_type =
                  TYPE_TARGET_TYPE (SYMBOL_TYPE (function));

              /* Remember only non-void return types.  */
              if (TYPE_CODE (ret_type) != TYPE_CODE_VOID)
                {
                  struct value *func_value;

                  /* Ignore Python errors at this stage.  */
                  self_bpfinish->return_type = type_to_type_object (ret_type);
                  PyErr_Clear ();
                  func_value = read_var_value (function, frame);
                  self_bpfinish->function_value =
                      value_to_value_object (func_value);
                  PyErr_Clear ();
                }
            }
        }
    }
  if (except.reason < 0
      || !self_bpfinish->return_type || !self_bpfinish->function_value)
    {
      /* Won't be able to compute return value.  */
      Py_XDECREF (self_bpfinish->return_type);
      Py_XDECREF (self_bpfinish->function_value);

      self_bpfinish->return_type = NULL;
      self_bpfinish->function_value = NULL;
    }

  bppy_pending_object = &self_bpfinish->py_bp;
  bppy_pending_object->number = -1;
  bppy_pending_object->bp = NULL;

  TRY_CATCH (except, RETURN_MASK_ALL)
    {
      /* Set a breakpoint on the return address.  */
      finish_pc = get_frame_pc (prev_frame);
      xsnprintf (small_buf, sizeof (small_buf), "*%s", hex_string (finish_pc));
      addr_str = small_buf;

      create_breakpoint (python_gdbarch,
                         addr_str, NULL, thread, NULL,
                         0,
                         1 /*temp_flag*/,
                         bp_breakpoint,
                         0,
                         AUTO_BOOLEAN_TRUE,
                         &bkpt_breakpoint_ops,
                         0, 1, internal_bp, 0);
    }
  GDB_PY_SET_HANDLE_EXCEPTION (except);

  self_bpfinish->py_bp.bp->frame_id = frame_id;
  self_bpfinish->py_bp.is_finish_bp = 1;

  /* Bind the breakpoint with the current program space.  */
  self_bpfinish->py_bp.bp->pspace = current_program_space;

  return 0;
}

/* Called when GDB notices that the finish breakpoint BP_OBJ is out of
   the current callstack.  Triggers the method OUT_OF_SCOPE if implemented,
   then delete the breakpoint.  */

static void
bpfinishpy_out_of_scope (struct finish_breakpoint_object *bpfinish_obj)
{
  gdbpy_breakpoint_object *bp_obj = (gdbpy_breakpoint_object *) bpfinish_obj;
  PyObject *py_obj = (PyObject *) bp_obj;

  if (bpfinish_obj->py_bp.bp->enable_state == bp_enabled
      && PyObject_HasAttrString (py_obj, outofscope_func))
    {
      PyObject *meth_result;

      meth_result = PyObject_CallMethod (py_obj, outofscope_func, NULL);
      if (meth_result == NULL)
	gdbpy_print_stack ();
      Py_XDECREF (meth_result);
    }

  delete_breakpoint (bpfinish_obj->py_bp.bp);
}

/* Callback for `bpfinishpy_detect_out_scope'.  Triggers Python's
   `B->out_of_scope' function if B is a FinishBreakpoint out of its scope.  */

static int
bpfinishpy_detect_out_scope_cb (struct breakpoint *b, void *args)
{
  volatile struct gdb_exception except;
  struct breakpoint *bp_stopped = (struct breakpoint *) args;
  PyObject *py_bp = (PyObject *) b->py_bp_object;
  struct gdbarch *garch = b->gdbarch ? b->gdbarch : get_current_arch ();

  /* Trigger out_of_scope if this is a FinishBreakpoint and its frame is
     not anymore in the current callstack.  */
  if (py_bp != NULL && b->py_bp_object->is_finish_bp)
    {
      struct finish_breakpoint_object *finish_bp =
          (struct finish_breakpoint_object *) py_bp;

      /* Check scope if not currently stopped at the FinishBreakpoint.  */
      if (b != bp_stopped)
        {
          TRY_CATCH (except, RETURN_MASK_ALL)
            {
              if (b->pspace == current_inferior ()->pspace
                  && (!target_has_registers
                      || frame_find_by_id (b->frame_id) == NULL))
                bpfinishpy_out_of_scope (finish_bp);
            }
          if (except.reason < 0)
            {
              gdbpy_convert_exception (except);
              gdbpy_print_stack ();
            }
        }
    }

  return 0;
}

/* Attached to `stop' notifications, check if the execution has run
   out of the scope of any FinishBreakpoint before it has been hit.  */

static void
bpfinishpy_handle_stop (struct bpstats *bs, int print_frame)
{
  struct cleanup *cleanup = ensure_python_env (get_current_arch (),
                                               current_language);

  iterate_over_breakpoints (bpfinishpy_detect_out_scope_cb,
                            bs == NULL ? NULL : bs->breakpoint_at);

  do_cleanups (cleanup);
}

/* Attached to `exit' notifications, triggers all the necessary out of
   scope notifications.  */

static void
bpfinishpy_handle_exit (struct inferior *inf)
{
  struct cleanup *cleanup = ensure_python_env (target_gdbarch (),
                                               current_language);

  iterate_over_breakpoints (bpfinishpy_detect_out_scope_cb, NULL);

  do_cleanups (cleanup);
}

/* Initialize the Python finish breakpoint code.  */

int
gdbpy_initialize_finishbreakpoints (void)
{
  if (PyType_Ready (&finish_breakpoint_object_type) < 0)
    return -1;

  if (gdb_pymodule_addobject (gdb_module, "FinishBreakpoint",
			      (PyObject *) &finish_breakpoint_object_type) < 0)
    return -1;

  observer_attach_normal_stop (bpfinishpy_handle_stop);
  observer_attach_inferior_exit (bpfinishpy_handle_exit);

  return 0;
}

static PyGetSetDef finish_breakpoint_object_getset[] = {
  { "return_value", bpfinishpy_get_returnvalue, NULL,
  "gdb.Value object representing the return value, if any. \
None otherwise.", NULL },
    { NULL }  /* Sentinel.  */
};

static PyTypeObject finish_breakpoint_object_type =
{
  PyVarObject_HEAD_INIT (NULL, 0)
  "gdb.FinishBreakpoint",         /*tp_name*/
  sizeof (struct finish_breakpoint_object),  /*tp_basicsize*/
  0,                              /*tp_itemsize*/
  bpfinishpy_dealloc,             /*tp_dealloc*/
  0,                              /*tp_print*/
  0,                              /*tp_getattr*/
  0,                              /*tp_setattr*/
  0,                              /*tp_compare*/
  0,                              /*tp_repr*/
  0,                              /*tp_as_number*/
  0,                              /*tp_as_sequence*/
  0,                              /*tp_as_mapping*/
  0,                              /*tp_hash */
  0,                              /*tp_call*/
  0,                              /*tp_str*/
  0,                              /*tp_getattro*/
  0,                              /*tp_setattro */
  0,                              /*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
  "GDB finish breakpoint object", /* tp_doc */
  0,                              /* tp_traverse */
  0,                              /* tp_clear */
  0,                              /* tp_richcompare */
  0,                              /* tp_weaklistoffset */
  0,                              /* tp_iter */
  0,                              /* tp_iternext */
  0,                              /* tp_methods */
  0,                              /* tp_members */
  finish_breakpoint_object_getset,/* tp_getset */
  &breakpoint_object_type,        /* tp_base */
  0,                              /* tp_dict */
  0,                              /* tp_descr_get */
  0,                              /* tp_descr_set */
  0,                              /* tp_dictoffset */
  bpfinishpy_init,                /* tp_init */
  0,                              /* tp_alloc */
  0                               /* tp_new */
};
