MIPS Linux signals

Michael Eager
2012-05-20T02:03:09Z

[-- Attachment #1: Type: text/plain, Size: 1612 bytes --]

MIPS Linux has different values assigned to signals than
X86 or PPC Linux. The result is that a SIGBUS on MIPS
(value 0xA) is reported as SIGUSR1, since that signal has
the that value on X86. This causes confusion (obviously).
Telling gdb to handle SIGUSR1 will cause it to respond to
SIGBUS but ignore SIGUSR1 (which has the value 0x16 on MIPS).

I didn't find a bug report for this in Bugzilla. I
have trouble believing that this problem has gone unnoticed.

The attached patch adds target_signal->internal_signal
translation, and vice versa, for MIPS Linux targets. I
adapted the code from target_symbol_from_host() and
do_target_symbol_to_host()in gdb/common/signals.c. Other
than being poor names, these functions and the wrappers
around them seem unnecessarily complicated. In particular,
I left out EXE_BAD_* translations because they appear to
be darwin-specific and translations for REALTIME_LO/HI
seem to be obsolete. ChangeLog-2006 mentions removing
these defines.

Which leads me to some questions:
1 -- Is there a bug report for this somewhere?
2 -- Is there any reason to implement EXE_BAD_* translations?
3 -- Is the REALTIME_LO/HI translation obsolete cruft?
4 -- Do the multiple layers of wrappers around target_
signal_{to,from}_host in signals.c serve any purpose?

I'm still testing the patch. I have a core file which now
displays the correct signal, but I have to create a test
program where I can test the translation in the other direction.

Any comments on the patch?

--
Michael Eager eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306 650-325-8077

[-- Attachment #2: mips-signal.patch --]
[-- Type: text/x-patch, Size: 7283 bytes --]

Index: gdb/gdb/mips-linux-tdep.c
===================================================================
--- gdb/.CC/cache/mips-linux-tdep.c@@/main/gdb_7_2_dev/3 2012-05-19 18:25:39.000077000 -0700
+++ gdb/mips-linux-tdep.c 2012-05-19 18:25:27.000033000 -0700
@@ -1130,6 +1130,101 @@ mips_linux_syscall_next_pc (struct frame
return pc + 4;
}

+/* Translate signals based on MIPS signal values.
+ Adapted from gdb/common/signals.c. */
+
+static enum target_signal
+mips_target_signal_from_host (struct gdbarch *gdbarch, int signo)
+{
+ printf ("MJE: mips_target_signal_from_host (<gdbarch>, signo=%d)\n", signo);
+
+ switch (signo) {
+ case 0: return TARGET_SIGNAL_0;
+ case MIPS_SIGHUP: return TARGET_SIGNAL_HUP;
+ case MIPS_SIGINT: return TARGET_SIGNAL_INT;
+ case MIPS_SIGQUIT: return TARGET_SIGNAL_QUIT;
+ case MIPS_SIGILL: return TARGET_SIGNAL_ILL;
+ case MIPS_SIGTRAP: return TARGET_SIGNAL_TRAP;
+ case MIPS_SIGABRT: return TARGET_SIGNAL_ABRT;
+ case MIPS_SIGEMT: return TARGET_SIGNAL_EMT;
+ case MIPS_SIGFPE: return TARGET_SIGNAL_FPE;
+ case MIPS_SIGKILL: return TARGET_SIGNAL_KILL;
+ case MIPS_SIGBUS: return TARGET_SIGNAL_BUS;
+ case MIPS_SIGSEGV: return TARGET_SIGNAL_SEGV;
+ case MIPS_SIGSYS: return TARGET_SIGNAL_SYS;
+ case MIPS_SIGPIPE: return TARGET_SIGNAL_PIPE;
+ case MIPS_SIGALRM: return TARGET_SIGNAL_ALRM;
+ case MIPS_SIGTERM: return TARGET_SIGNAL_TERM;
+ case MIPS_SIGUSR1: return TARGET_SIGNAL_USR1;
+ case MIPS_SIGUSR2: return TARGET_SIGNAL_USR2;
+ case MIPS_SIGCHLD: return TARGET_SIGNAL_CHLD;
+ case MIPS_SIGPWR: return TARGET_SIGNAL_PWR;
+ case MIPS_SIGWINCH: return TARGET_SIGNAL_WINCH;
+ case MIPS_SIGURG: return TARGET_SIGNAL_URG;
+ case MIPS_SIGPOLL: return TARGET_SIGNAL_POLL;
+ case MIPS_SIGSTOP: return TARGET_SIGNAL_STOP;
+ case MIPS_SIGTSTP: return TARGET_SIGNAL_TSTP;
+ case MIPS_SIGCONT: return TARGET_SIGNAL_CONT;
+ case MIPS_SIGTTIN: return TARGET_SIGNAL_TTIN;
+ case MIPS_SIGTTOU: return TARGET_SIGNAL_TTOU;
+ case MIPS_SIGVTALRM: return TARGET_SIGNAL_VTALRM;
+ case MIPS_SIGPROF: return TARGET_SIGNAL_PROF;
+ case MIPS_SIGXCPU: return TARGET_SIGNAL_XCPU;
+ case MIPS_SIGXFSZ: return TARGET_SIGNAL_XFSZ;
+ }
+
+#ifdef _SIG
+#endif
+
+ return TARGET_SIGNAL_UNKNOWN;
+}
+
+static int
+mips_target_signal_to_host (struct gdbarch *gdbarch, enum target_signal signo)
+{
+ printf ("MJE: mips_target_signal_to_host (<gdbarch>, signo=%d)\n", signo);
+
+ switch (signo) {
+ case TARGET_SIGNAL_0: return 0;
+ case TARGET_SIGNAL_HUP: return MIPS_SIGHUP;
+ case TARGET_SIGNAL_INT: return MIPS_SIGINT;
+ case TARGET_SIGNAL_QUIT: return MIPS_SIGQUIT;
+ case TARGET_SIGNAL_ILL: return MIPS_SIGILL;
+ case TARGET_SIGNAL_TRAP: return MIPS_SIGTRAP;
+ case TARGET_SIGNAL_ABRT: return MIPS_SIGABRT;
+ case TARGET_SIGNAL_EMT: return MIPS_SIGEMT;
+ case TARGET_SIGNAL_FPE: return MIPS_SIGFPE;
+ case TARGET_SIGNAL_KILL: return MIPS_SIGKILL;
+ case TARGET_SIGNAL_BUS: return MIPS_SIGBUS;
+ case TARGET_SIGNAL_SEGV: return MIPS_SIGSEGV;
+ case TARGET_SIGNAL_SYS: return MIPS_SIGSYS;
+ case TARGET_SIGNAL_PIPE: return MIPS_SIGPIPE;
+ case TARGET_SIGNAL_ALRM: return MIPS_SIGALRM;
+ case TARGET_SIGNAL_TERM: return MIPS_SIGTERM;
+ case TARGET_SIGNAL_USR1: return MIPS_SIGUSR1;
+ case TARGET_SIGNAL_USR2: return MIPS_SIGUSR2;
+ case TARGET_SIGNAL_CHLD: return MIPS_SIGCHLD;
+ case TARGET_SIGNAL_PWR: return MIPS_SIGPWR;
+ case TARGET_SIGNAL_WINCH: return MIPS_SIGWINCH;
+ case TARGET_SIGNAL_URG: return MIPS_SIGURG;
+ case TARGET_SIGNAL_POLL: return MIPS_SIGPOLL;
+ case TARGET_SIGNAL_STOP: return MIPS_SIGSTOP;
+ case TARGET_SIGNAL_TSTP: return MIPS_SIGTSTP;
+ case TARGET_SIGNAL_CONT: return MIPS_SIGCONT;
+ case TARGET_SIGNAL_TTIN: return MIPS_SIGTTIN;
+ case TARGET_SIGNAL_TTOU: return MIPS_SIGTTOU;
+ case TARGET_SIGNAL_VTALRM: return MIPS_SIGVTALRM;
+ case TARGET_SIGNAL_PROF: return MIPS_SIGPROF;
+ case TARGET_SIGNAL_XCPU: return MIPS_SIGXCPU;
+ case TARGET_SIGNAL_XFSZ: return MIPS_SIGXFSZ;
+
+ default:
+ warning ("Signal %s does not exist on this system.\n",
+ target_signal_to_name (signo));
+ return 0;
+ }
+}
+
/* Initialize one of the GNU/Linux OS ABIs. */

static void
@@ -1203,6 +1298,11 @@ mips_linux_init_abi (struct gdbarch_info
set_gdbarch_core_read_description (gdbarch,
mips_linux_core_read_description);

+ set_gdbarch_target_signal_from_host (gdbarch,
+ mips_target_signal_from_host);
+ set_gdbarch_target_signal_to_host (gdbarch,
+ mips_target_signal_to_host);
+
tdep->syscall_next_pc = mips_linux_syscall_next_pc;

if (tdesc_data)

Index: gdb/gdb/mips-linux-tdep.h
===================================================================
--- gdb/.CC/cache/mips-linux-tdep.h@@/main/gdb_7_2_dev/1 2012-05-19 18:25:40.000041000 -0700
+++ gdb/mips-linux-tdep.h 2012-05-19 10:53:12.000064000 -0700
@@ -100,3 +100,43 @@ enum {
/* Return 1 if MIPS_RESTART_REGNUM is usable. */

int mips_linux_restart_reg_p (struct gdbarch *gdbarch);
+
+/* MIPS Signals -- adapted from linux/arch/mips/include/asm/signal.h. */
+
+enum mips_signals {
+ MIPS_SIGHUP = 1, /* Hangup (POSIX). */
+ MIPS_SIGINT = 2, /* Interrupt (ANSI). */
+ MIPS_SIGQUIT = 3, /* Quit (POSIX). */
+ MIPS_SIGILL = 4, /* Illegal instruction (ANSI). */
+ MIPS_SIGTRAP = 5, /* Trace trap (POSIX). */
+ MIPS_SIGIOT = 6, /* IOT trap (4.2 BSD). */
+ MIPS_SIGABRT = MIPS_SIGIOT, /* Abort (ANSI). */
+ MIPS_SIGEMT = 7,
+ MIPS_SIGFPE = 8, /* Floating-point exception (ANSI). */
+ MIPS_SIGKILL = 9, /* Kill, unblockable (POSIX). */
+ MIPS_SIGBUS = 10, /* BUS error (4.2 BSD). */
+ MIPS_SIGSEGV = 11, /* Segmentation violation (ANSI). */
+ MIPS_SIGSYS = 12,
+ MIPS_SIGPIPE = 13, /* Broken pipe (POSIX). */
+ MIPS_SIGALRM = 14, /* Alarm clock (POSIX). */
+ MIPS_SIGTERM = 15, /* Termination (ANSI). */
+ MIPS_SIGUSR1 = 16, /* User-defined signal 1 (POSIX). */
+ MIPS_SIGUSR2 = 17, /* User-defined signal 2 (POSIX). */
+ MIPS_SIGCHLD = 18, /* Child status has changed (POSIX). */
+ MIPS_SIGCLD = MIPS_SIGCHLD, /* Same as SIGCHLD (System V). */
+ MIPS_SIGPWR = 19, /* Power failure restart (System V). */
+ MIPS_SIGWINCH = 20, /* Window size change (4.3 BSD, Sun). */
+ MIPS_SIGURG = 21, /* Urgent condition on socket (4.2 BSD). */
+ MIPS_SIGIO = 22, /* I/O now possible (4.2 BSD). */
+ MIPS_SIGPOLL = MIPS_SIGIO,/* Pollable event occurred (System V). */
+ MIPS_SIGSTOP = 23, /* Stop, unblockable (POSIX). */
+ MIPS_SIGTSTP = 24, /* Keyboard stop (POSIX). */
+ MIPS_SIGCONT = 25, /* Continue (POSIX). */
+ MIPS_SIGTTIN = 26, /* Background read from tty (POSIX). */
+ MIPS_SIGTTOU = 27, /* Background write to tty (POSIX). */
+ MIPS_SIGVTALRM= 28, /* Virtual alarm clock (4.2 BSD). */
+ MIPS_SIGPROF = 29, /* Profiling alarm clock (4.2 BSD). */
+ MIPS_SIGXCPU = 30, /* CPU limit exceeded (4.2 BSD). */
+ MIPS_SIGXFSZ = 31 /* File size limit exceeded (4.2 BSD). */
+ };
+