/* Everything about catch/throw catchpoints, for GDB.

   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 "arch-utils.h"
#include <ctype.h>
#include "breakpoint.h"
#include "gdbcmd.h"
#include "inferior.h"
#include "annotate.h"
#include "valprint.h"
#include "cli/cli-utils.h"
#include "completer.h"
#include "gdb_obstack.h"
#include "mi/mi-common.h"
#include "linespec.h"
#include "probe.h"
#include "objfiles.h"
#include "cp-abi.h"
#include "gdb_regex.h"
#include "cp-support.h"
#include "location.h"

/* Each spot where we may place an exception-related catchpoint has
   two names: the SDT probe point and the function name.  This
   structure holds both.  */

struct exception_names
{
  /* The name of the probe point to try, in the form accepted by
     'parse_probes'.  */

  const char *probe;

  /* The name of the corresponding function.  */

  const char *function;
};

/* Names of the probe points and functions on which to break.  This is
   indexed by exception_event_kind.  */
static const struct exception_names exception_functions[] =
{
  { "-probe-stap libstdcxx:throw", "__cxa_throw" },
  { "-probe-stap libstdcxx:rethrow", "__cxa_rethrow" },
  { "-probe-stap libstdcxx:catch", "__cxa_begin_catch" }
};

static struct breakpoint_ops gnu_v3_exception_catchpoint_ops;

/* The type of an exception catchpoint.  */

struct exception_catchpoint : public breakpoint
{
  /* The kind of exception catchpoint.  */

  enum exception_event_kind kind;

  /* If not empty, a string holding the source form of the regular
     expression to match against.  */

  std::string exception_rx;

  /* If non-NULL, a compiled regular expression which is used to
     determine which exceptions to stop on.  */

  std::unique_ptr<compiled_regex> pattern;
};

/* See breakpoint.h.  */

bool
is_exception_catchpoint (breakpoint *bp)
{
  return bp->ops == &gnu_v3_exception_catchpoint_ops;
}



/* A helper function that fetches exception probe arguments.  This
   fills in *ARG0 (if non-NULL) and *ARG1 (which must be non-NULL).
   It will throw an exception on any kind of failure.  */

static void
fetch_probe_arguments (struct value **arg0, struct value **arg1)
{
  struct frame_info *frame = get_selected_frame (_("No frame selected"));
  CORE_ADDR pc = get_frame_pc (frame);
  struct bound_probe pc_probe;
  unsigned n_args;

  pc_probe = find_probe_by_pc (pc);
  if (pc_probe.prob == NULL)
    error (_("did not find exception probe (does libstdcxx have SDT probes?)"));

  if (pc_probe.prob->get_provider () != "libstdcxx"
      || (pc_probe.prob->get_name () != "catch"
	  && pc_probe.prob->get_name () != "throw"
	  && pc_probe.prob->get_name () != "rethrow"))
    error (_("not stopped at a C++ exception catchpoint"));

  n_args = pc_probe.prob->get_argument_count (get_frame_arch (frame));
  if (n_args < 2)
    error (_("C++ exception catchpoint has too few arguments"));

  if (arg0 != NULL)
    *arg0 = pc_probe.prob->evaluate_argument (0, frame);
  *arg1 = pc_probe.prob->evaluate_argument (1, frame);

  if ((arg0 != NULL && *arg0 == NULL) || *arg1 == NULL)
    error (_("error computing probe argument at c++ exception catchpoint"));
}



/* A helper function that returns a value indicating the kind of the
   exception catchpoint B.  */

static enum exception_event_kind
classify_exception_breakpoint (struct breakpoint *b)
{
  struct exception_catchpoint *cp = (struct exception_catchpoint *) b;

  return cp->kind;
}

/* Implement the 'check_status' method.  */

