/* Everything about signal catchpoints, for GDB.

   Copyright (C) 2011-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 "infrun.h"
#include "annotate.h"
#include "valprint.h"
#include "cli/cli-utils.h"
#include "completer.h"
#include "cli/cli-style.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,
				  const 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>",
			 metadata_style.style ());
  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 (const 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 (const 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);
}
