]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
This patch implements the new gdbarch method gdbarch_gdb_signal_to_target.
authorSergio Durigan Junior <sergiodj@redhat.com>
Fri, 9 Aug 2013 16:54:43 +0000 (16:54 +0000)
committerSergio Durigan Junior <sergiodj@redhat.com>
Fri, 9 Aug 2013 16:54:43 +0000 (16:54 +0000)
It will be used when one wants to convert between the internal GDB signal
representation (enum gdb_signal) and the target's representation.

The idea of this patch came from a chat between Pedro and I on IRC, plus
the discussion of my patches to add the new $_exitsignal convenience
variable:

<http://sourceware.org/ml/gdb-patches/2013-06/msg00452.html>
<http://sourceware.org/ml/gdb-patches/2013-06/msg00352.html>

What I did was to investigate, on the Linux kernel, which targets shared
the signal numbers definition with the generic definition, present at
<include/uapi/asm-generic/signal.h>.  For the record, I used linux-3.10-rc7
as the main source of information, always looking at
<arch/<ARCH_NAME>/include/uapi/asm/signal.h>.  For SIGRTMAX (which defaults
to _NSIG in most cases), I had to look at different signal-related
files, but most of them (except MIPS) were defined to 64 anyway.

Then, with all the differences in hand, I implemented the bits on each
target.

2013-08-09  Sergio Durigan Junior  <sergiodj@redhat.com>

* linux-tdep.c: Define enum with generic signal numbers.
(linux_gdb_signal_from_target): New function.
(linux_gdb_signal_to_target): Likewise.
(linux_init_abi): Set gdbarch_gdb_signal_{to,from}_target
methods to the functions above.
* linux-tdep.h (linux_gdb_signal_from_target): New prototype.
(linux_gdb_signal_to_target): Likewise.
* alpha-linux-tdep.c: Define new enum with signals different
from generic Linux kernel.
(alpha_linux_gdb_signal_from_target): New function.
(alpha_linux_gdb_signal_to_target): Likewise.
(alpha_linux_init_abi): Set gdbarch_gdb_signal_{to,from}_target
with the functions mentioned above.
* avr-tdep.c: Define enum with differences between Linux kernel
and AVR signals.
(avr_linux_gdb_signal_from_target): New function.
(avr_linux_gdb_signal_to_target): Likewise.
(avr_gdbarch_init): Set gdbarch_gdb_signal_{to,from}_target to
the functions mentioned above.
* sparc-linux-tdep.c: Define enum with differences between SPARC
and generic Linux kernel signal numbers.
(sparc32_linux_gdb_signal_from_target): New function.
(sparc32_linux_gdb_signal_to_target): Likewise.
(sparc32_linux_init_abi): Set gdbarch_gdb_signal_{to,from}_target
to the functions defined above.
* xtensa-linux-tdep.c: Define enum with differences between
Xtensa and Linux kernel generic signals.
(xtensa_linux_gdb_signal_from_target): New function.
(xtensa_linux_gdb_signal_to_target): Likewise.
(xtensa_linux_init_abi): Set gdbarch_gdb_signal_to_target
to the functions defined above.
* mips-linux-tdep.c: Define enum with differences between
signals in MIPS and Linux kernel generic ones.
(mips_gdb_signal_to_target): New function.
(mips_gdb_signal_from_target): Redefine to use new enum, handle
only different signals from the Linux kernel generic.
(mips_linux_init_abi): Set gdbarch_gdb_signal_{to,from}_target
the functions defined above.
* mips-linux-tdep.h (enum mips_signals): Remove.

12 files changed:
gdb/ChangeLog
gdb/alpha-linux-tdep.c
gdb/avr-tdep.c
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh
gdb/linux-tdep.c
gdb/linux-tdep.h
gdb/mips-linux-tdep.c
gdb/mips-linux-tdep.h
gdb/sparc-linux-tdep.c
gdb/xtensa-linux-tdep.c

index 469678f0e5650ecc0a63930e2c4e1f2440c07c8e..9e99003ca6543f99f2e02688f9f51ecb7ee7a3b9 100644 (file)
@@ -1,3 +1,45 @@
+2013-08-09  Sergio Durigan Junior  <sergiodj@redhat.com>
+
+       * linux-tdep.c: Define enum with generic signal numbers.
+       (linux_gdb_signal_from_target): New function.
+       (linux_gdb_signal_to_target): Likewise.
+       (linux_init_abi): Set gdbarch_gdb_signal_{to,from}_target
+       methods to the functions above.
+       * linux-tdep.h (linux_gdb_signal_from_target): New prototype.
+       (linux_gdb_signal_to_target): Likewise.
+       * alpha-linux-tdep.c: Define new enum with signals different
+       from generic Linux kernel.
+       (alpha_linux_gdb_signal_from_target): New function.
+       (alpha_linux_gdb_signal_to_target): Likewise.
+       (alpha_linux_init_abi): Set gdbarch_gdb_signal_{to,from}_target
+       with the functions mentioned above.
+       * avr-tdep.c: Define enum with differences between Linux kernel
+       and AVR signals.
+       (avr_linux_gdb_signal_from_target): New function.
+       (avr_linux_gdb_signal_to_target): Likewise.
+       (avr_gdbarch_init): Set gdbarch_gdb_signal_{to,from}_target to
+       the functions mentioned above.
+       * sparc-linux-tdep.c: Define enum with differences between SPARC
+       and generic Linux kernel signal numbers.
+       (sparc32_linux_gdb_signal_from_target): New function.
+       (sparc32_linux_gdb_signal_to_target): Likewise.
+       (sparc32_linux_init_abi): Set gdbarch_gdb_signal_{to,from}_target
+       to the functions defined above.
+       * xtensa-linux-tdep.c: Define enum with differences between
+       Xtensa and Linux kernel generic signals.
+       (xtensa_linux_gdb_signal_from_target): New function.
+       (xtensa_linux_gdb_signal_to_target): Likewise.
+       (xtensa_linux_init_abi): Set gdbarch_gdb_signal_to_target
+       to the functions defined above.
+       * mips-linux-tdep.c: Define enum with differences between
+       signals in MIPS and Linux kernel generic ones.
+       (mips_gdb_signal_to_target): New function.
+       (mips_gdb_signal_from_target): Redefine to use new enum, handle
+       only different signals from the Linux kernel generic.
+       (mips_linux_init_abi): Set gdbarch_gdb_signal_{to,from}_target
+       the functions defined above.
+       * mips-linux-tdep.h (enum mips_signals): Remove.
+
 2013-08-09  Pedro Alves  <palves@redhat.com>
 
        * avr-tdep.c (XMALLOC): Delete macro.
index 9efc5bd6fe9932fd0235002b60d38a39cd297ad2..8cb087ee47676c8f6a46ff4be25f8d0491abd310 100644 (file)
 #include "linux-tdep.h"
 #include "alpha-tdep.h"
 
