* infrun.c (adjust_pc_after_break): Do not assume software single-step
[deliverable/binutils-gdb.git] / gdb / mips-linux-tdep.c
index ff0b124d7d75cc9534af6be4033a58a1918dee89..301843e847c6d3b70a4c3e00173400be89732d2d 100644 (file)
@@ -37,6 +37,7 @@
 #include "solib-svr4.h"
 #include "solist.h"
 #include "symtab.h"
+#include "target-descriptions.h"
 #include "mips-linux-tdep.h"
 
 static struct target_so_ops mips_svr4_so_ops;
@@ -51,19 +52,22 @@ static struct target_so_ops mips_svr4_so_ops;
 #define MIPS_LINUX_JB_PC 0
 
 static int
-mips_linux_get_longjmp_target (CORE_ADDR *pc)
+mips_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
 {
   CORE_ADDR jb_addr;
-  char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
+  char buf[gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT];
 
-  jb_addr = read_register (MIPS_A0_REGNUM);
+  jb_addr = get_frame_register_unsigned (frame, MIPS_A0_REGNUM);
 
   if (target_read_memory (jb_addr
-                         + MIPS_LINUX_JB_PC * MIPS_LINUX_JB_ELEMENT_SIZE,
-                         buf, TARGET_PTR_BIT / TARGET_CHAR_BIT))
+                           + MIPS_LINUX_JB_PC * MIPS_LINUX_JB_ELEMENT_SIZE,
+                         buf,
+                         gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT))
     return 0;
 
-  *pc = extract_unsigned_integer (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+  *pc = extract_unsigned_integer (buf,
+                                 gdbarch_ptr_bit (current_gdbarch)
+                                   / TARGET_CHAR_BIT);
 
   return 1;
 }
