/* Memory breakpoint operations for the remote server for GDB.
   Copyright (C) 2002-2024 Free Software Foundation, Inc.

   Contributed by MontaVista Software.

   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 "regcache.h"
#include "ax.h"

#define MAX_BREAKPOINT_LEN 8

/* Helper macro used in loops that append multiple items to a singly-linked
   list instead of inserting items at the head of the list, as, say, in the
   breakpoint lists.  LISTPP is a pointer to the pointer that is the head of
   the new list.  ITEMP is a pointer to the item to be added to the list.
   TAILP must be defined to be the same type as ITEMP, and initialized to
   NULL.  */

#define APPEND_TO_LIST(listpp, itemp, tailp) \
	  do \
	    { \
	      if ((tailp) == NULL) \
		*(listpp) = (itemp); \
	      else \
		(tailp)->next = (itemp); \
	      (tailp) = (itemp); \
	    } \
	  while (0)

/* GDB will never try to install multiple breakpoints at the same
   address.  However, we can see GDB requesting to insert a breakpoint
   at an address is had already inserted one previously in a few
   situations.

   - The RSP documentation on Z packets says that to avoid potential
   problems with duplicate packets, the operations should be
   implemented in an idempotent way.

   - A breakpoint is set at ADDR, an address in a shared library.
   Then the shared library is unloaded.  And then another, unrelated,
   breakpoint at ADDR is set.  There is not breakpoint removal request
   between the first and the second breakpoint.

   - When GDB wants to update the target-side breakpoint conditions or
   commands, it re-inserts the breakpoint, with updated
   conditions/commands associated.

   Also, we need to keep track of internal breakpoints too, so we do
   need to be able to install multiple breakpoints at the same address
   transparently.

   We keep track of two different, and closely related structures.  A
   raw breakpoint, which manages the low level, close to the metal
   aspect of a breakpoint.  It holds the breakpoint address, and for
   software breakpoints, a buffer holding a copy of the instructions
   that would be in memory had not been a breakpoint there (we call
   that the shadow memory of the breakpoint).  We occasionally need to
   temporarily uninsert a breakpoint without the client knowing about
   it (e.g., to step over an internal breakpoint), so we keep an
   `inserted' state associated with this low level breakpoint
   structure.  There can only be one such object for a given address.
   Then, we have (a bit higher level) breakpoints.  This structure
   holds a callback to be called whenever a breakpoint is hit, a
   high-level type, and a link to a low level raw breakpoint.  There
   can be many high-level breakpoints at the same address, and all of
   them will point to the same raw breakpoint, which is reference
   counted.  */

/* The low level, physical, raw breakpoint.  */
struct raw_breakpoint
{
  struct raw_breakpoint *next;

  /* The low level type of the breakpoint (software breakpoint,
     watchpoint, etc.)  */
  enum raw_bkpt_type raw_type;

  /* A reference count.  Each high level breakpoint referencing this
     raw breakpoint accounts for one reference.  */
  int refcount;

  /* The breakpoint's insertion address.  There can only be one raw
     breakpoint for a given PC.  */
  CORE_ADDR pc;

  /* The breakpoint's kind.  This is target specific.  Most
     architectures only use one specific instruction for breakpoints, while
     others may use more than one.  E.g., on ARM, we need to use different
     breakpoint instructions on Thumb, Thumb-2, and ARM code.  Likewise for
     hardware breakpoints -- some architectures (including ARM) need to
     setup debug registers differently depending on mode.  */
  int kind;

  /* The breakpoint's shadow memory.  */
  unsigned char old_data[MAX_BREAKPOINT_LEN];

  /* Positive if this breakpoint is currently inserted in the
     inferior.  Negative if it was, but we've detected that it's now
     gone.  Zero if not inserted.  */
  int inserted;
};

/* The type of a breakpoint.  */
enum bkpt_type
  {
    /* A GDB breakpoint, requested with a Z0 packet.  */
    gdb_breakpoint_Z0,

    /* A GDB hardware breakpoint, requested with a Z1 packet.  */
    gdb_breakpoint_Z1,

    /* A GDB write watchpoint, requested with a Z2 packet.  */
    gdb_breakpoint_Z2,

    /* A GDB read watchpoint, requested with a Z3 packet.  */
    gdb_breakpoint_Z3,

    /* A GDB access watchpoint, requested with a Z4 packet.  */
    gdb_breakpoint_Z4,

    /* A software single-step breakpoint.  */
    single_step_breakpoint,

    /* Any other breakpoint type that doesn't require specific
       treatment goes here.  E.g., an event breakpoint.  */
    other_breakpoint,
  };

struct point_cond_list
{
  /* Pointer to the agent expression that is the breakpoint's
     conditional.  */
  struct agent_expr *cond;

  /* Pointer to the next condition.  */
  struct point_cond_list *next;
};

struct point_command_list
{
  /* Pointer to the agent expression that is the breakpoint's
     commands.  */
  struct agent_expr *cmd;

  /* Flag that is true if this command should run even while GDB is
     disconnected.  */
  int persistence;

  /* Pointer to the next command.  */
  struct point_command_list *next;
};

/* A high level (in gdbserver's perspective) breakpoint.  */
struct breakpoint
{
  struct breakpoint *next;

  /* The breakpoint's type.  */
  enum bkpt_type type;

  /* Link to this breakpoint's raw breakpoint.  This is always
     non-NULL.  */
  struct raw_breakpoint *raw;
};

/* Breakpoint requested by GDB.  */

struct gdb_breakpoint
{
  struct breakpoint base;

  /* Pointer to the condition list that should be evaluated on
     the target or NULL if the breakpoint is unconditional or
     if GDB doesn't want us to evaluate the conditionals on the
     target's side.  */
  struct point_cond_list *cond_list;

  /* Point to the list of commands to run when this is hit.  */
  struct point_command_list *command_list;
};

/* Breakpoint used by GDBserver.  */

struct other_breakpoint
{
  struct breakpoint base;

  /* Function to call when we hit this breakpoint.  If it returns 1,
     the breakpoint shall be deleted; 0 or if this callback is NULL,
     it will be left inserted.  */
  int (*handler) (CORE_ADDR);
};

/* Breakpoint for single step.  */

struct single_step_breakpoint
{
  struct breakpoint base;

  /* Thread the reinsert breakpoint belongs to.  */
  ptid_t ptid;
};

/* Return the breakpoint size from its kind.  */

static int
bp_size (struct raw_breakpoint *bp)
{
  int size = 0;

  the_target->sw_breakpoint_from_kind (bp->kind, &size);
  return size;
}

/* Return the breakpoint opcode from its kind.  */

static const gdb_byte *
bp_opcode (struct raw_breakpoint *bp)
{
  int size = 0;

  return the_target->sw_breakpoint_from_kind (bp->kind, &size);
}

/* See mem-break.h.  */

enum target_hw_bp_type
raw_bkpt_type_to_target_hw_bp_type (enum raw_bkpt_type raw_type)
{
  switch (raw_type)
    {
    case raw_bkpt_type_hw:
      return hw_execute;
    case raw_bkpt_type_write_wp:
      return hw_write;
    case raw_bkpt_type_read_wp:
      return hw_read;
    case raw_bkpt_type_access_wp:
      return hw_access;
    default:
      internal_error ("bad raw breakpoint type %d", (int) raw_type);
    }
}

/* See mem-break.h.  */

static enum bkpt_type
Z_packet_to_bkpt_type (char z_type)
{
  gdb_assert ('0' <= z_type && z_type <= '4');

  return (enum bkpt_type) (gdb_breakpoint_Z0 + (z_type - '0'));
}

/* See mem-break.h.  */

