2007-06-13 Claudio Fontana <claudio.fontana@gmail.com>
[deliverable/binutils-gdb.git] / gdb / rs6000-aix-tdep.c
index a488637c377870a949571a89df9909bdd29982a9..ee6b03962d6503d9b5d4ae0237e9282e090d9e29 100644 (file)
@@ -1,6 +1,6 @@
 /* Native support code for PPC AIX, for GDB the GNU debugger.
 
-   Copyright (C) 2006 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2007 Free Software Foundation, Inc.
 
    Free Software Foundation, Inc.
 
    Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
+#include "gdb_string.h"
 #include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
 #include "rs6000-tdep.h"
+#include "ppc-tdep.h"
+
+
+/* Core file support.  */
+
+static struct ppc_reg_offsets rs6000_aix32_reg_offsets =
+{
+  /* General-purpose registers.  */
+  208, /* r0_offset */
+  24, /* pc_offset */
+  28, /* ps_offset */
+  32, /* cr_offset */
+  36, /* lr_offset */
+  40, /* ctr_offset */
+  44, /* xer_offset */
+  48, /* mq_offset */
+
+  /* Floating-point registers.  */
+  336, /* f0_offset */
+  56, /* fpscr_offset */
+
+  /* AltiVec registers.  */
+  -1, /* vr0_offset */
+  -1, /* vscr_offset */
+  -1 /* vrsave_offset */
+};
+
+static struct ppc_reg_offsets rs6000_aix64_reg_offsets =
+{
+  /* General-purpose registers.  */
+  0, /* r0_offset */
+  264, /* pc_offset */
+  256, /* ps_offset */
+  288, /* cr_offset */
+  272, /* lr_offset */
+  280, /* ctr_offset */
+  292, /* xer_offset */
+  -1, /* mq_offset */
+
+  /* Floating-point registers.  */
+  312, /* f0_offset */
+  296, /* fpscr_offset */
+
+  /* AltiVec registers.  */
+  -1, /* vr0_offset */
+  -1, /* vscr_offset */
+  -1 /* vrsave_offset */
+};
+
+
+/* Supply register REGNUM in the general-purpose register set REGSET
+   from the buffer specified by GREGS and LEN to register cache
+   REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
+
+static void
+rs6000_aix_supply_regset (const struct regset *regset,
+                         struct regcache *regcache, int regnum,
+                         const void *gregs, size_t len)
+{
+  ppc_supply_gregset (regset, regcache, regnum, gregs, len);
+
+  if (ppc_floating_point_unit_p (get_regcache_arch (regcache)))
+    ppc_supply_fpregset (regset, regcache, regnum, gregs, len);
+}
+
+/* Collect register REGNUM in the general-purpose register set
+   REGSET. from register cache REGCACHE into the buffer specified by
+   GREGS and LEN.  If REGNUM is -1, do this for all registers in
+   REGSET.  */
+
+static void
+rs6000_aix_collect_regset (const struct regset *regset,
+                          const struct regcache *regcache, int regnum,
+                          void *gregs, size_t len)
+{
+  ppc_collect_gregset (regset, regcache, regnum, gregs, len);
+
+  if (ppc_floating_point_unit_p (get_regcache_arch (regcache)))
+    ppc_collect_fpregset (regset, regcache, regnum, gregs, len);
+}
+
+/* AIX register set.  */
+
+static struct regset rs6000_aix32_regset =
+{
+  &rs6000_aix32_reg_offsets,
+  rs6000_aix_supply_regset,
+  rs6000_aix_collect_regset,
+};
+
+static struct regset rs6000_aix64_regset =
+{
+  &rs6000_aix64_reg_offsets,
+  rs6000_aix_supply_regset,
+  rs6000_aix_collect_regset,
+};
+
+/* Return the appropriate register set for the core section identified
+   by SECT_NAME and SECT_SIZE.  */
+
+static const struct regset *
+rs6000_aix_regset_from_core_section (struct gdbarch *gdbarch,
+                                    const char *sect_name, size_t sect_size)
+{
+  if (gdbarch_tdep (gdbarch)->wordsize == 4)
+    {
+      if (strcmp (sect_name, ".reg") == 0 && sect_size >= 592)
+        return &rs6000_aix32_regset;
+    }
+  else
+    {
+      if (strcmp (sect_name, ".reg") == 0 && sect_size >= 576)
+        return &rs6000_aix64_regset;
+    }
+
+  return NULL;
+}
+
 
 static enum gdb_osabi
 rs6000_aix_osabi_sniffer (bfd *abfd)
@@ -40,6 +161,13 @@ rs6000_aix_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   /* RS6000/AIX does not support PT_STEP.  Has to be simulated.  */
   set_gdbarch_software_single_step (gdbarch, rs6000_software_single_step);
+
+  /* Core file support.  */
+  set_gdbarch_regset_from_core_section
+    (gdbarch, rs6000_aix_regset_from_core_section);
+
+  /* Minimum possible text address in AIX.  */
+  gdbarch_tdep (gdbarch)->text_segment_base = 0x10000000;
 }
 
 void
@@ -48,8 +176,13 @@ _initialize_rs6000_aix_tdep (void)
   gdbarch_register_osabi_sniffer (bfd_arch_rs6000,
                                   bfd_target_xcoff_flavour,
                                   rs6000_aix_osabi_sniffer);
+  gdbarch_register_osabi_sniffer (bfd_arch_powerpc,
+                                  bfd_target_xcoff_flavour,
+                                  rs6000_aix_osabi_sniffer);
 
   gdbarch_register_osabi (bfd_arch_rs6000, 0, GDB_OSABI_AIX,
                           rs6000_aix_init_osabi);
+  gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_AIX,
+                          rs6000_aix_init_osabi);
 }
 
This page took 0.024759 seconds and 4 git commands to generate.