+/* This enum represents the signals' numbers on the Alpha
+   architecture.  It just contains the signal definitions which are
+   different from the generic implementation.
+
+   It is derived from the file <arch/alpha/include/uapi/asm/signal.h>,
+   from the Linux kernel tree.  */
+
+enum
+  {
+    /* SIGABRT is the same as in the generic implementation, but is
+       defined here because SIGIOT depends on it.  */
+    ALPHA_LINUX_SIGABRT = 6,
+    ALPHA_LINUX_SIGEMT = 7,
+    ALPHA_LINUX_SIGBUS = 10,
+    ALPHA_LINUX_SIGSYS = 12,
+    ALPHA_LINUX_SIGURG = 16,
+    ALPHA_LINUX_SIGSTOP = 17,
+    ALPHA_LINUX_SIGTSTP = 18,
+    ALPHA_LINUX_SIGCONT = 19,
+    ALPHA_LINUX_SIGCHLD = 20,
+    ALPHA_LINUX_SIGIO = 23,
+    ALPHA_LINUX_SIGINFO = 29,
+    ALPHA_LINUX_SIGUSR1 = 30,
+    ALPHA_LINUX_SIGUSR2 = 31,
+    ALPHA_LINUX_SIGPOLL = ALPHA_LINUX_SIGIO,
+    ALPHA_LINUX_SIGPWR = ALPHA_LINUX_SIGINFO,
+    ALPHA_LINUX_SIGIOT = ALPHA_LINUX_SIGABRT,
+  };
+
 /* Under GNU/Linux, signal handler invocations can be identified by
    the designated code sequence that is used to return from a signal
    handler.  In particular, the return address of a signal handler
@@ -205,6 +234,114 @@ alpha_linux_regset_from_core_section (struct gdbarch *gdbarch,
   return NULL;
 }
 
+/* Implementation of `gdbarch_gdb_signal_from_target', as defined in
+   gdbarch.h.  */
+
+static enum gdb_signal
+alpha_linux_gdb_signal_from_target (struct gdbarch *gdbarch,
+                                   int signal)
+{
+  switch (signal)
+    {
+    case ALPHA_LINUX_SIGEMT:
+      return GDB_SIGNAL_EMT;
+
+    case ALPHA_LINUX_SIGBUS:
+      return GDB_SIGNAL_BUS;
+
+    case ALPHA_LINUX_SIGSYS:
+      return GDB_SIGNAL_SYS;
+
+    case ALPHA_LINUX_SIGURG:
+      return GDB_SIGNAL_URG;
+
+    case ALPHA_LINUX_SIGSTOP:
+      return GDB_SIGNAL_STOP;
+
+    case ALPHA_LINUX_SIGTSTP:
+      return GDB_SIGNAL_TSTP;
+
+    case ALPHA_LINUX_SIGCONT:
+      return GDB_SIGNAL_CONT;
+
+    case ALPHA_LINUX_SIGCHLD:
+      return GDB_SIGNAL_CHLD;
+
+    /* No way to differentiate between SIGIO and SIGPOLL.
+       Therefore, we just handle the first one.  */
+    case ALPHA_LINUX_SIGIO:
+      return GDB_SIGNAL_IO;
+
+    /* No way to differentiate between SIGINFO and SIGPWR.
+       Therefore, we just handle the first one.  */
+    case ALPHA_LINUX_SIGINFO:
+      return GDB_SIGNAL_INFO;
+
+    case ALPHA_LINUX_SIGUSR1:
+      return GDB_SIGNAL_USR1;
+
+    case ALPHA_LINUX_SIGUSR2:
+      return GDB_SIGNAL_USR2;
+    }
+
+  return linux_gdb_signal_from_target (gdbarch, signal);
+}
+
+/* Implementation of `gdbarch_gdb_signal_to_target', as defined in
+   gdbarch.h.  */
+
+static int
+alpha_linux_gdb_signal_to_target (struct gdbarch *gdbarch,
+                                 enum gdb_signal signal)
+{
+  switch (signal)
+    {
+    case GDB_SIGNAL_EMT:
+      return ALPHA_LINUX_SIGEMT;
+
+    case GDB_SIGNAL_BUS:
+      return ALPHA_LINUX_SIGBUS;
+
+    case GDB_SIGNAL_SYS:
+      return ALPHA_LINUX_SIGSYS;
+
+    case GDB_SIGNAL_URG:
+      return ALPHA_LINUX_SIGURG;
+
+    case GDB_SIGNAL_STOP:
+      return ALPHA_LINUX_SIGSTOP;
+
+    case GDB_SIGNAL_TSTP:
+      return ALPHA_LINUX_SIGTSTP;
+
+    case GDB_SIGNAL_CONT:
+      return ALPHA_LINUX_SIGCONT;
+
+    case GDB_SIGNAL_CHLD:
+      return ALPHA_LINUX_SIGCHLD;
+
+    case GDB_SIGNAL_IO:
+      return ALPHA_LINUX_SIGIO;
+
+    case GDB_SIGNAL_INFO:
+      return ALPHA_LINUX_SIGINFO;
+
+    case GDB_SIGNAL_USR1:
+      return ALPHA_LINUX_SIGUSR1;
+
+    case GDB_SIGNAL_USR2:
+      return ALPHA_LINUX_SIGUSR2;
+
+    case GDB_SIGNAL_POLL:
+      return ALPHA_LINUX_SIGPOLL;
+
+    case GDB_SIGNAL_PWR:
+      return ALPHA_LINUX_SIGPWR;
+    }
+
+  return linux_gdb_signal_to_target (gdbarch, signal);
+}
+
 static void
 alpha_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -236,6 +373,11 @@ alpha_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   set_gdbarch_regset_from_core_section
     (gdbarch, alpha_linux_regset_from_core_section);
+
+  set_gdbarch_gdb_signal_from_target (gdbarch,
+                                     alpha_linux_gdb_signal_from_target);
+  set_gdbarch_gdb_signal_to_target (gdbarch,
+                                   alpha_linux_gdb_signal_to_target);
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
index fc4e0f062dfe9662f1071d958d5bb31483df24f6..6beac3d1bbb20b161e5343604f191b9b3993ffd1 100644 (file)
@@ -36,6 +36,7 @@
 #include "regcache.h"
 #include "gdb_string.h"
 #include "dis-asm.h"
+#include "linux-tdep.h"
 
 /* AVR Background:
 
@@ -190,6 +191,19 @@ struct gdbarch_tdep
   struct type *pc_type;
 };
 
+/* This enum represents the signals' numbers on the AVR
+   architecture.  It just contains the signal definitions which are
+   different from the generic implementation.
+
+   It is derived from the file <arch/avr32/include/uapi/asm/signal.h>,
+   from the Linux kernel tree.  */
+
+enum
+  {
+    AVR_LINUX_SIGRTMIN = 32,
+    AVR_LINUX_SIGRTMAX = 63,
+  };
+
 /* Lookup the name of a register given it's number.  */
 
 static const char *
@@ -1341,6 +1355,60 @@ avr_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
   return -1;
 }
 
