From b9d580a4b05c1cb882a9fbcf11ffd3baa16b291f Mon Sep 17 00:00:00 2001 From: Stu Grossman Date: Thu, 25 Sep 1997 00:51:17 +0000 Subject: [PATCH] * Make-common.in: New files sim-break.c, sim-break.h. * sim-base.h: Add point to breakpoint list to sim_state_base. * sim-break.c sim-break.h: New modules that implement intrinsic breakpoint support. * sim-module.c: Add breakpoint module. --- sim/common/.Sanitize | 2 + sim/common/ChangeLog | 8 ++ sim/common/Make-common.in | 5 + sim/common/sim-break.c | 278 ++++++++++++++++++++++++++++++++++++++++++++++ sim/common/sim-break.h | 38 +++++++ 5 files changed, 331 insertions(+) create mode 100644 sim/common/sim-break.c create mode 100644 sim/common/sim-break.h diff --git a/sim/common/.Sanitize b/sim/common/.Sanitize index bd1065b..7dd8777 100644 --- a/sim/common/.Sanitize +++ b/sim/common/.Sanitize @@ -53,6 +53,8 @@ sim-base.h sim-basics.h sim-bits.c sim-bits.h +sim-break.c +sim-break.h sim-config.c sim-config.h sim-core.c diff --git a/sim/common/ChangeLog b/sim/common/ChangeLog index ad8f146..5627349 100644 --- a/sim/common/ChangeLog +++ b/sim/common/ChangeLog @@ -1,3 +1,11 @@ +Wed Sep 24 17:41:40 1997 Stu Grossman + + * Make-common.in: New files sim-break.c, sim-break.h. + * sim-base.h: Add point to breakpoint list to sim_state_base. + * sim-break.c sim-break.h: New modules that implement intrinsic + breakpoint support. + * sim-module.c: Add breakpoint module. + Tue Sep 23 00:26:39 1997 Felix Lee * sim-events.c (SIM_EVENTS_POLL_RATE): poll more often than once diff --git a/sim/common/Make-common.in b/sim/common/Make-common.in index 2e2075c..c0e200c 100644 --- a/sim/common/Make-common.in +++ b/sim/common/Make-common.in @@ -239,6 +239,7 @@ sim-events_h = $(srcdir)/../common/sim-events.h sim-fpu_h = $(srcdir)/../common/sim-fpu.h sim-io_h = $(srcdir)/../common/sim-io.h sim-options_h = $(srcdir)/../common/sim-options.h +sim-break_h = $(srcdir)/../common/sim-break.h # FIXME: If this complicated way of building .o files from ../common is # necessary, the reason should be documented here. @@ -353,6 +354,10 @@ sim-watch.o: $(srcdir)/../common/sim-watch.c $(sim_main_headers) \ sim-load.o: $(srcdir)/../common/sim-load.c $(CC) -c $(srcdir)/../common/sim-load.c $(ALL_CFLAGS) +sim-break.o: $(srcdir)/../common/sim-break.c $(sim_main_headers) \ + $(SIM_EXTRA_DEPS) $(sim_break_h) + $(CC) -c $(srcdir)/../common/sim-break.c $(ALL_CFLAGS) + nrun.o: $(srcdir)/../common/nrun.c config.h tconfig.h \ $(srcroot)/include/callback.h $(sim_main_headers) $(CC) -c $(srcdir)/../common/nrun.c $(ALL_CFLAGS) diff --git a/sim/common/sim-break.c b/sim/common/sim-break.c new file mode 100644 index 0000000..809f3ab --- /dev/null +++ b/sim/common/sim-break.c @@ -0,0 +1,278 @@ +/* Simulator breakpoint support. + Copyright (C) 1997 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 2, 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, write to the Free Software Foundation, Inc., +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include +#include + +#include "sim-main.h" +#include "sim-assert.h" +#include "sim-break.h" + +#ifndef SIM_BREAKPOINT +#define SIM_BREAKPOINT {0x00} +#define SIM_BREAKPOINT_SIZE (1) +#endif + +struct +sim_breakpoint +{ + struct sim_breakpoint *next; + SIM_ADDR addr; /* Address of this breakpoint */ + int flags; + unsigned char loc_contents[SIM_BREAKPOINT_SIZE]; /* Contents of addr while + BP is enabled */ +}; + +#define SIM_BREAK_INSERTED 0x1 /* Breakpoint has been inserted */ +#define SIM_BREAK_DISABLED 0x2 /* Breakpoint is disabled */ + +static unsigned char sim_breakpoint [] = SIM_BREAKPOINT; + +static void insert_breakpoint PARAMS ((SIM_DESC sd, + struct sim_breakpoint *bp)); +static void remove_breakpoint PARAMS ((SIM_DESC sd, + struct sim_breakpoint *bp)); +static SIM_RC resume_handler PARAMS ((SIM_DESC sd)); +static SIM_RC suspend_handler PARAMS ((SIM_DESC sd)); + + +/* Do the actual work of inserting a breakpoint into the instruction stream. */ + +static void +insert_breakpoint (sd, bp) + SIM_DESC sd; + struct sim_breakpoint *bp; +{ + if (bp->flags & (SIM_BREAK_INSERTED | SIM_BREAK_DISABLED)) + return; + + sim_core_read_buffer (sd, NULL, sim_core_write_map, bp->loc_contents, + bp->addr, SIM_BREAKPOINT_SIZE); + sim_core_write_buffer (sd, NULL, sim_core_write_map, sim_breakpoint, + bp->addr, SIM_BREAKPOINT_SIZE); + bp->flags |= SIM_BREAK_INSERTED; +} + +/* Do the actual work of removing a breakpoint. */ + +static void +remove_breakpoint (sd, bp) + SIM_DESC sd; + struct sim_breakpoint *bp; +{ + if (!(bp->flags & SIM_BREAK_INSERTED)) + return; + + sim_core_write_buffer (sd, NULL, sim_core_write_map, bp->loc_contents, + bp->addr, SIM_BREAKPOINT_SIZE); + bp->flags &= SIM_BREAK_INSERTED; +} + +/* Come here when a breakpoint insn is hit. If it's really a breakpoint, we + halt things, and never return. If it's a false hit, we return to let the + caller handle things. */ + +void +sim_handle_breakpoint (sd, cpu, cia) + SIM_DESC sd; + sim_cpu *cpu; + sim_cia cia; +{ + struct sim_breakpoint *bp; + + for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next) + if (bp->addr == cia) + break; + + if (!bp || !(bp->flags & SIM_BREAK_INSERTED)) + return; + + sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, cia, sim_stopped, SIGTRAP); +} + +/* Handler functions for simulator resume and suspend events. */ + +static SIM_RC +resume_handler (sd) + SIM_DESC sd; +{ + struct sim_breakpoint *bp; + + for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next) + insert_breakpoint (sd, bp); + + return SIM_RC_OK; +} + +static SIM_RC +suspend_handler (sd) + SIM_DESC sd; +{ + struct sim_breakpoint *bp; + + for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next) + remove_breakpoint (sd, bp); + + return SIM_RC_OK; +} + +/* Called from simulator module initialization. */ + +SIM_RC +sim_break_install (sd) + SIM_DESC sd; +{ + sim_module_add_resume_fn (sd, resume_handler); + sim_module_add_suspend_fn (sd, suspend_handler); + + return SIM_RC_OK; +} + +/* Install a breakpoint. This is a user-function. The breakpoint isn't + actually installed here. We just record it. Resume_handler does the + actual work. +*/ + +SIM_RC +sim_set_breakpoint (sd, addr) + SIM_DESC sd; + SIM_ADDR addr; +{ + struct sim_breakpoint *bp; + + for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next) + if (bp->addr == addr) + return SIM_RC_DUPLICATE_BREAKPOINT; /* Already there */ + else + break; + + bp = (struct sim_breakpoint *) xmalloc (sizeof (struct sim_breakpoint)); + + bp->addr = addr; + bp->next = STATE_BREAKPOINTS (sd); + bp->flags = 0; + STATE_BREAKPOINTS (sd) = bp; + + return SIM_RC_OK; +} + +/* Delete a breakpoint. All knowlege of the breakpoint is removed from the + simulator. +*/ + +SIM_RC +sim_clear_breakpoint (sd, addr) + SIM_DESC sd; + SIM_ADDR addr; +{ + struct sim_breakpoint *bp, *bpprev; + + for (bp = STATE_BREAKPOINTS (sd), bpprev = NULL; + bp; + bpprev = bp, bp = bp->next) + if (bp->addr == addr) + break; + + if (!bp) + return SIM_RC_UNKNOWN_BREAKPOINT; + + remove_breakpoint (sd, bp); + + if (bpprev) + bpprev->next = bp->next; + else + STATE_BREAKPOINTS (sd) = NULL; + + free (bp); + + return SIM_RC_OK; +} + +SIM_RC +sim_clear_all_breakpoints (sd) + SIM_DESC sd; +{ + while (STATE_BREAKPOINTS (sd)) + sim_clear_breakpoint (sd, STATE_BREAKPOINTS (sd)->addr); + + return SIM_RC_OK; +} + +SIM_RC +sim_enable_breakpoint (sd, addr) + SIM_DESC sd; + SIM_ADDR addr; +{ + struct sim_breakpoint *bp; + + for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next) + if (bp->addr == addr) + break; + + if (!bp) + return SIM_RC_UNKNOWN_BREAKPOINT; + + bp->flags &= ~SIM_BREAK_DISABLED; + + return SIM_RC_OK; +} + +SIM_RC +sim_disable_breakpoint (sd, addr) + SIM_DESC sd; + SIM_ADDR addr; +{ + struct sim_breakpoint *bp; + + for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next) + if (bp->addr == addr) + break; + + if (!bp) + return SIM_RC_UNKNOWN_BREAKPOINT; + + bp->flags |= SIM_BREAK_DISABLED; + + return SIM_RC_OK; +} + +SIM_RC +sim_enable_all_breakpoints (sd) + SIM_DESC sd; +{ + struct sim_breakpoint *bp; + + for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next) + bp->flags &= ~SIM_BREAK_DISABLED; + + return SIM_RC_OK; +} + +SIM_RC +sim_disable_all_breakpoints (sd) + SIM_DESC sd; +{ + struct sim_breakpoint *bp; + + for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next) + bp->flags |= SIM_BREAK_DISABLED; + + return SIM_RC_OK; +} diff --git a/sim/common/sim-break.h b/sim/common/sim-break.h new file mode 100644 index 0000000..8b0338f --- /dev/null +++ b/sim/common/sim-break.h @@ -0,0 +1,38 @@ +/* Simulator breakpoint support. + Copyright (C) 1997 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 2, 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, write to the Free Software Foundation, Inc., +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + + +#ifndef SIM_BREAK_H +#define SIM_BREAK_H + +/* Call this to install the resume and suspend handlers for the breakpoint + module. */ + +MODULE_INSTALL_FN sim_break_install; + +/* Call this inside the simulator when we execute the potential + breakpoint insn. If the breakpoint system knows about it, the + breakpoint is handled, and this routine never returns. If this + isn't really a breakpoint, then it returns to allow the caller to + handle things. */ + +void sim_handle_breakpoint PARAMS ((SIM_DESC sd, sim_cpu *cpu, sim_cia cia)); + +#endif /* SIM_BREAK_H */ -- 2.7.4