gdb/
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-mips-low.c
index 797d0461f0f22e4ecebb72ab3d8ed65cdc7342de..ec516724d35b5c07f4f0b95356a1298ad817acd0 100644 (file)
@@ -1,12 +1,12 @@
 /* GNU/Linux/MIPS specific low level interface, for the remote server for GDB.
-   Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2005, 2006
-   Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2005, 2006, 2007,
+   2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -15,9 +15,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "server.h"
 #include "linux-low.h"
 
 #include "gdb_proc_service.h"
 
+/* Defined in auto-generated file mips-linux.c.  */
+void init_registers_mips_linux (void);
+/* Defined in auto-generated file mips64-linux.c.  */
+void init_registers_mips64_linux (void);
+
 #ifndef PTRACE_GET_THREAD_AREA
 #define PTRACE_GET_THREAD_AREA 25
 #endif
@@ -35,7 +38,7 @@
 #include <sys/reg.h>
 #endif
 
-#define mips_num_regs 90
+#define mips_num_regs 73
 
 #include <asm/ptrace.h>
 
@@ -50,9 +53,8 @@ union mips_register
 
 /* Return the ptrace ``address'' of register REGNO. */
 
-/* Matches mips_generic32_regs */
 static int mips_regmap[] = {
-  0,  1,  2,  3,  4,  5,  6,  7,
+  -1,  1,  2,  3,  4,  5,  6,  7,
   8,  9,  10, 11, 12, 13, 14, 15,
   16, 17, 18, 19, 20, 21, 22, 23,
   24, 25, 26, 27, 28, 29, 30, 31,
@@ -69,9 +71,7 @@ static int mips_regmap[] = {
   FPR_BASE + 28, FPR_BASE + 29, FPR_BASE + 30, FPR_BASE + 31,
   FPC_CSR, FPC_EIR,
 
-  -1, -1,
-  -1, -1, -1, -1, -1, -1, -1, -1,
-  -1, -1, -1, -1, -1, -1, -1, -1,
+  0
 };
 
 /* From mips-linux-nat.c.  */
@@ -87,7 +87,7 @@ mips_cannot_fetch_register (int regno)
   if (mips_regmap[regno] == -1)
     return 1;
 
-  if (find_regno ("zero") == regno)
+  if (find_regno ("r0") == regno)
     return 1;
 
   return 0;
@@ -99,13 +99,13 @@ mips_cannot_store_register (int regno)
   if (mips_regmap[regno] == -1)
     return 1;
 
-  if (find_regno ("zero") == regno)
+  if (find_regno ("r0") == regno)
     return 1;
 
   if (find_regno ("cause") == regno)
     return 1;
 
-  if (find_regno ("bad") == regno)
+  if (find_regno ("badvaddr") == regno)
     return 1;
 
   if (find_regno ("fir") == regno)
@@ -115,15 +115,15 @@ mips_cannot_store_register (int regno)
 }
 
 static CORE_ADDR
-mips_get_pc ()
+mips_get_pc (struct regcache *regcache)
 {
   union mips_register pc;
-  collect_register_by_name ("pc", pc.buf);
+  collect_register_by_name (regcache, "pc", pc.buf);
   return register_size (0) == 4 ? pc.reg32 : pc.reg64;
 }
 
 static void
-mips_set_pc (CORE_ADDR pc)
+mips_set_pc (struct regcache *regcache, CORE_ADDR pc)
 {
   union mips_register newpc;
   if (register_size (0) == 4)
@@ -131,7 +131,7 @@ mips_set_pc (CORE_ADDR pc)
   else
     newpc.reg64 = pc;
 
-  supply_register_by_name ("pc", newpc.buf);
+  supply_register_by_name (regcache, "pc", newpc.buf);
 }
 
 /* Correct in either endianness.  */
@@ -142,10 +142,11 @@ static const unsigned int mips_breakpoint = 0x0005000d;
    is outside of the function.  So rather than importing software single-step,
    we can just run until exit.  */
 static CORE_ADDR
-mips_reinsert_addr ()
+mips_reinsert_addr (void)
 {
+  struct regcache *regcache = get_thread_regcache (current_inferior, 1);
   union mips_register ra;
-  collect_register_by_name ("ra", ra.buf);
+  collect_register_by_name (regcache, "r31", ra.buf);
   return register_size (0) == 4 ? ra.reg32 : ra.reg64;
 }
 
