/* Generic simulator watchpoint support.
   Copyright (C) 1997-2026 Free Software Foundation, Inc.
   Contributed by Cygnus Support.

This file is part of GDB, the GNU debugger.

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/>.  */

/* This must come before any other includes.  */
#include "defs.h"

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "libiberty.h"

#include "sim-main.h"
#include "sim-options.h"
#include "sim-signal.h"
#include "sim-assert.h"

enum {
  OPTION_WATCH_DELETE                      = OPTION_START,

  OPTION_WATCH_INFO,
  OPTION_WATCH_CLOCK,
  OPTION_WATCH_CYCLES,
  OPTION_WATCH_PC,

  OPTION_WATCH_OP,
};


/* Break an option number into its op/int-nr */
static watchpoint_type
option_to_type (SIM_DESC sd,
		int option)
{
  sim_watchpoints *watch = STATE_WATCHPOINTS (sd);
  watchpoint_type type = ((option - OPTION_WATCH_OP)
			  / (watch->nr_interrupts + 1));
  SIM_ASSERT (type >= 0 && type < nr_watchpoint_types);
  return type;
}

static int
option_to_interrupt_nr (SIM_DESC sd,
			int option)
{
  sim_watchpoints *watch = STATE_WATCHPOINTS (sd);
  int interrupt_nr = ((option - OPTION_WATCH_OP)
		      % (watch->nr_interrupts + 1));
  return interrupt_nr;
}

static int
type_to_option (SIM_DESC sd,
		watchpoint_type type,
		int interrupt_nr)
{
  sim_watchpoints *watch = STATE_WATCHPOINTS (sd);
  return ((type * (watch->nr_interrupts + 1))
	  + interrupt_nr
	  + OPTION_WATCH_OP);
}


/* Delete one or more watchpoints.  Fail if no watchpoints were found */

static SIM_RC
do_watchpoint_delete (SIM_DESC sd,
		      int ident,
		      watchpoint_type type)
{
  sim_watchpoints *watch = STATE_WATCHPOINTS (sd);
  sim_watch_point **entry = &watch->points;
  SIM_RC status = SIM_RC_FAIL;
  while ((*entry) != NULL)
    {
      if ((*entry)->ident == ident
	  || (*entry)->type == type)
	{
	  sim_watch_point *dead = (*entry);
	  (*entry) = (*entry)->next;
	  sim_events_deschedule (sd, dead->event);
	  free (dead);
	  status = SIM_RC_OK;
	}
      else
	entry = &(*entry)->next;
    }
  return status;
}

static const char *
watchpoint_type_to_str (SIM_DESC sd,
			watchpoint_type type)
{
  switch (type)
    {
    case  pc_watchpoint:
      return "pc";
    case clock_watchpoint:
      return "clock";
    case cycles_watchpoint:
      return "cycles";
    case invalid_watchpoint:
    case nr_watchpoint_types:
      return "(invalid-type)";
    }
  return NULL;
}

static const char *
interrupt_nr_to_str (SIM_DESC sd,
		     int interrupt_nr)
{
  sim_watchpoints *watch = STATE_WATCHPOINTS (sd);
  if (interrupt_nr < 0)
    return "(invalid-interrupt)";
  else if (interrupt_nr >= watch->nr_interrupts)
    return "breakpoint";
  else
    return watch->interrupt_names[interrupt_nr];
}


static void
do_watchpoint_info (SIM_DESC sd)
{
  sim_watchpoints *watch = STATE_WATCHPOINTS (sd);
  sim_watch_point *point;
  sim_io_printf (sd, "Watchpoints:\n");
  for (point = watch->points; point != NULL; point = point->next)
    {
      sim_io_printf (sd, "%3d: watch %s %s ",
		     point->ident,
		     watchpoint_type_to_str (sd, point->type),
		     interrupt_nr_to_str (sd, point->interrupt_nr));
      if (point->is_periodic)
	sim_io_printf (sd, "+");
      if (!point->is_within)
	sim_io_printf (sd, "!");
      sim_io_printf (sd, "0x%lx", point->arg0);
      if (point->arg1 != point->arg0)
	sim_io_printf (sd, ",0x%lx", point->arg1);
      sim_io_printf (sd, "\n");
    }
}



static sim_event_handler handle_watchpoint;

static SIM_RC
schedule_watchpoint (SIM_DESC sd,
		     sim_watch_point *point)
{
  switch (point->type)
    {
    case pc_watchpoint:
      point->event = sim_events_watch_pc (sd,
					  point->is_within,
					  point->arg0, point->arg1,
					  /* PC in arg0..arg1 */
					  handle_watchpoint,
					  point);
      return SIM_RC_OK;
    case clock_watchpoint:
      point->event = sim_events_watch_clock (sd,
					     point->arg0, /* ms time */
					     handle_watchpoint,
					     point);
      return SIM_RC_OK;
    case cycles_watchpoint:
      point->event = sim_events_schedule (sd,
					  point->arg0, /* time */
					  handle_watchpoint,
					  point);
      return SIM_RC_OK;
    default:
      sim_engine_abort (sd, NULL, NULL_CIA,
			"handle_watchpoint - internal error - bad switch");
      return SIM_RC_FAIL;
    }
  return SIM_RC_OK;
}