enum raw_bkpt_type
Z_packet_to_raw_bkpt_type (char z_type)
{
  switch (z_type)
    {
    case Z_PACKET_SW_BP:
      return raw_bkpt_type_sw;
    case Z_PACKET_HW_BP:
      return raw_bkpt_type_hw;
    case Z_PACKET_WRITE_WP:
      return raw_bkpt_type_write_wp;
    case Z_PACKET_READ_WP:
      return raw_bkpt_type_read_wp;
    case Z_PACKET_ACCESS_WP:
      return raw_bkpt_type_access_wp;
    default:
      gdb_assert_not_reached ("unhandled Z packet type.");
    }
}

/* Return true if breakpoint TYPE is a GDB breakpoint.  */

static int
is_gdb_breakpoint (enum bkpt_type type)
{
  return (type == gdb_breakpoint_Z0
	  || type == gdb_breakpoint_Z1
	  || type == gdb_breakpoint_Z2
	  || type == gdb_breakpoint_Z3
	  || type == gdb_breakpoint_Z4);
}

bool
any_persistent_commands (process_info *proc)
{
  struct breakpoint *bp;
  struct point_command_list *cl;

  for (bp = proc->breakpoints; bp != NULL; bp = bp->next)
    {
      if (is_gdb_breakpoint (bp->type))
	{
	  struct gdb_breakpoint *gdb_bp = (struct gdb_breakpoint *) bp;

	  for (cl = gdb_bp->command_list; cl != NULL; cl = cl->next)
	    if (cl->persistence)
	      return true;
	}
    }

  return false;
}

/* Find low-level breakpoint of type TYPE at address ADDR that is not
   insert-disabled.  Returns NULL if not found.  */

static struct raw_breakpoint *
find_enabled_raw_code_breakpoint_at (CORE_ADDR addr, enum raw_bkpt_type type)
{
  struct process_info *proc = current_process ();
  struct raw_breakpoint *bp;

  for (bp = proc->raw_breakpoints; bp != NULL; bp = bp->next)
    if (bp->pc == addr
	&& bp->raw_type == type
	&& bp->inserted >= 0)
      return bp;

  return NULL;
}

/* Find low-level breakpoint of type TYPE at address ADDR.  Returns
   NULL if not found.  */

static struct raw_breakpoint *
find_raw_breakpoint_at (CORE_ADDR addr, enum raw_bkpt_type type, int kind)
{
  struct process_info *proc = current_process ();
  struct raw_breakpoint *bp;

  for (bp = proc->raw_breakpoints; bp != NULL; bp = bp->next)
    if (bp->pc == addr && bp->raw_type == type && bp->kind == kind)
      return bp;

  return NULL;
}

/* See mem-break.h.  */

int
insert_memory_breakpoint (struct raw_breakpoint *bp)
{
  unsigned char buf[MAX_BREAKPOINT_LEN];
  int err;

  /* Note that there can be fast tracepoint jumps installed in the
     same memory range, so to get at the original memory, we need to
     use read_inferior_memory, which masks those out.  */
  err = read_inferior_memory (bp->pc, buf, bp_size (bp));
  if (err != 0)
    {
      threads_debug_printf ("Failed to read shadow memory of"
			    " breakpoint at 0x%s (%s).",
			    paddress (bp->pc), safe_strerror (err));
    }
  else
    {
      memcpy (bp->old_data, buf, bp_size (bp));

      err = the_target->write_memory (bp->pc, bp_opcode (bp),
				      bp_size (bp));
      if (err != 0)
	threads_debug_printf ("Failed to insert breakpoint at 0x%s (%s).",
			      paddress (bp->pc), safe_strerror (err));
    }
  return err != 0 ? -1 : 0;
}

/* See mem-break.h  */

int
remove_memory_breakpoint (struct raw_breakpoint *bp)
{
  unsigned char buf[MAX_BREAKPOINT_LEN];
  int err;

  /* Since there can be trap breakpoints inserted in the same address
     range, we use `target_write_memory', which takes care of
     layering breakpoints on top of fast tracepoints, and on top of
     the buffer we pass it.  This works because the caller has already
     either unlinked the breakpoint or marked it uninserted.  Also
     note that we need to pass the current shadow contents, because
     target_write_memory updates any shadow memory with what we pass
     here, and we want that to be a nop.  */
  memcpy (buf, bp->old_data, bp_size (bp));
  err = target_write_memory (bp->pc, buf, bp_size (bp));
  if (err != 0)
      threads_debug_printf ("Failed to uninsert raw breakpoint "
			    "at 0x%s (%s) while deleting it.",
			    paddress (bp->pc), safe_strerror (err));

  return err != 0 ? -1 : 0;
}

/* Set a RAW breakpoint of type TYPE and kind KIND at WHERE.  On
   success, a pointer to the new breakpoint is returned.  On failure,
   returns NULL and writes the error code to *ERR.  */

static struct raw_breakpoint *
set_raw_breakpoint_at (enum raw_bkpt_type type, CORE_ADDR where, int kind,
		       int *err)
{
  struct process_info *proc = current_process ();
  struct raw_breakpoint *bp;

  if (type == raw_bkpt_type_sw || type == raw_bkpt_type_hw)
    {
      bp = find_enabled_raw_code_breakpoint_at (where, type);
      if (bp != NULL && bp->kind != kind)
	{
	  /* A different kind than previously seen.  The previous
	     breakpoint must be gone then.  */
	  threads_debug_printf
	    ("Inconsistent breakpoint kind?  Was %d, now %d.",
	     bp->kind, kind);
	  bp->inserted = -1;
	  bp = NULL;
	}
    }
  else
    bp = find_raw_breakpoint_at (where, type, kind);

  gdb::unique_xmalloc_ptr<struct raw_breakpoint> bp_holder;
  if (bp == NULL)
    {
      bp_holder.reset (XCNEW (struct raw_breakpoint));
      bp = bp_holder.get ();
      bp->pc = where;
      bp->kind = kind;
      bp->raw_type = type;
    }

  if (!bp->inserted)
    {
      *err = the_target->insert_point (bp->raw_type, bp->pc, bp->kind, bp);
      if (*err != 0)
	{
	  threads_debug_printf ("Failed to insert breakpoint at 0x%s (%d).",
				paddress (where), *err);

	  return NULL;
	}

      bp->inserted = 1;
    }

  /* If the breakpoint was allocated above, we know we want to keep it
     now.  */
  bp_holder.release ();

  /* Link the breakpoint in, if this is the first reference.  */
  if (++bp->refcount == 1)
    {
      bp->next = proc->raw_breakpoints;
      proc->raw_breakpoints = bp;
    }
  return bp;
}

/* Notice that breakpoint traps are always installed on top of fast
   tracepoint jumps.  This is even if the fast tracepoint is installed
   at a later time compared to when the breakpoint was installed.
   This means that a stopping breakpoint or tracepoint has higher
   "priority".  In turn, this allows having fast and slow tracepoints
   (and breakpoints) at the same address behave correctly.  */


/* A fast tracepoint jump.  */

struct fast_tracepoint_jump
{
  struct fast_tracepoint_jump *next;

  /* A reference count.  GDB can install more than one fast tracepoint
     at the same address (each with its own action list, for
     example).  */
  int refcount;

  /* The fast tracepoint's insertion address.  There can only be one
     of these for a given PC.  */
  CORE_ADDR pc;

  /* Non-zero if this fast tracepoint jump is currently inserted in
     the inferior.  */
  int inserted;

  /* The length of the jump instruction.  */
  int length;

  /* A poor-man's flexible array member, holding both the jump
     instruction to insert, and a copy of the instruction that would
     be in memory had not been a jump there (the shadow memory of the
     tracepoint jump).  */
  unsigned char insn_and_shadow[0];
};

/* Fast tracepoint FP's jump instruction to insert.  */
#define fast_tracepoint_jump_insn(fp) \
  ((fp)->insn_and_shadow + 0)

/* The shadow memory of fast tracepoint jump FP.  */
#define fast_tracepoint_jump_shadow(fp) \
  ((fp)->insn_and_shadow + (fp)->length)


/* Return the fast tracepoint jump set at WHERE.  */