+/* Implementation of `gdbarch_gdb_signal_from_target', as defined in
+   gdbarch.h.  */
+
+static enum gdb_signal
+avr_linux_gdb_signal_from_target (struct gdbarch *gdbarch, int signal)
+{
+  if (signal >= AVR_LINUX_SIGRTMIN && signal <= AVR_LINUX_SIGRTMAX)
+    {
+      int offset = signal - AVR_LINUX_SIGRTMIN;
+
+      if (offset == 0)
+       return GDB_SIGNAL_REALTIME_32;
+      else
+       return (enum gdb_signal) (offset - 1
+                                 + (int) GDB_SIGNAL_REALTIME_33);
+    }
+  else if (signal > AVR_LINUX_SIGRTMAX)
+    return GDB_SIGNAL_UNKNOWN;
+
+  return linux_gdb_signal_from_target (gdbarch, signal);
+}
+
+/* Implementation of `gdbarch_gdb_signal_to_target', as defined in
+   gdbarch.h.  */
+
+static int
+avr_linux_gdb_signal_to_target (struct gdbarch *gdbarch,
+                               enum gdb_signal signal)
+{
+  switch (signal)
+    {
+    /* GDB_SIGNAL_REALTIME_32 is not continuous in <gdb/signals.def>,
+       therefore we have to handle it here.  */
+    case GDB_SIGNAL_REALTIME_32:
+      return AVR_LINUX_SIGRTMIN;
+
+    /* GDB_SIGNAL_REALTIME_64 is not valid on AVR.  */
+    case GDB_SIGNAL_REALTIME_64:
+      return -1;
+    }
+
+  /* GDB_SIGNAL_REALTIME_33 to _63 are continuous.
+     AVR does not have _64.  */
+  if (signal >= GDB_SIGNAL_REALTIME_33
+      && signal <= GDB_SIGNAL_REALTIME_63)
+    {
+      int offset = signal - GDB_SIGNAL_REALTIME_33;
+
+      return AVR_LINUX_SIGRTMIN + 1 + offset;
+    }
+
+  return linux_gdb_signal_to_target (gdbarch, signal);
+}
+
 /* Initialize the gdbarch structure for the AVR's.  */
 
 static struct gdbarch *
@@ -1444,6 +1512,11 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_unwind_pc (gdbarch, avr_unwind_pc);
   set_gdbarch_unwind_sp (gdbarch, avr_unwind_sp);
 
+  set_gdbarch_gdb_signal_from_target (gdbarch,
+                                     avr_linux_gdb_signal_from_target);
+  set_gdbarch_gdb_signal_to_target (gdbarch,
+                                   avr_linux_gdb_signal_to_target);
+
   return gdbarch;
 }
 
index db35b40fae8bc446bb35ce670b813c7a6d2a8a1e..1f3380ed58fc4c6affc100af2ca369a3fd40f1fa 100644 (file)
@@ -261,6 +261,7 @@ struct gdbarch
   gdbarch_process_record_ftype *process_record;
   gdbarch_process_record_signal_ftype *process_record_signal;
   gdbarch_gdb_signal_from_target_ftype *gdb_signal_from_target;
+  gdbarch_gdb_signal_to_target_ftype *gdb_signal_to_target;
   gdbarch_get_siginfo_type_ftype *get_siginfo_type;
   gdbarch_record_special_symbol_ftype *record_special_symbol;
   gdbarch_get_syscall_number_ftype *get_syscall_number;
@@ -433,6 +434,7 @@ struct gdbarch startup_gdbarch =
   0,  /* process_record */
   0,  /* process_record_signal */
   0,  /* gdb_signal_from_target */
+  0,  /* gdb_signal_to_target */
   0,  /* get_siginfo_type */
   0,  /* record_special_symbol */
   0,  /* get_syscall_number */
@@ -738,6 +740,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of process_record, has predicate.  */
   /* Skip verify of process_record_signal, has predicate.  */
   /* Skip verify of gdb_signal_from_target, has predicate.  */
+  /* Skip verify of gdb_signal_to_target, has predicate.  */
   /* Skip verify of get_siginfo_type, has predicate.  */
   /* Skip verify of record_special_symbol, has predicate.  */
   /* Skip verify of get_syscall_number, has predicate.  */
@@ -1032,6 +1035,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                       "gdbarch_dump: gdb_signal_from_target = <%s>\n",
                       host_address_to_string (gdbarch->gdb_signal_from_target));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_gdb_signal_to_target_p() = %d\n",
+                      gdbarch_gdb_signal_to_target_p (gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: gdb_signal_to_target = <%s>\n",
+                      host_address_to_string (gdbarch->gdb_signal_to_target));
   fprintf_unfiltered (file,
                       "gdbarch_dump: gen_return_address = <%s>\n",
                       host_address_to_string (gdbarch->gen_return_address));
@@ -3899,6 +3908,30 @@ set_gdbarch_gdb_signal_from_target (struct gdbarch *gdbarch,
   gdbarch->gdb_signal_from_target = gdb_signal_from_target;
 }
 