static void
check_status_exception_catchpoint (struct bpstats *bs)
{
  struct exception_catchpoint *self
    = (struct exception_catchpoint *) bs->breakpoint_at;
  std::string type_name;

  bkpt_breakpoint_ops.check_status (bs);
  if (bs->stop == 0)
    return;

  if (self->pattern == NULL)
    return;

  try
    {
      struct value *typeinfo_arg;
      std::string canon;

      fetch_probe_arguments (NULL, &typeinfo_arg);
      type_name = cplus_typename_from_type_info (typeinfo_arg);

      canon = cp_canonicalize_string (type_name.c_str ());
      if (!canon.empty ())
	std::swap (type_name, canon);
    }
  catch (const gdb_exception_error &e)
    {
      exception_print (gdb_stderr, e);
    }

  if (!type_name.empty ())
    {
      if (self->pattern->exec (type_name.c_str (), 0, NULL, 0) != 0)
	bs->stop = 0;
    }
}

/* Implement the 're_set' method.  */

static void
re_set_exception_catchpoint (struct breakpoint *self)
{
  std::vector<symtab_and_line> sals;
  enum exception_event_kind kind = classify_exception_breakpoint (self);
  struct program_space *filter_pspace = current_program_space;

  /* We first try to use the probe interface.  */
  try
    {
      event_location_up location
	= new_probe_location (exception_functions[kind].probe);
      sals = parse_probes (location.get (), filter_pspace, NULL);
    }
  catch (const gdb_exception_error &e)
    {
      /* Using the probe interface failed.  Let's fallback to the normal
	 catchpoint mode.  */
      try
	{
	  struct explicit_location explicit_loc;

	  initialize_explicit_location (&explicit_loc);
	  explicit_loc.function_name
	    = ASTRDUP (exception_functions[kind].function);
	  event_location_up location = new_explicit_location (&explicit_loc);
	  sals = self->ops->decode_location (self, location.get (),
					     filter_pspace);
	}
      catch (const gdb_exception_error &ex)
	{
	  /* NOT_FOUND_ERROR just means the breakpoint will be
	     pending, so let it through.  */
	  if (ex.error != NOT_FOUND_ERROR)
	    throw;
	}
    }

  update_breakpoint_locations (self, filter_pspace, sals, {});
}

