[commit/CRIS] Dwarf-2 and sigtramp frame unwinder (and more)

Orjan Friberg orjan.friberg@axis.com
Mon Oct 11 15:02:00 GMT 2004


FYI, committed the following:

2004-10-11  Orjan Friberg  <orjanf@axis.com>

	* cris-tdep.c (cris_sigtramp_start, cris_rt_sigtramp_start)
	(cris_sigcontext_addr, cris_sigtramp_frame_unwind_cache)
	(cris_sigtramp_frame_this_id, cris_sigtramp_frame_prev_register)
	(cris_sigtramp_frame_sniffer): New functions.
	(cris_gdbarch_init): Hook in signal trampoline unwinder.
	(cris_dwarf2_reg_to_regnum, cris_dwarf2_frame_init_reg): New functions.
	(cris_gdbarch_init): Hook in Dwarf-2 unwinder.
	(struct gdbarch_tdep, set_cris_dwarf2_cfi, cris_dump_tdep)
	(cris_gdbarch_init, _initialize_cris_tdep): Add CRIS Dwarf-2 CFI usage
	command.
	(cris_version_update): Remove, replace with ...
	(set_cris_version): New function.
	(struct gdbarch_tdep, cris_mode, cris_mode_update)
	(cris_cannot_store_register, cris_dump_tdep, cris_gdbarch_init)
	(_initialize_cris_tdep): Remove CRIS mode command.
	(cris_fpless_backtrace, _initialize_cris_tdep): Remove CRIS command for
	framepointer-less backtrace.
	(cris_scan_prologue): Fix prologue scanning limit.
	(cris_register_type): Update to reflect actual registers.
	(cris_register_bytes_ok) Remove.
	(cris_gdbarch_init): Remove support for CRIS v8 and v9. Remove
	set_gdbarch_deprecated_register_size,
	set_gdbarch_deprecated_register_byte, set_gdbarch_register_bytes_ok.


--- cris-tdep.c Mon Oct 11 15:19:36 2004
+++ xxx Fri Oct  8 16:02:39 2004
@@ -107,19 +107,32 @@

  /* CRIS version, set via the user command 'set cris-version'.  Affects
     register names and sizes.*/
-static unsigned int usr_cmd_cris_version;
+static int usr_cmd_cris_version;

  /* Indicates whether to trust the above variable.  */
  static int usr_cmd_cris_version_valid = 0;

-/* Whether to make use of Dwarf-2 CFI (default on).  */
-static int usr_cmd_cris_dwarf2_cfi = 1;
+/* CRIS mode, set via the user command 'set cris-mode'.  Affects availability
+   of some registers.  */
+static const char *usr_cmd_cris_mode;
+
+/* Indicates whether to trust the above variable.  */
+static int usr_cmd_cris_mode_valid = 0;
+
+static const char CRIS_MODE_USER[] = "CRIS_MODE_USER";
+static const char CRIS_MODE_SUPERVISOR[] = "CRIS_MODE_SUPERVISOR";
+static const char *cris_mode_enums[] =
+{
+  CRIS_MODE_USER,
+  CRIS_MODE_SUPERVISOR,
+  0
+};

  /* CRIS architecture specific information.  */
  struct gdbarch_tdep
  {
-  unsigned int cris_version;
-  int cris_dwarf2_cfi;
+  int cris_version;
+  const char *cris_mode;
  };

  /* Functions for accessing target dependent data.  */
@@ -130,6 +143,12 @@
    return (gdbarch_tdep (current_gdbarch)->cris_version);
  }

+static const char *
+cris_mode (void)
+{
+  return (gdbarch_tdep (current_gdbarch)->cris_mode);
+}
+
  /* Sigtramp identification code copied from i386-linux-tdep.c. */

  #define SIGTRAMP_INSN0    0x9c5f  /* movu.w 0xXX, $r9 */
@@ -547,11 +566,11 @@

  static void cris_dump_tdep (struct gdbarch *, struct ui_file *);

-static void set_cris_version (char *ignore_args, int from_tty,
-                             struct cmd_list_element *c);
+static void cris_version_update (char *ignore_args, int from_tty,
+                                 struct cmd_list_element *c);

-static void set_cris_dwarf2_cfi (char *ignore_args, int from_tty,
-                                struct cmd_list_element *c);
+static void cris_mode_update (char *ignore_args, int from_tty,
+                              struct cmd_list_element *c);

  static CORE_ADDR cris_scan_prologue (CORE_ADDR pc,
                                      struct frame_info *next_frame,
@@ -1370,8 +1389,13 @@
      /* Writing has no effect.  */
      return 1;

-  /* IBR, BAR, BRP and IRP are read-only in user mode.  Let the debug
-     agent decide whether they are writable.  */
+  else if (cris_mode () == CRIS_MODE_USER)
+    {
+      if (regno == IBR_REGNUM || regno == BAR_REGNUM || regno == BRP_REGNUM
+          || regno == IRP_REGNUM)
+        /* Read-only in user mode.  */
+        return 1;
+    }

    return 0;
  }
@@ -3652,32 +3676,25 @@
  void
  _initialize_cris_tdep (void)
  {
-  static struct cmd_list_element *cris_set_cmdlist;
-  static struct cmd_list_element *cris_show_cmdlist;
-
    struct cmd_list_element *c;

    gdbarch_register (bfd_arch_cris, cris_gdbarch_init, cris_dump_tdep);

    /* CRIS-specific user-commands.  */
-  add_setshow_uinteger_cmd ("cris-version", class_support,
-                           &usr_cmd_cris_version,
-                           "Set the current CRIS version.",
-                           "Show the current CRIS version.",
-                           "Set if autodetection fails.",
-                           "Current CRIS version is %s.",
-                           set_cris_version, NULL,
-                           &setlist, &showlist);
-
-  add_setshow_boolean_cmd ("cris-dwarf2-cfi", class_support,
-                          &usr_cmd_cris_dwarf2_cfi,
-                          "Set the usage of Dwarf-2 CFI for CRIS.",
-                          "Show the usage of Dwarf-2 CFI for CRIS.",
-                          "Set to \"off\" if using gcc-cris < R59.",
-                          "Usage of Dwarf-2 CFI for CRIS is %d.",
-                          set_cris_dwarf2_cfi, NULL,
-                          &setlist, &showlist);
+  c = add_set_cmd ("cris-version", class_support, var_integer,
+                   (char *) &usr_cmd_cris_version,
+                   "Set the current CRIS version.", &setlist);
+  set_cmd_sfunc (c, cris_version_update);
+  deprecated_add_show_from_set (c, &showlist);
+
+  c = add_set_enum_cmd ("cris-mode", class_support, cris_mode_enums,
+                        &usr_cmd_cris_mode,
+                        "Set the current CRIS mode.", &setlist);
+  set_cmd_sfunc (c, cris_mode_update);
+  deprecated_add_show_from_set (c, &showlist);

+  deprecated_add_core_fns (&cris_elf_core_fns);
+
  }

  /* Prints out all target specific values.  */
