PATCH: Use target values for signals in simulator

mitchell
2005-11-23T18:58:10Z

At present, when the GDB simulators report signals to GDB, they use
the host signal numbers. That leads to the problem that different
hosts have different sets of signals, so things like:

#ifndef SIGTRAP
#define SIGTRAP 5
#endif

appear in some the simulators -- and the ones that don't won't build
on some systems, notably Windows.

The #ifdef hack works, in practice, but isn't really correct; we don't
know that no other signal has the value 5. Also, some of the
simulators translate a simulated SIGBUS as SIGSEGV on systems without
SIGBUS, meaning that the behavior of the simulator depends on the host
system -- clearly undesirable.

There's been a comment about this problem in gdbsim_wait for some
time. Both the comment and Daniel Jacobowitz suggest that the right
solution is for the simulator to communicate with GDB using the
TARGET_SIGNAL_* enumeration in gdb/signals.h. Then, there's no need
for the #ifdefs, and no host dependency.

This patch implements that change.

The principal risk with this patch is that I may have failed to
translate from one of the various simulator's internal representation
of a signal to the appropriate TARGET_SIGNAL_ value. However, because
TARGET_SIGNAL_* uses the conventional UNIX values for signals to the
extent there are conventions (like, TARGET_SIGNAL_SEGV is 11 and
TARGET_SIGNAL_TRAP is 5) it's unlikely that any places I missed will
actually matter.

In other words, the simulators were already translating to the host
signal numbers, which, in practice, are very likely to match up with
TARGET_SIGNAL_* -- especially since most of the simulators generate a
pretty limited set of signals. So, if I missed a spot, it's very
likely that the values are correct anyhow. Therefore, I think this
patch is pretty safe.

I will of course clean up any fall-out. (I realize the ChangeLog
below will require separation into the ChangeLogs in the various
subdirectories.) I tested this patch by debugging PowerPC EABI
programs in simulation.

OK to apply?

Thanks,

--

2005-11-16 Mark Mitchell <mark@codesourcery.com>

* gdb/remote-sim.c (gdbsim_wait): Don't use target_signal_to_host
or target_signal_from_host.
* sim/arm/wrapper.c (gdb/signals.h): Include it.
(SIGTRAP): Don't define it.
(SIGBUS): Likewise.
(sim_stop_reason): Use TARGET_SIGNAL_*.
* sim/common/sim-reason.c (sim_stop_reason): Use
sim_signal_to_target, not sim_signal_to_host.
* sim/common/sim-signal.c (sim_signal_to_host): Fix typo.
(sim_signal_to_target): New function.
* sim/common/sim-signal.h: Declare it.
* sim/d10v/interp.c (gdb/signals.h): Include it.
(sim_stop_reason): Use TARGET_SIGNAL_*.
* sim/erc32/interf.c: (gdb/signals.h): Include it.
(sim_stop_reason): Use TARGET_SIGNAL_*.
* sim/ppc/sim_calls.c (gdb/signals.h): Include it.
(sim_stop_reason): Use TARGET_SIGNAL_*.

Index: gdb/remote-sim.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-sim.c,v
retrieving revision 1.49
retrieving revision 1.49.6.1
diff -c -5 -p -r1.49 -r1.49.6.1
*** gdb/remote-sim.c 19 Jun 2005 20:08:37 -0000 1.49
--- gdb/remote-sim.c 17 Nov 2005 06:22:44 -0000 1.49.6.1
*************** gdbsim_wait (ptid_t ptid, struct target_
*** 672,683 ****
prev_sigint = osa.sa_handler;
}
#else
prev_sigint = signal (SIGINT, gdbsim_cntrl_c);
#endif
! sim_resume (gdbsim_desc, resume_step,
! target_signal_to_host (resume_siggnal));
signal (SIGINT, prev_sigint);
resume_step = 0;

sim_stop_reason (gdbsim_desc, &reason, &sigrc);

--- 672,682 ----
prev_sigint = osa.sa_handler;
}
#else
prev_sigint = signal (SIGINT, gdbsim_cntrl_c);
#endif
! sim_resume (gdbsim_desc, resume_step, resume_siggnal);
signal (SIGINT, prev_sigint);
resume_step = 0;

sim_stop_reason (gdbsim_desc, &reason, &sigrc);