static struct fast_tracepoint_jump *
find_fast_tracepoint_jump_at (CORE_ADDR where)
{
  struct process_info *proc = current_process ();
  struct fast_tracepoint_jump *jp;

  for (jp = proc->fast_tracepoint_jumps; jp != NULL; jp = jp->next)
    if (jp->pc == where)
      return jp;

  return NULL;
}

int
fast_tracepoint_jump_here (CORE_ADDR where)
{
  struct fast_tracepoint_jump *jp = find_fast_tracepoint_jump_at (where);

  return (jp != NULL);
}

int
delete_fast_tracepoint_jump (struct fast_tracepoint_jump *todel)
{
  struct fast_tracepoint_jump *bp, **bp_link;
  int ret;
  struct process_info *proc = current_process ();

  bp = proc->fast_tracepoint_jumps;
  bp_link = &proc->fast_tracepoint_jumps;

  while (bp)
    {
      if (bp == todel)
	{
	  if (--bp->refcount == 0)
	    {
	      struct fast_tracepoint_jump *prev_bp_link = *bp_link;
	      unsigned char *buf;

	      /* Unlink it.  */
	      *bp_link = bp->next;

	      /* Since there can be breakpoints inserted in the same
		 address range, we use `target_write_memory', which
		 takes care of layering breakpoints on top of fast
		 tracepoints, and on top of the buffer we pass it.
		 This works because we've already unlinked the fast
		 tracepoint jump above.  Also note that we need to
		 pass the current shadow contents, because
		 target_write_memory updates any shadow memory with
		 what we pass here, and we want that to be a nop.  */
	      buf = (unsigned char *) alloca (bp->length);
	      memcpy (buf, fast_tracepoint_jump_shadow (bp), bp->length);
	      ret = target_write_memory (bp->pc, buf, bp->length);
	      if (ret != 0)
		{
		  /* Something went wrong, relink the jump.  */
		  *bp_link = prev_bp_link;

		  threads_debug_printf
		    ("Failed to uninsert fast tracepoint jump "
		     "at 0x%s (%s) while deleting it.",
		     paddress (bp->pc), safe_strerror (ret));
		  return ret;
		}

	      free (bp);
	    }

	  return 0;
	}
      else
	{
	  bp_link = &bp->next;
	  bp = *bp_link;
	}
    }

  warning ("Could not find fast tracepoint jump in list.");
  return ENOENT;
}

void
inc_ref_fast_tracepoint_jump (struct fast_tracepoint_jump *jp)
{
  jp->refcount++;
}

struct fast_tracepoint_jump *
set_fast_tracepoint_jump (CORE_ADDR where,
			  unsigned char *insn, ULONGEST length)
{
  struct process_info *proc = current_process ();
  struct fast_tracepoint_jump *jp;
  int err;
  unsigned char *buf;

  /* We refcount fast tracepoint jumps.  Check if we already know
     about a jump at this address.  */
  jp = find_fast_tracepoint_jump_at (where);
  if (jp != NULL)
    {
      jp->refcount++;
      return jp;
    }

  /* We don't, so create a new object.  Double the length, because the
     flexible array member holds both the jump insn, and the
     shadow.  */
  jp = (struct fast_tracepoint_jump *) xcalloc (1, sizeof (*jp) + (length * 2));
  jp->pc = where;
  jp->length = length;
  memcpy (fast_tracepoint_jump_insn (jp), insn, length);
  jp->refcount = 1;
  buf = (unsigned char *) alloca (length);

  /* Note that there can be trap breakpoints inserted in the same
     address range.  To access the original memory contents, we use
     `read_inferior_memory', which masks out breakpoints.  */
  err = read_inferior_memory (where, buf, length);
  if (err != 0)
    {
      threads_debug_printf ("Failed to read shadow memory of"
			    " fast tracepoint at 0x%s (%s).",
			    paddress (where), safe_strerror (err));
      free (jp);
      return NULL;
    }
  memcpy (fast_tracepoint_jump_shadow (jp), buf, length);

  /* Link the jump in.  */
  jp->inserted = 1;
  jp->next = proc->fast_tracepoint_jumps;
  proc->fast_tracepoint_jumps = jp;

  /* Since there can be trap breakpoints inserted in the same address
     range, we use use `target_write_memory', which takes care of
     layering breakpoints on top of fast tracepoints, on top of the
     buffer we pass it.  This works because we've already linked in
     the fast tracepoint jump above.  Also note that we need to pass
     the current shadow contents, because target_write_memory
     updates any shadow memory with what we pass here, and we want
     that to be a nop.  */
  err = target_write_memory (where, buf, length);
  if (err != 0)
    {
      threads_debug_printf
	("Failed to insert fast tracepoint jump at 0x%s (%s).",
	 paddress (where), safe_strerror (err));

      /* Unlink it.  */
      proc->fast_tracepoint_jumps = jp->next;
      free (jp);

      return NULL;
    }

  return jp;
}

void
uninsert_fast_tracepoint_jumps_at (CORE_ADDR pc)
{
  struct fast_tracepoint_jump *jp;
  int err;

  jp = find_fast_tracepoint_jump_at (pc);
  if (jp == NULL)
    {
      /* This can happen when we remove all breakpoints while handling
	 a step-over.  */
      threads_debug_printf ("Could not find fast tracepoint jump at 0x%s "
			    "in list (uninserting).",
			    paddress (pc));
      return;
    }

  if (jp->inserted)
    {
      unsigned char *buf;

      jp->inserted = 0;

      /* Since there can be trap breakpoints inserted in the same
	 address range, we use use `target_write_memory', which
	 takes care of layering breakpoints on top of fast
	 tracepoints, and on top of the buffer we pass it.  This works
	 because we've already marked the fast tracepoint fast
	 tracepoint jump uninserted above.  Also note that we need to
	 pass the current shadow contents, because
	 target_write_memory updates any shadow memory with what we
	 pass here, and we want that to be a nop.  */
      buf = (unsigned char *) alloca (jp->length);
      memcpy (buf, fast_tracepoint_jump_shadow (jp), jp->length);
      err = target_write_memory (jp->pc, buf, jp->length);
      if (err != 0)
	{
	  jp->inserted = 1;

	  threads_debug_printf ("Failed to uninsert fast tracepoint jump at"
				" 0x%s (%s).",
				paddress (pc), safe_strerror (err));
	}
    }
}

void
reinsert_fast_tracepoint_jumps_at (CORE_ADDR where)
{
  struct fast_tracepoint_jump *jp;
  int err;
  unsigned char *buf;

  jp = find_fast_tracepoint_jump_at (where);
  if (jp == NULL)
    {
      /* This can happen when we remove breakpoints when a tracepoint
	 hit causes a tracing stop, while handling a step-over.  */
      threads_debug_printf ("Could not find fast tracepoint jump at 0x%s "
			    "in list (reinserting).",
			    paddress (where));
      return;
    }

  if (jp->inserted)
    error ("Jump already inserted at reinsert time.");

  jp->inserted = 1;

  /* Since there can be trap breakpoints inserted in the same address
     range, we use `target_write_memory', which takes care of
     layering breakpoints on top of fast tracepoints, and on top of
     the buffer we pass it.  This works because we've already marked
     the fast tracepoint jump inserted above.  Also note that we need
     to pass the current shadow contents, because
     target_write_memory updates any shadow memory with what we pass
     here, and we want that to be a nop.  */
  buf = (unsigned char *) alloca (jp->length);
  memcpy (buf, fast_tracepoint_jump_shadow (jp), jp->length);
  err = target_write_memory (where, buf, jp->length);
  if (err != 0)
    {
      jp->inserted = 0;

      threads_debug_printf ("Failed to reinsert fast tracepoint jump at"
			    " 0x%s (%s).",
			    paddress (where), safe_strerror (err));
    }
}

/* Set a high-level breakpoint of type TYPE, with low level type
   RAW_TYPE and kind KIND, at WHERE.  On success, a pointer to the new
   breakpoint is returned.  On failure, returns NULL and writes the
   error code to *ERR.  HANDLER is called when the breakpoint is hit.
   HANDLER should return 1 if the breakpoint should be deleted, 0
   otherwise.  */