@@ -3690,37 +3707,65 @@
      {
        fprintf_unfiltered (file, "cris_dump_tdep: tdep->cris_version = %i\n",
                            tdep->cris_version);
-      fprintf_unfiltered (file, "cris_dump_tdep: tdep->cris_dwarf2_cfi = %i\n",
-                          tdep->cris_dwarf2_cfi);
+      fprintf_unfiltered (file, "cris_dump_tdep: tdep->cris_mode = %s\n",
+                          tdep->cris_mode);
      }
  }

  static void
-set_cris_version (char *ignore_args, int from_tty,
-                 struct cmd_list_element *c)
+cris_version_update (char *ignore_args, int from_tty,
+                     struct cmd_list_element *c)
  {
    struct gdbarch_info info;

-  usr_cmd_cris_version_valid = 1;
-
-  /* Update the current architecture, if needed.  */
-  gdbarch_info_init (&info);
-  if (!gdbarch_update_p (info))
-    internal_error (__FILE__, __LINE__,
-                   "cris_gdbarch_update: failed to update architecture.");
+  /* NOTE: cagney/2002-03-17: The deprecated_add_show_from_set()
+     function clones the set command passed as a parameter.  The clone
+     operation will include (BUG?) any ``set'' command callback, if
+     present.  Commands like ``info set'' call all the ``show''
+     command callbacks.  Unfortunately, for ``show'' commands cloned
+     from ``set'', this includes callbacks belonging to ``set''
+     commands.  Making this worse, this only occures if
+     deprecated_add_show_from_set() is called after add_cmd_sfunc()
+     (BUG?).  */
+
+  /* From here on, trust the user's CRIS version setting.  */
+  if (cmd_type (c) == set_cmd)
+    {
+      usr_cmd_cris_version_valid = 1;
+
+      /* Update the current architecture, if needed.  */
+      gdbarch_info_init (&info);
+      if (!gdbarch_update_p (info))
+        internal_error (__FILE__, __LINE__, "cris_gdbarch_update: failed to 
update architecture.");
+    }
  }

  static void
-set_cris_dwarf2_cfi (char *ignore_args, int from_tty,
-                    struct cmd_list_element *c)
+cris_mode_update (char *ignore_args, int from_tty,
+                 struct cmd_list_element *c)
  {
    struct gdbarch_info info;
-
-  /* Update the current architecture, if needed.  */
-  gdbarch_info_init (&info);
-  if (!gdbarch_update_p (info))
-    internal_error (__FILE__, __LINE__,
-                   "cris_gdbarch_update: failed to update architecture.");
+
+  /* NOTE: cagney/2002-03-17: The deprecated_add_show_from_set()
+     function clones the set command passed as a parameter.  The clone
+     operation will include (BUG?) any ``set'' command callback, if
+     present.  Commands like ``info set'' call all the ``show''
+     command callbacks.  Unfortunately, for ``show'' commands cloned
+     from ``set'', this includes callbacks belonging to ``set''
+     commands.  Making this worse, this only occures if
+     deprecated_add_show_from_set() is called after add_cmd_sfunc()
+     (BUG?).  */
+
+  /* From here on, trust the user's CRIS mode setting.  */
+  if (cmd_type (c) == set_cmd)
+    {
+      usr_cmd_cris_mode_valid = 1;
+
+      /* Update the current architecture, if needed.  */
+      gdbarch_info_init (&info);
+      if (!gdbarch_update_p (info))
+        internal_error (__FILE__, __LINE__, "cris_gdbarch_update: failed to 
update architecture.");
+    }
  }

  static struct gdbarch *
@@ -3729,6 +3774,7 @@
    struct gdbarch *gdbarch;
    struct gdbarch_tdep *tdep;
    int cris_version;
+  const char *cris_mode;

    if (usr_cmd_cris_version_valid)
      {
@@ -3741,8 +3787,26 @@
        cris_version = 10;
      }

+  if (usr_cmd_cris_mode_valid)
+    {
+      /* Trust the user's CRIS mode setting.  */
+      cris_mode = usr_cmd_cris_mode;
+    }
+  else if (cris_version == 10)
+    {
+      /* Assume CRIS version 10 is in user mode.  */
+      cris_mode = CRIS_MODE_USER;
+    }
+  else
+    {
+      /* Strictly speaking, older CRIS version don't have a supervisor mode,
+         but we regard its only mode as supervisor mode.  */
+      cris_mode = CRIS_MODE_SUPERVISOR;
+    }
+
    /* Make the current settings visible to the user.  */
    usr_cmd_cris_version = cris_version;
+  usr_cmd_cris_mode = cris_mode;

    /* Find a candidate among the list of pre-declared architectures.  Both
       CRIS version and ABI must match.  */
@@ -3750,10 +3814,8 @@
         arches != NULL;
         arches = gdbarch_list_lookup_by_info (arches->next, &info))
      {
-      if ((gdbarch_tdep (arches->gdbarch)->cris_version
-          == usr_cmd_cris_version)
-         && (gdbarch_tdep (arches->gdbarch)->cris_dwarf2_cfi
-             == usr_cmd_cris_dwarf2_cfi))
+      if ((gdbarch_tdep (arches->gdbarch)->cris_version == cris_version)
+          && (gdbarch_tdep (arches->gdbarch)->cris_mode == cris_mode))
          return arches->gdbarch;
      }

@@ -3761,8 +3823,8 @@
    tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
    gdbarch = gdbarch_alloc (&info, tdep);

-  tdep->cris_version = usr_cmd_cris_version;
-  tdep->cris_dwarf2_cfi = usr_cmd_cris_dwarf2_cfi;
+  tdep->cris_version = cris_version;
+  tdep->cris_mode = cris_mode;

    /* INIT shall ensure that the INFO.BYTE_ORDER is non-zero.  */
    switch (info.byte_order)
@@ -3790,6 +3852,10 @@
    set_gdbarch_pc_regnum (gdbarch, 15);
    set_gdbarch_register_name (gdbarch, cris_register_name);

+  /* Length of ordinary registers used in push_word and a few other
+     places.  register_size() is the real way to know how big a
+     register is.  */
+  set_gdbarch_deprecated_register_size (gdbarch, 4);
    set_gdbarch_double_bit (gdbarch, 64);
    /* The default definition of a long double is 2 * TARGET_DOUBLE_BIT,
       which means we have to set this explicitly.  */
@@ -3843,13 +3909,10 @@
    set_gdbarch_unwind_sp (gdbarch, cris_unwind_sp);
    set_gdbarch_unwind_dummy_id (gdbarch, cris_unwind_dummy_id);

-  if (tdep->cris_dwarf2_cfi == 1)
-    {
-      /* Hook in the Dwarf-2 frame sniffer. */
-      set_gdbarch_dwarf2_reg_to_regnum (gdbarch, cris_dwarf2_reg_to_regnum);
-      dwarf2_frame_set_init_reg (gdbarch, cris_dwarf2_frame_init_reg);
-      frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
-    }
+  /* Dwarf-2 frame sniffer stuff. */
+  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, cris_dwarf2_reg_to_regnum);
+  dwarf2_frame_set_init_reg (gdbarch, cris_dwarf2_frame_init_reg);
+  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);

    frame_unwind_append_sniffer (gdbarch, cris_sigtramp_frame_sniffer);

