/* Everything about signal catchpoints, for GDB.

   Copyright (C) 2011-2017 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 "infrun.h"
#include "annotate.h"
#include "valprint.h"
#include "cli/cli-utils.h"
#include "completer.h"

#include <string>

#define INTERNAL_SIGNAL(x) ((x) == GDB_SIGNAL_TRAP || (x) == GDB_SIGNAL_INT)

/* An instance of this type is used to represent a signal catchpoint.
   A breakpoint is really of this type iff its ops pointer points to
   SIGNAL_CATCHPOINT_OPS.  */

struct signal_catchpoint : public breakpoint
{
  /* Signal numbers used for the 'catch signal' feature.  If no signal
     has been specified for filtering, it is empty.  Otherwise,
     it holds a list of all signals to be caught.  */

  std::vector<gdb_signal> signals_to_be_caught;

  /* If SIGNALS_TO_BE_CAUGHT is empty, then all "ordinary" signals are
     caught.  If CATCH_ALL is true, then internal signals are caught
     as well.  If SIGNALS_TO_BE_CAUGHT is not empty, then this field
     is ignored.  */

  bool catch_all;
};

/* The breakpoint_ops structure to be used in signal catchpoints.  */

static struct breakpoint_ops signal_catchpoint_ops;

/* Count of each signal.  */

static unsigned int *signal_catch_counts;



/* A convenience wrapper for gdb_signal_to_name that returns the
   integer value if the name is not known.  */

static const char *
signal_to_name_or_int (enum gdb_signal sig)
{
  const char *result = gdb_signal_to_name (sig);

  if (strcmp (result, "?") == 0)
    result = plongest (sig);

  return result;
}



/* Implement the "insert_location" breakpoint_ops method for signal
   catchpoints.  */

static int
signal_catchpoint_insert_location (struct bp_location *bl)
{
  struct signal_catchpoint *c = (struct signal_catchpoint *) bl->owner;

  if (!c->signals_to_be_caught.empty ())
    {
      for (gdb_signal iter : c->signals_to_be_caught)
	++signal_catch_counts[iter];
    }
  else
    {
      for (int i = 0; i < GDB_SIGNAL_LAST; ++i)
	{
	  if (c->catch_all || !INTERNAL_SIGNAL (i))
	    ++signal_catch_counts[i];
	}
    }

  signal_catch_update (signal_catch_counts);

  return 0;
}

/* Implement the "remove_location" breakpoint_ops method for signal
   catchpoints.  */

static int
signal_catchpoint_remove_location (struct bp_location *bl,
				   enum remove_bp_reason reason)
{
  struct signal_catchpoint *c = (struct signal_catchpoint *) bl->owner;

  if (!c->signals_to_be_caught.empty ())
    {
      for (gdb_signal iter : c->signals_to_be_caught)
	{
	  gdb_assert (signal_catch_counts[iter] > 0);
	  --signal_catch_counts[iter];
	}
    }
  else
    {
      for (int i = 0; i < GDB_SIGNAL_LAST; ++i)
	{
	  if (c->catch_all || !INTERNAL_SIGNAL (i))
	    {
	      gdb_assert (signal_catch_counts[i] > 0);
	      --signal_catch_counts[i];
	    }
	}
    }

  signal_catch_update (signal_catch_counts);

  return 0;
}

/* Implement the "breakpoint_hit" breakpoint_ops method for signal
   catchpoints.  */

static int
signal_catchpoint_breakpoint_hit (const struct bp_location *bl,
				  struct address_space *aspace,
				  CORE_ADDR bp_addr,
				  const struct target_waitstatus *ws)
{
  const struct signal_catchpoint *c
    = (const struct signal_catchpoint *) bl->owner;
  gdb_signal signal_number;

  if (ws->kind != TARGET_WAITKIND_STOPPED)
    return 0;

  signal_number = ws->value.sig;

  /* If we are catching specific signals in this breakpoint, then we
     must guarantee that the called signal is the same signal we are
     catching.  */
  if (!c->signals_to_be_caught.empty ())
    {
      for (gdb_signal iter : c->signals_to_be_caught)
	if (signal_number == iter)
	  return 1;
      /* Not the same.  */
      return 0;
    }
  else
    return c->catch_all || !INTERNAL_SIGNAL (signal_number);
}