static void
handle_watchpoint (SIM_DESC sd, void *data)
{
  sim_watchpoints *watch = STATE_WATCHPOINTS (sd);
  sim_watch_point *point = (sim_watch_point *) data;
  int interrupt_nr = point->interrupt_nr;

  if (point->is_periodic)
    /* reschedule this event before processing it */
    schedule_watchpoint (sd, point);
  else
    do_watchpoint_delete (sd, point->ident, invalid_watchpoint);

  if (point->interrupt_nr == watch->nr_interrupts)
    sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIM_SIGINT);
  else
    watch->interrupt_handler (sd, &watch->interrupt_names[interrupt_nr]);
}


static SIM_RC
do_watchpoint_create (SIM_DESC sd,
		      watchpoint_type type,
		      int opt,
		      char *arg)
{
  sim_watchpoints *watch = STATE_WATCHPOINTS (sd);
  sim_watch_point **point;

  /* create the watchpoint */
  point = &watch->points;
  while ((*point) != NULL)
    point = &(*point)->next;
  (*point) = ZALLOC (sim_watch_point);

  /* fill in the details */
  (*point)->ident = ++(watch->last_point_nr);
  (*point)->type = option_to_type (sd, opt);
  (*point)->interrupt_nr = option_to_interrupt_nr (sd, opt);
  /* prefixes to arg - +== periodic, !==not or outside */
  (*point)->is_within = 1;
  while (1)
    {
      if (arg[0] == '+')
	(*point)->is_periodic = 1;
      else if (arg[0] == '!')
	(*point)->is_within = 0;
      else
	break;
      arg++;
    }

  (*point)->arg0 = strtoul (arg, &arg, 0);
  if (arg[0] == ',')
    (*point)->arg1 = strtoul (arg + 1, NULL, 0);
  else
    (*point)->arg1 = (*point)->arg0;

  /* schedule it */
  schedule_watchpoint (sd, (*point));

  return SIM_RC_OK;
}


static SIM_RC
watchpoint_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
			   char *arg, int is_command)
{
  if (opt >= OPTION_WATCH_OP)
    return do_watchpoint_create (sd, clock_watchpoint, opt, arg);
  else
    switch (opt)
      {

      case OPTION_WATCH_DELETE:
	if (isdigit ((int) arg[0]))
	  {
	    int ident = strtol (arg, NULL, 0);
	    if (do_watchpoint_delete (sd, ident, invalid_watchpoint)
		!= SIM_RC_OK)
	      {
		sim_io_eprintf (sd, "Watchpoint %d not found\n", ident);
		return SIM_RC_FAIL;
	      }
	    return SIM_RC_OK;
	  }
	else if (strcasecmp (arg, "all") == 0)
	  {
	    watchpoint_type type;
	    for (type = invalid_watchpoint + 1;
		 type < nr_watchpoint_types;
		 type++)
	      {
		do_watchpoint_delete (sd, 0, type);
	      }
	    return SIM_RC_OK;
	  }
	else if (strcasecmp (arg, "pc") == 0)
	  {
	    if (do_watchpoint_delete (sd, 0, pc_watchpoint)
		!= SIM_RC_OK)
	      {
		sim_io_eprintf (sd, "No PC watchpoints found\n");
		return SIM_RC_FAIL;
	      }
	    return SIM_RC_OK;
	  }
	else if (strcasecmp (arg, "clock") == 0)
	  {
	    if (do_watchpoint_delete (sd, 0, clock_watchpoint) != SIM_RC_OK)
	      {
		sim_io_eprintf (sd, "No CLOCK watchpoints found\n");
		return SIM_RC_FAIL;
	      }
	    return SIM_RC_OK;
	  }
	else if (strcasecmp (arg, "cycles") == 0)
	  {
	    if (do_watchpoint_delete (sd, 0, cycles_watchpoint) != SIM_RC_OK)
	      {
		sim_io_eprintf (sd, "No CYCLES watchpoints found\n");
		return SIM_RC_FAIL;
	      }
	    return SIM_RC_OK;
	  }
	sim_io_eprintf (sd, "Unknown watchpoint type `%s'\n", arg);
	return SIM_RC_FAIL;

      case OPTION_WATCH_INFO:
	{
	  do_watchpoint_info (sd);
	  return SIM_RC_OK;
	}

      default:
	sim_io_eprintf (sd, "Unknown watch option %d\n", opt);
	return SIM_RC_FAIL;

      }

}