ironmaiden: gdb-fresh/src/gdb> cvs diff -u cris-tdep.c | less
cvs [diff aborted]: received broken pipe signal
ironmaiden: gdb-fresh/src/gdb> cvs diff -up cris-tdep.c | less
ironmaiden: gdb-fresh/src/gdb> cvs diff -up cris-tdep.c > patch
ironmaiden: gdb-fresh/src/gdb> cvs diff -up cris-tdep.c > patch
ironmaiden: gdb-fresh/src/gdb> cvs diff -up ChangeLog cris-tdep.c > ~/patch
ironmaiden: gdb-fresh/src/gdb> cat ~/patch
Index: ChangeLog
===================================================================
RCS file: /cvs/src/src/gdb/ChangeLog,v
retrieving revision 1.6474
diff -u -p -r1.6474 ChangeLog
--- ChangeLog   11 Oct 2004 05:26:24 -0000      1.6474
+++ ChangeLog   11 Oct 2004 14:43:35 -0000
@@ -1,3 +1,29 @@
+2004-10-11  Orjan Friberg  <orjanf@axis.com>
+
+       * cris-tdep.c (cris_sigtramp_start, cris_rt_sigtramp_start)
+       (cris_sigcontext_addr, cris_sigtramp_frame_unwind_cache)
+       (cris_sigtramp_frame_this_id, cris_sigtramp_frame_prev_register)
+       (cris_sigtramp_frame_sniffer): New functions.
+       (cris_gdbarch_init): Hook in signal trampoline unwinder.
+       (cris_dwarf2_reg_to_regnum, cris_dwarf2_frame_init_reg): New functions.
+       (cris_gdbarch_init): Hook in Dwarf-2 unwinder.
+       (struct gdbarch_tdep, set_cris_dwarf2_cfi, cris_dump_tdep)
+       (cris_gdbarch_init, _initialize_cris_tdep): Add CRIS Dwarf-2 CFI usage
+       command.
+       (cris_version_update): Remove, replace with ...
+       (set_cris_version): New function.
+       (struct gdbarch_tdep, cris_mode, cris_mode_update)
+       (cris_cannot_store_register, cris_dump_tdep, cris_gdbarch_init)
+       (_initialize_cris_tdep): Remove CRIS mode command.
+       (cris_fpless_backtrace, _initialize_cris_tdep): Remove
+       cris-fpless-backtrace command.
+       (cris_scan_prologue): Fix prologue scanning limit.
+       (cris_register_type): Update to reflect actual registers.
+       (cris_register_bytes_ok) Remove.
+       (cris_gdbarch_init): Remove support for CRIS v8 and v9.
+       Remove set_gdbarch_deprecated_register_size,
+       set_gdbarch_deprecated_register_byte, set_gdbarch_register_bytes_ok.
+
  2004-10-10  Andrew Cagney  <cagney@gnu.org>

         * ada-lang.c (lim_warning): Add ATTR_FORMAT prototype and FIXME
Index: cris-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/cris-tdep.c,v
retrieving revision 1.116
diff -u -p -r1.116 cris-tdep.c
--- cris-tdep.c 3 Aug 2004 03:58:49 -0000       1.116
+++ cris-tdep.c 11 Oct 2004 14:43:36 -0000
@@ -42,12 +42,11 @@ Foundation, Inc., 59 Temple Place - Suit
  /* To get entry_point_address.  */
  #include "objfiles.h"

-#include "solib.h"              /* Support for shared libraries. */
+#include "solib.h"              /* Support for shared libraries.  */
  #include "solib-svr4.h"         /* For struct link_map_offsets.  */
  #include "gdb_string.h"
  #include "dis-asm.h"

-
  enum cris_num_regs
  {
    /* There are no floating point registers.  Used in gdbserver low-linux.c.  */
@@ -108,32 +107,19 @@ extern const struct cris_spec_reg cris_s

  /* CRIS version, set via the user command 'set cris-version'.  Affects
     register names and sizes.*/
-static int usr_cmd_cris_version;
+static unsigned int usr_cmd_cris_version;

  /* Indicates whether to trust the above variable.  */
  static int usr_cmd_cris_version_valid = 0;

-/* CRIS mode, set via the user command 'set cris-mode'.  Affects availability
-   of some registers.  */
-static const char *usr_cmd_cris_mode;
-
-/* Indicates whether to trust the above variable.  */
-static int usr_cmd_cris_mode_valid = 0;
-
-static const char CRIS_MODE_USER[] = "CRIS_MODE_USER";
-static const char CRIS_MODE_SUPERVISOR[] = "CRIS_MODE_SUPERVISOR";
-static const char *cris_mode_enums[] =
-{
-  CRIS_MODE_USER,
-  CRIS_MODE_SUPERVISOR,
-  0
-};
+/* Whether to make use of Dwarf-2 CFI (default on).  */
+static int usr_cmd_cris_dwarf2_cfi = 1;

  /* CRIS architecture specific information.  */
  struct gdbarch_tdep
  {
-  int cris_version;
-  const char *cris_mode;
+  unsigned int cris_version;
+  int cris_dwarf2_cfi;
  };

  /* Functions for accessing target dependent data.  */
@@ -144,10 +130,121 @@ cris_version (void)
    return (gdbarch_tdep (current_gdbarch)->cris_version);
  }