static struct breakpoint *
set_breakpoint (enum bkpt_type type, enum raw_bkpt_type raw_type,
		CORE_ADDR where, int kind,
		int (*handler) (CORE_ADDR), int *err)
{
  struct process_info *proc = current_process ();
  struct breakpoint *bp;
  struct raw_breakpoint *raw;

  raw = set_raw_breakpoint_at (raw_type, where, kind, err);

  if (raw == NULL)
    {
      /* warn? */
      return NULL;
    }

  if (is_gdb_breakpoint (type))
    {
      struct gdb_breakpoint *gdb_bp = XCNEW (struct gdb_breakpoint);

      bp = (struct breakpoint *) gdb_bp;
      gdb_assert (handler == NULL);
    }
  else if (type == other_breakpoint)
    {
      struct other_breakpoint *other_bp = XCNEW (struct other_breakpoint);

      other_bp->handler = handler;
      bp = (struct breakpoint *) other_bp;
    }
  else if (type == single_step_breakpoint)
    {
      struct single_step_breakpoint *ss_bp
	= XCNEW (struct single_step_breakpoint);

      bp = (struct breakpoint *) ss_bp;
    }
  else
    gdb_assert_not_reached ("unhandled breakpoint type");

  bp->type = type;
  bp->raw = raw;

  bp->next = proc->breakpoints;
  proc->breakpoints = bp;

  return bp;
}

/* Set breakpoint of TYPE on address WHERE with handler HANDLER.  */

static struct breakpoint *
set_breakpoint_type_at (enum bkpt_type type, CORE_ADDR where,
			int (*handler) (CORE_ADDR))
{
  int err_ignored;
  CORE_ADDR placed_address = where;
  int breakpoint_kind = target_breakpoint_kind_from_pc (&placed_address);

  return set_breakpoint (type, raw_bkpt_type_sw,
			 placed_address, breakpoint_kind, handler,
			 &err_ignored);
}

/* See mem-break.h  */

struct breakpoint *
set_breakpoint_at (CORE_ADDR where, int (*handler) (CORE_ADDR))
{
  return set_breakpoint_type_at (other_breakpoint, where, handler);
}


static int
delete_raw_breakpoint (struct process_info *proc, struct raw_breakpoint *todel)
{
  struct raw_breakpoint *bp, **bp_link;
  int ret;

  bp = proc->raw_breakpoints;
  bp_link = &proc->raw_breakpoints;

  while (bp)
    {
      if (bp == todel)
	{
	  if (bp->inserted > 0)
	    {
	      struct raw_breakpoint *prev_bp_link = *bp_link;

	      *bp_link = bp->next;

	      ret = the_target->remove_point (bp->raw_type, bp->pc,
					      bp->kind, bp);
	      if (ret != 0)
		{
		  /* Something went wrong, relink the breakpoint.  */
		  *bp_link = prev_bp_link;

		  threads_debug_printf ("Failed to uninsert raw breakpoint "
					"at 0x%s while deleting it.",
					paddress (bp->pc));
		  return ret;
		}
	    }
	  else
	    *bp_link = bp->next;

	  free (bp);
	  return 0;
	}
      else
	{
	  bp_link = &bp->next;
	  bp = *bp_link;
	}
    }

  warning ("Could not find raw breakpoint in list.");
  return ENOENT;
}

static int
release_breakpoint (struct process_info *proc, struct breakpoint *bp)
{
  int newrefcount;
  int ret;

  newrefcount = bp->raw->refcount - 1;
  if (newrefcount == 0)
    {
      ret = delete_raw_breakpoint (proc, bp->raw);
      if (ret != 0)
	return ret;
    }
  else
    bp->raw->refcount = newrefcount;

  free (bp);

  return 0;
}

static int
delete_breakpoint_1 (struct process_info *proc, struct breakpoint *todel)
{
  struct breakpoint *bp, **bp_link;
  int err;

  bp = proc->breakpoints;
  bp_link = &proc->breakpoints;

  while (bp)
    {
      if (bp == todel)
	{
	  *bp_link = bp->next;

	  err = release_breakpoint (proc, bp);
	  if (err != 0)
	    return err;

	  bp = *bp_link;
	  return 0;
	}
      else
	{
	  bp_link = &bp->next;
	  bp = *bp_link;
	}
    }

  warning ("Could not find breakpoint in list.");
  return ENOENT;
}

int
delete_breakpoint (struct breakpoint *todel)
{
  struct process_info *proc = current_process ();
  return delete_breakpoint_1 (proc, todel);
}

/* Locate a GDB breakpoint of type Z_TYPE and kind KIND placed at
   address ADDR and return a pointer to its structure.  If KIND is -1,
   the breakpoint's kind is ignored.  */

static struct gdb_breakpoint *
find_gdb_breakpoint (char z_type, CORE_ADDR addr, int kind)
{
  struct process_info *proc = current_process ();

  /* In some situations the current process exits, we inform GDB, but
     before GDB can acknowledge that the process has exited GDB tries to
     detach from the inferior.  As part of the detach process GDB will
     remove all breakpoints, which means we can end up here when the
     current process has already exited and so PROC is nullptr.  In this
     case just claim we can't find (and so delete) the breakpoint, GDB
     will ignore this error during detach.  */
  if (proc == nullptr)
    return nullptr;

  struct breakpoint *bp;
  enum bkpt_type type = Z_packet_to_bkpt_type (z_type);

  for (bp = proc->breakpoints; bp != NULL; bp = bp->next)
    if (bp->type == type && bp->raw->pc == addr
	&& (kind == -1 || bp->raw->kind == kind))
      return (struct gdb_breakpoint *) bp;

  return NULL;
}

static int
z_type_supported (char z_type)
{
  return (z_type >= '0' && z_type <= '4'
	  && the_target->supports_z_point_type (z_type));
}

/* Create a new GDB breakpoint of type Z_TYPE at ADDR with kind KIND.
   Returns a pointer to the newly created breakpoint on success.  On
   failure returns NULL and sets *ERR to either -1 for error, or 1 if
   Z_TYPE breakpoints are not supported on this target.  */

struct gdb_breakpoint *
set_gdb_breakpoint (char z_type, CORE_ADDR addr, int kind, int *err)
{
  struct gdb_breakpoint *bp;
  enum bkpt_type type;
  enum raw_bkpt_type raw_type;

  if (!z_type_supported (z_type))
    {
      *err = 1;
      return nullptr;
    }

  /* If we see GDB inserting a second code breakpoint at the same
     address, then either: GDB is updating the breakpoint's conditions
     or commands; or, the first breakpoint must have disappeared due
     to a shared library unload.  On targets where the shared
     libraries are handled by userspace, like SVR4, for example,
     GDBserver can't tell if a library was loaded or unloaded.  Since
     we refcount raw breakpoints, we must be careful to make sure GDB
     breakpoints never contribute more than one reference.  if we
     didn't do this, in case the previous breakpoint is gone due to a
     shared library unload, we'd just increase the refcount of the
     previous breakpoint at this address, but the trap was not planted
     in the inferior anymore, thus the breakpoint would never be hit.
     Note this must be careful to not create a window where
     breakpoints are removed from the target, for non-stop, in case
     the target can poke at memory while the program is running.  */
  if (z_type == Z_PACKET_SW_BP
      || z_type == Z_PACKET_HW_BP)
    {
      bp = find_gdb_breakpoint (z_type, addr, -1);

      if (bp != NULL)
	{
	  if (bp->base.raw->kind != kind)
	    {
	      /* A different kind than previously seen.  The previous
		 breakpoint must be gone then.  */
	      bp->base.raw->inserted = -1;
	      delete_breakpoint ((struct breakpoint *) bp);
	      bp = NULL;
	    }
	  else if (z_type == Z_PACKET_SW_BP)
	    {
	      /* Check if the breakpoint is actually gone from the
		 target, due to an solib unload, for example.  Might
		 as well validate _all_ breakpoints.  */
	      validate_breakpoints ();

	      /* Breakpoints that don't pass validation are
		 deleted.  */
	      bp = find_gdb_breakpoint (z_type, addr, -1);
	    }
	}
    }
  else
    {
      /* Data breakpoints for the same address but different kind are
	 expected.  GDB doesn't merge these.  The backend gets to do
	 that if it wants/can.  */
      bp = find_gdb_breakpoint (z_type, addr, kind);
    }

  if (bp != NULL)
    {
      /* We already know about this breakpoint, there's nothing else
	 to do - GDB's reference is already accounted for.  Note that
	 whether the breakpoint inserted is left as is - we may be
	 stepping over it, for example, in which case we don't want to
	 force-reinsert it.  */
      return bp;
    }

  raw_type = Z_packet_to_raw_bkpt_type (z_type);
  type = Z_packet_to_bkpt_type (z_type);
  return (struct gdb_breakpoint *) set_breakpoint (type, raw_type, addr,
						   kind, NULL, err);
}