@@ -167,7 +168,7 @@ mips_breakpoint_at (CORE_ADDR where)
 
 ps_err_e
 ps_get_thread_area (const struct ps_prochandle *ph,
-                    lwpid_t lwpid, int idx, void **base)
+                   lwpid_t lwpid, int idx, void **base)
 {
   if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
     return PS_ERR;
@@ -183,24 +184,26 @@ ps_get_thread_area (const struct ps_prochandle *ph,
 #ifdef HAVE_PTRACE_GETREGS
 
 static void
-mips_collect_register (int use_64bit, int regno, union mips_register *reg)
+mips_collect_register (struct regcache *regcache,
+                      int use_64bit, int regno, union mips_register *reg)
 {
   union mips_register tmp_reg;
 
   if (use_64bit)
     {
-      collect_register (regno, &tmp_reg.reg64);
+      collect_register (regcache, regno, &tmp_reg.reg64);
       *reg = tmp_reg;
     }
   else
     {
-      collect_register (regno, &tmp_reg.reg32);
+      collect_register (regcache, regno, &tmp_reg.reg32);
       reg->reg64 = tmp_reg.reg32;
     }
 }
 
 static void
-mips_supply_register (int use_64bit, int regno, const union mips_register *reg)
+mips_supply_register (struct regcache *regcache,
+                     int use_64bit, int regno, const union mips_register *reg)
 {
   int offset = 0;
 
@@ -209,52 +212,63 @@ mips_supply_register (int use_64bit, int regno, const union mips_register *reg)
   if (__BYTE_ORDER == __BIG_ENDIAN && !use_64bit)
     offset = 4;
 
-  supply_register (regno, reg->buf + offset);
+  supply_register (regcache, regno, reg->buf + offset);
 }
 
 static void
-mips_collect_register_32bit (int use_64bit, int regno, unsigned char *buf)
+mips_collect_register_32bit (struct regcache *regcache,
+                            int use_64bit, int regno, unsigned char *buf)
 {
   union mips_register tmp_reg;
   int reg32;
 
-  mips_collect_register (use_64bit, regno, &tmp_reg);
+  mips_collect_register (regcache, use_64bit, regno, &tmp_reg);
   reg32 = tmp_reg.reg64;
   memcpy (buf, &reg32, 4);
 }
 
 static void
-mips_supply_register_32bit (int use_64bit, int regno, const unsigned char *buf)
+mips_supply_register_32bit (struct regcache *regcache,
+                           int use_64bit, int regno, const unsigned char *buf)
 {
   union mips_register tmp_reg;
   int reg32;
 
   memcpy (&reg32, buf, 4);
   tmp_reg.reg64 = reg32;
-  mips_supply_register (use_64bit, regno, &tmp_reg);
+  mips_supply_register (regcache, use_64bit, regno, &tmp_reg);
 }
 
 static void
-mips_fill_gregset (void *buf)
+mips_fill_gregset (struct regcache *regcache, void *buf)
 {
   union mips_register *regset = buf;
   int i, use_64bit;
 
   use_64bit = (register_size (0) == 8);
 
-  for (i = 0; i < 32; i++)
-    mips_collect_register (use_64bit, i, regset + i);
-
-  mips_collect_register (use_64bit, find_regno ("lo"), regset + 32);
-  mips_collect_register (use_64bit, find_regno ("hi"), regset + 33);
-  mips_collect_register (use_64bit, find_regno ("pc"), regset + 34);
-  mips_collect_register (use_64bit, find_regno ("bad"), regset + 35);
-  mips_collect_register (use_64bit, find_regno ("sr"), regset + 36);
-  mips_collect_register (use_64bit, find_regno ("cause"), regset + 37);
+  for (i = 1; i < 32; i++)
+    mips_collect_register (regcache, use_64bit, i, regset + i);
+
+  mips_collect_register (regcache, use_64bit,
+                        find_regno ("lo"), regset + 32);
+  mips_collect_register (regcache, use_64bit,
+                        find_regno ("hi"), regset + 33);
+  mips_collect_register (regcache, use_64bit,
+                        find_regno ("pc"), regset + 34);
+  mips_collect_register (regcache, use_64bit,
+                        find_regno ("badvaddr"), regset + 35);
+  mips_collect_register (regcache, use_64bit,
+                        find_regno ("status"), regset + 36);
+  mips_collect_register (regcache, use_64bit,
+                        find_regno ("cause"), regset + 37);
+
+  mips_collect_register (regcache, use_64bit,
+                        find_regno ("restart"), regset + 0);
 }
 
 static void
-mips_store_gregset (const void *buf)
+mips_store_gregset (struct regcache *regcache, const void *buf)
 {
   const union mips_register *regset = buf;
   int i, use_64bit;
@@ -262,18 +276,24 @@ mips_store_gregset (const void *buf)
   use_64bit = (register_size (0) == 8);
 
   for (i = 0; i < 32; i++)
-    mips_supply_register (use_64bit, i, regset + i);
-
-  mips_supply_register (use_64bit, find_regno ("lo"), regset + 32);
-  mips_supply_register (use_64bit, find_regno ("hi"), regset + 33);
-  mips_supply_register (use_64bit, find_regno ("pc"), regset + 34);
-  mips_supply_register (use_64bit, find_regno ("bad"), regset + 35);
-  mips_supply_register (use_64bit, find_regno ("sr"), regset + 36);
-  mips_supply_register (use_64bit, find_regno ("cause"), regset + 37);
+    mips_supply_register (regcache, use_64bit, i, regset + i);
+
+  mips_supply_register (regcache, use_64bit, find_regno ("lo"), regset + 32);
+  mips_supply_register (regcache, use_64bit, find_regno ("hi"), regset + 33);
+  mips_supply_register (regcache, use_64bit, find_regno ("pc"), regset + 34);
+  mips_supply_register (regcache, use_64bit,
+                       find_regno ("badvaddr"), regset + 35);
+  mips_supply_register (regcache, use_64bit,
+                       find_regno ("status"), regset + 36);
+  mips_supply_register (regcache, use_64bit,
+                       find_regno ("cause"), regset + 37);
+
+  mips_supply_register (regcache, use_64bit,
+                       find_regno ("restart"), regset + 0);
 }
 
 static void
-mips_fill_fpregset (void *buf)
+mips_fill_fpregset (struct regcache *regcache, void *buf)
 {
   union mips_register *regset = buf;
   int i, use_64bit, first_fp, big_endian;
@@ -285,18 +305,19 @@ mips_fill_fpregset (void *buf)
   /* See GDB for a discussion of this peculiar layout.  */
   for (i = 0; i < 32; i++)
     if (use_64bit)
-      collect_register (first_fp + i, regset[i].buf);
+      collect_register (regcache, first_fp + i, regset[i].buf);
     else
-      collect_register (first_fp + i,
+      collect_register (regcache, first_fp + i,
                        regset[i & ~1].buf + 4 * (big_endian != (i & 1)));
 
-  mips_collect_register_32bit (use_64bit, find_regno ("fsr"), regset[32].buf);
-  mips_collect_register_32bit (use_64bit, find_regno ("fir"),
+  mips_collect_register_32bit (regcache, use_64bit,
+                              find_regno ("fcsr"), regset[32].buf);
+  mips_collect_register_32bit (regcache, use_64bit, find_regno ("fir"),
                               regset[32].buf + 4);
 }
 
 static void
-mips_store_fpregset (const void *buf)
+mips_store_fpregset (struct regcache *regcache, const void *buf)
 {
   const union mips_register *regset = buf;
   int i, use_64bit, first_fp, big_endian;
@@ -308,28 +329,34 @@ mips_store_fpregset (const void *buf)
   /* See GDB for a discussion of this peculiar layout.  */
   for (i = 0; i < 32; i++)
     if (use_64bit)
-      supply_register (first_fp + i, regset[i].buf);
+      supply_register (regcache, first_fp + i, regset[i].buf);
     else
-      supply_register (first_fp + i,
+      supply_register (regcache, first_fp + i,
                       regset[i & ~1].buf + 4 * (big_endian != (i & 1)));
 
-  mips_supply_register_32bit (use_64bit, find_regno ("fsr"), regset[32].buf);
-  mips_supply_register_32bit (use_64bit, find_regno ("fir"),
+  mips_supply_register_32bit (regcache, use_64bit,
+                             find_regno ("fcsr"), regset[32].buf);
+  mips_supply_register_32bit (regcache, use_64bit, find_regno ("fir"),
                              regset[32].buf + 4);
 }
 #endif /* HAVE_PTRACE_GETREGS */
 
 struct regset_info target_regsets[] = {
 #ifdef HAVE_PTRACE_GETREGS
-  { PTRACE_GETREGS, PTRACE_SETREGS, 38 * 8, GENERAL_REGS,
+  { PTRACE_GETREGS, PTRACE_SETREGS, 0, 38 * 8, GENERAL_REGS,
     mips_fill_gregset, mips_store_gregset },
-  { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 33 * 8, FP_REGS,
+  { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 0, 33 * 8, FP_REGS,
     mips_fill_fpregset, mips_store_fpregset },
 #endif /* HAVE_PTRACE_GETREGS */
-  { 0, 0, -1, -1, NULL, NULL }
+  { 0, 0, 0, -1, -1, NULL, NULL }
 };
 
 struct linux_target_ops the_low_target = {
+#ifdef __mips64
+  init_registers_mips64_linux,
+#else
+  init_registers_mips_linux,
+#endif
   mips_num_regs,
   mips_regmap,
   mips_cannot_fetch_register,
This page took 0.028975 seconds and 4 git commands to generate.