@@ -93,9 +97,12 @@ mips_supply_gregset (struct regcache *regcache,
 
   memset (zerobuf, 0, MAX_REGISTER_SIZE);
 
-  for (regi = EF_REG0; regi <= EF_REG31; regi++)
+  for (regi = EF_REG0 + 1; regi <= EF_REG31; regi++)
     supply_32bit_reg (regcache, regi - EF_REG0, regp + regi);
 
+  if (mips_linux_restart_reg_p (current_gdbarch))
+    supply_32bit_reg (regcache, MIPS_RESTART_REGNUM, regp + EF_REG0);
+
   supply_32bit_reg (regcache, mips_regnum (current_gdbarch)->lo,
                    regp + EF_LO);
   supply_32bit_reg (regcache, mips_regnum (current_gdbarch)->hi,
@@ -110,9 +117,10 @@ mips_supply_gregset (struct regcache *regcache,
                    regp + EF_CP0_CAUSE);
 
   /* Fill inaccessible registers with zero.  */
+  regcache_raw_supply (regcache, MIPS_ZERO_REGNUM, zerobuf);
   regcache_raw_supply (regcache, MIPS_UNUSED_REGNUM, zerobuf);
   for (regi = MIPS_FIRST_EMBED_REGNUM;
-       regi < MIPS_LAST_EMBED_REGNUM;
+       regi <= MIPS_LAST_EMBED_REGNUM;
        regi++)
     regcache_raw_supply (regcache, regi, zerobuf);
 }
@@ -130,7 +138,7 @@ mips_fill_gregset (const struct regcache *regcache,
   if (regno == -1)
     {
       memset (regp, 0, sizeof (mips_elf_gregset_t));
-      for (regi = 0; regi < 32; regi++)
+      for (regi = 1; regi < 32; regi++)
        mips_fill_gregset (regcache, gregsetp, regi);
       mips_fill_gregset (regcache, gregsetp,
                         mips_regnum (current_gdbarch)->lo);
@@ -143,10 +151,11 @@ mips_fill_gregset (const struct regcache *regcache,
       mips_fill_gregset (regcache, gregsetp, MIPS_PS_REGNUM);
       mips_fill_gregset (regcache, gregsetp,
                         mips_regnum (current_gdbarch)->cause);
+      mips_fill_gregset (regcache, gregsetp, MIPS_RESTART_REGNUM);
       return;
    }
 
-  if (regno < 32)
+  if (regno > 0 && regno < 32)
     {
       dst = regp + regno + EF_REG0;
       regcache_raw_collect (regcache, regno, dst);
@@ -165,6 +174,9 @@ mips_fill_gregset (const struct regcache *regcache,
     regaddr = EF_CP0_STATUS;
   else if (regno == mips_regnum (current_gdbarch)->cause)
     regaddr = EF_CP0_CAUSE;
+  else if (mips_linux_restart_reg_p (current_gdbarch)
+          && regno == MIPS_RESTART_REGNUM)
+    regaddr = EF_REG0;
   else
     regaddr = -1;
 
@@ -187,7 +199,9 @@ mips_supply_fpregset (struct regcache *regcache,
   memset (zerobuf, 0, MAX_REGISTER_SIZE);
 
   for (regi = 0; regi < 32; regi++)
-    regcache_raw_supply (regcache, FP0_REGNUM + regi, *fpregsetp + regi);
+    regcache_raw_supply (regcache,
+                        gdbarch_fp0_regnum (current_gdbarch) + regi,
+                        *fpregsetp + regi);
 
   regcache_raw_supply (regcache,
                       mips_regnum (current_gdbarch)->fp_control_status,
@@ -208,9 +222,10 @@ mips_fill_fpregset (const struct regcache *regcache,
 {
   char *from, *to;
 
-  if ((regno >= FP0_REGNUM) && (regno < FP0_REGNUM + 32))
+  if ((regno >= gdbarch_fp0_regnum (current_gdbarch))
+      && (regno < gdbarch_fp0_regnum (current_gdbarch) + 32))
     {
-      to = (char *) (*fpregsetp + regno - FP0_REGNUM);
+      to = (char *) (*fpregsetp + regno - gdbarch_fp0_regnum (current_gdbarch));
       regcache_raw_collect (regcache, regno, to);
     }
   else if (regno == mips_regnum (current_gdbarch)->fp_control_status)
@@ -223,7 +238,8 @@ mips_fill_fpregset (const struct regcache *regcache,
       int regi;
 
       for (regi = 0; regi < 32; regi++)
-       mips_fill_fpregset (regcache, fpregsetp, FP0_REGNUM + regi);
+       mips_fill_fpregset (regcache, fpregsetp,
+                           gdbarch_fp0_regnum (current_gdbarch) + regi);
       mips_fill_fpregset (regcache, fpregsetp,
                          mips_regnum (current_gdbarch)->fp_control_status);
     }
@@ -242,19 +258,22 @@ mips_fill_fpregset (const struct regcache *regcache,
 #define MIPS64_LINUX_JB_PC 0
 
 static int
-mips64_linux_get_longjmp_target (CORE_ADDR *pc)
+mips64_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
 {
   CORE_ADDR jb_addr;
-  void *buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
-  int element_size = TARGET_PTR_BIT == 32 ? 4 : 8;
+  void *buf = alloca (gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT);
+  int element_size = gdbarch_ptr_bit (current_gdbarch) == 32 ? 4 : 8;
 
-  jb_addr = read_register (MIPS_A0_REGNUM);
+  jb_addr = get_frame_register_unsigned (frame, MIPS_A0_REGNUM);
 
   if (target_read_memory (jb_addr + MIPS64_LINUX_JB_PC * element_size,
-                         buf, TARGET_PTR_BIT / TARGET_CHAR_BIT))
+                         buf,
+                         gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT))
     return 0;
 
-  *pc = extract_unsigned_integer (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+  *pc = extract_unsigned_integer (buf,
+                                 gdbarch_ptr_bit (current_gdbarch)
+                                   / TARGET_CHAR_BIT);
 
   return 1;
 }
@@ -288,10 +307,14 @@ mips64_supply_gregset (struct regcache *regcache,
 
   memset (zerobuf, 0, MAX_REGISTER_SIZE);
 
-  for (regi = MIPS64_EF_REG0; regi <= MIPS64_EF_REG31; regi++)
+  for (regi = MIPS64_EF_REG0 + 1; regi <= MIPS64_EF_REG31; regi++)
     supply_64bit_reg (regcache, regi - MIPS64_EF_REG0,
                      (const gdb_byte *)(regp + regi));
 
+  if (mips_linux_restart_reg_p (current_gdbarch))
+    supply_64bit_reg (regcache, MIPS_RESTART_REGNUM,
+                     (const gdb_byte *)(regp + MIPS64_EF_REG0));
+
   supply_64bit_reg (regcache, mips_regnum (current_gdbarch)->lo,
                    (const gdb_byte *) (regp + MIPS64_EF_LO));
   supply_64bit_reg (regcache, mips_regnum (current_gdbarch)->hi,
@@ -307,9 +330,10 @@ mips64_supply_gregset (struct regcache *regcache,
                    (const gdb_byte *) (regp + MIPS64_EF_CP0_CAUSE));
 
   /* Fill inaccessible registers with zero.  */
+  regcache_raw_supply (regcache, MIPS_ZERO_REGNUM, zerobuf);
   regcache_raw_supply (regcache, MIPS_UNUSED_REGNUM, zerobuf);
   for (regi = MIPS_FIRST_EMBED_REGNUM;
-       regi < MIPS_LAST_EMBED_REGNUM;
+       regi <= MIPS_LAST_EMBED_REGNUM;
        regi++)
     regcache_raw_supply (regcache, regi, zerobuf);
 }
@@ -327,7 +351,7 @@ mips64_fill_gregset (const struct regcache *regcache,
   if (regno == -1)
     {
       memset (regp, 0, sizeof (mips64_elf_gregset_t));
-      for (regi = 0; regi < 32; regi++)
+      for (regi = 1; regi < 32; regi++)
         mips64_fill_gregset (regcache, gregsetp, regi);
       mips64_fill_gregset (regcache, gregsetp,
                           mips_regnum (current_gdbarch)->lo);
@@ -340,10 +364,11 @@ mips64_fill_gregset (const struct regcache *regcache,
       mips64_fill_gregset (regcache, gregsetp, MIPS_PS_REGNUM);
       mips64_fill_gregset (regcache, gregsetp,
                           mips_regnum (current_gdbarch)->cause);
+      mips64_fill_gregset (regcache, gregsetp, MIPS_RESTART_REGNUM);
       return;
    }
 
-  if (regno < 32)
+  if (regno > 0 && regno < 32)
     regaddr = regno + MIPS64_EF_REG0;
   else if (regno == mips_regnum (current_gdbarch)->lo)
     regaddr = MIPS64_EF_LO;
@@ -357,6 +382,9 @@ mips64_fill_gregset (const struct regcache *regcache,
     regaddr = MIPS64_EF_CP0_STATUS;
   else if (regno == mips_regnum (current_gdbarch)->cause)
     regaddr = MIPS64_EF_CP0_CAUSE;
+  else if (mips_linux_restart_reg_p (current_gdbarch)
+          && regno == MIPS_RESTART_REGNUM)
+    regaddr = MIPS64_EF_REG0;
   else
     regaddr = -1;
 
@@ -383,17 +411,22 @@ mips64_supply_fpregset (struct regcache *regcache,
 
   /* See mips_linux_o32_sigframe_init for a description of the
      peculiar FP register layout.  */
-  if (register_size (current_gdbarch, FP0_REGNUM) == 4)
+  if (register_size (current_gdbarch,
+                    gdbarch_fp0_regnum (current_gdbarch)) == 4)
     for (regi = 0; regi < 32; regi++)
       {
        const gdb_byte *reg_ptr = (const gdb_byte *)(*fpregsetp + (regi & ~1));
-       if ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) != (regi & 1))
+       if ((gdbarch_byte_order (current_gdbarch)
+           == BFD_ENDIAN_BIG) != (regi & 1))
          reg_ptr += 4;
-       regcache_raw_supply (regcache, FP0_REGNUM + regi, reg_ptr);
+       regcache_raw_supply (regcache,
+                            gdbarch_fp0_regnum (current_gdbarch) + regi,
+                            reg_ptr);
       }
   else
     for (regi = 0; regi < 32; regi++)
-      regcache_raw_supply (regcache, FP0_REGNUM + regi,
+      regcache_raw_supply (regcache,
+                          gdbarch_fp0_regnum (current_gdbarch) + regi,
                           (const char *)(*fpregsetp + regi));
 
   supply_32bit_reg (regcache, mips_regnum (current_gdbarch)->fp_control_status,
@@ -416,22 +449,25 @@ mips64_fill_fpregset (const struct regcache *regcache,
 {
   gdb_byte *to;
 
-  if ((regno >= FP0_REGNUM) && (regno < FP0_REGNUM + 32))
+  if ((regno >= gdbarch_fp0_regnum (current_gdbarch))
+      && (regno < gdbarch_fp0_regnum (current_gdbarch) + 32))
     {
       /* See mips_linux_o32_sigframe_init for a description of the
         peculiar FP register layout.  */
       if (register_size (current_gdbarch, regno) == 4)
        {
-         int regi = regno - FP0_REGNUM;
+         int regi = regno - gdbarch_fp0_regnum (current_gdbarch);
 
          to = (gdb_byte *) (*fpregsetp + (regi & ~1));
-         if ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) != (regi & 1))
+         if ((gdbarch_byte_order (current_gdbarch)
+             == BFD_ENDIAN_BIG) != (regi & 1))
            to += 4;
          regcache_raw_collect (regcache, regno, to);
        }
       else
        {
-         to = (gdb_byte *) (*fpregsetp + regno - FP0_REGNUM);
+         to = (gdb_byte *) (*fpregsetp + regno
+                            - gdbarch_fp0_regnum (current_gdbarch));
          regcache_raw_collect (regcache, regno, to);
        }
     }
@@ -462,7 +498,8 @@ mips64_fill_fpregset (const struct regcache *regcache,
       int regi;
 
       for (regi = 0; regi < 32; regi++)
-       mips64_fill_fpregset (regcache, fpregsetp, FP0_REGNUM + regi);
+       mips64_fill_fpregset (regcache, fpregsetp,
+                             gdbarch_fp0_regnum (current_gdbarch) + regi);
       mips64_fill_fpregset (regcache, fpregsetp,
                            mips_regnum (current_gdbarch)->fp_control_status);
       mips64_fill_fpregset (regcache, fpregsetp,
@@ -825,19 +862,21 @@ mips_linux_o32_sigframe_init (const struct tramp_frame *self,
      per-frame basis, but right now we don't; the kernel saves eight
      bytes but we only want four.  Use regs_base to access any
      64-bit fields.  */
-  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+  if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
     regs_base = sigcontext_base + 4;
   else
     regs_base = sigcontext_base;
 
-#if 0
-  trad_frame_set_reg_addr (this_cache, ORIG_ZERO_REGNUM + NUM_REGS,
-                          regs_base + SIGCONTEXT_REGS);
-#endif
+  if (mips_linux_restart_reg_p (current_gdbarch))
+    trad_frame_set_reg_addr (this_cache,
+                            (MIPS_RESTART_REGNUM
+                             + gdbarch_num_regs (current_gdbarch)),
+                            regs_base + SIGCONTEXT_REGS);
 
   for (ireg = 1; ireg < 32; ireg++)
     trad_frame_set_reg_addr (this_cache,
-                            ireg + MIPS_ZERO_REGNUM + NUM_REGS,
+                            ireg + MIPS_ZERO_REGNUM
+                              + gdbarch_num_regs (current_gdbarch),
                             regs_base + SIGCONTEXT_REGS
                             + ireg * SIGCONTEXT_REG_SIZE);
 
@@ -850,28 +889,38 @@ mips_linux_o32_sigframe_init (const struct tramp_frame *self,
      layout, since we can't tell, and it's much more common.  Which bits are
      the "high" bits depends on endianness.  */
   for (ireg = 0; ireg < 32; ireg++)
-    if ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) != (ireg & 1))
-      trad_frame_set_reg_addr (this_cache, ireg + regs->fp0 + NUM_REGS,
+    if ((gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) != (ireg & 1))
+      trad_frame_set_reg_addr (this_cache,
+                              ireg + regs->fp0 +
+                                gdbarch_num_regs (current_gdbarch),
                               sigcontext_base + SIGCONTEXT_FPREGS + 4
                               + (ireg & ~1) * SIGCONTEXT_REG_SIZE);
     else
-      trad_frame_set_reg_addr (this_cache, ireg + regs->fp0 + NUM_REGS,
+      trad_frame_set_reg_addr (this_cache,
+                              ireg + regs->fp0
+                                + gdbarch_num_regs (current_gdbarch),
                               sigcontext_base + SIGCONTEXT_FPREGS
                               + (ireg & ~1) * SIGCONTEXT_REG_SIZE);
 
-  trad_frame_set_reg_addr (this_cache, regs->pc + NUM_REGS,
+  trad_frame_set_reg_addr (this_cache,
+                          regs->pc + gdbarch_num_regs (current_gdbarch),
                           regs_base + SIGCONTEXT_PC);
 
   trad_frame_set_reg_addr (this_cache,
-                          regs->fp_control_status + NUM_REGS,
+                          regs->fp_control_status
+                          + gdbarch_num_regs (current_gdbarch),
                           sigcontext_base + SIGCONTEXT_FPCSR);
-  trad_frame_set_reg_addr (this_cache, regs->hi + NUM_REGS,
+  trad_frame_set_reg_addr (this_cache,
+                          regs->hi + gdbarch_num_regs (current_gdbarch),
                           regs_base + SIGCONTEXT_HI);
-  trad_frame_set_reg_addr (this_cache, regs->lo + NUM_REGS,
+  trad_frame_set_reg_addr (this_cache,
+                          regs->lo + gdbarch_num_regs (current_gdbarch),
                           regs_base + SIGCONTEXT_LO);
-  trad_frame_set_reg_addr (this_cache, regs->cause + NUM_REGS,
+  trad_frame_set_reg_addr (this_cache,
+                          regs->cause + gdbarch_num_regs (current_gdbarch),
                           sigcontext_base + SIGCONTEXT_CAUSE);
-  trad_frame_set_reg_addr (this_cache, regs->badvaddr + NUM_REGS,
+  trad_frame_set_reg_addr (this_cache,
+                          regs->badvaddr + gdbarch_num_regs (current_gdbarch),
                           sigcontext_base + SIGCONTEXT_BADVADDR);
 
   /* Choice of the bottom of the sigframe is somewhat arbitrary.  */
@@ -968,35 +1017,45 @@ mips_linux_n32n64_sigframe_init (const struct tramp_frame *self,
   else
     sigcontext_base += N64_SIGFRAME_SIGCONTEXT_OFFSET;
 
-#if 0
-  trad_frame_set_reg_addr (this_cache, ORIG_ZERO_REGNUM + NUM_REGS,
-                          sigcontext_base + N64_SIGCONTEXT_REGS);
-#endif
+  if (mips_linux_restart_reg_p (current_gdbarch))
+    trad_frame_set_reg_addr (this_cache,
+                            (MIPS_RESTART_REGNUM
+                             + gdbarch_num_regs (current_gdbarch)),
+                            sigcontext_base + N64_SIGCONTEXT_REGS);
 
   for (ireg = 1; ireg < 32; ireg++)
     trad_frame_set_reg_addr (this_cache,
-                            ireg + MIPS_ZERO_REGNUM + NUM_REGS,
+                            ireg + MIPS_ZERO_REGNUM
+                            + gdbarch_num_regs (current_gdbarch),
                             sigcontext_base + N64_SIGCONTEXT_REGS
                             + ireg * N64_SIGCONTEXT_REG_SIZE);
 
   for (ireg = 0; ireg < 32; ireg++)
-    trad_frame_set_reg_addr (this_cache, ireg + regs->fp0 + NUM_REGS,
+    trad_frame_set_reg_addr (this_cache,
+                            ireg + regs->fp0
+                            + gdbarch_num_regs (current_gdbarch),
                             sigcontext_base + N64_SIGCONTEXT_FPREGS
                             + ireg * N64_SIGCONTEXT_REG_SIZE);
 
-  trad_frame_set_reg_addr (this_cache, regs->pc + NUM_REGS,
+  trad_frame_set_reg_addr (this_cache,
+                          regs->pc + gdbarch_num_regs (current_gdbarch),
                           sigcontext_base + N64_SIGCONTEXT_PC);
 
   trad_frame_set_reg_addr (this_cache,
-                          regs->fp_control_status + NUM_REGS,
+                          regs->fp_control_status
+                          + gdbarch_num_regs (current_gdbarch),
                           sigcontext_base + N64_SIGCONTEXT_FPCSR);
-  trad_frame_set_reg_addr (this_cache, regs->hi + NUM_REGS,
+  trad_frame_set_reg_addr (this_cache,
+                          regs->hi + gdbarch_num_regs (current_gdbarch),
                           sigcontext_base + N64_SIGCONTEXT_HI);
-  trad_frame_set_reg_addr (this_cache, regs->lo + NUM_REGS,
+  trad_frame_set_reg_addr (this_cache,
+                          regs->lo + gdbarch_num_regs (current_gdbarch),
                           sigcontext_base + N64_SIGCONTEXT_LO);
-  trad_frame_set_reg_addr (this_cache, regs->cause + NUM_REGS,
+  trad_frame_set_reg_addr (this_cache,
+                          regs->cause + gdbarch_num_regs (current_gdbarch),
                           sigcontext_base + N64_SIGCONTEXT_CAUSE);
-  trad_frame_set_reg_addr (this_cache, regs->badvaddr + NUM_REGS,
+  trad_frame_set_reg_addr (this_cache,
+                          regs->badvaddr + gdbarch_num_regs (current_gdbarch),
                           sigcontext_base + N64_SIGCONTEXT_BADVADDR);
 
   /* Choice of the bottom of the sigframe is somewhat arbitrary.  */
@@ -1005,6 +1064,31 @@ mips_linux_n32n64_sigframe_init (const struct tramp_frame *self,
                                     func));
 }
 
+static void
+mips_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
+{
+  regcache_cooked_write_unsigned (regcache,
+                                 gdbarch_pc_regnum (current_gdbarch), pc);
+
+  /* Clear the syscall restart flag.  */
+  if (mips_linux_restart_reg_p (current_gdbarch))
+    regcache_cooked_write_unsigned (regcache, MIPS_RESTART_REGNUM, 0);
+}
+
+/* Return 1 if MIPS_RESTART_REGNUM is usable.  */
+
+int
+mips_linux_restart_reg_p (struct gdbarch *gdbarch)
+{
+  /* If we do not have a target description with registers, then
+     MIPS_RESTART_REGNUM will not be included in the register set.  */
+  if (!tdesc_has_registers (gdbarch_target_desc (gdbarch)))
+    return 0;
+
+  /* If we do, then MIPS_RESTART_REGNUM is safe to check; it will
+     either be GPR-sized or missing.  */
+  return register_size (gdbarch, MIPS_RESTART_REGNUM) > 0;
+}
 
 /* Initialize one of the GNU/Linux OS ABIs.  */
 
@@ -1014,6 +1098,7 @@ mips_linux_init_abi (struct gdbarch_info info,
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   enum mips_abi abi = mips_abi (gdbarch);
+  struct tdesc_arch_data *tdesc_data = (void *) info.tdep_info;
 
   switch (abi)
     {
@@ -1074,6 +1159,26 @@ mips_linux_init_abi (struct gdbarch_info info,
        = mips_linux_in_dynsym_resolve_code;
     }
   set_solib_ops (gdbarch, &mips_svr4_so_ops);
+
+  set_gdbarch_write_pc (gdbarch, mips_linux_write_pc);
+
+  if (tdesc_data)
+    {
+      const struct tdesc_feature *feature;
+
+      /* If we have target-described registers, then we can safely
+        reserve a number for MIPS_RESTART_REGNUM (whether it is
+        described or not).  */
+      gdb_assert (gdbarch_num_regs (gdbarch) <= MIPS_RESTART_REGNUM);
+      set_gdbarch_num_regs (gdbarch, MIPS_RESTART_REGNUM + 1);
+
+      /* If it's present, then assign it to the reserved number.  */
+      feature = tdesc_find_feature (info.target_desc,
+                                   "org.gnu.gdb.mips.linux");
+      if (feature != NULL)
+       tdesc_numbered_register (feature, tdesc_data, MIPS_RESTART_REGNUM,
+                                "restart");
+    }
 }
 
 void
This page took 0.029627 seconds and 4 git commands to generate.