/* Everything about signal catchpoints, for GDB.

   Copyright (C) 2011-2021 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 "cli/cli-decode.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[GDB_SIGNAL_LAST];



/* 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;
  struct target_waitstatus last;
  const char *signal_name;
  struct ui_out *uiout = current_uiout;

  get_last_target_status (nullptr, nullptr, &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);
    }
  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 = command->context () == 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_break_catch_sig ()
{
  initialize_signal_catchpoint_ops ();

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