/* Implement the "print_it" breakpoint_ops method for signal
   catchpoints.  */

static enum print_stop_action
signal_catchpoint_print_it (bpstat bs)
{
  struct breakpoint *b = bs->breakpoint_at;
  ptid_t ptid;
  struct target_waitstatus last;
  const char *signal_name;
  struct ui_out *uiout = current_uiout;

  get_last_target_status (&ptid, &last);

  signal_name = signal_to_name_or_int (last.value.sig);

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

  printf_filtered (_("Catchpoint %d (signal %s), "), b->number, signal_name);

  return PRINT_SRC_AND_LOC;
}

/* Implement the "print_one" breakpoint_ops method for signal
   catchpoints.  */

static void
signal_catchpoint_print_one (struct breakpoint *b,
			     struct bp_location **last_loc)
{
  struct signal_catchpoint *c = (struct signal_catchpoint *) b;
  struct value_print_options opts;
  struct ui_out *uiout = current_uiout;

  get_user_print_options (&opts);

  /* Field 4, the address, is omitted (which makes the columns
     not line up too nicely with the headers, but the effect
     is relatively readable).  */
  if (opts.addressprint)
    uiout->field_skip ("addr");
  annotate_field (5);

  if (c->signals_to_be_caught.size () > 1)
    uiout->text ("signals \"");
  else
    uiout->text ("signal \"");

  if (!c->signals_to_be_caught.empty ())
    {
      std::string text;

      bool first = true;
      for (gdb_signal iter : c->signals_to_be_caught)
        {
	  const char *name = signal_to_name_or_int (iter);

	  if (!first)
	    text += " ";
	  first = false;

	  text += name;
        }
      uiout->field_string ("what", text.c_str ());
    }
  else
    uiout->field_string ("what",
			 c->catch_all ? "<any signal>" : "<standard signals>");
  uiout->text ("\" ");

  if (uiout->is_mi_like_p ())
    uiout->field_string ("catch-type", "signal");
}

/* Implement the "print_mention" breakpoint_ops method for signal
   catchpoints.  */

static void
signal_catchpoint_print_mention (struct breakpoint *b)
{
  struct signal_catchpoint *c = (struct signal_catchpoint *) b;

  if (!c->signals_to_be_caught.empty ())
    {
      if (c->signals_to_be_caught.size () > 1)
        printf_filtered (_("Catchpoint %d (signals"), b->number);
      else
        printf_filtered (_("Catchpoint %d (signal"), b->number);

      for (gdb_signal iter : c->signals_to_be_caught)
        {
	  const char *name = signal_to_name_or_int (iter);

	  printf_filtered (" %s", name);
        }
      printf_filtered (")");
    }
  else if (c->catch_all)
    printf_filtered (_("Catchpoint %d (any signal)"), b->number);
  else
    printf_filtered (_("Catchpoint %d (standard signals)"), b->number);
}

/* Implement the "print_recreate" breakpoint_ops method for signal
   catchpoints.  */

static void
signal_catchpoint_print_recreate (struct breakpoint *b, struct ui_file *fp)
{
  struct signal_catchpoint *c = (struct signal_catchpoint *) b;

  fprintf_unfiltered (fp, "catch signal");

  if (!c->signals_to_be_caught.empty ())
    {
      for (gdb_signal iter : c->signals_to_be_caught)
	fprintf_unfiltered (fp, " %s", signal_to_name_or_int (iter));
    }
  else if (c->catch_all)
    fprintf_unfiltered (fp, " all");
  fputc_unfiltered ('\n', fp);
}

/* Implement the "explains_signal" breakpoint_ops method for signal
   catchpoints.  */

static int
signal_catchpoint_explains_signal (struct breakpoint *b, enum gdb_signal sig)
{
  return 1;
}