+int
+gdbarch_gdb_signal_to_target_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->gdb_signal_to_target != NULL;
+}
+
+int
+gdbarch_gdb_signal_to_target (struct gdbarch *gdbarch, enum gdb_signal signal)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->gdb_signal_to_target != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_gdb_signal_to_target called\n");
+  return gdbarch->gdb_signal_to_target (gdbarch, signal);
+}
+
+void
+set_gdbarch_gdb_signal_to_target (struct gdbarch *gdbarch,
+                                  gdbarch_gdb_signal_to_target_ftype gdb_signal_to_target)
+{
+  gdbarch->gdb_signal_to_target = gdb_signal_to_target;
+}
+
 int
 gdbarch_get_siginfo_type_p (struct gdbarch *gdbarch)
 {
index e1959c39182c36b3dd538fc31a9b8d571b54931f..013f0717b74398067a79999437c1cde5468647f5 100644 (file)
@@ -993,6 +993,20 @@ typedef enum gdb_signal (gdbarch_gdb_signal_from_target_ftype) (struct gdbarch *
 extern enum gdb_signal gdbarch_gdb_signal_from_target (struct gdbarch *gdbarch, int signo);
 extern void set_gdbarch_gdb_signal_from_target (struct gdbarch *gdbarch, gdbarch_gdb_signal_from_target_ftype *gdb_signal_from_target);
 
+/* Signal translation: translate the GDB's internal signal number into
+   the inferior's signal (target's) representation.  The implementation
+   of this method must be host independent.  IOW, don't rely on symbols
+   of the NAT_FILE header (the nm-*.h files), the host <signal.h>
+   header, or similar headers.
+   Return the target signal number if found, or -1 if the GDB internal
+   signal number is invalid. */
+
+extern int gdbarch_gdb_signal_to_target_p (struct gdbarch *gdbarch);
+
+typedef int (gdbarch_gdb_signal_to_target_ftype) (struct gdbarch *gdbarch, enum gdb_signal signal);
+extern int gdbarch_gdb_signal_to_target (struct gdbarch *gdbarch, enum gdb_signal signal);
+extern void set_gdbarch_gdb_signal_to_target (struct gdbarch *gdbarch, gdbarch_gdb_signal_to_target_ftype *gdb_signal_to_target);
+
 /* Extra signal info inspection.
   
    Return a type suitable to inspect extra signal information. */
index c92a857b70cadfe3b07479ad1fe4875068b859c1..04ca38c0940c83c1b81c967a142bd10d999f5200 100755 (executable)
@@ -799,6 +799,15 @@ M:int:process_record_signal:struct regcache *regcache, enum gdb_signal signal:re
 # (target_wait, target_resume, etc.).
 M:enum gdb_signal:gdb_signal_from_target:int signo:signo
 
+# Signal translation: translate the GDB's internal signal number into
+# the inferior's signal (target's) representation.  The implementation
+# of this method must be host independent.  IOW, don't rely on symbols
+# of the NAT_FILE header (the nm-*.h files), the host <signal.h>
+# header, or similar headers.
+# Return the target signal number if found, or -1 if the GDB internal
+# signal number is invalid.
+M:int:gdb_signal_to_target:enum gdb_signal signal:signal
+
 # Extra signal info inspection.
 #
 # Return a type suitable to inspect extra signal information.
index bfb64049bc45cadd81a1ad0c5706598a0ec85c52..fbdca463510dc4d47d0657755da7b5117058c88c 100644 (file)
 
 #include <ctype.h>
 
+/* This enum represents the signals' numbers on a generic architecture
+   running the Linux kernel.  The definition of "generic" comes from
+   the file <include/uapi/asm-generic/signal.h>, from the Linux kernel
+   tree, which is the "de facto" implementation of signal numbers to
+   be used by new architecture ports.
+
+   For those architectures which have differences between the generic
+   standard (e.g., Alpha), we define the different signals (and *only*
+   those) in the specific target-dependent file (e.g.,
+   alpha-linux-tdep.c, for Alpha).  Please refer to the architecture's
+   tdep file for more information.
+
+   ARM deserves a special mention here.  On the file
+   <arch/arm/include/uapi/asm/signal.h>, it defines only one different
+   (and ARM-only) signal, which is SIGSWI, with the same number as
+   SIGRTMIN.  This signal is used only for a very specific target,
+   called ArthurOS (from RISCOS).  Therefore, we do not handle it on
+   the ARM-tdep file, and we can safely use the generic signal handler
+   here for ARM targets.
+
+   As stated above, this enum is derived from
+   <include/uapi/asm-generic/signal.h>, from the Linux kernel
+   tree.  */
+
+enum
+  {
+    LINUX_SIGHUP = 1,
+    LINUX_SIGINT = 2,
+    LINUX_SIGQUIT = 3,
+    LINUX_SIGILL = 4,
+    LINUX_SIGTRAP = 5,
+    LINUX_SIGABRT = 6,
+    LINUX_SIGIOT = 6,
+    LINUX_SIGBUS = 7,
+    LINUX_SIGFPE = 8,
+    LINUX_SIGKILL = 9,
+    LINUX_SIGUSR1 = 10,
+    LINUX_SIGSEGV = 11,
+    LINUX_SIGUSR2 = 12,
+    LINUX_SIGPIPE = 13,
+    LINUX_SIGALRM = 14,
+    LINUX_SIGTERM = 15,
+    LINUX_SIGSTKFLT = 16,
+    LINUX_SIGCHLD = 17,
+    LINUX_SIGCONT = 18,
+    LINUX_SIGSTOP = 19,
+    LINUX_SIGTSTP = 20,
+    LINUX_SIGTTIN = 21,
+    LINUX_SIGTTOU = 22,
+    LINUX_SIGURG = 23,
+    LINUX_SIGXCPU = 24,
+    LINUX_SIGXFSZ = 25,
+    LINUX_SIGVTALRM = 26,
+    LINUX_SIGPROF = 27,
+    LINUX_SIGWINCH = 28,
+    LINUX_SIGIO = 29,
+    LINUX_SIGPOLL = LINUX_SIGIO,
+    LINUX_SIGPWR = 30,
+    LINUX_SIGSYS = 31,
+    LINUX_SIGUNUSED = 31,
+
+    LINUX_SIGRTMIN = 32,
+    LINUX_SIGRTMAX = 64,
+  };
+
 static struct gdbarch_data *linux_gdbarch_data_handle;
 
 struct linux_gdbarch_data
@@ -1447,6 +1512,257 @@ linux_make_corefile_notes_1 (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
                                      linux_collect_thread_registers);
 }
 
+/* Implementation of `gdbarch_gdb_signal_from_target', as defined in
+   gdbarch.h.  This function is not static because it is exported to
+   other -tdep files.  */
+
+enum gdb_signal
+linux_gdb_signal_from_target (struct gdbarch *gdbarch, int signal)
+{
+  switch (signal)
+    {
+    case 0:
+      return GDB_SIGNAL_0;
+
+    case LINUX_SIGHUP:
+      return GDB_SIGNAL_HUP;
+
+    case LINUX_SIGINT:
+      return GDB_SIGNAL_INT;
+
+    case LINUX_SIGQUIT:
+      return GDB_SIGNAL_QUIT;
+
+    case LINUX_SIGILL:
+      return GDB_SIGNAL_ILL;
+
+    case LINUX_SIGTRAP:
+      return GDB_SIGNAL_TRAP;
+
+    case LINUX_SIGABRT:
+      return GDB_SIGNAL_ABRT;
+
+    case LINUX_SIGBUS:
+      return GDB_SIGNAL_BUS;
+
+    case LINUX_SIGFPE:
+      return GDB_SIGNAL_FPE;
+
+    case LINUX_SIGKILL:
+      return GDB_SIGNAL_KILL;
+
+    case LINUX_SIGUSR1:
+      return GDB_SIGNAL_USR1;
+
+    case LINUX_SIGSEGV:
+      return GDB_SIGNAL_SEGV;
+
+    case LINUX_SIGUSR2:
+      return GDB_SIGNAL_USR2;
+
+    case LINUX_SIGPIPE:
+      return GDB_SIGNAL_PIPE;
+
+    case LINUX_SIGALRM:
+      return GDB_SIGNAL_ALRM;
+
+    case LINUX_SIGTERM:
+      return GDB_SIGNAL_TERM;
+
+    case LINUX_SIGCHLD:
+      return GDB_SIGNAL_CHLD;
+
+    case LINUX_SIGCONT:
+      return GDB_SIGNAL_CONT;
+
+    case LINUX_SIGSTOP:
+      return GDB_SIGNAL_STOP;
+
+    case LINUX_SIGTSTP:
+      return GDB_SIGNAL_TSTP;
+
+    case LINUX_SIGTTIN:
+      return GDB_SIGNAL_TTIN;
+
+    case LINUX_SIGTTOU:
+      return GDB_SIGNAL_TTOU;
+
+    case LINUX_SIGURG:
+      return GDB_SIGNAL_URG;
+
+    case LINUX_SIGXCPU:
+      return GDB_SIGNAL_XCPU;
+
+    case LINUX_SIGXFSZ:
+      return GDB_SIGNAL_XFSZ;
+
+    case LINUX_SIGVTALRM:
+      return GDB_SIGNAL_VTALRM;
+
+    case LINUX_SIGPROF:
+      return GDB_SIGNAL_PROF;
+
+    case LINUX_SIGWINCH:
+      return GDB_SIGNAL_WINCH;
+
+    /* No way to differentiate between SIGIO and SIGPOLL.
+       Therefore, we just handle the first one.  */
+    case LINUX_SIGIO:
+      return GDB_SIGNAL_IO;
+
+    case LINUX_SIGPWR:
+      return GDB_SIGNAL_PWR;
+
+    case LINUX_SIGSYS:
+      return GDB_SIGNAL_SYS;
+
+    /* SIGRTMIN and SIGRTMAX are not continuous in <gdb/signals.def>,
+       therefore we have to handle them here.  */
+    case LINUX_SIGRTMIN:
+      return GDB_SIGNAL_REALTIME_32;
+
+    case LINUX_SIGRTMAX:
+      return GDB_SIGNAL_REALTIME_64;
+    }
+
+  if (signal >= LINUX_SIGRTMIN + 1 && signal <= LINUX_SIGRTMAX - 1)
+    {
+      int offset = signal - LINUX_SIGRTMIN + 1;
+
+      return (enum gdb_signal) ((int) GDB_SIGNAL_REALTIME_33 + offset);
+    }
+
+  return GDB_SIGNAL_UNKNOWN;
+}
+
+/* Implementation of `gdbarch_gdb_signal_to_target', as defined in
+   gdbarch.h.  This function is not static because it is exported to
+   other -tdep files.  */
+
+int
+linux_gdb_signal_to_target (struct gdbarch *gdbarch,
+                           enum gdb_signal signal)
+{
+  switch (signal)
+    {
+    case GDB_SIGNAL_0:
+      return 0;
+
+    case GDB_SIGNAL_HUP:
+      return LINUX_SIGHUP;
+
+    case GDB_SIGNAL_INT:
+      return LINUX_SIGINT;
+
+    case GDB_SIGNAL_QUIT:
+      return LINUX_SIGQUIT;
+
+    case GDB_SIGNAL_ILL:
+      return LINUX_SIGILL;
+
+    case GDB_SIGNAL_TRAP:
+      return LINUX_SIGTRAP;
+
+    case GDB_SIGNAL_ABRT:
+      return LINUX_SIGABRT;
+
+    case GDB_SIGNAL_FPE:
+      return LINUX_SIGFPE;
+
+    case GDB_SIGNAL_KILL:
+      return LINUX_SIGKILL;
+
+    case GDB_SIGNAL_BUS:
+      return LINUX_SIGBUS;
+
+    case GDB_SIGNAL_SEGV:
+      return LINUX_SIGSEGV;
+
+    case GDB_SIGNAL_SYS:
+      return LINUX_SIGSYS;
+
+    case GDB_SIGNAL_PIPE:
+      return LINUX_SIGPIPE;
+
+    case GDB_SIGNAL_ALRM:
+      return LINUX_SIGALRM;
+
+    case GDB_SIGNAL_TERM:
+      return LINUX_SIGTERM;
+
+    case GDB_SIGNAL_URG:
+      return LINUX_SIGURG;
+
+    case GDB_SIGNAL_STOP:
+      return LINUX_SIGSTOP;
+
+    case GDB_SIGNAL_TSTP:
+      return LINUX_SIGTSTP;
+
+    case GDB_SIGNAL_CONT:
+      return LINUX_SIGCONT;
+
+    case GDB_SIGNAL_CHLD:
+      return LINUX_SIGCHLD;
+
+    case GDB_SIGNAL_TTIN:
+      return LINUX_SIGTTIN;
+
+    case GDB_SIGNAL_TTOU:
+      return LINUX_SIGTTOU;
+
+    case GDB_SIGNAL_IO:
+      return LINUX_SIGIO;
+
+    case GDB_SIGNAL_XCPU:
+      return LINUX_SIGXCPU;
+
+    case GDB_SIGNAL_XFSZ:
+      return LINUX_SIGXFSZ;
+
+    case GDB_SIGNAL_VTALRM:
+      return LINUX_SIGVTALRM;
+
+    case GDB_SIGNAL_PROF:
+      return LINUX_SIGPROF;
+
+    case GDB_SIGNAL_WINCH:
+      return LINUX_SIGWINCH;
+
+    case GDB_SIGNAL_USR1:
+      return LINUX_SIGUSR1;
+
+    case GDB_SIGNAL_USR2:
+      return LINUX_SIGUSR2;
+
+    case GDB_SIGNAL_PWR:
+      return LINUX_SIGPWR;
+
+    case GDB_SIGNAL_POLL:
+      return LINUX_SIGPOLL;
+
+    /* GDB_SIGNAL_REALTIME_32 is not continuous in <gdb/signals.def>,
+       therefore we have to handle it here.  */
+    case GDB_SIGNAL_REALTIME_32:
+      return LINUX_SIGRTMIN;
+
+    /* Same comment applies to _64.  */
+    case GDB_SIGNAL_REALTIME_64:
+      return LINUX_SIGRTMAX;
+    }
+
+  /* GDB_SIGNAL_REALTIME_33 to _64 are continuous.  */
+  if (signal >= GDB_SIGNAL_REALTIME_33
+      && signal <= GDB_SIGNAL_REALTIME_63)
+    {
+      int offset = signal - GDB_SIGNAL_REALTIME_33;
+
+      return LINUX_SIGRTMIN + 1 + offset;
+    }
+
+  return -1;
+}
+
 /* To be called from the various GDB_OSABI_LINUX handlers for the
    various GNU/Linux architectures and machine types.  */
 
@@ -1460,6 +1776,10 @@ linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_make_corefile_notes (gdbarch, linux_make_corefile_notes_1);
   set_gdbarch_has_shared_address_space (gdbarch,
                                        linux_has_shared_address_space);
+  set_gdbarch_gdb_signal_from_target (gdbarch,
+                                     linux_gdb_signal_from_target);
+  set_gdbarch_gdb_signal_to_target (gdbarch,
+                                   linux_gdb_signal_to_target);
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
index 380507e96749d79ca12a015470fead9f5b93d964..5841f296b1293a3797b67c34aa90583f78ea9875 100644 (file)
@@ -34,6 +34,12 @@ char *linux_make_corefile_notes (struct gdbarch *, bfd *, int *,
 
 struct type *linux_get_siginfo_type (struct gdbarch *);
 
+extern enum gdb_signal linux_gdb_signal_from_target (struct gdbarch *gdbarch,
+                                                    int signal);
+
+extern int linux_gdb_signal_to_target (struct gdbarch *gdbarch,
+                                      enum gdb_signal signal);
+
 extern void linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch);
 
 #endif /* linux-tdep.h */
index 484b39f7fe58260271e2a01f7b07818305683603..8d17839c6ef542a6c4dfa193163cb962e4cb34f0 100644 (file)
 
 static struct target_so_ops mips_svr4_so_ops;
 
+/* This enum represents the signals' numbers on the MIPS
+   architecture.  It just contains the signal definitions which are
+   different from the generic implementation.
+
+   It is derived from the file <arch/mips/include/uapi/asm/signal.h>,
+   from the Linux kernel tree.  */
+
+enum
+  {
+    MIPS_LINUX_SIGEMT = 7,
+    MIPS_LINUX_SIGBUS = 10,
+    MIPS_LINUX_SIGSYS = 12,
+    MIPS_LINUX_SIGUSR1 = 16,
+    MIPS_LINUX_SIGUSR2 = 17,
+    MIPS_LINUX_SIGCHLD = 18,
+    MIPS_LINUX_SIGCLD = MIPS_LINUX_SIGCHLD,
+    MIPS_LINUX_SIGPWR = 19,
+    MIPS_LINUX_SIGWINCH = 20,
+    MIPS_LINUX_SIGURG = 21,
+    MIPS_LINUX_SIGIO = 22,
+    MIPS_LINUX_SIGPOLL = MIPS_LINUX_SIGIO,
+    MIPS_LINUX_SIGSTOP = 23,
+    MIPS_LINUX_SIGTSTP = 24,
+    MIPS_LINUX_SIGCONT = 25,
+    MIPS_LINUX_SIGTTIN = 26,
+    MIPS_LINUX_SIGTTOU = 27,
+    MIPS_LINUX_SIGVTALRM = 28,
+    MIPS_LINUX_SIGPROF = 29,
+    MIPS_LINUX_SIGXCPU = 30,
+    MIPS_LINUX_SIGXFSZ = 31,
+
+    MIPS_LINUX_SIGRTMIN = 32,
+    MIPS_LINUX_SIGRT64 = 64,
+    MIPS_LINUX_SIGRTMAX = 127,
+  };
+
 /* Figure out where the longjmp will land.
    We expect the first arg to be a pointer to the jmp_buf structure
    from which we extract the pc (MIPS_LINUX_JB_PC) that we will land
@@ -1339,94 +1375,184 @@ mips_linux_get_syscall_number (struct gdbarch *gdbarch,
   return ret;
 }
 
+/* Implementation of `gdbarch_gdb_signal_to_target', as defined in
+   gdbarch.h.  */
+
+static int
+mips_gdb_signal_to_target (struct gdbarch *gdbarch,
+                          enum gdb_signal signal)
+{
+  switch (signal)
+    {
+    case GDB_SIGNAL_EMT:
+      return MIPS_LINUX_SIGEMT;
+
+    case GDB_SIGNAL_BUS:
+      return MIPS_LINUX_SIGBUS;
+
+    case GDB_SIGNAL_SYS:
+      return MIPS_LINUX_SIGSYS;
+
+    case GDB_SIGNAL_USR1:
+      return MIPS_LINUX_SIGUSR1;
+
+    case GDB_SIGNAL_USR2:
+      return MIPS_LINUX_SIGUSR2;
+
+    case GDB_SIGNAL_CHLD:
+      return MIPS_LINUX_SIGCHLD;
+
+    case GDB_SIGNAL_PWR:
+      return MIPS_LINUX_SIGPWR;
+
+    case GDB_SIGNAL_WINCH:
+      return MIPS_LINUX_SIGWINCH;
+
+    case GDB_SIGNAL_URG:
+      return MIPS_LINUX_SIGURG;
+
+    case GDB_SIGNAL_IO:
+      return MIPS_LINUX_SIGIO;
+
+    case GDB_SIGNAL_POLL:
+      return MIPS_LINUX_SIGPOLL;
+
+    case GDB_SIGNAL_STOP:
+      return MIPS_LINUX_SIGSTOP;
+
+    case GDB_SIGNAL_TSTP:
+      return MIPS_LINUX_SIGTSTP;
+
+    case GDB_SIGNAL_CONT:
+      return MIPS_LINUX_SIGCONT;
+
+    case GDB_SIGNAL_TTIN:
+      return MIPS_LINUX_SIGTTIN;
+
+    case GDB_SIGNAL_TTOU:
+      return MIPS_LINUX_SIGTTOU;
+
+    case GDB_SIGNAL_VTALRM:
+      return MIPS_LINUX_SIGVTALRM;
+
+    case GDB_SIGNAL_PROF:
+      return MIPS_LINUX_SIGPROF;
+
+    case GDB_SIGNAL_XCPU:
+      return MIPS_LINUX_SIGXCPU;
+
+    case GDB_SIGNAL_XFSZ:
+      return MIPS_LINUX_SIGXFSZ;
+
+    /* GDB_SIGNAL_REALTIME_32 is not continuous in <gdb/signals.def>,
+       therefore we have to handle it here.  */
+    case GDB_SIGNAL_REALTIME_32:
+      return MIPS_LINUX_SIGRTMIN;
+    }
+
+  if (signal >= GDB_SIGNAL_REALTIME_33
+      && signal <= GDB_SIGNAL_REALTIME_63)
+    {
+      int offset = signal - GDB_SIGNAL_REALTIME_33;
+
+      return MIPS_LINUX_SIGRTMIN + 1 + offset;
+    }
+  else if (signal >= GDB_SIGNAL_REALTIME_64
+          && signal <= GDB_SIGNAL_REALTIME_127)
+    {
+      int offset = signal - GDB_SIGNAL_REALTIME_64;
+
+      return MIPS_LINUX_SIGRT64 + offset;
+    }
+
+  return linux_gdb_signal_to_target (gdbarch, signal);
+}
+
 /* Translate signals based on MIPS signal values.
    Adapted from gdb/common/signals.c.  */
 
 static enum gdb_signal
-mips_gdb_signal_from_target (struct gdbarch *gdbarch, int signo)
+mips_gdb_signal_from_target (struct gdbarch *gdbarch, int signal)
 {
-  switch (signo)
+  switch (signal)
     {
-    case 0:
-      return GDB_SIGNAL_0;
-    case MIPS_SIGHUP:
-      return GDB_SIGNAL_HUP;
-    case MIPS_SIGINT:
-      return GDB_SIGNAL_INT;
-    case MIPS_SIGQUIT:
-      return GDB_SIGNAL_QUIT;
-    case MIPS_SIGILL:
-      return GDB_SIGNAL_ILL;
-    case MIPS_SIGTRAP:
-      return GDB_SIGNAL_TRAP;
-    case MIPS_SIGABRT:
-      return GDB_SIGNAL_ABRT;
-    case MIPS_SIGEMT:
+    case MIPS_LINUX_SIGEMT:
       return GDB_SIGNAL_EMT;
-    case MIPS_SIGFPE:
-      return GDB_SIGNAL_FPE;
-    case MIPS_SIGKILL:
-      return GDB_SIGNAL_KILL;
-    case MIPS_SIGBUS:
+
+    case MIPS_LINUX_SIGBUS:
       return GDB_SIGNAL_BUS;
-    case MIPS_SIGSEGV:
-      return GDB_SIGNAL_SEGV;
-    case MIPS_SIGSYS:
+
+    case MIPS_LINUX_SIGSYS:
       return GDB_SIGNAL_SYS;
-    case MIPS_SIGPIPE:
-      return GDB_SIGNAL_PIPE;
-    case MIPS_SIGALRM:
-      return GDB_SIGNAL_ALRM;
-    case MIPS_SIGTERM:
-      return GDB_SIGNAL_TERM;
-    case MIPS_SIGUSR1:
+
+    case MIPS_LINUX_SIGUSR1:
       return GDB_SIGNAL_USR1;
-    case MIPS_SIGUSR2:
+
+    case MIPS_LINUX_SIGUSR2:
       return GDB_SIGNAL_USR2;
-    case MIPS_SIGCHLD:
+
+    case MIPS_LINUX_SIGCHLD:
       return GDB_SIGNAL_CHLD;
-    case MIPS_SIGPWR:
+
+    case MIPS_LINUX_SIGPWR:
       return GDB_SIGNAL_PWR;
-    case MIPS_SIGWINCH:
+
+    case MIPS_LINUX_SIGWINCH:
       return GDB_SIGNAL_WINCH;
-    case MIPS_SIGURG:
+
+    case MIPS_LINUX_SIGURG:
       return GDB_SIGNAL_URG;
-    case MIPS_SIGPOLL:
-      return GDB_SIGNAL_POLL;
-    case MIPS_SIGSTOP:
+
+    /* No way to differentiate between SIGIO and SIGPOLL.
+       Therefore, we just handle the first one.  */
+    case MIPS_LINUX_SIGIO:
+      return GDB_SIGNAL_IO;
+
+    case MIPS_LINUX_SIGSTOP:
       return GDB_SIGNAL_STOP;
-    case MIPS_SIGTSTP:
+
+    case MIPS_LINUX_SIGTSTP:
       return GDB_SIGNAL_TSTP;
-    case MIPS_SIGCONT:
+
+    case MIPS_LINUX_SIGCONT:
       return GDB_SIGNAL_CONT;
-    case MIPS_SIGTTIN:
+
+    case MIPS_LINUX_SIGTTIN:
       return GDB_SIGNAL_TTIN;
-    case MIPS_SIGTTOU:
+
+    case MIPS_LINUX_SIGTTOU:
       return GDB_SIGNAL_TTOU;
-    case MIPS_SIGVTALRM:
+
+    case MIPS_LINUX_SIGVTALRM:
       return GDB_SIGNAL_VTALRM;
-    case MIPS_SIGPROF:
+
+    case MIPS_LINUX_SIGPROF:
       return GDB_SIGNAL_PROF;
-    case MIPS_SIGXCPU:
+
+    case MIPS_LINUX_SIGXCPU:
       return GDB_SIGNAL_XCPU;
-    case MIPS_SIGXFSZ:
+
+    case MIPS_LINUX_SIGXFSZ:
       return GDB_SIGNAL_XFSZ;
-  }
+    }
 
-  if (signo >= MIPS_SIGRTMIN && signo <= MIPS_SIGRTMAX)
+  if (signal >= MIPS_LINUX_SIGRTMIN && signal <= MIPS_LINUX_SIGRTMAX)
     {
       /* GDB_SIGNAL_REALTIME values are not contiguous, map parts of
          the MIPS block to the respective GDB_SIGNAL_REALTIME blocks.  */
-      signo -= MIPS_SIGRTMIN;
-      if (signo == 0)
+      int offset = signal - MIPS_LINUX_SIGRTMIN;
+
+      if (offset == 0)
        return GDB_SIGNAL_REALTIME_32;
-      else if (signo < 32)
-       return ((enum gdb_signal) (signo - 1 + (int) GDB_SIGNAL_REALTIME_33));
+      else if (offset < 32)
+       return (enum gdb_signal) (offset - 1
+                                 + (int) GDB_SIGNAL_REALTIME_33);
       else
-       return ((enum gdb_signal) (signo - 32 + (int) GDB_SIGNAL_REALTIME_64));
+       return (enum gdb_signal) (offset - 32
+                                 + (int) GDB_SIGNAL_REALTIME_64);
     }
 
-  return GDB_SIGNAL_UNKNOWN;
+  return linux_gdb_signal_from_target (gdbarch, signal);
 }
 
 /* Initialize one of the GNU/Linux OS ABIs.  */
