From mboxrd@z Thu Jan 1 00:00:00 1970 From: Daniel Jacobowitz To: gdb-patches@sources.redhat.com Subject: [rfa] gdbserver 2/n - signals Date: Thu, 19 Jul 2001 12:01:00 -0000 Message-id: <20010719120143.A19963@nevyn.them.org> X-SW-Source: 2001-07/msg00479.html This updates the remote protocol documentation and the gdbserver signal code so that signals are converted properly before being sent. The documentation needs (a lot) more work; this doc change is mostly to remind me to revisit the Protocol node later. -- Daniel Jacobowitz Carnegie Mellon University MontaVista Software Debian GNU/Linux Developer 2001-07-19 Daniel Jacobowitz * gdbserver/server.c (main): Call target_signal_to_host_p and target_signal_to_host on signals received from the remote. * gdbserver/remote-utils.c (prepare_resume_reply): Call target_signal_from_host on signals sent to the remote. * gdbserver/signals.c: New file. * gdbserver/Makefile.in: Add signals.o. 2001-07-19 Daniel Jacobowitz * gdb.texinfo (Protocol): Mention that signal numbers are defined by the target_signal enum. --- server.c Thu Jul 19 11:44:35 2001 +++ server.c Thu Jul 19 11:47:02 2001 @@ -130,13 +133,21 @@ break; case 'C': convert_ascii_to_int (own_buf + 1, &sig, 1); - myresume (0, sig); + if (target_signal_to_host_p (sig)) + signal = target_signal_to_host (sig); + else + signal = 0; + myresume (0, signal); signal = mywait (&status); prepare_resume_reply (own_buf, status, signal); break; case 'S': convert_ascii_to_int (own_buf + 1, &sig, 1); - myresume (1, sig); + if (target_signal_to_host_p (sig)) + signal = target_signal_to_host (sig); + else + signal = 0; + myresume (1, signal); signal = mywait (&status); prepare_resume_reply (own_buf, status, signal); break; --- /dev/null Wed Dec 31 16:00:00 1969 +++ signals.c Tue Jul 17 13:48:06 2001 @@ -0,0 +1,589 @@ +/* Functions to convert to and from the target signal protocol. + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + 2000, 2001 Free Software Foundation, Inc. + Contributed by Cygnus Support. + + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "target.h" + +#include + +/* Convert host signal to our signals. */ +enum target_signal +target_signal_from_host (int hostsig) +{ + /* A switch statement would make sense but would require special kludges + to deal with the cases where more than one signal has the same number. */ + + if (hostsig == 0) + return TARGET_SIGNAL_0; + +#if defined (SIGHUP) + if (hostsig == SIGHUP) + return TARGET_SIGNAL_HUP; +#endif +#if defined (SIGINT) + if (hostsig == SIGINT) + return TARGET_SIGNAL_INT; +#endif +#if defined (SIGQUIT) + if (hostsig == SIGQUIT) + return TARGET_SIGNAL_QUIT; +#endif +#if defined (SIGILL) + if (hostsig == SIGILL) + return TARGET_SIGNAL_ILL; +#endif +#if defined (SIGTRAP) + if (hostsig == SIGTRAP) + return TARGET_SIGNAL_TRAP; +#endif +#if defined (SIGABRT) + if (hostsig == SIGABRT) + return TARGET_SIGNAL_ABRT; +#endif +#if defined (SIGEMT) + if (hostsig == SIGEMT) + return TARGET_SIGNAL_EMT; +#endif +#if defined (SIGFPE) + if (hostsig == SIGFPE) + return TARGET_SIGNAL_FPE; +#endif +#if defined (SIGKILL) + if (hostsig == SIGKILL) + return TARGET_SIGNAL_KILL; +#endif +#if defined (SIGBUS) + if (hostsig == SIGBUS) + return TARGET_SIGNAL_BUS; +#endif +#if defined (SIGSEGV) + if (hostsig == SIGSEGV) + return TARGET_SIGNAL_SEGV; +#endif +#if defined (SIGSYS) + if (hostsig == SIGSYS) + return TARGET_SIGNAL_SYS; +#endif +#if defined (SIGPIPE) + if (hostsig == SIGPIPE) + return TARGET_SIGNAL_PIPE; +#endif +#if defined (SIGALRM) + if (hostsig == SIGALRM) + return TARGET_SIGNAL_ALRM; +#endif +#if defined (SIGTERM) + if (hostsig == SIGTERM) + return TARGET_SIGNAL_TERM; +#endif +#if defined (SIGUSR1) + if (hostsig == SIGUSR1) + return TARGET_SIGNAL_USR1; +#endif +#if defined (SIGUSR2) + if (hostsig == SIGUSR2) + return TARGET_SIGNAL_USR2; +#endif +#if defined (SIGCLD) + if (hostsig == SIGCLD) + return TARGET_SIGNAL_CHLD; +#endif +#if defined (SIGCHLD) + if (hostsig == SIGCHLD) + return TARGET_SIGNAL_CHLD; +#endif +#if defined (SIGPWR) + if (hostsig == SIGPWR) + return TARGET_SIGNAL_PWR; +#endif +#if defined (SIGWINCH) + if (hostsig == SIGWINCH) + return TARGET_SIGNAL_WINCH; +#endif +#if defined (SIGURG) + if (hostsig == SIGURG) + return TARGET_SIGNAL_URG; +#endif +#if defined (SIGIO) + if (hostsig == SIGIO) + return TARGET_SIGNAL_IO; +#endif +#if defined (SIGPOLL) + if (hostsig == SIGPOLL) + return TARGET_SIGNAL_POLL; +#endif +#if defined (SIGSTOP) + if (hostsig == SIGSTOP) + return TARGET_SIGNAL_STOP; +#endif +#if defined (SIGTSTP) + if (hostsig == SIGTSTP) + return TARGET_SIGNAL_TSTP; +#endif +#if defined (SIGCONT) + if (hostsig == SIGCONT) + return TARGET_SIGNAL_CONT; +#endif +#if defined (SIGTTIN) + if (hostsig == SIGTTIN) + return TARGET_SIGNAL_TTIN; +#endif +#if defined (SIGTTOU) + if (hostsig == SIGTTOU) + return TARGET_SIGNAL_TTOU; +#endif +#if defined (SIGVTALRM) + if (hostsig == SIGVTALRM) + return TARGET_SIGNAL_VTALRM; +#endif +#if defined (SIGPROF) + if (hostsig == SIGPROF) + return TARGET_SIGNAL_PROF; +#endif +#if defined (SIGXCPU) + if (hostsig == SIGXCPU) + return TARGET_SIGNAL_XCPU; +#endif +#if defined (SIGXFSZ) + if (hostsig == SIGXFSZ) + return TARGET_SIGNAL_XFSZ; +#endif +#if defined (SIGWIND) + if (hostsig == SIGWIND) + return TARGET_SIGNAL_WIND; +#endif +#if defined (SIGPHONE) + if (hostsig == SIGPHONE) + return TARGET_SIGNAL_PHONE; +#endif +#if defined (SIGLOST) + if (hostsig == SIGLOST) + return TARGET_SIGNAL_LOST; +#endif +#if defined (SIGWAITING) + if (hostsig == SIGWAITING) + return TARGET_SIGNAL_WAITING; +#endif +#if defined (SIGCANCEL) + if (hostsig == SIGCANCEL) + return TARGET_SIGNAL_CANCEL; +#endif +#if defined (SIGLWP) + if (hostsig == SIGLWP) + return TARGET_SIGNAL_LWP; +#endif +#if defined (SIGDANGER) + if (hostsig == SIGDANGER) + return TARGET_SIGNAL_DANGER; +#endif +#if defined (SIGGRANT) + if (hostsig == SIGGRANT) + return TARGET_SIGNAL_GRANT; +#endif +#if defined (SIGRETRACT) + if (hostsig == SIGRETRACT) + return TARGET_SIGNAL_RETRACT; +#endif +#if defined (SIGMSG) + if (hostsig == SIGMSG) + return TARGET_SIGNAL_MSG; +#endif +#if defined (SIGSOUND) + if (hostsig == SIGSOUND) + return TARGET_SIGNAL_SOUND; +#endif +#if defined (SIGSAK) + if (hostsig == SIGSAK) + return TARGET_SIGNAL_SAK; +#endif +#if defined (SIGPRIO) + if (hostsig == SIGPRIO) + return TARGET_SIGNAL_PRIO; +#endif + + /* Mach exceptions. Assumes that the values for EXC_ are positive! */ +#if defined (EXC_BAD_ACCESS) && defined (_NSIG) + if (hostsig == _NSIG + EXC_BAD_ACCESS) + return TARGET_EXC_BAD_ACCESS; +#endif +#if defined (EXC_BAD_INSTRUCTION) && defined (_NSIG) + if (hostsig == _NSIG + EXC_BAD_INSTRUCTION) + return TARGET_EXC_BAD_INSTRUCTION; +#endif +#if defined (EXC_ARITHMETIC) && defined (_NSIG) + if (hostsig == _NSIG + EXC_ARITHMETIC) + return TARGET_EXC_ARITHMETIC; +#endif +#if defined (EXC_EMULATION) && defined (_NSIG) + if (hostsig == _NSIG + EXC_EMULATION) + return TARGET_EXC_EMULATION; +#endif +#if defined (EXC_SOFTWARE) && defined (_NSIG) + if (hostsig == _NSIG + EXC_SOFTWARE) + return TARGET_EXC_SOFTWARE; +#endif +#if defined (EXC_BREAKPOINT) && defined (_NSIG) + if (hostsig == _NSIG + EXC_BREAKPOINT) + return TARGET_EXC_BREAKPOINT; +#endif + +#if defined (SIGINFO) + if (hostsig == SIGINFO) + return TARGET_SIGNAL_INFO; +#endif + +#if defined (REALTIME_LO) + if (hostsig >= REALTIME_LO && hostsig < REALTIME_HI) + { + /* This block of TARGET_SIGNAL_REALTIME value is in order. */ + if (33 <= hostsig && hostsig <= 63) + return (enum target_signal) + (hostsig - 33 + (int) TARGET_SIGNAL_REALTIME_33); + else if (hostsig == 32) + return TARGET_SIGNAL_REALTIME_32; + else if (64 <= hostsig && hostsig <= 127) + return (enum target_signal) + (hostsig - 64 + (int) TARGET_SIGNAL_REALTIME_64); + else + error ("GDB bug: target.c (target_signal_from_host): unrecognized real-time signal"); + } +#endif + +#if defined (SIGRTMIN) + if (hostsig >= SIGRTMIN && hostsig <= SIGRTMAX) + { + /* This block of TARGET_SIGNAL_REALTIME value is in order. */ + if (33 <= hostsig && hostsig <= 63) + return (enum target_signal) + (hostsig - 33 + (int) TARGET_SIGNAL_REALTIME_33); + else if (hostsig == 64) + return TARGET_SIGNAL_REALTIME_64; + else + error ("GDB bug: target.c (target_signal_from_host): unrecognized real-time signal"); + } +#endif + return TARGET_SIGNAL_UNKNOWN; +} + +/* Convert a OURSIG (an enum target_signal) to the form used by the + target operating system (refered to as the ``host'') or zero if the + equivalent host signal is not available. Set/clear OURSIG_OK + accordingly. */ + +static int +do_target_signal_to_host (enum target_signal oursig, + int *oursig_ok) +{ + *oursig_ok = 1; + switch (oursig) + { + case TARGET_SIGNAL_0: + return 0; + +#if defined (SIGHUP) + case TARGET_SIGNAL_HUP: + return SIGHUP; +#endif +#if defined (SIGINT) + case TARGET_SIGNAL_INT: + return SIGINT; +#endif +#if defined (SIGQUIT) + case TARGET_SIGNAL_QUIT: + return SIGQUIT; +#endif +#if defined (SIGILL) + case TARGET_SIGNAL_ILL: + return SIGILL; +#endif +#if defined (SIGTRAP) + case TARGET_SIGNAL_TRAP: + return SIGTRAP; +#endif +#if defined (SIGABRT) + case TARGET_SIGNAL_ABRT: + return SIGABRT; +#endif +#if defined (SIGEMT) + case TARGET_SIGNAL_EMT: + return SIGEMT; +#endif +#if defined (SIGFPE) + case TARGET_SIGNAL_FPE: + return SIGFPE; +#endif +#if defined (SIGKILL) + case TARGET_SIGNAL_KILL: + return SIGKILL; +#endif +#if defined (SIGBUS) + case TARGET_SIGNAL_BUS: + return SIGBUS; +#endif +#if defined (SIGSEGV) + case TARGET_SIGNAL_SEGV: + return SIGSEGV; +#endif +#if defined (SIGSYS) + case TARGET_SIGNAL_SYS: + return SIGSYS; +#endif +#if defined (SIGPIPE) + case TARGET_SIGNAL_PIPE: + return SIGPIPE; +#endif +#if defined (SIGALRM) + case TARGET_SIGNAL_ALRM: + return SIGALRM; +#endif +#if defined (SIGTERM) + case TARGET_SIGNAL_TERM: + return SIGTERM; +#endif +#if defined (SIGUSR1) + case TARGET_SIGNAL_USR1: + return SIGUSR1; +#endif +#if defined (SIGUSR2) + case TARGET_SIGNAL_USR2: + return SIGUSR2; +#endif +#if defined (SIGCHLD) || defined (SIGCLD) + case TARGET_SIGNAL_CHLD: +#if defined (SIGCHLD) + return SIGCHLD; +#else + return SIGCLD; +#endif +#endif /* SIGCLD or SIGCHLD */ +#if defined (SIGPWR) + case TARGET_SIGNAL_PWR: + return SIGPWR; +#endif +#if defined (SIGWINCH) + case TARGET_SIGNAL_WINCH: + return SIGWINCH; +#endif +#if defined (SIGURG) + case TARGET_SIGNAL_URG: + return SIGURG; +#endif +#if defined (SIGIO) + case TARGET_SIGNAL_IO: + return SIGIO; +#endif +#if defined (SIGPOLL) + case TARGET_SIGNAL_POLL: + return SIGPOLL; +#endif +#if defined (SIGSTOP) + case TARGET_SIGNAL_STOP: + return SIGSTOP; +#endif +#if defined (SIGTSTP) + case TARGET_SIGNAL_TSTP: + return SIGTSTP; +#endif +#if defined (SIGCONT) + case TARGET_SIGNAL_CONT: + return SIGCONT; +#endif +#if defined (SIGTTIN) + case TARGET_SIGNAL_TTIN: + return SIGTTIN; +#endif +#if defined (SIGTTOU) + case TARGET_SIGNAL_TTOU: + return SIGTTOU; +#endif +#if defined (SIGVTALRM) + case TARGET_SIGNAL_VTALRM: + return SIGVTALRM; +#endif +#if defined (SIGPROF) + case TARGET_SIGNAL_PROF: + return SIGPROF; +#endif +#if defined (SIGXCPU) + case TARGET_SIGNAL_XCPU: + return SIGXCPU; +#endif +#if defined (SIGXFSZ) + case TARGET_SIGNAL_XFSZ: + return SIGXFSZ; +#endif +#if defined (SIGWIND) + case TARGET_SIGNAL_WIND: + return SIGWIND; +#endif +#if defined (SIGPHONE) + case TARGET_SIGNAL_PHONE: + return SIGPHONE; +#endif +#if defined (SIGLOST) + case TARGET_SIGNAL_LOST: + return SIGLOST; +#endif +#if defined (SIGWAITING) + case TARGET_SIGNAL_WAITING: + return SIGWAITING; +#endif +#if defined (SIGCANCEL) + case TARGET_SIGNAL_CANCEL: + return SIGCANCEL; +#endif +#if defined (SIGLWP) + case TARGET_SIGNAL_LWP: + return SIGLWP; +#endif +#if defined (SIGDANGER) + case TARGET_SIGNAL_DANGER: + return SIGDANGER; +#endif +#if defined (SIGGRANT) + case TARGET_SIGNAL_GRANT: + return SIGGRANT; +#endif +#if defined (SIGRETRACT) + case TARGET_SIGNAL_RETRACT: + return SIGRETRACT; +#endif +#if defined (SIGMSG) + case TARGET_SIGNAL_MSG: + return SIGMSG; +#endif +#if defined (SIGSOUND) + case TARGET_SIGNAL_SOUND: + return SIGSOUND; +#endif +#if defined (SIGSAK) + case TARGET_SIGNAL_SAK: + return SIGSAK; +#endif +#if defined (SIGPRIO) + case TARGET_SIGNAL_PRIO: + return SIGPRIO; +#endif + + /* Mach exceptions. Assumes that the values for EXC_ are positive! */ +#if defined (EXC_BAD_ACCESS) && defined (_NSIG) + case TARGET_EXC_BAD_ACCESS: + return _NSIG + EXC_BAD_ACCESS; +#endif +#if defined (EXC_BAD_INSTRUCTION) && defined (_NSIG) + case TARGET_EXC_BAD_INSTRUCTION: + return _NSIG + EXC_BAD_INSTRUCTION; +#endif +#if defined (EXC_ARITHMETIC) && defined (_NSIG) + case TARGET_EXC_ARITHMETIC: + return _NSIG + EXC_ARITHMETIC; +#endif +#if defined (EXC_EMULATION) && defined (_NSIG) + case TARGET_EXC_EMULATION: + return _NSIG + EXC_EMULATION; +#endif +#if defined (EXC_SOFTWARE) && defined (_NSIG) + case TARGET_EXC_SOFTWARE: + return _NSIG + EXC_SOFTWARE; +#endif +#if defined (EXC_BREAKPOINT) && defined (_NSIG) + case TARGET_EXC_BREAKPOINT: + return _NSIG + EXC_BREAKPOINT; +#endif + +#if defined (SIGINFO) + case TARGET_SIGNAL_INFO: + return SIGINFO; +#endif + + default: +#if defined (REALTIME_LO) + if (oursig >= TARGET_SIGNAL_REALTIME_33 + && oursig <= TARGET_SIGNAL_REALTIME_63) + { + /* This block of signals is continuous, and + TARGET_SIGNAL_REALTIME_33 is 33 by definition. */ + int retsig = + (int) oursig - (int) TARGET_SIGNAL_REALTIME_33 + 33; + if (retsig >= REALTIME_LO && retsig < REALTIME_HI) + return retsig; + } +#if (REALTIME_LO < 33) + else if (oursig == TARGET_SIGNAL_REALTIME_32) + { + /* TARGET_SIGNAL_REALTIME_32 isn't contiguous with + TARGET_SIGNAL_REALTIME_33. It is 32 by definition. */ + return 32; + } +#endif +#if (REALTIME_HI > 64) + if (oursig >= TARGET_SIGNAL_REALTIME_64 + && oursig <= TARGET_SIGNAL_REALTIME_127) + { + /* This block of signals is continuous, and + TARGET_SIGNAL_REALTIME_64 is 64 by definition. */ + int retsig = + (int) oursig - (int) TARGET_SIGNAL_REALTIME_64 + 64; + if (retsig >= REALTIME_LO && retsig < REALTIME_HI) + return retsig; + } + +#endif +#endif + +#if defined (SIGRTMIN) + if (oursig >= TARGET_SIGNAL_REALTIME_33 + && oursig <= TARGET_SIGNAL_REALTIME_63) + { + /* This block of signals is continuous, and + TARGET_SIGNAL_REALTIME_33 is 33 by definition. */ + int retsig = + (int) oursig - (int) TARGET_SIGNAL_REALTIME_33 + 33; + if (retsig >= SIGRTMIN && retsig <= SIGRTMAX) + return retsig; + } + else if (oursig == TARGET_SIGNAL_REALTIME_64) + return 64; +#endif + *oursig_ok = 0; + return 0; + } +} + +int +target_signal_to_host_p (enum target_signal oursig) +{ + int oursig_ok; + do_target_signal_to_host (oursig, &oursig_ok); + return oursig_ok; +} + +int +target_signal_to_host (enum target_signal oursig) +{ + int oursig_ok; + int targ_signo = do_target_signal_to_host (oursig, &oursig_ok); + if (!oursig_ok) + return 0; + else + return targ_signo; +} Index: remote-utils.c =================================================================== RCS file: /cvs/src/src/gdb/gdbserver/remote-utils.c,v retrieving revision 1.7 diff -u -r1.7 remote-utils.c --- remote-utils.c 2001/07/12 21:04:35 1.7 +++ remote-utils.c 2001/07/19 18:50:33 @@ -459,17 +459,15 @@ void prepare_resume_reply (char *buf, char status, unsigned char signo) { - int nib; + int nib, sig; *buf++ = status; - /* FIXME! Should be converting this signal number (numbered - according to the signal numbering of the system we are running on) - to the signal numbers used by the gdb protocol (see enum target_signal - in gdb/target.h). */ - nib = ((signo & 0xf0) >> 4); + sig = (int)target_signal_from_host (signo); + + nib = ((sig & 0xf0) >> 4); *buf++ = tohex (nib); - nib = signo & 0x0f; + nib = sig & 0x0f; *buf++ = tohex (nib); if (status == 'T') Index: Makefile.in =================================================================== RCS file: /cvs/src/src/gdb/gdbserver/Makefile.in,v retrieving revision 1.3 diff -u -r1.3 Makefile.in --- Makefile.in 2001/03/06 08:21:43 1.3 +++ Makefile.in 2001/07/19 18:51:48 @@ -137,7 +137,7 @@ SOURCES = $(SFILES) $(ALLDEPFILES) TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS} -OBS = utils.o $(GDBSERVER_DEPFILES) server.o remote-utils.o +OBS = utils.o $(GDBSERVER_DEPFILES) server.o remote-utils.o signals.o # Prevent Sun make from putting in the machine type. Setting # TARGET_ARCH to nothing works for SunOS 3, 4.0, but not for 4.1. Index: gdb.texinfo =================================================================== RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v retrieving revision 1.44 diff -u -r1.44 gdb.texinfo --- gdb.texinfo 2001/07/06 04:07:29 1.44 +++ gdb.texinfo 2001/07/19 18:56:55 @@ -10211,8 +10211,8 @@ receive any of the below as a reply. In the case of the @samp{C}, @samp{c}, @samp{S} and @samp{s} packets, that reply is only returned when the target halts. In the below the exact meaning of @samp{signal -number} is poorly defined. In general one of the UNIX signal numbering -conventions is used. +number} is defined by the type @code{enum target_signal}. For the most +common signals this corresponds to the UNIX signal numbering conventions. @multitable @columnfractions .4 .6