*************** gdbsim_wait (ptid_t ptid, struct target_
*** 688,715 ****
status->value.integer = sigrc;
break;
case sim_stopped:
switch (sigrc)
{
! case SIGABRT:
quit ();
break;
! case SIGINT:
! case SIGTRAP:
default:
status->kind = TARGET_WAITKIND_STOPPED;
! /* The signal in sigrc is a host signal. That probably
! should be fixed. */
! status->value.sig = target_signal_from_host (sigrc);
break;
}
break;
case sim_signalled:
status->kind = TARGET_WAITKIND_SIGNALLED;
! /* The signal in sigrc is a host signal. That probably
! should be fixed. */
! status->value.sig = target_signal_from_host (sigrc);
break;
case sim_running:
case sim_polling:
/* FIXME: Is this correct? */
break;
--- 687,710 ----
status->value.integer = sigrc;
break;
case sim_stopped:
switch (sigrc)
{
! case TARGET_SIGNAL_ABRT:
quit ();
break;
! case TARGET_SIGNAL_INT:
! case TARGET_SIGNAL_TRAP:
default:
status->kind = TARGET_WAITKIND_STOPPED;
! status->value.sig = sigrc;
break;
}
break;
case sim_signalled:
status->kind = TARGET_WAITKIND_SIGNALLED;
! status->value.sig = sigrc;
break;
case sim_running:
case sim_polling:
/* FIXME: Is this correct? */
break;
Index: sim/arm/wrapper.c
===================================================================
RCS file: /cvs/src/src/sim/arm/wrapper.c,v
retrieving revision 1.30
retrieving revision 1.30.8.1
diff -c -5 -p -r1.30 -r1.30.8.1
*** sim/arm/wrapper.c 12 May 2005 07:36:59 -0000 1.30
--- sim/arm/wrapper.c 17 Nov 2005 06:22:44 -0000 1.30.8.1
***************
*** 35,52 ****
#include "dbg_rdi.h"
#include "ansidecl.h"
#include "sim-utils.h"
#include "run-sim.h"
#include "gdb/sim-arm.h"
!
! #ifndef SIGTRAP
! #define SIGTRAP 5
! #endif
!
! #ifndef SIGBUS
! #define SIGBUS SIGSEGV
! #endif

host_callback *sim_callback;

static struct ARMul_State *state;

--- 35,45 ----
#include "dbg_rdi.h"
#include "ansidecl.h"
#include "sim-utils.h"
#include "run-sim.h"
#include "gdb/sim-arm.h"
! #include "gdb/signals.h"

host_callback *sim_callback;

static struct ARMul_State *state;

*************** sim_stop_reason (sd, reason, sigrc)
*** 908,932 ****
int *sigrc;
{
if (stop_simulator)
{
*reason = sim_stopped;
! *sigrc = SIGINT;
}
else if (state->EndCondition == 0)
{
*reason = sim_exited;
*sigrc = state->Reg[0] & 255;
}
else
{
*reason = sim_stopped;
if (state->EndCondition == RDIError_BreakpointReached)
! *sigrc = SIGTRAP;
else if ( state->EndCondition == RDIError_DataAbort
|| state->EndCondition == RDIError_AddressException)
! *sigrc = SIGBUS;
else
*sigrc = 0;
}
}

--- 901,925 ----
int *sigrc;
{
if (stop_simulator)
{
*reason = sim_stopped;
! *sigrc = TARGET_SIGNAL_INT;
}
else if (state->EndCondition == 0)
{
*reason = sim_exited;
*sigrc = state->Reg[0] & 255;
}
else
{
*reason = sim_stopped;
if (state->EndCondition == RDIError_BreakpointReached)
! *sigrc = TARGET_SIGNAL_TRAP;
else if ( state->EndCondition == RDIError_DataAbort
|| state->EndCondition == RDIError_AddressException)
! *sigrc = TARGET_SIGNAL_BUS;
else
*sigrc = 0;
}
}

Index: sim/common/sim-reason.c
===================================================================
RCS file: /cvs/src/src/sim/common/sim-reason.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.98.1
diff -c -5 -p -r1.1.1.1 -r1.1.1.1.98.1
*** sim/common/sim-reason.c 16 Apr 1999 01:34:58 -0000 1.1.1.1
--- sim/common/sim-reason.c 17 Nov 2005 06:22:44 -0000 1.1.1.1.98.1
*************** sim_stop_reason (SIM_DESC sd, enum sim_s
*** 33,57 ****
switch (*reason)
{
case sim_exited :
*sigrc = engine->sigrc;
break;
- case sim_signalled :
- /* ??? See the comment below case `sim_signalled' in
- gdb/remote-sim.c:gdbsim_wait.
- ??? Consider the case of the target requesting that it
- kill(2) itself with SIGNAL. That SIGNAL, being target
- specific, will not correspond to either of the SIM_SIGNAL
- enum nor the HOST_SIGNAL. A mapping from TARGET_SIGNAL to
- HOST_SIGNAL is needed. */
- *sigrc = sim_signal_to_host (sd, engine->sigrc);
- break;
case sim_stopped :
! /* The gdb/simulator interface calls for us to return the host
! version of the signal which gdb then converts into the
! target's version. This is obviously a bit clumsy. */
! *sigrc = sim_signal_to_host (sd, engine->sigrc);
break;
default :
abort ();
}
}
--- 33,45 ----
switch (*reason)
{
case sim_exited :
*sigrc = engine->sigrc;
break;
case sim_stopped :
! case sim_signalled :
! *sigrc = sim_signal_to_target (sd, engine->sigrc);
break;
default :
abort ();
}
}
Index: sim/common/sim-signal.c
===================================================================
RCS file: /cvs/src/src/sim/common/sim-signal.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.98.1
diff -c -5 -p -r1.1.1.1 -r1.1.1.1.98.1
*** sim/common/sim-signal.c 16 Apr 1999 01:34:59 -0000 1.1.1.1
--- sim/common/sim-signal.c 17 Nov 2005 06:22:44 -0000 1.1.1.1.98.1
*************** sim_signal_to_host (SIM_DESC sd, SIM_SIG
*** 75,85 ****
return SIGXCPU;
#endif
break;

case SIM_SIGFPE:
! #ifdef SIGXCPU
return SIGFPE;
#endif
break;

case SIM_SIGNONE:
--- 75,85 ----
return SIGXCPU;
#endif
break;

case SIM_SIGFPE:
! #ifdef SIGFPE
return SIGFPE;
#endif
break;

case SIM_SIGNONE:
*************** sim_signal_to_host (SIM_DESC sd, SIM_SIG
*** 92,96 ****
--- 92,135 ----
return SIGHUP; /* FIXME: Suggestions? */
#else
return 1;
#endif
}
+
+ int
+ sim_signal_to_target (SIM_DESC sd, SIM_SIGNAL sig)
+ {
+ switch (sig)
+ {
+ case SIM_SIGINT :
+ return TARGET_SIGNAL_INT;
+
+ case SIM_SIGABRT :
+ return TARGET_SIGNAL_ABRT;
+
+ case SIM_SIGILL :
+ return TARGET_SIGNAL_ILL;
+
+ case SIM_SIGTRAP :
+ return TARGET_SIGNAL_TRAP;
+
+ case SIM_SIGBUS :
+ return TARGET_SIGNAL_BUS;
+
+ case SIM_SIGSEGV
+ return TARGET_SIGNAL_SEGV;
+
+ case SIM_SIGXCPU :
+ return TARGET_SIGNAL_XCPU;
+
+ case SIM_SIGFPE:
+ return TARGET_SIGNAL_FPE;
+ break;
+
+ case SIM_SIGNONE:
+ return TARGET_SIGNAL_0;
+ break;
+ }
+
+ sim_io_eprintf (sd, "sim_signal_to_host: unknown signal: %d\n", sig);
+ return TARGET_SIGNAL_HUP;
+ }
Index: sim/common/sim-signal.h
===================================================================
RCS file: /cvs/src/src/sim/common/sim-signal.h,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.98.1
diff -c -5 -p -r1.1.1.1 -r1.1.1.1.98.1
*** sim/common/sim-signal.h 16 Apr 1999 01:34:59 -0000 1.1.1.1
--- sim/common/sim-signal.h 17 Nov 2005 06:22:44 -0000 1.1.1.1.98.1
*************** with this program; if not, write to the
*** 19,28 ****
--- 19,30 ----
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */

#ifndef SIM_SIGNAL_H
#define SIM_SIGNAL_H

+ #include "gdb/signals.h"
+
/* Signals we use.
This provides a layer between our values and host/target values. */

typedef enum {
SIM_SIGNONE = 64,
*************** typedef enum {
*** 43,49 ****
--- 45,52 ----
/* simulation aborted */
SIM_SIGABRT
} SIM_SIGNAL;

int sim_signal_to_host (SIM_DESC sd, SIM_SIGNAL);
+ enum target_signal sim_signal_to_target (SIM_DESC sd, SIM_SIGNAL);

#endif /* SIM_SIGNAL_H */
Index: sim/d10v/interp.c
===================================================================
RCS file: /cvs/src/src/sim/d10v/interp.c,v
retrieving revision 1.16
retrieving revision 1.16.16.1
diff -c -5 -p -r1.16 -r1.16.16.1
*** sim/d10v/interp.c 29 Jun 2004 00:54:00 -0000 1.16
--- sim/d10v/interp.c 17 Nov 2005 06:22:44 -0000 1.16.16.1
***************
*** 4,13 ****
--- 4,14 ----
#include "gdb/callback.h"
#include "gdb/remote-sim.h"

#include "d10v_sim.h"
#include "gdb/sim-d10v.h"
+ #include "gdb/signals.h"

enum _leftright { LEFT_FIRST, RIGHT_FIRST };

static char *myname;
static SIM_OPEN_KIND sim_kind;
*************** sim_stop_reason (sd, reason, sigrc)
*** 1275,1295 ****
*sigrc = GPR (0);
break;

case SIG_D10V_BUS:
*reason = sim_stopped;
! #ifdef SIGBUS
! *sigrc = SIGBUS;
! #else
! *sigrc = SIGSEGV;
! #endif
break;

default: /* some signal */
*reason = sim_stopped;
if (stop_simulator && !State.exception)
! *sigrc = SIGINT;
else
*sigrc = State.exception;
break;
}

--- 1276,1292 ----
*sigrc = GPR (0);
break;

case SIG_D10V_BUS:
*reason = sim_stopped;
! *reson = TARGET_SIGNAL_BUS;
break;

default: /* some signal */
*reason = sim_stopped;
if (stop_simulator && !State.exception)
! *sigrc = TARGET_SIGNAL_INT;
else
*sigrc = State.exception;
break;
}

