sim: watchpoints: use common sim_pc_get

Few arches implement STATE_WATCHPOINTS()->pc while all of them implement
sim_pc_get.  Lets switch the sim-watch core for monitoring pc events to
the sim_pc_get API so this module works for all ports, and then we can
delete this old back channel of snooping in the port's cpu state -- the
code needs the pointer to the pc storage so that it can read out bytes
and compare them to the watchrange.

This also fixes the logic on multi-cpu sims by removing the limitation
of only being able to watch CPU0's state.
This commit is contained in:
Mike Frysinger
2015-03-23 00:44:54 -04:00
parent cd89c53f6d
commit 4c0d76b9c4
25 changed files with 129 additions and 54 deletions

View File

@@ -1,3 +1,7 @@
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* README-HACKING: Replace STATE_WATCHPOINTS with CPU_PC_FETCH.
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* configure.ac (HDEFINES): Delete AC_SUBST call.

View File

@@ -267,8 +267,8 @@ And in your insn fetcher:
PROFILE_COUNT_CORE (cpu, target_addr, size_in_bytes, map_exec);
To use the PC profiling code, you simply have to tell the system where to find
your simulator's PC. So in your sim_open() function:
STATE_WATCHPOINTS (sd)->pc = address_of_cpu0_pc;
your simulator's PC. So in your model initialization function:
CPU_PC_FETCH (cpu) = function_that_fetches_the_pc;
To profile branches, in every location where a branch insn is executed, call
one of the related helpers:

View File

@@ -1,3 +1,7 @@
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* interp.c (sim_open): Delete call to STATE_WATCHPOINTS.
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* configure: Regenerate.

View File