static enum print_stop_action
print_it_exception_catchpoint (bpstat bs)
{
  struct ui_out *uiout = current_uiout;
  struct breakpoint *b = bs->breakpoint_at;
  int bp_temp;
  enum exception_event_kind kind = classify_exception_breakpoint (b);

  annotate_catchpoint (b->number);
  maybe_print_thread_hit_breakpoint (uiout);

  bp_temp = b->disposition == disp_del;
  uiout->text (bp_temp ? "Temporary catchpoint "
		       : "Catchpoint ");
  uiout->field_signed ("bkptno", b->number);
  uiout->text ((kind == EX_EVENT_THROW ? " (exception thrown), "
		: (kind == EX_EVENT_CATCH ? " (exception caught), "
		   : " (exception rethrown), ")));
  if (uiout->is_mi_like_p ())
    {
      uiout->field_string ("reason",
			   async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
      uiout->field_string ("disp", bpdisp_text (b->disposition));
    }
  return PRINT_SRC_AND_LOC;
}

static void
print_one_exception_catchpoint (struct breakpoint *b, 
				struct bp_location **last_loc)
{
  struct value_print_options opts;
  struct ui_out *uiout = current_uiout;
  enum exception_event_kind kind = classify_exception_breakpoint (b);

  get_user_print_options (&opts);

  if (opts.addressprint)
    uiout->field_skip ("addr");
  annotate_field (5);

  switch (kind)
    {
    case EX_EVENT_THROW:
      uiout->field_string ("what", "exception throw");
      if (uiout->is_mi_like_p ())
	uiout->field_string ("catch-type", "throw");
      break;

    case EX_EVENT_RETHROW:
      uiout->field_string ("what", "exception rethrow");
      if (uiout->is_mi_like_p ())
	uiout->field_string ("catch-type", "rethrow");
      break;

    case EX_EVENT_CATCH:
      uiout->field_string ("what", "exception catch");
      if (uiout->is_mi_like_p ())
	uiout->field_string ("catch-type", "catch");
      break;
    }
}

/* Implement the 'print_one_detail' method.  */

static void
print_one_detail_exception_catchpoint (const struct breakpoint *b,
				       struct ui_out *uiout)
{
  const struct exception_catchpoint *cp
    = (const struct exception_catchpoint *) b;

  if (!cp->exception_rx.empty ())
    {
      uiout->text (_("\tmatching: "));
      uiout->field_string ("regexp", cp->exception_rx.c_str ());
      uiout->text ("\n");
    }
}

static void
print_mention_exception_catchpoint (struct breakpoint *b)
{
  struct ui_out *uiout = current_uiout;
  int bp_temp;
  enum exception_event_kind kind = classify_exception_breakpoint (b);

  bp_temp = b->disposition == disp_del;
  uiout->message ("%s %d %s",
		  (bp_temp ? _("Temporary catchpoint ") : _("Catchpoint")),
		  b->number,
		  (kind == EX_EVENT_THROW
		   ? _("(throw)") : (kind == EX_EVENT_CATCH
				     ? _("(catch)") : _("(rethrow)"))));
}

/* Implement the "print_recreate" breakpoint_ops method for throw and
   catch catchpoints.  */

static void
print_recreate_exception_catchpoint (struct breakpoint *b, 
				     struct ui_file *fp)
{
  int bp_temp;
  enum exception_event_kind kind = classify_exception_breakpoint (b);

  bp_temp = b->disposition == disp_del;
  fprintf_unfiltered (fp, bp_temp ? "tcatch " : "catch ");
  switch (kind)
    {
    case EX_EVENT_THROW:
      fprintf_unfiltered (fp, "throw");
      break;
    case EX_EVENT_CATCH:
      fprintf_unfiltered (fp, "catch");
      break;
    case EX_EVENT_RETHROW:
      fprintf_unfiltered (fp, "rethrow");
      break;
    }
  print_recreate_thread (b, fp);
}

/* Implement the "allocate_location" breakpoint_ops method for throw
   and catch catchpoints.  */

static bp_location *
allocate_location_exception_catchpoint (breakpoint *self)
{
  return new bp_location (self, bp_loc_software_breakpoint);
}

static void
handle_gnu_v3_exceptions (int tempflag, std::string &&except_rx,
			  const char *cond_string,
			  enum exception_event_kind ex_event, int from_tty)
{
  std::unique_ptr<compiled_regex> pattern;

  if (!except_rx.empty ())
    {
      pattern.reset (new compiled_regex (except_rx.c_str (), REG_NOSUB,
					 _("invalid type-matching regexp")));
    }

  std::unique_ptr<exception_catchpoint> cp (new exception_catchpoint ());

  init_catchpoint (cp.get (), get_current_arch (), tempflag, cond_string,
		   &gnu_v3_exception_catchpoint_ops);
  cp->kind = ex_event;
  cp->exception_rx = std::move (except_rx);
  cp->pattern = std::move (pattern);

  re_set_exception_catchpoint (cp.get ());

  install_breakpoint (0, std::move (cp), 1);
}

/* Look for an "if" token in *STRING.  The "if" token must be preceded
   by whitespace.
   
   If there is any non-whitespace text between *STRING and the "if"
   token, then it is returned in a newly-xmalloc'd string.  Otherwise,
   this returns NULL.
   
   STRING is updated to point to the "if" token, if it exists, or to
   the end of the string.  */

static std::string
extract_exception_regexp (const char **string)
{
  const char *start;
  const char *last, *last_space;

  start = skip_spaces (*string);

  last = start;
  last_space = start;
  while (*last != '\0')
    {
      const char *if_token = last;

      /* Check for the "if".  */
      if (check_for_argument (&if_token, "if", 2))
	break;

      /* No "if" token here.  Skip to the next word start.  */
      last_space = skip_to_space (last);
      last = skip_spaces (last_space);
    }

  *string = last;
  if (last_space > start)
    return std::string (start, last_space - start);
  return std::string ();
}

/* See breakpoint.h.  */

void
catch_exception_event (enum exception_event_kind ex_event,
		       const char *arg, bool tempflag, int from_tty)
{
  const char *cond_string = NULL;

  if (!arg)
    arg = "";
  arg = skip_spaces (arg);

  std::string except_rx = extract_exception_regexp (&arg);

  cond_string = ep_parse_optional_if_clause (&arg);

  if ((*arg != '\0') && !isspace (*arg))
    error (_("Junk at end of arguments."));

  if (ex_event != EX_EVENT_THROW
      && ex_event != EX_EVENT_CATCH
      && ex_event != EX_EVENT_RETHROW)
    error (_("Unsupported or unknown exception event; cannot catch it"));

  handle_gnu_v3_exceptions (tempflag, std::move (except_rx), cond_string,
			    ex_event, from_tty);
}

/* Implementation of "catch catch" command.  */

static void
catch_catch_command (const char *arg, int from_tty,
		     struct cmd_list_element *command)
{
  bool tempflag = get_cmd_context (command) == CATCH_TEMPORARY;

  catch_exception_event (EX_EVENT_CATCH, arg, tempflag, from_tty);
}

/* Implementation of "catch throw" command.  */

static void
catch_throw_command (const char *arg, int from_tty,
		     struct cmd_list_element *command)
{
  bool tempflag = get_cmd_context (command) == CATCH_TEMPORARY;

  catch_exception_event (EX_EVENT_THROW, arg, tempflag, from_tty);
}

/* Implementation of "catch rethrow" command.  */

static void
catch_rethrow_command (const char *arg, int from_tty,
		       struct cmd_list_element *command)
{
  bool tempflag = get_cmd_context (command) == CATCH_TEMPORARY;

  catch_exception_event (EX_EVENT_RETHROW, arg, tempflag, from_tty);
}



/* Implement the 'make_value' method for the $_exception
   internalvar.  */

static struct value *
compute_exception (struct gdbarch *argc, struct internalvar *var, void *ignore)
{
  struct value *arg0, *arg1;
  struct type *obj_type;

  fetch_probe_arguments (&arg0, &arg1);

  /* ARG0 is a pointer to the exception object.  ARG1 is a pointer to
     the std::type_info for the exception.  Now we find the type from
     the type_info and cast the result.  */
  obj_type = cplus_type_from_type_info (arg1);
  return value_ind (value_cast (make_pointer_type (obj_type, NULL), arg0));
}

/* Implementation of the '$_exception' variable.  */

static const struct internalvar_funcs exception_funcs =
{
  compute_exception,
  NULL,
  NULL
};



static void
initialize_throw_catchpoint_ops (void)
{
  struct breakpoint_ops *ops;

  initialize_breakpoint_ops ();

  /* GNU v3 exception catchpoints.  */
  ops = &gnu_v3_exception_catchpoint_ops;
  *ops = bkpt_breakpoint_ops;
  ops->re_set = re_set_exception_catchpoint;
  ops->print_it = print_it_exception_catchpoint;
  ops->print_one = print_one_exception_catchpoint;
  ops->print_mention = print_mention_exception_catchpoint;
  ops->print_recreate = print_recreate_exception_catchpoint;
  ops->print_one_detail = print_one_detail_exception_catchpoint;
  ops->check_status = check_status_exception_catchpoint;
  ops->allocate_location = allocate_location_exception_catchpoint;
}

void
_initialize_break_catch_throw (void)
{
  initialize_throw_catchpoint_ops ();

  /* Add catch and tcatch sub-commands.  */
  add_catch_command ("catch", _("\
Catch an exception, when caught."),
		     catch_catch_command,
                     NULL,
		     CATCH_PERMANENT,
		     CATCH_TEMPORARY);
  add_catch_command ("throw", _("\
Catch an exception, when thrown."),
		     catch_throw_command,
                     NULL,
		     CATCH_PERMANENT,
		     CATCH_TEMPORARY);
  add_catch_command ("rethrow", _("\
Catch an exception, when rethrown."),
		     catch_rethrow_command,
                     NULL,
		     CATCH_PERMANENT,
		     CATCH_TEMPORARY);

  create_internalvar_type_lazy ("_exception", &exception_funcs, NULL);
}
