daily update
[deliverable/binutils-gdb.git] / gdb / mips-linux-tdep.c
index 6d0e7f6c9d2dc1b1bd6bb94440adb98ad42af6cb..be346d75844e2efb52f99a57fb27153f0812fb76 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for GNU/Linux on MIPS processors.
 
-   Copyright (C) 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   Copyright (C) 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -36,6 +36,7 @@
 #include "solist.h"
 #include "symtab.h"
 #include "target-descriptions.h"
+#include "regset.h"
 #include "mips-linux-tdep.h"
 #include "glibc-tdep.h"
 #include "linux-tdep.h"
@@ -127,6 +128,16 @@ mips_supply_gregset (struct regcache *regcache,
     regcache_raw_supply (regcache, regi, zerobuf);
 }
 
+static void
+mips_supply_gregset_wrapper (const struct regset *regset,
+                             struct regcache *regcache,
+                            int regnum, const void *gregs, size_t len)
+{
+  gdb_assert (len == sizeof (mips_elf_gregset_t));
+
+  mips_supply_gregset (regcache, (const mips_elf_gregset_t *)gregs);
+}
+
 /* Pack our registers (or one register) into an elf_gregset_t.  */
 
 void
@@ -185,6 +196,16 @@ mips_fill_gregset (const struct regcache *regcache,
     }
 }
 
+static void
+mips_fill_gregset_wrapper (const struct regset *regset,
+                          const struct regcache *regcache,
+                          int regnum, void *gregs, size_t len)
+{
+  gdb_assert (len == sizeof (mips_elf_gregset_t));
+
+  mips_fill_gregset (regcache, (mips_elf_gregset_t *)gregs, regnum);
+}
+
 /* Likewise, unpack an elf_fpregset_t.  */
 
 void
@@ -212,6 +233,16 @@ mips_supply_fpregset (struct regcache *regcache,
                       zerobuf);
 }
 
+static void
+mips_supply_fpregset_wrapper (const struct regset *regset,
+                              struct regcache *regcache,
+                             int regnum, const void *gregs, size_t len)
+{
+  gdb_assert (len == sizeof (mips_elf_fpregset_t));
+
+  mips_supply_fpregset (regcache, (const mips_elf_fpregset_t *)gregs);
+}
+
 /* Likewise, pack one or all floating point registers into an
    elf_fpregset_t.  */
 
@@ -245,6 +276,16 @@ mips_fill_fpregset (const struct regcache *regcache,
     }
 }
 
+static void
+mips_fill_fpregset_wrapper (const struct regset *regset,
+                           const struct regcache *regcache,
+                           int regnum, void *gregs, size_t len)
+{
+  gdb_assert (len == sizeof (mips_elf_fpregset_t));
+
+  mips_fill_fpregset (regcache, (mips_elf_fpregset_t *)gregs, regnum);
+}
+
 /* Support for 64-bit ABIs.  */
 
 /* Figure out where the longjmp will land.
@@ -342,6 +383,16 @@ mips64_supply_gregset (struct regcache *regcache,
     regcache_raw_supply (regcache, regi, zerobuf);
 }
 
+static void
+mips64_supply_gregset_wrapper (const struct regset *regset,
+                               struct regcache *regcache,
+                              int regnum, const void *gregs, size_t len)
+{
+  gdb_assert (len == sizeof (mips64_elf_gregset_t));
+
+  mips64_supply_gregset (regcache, (const mips64_elf_gregset_t *)gregs);
+}
+
 /* Pack our registers (or one register) into a 64-bit elf_gregset_t.  */
 
 void
@@ -362,7 +413,8 @@ mips64_fill_gregset (const struct regcache *regcache,
       mips64_fill_gregset (regcache, gregsetp, mips_regnum (gdbarch)->lo);
       mips64_fill_gregset (regcache, gregsetp, mips_regnum (gdbarch)->hi);
       mips64_fill_gregset (regcache, gregsetp, mips_regnum (gdbarch)->pc);
-      mips64_fill_gregset (regcache, gregsetp, mips_regnum (gdbarch)->badvaddr);
+      mips64_fill_gregset (regcache, gregsetp,
+                          mips_regnum (gdbarch)->badvaddr);
       mips64_fill_gregset (regcache, gregsetp, MIPS_PS_REGNUM);
       mips64_fill_gregset (regcache, gregsetp,  mips_regnum (gdbarch)->cause);
       mips64_fill_gregset (regcache, gregsetp, MIPS_RESTART_REGNUM);
@@ -402,6 +454,16 @@ mips64_fill_gregset (const struct regcache *regcache,
     }
 }
 
+static void
+mips64_fill_gregset_wrapper (const struct regset *regset,
+                            const struct regcache *regcache,
+                            int regnum, void *gregs, size_t len)
+{
+  gdb_assert (len == sizeof (mips64_elf_gregset_t));
+
+  mips64_fill_gregset (regcache, (mips64_elf_gregset_t *)gregs, regnum);
+}
+
 /* Likewise, unpack an elf_fpregset_t.  */
 
 void
@@ -440,6 +502,16 @@ mips64_supply_fpregset (struct regcache *regcache,
                    (const gdb_byte *)(*fpregsetp + 32) + 4);
 }
 
+static void
+mips64_supply_fpregset_wrapper (const struct regset *regset,
+                                struct regcache *regcache,
+                               int regnum, const void *gregs, size_t len)
+{
+  gdb_assert (len == sizeof (mips64_elf_fpregset_t));
+
+  mips64_supply_fpregset (regcache, (const mips64_elf_fpregset_t *)gregs);
+}
+
 /* Likewise, pack one or all floating point registers into an
    elf_fpregset_t.  */
 