static SIM_RC
sim_watchpoint_init (SIM_DESC sd)
{
  sim_watchpoints *watch = STATE_WATCHPOINTS (sd);
  sim_watch_point *point;
  /* NOTE: Do not need to de-schedule any previous watchpoints as
     sim-events has already done this */
  /* schedule any watchpoints enabled by command line options */
  for (point = watch->points; point != NULL; point = point->next)
    {
      schedule_watchpoint (sd, point);
    }
  return SIM_RC_OK;
}


static const OPTION watchpoint_options[] =
{
  { {"watch-delete", required_argument, NULL, OPTION_WATCH_DELETE },
      '\0', "IDENT|all|pc|cycles|clock", "Delete a watchpoint",
      watchpoint_option_handler, NULL },

  { {"watch-info", no_argument, NULL, OPTION_WATCH_INFO },
      '\0', NULL, "List scheduled watchpoints",
      watchpoint_option_handler, NULL },

  { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
};

static const char *default_interrupt_names[] = { "int", 0, };

/* This default handler is "good enough" for targets that just want to trap into
   gdb when watchpoints are hit, and have only configured the STATE_WATCHPOINTS
   pc field.  */
static void
default_interrupt_handler (SIM_DESC sd, void *data)
{
  sim_cpu *cpu = STATE_CPU (sd, 0);
  address_word cia = CPU_PC_GET (cpu);
  sim_engine_halt (sd, cpu, NULL, cia, sim_stopped, SIM_SIGTRAP);
}

SIM_RC
sim_watchpoint_install (SIM_DESC sd)
{
  sim_watchpoints *watch = STATE_WATCHPOINTS (sd);
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  /* the basic command set */
  sim_module_add_init_fn (sd, sim_watchpoint_init);
  sim_add_option_table (sd, NULL, watchpoint_options);
  /* fill in some details */
  if (watch->interrupt_names == NULL)
    watch->interrupt_names = default_interrupt_names;
  if (watch->interrupt_handler == NULL)
    watch->interrupt_handler = default_interrupt_handler;
  watch->nr_interrupts = 0;
  while (watch->interrupt_names[watch->nr_interrupts] != NULL)
    watch->nr_interrupts++;
  /* generate more advansed commands */
  {
    OPTION *int_options = NZALLOC (OPTION, 1 + (watch->nr_interrupts + 1) * nr_watchpoint_types);
    int interrupt_nr;
    for (interrupt_nr = 0; interrupt_nr <= watch->nr_interrupts; interrupt_nr++)
      {
	watchpoint_type type;
	for (type = 0; type < nr_watchpoint_types; type++)
	  {
	    char *name;
	    int nr = interrupt_nr * nr_watchpoint_types + type;
	    OPTION *option = &int_options[nr];
	    if (asprintf (&name, "watch-%s-%s",
			  watchpoint_type_to_str (sd, type),
			  interrupt_nr_to_str (sd, interrupt_nr)) < 0)
	      return SIM_RC_FAIL;
	    option->opt.name = name;
	    option->opt.has_arg = required_argument;
	    option->opt.val = type_to_option (sd, type, interrupt_nr);
	    option->doc = "";
	    option->doc_name = "";
	    option->handler = watchpoint_option_handler;
	  }
      }
    /* adjust first few entries so that they contain real
       documentation, the first entry includes a list of actions. */
    {
      const char *prefix =
	"Watch the simulator, take ACTION in COUNT cycles (`+' for every COUNT cycles), ACTION is";
      char *doc;
      int len = strlen (prefix) + 1;
      for (interrupt_nr = 0; interrupt_nr <= watch->nr_interrupts; interrupt_nr++)
	len += strlen (interrupt_nr_to_str (sd, interrupt_nr)) + 1;
      doc = NZALLOC (char, len);
      strcpy (doc, prefix);
      for (interrupt_nr = 0; interrupt_nr <= watch->nr_interrupts; interrupt_nr++)
	{
	  strcat (doc, " ");
	  strcat (doc, interrupt_nr_to_str (sd, interrupt_nr));
	}
      int_options[0].doc_name = "watch-cycles-ACTION";
      int_options[0].arg = "[+]COUNT";
      int_options[0].doc = doc;
    }
    int_options[1].doc_name = "watch-pc-ACTION";
    int_options[1].arg = "[!]ADDRESS";
    int_options[1].doc =
      "Watch the PC, take ACTION when matches ADDRESS (in range ADDRESS,ADDRESS), `!' negates test";
    int_options[2].doc_name = "watch-clock-ACTION";
    int_options[2].arg = "[+]MILLISECONDS";
    int_options[2].doc =
      "Watch the clock, take ACTION after MILLISECONDS (`+' for every MILLISECONDS)";

    sim_add_option_table (sd, NULL, int_options);
  }
  return SIM_RC_OK;
}