/* Delete a GDB breakpoint of type Z_TYPE and kind KIND previously
   inserted at ADDR with set_gdb_breakpoint_at.  Returns 0 on success,
   -1 on error, and 1 if Z_TYPE breakpoints are not supported on this
   target.  */

int
delete_gdb_breakpoint (char z_type, CORE_ADDR addr, int kind)
{
  if (!z_type_supported (z_type))
    return 1;

  gdb_breakpoint *bp = find_gdb_breakpoint (z_type, addr, kind);
  if (bp == NULL)
    return -1;

  /* Before deleting the breakpoint, make sure to free its condition
     and command lists.  */
  clear_breakpoint_conditions_and_commands (bp);
  int err = delete_breakpoint ((struct breakpoint *) bp);
  if (err != 0)
    return -1;

  return 0;
}

/* Clear all conditions associated with a breakpoint.  */

static void
clear_breakpoint_conditions (struct gdb_breakpoint *bp)
{
  struct point_cond_list *cond;

  if (bp->cond_list == NULL)
    return;

  cond = bp->cond_list;

  while (cond != NULL)
    {
      struct point_cond_list *cond_next;

      cond_next = cond->next;
      gdb_free_agent_expr (cond->cond);
      free (cond);
      cond = cond_next;
    }

  bp->cond_list = NULL;
}

/* Clear all commands associated with a breakpoint.  */

static void
clear_breakpoint_commands (struct gdb_breakpoint *bp)
{
  struct point_command_list *cmd;

  if (bp->command_list == NULL)
    return;

  cmd = bp->command_list;

  while (cmd != NULL)
    {
      struct point_command_list *cmd_next;

      cmd_next = cmd->next;
      gdb_free_agent_expr (cmd->cmd);
      free (cmd);
      cmd = cmd_next;
    }

  bp->command_list = NULL;
}

void
clear_breakpoint_conditions_and_commands (struct gdb_breakpoint *bp)
{
  clear_breakpoint_conditions (bp);
  clear_breakpoint_commands (bp);
}

/* Add condition CONDITION to GDBserver's breakpoint BP.  */

static void
add_condition_to_breakpoint (struct gdb_breakpoint *bp,
			     struct agent_expr *condition)
{
  struct point_cond_list *new_cond;

  /* Create new condition.  */
  new_cond = XCNEW (struct point_cond_list);
  new_cond->cond = condition;

  /* Add condition to the list.  */
  new_cond->next = bp->cond_list;
  bp->cond_list = new_cond;
}

/* Add a target-side condition CONDITION to a breakpoint.  */

int
add_breakpoint_condition (struct gdb_breakpoint *bp, const char **condition)
{
  const char *actparm = *condition;
  struct agent_expr *cond;

  if (condition == NULL)
    return 1;

  if (bp == NULL)
    return 0;

  cond = gdb_parse_agent_expr (&actparm);

  if (cond == NULL)
    {
      warning ("Condition evaluation failed. Assuming unconditional.");
      return 0;
    }

  add_condition_to_breakpoint (bp, cond);

  *condition = actparm;

  return 1;
}

/* Evaluate condition (if any) at breakpoint BP.  Return 1 if
   true and 0 otherwise.  */

static int
gdb_condition_true_at_breakpoint_z_type (char z_type, CORE_ADDR addr)
{
  /* Fetch registers for the current inferior.  */
  struct gdb_breakpoint *bp = find_gdb_breakpoint (z_type, addr, -1);
  ULONGEST value = 0;
  struct point_cond_list *cl;
  int err = 0;
  struct eval_agent_expr_context ctx;

  if (bp == NULL)
    return 0;

  /* Check if the breakpoint is unconditional.  If it is,
     the condition always evaluates to TRUE.  */
  if (bp->cond_list == NULL)
    return 1;

  ctx.regcache = get_thread_regcache (current_thread, 1);
  ctx.tframe = NULL;
  ctx.tpoint = NULL;

  /* Evaluate each condition in the breakpoint's list of conditions.
     Return true if any of the conditions evaluates to TRUE.

     If we failed to evaluate the expression, TRUE is returned.  This
     forces GDB to reevaluate the conditions.  */
  for (cl = bp->cond_list;
       cl && !value && !err; cl = cl->next)
    {
      /* Evaluate the condition.  */
      err = gdb_eval_agent_expr (&ctx, cl->cond, &value);
    }

  if (err)
    return 1;

  return (value != 0);
}

int
gdb_condition_true_at_breakpoint (CORE_ADDR where)
{
  /* Only check code (software or hardware) breakpoints.  */
  return (gdb_condition_true_at_breakpoint_z_type (Z_PACKET_SW_BP, where)
	  || gdb_condition_true_at_breakpoint_z_type (Z_PACKET_HW_BP, where));
}

/* Add commands COMMANDS to GDBserver's breakpoint BP.  */

static void
add_commands_to_breakpoint (struct gdb_breakpoint *bp,
			    struct agent_expr *commands, int persist)
{
  struct point_command_list *new_cmd;

  /* Create new command.  */
  new_cmd = XCNEW (struct point_command_list);
  new_cmd->cmd = commands;
  new_cmd->persistence = persist;

  /* Add commands to the list.  */
  new_cmd->next = bp->command_list;
  bp->command_list = new_cmd;
}

/* Add a target-side command COMMAND to the breakpoint at ADDR.  */

int
add_breakpoint_commands (struct gdb_breakpoint *bp, const char **command,
			 int persist)
{
  const char *actparm = *command;
  struct agent_expr *cmd;

  if (command == NULL)
    return 1;

  if (bp == NULL)
    return 0;

  cmd = gdb_parse_agent_expr (&actparm);

  if (cmd == NULL)
    {
      warning ("Command evaluation failed. Disabling.");
      return 0;
    }

  add_commands_to_breakpoint (bp, cmd, persist);

  *command = actparm;

  return 1;
}

/* Return true if there are no commands to run at this location,
   which likely means we want to report back to GDB.  */

static int
gdb_no_commands_at_breakpoint_z_type (char z_type, CORE_ADDR addr)
{
  struct gdb_breakpoint *bp = find_gdb_breakpoint (z_type, addr, -1);

  if (bp == NULL)
    return 1;

  threads_debug_printf ("at 0x%s, type Z%c, bp command_list is 0x%s",
			paddress (addr), z_type,
			phex_nz ((uintptr_t) bp->command_list, 0));
  return (bp->command_list == NULL);
}

/* Return true if there are no commands to run at this location,
   which likely means we want to report back to GDB.  */

int
gdb_no_commands_at_breakpoint (CORE_ADDR where)
{
  /* Only check code (software or hardware) breakpoints.  */
  return (gdb_no_commands_at_breakpoint_z_type (Z_PACKET_SW_BP, where)
	  && gdb_no_commands_at_breakpoint_z_type (Z_PACKET_HW_BP, where));
}