@@ -1516,6 +1642,9 @@ mips_linux_init_abi (struct gdbarch_info info,
   set_gdbarch_gdb_signal_from_target (gdbarch,
                                      mips_gdb_signal_from_target);
 
+  set_gdbarch_gdb_signal_to_target (gdbarch,
+                                   mips_gdb_signal_to_target);
+
   tdep->syscall_next_pc = mips_linux_syscall_next_pc;
 
   if (tdesc_data)
index 09cbc131146893af867f631e2fac0ac3cdda4317..482d3c5329ffe64badfde1b43eee4ebb5d7c0b2a 100644 (file)
@@ -105,45 +105,3 @@ 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).  */
-    MIPS_SIGRTMIN  = 32,       /* Minimum RT signal.  */
-    MIPS_SIGRTMAX  = 128 - 1   /* Maximum RT signal.  */
-  };
index 02c4137a3b63ae051ec2eb8861bdef0e051f0a7f..75d40a64e8aa613d7423ce8e4960a9458a3f1b1e 100644 (file)
@@ -90,6 +90,31 @@ static const struct tramp_frame sparc32_linux_rt_sigframe =
   sparc32_linux_sigframe_init
 };
 
+/* This enum represents the signals' numbers on the SPARC
+   architecture.  It just contains the signal definitions which are
+   different from the generic implementation.
+
+   It is derived from the file <arch/sparc/include/uapi/asm/signal.h>,
+   from the Linux kernel tree.  */
+
+enum
+  {
+    SPARC_LINUX_SIGEMT = 7,
+    SPARC_LINUX_SIGBUS = 10,
+    SPARC_LINUX_SIGSYS = 12,
+    SPARC_LINUX_SIGURG = 16,
+    SPARC_LINUX_SIGSTOP = 17,
+    SPARC_LINUX_SIGTSTP = 18,
+    SPARC_LINUX_SIGCONT = 19,
+    SPARC_LINUX_SIGCHLD = 20,
+    SPARC_LINUX_SIGIO = 23,
+    SPARC_LINUX_SIGPOLL = SPARC_LINUX_SIGIO,
+    SPARC_LINUX_SIGLOST = 29,
+    SPARC_LINUX_SIGPWR = SPARC_LINUX_SIGLOST,
+    SPARC_LINUX_SIGUSR1 = 30,
+    SPARC_LINUX_SIGUSR2 = 31,
+  };
+
 static void
 sparc32_linux_sigframe_init (const struct tramp_frame *self,
                             struct frame_info *this_frame,
@@ -268,6 +293,114 @@ sparc32_linux_get_syscall_number (struct gdbarch *gdbarch,
   return ret;
 }
 
+/* Implementation of `gdbarch_gdb_signal_from_target', as defined in
+   gdbarch.h.  */
+
+static enum gdb_signal
+sparc32_linux_gdb_signal_from_target (struct gdbarch *gdbarch,
+                                     int signal)
+{
+  switch (signal)
+    {
+    case SPARC_LINUX_SIGEMT:
+      return GDB_SIGNAL_EMT;
+
+    case SPARC_LINUX_SIGBUS:
+      return GDB_SIGNAL_BUS;
+
+    case SPARC_LINUX_SIGSYS:
+      return GDB_SIGNAL_SYS;
+
+    case SPARC_LINUX_SIGURG:
+      return GDB_SIGNAL_URG;
+
+    case SPARC_LINUX_SIGSTOP:
+      return GDB_SIGNAL_STOP;
+
+    case SPARC_LINUX_SIGTSTP:
+      return GDB_SIGNAL_TSTP;
+
+    case SPARC_LINUX_SIGCONT:
+      return GDB_SIGNAL_CONT;
+
+    case SPARC_LINUX_SIGCHLD:
+      return GDB_SIGNAL_CHLD;
+
+    /* No way to differentiate between SIGIO and SIGPOLL.
+       Therefore, we just handle the first one.  */
+    case SPARC_LINUX_SIGIO:
+      return GDB_SIGNAL_IO;
+
+    /* No way to differentiate between SIGLOST and SIGPWR.
+       Therefore, we just handle the first one.  */
+    case SPARC_LINUX_SIGLOST:
+      return GDB_SIGNAL_LOST;
+
+    case SPARC_LINUX_SIGUSR1:
+      return GDB_SIGNAL_USR1;
+
+    case SPARC_LINUX_SIGUSR2:
+      return GDB_SIGNAL_USR2;
+    }
+
+  return linux_gdb_signal_from_target (gdbarch, signal);
+}
+
+/* Implementation of `gdbarch_gdb_signal_to_target', as defined in
+   gdbarch.h.  */
+
+static int
+sparc32_linux_gdb_signal_to_target (struct gdbarch *gdbarch,
+                                   enum gdb_signal signal)
+{
+  switch (signal)
+    {
+    case GDB_SIGNAL_EMT:
+      return SPARC_LINUX_SIGEMT;
+
+    case GDB_SIGNAL_BUS:
+      return SPARC_LINUX_SIGBUS;
+
+    case GDB_SIGNAL_SYS:
+      return SPARC_LINUX_SIGSYS;
+
+    case GDB_SIGNAL_URG:
+      return SPARC_LINUX_SIGURG;
+
+    case GDB_SIGNAL_STOP:
+      return SPARC_LINUX_SIGSTOP;
+
+    case GDB_SIGNAL_TSTP:
+      return SPARC_LINUX_SIGTSTP;
+
+    case GDB_SIGNAL_CONT:
+      return SPARC_LINUX_SIGCONT;
+
+    case GDB_SIGNAL_CHLD:
+      return SPARC_LINUX_SIGCHLD;
+
+    case GDB_SIGNAL_IO:
+      return SPARC_LINUX_SIGIO;
+
+    case GDB_SIGNAL_POLL:
+      return SPARC_LINUX_SIGPOLL;
+
+    case GDB_SIGNAL_LOST:
+      return SPARC_LINUX_SIGLOST;
+
+    case GDB_SIGNAL_PWR:
+      return SPARC_LINUX_SIGPWR;
+
+    case GDB_SIGNAL_USR1:
+      return SPARC_LINUX_SIGUSR1;
+
+    case GDB_SIGNAL_USR2:
+      return SPARC_LINUX_SIGUSR2;
+    }
+
+  return linux_gdb_signal_to_target (gdbarch, signal);
+}
+
 \f
 
 static void
@@ -313,6 +446,11 @@ sparc32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_xml_syscall_file_name (XML_SYSCALL_FILENAME_SPARC32);
   set_gdbarch_get_syscall_number (gdbarch,
                                   sparc32_linux_get_syscall_number);
+
+  set_gdbarch_gdb_signal_from_target (gdbarch,
+                                     sparc32_linux_gdb_signal_from_target);
+  set_gdbarch_gdb_signal_to_target (gdbarch,
+                                   sparc32_linux_gdb_signal_to_target);
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
index b7f11b977412a04e8b2d9d8253213afab353caf3..e7c6287571001a4e4cf3ea40e9e7bbaf9a116dad 100644 (file)
 #include "solib-svr4.h"
 #include "symtab.h"
 
+/* This enum represents the signals' numbers on the Xtensa
+   architecture.  It just contains the signal definitions which are
+   different from the generic implementation.
+
+   It is derived from the file <arch/xtensa/include/uapi/asm/signal.h>,
+   from the Linux kernel tree.  */
+
+enum
+  {
+    XTENSA_LINUX_SIGRTMIN = 32,
+    XTENSA_LINUX_SIGRTMAX = 63,
+  };
+
+/* Implementation of `gdbarch_gdb_signal_from_target', as defined in
+   gdbarch.h.  */
+
+static enum gdb_signal
+xtensa_linux_gdb_signal_from_target (struct gdbarch *gdbarch,
+                                  int signal)
+{
+  if (signal >= XTENSA_LINUX_SIGRTMIN && signal <= XTENSA_LINUX_SIGRTMAX)
+    {
+      int offset = signal - XTENSA_LINUX_SIGRTMIN;
+
+      if (offset == 0)
+       return GDB_SIGNAL_REALTIME_32;
+      else
+       return (enum gdb_signal) (offset - 1
+                                 + (int) GDB_SIGNAL_REALTIME_33);
+    }
+  else if (signal > XTENSA_LINUX_SIGRTMAX)
+    return GDB_SIGNAL_UNKNOWN;
+
+  return linux_gdb_signal_from_target (gdbarch, signal);
+}
+
+/* Implementation of `gdbarch_gdb_signal_to_target', as defined in
+   gdbarch.h.  */
+
+static int
+xtensa_linux_gdb_signal_to_target (struct gdbarch *gdbarch,
+                                  enum gdb_signal signal)
+{
+  switch (signal)
+    {
+    /* GDB_SIGNAL_REALTIME_32 is not continuous in <gdb/signals.def>,
+       therefore we have to handle it here.  */
+    case GDB_SIGNAL_REALTIME_32:
+      return XTENSA_LINUX_SIGRTMIN;
+
+    /* GDB_SIGNAL_REALTIME_64 is not valid on Xtensa.  */
+    case GDB_SIGNAL_REALTIME_64:
+      return -1;
+    }
+
+  /* GDB_SIGNAL_REALTIME_33 to _63 are continuous.
+
+     Xtensa does not have _64.  */
+  if (signal >= GDB_SIGNAL_REALTIME_33
+      && signal <= GDB_SIGNAL_REALTIME_63)
+    {
+      int offset = signal - GDB_SIGNAL_REALTIME_33;
+
+      return XTENSA_LINUX_SIGRTMIN + 1 + offset;
+    }
+
+  return linux_gdb_signal_to_target (gdbarch, signal);
+}
+
 /* OS specific initialization of gdbarch.  */
 
 static void
@@ -32,6 +101,11 @@ xtensa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   set_solib_svr4_fetch_link_map_offsets
     (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+
+  set_gdbarch_gdb_signal_from_target (gdbarch,
+                                     xtensa_linux_gdb_signal_from_target);
+  set_gdbarch_gdb_signal_to_target (gdbarch,
+                                   xtensa_linux_gdb_signal_to_target);
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */