gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / xtensa-linux-tdep.c
index 240a33b088dd1297ca26d02b3210e47dae677734..028c8ea034c9d2f17dd33b12e76042cd8fbadcfd 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for GNU/Linux on Xtensa processors.
 
-   Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2007-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "xtensa-tdep.h"
 #include "osabi.h"
-
+#include "linux-tdep.h"
 #include "solib-svr4.h"
 #include "symtab.h"
+#include "gdbarch.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
 xtensa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (tdep->num_nopriv_regs < tdep->num_regs)
+    {
+      tdep->num_pseudo_regs += tdep->num_regs - tdep->num_nopriv_regs;
+      tdep->num_regs = tdep->num_nopriv_regs;
+
+      set_gdbarch_num_regs (gdbarch, tdep->num_regs);
+      set_gdbarch_num_pseudo_regs (gdbarch, tdep->num_pseudo_regs);
+    }
+
+  linux_init_abi (info, 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);
+
+  /* Enable TLS support.  */
+  set_gdbarch_fetch_tls_load_module_address (gdbarch,
+                                             svr4_fetch_objfile_link_map);
 }
 
+void _initialize_xtensa_linux_tdep ();
 void
-_initialize_xtensa_linux_tdep (void)
+_initialize_xtensa_linux_tdep ()
 {
   gdbarch_register_osabi (bfd_arch_xtensa, bfd_mach_xtensa, GDB_OSABI_LINUX,
                          xtensa_linux_init_abi);
This page took 0.024789 seconds and 4 git commands to generate.