@@ -467,7 +539,8 @@ mips64_fill_fpregset (const struct regcache *regcache,
        }
       else
        {
-         to = (gdb_byte *) (*fpregsetp + regno - gdbarch_fp0_regnum (gdbarch));
+         to = (gdb_byte *) (*fpregsetp + regno
+                            - gdbarch_fp0_regnum (gdbarch));
          regcache_raw_collect (regcache, regno, to);
        }
     }
@@ -508,72 +581,75 @@ mips64_fill_fpregset (const struct regcache *regcache,
     }
 }
 
+static void
+mips64_fill_fpregset_wrapper (const struct regset *regset,
+                             const struct regcache *regcache,
+                             int regnum, void *gregs, size_t len)
+{
+  gdb_assert (len == sizeof (mips64_elf_fpregset_t));
 
-/*  Use a local version of this function to get the correct types for
-    regsets, until multi-arch core support is ready.  */
+  mips64_fill_fpregset (regcache, (mips64_elf_fpregset_t *)gregs, regnum);
+}
 
-static void
-fetch_core_registers (struct regcache *regcache,
-                     char *core_reg_sect, unsigned core_reg_size,
-                     int which, CORE_ADDR reg_addr)
+const struct regset *
+mips_linux_regset_from_core_section (struct gdbarch *gdbarch,
+                                    const char *sect_name, size_t sect_size)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   mips_elf_gregset_t gregset;
   mips_elf_fpregset_t fpregset;
   mips64_elf_gregset_t gregset64;
   mips64_elf_fpregset_t fpregset64;
 
-  if (which == 0)
+  if (strcmp (sect_name, ".reg") == 0)
     {
-      if (core_reg_size == sizeof (gregset))
+      if (sect_size == sizeof (gregset))
        {
-         memcpy ((char *) &gregset, core_reg_sect, sizeof (gregset));
-         mips_supply_gregset (regcache,
-                              (const mips_elf_gregset_t *) &gregset);
+         if (tdep->gregset == NULL)
+           tdep->gregset = regset_alloc (gdbarch,
+                                          mips_supply_gregset_wrapper,
+                                         mips_fill_gregset_wrapper);
+         return tdep->gregset;
        }
-      else if (core_reg_size == sizeof (gregset64))
+      else if (sect_size == sizeof (gregset64))
        {
-         memcpy ((char *) &gregset64, core_reg_sect, sizeof (gregset64));
-         mips64_supply_gregset (regcache,
-                                (const mips64_elf_gregset_t *) &gregset64);
+         if (tdep->gregset64 == NULL)
+           tdep->gregset64 = regset_alloc (gdbarch,
+                                            mips64_supply_gregset_wrapper,
+                                           mips64_fill_gregset_wrapper);
+         return tdep->gregset64;
        }
       else
        {
          warning (_("wrong size gregset struct in core file"));
        }
     }
-  else if (which == 2)
+  else if (strcmp (sect_name, ".reg2") == 0)
     {
-      if (core_reg_size == sizeof (fpregset))
+      if (sect_size == sizeof (fpregset))
        {
-         memcpy ((char *) &fpregset, core_reg_sect, sizeof (fpregset));
-         mips_supply_fpregset (regcache,
-                               (const mips_elf_fpregset_t *) &fpregset);
+         if (tdep->fpregset == NULL)
+           tdep->fpregset = regset_alloc (gdbarch,
+                                           mips_supply_fpregset_wrapper,
+                                          mips_fill_fpregset_wrapper);
+         return tdep->fpregset;
        }
-      else if (core_reg_size == sizeof (fpregset64))
+      else if (sect_size == sizeof (fpregset64))
        {
-         memcpy ((char *) &fpregset64, core_reg_sect,
-                 sizeof (fpregset64));
-         mips64_supply_fpregset (regcache,
-                                 (const mips64_elf_fpregset_t *) &fpregset64);
+         if (tdep->fpregset64 == NULL)
+           tdep->fpregset64 = regset_alloc (gdbarch,
+                                             mips64_supply_fpregset_wrapper,
+                                            mips64_fill_fpregset_wrapper);
+         return tdep->fpregset64;
        }
       else
        {
          warning (_("wrong size fpregset struct in core file"));
        }
     }
-}
-
-/* Register that we are able to handle ELF file formats using standard
-   procfs "regset" structures.  */
 
-static struct core_fns regset_core_fns =
-{
-  bfd_target_elf_flavour,              /* core_flavour */
-  default_check_format,                        /* check_format */
-  default_core_sniffer,                        /* core_sniffer */
-  fetch_core_registers,                        /* core_read_registers */
-  NULL                                 /* next */
-};
+  return NULL;
+}
 
 static const struct target_desc *
 mips_linux_core_read_description (struct gdbarch *gdbarch,
@@ -1206,6 +1282,9 @@ mips_linux_init_abi (struct gdbarch_info info,
   set_gdbarch_core_read_description (gdbarch,
                                     mips_linux_core_read_description);
 
+  set_gdbarch_regset_from_core_section (gdbarch,
+                                       mips_linux_regset_from_core_section);
+
   tdep->syscall_next_pc = mips_linux_syscall_next_pc;
 
   if (tdesc_data)
@@ -1243,6 +1322,4 @@ _initialize_mips_linux_tdep (void)
                              GDB_OSABI_LINUX,
                              mips_linux_init_abi);
     }
-
-  deprecated_add_core_fns (&regset_core_fns);
 }
This page took 0.025759 seconds and 4 git commands to generate.