@@ -1690,12 +1690,6 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb,
return 0;
}
{
/* XXX: Only first core gets profiled ? */
SIM_CPU *cpu = STATE_CPU (sd, 0);
STATE_WATCHPOINTS (sd)->pc = &cpu->pc;
}
if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
{
free_state (sd);

View File

@@ -1,3 +1,7 @@
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* interp.c (sim_open): Delete call to STATE_WATCHPOINTS.
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* configure: Regenerate.

View File

@@ -729,12 +729,6 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback,
return 0;
}
{
/* XXX: Only first core gets profiled ? */
SIM_CPU *cpu = STATE_CPU (sd, 0);
STATE_WATCHPOINTS (sd)->pc = &PCREG;
}
if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
{
free_state (sd);

View File

@@ -1,3 +1,14 @@
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* sim-events.c: Include sim-cpu.h.
(sim_event_watchpoints): Define watch_pc.
(sim_events_watch_pc): New function.
(WATCH_SIM): Handle watch_pc.
* sim-events.h (sim_events_watch_pc): New prototype.
* sim-watch.c (schedule_watchpoint): Replace sim_events_watch_sim with
sim_events_watch_pc.
* sim-watch.h (sim_watchpoints): Delete pc.
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* acinclude.m4 (SIM_AC_COMMON): Replace AC_CONFIG_HEADER with

View File

@@ -25,6 +25,7 @@
#include "sim-main.h"
#include "sim-assert.h"
#include "sim-cpu.h"
#include "libiberty.h"
#include <string.h>
@@ -66,6 +67,9 @@ typedef enum {
watch_sim_le_4,
watch_sim_le_8,
/* pc */
watch_pc,
/* wallclock */
watch_clock,
@@ -608,6 +612,45 @@ sim_events_watch_clock (SIM_DESC sd,
#endif
#if EXTERN_SIM_EVENTS_P
sim_event *
sim_events_watch_pc (SIM_DESC sd,
int is_within,
unsigned64 lb,
unsigned64 ub,
sim_event_handler *handler,
void *data)
{
sim_events *events = STATE_EVENTS (sd);
sim_event *new_event = sim_events_zalloc (sd);
/* type */
new_event->watching = watch_pc;
/* handler */
new_event->data = data;
new_event->handler = handler;
/* data */
new_event->lb = lb;
new_event->lb64 = lb;
new_event->ub = ub;
new_event->ub64 = ub;
new_event->is_within = (is_within != 0);
/* insert */
new_event->next = events->watchpoints;
events->watchpoints = new_event;
events->work_pending = 1;
ETRACE ((_ETRACE,
"event watching pc at %ld - tag 0x%lx - pc 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
(long)sim_events_time (sd),
(long)new_event,
(long)new_event->lb,
(long)new_event->ub,
(long)new_event->handler,
(long)new_event->data));
return new_event;
}
#endif
#if EXTERN_SIM_EVENTS_P
sim_event *
sim_events_watch_sim (SIM_DESC sd,
@@ -965,6 +1008,21 @@ sim_watch_valid (SIM_DESC sd,
}
#undef WATCH_SIM
case watch_pc:
{
int c;
for (c = 0; c < MAX_NR_PROCESSORS; ++c)
{
sim_cpu *cpu = STATE_CPU (sd, c);
sim_cia cia = sim_pc_get (cpu);
if (to_do->is_within == (cia >= to_do->lb64 && cia <= to_do->ub64))
return 1;
}
return 0;
}
case watch_clock: /* wallclock */
{
unsigned long elapsed_time = sim_events_elapsed_time (sd);

View File

@@ -149,6 +149,17 @@ extern sim_event *sim_events_watch_clock
void *data);
/* Schedule an event when a PC matches a range. */
extern sim_event *sim_events_watch_pc
(SIM_DESC sd,
int is_within,
unsigned64 lb,
unsigned64 ub,
sim_event_handler *handler,
void *data);
/* Schedule an event when the test (IS_WITHIN == (VAL >= LB && VAL <=
UB)) of the NR_BYTES value at HOST_ADDR with BYTE_ORDER endian is
true.

View File

@@ -167,18 +167,16 @@ schedule_watchpoint (SIM_DESC sd,
sim_watch_point *point)
{
sim_watchpoints *watch = STATE_WATCHPOINTS (sd);
switch (point->type)
{
case pc_watchpoint:
point->event = sim_events_watch_sim (sd,
watch->pc,
sizeof (sim_cia),
HOST_BYTE_ORDER,
point->is_within,
point->arg0, point->arg1,
/* PC in arg0..arg1 */
handle_watchpoint,
point);
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,

View File

@@ -49,7 +49,6 @@ typedef struct _sim_watchpoints {
address/size of the program-counter */
/* FIXME: In the future this shall be generalized so that any of the
N processors M registers can be watched */
void *pc;
/* Pointer to the handler for interrupt watchpoints */
/* FIXME: can this be done better? */

View File

@@ -1,3 +1,7 @@
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* sim-if.c (sim_open): Delete call to STATE_WATCHPOINTS.
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* configure: Regenerate.

View File

@@ -61,14 +61,6 @@ sim_open (kind, callback, abfd, argv)
return 0;
}
#if 0 /* FIXME: pc is in mach-specific struct */
/* FIXME: watchpoints code shouldn't need this */
{
SIM_CPU *current_cpu = STATE_CPU (sd, 0);
STATE_WATCHPOINTS (sd)->pc = &(PC);
}
#endif
if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
{
free_state (sd);

View File

@@ -1,3 +1,7 @@
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* sim-if.c (sim_open): Delete call to STATE_WATCHPOINTS.
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* configure: Regenerate.

View File

@@ -67,14 +67,6 @@ sim_open (kind, callback, abfd, argv)
return 0;
}
#if 0 /* FIXME: pc is in mach-specific struct */
/* FIXME: watchpoints code shouldn't need this */
{
SIM_CPU *current_cpu = STATE_CPU (sd, 0);
STATE_WATCHPOINTS (sd)->pc = &(PC);
}
#endif
if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
{
free_state (sd);

View File

@@ -1,3 +1,7 @@
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* sim-if.c (sim_open): Delete call to STATE_WATCHPOINTS.
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* configure: Regenerate.

View File

@@ -61,14 +61,6 @@ sim_open (kind, callback, abfd, argv)
return 0;
}
#if 0 /* FIXME: pc is in mach-specific struct */
/* FIXME: watchpoints code shouldn't need this */
{
SIM_CPU *current_cpu = STATE_CPU (sd, 0);
STATE_WATCHPOINTS (sd)->pc = &(PC);
}
#endif
if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
{
free_state (sd);

View File

@@ -1,3 +1,7 @@
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* interp.c (sim_open): Delete call to STATE_WATCHPOINTS.
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* configure: Regenerate.

View File

@@ -355,7 +355,6 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb,
cpu = STATE_CPU (sd, 0); /* FIXME */
/* FIXME: watchpoints code shouldn't need this */
STATE_WATCHPOINTS (sd)->pc = &(PC);
STATE_WATCHPOINTS (sd)->interrupt_handler = interrupt_event;
/* Initialize the mechanism for doing insn profiling. */

View File

@@ -1,3 +1,7 @@
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* interp.c (sim_open): Delete call to STATE_WATCHPOINTS.
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* configure: Regenerate.
@@ -1573,4 +1577,3 @@ Mon Nov 25 12:46:38 1996 Jeffrey A Law (law@cygnus.com)
* Makefile.in, config.in, configure, configure.in: New files.
* gencode.c, interp.c, mn10300_sim.h, simops.c: New files.

View File

@@ -102,7 +102,6 @@ sim_open (SIM_OPEN_KIND kind,
/* FIXME: should be better way of setting up interrupts. For
moment, only support watchpoints causing a breakpoint (gdb
halt). */
STATE_WATCHPOINTS (sd)->pc = &(PC);
STATE_WATCHPOINTS (sd)->interrupt_handler = NULL;
STATE_WATCHPOINTS (sd)->interrupt_names = NULL;

View File

@@ -1,3 +1,7 @@
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* interp.c (sim_open): Delete call to STATE_WATCHPOINTS.
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* configure: Regenerate.

View File

@@ -1203,8 +1203,6 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb,
return 0;
}
STATE_WATCHPOINTS (sd)->pc = &cpu.asregs.regs[PC_REGNO];
if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
{
free_state (sd);

View File

@@ -1,3 +1,7 @@
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* interp.c (sim_open): Delete call to STATE_WATCHPOINTS.
2021-02-06 Mike Frysinger <vapier@gentoo.org>
* configure: Regenerate.

View File

@@ -202,7 +202,6 @@ sim_open (SIM_OPEN_KIND kind,
simulator = sd;
/* FIXME: should be better way of setting up interrupts */
STATE_WATCHPOINTS (sd)->pc = &(PC);
STATE_WATCHPOINTS (sd)->interrupt_handler = do_interrupt;
STATE_WATCHPOINTS (sd)->interrupt_names = interrupt_names;