/* Run a breakpoint's commands.  Returns 0 if there was a problem
   running any command, 1 otherwise.  */

static int
run_breakpoint_commands_z_type (char z_type, CORE_ADDR addr)
{
  /* Fetch registers for the current inferior.  */
  struct gdb_breakpoint *bp = find_gdb_breakpoint (z_type, addr, -1);
  ULONGEST value = 0;
  struct point_command_list *cl;
  int err = 0;
  struct eval_agent_expr_context ctx;

  if (bp == NULL)
    return 1;

  ctx.regcache = get_thread_regcache (current_thread, 1);
  ctx.tframe = NULL;
  ctx.tpoint = NULL;

  for (cl = bp->command_list;
       cl && !value && !err; cl = cl->next)
    {
      /* Run the command.  */
      err = gdb_eval_agent_expr (&ctx, cl->cmd, &value);

      /* If one command has a problem, stop digging the hole deeper.  */
      if (err)
	return 0;
    }

  return 1;
}

void
run_breakpoint_commands (CORE_ADDR where)
{
  /* Only check code (software or hardware) breakpoints.  If one
     command has a problem, stop digging the hole deeper.  */
  if (run_breakpoint_commands_z_type (Z_PACKET_SW_BP, where))
    run_breakpoint_commands_z_type (Z_PACKET_HW_BP, where);
}

/* See mem-break.h.  */

int
gdb_breakpoint_here (CORE_ADDR where)
{
  /* Only check code (software or hardware) breakpoints.  */
  return (find_gdb_breakpoint (Z_PACKET_SW_BP, where, -1) != NULL
	  || find_gdb_breakpoint (Z_PACKET_HW_BP, where, -1) != NULL);
}

void
set_single_step_breakpoint (CORE_ADDR stop_at, ptid_t ptid)
{
  struct single_step_breakpoint *bp;

  gdb_assert (current_ptid.pid () == ptid.pid ());

  bp = (struct single_step_breakpoint *) set_breakpoint_type_at (single_step_breakpoint,
								stop_at, NULL);
  bp->ptid = ptid;
}

void
delete_single_step_breakpoints (struct thread_info *thread)
{
  struct process_info *proc = get_thread_process (thread);
  struct breakpoint *bp, **bp_link;

  bp = proc->breakpoints;
  bp_link = &proc->breakpoints;

  while (bp)
    {
      if (bp->type == single_step_breakpoint
	  && ((struct single_step_breakpoint *) bp)->ptid == ptid_of (thread))
	{
	  scoped_restore_current_thread restore_thread;

	  switch_to_thread (thread);
	  *bp_link = bp->next;
	  release_breakpoint (proc, bp);
	  bp = *bp_link;
	}
      else
	{
	  bp_link = &bp->next;
	  bp = *bp_link;
	}
    }
}

static void
uninsert_raw_breakpoint (struct raw_breakpoint *bp)
{
  if (bp->inserted < 0)
    {
      threads_debug_printf ("Breakpoint at %s is marked insert-disabled.",
			    paddress (bp->pc));
    }
  else if (bp->inserted > 0)
    {
      int err;

      bp->inserted = 0;

      err = the_target->remove_point (bp->raw_type, bp->pc, bp->kind, bp);
      if (err != 0)
	{
	  bp->inserted = 1;

	  threads_debug_printf ("Failed to uninsert raw breakpoint at 0x%s.",
				paddress (bp->pc));
	}
    }
}

void
uninsert_breakpoints_at (CORE_ADDR pc)
{
  struct process_info *proc = current_process ();
  struct raw_breakpoint *bp;
  int found = 0;

  for (bp = proc->raw_breakpoints; bp != NULL; bp = bp->next)
    if ((bp->raw_type == raw_bkpt_type_sw
	 || bp->raw_type == raw_bkpt_type_hw)
	&& bp->pc == pc)
      {
	found = 1;

	if (bp->inserted)
	  uninsert_raw_breakpoint (bp);
      }

  if (!found)
    {
      /* This can happen when we remove all breakpoints while handling
	 a step-over.  */
      threads_debug_printf ("Could not find breakpoint at 0x%s "
			    "in list (uninserting).",
			    paddress (pc));
    }
}

void
uninsert_all_breakpoints (void)
{
  struct process_info *proc = current_process ();
  struct raw_breakpoint *bp;

  for (bp = proc->raw_breakpoints; bp != NULL; bp = bp->next)
    if ((bp->raw_type == raw_bkpt_type_sw
	 || bp->raw_type == raw_bkpt_type_hw)
	&& bp->inserted)
      uninsert_raw_breakpoint (bp);
}

void
uninsert_single_step_breakpoints (struct thread_info *thread)
{
  struct process_info *proc = get_thread_process (thread);
  struct breakpoint *bp;

  for (bp = proc->breakpoints; bp != NULL; bp = bp->next)
    {
    if (bp->type == single_step_breakpoint
	&& ((struct single_step_breakpoint *) bp)->ptid == ptid_of (thread))
      {
	gdb_assert (bp->raw->inserted > 0);

	/* Only uninsert the raw breakpoint if it only belongs to a
	   reinsert breakpoint.  */
	if (bp->raw->refcount == 1)
	  {
	    scoped_restore_current_thread restore_thread;

	    switch_to_thread (thread);
	    uninsert_raw_breakpoint (bp->raw);
	  }
      }
    }
}

static void
reinsert_raw_breakpoint (struct raw_breakpoint *bp)
{
  int err;

  if (bp->inserted)
    return;

  err = the_target->insert_point (bp->raw_type, bp->pc, bp->kind, bp);
  if (err == 0)
    bp->inserted = 1;
  else
    threads_debug_printf ("Failed to reinsert breakpoint at 0x%s (%d).",
			  paddress (bp->pc), err);
}

void
reinsert_breakpoints_at (CORE_ADDR pc)
{
  struct process_info *proc = current_process ();
  struct raw_breakpoint *bp;
  int found = 0;

  for (bp = proc->raw_breakpoints; bp != NULL; bp = bp->next)
    if ((bp->raw_type == raw_bkpt_type_sw
	 || bp->raw_type == raw_bkpt_type_hw)
	&& bp->pc == pc)
      {
	found = 1;

	reinsert_raw_breakpoint (bp);
      }

  if (!found)
    {
      /* This can happen when we remove all breakpoints while handling
	 a step-over.  */
      threads_debug_printf ("Could not find raw breakpoint at 0x%s "
			    "in list (reinserting).",
			    paddress (pc));
    }
}

int
has_single_step_breakpoints (struct thread_info *thread)
{
  struct process_info *proc = get_thread_process (thread);
  struct breakpoint *bp, **bp_link;

  bp = proc->breakpoints;
  bp_link = &proc->breakpoints;

  while (bp)
    {
      if (bp->type == single_step_breakpoint
	  && ((struct single_step_breakpoint *) bp)->ptid == ptid_of (thread))
	return 1;
      else
	{
	  bp_link = &bp->next;
	  bp = *bp_link;
	}
    }

  return 0;
}

void
reinsert_all_breakpoints (void)
{
  struct process_info *proc = current_process ();
  struct raw_breakpoint *bp;

  for (bp = proc->raw_breakpoints; bp != NULL; bp = bp->next)
    if ((bp->raw_type == raw_bkpt_type_sw
	 || bp->raw_type == raw_bkpt_type_hw)
	&& !bp->inserted)
      reinsert_raw_breakpoint (bp);
}

void
reinsert_single_step_breakpoints (struct thread_info *thread)
{
  struct process_info *proc = get_thread_process (thread);
  struct breakpoint *bp;

  for (bp = proc->breakpoints; bp != NULL; bp = bp->next)
    {
      if (bp->type == single_step_breakpoint
	  && ((struct single_step_breakpoint *) bp)->ptid == ptid_of (thread))
	{
	  gdb_assert (bp->raw->inserted > 0);

	  if (bp->raw->refcount == 1)
	    {
	      scoped_restore_current_thread restore_thread;

	      switch_to_thread (thread);
	      reinsert_raw_breakpoint (bp->raw);
	    }
	}
    }
}

void
check_breakpoints (CORE_ADDR stop_pc)
{
  struct process_info *proc = current_process ();
  struct breakpoint *bp, **bp_link;

  bp = proc->breakpoints;
  bp_link = &proc->breakpoints;

  while (bp)
    {
      struct raw_breakpoint *raw = bp->raw;

      if ((raw->raw_type == raw_bkpt_type_sw
	   || raw->raw_type == raw_bkpt_type_hw)
	  && raw->pc == stop_pc)
	{
	  if (!raw->inserted)
	    {
	      warning ("Hit a removed breakpoint?");
	      return;
	    }

	  if (bp->type == other_breakpoint)
	    {
	      struct other_breakpoint *other_bp
		= (struct other_breakpoint *) bp;

	      if (other_bp->handler != NULL && (*other_bp->handler) (stop_pc))
		{
		  *bp_link = bp->next;

		  release_breakpoint (proc, bp);

		  bp = *bp_link;
		  continue;
		}
	    }
	}

      bp_link = &bp->next;
      bp = *bp_link;
    }
}

int
breakpoint_here (CORE_ADDR addr)
{
  struct process_info *proc = current_process ();
  struct raw_breakpoint *bp;

  for (bp = proc->raw_breakpoints; bp != NULL; bp = bp->next)
    if ((bp->raw_type == raw_bkpt_type_sw
	 || bp->raw_type == raw_bkpt_type_hw)
	&& bp->pc == addr)
      return 1;

  return 0;
}

int
breakpoint_inserted_here (CORE_ADDR addr)
{
  struct process_info *proc = current_process ();
  struct raw_breakpoint *bp;

  for (bp = proc->raw_breakpoints; bp != NULL; bp = bp->next)
    if ((bp->raw_type == raw_bkpt_type_sw
	 || bp->raw_type == raw_bkpt_type_hw)
	&& bp->pc == addr
	&& bp->inserted)
      return 1;

  return 0;
}

/* See mem-break.h.  */

int
software_breakpoint_inserted_here (CORE_ADDR addr)
{
  struct process_info *proc = current_process ();
  struct raw_breakpoint *bp;

  for (bp = proc->raw_breakpoints; bp != NULL; bp = bp->next)
    if (bp->raw_type == raw_bkpt_type_sw
	&& bp->pc == addr
	&& bp->inserted)
      return 1;

  return 0;
}

/* See mem-break.h.  */

int
hardware_breakpoint_inserted_here (CORE_ADDR addr)
{
  struct process_info *proc = current_process ();
  struct raw_breakpoint *bp;

  for (bp = proc->raw_breakpoints; bp != NULL; bp = bp->next)
    if (bp->raw_type == raw_bkpt_type_hw
	&& bp->pc == addr
	&& bp->inserted)
      return 1;

  return 0;
}

/* See mem-break.h.  */

int
single_step_breakpoint_inserted_here (CORE_ADDR addr)
{
  struct process_info *proc = current_process ();
  struct breakpoint *bp;

  for (bp = proc->breakpoints; bp != NULL; bp = bp->next)
    if (bp->type == single_step_breakpoint
	&& bp->raw->pc == addr
	&& bp->raw->inserted)
      return 1;

  return 0;
}

static int
validate_inserted_breakpoint (struct raw_breakpoint *bp)
{
  unsigned char *buf;
  int err;

  gdb_assert (bp->inserted);
  gdb_assert (bp->raw_type == raw_bkpt_type_sw);

  buf = (unsigned char *) alloca (bp_size (bp));
  err = the_target->read_memory (bp->pc, buf, bp_size (bp));
  if (err || memcmp (buf, bp_opcode (bp), bp_size (bp)) != 0)
    {
      /* Tag it as gone.  */
      bp->inserted = -1;
      return 0;
    }

  return 1;
}

static void
delete_disabled_breakpoints (void)
{
  struct process_info *proc = current_process ();
  struct breakpoint *bp, *next;

  for (bp = proc->breakpoints; bp != NULL; bp = next)
    {
      next = bp->next;
      if (bp->raw->inserted < 0)
	{
	  /* If single_step_breakpoints become disabled, that means the
	     manipulations (insertion and removal) of them are wrong.  */
	  gdb_assert (bp->type != single_step_breakpoint);
	  delete_breakpoint_1 (proc, bp);
	}
    }
}

/* Check if breakpoints we inserted still appear to be inserted.  They
   may disappear due to a shared library unload, and worse, a new
   shared library may be reloaded at the same address as the
   previously unloaded one.  If that happens, we should make sure that
   the shadow memory of the old breakpoints isn't used when reading or
   writing memory.  */

void
validate_breakpoints (void)
{
  struct process_info *proc = current_process ();
  struct breakpoint *bp;

  for (bp = proc->breakpoints; bp != NULL; bp = bp->next)
    {
      struct raw_breakpoint *raw = bp->raw;

      if (raw->raw_type == raw_bkpt_type_sw && raw->inserted > 0)
	validate_inserted_breakpoint (raw);
    }

  delete_disabled_breakpoints ();
}

void
check_mem_read (CORE_ADDR mem_addr, unsigned char *buf, int mem_len)
{
  struct process_info *proc = current_process ();
  struct raw_breakpoint *bp = proc->raw_breakpoints;
  struct fast_tracepoint_jump *jp = proc->fast_tracepoint_jumps;
  CORE_ADDR mem_end = mem_addr + mem_len;
  int disabled_one = 0;

  for (; jp != NULL; jp = jp->next)
    {
      CORE_ADDR bp_end = jp->pc + jp->length;
      CORE_ADDR start, end;
      int copy_offset, copy_len, buf_offset;

      gdb_assert (fast_tracepoint_jump_shadow (jp) >= buf + mem_len
		  || buf >= fast_tracepoint_jump_shadow (jp) + (jp)->length);

      if (mem_addr >= bp_end)
	continue;
      if (jp->pc >= mem_end)
	continue;

      start = jp->pc;
      if (mem_addr > start)
	start = mem_addr;

      end = bp_end;
      if (end > mem_end)
	end = mem_end;

      copy_len = end - start;
      copy_offset = start - jp->pc;
      buf_offset = start - mem_addr;

      if (jp->inserted)
	memcpy (buf + buf_offset,
		fast_tracepoint_jump_shadow (jp) + copy_offset,
		copy_len);
    }

  for (; bp != NULL; bp = bp->next)
    {
      CORE_ADDR bp_end = bp->pc + bp_size (bp);
      CORE_ADDR start, end;
      int copy_offset, copy_len, buf_offset;

      if (bp->raw_type != raw_bkpt_type_sw)
	continue;

      gdb_assert (bp->old_data >= buf + mem_len
		  || buf >= &bp->old_data[sizeof (bp->old_data)]);

      if (mem_addr >= bp_end)
	continue;
      if (bp->pc >= mem_end)
	continue;

      start = bp->pc;
      if (mem_addr > start)
	start = mem_addr;

      end = bp_end;
      if (end > mem_end)
	end = mem_end;

      copy_len = end - start;
      copy_offset = start - bp->pc;
      buf_offset = start - mem_addr;

      if (bp->inserted > 0)
	{
	  if (validate_inserted_breakpoint (bp))
	    memcpy (buf + buf_offset, bp->old_data + copy_offset, copy_len);
	  else
	    disabled_one = 1;
	}
    }

  if (disabled_one)
    delete_disabled_breakpoints ();
}

void
check_mem_write (CORE_ADDR mem_addr, unsigned char *buf,
		 const unsigned char *myaddr, int mem_len)
{
  struct process_info *proc = current_process ();
  struct raw_breakpoint *bp = proc->raw_breakpoints;
  struct fast_tracepoint_jump *jp = proc->fast_tracepoint_jumps;
  CORE_ADDR mem_end = mem_addr + mem_len;
  int disabled_one = 0;

  /* First fast tracepoint jumps, then breakpoint traps on top.  */

  for (; jp != NULL; jp = jp->next)
    {
      CORE_ADDR jp_end = jp->pc + jp->length;
      CORE_ADDR start, end;
      int copy_offset, copy_len, buf_offset;

      gdb_assert (fast_tracepoint_jump_shadow (jp) >= myaddr + mem_len
		  || myaddr >= fast_tracepoint_jump_shadow (jp) + (jp)->length);
      gdb_assert (fast_tracepoint_jump_insn (jp) >= buf + mem_len
		  || buf >= fast_tracepoint_jump_insn (jp) + (jp)->length);

      if (mem_addr >= jp_end)
	continue;
      if (jp->pc >= mem_end)
	continue;

      start = jp->pc;
      if (mem_addr > start)
	start = mem_addr;

      end = jp_end;
      if (end > mem_end)
	end = mem_end;

      copy_len = end - start;
      copy_offset = start - jp->pc;
      buf_offset = start - mem_addr;

      memcpy (fast_tracepoint_jump_shadow (jp) + copy_offset,
	      myaddr + buf_offset, copy_len);
      if (jp->inserted)
	memcpy (buf + buf_offset,
		fast_tracepoint_jump_insn (jp) + copy_offset, copy_len);
    }

  for (; bp != NULL; bp = bp->next)
    {
      CORE_ADDR bp_end = bp->pc + bp_size (bp);
      CORE_ADDR start, end;
      int copy_offset, copy_len, buf_offset;

      if (bp->raw_type != raw_bkpt_type_sw)
	continue;

      gdb_assert (bp->old_data >= myaddr + mem_len
		  || myaddr >= &bp->old_data[sizeof (bp->old_data)]);

      if (mem_addr >= bp_end)
	continue;
      if (bp->pc >= mem_end)
	continue;

      start = bp->pc;
      if (mem_addr > start)
	start = mem_addr;

      end = bp_end;
      if (end > mem_end)
	end = mem_end;

      copy_len = end - start;
      copy_offset = start - bp->pc;
      buf_offset = start - mem_addr;

      memcpy (bp->old_data + copy_offset, myaddr + buf_offset, copy_len);
      if (bp->inserted > 0)
	{
	  if (validate_inserted_breakpoint (bp))
	    memcpy (buf + buf_offset, bp_opcode (bp) + copy_offset, copy_len);
	  else
	    disabled_one = 1;
	}
    }

  if (disabled_one)
    delete_disabled_breakpoints ();
}

/* Delete all breakpoints, watchpoints, tracepoints, and catchpoints,
   and un-insert them from the inferior.  */

void
delete_all_breakpoints (void)
{
  struct process_info *proc = current_process ();

  while (proc->breakpoints)
    delete_breakpoint_1 (proc, proc->breakpoints);
}

/* Clear the "inserted" flag in all breakpoints.  */

void
mark_breakpoints_out (struct process_info *proc)
{
  struct raw_breakpoint *raw_bp;

  for (raw_bp = proc->raw_breakpoints; raw_bp != NULL; raw_bp = raw_bp->next)
    raw_bp->inserted = 0;
}

/* Release all breakpoints, watchpoints, tracepoints, and catchpoints,
   but do not try to un-insert them from the inferior.  */

void
free_all_breakpoints (struct process_info *proc)
{
  mark_breakpoints_out (proc);

  /* Note: use PROC explicitly instead of deferring to
     delete_all_breakpoints --- CURRENT_INFERIOR may already have been
     released when we get here.  There should be no call to
     current_process from here on.  */
  while (proc->breakpoints)
    delete_breakpoint_1 (proc, proc->breakpoints);
}

/* Clone an agent expression.  */

static struct agent_expr *
clone_agent_expr (const struct agent_expr *src_ax)
{
  struct agent_expr *ax;

  ax = XCNEW (struct agent_expr);
  ax->length = src_ax->length;
  ax->bytes = (unsigned char *) xcalloc (ax->length, 1);
  memcpy (ax->bytes, src_ax->bytes, ax->length);
  return ax;
}

/* Deep-copy the contents of one breakpoint to another.  */

static struct breakpoint *
clone_one_breakpoint (const struct breakpoint *src, ptid_t ptid)
{
  struct breakpoint *dest;
  struct raw_breakpoint *dest_raw;

  /* Clone the raw breakpoint.  */
  dest_raw = XCNEW (struct raw_breakpoint);
  dest_raw->raw_type = src->raw->raw_type;
  dest_raw->refcount = src->raw->refcount;
  dest_raw->pc = src->raw->pc;
  dest_raw->kind = src->raw->kind;
  memcpy (dest_raw->old_data, src->raw->old_data, MAX_BREAKPOINT_LEN);
  dest_raw->inserted = src->raw->inserted;

  /* Clone the high-level breakpoint.  */
  if (is_gdb_breakpoint (src->type))
    {
      struct gdb_breakpoint *gdb_dest = XCNEW (struct gdb_breakpoint);
      struct point_cond_list *current_cond;
      struct point_cond_list *new_cond;
      struct point_cond_list *cond_tail = NULL;
      struct point_command_list *current_cmd;
      struct point_command_list *new_cmd;
      struct point_command_list *cmd_tail = NULL;

      /* Clone the condition list.  */
      for (current_cond = ((struct gdb_breakpoint *) src)->cond_list;
	   current_cond != NULL;
	   current_cond = current_cond->next)
	{
	  new_cond = XCNEW (struct point_cond_list);
	  new_cond->cond = clone_agent_expr (current_cond->cond);
	  APPEND_TO_LIST (&gdb_dest->cond_list, new_cond, cond_tail);
	}

      /* Clone the command list.  */
      for (current_cmd = ((struct gdb_breakpoint *) src)->command_list;
	   current_cmd != NULL;
	   current_cmd = current_cmd->next)
	{
	  new_cmd = XCNEW (struct point_command_list);
	  new_cmd->cmd = clone_agent_expr (current_cmd->cmd);
	  new_cmd->persistence = current_cmd->persistence;
	  APPEND_TO_LIST (&gdb_dest->command_list, new_cmd, cmd_tail);
	}

      dest = (struct breakpoint *) gdb_dest;
    }
  else if (src->type == other_breakpoint)
    {
      struct other_breakpoint *other_dest = XCNEW (struct other_breakpoint);

      other_dest->handler = ((struct other_breakpoint *) src)->handler;
      dest = (struct breakpoint *) other_dest;
    }
  else if (src->type == single_step_breakpoint)
    {
      struct single_step_breakpoint *ss_dest
	= XCNEW (struct single_step_breakpoint);

      dest = (struct breakpoint *) ss_dest;
      /* Since single-step breakpoint is thread specific, don't copy
	 thread id from SRC, use ID instead.  */
      ss_dest->ptid = ptid;
    }
  else
    gdb_assert_not_reached ("unhandled breakpoint type");

  dest->type = src->type;
  dest->raw = dest_raw;

  return dest;
}

/* See mem-break.h.  */

void
clone_all_breakpoints (struct thread_info *child_thread,
		       const struct thread_info *parent_thread)
{
  const struct breakpoint *bp;
  struct breakpoint *new_bkpt;
  struct breakpoint *bkpt_tail = NULL;
  struct raw_breakpoint *raw_bkpt_tail = NULL;
  struct process_info *child_proc = get_thread_process (child_thread);
  struct process_info *parent_proc = get_thread_process (parent_thread);
  struct breakpoint **new_list = &child_proc->breakpoints;
  struct raw_breakpoint **new_raw_list = &child_proc->raw_breakpoints;

  for (bp = parent_proc->breakpoints; bp != NULL; bp = bp->next)
    {
      new_bkpt = clone_one_breakpoint (bp, ptid_of (child_thread));
      APPEND_TO_LIST (new_list, new_bkpt, bkpt_tail);
      APPEND_TO_LIST (new_raw_list, new_bkpt->raw, raw_bkpt_tail);
    }
}