Index: sim/erc32/interf.c
===================================================================
RCS file: /cvs/src/src/sim/erc32/interf.c,v
retrieving revision 1.5
retrieving revision 1.5.10.1
diff -c -5 -p -r1.5 -r1.5.10.1
*** sim/erc32/interf.c 7 Mar 2005 11:09:05 -0000 1.5
--- sim/erc32/interf.c 17 Nov 2005 06:22:44 -0000 1.5.10.1
***************
*** 31,40 ****
--- 31,41 ----
#include "bfd.h"
#include <dis-asm.h>
#include "sim-config.h"

#include "gdb/remote-sim.h"
+ #include "gdb/signals.h"

#define PSR_CWP 0x7

#define VAL(x) strtol(x,(char **)NULL,0)

*************** sim_stop_reason(sd, reason, sigrc)
*** 384,403 ****
{

switch (simstat) {
case CTRL_C:
*reason = sim_stopped;
! *sigrc = SIGINT;
break;
case OK:
case TIME_OUT:
case BPT_HIT:
*reason = sim_stopped;
! #ifdef _WIN32
! #define SIGTRAP 5
! #endif
! *sigrc = SIGTRAP;
break;
case ERROR:
*sigrc = 0;
*reason = sim_exited;
}
--- 385,401 ----
{

switch (simstat) {
case CTRL_C:
*reason = sim_stopped;
! *sigrc = TARGET_SIGNAL_INT;
break;
case OK:
case TIME_OUT:
case BPT_HIT:
*reason = sim_stopped;
! *sigrc = TARGET_SIGNAL_TRAP;
break;
case ERROR:
*sigrc = 0;
*reason = sim_exited;
}
Index: sim/ppc/sim_calls.c
===================================================================
RCS file: /cvs/src/src/sim/ppc/sim_calls.c,v
retrieving revision 1.11
retrieving revision 1.11.10.1
diff -c -5 -p -r1.11 -r1.11.10.1
*** sim/ppc/sim_calls.c 11 Nov 2004 21:58:57 -0000 1.11
--- sim/ppc/sim_calls.c 17 Nov 2005 06:22:44 -0000 1.11.10.1
***************
*** 42,51 ****
--- 42,52 ----

#include "libiberty.h"
#include "bfd.h"
#include "gdb/callback.h"
#include "gdb/remote-sim.h"
+ #include "gdb/signals.h"

/* Define the rate at which the simulator should poll the host
for a quit. */
#ifndef POLL_QUIT_INTERVAL
#define POLL_QUIT_INTERVAL 0x20
*************** sim_stop_reason (SIM_DESC sd, enum sim_s
*** 195,211 ****

switch (status.reason) {
case was_continuing:
*reason = sim_stopped;
if (status.signal == 0)
! *sigrc = SIGTRAP;
else
*sigrc = status.signal;
break;
case was_trap:
*reason = sim_stopped;
! *sigrc = SIGTRAP;
break;
case was_exited:
*reason = sim_exited;
*sigrc = status.signal;
break;
--- 196,212 ----

switch (status.reason) {
case was_continuing:
*reason = sim_stopped;
if (status.signal == 0)
! *sigrc = TARGET_SIGNAL_TRAP;
else
*sigrc = status.signal;
break;
case was_trap:
*reason = sim_stopped;
! *sigrc = TARGET_SIGNAL_TRAP;
break;
case was_exited:
*reason = sim_exited;
*sigrc = status.signal;
break;