-static const char *
-cris_mode (void)
+/* Sigtramp identification code copied from i386-linux-tdep.c.  */
+
+#define SIGTRAMP_INSN0    0x9c5f  /* movu.w 0xXX, $r9 */
+#define SIGTRAMP_OFFSET0  0
+#define SIGTRAMP_INSN1    0xe93d  /* break 13 */
+#define SIGTRAMP_OFFSET1  4
+
+static const unsigned short sigtramp_code[] =
+{
+  SIGTRAMP_INSN0, 0x0077,  /* movu.w $0x77, $r9 */
+  SIGTRAMP_INSN1           /* break 13 */
+};
+
+#define SIGTRAMP_LEN (sizeof sigtramp_code)
+
+/* Note: same length as normal sigtramp code.  */
+
+static const unsigned short rt_sigtramp_code[] =
  {
-  return (gdbarch_tdep (current_gdbarch)->cris_mode);
+  SIGTRAMP_INSN0, 0x00ad,  /* movu.w $0xad, $r9 */
+  SIGTRAMP_INSN1           /* break 13 */
+};
+
+/* If PC is in a sigtramp routine, return the address of the start of
+   the routine.  Otherwise, return 0.  */
+
+static CORE_ADDR
+cris_sigtramp_start (struct frame_info *next_frame)
+{
+  CORE_ADDR pc = frame_pc_unwind (next_frame);
+  unsigned short buf[SIGTRAMP_LEN];
+
+  if (!safe_frame_unwind_memory (next_frame, pc, buf, SIGTRAMP_LEN))
+    return 0;
+
+  if (buf[0] != SIGTRAMP_INSN0)
+    {
+      if (buf[0] != SIGTRAMP_INSN1)
+       return 0;
+
+      pc -= SIGTRAMP_OFFSET1;
+      if (!safe_frame_unwind_memory (next_frame, pc, buf, SIGTRAMP_LEN))
+       return 0;
+    }
+
+  if (memcmp (buf, sigtramp_code, SIGTRAMP_LEN) != 0)
+    return 0;
+
+  return pc;
+}
+
+/* If PC is in a RT sigtramp routine, return the address of the start of
+   the routine.  Otherwise, return 0.  */
+
+static CORE_ADDR
+cris_rt_sigtramp_start (struct frame_info *next_frame)
+{
+  CORE_ADDR pc = frame_pc_unwind (next_frame);
+  unsigned short buf[SIGTRAMP_LEN];
+
+  if (!safe_frame_unwind_memory (next_frame, pc, buf, SIGTRAMP_LEN))
+    return 0;
+
+  if (buf[0] != SIGTRAMP_INSN0)
+    {
+      if (buf[0] != SIGTRAMP_INSN1)
+       return 0;
+
+      pc -= SIGTRAMP_OFFSET1;
+      if (!safe_frame_unwind_memory (next_frame, pc, buf, SIGTRAMP_LEN))
+       return 0;
+    }
+
+  if (memcmp (buf, rt_sigtramp_code, SIGTRAMP_LEN) != 0)
+    return 0;
+
+  return pc;
+}
+
+/* Assuming NEXT_FRAME is a frame following a GNU/Linux sigtramp
+   routine, return the address of the associated sigcontext structure.  */
+
+static CORE_ADDR
+cris_sigcontext_addr (struct frame_info *next_frame)
+{
+  CORE_ADDR pc;
+  CORE_ADDR sp;
+  char buf[4];
+
+  frame_unwind_register (next_frame, SP_REGNUM, buf);
+  sp = extract_unsigned_integer (buf, 4);
+
+  /* Look for normal sigtramp frame first.  */
+  pc = cris_sigtramp_start (next_frame);
+  if (pc)
+    {
+      /* struct signal_frame (arch/cris/kernel/signal.c) contains
+        struct sigcontext as its first member, meaning the SP points to
+        it already.  */
+      return sp;
+    }
+
+  pc = cris_rt_sigtramp_start (next_frame);
+  if (pc)
+    {
+      /* struct rt_signal_frame (arch/cris/kernel/signal.c) contains
+        a struct ucontext, which in turn contains a struct sigcontext.
+        Magic digging:
+        4 + 4 + 128 to struct ucontext, then
+        4 + 4 + 12 to struct sigcontext.  */
+      return (sp + 156);
+    }
+
+  error ("Couldn't recognize signal trampoline.");
+  return 0;
  }

  struct cris_unwind_cache
@@ -173,6 +270,111 @@ struct cris_unwind_cache
    struct trad_frame_saved_reg *saved_regs;
  };

+static struct cris_unwind_cache *
+cris_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
+                                 void **this_cache)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct cris_unwind_cache *info;
+  CORE_ADDR pc;
+  CORE_ADDR sp;
+  CORE_ADDR addr;
+  char buf[4];
+  int i;
+
+  if ((*this_cache))
+    return (*this_cache);
+
+  info = FRAME_OBSTACK_ZALLOC (struct cris_unwind_cache);
+  (*this_cache) = info;
+  info->saved_regs = trad_frame_alloc_saved_regs (next_frame);
+
+  /* Zero all fields.  */
+  info->prev_sp = 0;
+  info->base = 0;
+  info->size = 0;
+  info->sp_offset = 0;
+  info->r8_offset = 0;
+  info->uses_frame = 0;
+  info->return_pc = 0;
+  info->leaf_function = 0;
+
+  frame_unwind_register (next_frame, SP_REGNUM, buf);
+  info->base = extract_unsigned_integer (buf, 4);
+
+  addr = cris_sigcontext_addr (next_frame);
+
+  /* Layout of the sigcontext struct:
+     struct sigcontext {
+       struct pt_regs regs;
+       unsigned long oldmask;
+       unsigned long usp;
+     }; */
+
+  /* R0 to R13 are stored in reverse order at offset (2 * 4) in
+     struct pt_regs.  */
+  for (i = 0; i <= 13; i++)
+    info->saved_regs[i].addr = addr + ((15 - i) * 4);
+
+  info->saved_regs[MOF_REGNUM].addr = addr + (16 * 4);
+  info->saved_regs[DCCR_REGNUM].addr = addr + (17 * 4);
+  info->saved_regs[SRP_REGNUM].addr = addr + (18 * 4);
+  /* Note: IRP is off by 2 at this point.  There's no point in correcting it
+     though since that will mean that the backtrace will show a PC different
+     from what is shown when stopped.  */
+  info->saved_regs[IRP_REGNUM].addr = addr + (19 * 4);
+  info->saved_regs[PC_REGNUM] = info->saved_regs[IRP_REGNUM];
+  info->saved_regs[SP_REGNUM].addr = addr + (24 * 4);
+
+  return info;
+}
+
+static void
+cris_sigtramp_frame_this_id (struct frame_info *next_frame, void **this_cache,
+                             struct frame_id *this_id)
+{
+  struct cris_unwind_cache *cache =
+    cris_sigtramp_frame_unwind_cache (next_frame, this_cache);
+  (*this_id) = frame_id_build (cache->base, frame_pc_unwind (next_frame));
+}
+
+/* Forward declaration.  */
+
+static void cris_frame_prev_register (struct frame_info *next_frame,
+                                     void **this_prologue_cache,
+                                     int regnum, int *optimizedp,
+                                     enum lval_type *lvalp, CORE_ADDR *addrp,
+                                     int *realnump, void *bufferp);
+static void
+cris_sigtramp_frame_prev_register (struct frame_info *next_frame,
+                                   void **this_cache,
+                                   int regnum, int *optimizedp,
+                                   enum lval_type *lvalp, CORE_ADDR *addrp,
+                                   int *realnump, void *valuep)
+{
+  /* Make sure we've initialized the cache.  */
+  cris_sigtramp_frame_unwind_cache (next_frame, this_cache);
+  cris_frame_prev_register (next_frame, this_cache, regnum,
+                            optimizedp, lvalp, addrp, realnump, valuep);
+}
+
+static const struct frame_unwind cris_sigtramp_frame_unwind =
+{
+  SIGTRAMP_FRAME,
+  cris_sigtramp_frame_this_id,
+  cris_sigtramp_frame_prev_register
+};
+
+static const struct frame_unwind *
+cris_sigtramp_frame_sniffer (struct frame_info *next_frame)
+{
+  if (cris_sigtramp_start (next_frame)
+      || cris_rt_sigtramp_start (next_frame))
+    return &cris_sigtramp_frame_unwind;
+
+  return NULL;
+}
+
  /* The instruction environment needed to find single-step breakpoints.  */
  typedef
  struct instruction_environment