/* Create a new signal catchpoint.  TEMPFLAG is true if this should be
   a temporary catchpoint.  FILTER is the list of signals to catch; it
   can be empty, meaning all signals.  CATCH_ALL is a flag indicating
   whether signals used internally by gdb should be caught; it is only
   valid if FILTER is NULL.  If FILTER is empty and CATCH_ALL is zero,
   then internal signals like SIGTRAP are not caught.  */

static void
create_signal_catchpoint (int tempflag, std::vector<gdb_signal> &&filter,
			  bool catch_all)
{
  struct gdbarch *gdbarch = get_current_arch ();

  std::unique_ptr<signal_catchpoint> c (new signal_catchpoint ());
  init_catchpoint (c.get (), gdbarch, tempflag, NULL, &signal_catchpoint_ops);
  c->signals_to_be_caught = std::move (filter);
  c->catch_all = catch_all;

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


/* Splits the argument using space as delimiter.  Returns a filter
   list, which is empty if no filtering is required.  */

static std::vector<gdb_signal>
catch_signal_split_args (char *arg, bool *catch_all)
{
  std::vector<gdb_signal> result;
  bool first = true;

  while (*arg != '\0')
    {
      int num;
      gdb_signal signal_number;
      char *endptr;

      std::string one_arg = extract_arg (&arg);
      if (one_arg.empty ())
	break;

      /* Check for the special flag "all".  */
      if (one_arg == "all")
	{
	  arg = skip_spaces (arg);
	  if (*arg != '\0' || !first)
	    error (_("'all' cannot be caught with other signals"));
	  *catch_all = true;
	  gdb_assert (result.empty ());
	  return result;
	}

      first = false;

      /* Check if the user provided a signal name or a number.  */
      num = (int) strtol (one_arg.c_str (), &endptr, 0);
      if (*endptr == '\0')
	signal_number = gdb_signal_from_command (num);
      else
	{
	  signal_number = gdb_signal_from_name (one_arg.c_str ());
	  if (signal_number == GDB_SIGNAL_UNKNOWN)
	    error (_("Unknown signal name '%s'."), one_arg.c_str ());
	}

      result.push_back (signal_number);
    }

  result.shrink_to_fit ();
  return result;
}

/* Implement the "catch signal" command.  */

static void
catch_signal_command (char *arg, int from_tty,
		      struct cmd_list_element *command)
{
  int tempflag;
  bool catch_all = false;
  std::vector<gdb_signal> filter;

  tempflag = get_cmd_context (command) == CATCH_TEMPORARY;

  arg = skip_spaces (arg);

  /* The allowed syntax is:
     catch signal
     catch signal <name | number> [<name | number> ... <name | number>]

     Let's check if there's a signal name.  */

  if (arg != NULL)
    filter = catch_signal_split_args (arg, &catch_all);

  create_signal_catchpoint (tempflag, std::move (filter), catch_all);
}

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

  initialize_breakpoint_ops ();

  ops = &signal_catchpoint_ops;
  *ops = base_breakpoint_ops;
  ops->insert_location = signal_catchpoint_insert_location;
  ops->remove_location = signal_catchpoint_remove_location;
  ops->breakpoint_hit = signal_catchpoint_breakpoint_hit;
  ops->print_it = signal_catchpoint_print_it;
  ops->print_one = signal_catchpoint_print_one;
  ops->print_mention = signal_catchpoint_print_mention;
  ops->print_recreate = signal_catchpoint_print_recreate;
  ops->explains_signal = signal_catchpoint_explains_signal;
}

void
_initialize_break_catch_sig (void)
{
  initialize_signal_catchpoint_ops ();

  signal_catch_counts = XCNEWVEC (unsigned int, GDB_SIGNAL_LAST);

  add_catch_command ("signal", _("\
Catch signals by their names and/or numbers.\n\
Usage: catch signal [[NAME|NUMBER] [NAME|NUMBER]...|all]\n\
Arguments say which signals to catch.  If no arguments\n\
are given, every \"normal\" signal will be caught.\n\
The argument \"all\" means to also catch signals used by GDB.\n\
Arguments, if given, should be one or more signal names\n\
(if your system supports that), or signal numbers."),
		     catch_signal_command,
		     signal_completer,
		     CATCH_PERMANENT,
		     CATCH_TEMPORARY);
}
