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

   Copyright (C) 1986-2018 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"

/* Enums for exception-handling support.  */
enum exception_event_kind
{
  EX_EVENT_THROW,
  EX_EVENT_RETHROW,
  EX_EVENT_CATCH
};

/* 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;
};



/* 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
      || 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 (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 (e, RETURN_MASK_ERROR)
    {
      exception_print (gdb_stderr, e);
    }
  END_CATCH

  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 (e, RETURN_MASK_ERROR)
    {
      /* 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 (ex, RETURN_MASK_ERROR)
	{
	  /* NOT_FOUND_ERROR just means the breakpoint will be
	     pending, so let it through.  */
	  if (ex.error != NOT_FOUND_ERROR)
	    throw_exception (ex);
	}
      END_CATCH
    }
  END_CATCH

  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 ");
  if (!uiout->is_mi_like_p ())
    uiout->field_int ("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));
      uiout->field_int ("bkptno", b->number);
    }
  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)
    {
      annotate_field (4);
      if (b->loc == NULL || b->loc->shlib_disabled)
	uiout->field_string ("addr", "<PENDING>");
      else
	uiout->field_core_addr ("addr",
				b->loc->gdbarch, b->loc->address);
    }
  annotate_field (5);
  if (b->loc)
    *last_loc = b->loc;

  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->text (bp_temp ? _("Temporary catchpoint ")
			      : _("Catchpoint "));
  uiout->field_int ("bkptno", b->number);
  uiout->text ((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);
}

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);
  /* We need to reset 'type' in order for code in breakpoint.c to do
     the right thing.  */
  cp->type = bp_breakpoint;
  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 ();
}

/* Deal with "catch catch", "catch throw", and "catch rethrow"
   commands.  */

static void
catch_exception_command_1 (enum exception_event_kind ex_event,
			   const char *arg,
			   int 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)
{
  int tempflag = get_cmd_context (command) == CATCH_TEMPORARY;

  catch_exception_command_1 (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)
{
  int tempflag = get_cmd_context (command) == CATCH_TEMPORARY;

  catch_exception_command_1 (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)
{
  int tempflag = get_cmd_context (command) == CATCH_TEMPORARY;

  catch_exception_command_1 (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;
}

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);
}