@@ -345,11 +547,11 @@ static struct gdbarch *cris_gdbarch_init

  static void cris_dump_tdep (struct gdbarch *, struct ui_file *);

-static void cris_version_update (char *ignore_args, int from_tty,
-                                 struct cmd_list_element *c);
+static void set_cris_version (char *ignore_args, int from_tty,
+                             struct cmd_list_element *c);

-static void cris_mode_update (char *ignore_args, int from_tty,
-                              struct cmd_list_element *c);
+static void set_cris_dwarf2_cfi (char *ignore_args, int from_tty,
+                                struct cmd_list_element *c);

  static CORE_ADDR cris_scan_prologue (CORE_ADDR pc,
                                      struct frame_info *next_frame,
@@ -362,9 +564,8 @@ static CORE_ADDR cris_unwind_sp (struct
                                  struct frame_info *next_frame);

  /* When arguments must be pushed onto the stack, they go on in reverse
-   order.  The below implements a FILO (stack) to do this. */
-
-/* Borrowed from d10v-tdep.c.  */
+   order.  The below implements a FILO (stack) to do this.
+   Copied from d10v-tdep.c.  */

  struct stack_item
  {
@@ -399,7 +600,7 @@ pop_stack_item (struct stack_item *si)
     the saved registers of frame described by FRAME_INFO.  This
     includes special registers such as pc and fp saved in special ways
     in the stack frame.  sp is even more special: the address we return
-   for it IS the sp for the next frame. */
+   for it IS the sp for the next frame.  */

  struct cris_unwind_cache *
  cris_frame_unwind_cache (struct frame_info *next_frame,
@@ -531,7 +732,7 @@ cris_push_dummy_call (struct gdbarch *gd

    struct stack_item *si = NULL;

-  /* Push the return address. */
+  /* Push the return address.  */
    regcache_cooked_write_unsigned (regcache, SRP_REGNUM, bp_addr);

    /* Are we returning a value using a structure return or a normal value
@@ -767,7 +968,7 @@ cris_scan_prologue (CORE_ADDR pc, struct
    limit = next_frame ? frame_pc_unwind (next_frame) : pc + 64;

    /* Find the prologue instructions.  */
-  while (pc < limit)
+  while (pc > 0 && pc < limit)
      {
        insn = read_memory_unsigned_integer (pc, 2);
        pc += 2;
@@ -1169,13 +1370,8 @@ cris_cannot_store_register (int regno)
      /* Writing has no effect.  */
      return 1;

-  else if (cris_mode () == CRIS_MODE_USER)
-    {
-      if (regno == IBR_REGNUM || regno == BAR_REGNUM || regno == BRP_REGNUM
-          || regno == IRP_REGNUM)
-        /* Read-only in user mode.  */
-        return 1;
-    }
+  /* IBR, BAR, BRP and IRP are read-only in user mode.  Let the debug
+     agent decide whether they are writable.  */

    return 0;
  }
@@ -1202,7 +1398,7 @@ cris_register_offset (int regno)
      }
    else
      {
-      /* Invalid register. */
+      /* Invalid register.  */
        return -1;
      }
  }
@@ -1213,33 +1409,21 @@ cris_register_offset (int regno)
  static struct type *
  cris_register_type (struct gdbarch *gdbarch, int regno)
  {
-  if (regno == SP_REGNUM || regno == PC_REGNUM
-      || (regno > P8_REGNUM && regno < USP_REGNUM))
-    {
-      /* SP, PC, IBR, IRP, SRP, BAR, DCCR, BRP */
-      return lookup_pointer_type (builtin_type_void);
-    }
-  else if (regno == P8_REGNUM || regno == USP_REGNUM
-           || (regno >= 0 && regno < SP_REGNUM))
-    {
-      /* R0 - R13, P8, P15 */
-      return builtin_type_unsigned_long;
-    }
-  else if (regno > P3_REGNUM && regno < P8_REGNUM)
-    {
-      /* P4, CCR, DCR0, DCR1 */
-      return builtin_type_unsigned_short;
-    }
-  else if (regno > PC_REGNUM && regno < P4_REGNUM)
-    {
-      /* P0, P1, P2, P3 */
-      return builtin_type_unsigned_char;
-    }
+  if (regno == PC_REGNUM)
+    return builtin_type_void_func_ptr;
+  else if (regno == SP_REGNUM || regno == CRIS_FP_REGNUM)
+    return builtin_type_void_data_ptr;
+  else if ((regno >= 0 && regno < SP_REGNUM)
+          || (regno >= MOF_REGNUM && regno <= USP_REGNUM))
+    /* Note: R8 taken care of previous clause.  */
+    return builtin_type_uint32;
+  else if (regno >= P4_REGNUM && regno <= CCR_REGNUM)
+      return builtin_type_uint16;
+  else if (regno >= P0_REGNUM && regno <= VR_REGNUM)
+      return builtin_type_uint8;
    else
-    {
-      /* Invalid register.  */
-      return builtin_type_void;
-    }
+      /* Invalid (unimplemented) register.  */
+      return builtin_type_int0;
  }

  /* Stores a function return value of type type, where valbuf is the address
@@ -1317,10 +1501,49 @@ cris_register_name (int regno)
      }
  }

+/* Convert DWARF register number REG to the appropriate register
+   number used by GDB.  */
+
  static int
-cris_register_bytes_ok (long bytes)
+cris_dwarf2_reg_to_regnum (int reg)
+{
+  /* We need to re-map a couple of registers (SRP is 16 in Dwarf-2 register
+     numbering, MOF is 18).
+     Adapted from gcc/config/cris/cris.h.  */
+  static int cris_dwarf_regmap[] = {
+    0,  1,  2,  3,
+    4,  5,  6,  7,
+    8,  9,  10, 11,
+    12, 13, 14, 15,
+    27, -1, -1, -1,
+    -1, -1, -1, 23,
+    -1, -1, -1, 27,
+    -1, -1, -1, -1
+  };
+  int regnum = -1;
+
+  if (reg >= 0 && reg < ARRAY_SIZE (cris_dwarf_regmap))
+    regnum = cris_dwarf_regmap[reg];
+
+  if (regnum == -1)
+    warning ("Unmapped DWARF Register #%d encountered\n", reg);
+
+  return regnum;
+}
+
+/* DWARF-2 frame support.  */
+
+static void
+cris_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
+                            struct dwarf2_frame_state_reg *reg)
  {
-  return (bytes == deprecated_register_bytes ());
+  /* The return address column.  */
+  if (regnum == PC_REGNUM)
+    reg->how = DWARF2_FRAME_REG_RA;
+
+  /* The call frame address.  */
+  else if (regnum == SP_REGNUM)
+    reg->how = DWARF2_FRAME_REG_CFA;
  }

  /* Extract from an array regbuf containing the raw register state a function
@@ -1596,6 +1819,7 @@ cris_software_single_step (enum target_s
        if (status == -1)
          {
            /* Could not find a target.  FIXME: Should do something.  */
+          warning ("cris_software_single_step: unable to find step target");
          }
        else
          {
@@ -3312,7 +3536,7 @@ cris_delayed_get_disassembler (bfd_vma a
       disassembler, even when there is no BFD.  Does something like
       "gdb; target remote; disassmeble *0x123" work?  */
    gdb_assert (exec_bfd != NULL);
-  print_insn =  cris_get_disassembler (exec_bfd);
+  print_insn = cris_get_disassembler (exec_bfd);
    gdb_assert (print_insn != NULL);
    return print_insn (addr, info);
  }
@@ -3423,230 +3647,37 @@ cris_linux_svr4_fetch_link_map_offsets (
    return lmp;
  }

-static void
-cris_fpless_backtrace (char *noargs, int from_tty)
-{
-  /* Points at the instruction after the jsr (except when in innermost frame
-     where it points at the original pc).  */
-  CORE_ADDR pc = 0;
-
-  /* Temporary variable, used for parsing from the start of the function that
-     the pc is in, up to the pc.  */
-  CORE_ADDR tmp_pc = 0;
-  CORE_ADDR sp = 0;
-
-  /* Information about current frame.  */
-  struct symtab_and_line sal;
-  char* func_name;
-
-  /* Present instruction.  */
-  unsigned short insn;
-
-  /* Next instruction, lookahead.  */
-  unsigned short insn_next;
-
-  /* This is to store the offset between sp at start of function and until we
-     reach push srp (if any).  */
-  int sp_add_later = 0;
-  int push_srp_found = 0;
-
-  int val = 0;
-
-  /* Frame counter.  */
-  int frame = 0;
-
-  /* For the innermost frame, we want to look at srp in case it's a leaf
-     function (since there's no push srp in that case).  */
-  int innermost_frame = 1;
-
-  deprecated_read_register_gen (PC_REGNUM, (char *) &pc);
-  deprecated_read_register_gen (SP_REGNUM, (char *) &sp);
-
-  /* We make an explicit return when we can't find an outer frame.  */
-  while (1)
-    {
-      /* Get file name and line number.  */
-      sal = find_pc_line (pc, 0);
-
-      /* Get function name.  */
-      find_pc_partial_function (pc, &func_name, (CORE_ADDR *) NULL,
-                                (CORE_ADDR *) NULL);
-
-      /* Print information about current frame.  */
-      printf_unfiltered ("#%i  0x%08lx in %s", frame++, pc, func_name);
-      if (sal.symtab)
-        {
-          printf_unfiltered (" at %s:%i", sal.symtab->filename, sal.line);
-        }
-      printf_unfiltered ("\n");
-
-      /* Get the start address of this function.  */
-      tmp_pc = get_pc_function_start (pc);
-
-      /* Mini parser, only meant to find push sp and sub ...,sp from the start
-         of the function, up to the pc.  */
-      while (tmp_pc < pc)
-        {
-          insn = read_memory_unsigned_integer (tmp_pc, sizeof (short));
-          tmp_pc += sizeof (short);
-          if (insn == 0xE1FC)
-            {
-              /* push <reg> 32 bit instruction */
-              insn_next = read_memory_unsigned_integer (tmp_pc,
-                                                        sizeof (short));
-              tmp_pc += sizeof (short);
-
-              /* Recognize srp.  */
-              if (insn_next == 0xBE7E)
-                {
-                  /* For subsequent (not this one though) push or sub which
-                     affects sp, adjust sp immediately.  */
-                  push_srp_found = 1;
-
-                  /* Note: this will break if we ever encounter a
-                     push vr (1 byte) or push ccr (2 bytes).  */
-                  sp_add_later += 4;
-                }
-              else
-                {
-                  /* Some other register was pushed.  */
-                  if (push_srp_found)
-                    {
-                      sp += 4;
-                    }
-                  else
-                    {
-                      sp_add_later += 4;
-                    }
-                }
-            }
-          else if (cris_get_operand2 (insn) == SP_REGNUM
-                   && cris_get_mode (insn) == 0x0000
-                   && cris_get_opcode (insn) == 0x000A)
-            {
-              /* subq <val>,sp */
-              val = cris_get_quick_value (insn);
-
-              if (push_srp_found)
-                {
-                  sp += val;
-                }
-              else
-                {
-                  sp_add_later += val;
-                }
-
-            }
-          else if (cris_get_operand2 (insn) == SP_REGNUM
-                   /* Autoincrement addressing mode.  */
-                   && cris_get_mode (insn) == 0x0003
-                   /* Opcode.  */
-                   && ((insn) & 0x03E0) >> 5 == 0x0004)
-            {
-              /* subu <val>,sp */
-              val = get_data_from_address (&insn, tmp_pc);
-
-              if (push_srp_found)
-                {
-                  sp += val;
-                }
-              else
-                {
-                  sp_add_later += val;
-                }
-            }
-          else if (cris_get_operand2 (insn) == SP_REGNUM
-                   && ((insn & 0x0F00) >> 8) == 0x0001
-                   && (cris_get_signed_offset (insn) < 0))
-            {
-              /* Immediate byte offset addressing prefix word with sp as base
-                 register.  Used for CRIS v8 i.e. ETRAX 100 and newer if <val>
-                 is between 64 and 128.
-                 movem r<regsave>,[sp=sp-<val>] */
-              val = -cris_get_signed_offset (insn);
-              insn_next = read_memory_unsigned_integer (tmp_pc,
-                                                        sizeof (short));
-              tmp_pc += sizeof (short);
-
-              if (cris_get_mode (insn_next) == PREFIX_ASSIGN_MODE
-                  && cris_get_opcode (insn_next) == 0x000F
-                  && cris_get_size (insn_next) == 0x0003
-                  && cris_get_operand1 (insn_next) == SP_REGNUM)
-                {
-                  if (push_srp_found)
-                    {
-                      sp += val;
-                    }
-                  else
-                    {
-                      sp_add_later += val;
-                    }
-                }
-            }
-        }
-
-      if (push_srp_found)
-        {
-          /* Reset flag.  */
-          push_srp_found = 0;
-
-          /* sp should now point at where srp is stored on the stack.  Update
-             the pc to the srp.  */
-          pc = read_memory_unsigned_integer (sp, 4);
-        }
-      else if (innermost_frame)
-        {
-          /* We couldn't find a push srp in the prologue, so this must be
-             a leaf function, and thus we use the srp register directly.
-             This should happen at most once, for the innermost function.  */
-          deprecated_read_register_gen (SRP_REGNUM, (char *) &pc);
-        }
-      else
-        {
-          /* Couldn't find an outer frame.  */
-          return;
-        }
-
-      /* Reset flag.  (In case the innermost frame wasn't a leaf, we don't
-         want to look at the srp register later either).  */
-      innermost_frame = 0;
-
-      /* Now, add the offset for everything up to, and including push srp,
-         that was held back during the prologue parsing.  */
-      sp += sp_add_later;
-      sp_add_later = 0;
-    }
-}
-
  extern initialize_file_ftype _initialize_cris_tdep; /* -Wmissing-prototypes */

  void
  _initialize_cris_tdep (void)
  {
+  static struct cmd_list_element *cris_set_cmdlist;
+  static struct cmd_list_element *cris_show_cmdlist;
+
    struct cmd_list_element *c;

    gdbarch_register (bfd_arch_cris, cris_gdbarch_init, cris_dump_tdep);

    /* CRIS-specific user-commands.  */
-  c = add_set_cmd ("cris-version", class_support, var_integer,
-                   (char *) &usr_cmd_cris_version,
-                   "Set the current CRIS version.", &setlist);
-  set_cmd_sfunc (c, cris_version_update);
-  deprecated_add_show_from_set (c, &showlist);
-
-  c = add_set_enum_cmd ("cris-mode", class_support, cris_mode_enums,
-                        &usr_cmd_cris_mode,
-                        "Set the current CRIS mode.", &setlist);
-  set_cmd_sfunc (c, cris_mode_update);
-  deprecated_add_show_from_set (c, &showlist);
-
-  c = add_cmd ("cris-fpless-backtrace", class_support, cris_fpless_backtrace,
-               "Display call chain using the subroutine return pointer.\n"
-               "Note that this displays the address after the jump to the "
-               "subroutine.", &cmdlist);
-
-  deprecated_add_core_fns (&cris_elf_core_fns);
-
+  add_setshow_uinteger_cmd ("cris-version", class_support,
+                           &usr_cmd_cris_version,
+                           "Set the current CRIS version.",
+                           "Show the current CRIS version.",
+                           "Set if autodetection fails.",
+                           "Current CRIS version is %s.",
+                           set_cris_version, NULL,
+                           &setlist, &showlist);
+
+  add_setshow_boolean_cmd ("cris-dwarf2-cfi", class_support,
+                          &usr_cmd_cris_dwarf2_cfi,
+                          "Set the usage of Dwarf-2 CFI for CRIS.",
+                          "Show the usage of Dwarf-2 CFI for CRIS.",
+                          "Set to \"off\" if using gcc-cris < R59.",
+                          "Usage of Dwarf-2 CFI for CRIS is %d.",
+                          set_cris_dwarf2_cfi, NULL,
+                          &setlist, &showlist);
+
  }

  /* Prints out all target specific values.  */
@@ -3659,65 +3690,37 @@ cris_dump_tdep (struct gdbarch *gdbarch,
      {
        fprintf_unfiltered (file, "cris_dump_tdep: tdep->cris_version = %i\n",
                            tdep->cris_version);
-      fprintf_unfiltered (file, "cris_dump_tdep: tdep->cris_mode = %s\n",
-                          tdep->cris_mode);
+      fprintf_unfiltered (file, "cris_dump_tdep: tdep->cris_dwarf2_cfi = %i\n",
+                          tdep->cris_dwarf2_cfi);
      }
  }

  static void
-cris_version_update (char *ignore_args, int from_tty,
-                     struct cmd_list_element *c)
+set_cris_version (char *ignore_args, int from_tty,
+                 struct cmd_list_element *c)
  {
    struct gdbarch_info info;

-  /* NOTE: cagney/2002-03-17: The deprecated_add_show_from_set()
-     function clones the set command passed as a parameter.  The clone
-     operation will include (BUG?) any ``set'' command callback, if
-     present.  Commands like ``info set'' call all the ``show''
-     command callbacks.  Unfortunately, for ``show'' commands cloned
-     from ``set'', this includes callbacks belonging to ``set''
-     commands.  Making this worse, this only occures if
-     deprecated_add_show_from_set() is called after add_cmd_sfunc()
-     (BUG?).  */
-
-  /* From here on, trust the user's CRIS version setting.  */
-  if (cmd_type (c) == set_cmd)
-    {
-      usr_cmd_cris_version_valid = 1;
-
-      /* Update the current architecture, if needed.  */
-      gdbarch_info_init (&info);
-      if (!gdbarch_update_p (info))
-        internal_error (__FILE__, __LINE__, "cris_gdbarch_update: failed to 
update architecture.");
-    }
+  usr_cmd_cris_version_valid = 1;
+
+  /* Update the current architecture, if needed.  */
+  gdbarch_info_init (&info);
+  if (!gdbarch_update_p (info))
+    internal_error (__FILE__, __LINE__,
+                   "cris_gdbarch_update: failed to update architecture.");
  }

  static void
-cris_mode_update (char *ignore_args, int from_tty,
-                 struct cmd_list_element *c)
+set_cris_dwarf2_cfi (char *ignore_args, int from_tty,
+                    struct cmd_list_element *c)
  {
    struct gdbarch_info info;
-
-  /* NOTE: cagney/2002-03-17: The deprecated_add_show_from_set()
-     function clones the set command passed as a parameter.  The clone
-     operation will include (BUG?) any ``set'' command callback, if
-     present.  Commands like ``info set'' call all the ``show''
-     command callbacks.  Unfortunately, for ``show'' commands cloned
-     from ``set'', this includes callbacks belonging to ``set''
-     commands.  Making this worse, this only occures if
-     deprecated_add_show_from_set() is called after add_cmd_sfunc()
-     (BUG?).  */
-
-  /* From here on, trust the user's CRIS mode setting.  */
-  if (cmd_type (c) == set_cmd)
-    {
-      usr_cmd_cris_mode_valid = 1;
-
-      /* Update the current architecture, if needed.  */
-      gdbarch_info_init (&info);
-      if (!gdbarch_update_p (info))
-        internal_error (__FILE__, __LINE__, "cris_gdbarch_update: failed to 
update architecture.");
-    }
+
+  /* Update the current architecture, if needed.  */
+  gdbarch_info_init (&info);
+  if (!gdbarch_update_p (info))
+    internal_error (__FILE__, __LINE__,
+                   "cris_gdbarch_update: failed to update architecture.");
  }

  static struct gdbarch *
@@ -3726,8 +3729,6 @@ cris_gdbarch_init (struct gdbarch_info i
    struct gdbarch *gdbarch;
    struct gdbarch_tdep *tdep;
    int cris_version;
-  const char *cris_mode;
-  int register_bytes;

    if (usr_cmd_cris_version_valid)
      {
@@ -3740,26 +3741,8 @@ cris_gdbarch_init (struct gdbarch_info i
        cris_version = 10;
      }

-  if (usr_cmd_cris_mode_valid)
-    {
-      /* Trust the user's CRIS mode setting.  */
-      cris_mode = usr_cmd_cris_mode;
-    }
-  else if (cris_version == 10)
-    {
-      /* Assume CRIS version 10 is in user mode.  */
-      cris_mode = CRIS_MODE_USER;
-    }
-  else
-    {
-      /* Strictly speaking, older CRIS version don't have a supervisor mode,
-         but we regard its only mode as supervisor mode.  */
-      cris_mode = CRIS_MODE_SUPERVISOR;
-    }
-
    /* Make the current settings visible to the user.  */
    usr_cmd_cris_version = cris_version;
-  usr_cmd_cris_mode = cris_mode;

    /* Find a candidate among the list of pre-declared architectures.  Both
       CRIS version and ABI must match.  */
@@ -3767,8 +3750,10 @@ cris_gdbarch_init (struct gdbarch_info i
         arches != NULL;
         arches = gdbarch_list_lookup_by_info (arches->next, &info))
      {
-      if ((gdbarch_tdep (arches->gdbarch)->cris_version == cris_version)
-          && (gdbarch_tdep (arches->gdbarch)->cris_mode == cris_mode))
+      if ((gdbarch_tdep (arches->gdbarch)->cris_version
+          == usr_cmd_cris_version)
+         && (gdbarch_tdep (arches->gdbarch)->cris_dwarf2_cfi
+             == usr_cmd_cris_dwarf2_cfi))
          return arches->gdbarch;
      }

@@ -3776,8 +3761,8 @@ cris_gdbarch_init (struct gdbarch_info i
    tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
    gdbarch = gdbarch_alloc (&info, tdep);

-  tdep->cris_version = cris_version;
-  tdep->cris_mode = cris_mode;
+  tdep->cris_version = usr_cmd_cris_version;
+  tdep->cris_dwarf2_cfi = usr_cmd_cris_dwarf2_cfi;

    /* INIT shall ensure that the INFO.BYTE_ORDER is non-zero.  */
    switch (info.byte_order)
@@ -3804,16 +3789,11 @@ cris_gdbarch_init (struct gdbarch_info i
    set_gdbarch_sp_regnum (gdbarch, 14);
    set_gdbarch_pc_regnum (gdbarch, 15);
    set_gdbarch_register_name (gdbarch, cris_register_name);
-
-  /* Length of ordinary registers used in push_word and a few other
-     places.  register_size() is the real way to know how big a
-     register is.  */
-  set_gdbarch_deprecated_register_size (gdbarch, 4);
+
    set_gdbarch_double_bit (gdbarch, 64);
    /* The default definition of a long double is 2 * TARGET_DOUBLE_BIT,
       which means we have to set this explicitly.  */
    set_gdbarch_long_double_bit (gdbarch, 64);
-  set_gdbarch_register_bytes_ok (gdbarch, cris_register_bytes_ok);
    set_gdbarch_cannot_store_register (gdbarch, cris_cannot_store_register);
    set_gdbarch_cannot_fetch_register (gdbarch, cris_cannot_fetch_register);

@@ -3827,33 +3807,23 @@ cris_gdbarch_init (struct gdbarch_info i
      case 1:
      case 2:
      case 3:
-      /* Support for these may be added later.  */
-      internal_error (__FILE__, __LINE__, "cris_gdbarch_init: unsupported CRIS 
version");
-      break;
-
      case 8:
      case 9:
-      /* CRIS v8 and v9, a.k.a. ETRAX 100.  General registers R0 - R15
-         (32 bits), special registers P0 - P1 (8 bits), P4 - P5 (16 bits),
-         and P8 - P14 (32 bits).  */
-      register_bytes = (16 * 4) + (2 * 1) + (2 * 2) + (7 * 4);
+      /* Old versions; not supported.  */
+      internal_error (__FILE__, __LINE__,
+                     "cris_gdbarch_init: unsupported CRIS version");
        break;

      case 10:
      case 11:
        /* CRIS v10 and v11, a.k.a. ETRAX 100LX.  In addition to ETRAX 100,
           P7 (32 bits), and P15 (32 bits) have been implemented.  */
-      register_bytes = (16 * 4) + (2 * 1) + (2 * 2) + (9 * 4);
        break;

      default:
        internal_error (__FILE__, __LINE__, "cris_gdbarch_init: unknown CRIS 
version");
      }

-  /* Returns the register offset for the first byte of register regno's space
-     in the saved register state.  */
-  set_gdbarch_deprecated_register_byte (gdbarch, cris_register_offset);
-
    set_gdbarch_register_type (gdbarch, cris_register_type);

    /* Dummy frame functions.  */
@@ -3873,9 +3843,16 @@ cris_gdbarch_init (struct gdbarch_info i
    set_gdbarch_unwind_sp (gdbarch, cris_unwind_sp);
    set_gdbarch_unwind_dummy_id (gdbarch, cris_unwind_dummy_id);

-  /* FIXME: Hook in the DWARF CFI frame unwinder.
-     frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
-  */
+  if (tdep->cris_dwarf2_cfi == 1)
+    {
+      /* Hook in the Dwarf-2 frame sniffer.  */
+      set_gdbarch_dwarf2_reg_to_regnum (gdbarch, cris_dwarf2_reg_to_regnum);
+      dwarf2_frame_set_init_reg (gdbarch, cris_dwarf2_frame_init_reg);
+      frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
+    }
+
+  frame_unwind_append_sniffer (gdbarch, cris_sigtramp_frame_sniffer);
+
    frame_unwind_append_sniffer (gdbarch, cris_frame_sniffer);
    frame_base_set_default (gdbarch, &cris_frame_base);


-- 
Orjan Friberg
Axis Communications



More information about the Gdb-patches mailing list