2004-03-15 Andrew Cagney <cagney@redhat.com>

* ppc-tdep.h: Update copyright.
	(ppc_linux_supply_gregset, ppc_linux_supply_fpregset): Change
	function signatures to match "regsets.h".
	* ppc-linux-tdep.c: Include "regset.h".
	(ELF_GREGSET_SIZE): Delete.
	(right_supply_register): New function.
	(ppc_linux_supply_fpregset, ppc_linux_supply_gregset): Rewrite
	using right_supply_register.
	(ppc32_linux_supply_gregset, ppc64_linux_supply_gregset): New
	functions.
	(ppc64_linux_gregset, ppc32_linux_gregset): Define.
	(ppc_linux_init_abi): Register ppc_linux_regset_from_core_section.
	(_initialize_ppc_linux_tdep): Do not register
	ppc_linux_regset_core_fns.
	(ppc_linux_regset_from_core_section): Replace
	fetch_core_registers.
	(ppc_linux_regset_core_fns): Delete.
	* ppc-linux-nat.c: (right_fill_reg): New function.
	(supply_gregset): Update call to ppc_linux_supply_gregset.
	(fill_gregset): Clear the register set, use right_fill_reg.
	(supply_fpregset): Update call to ppc_linux_supply_fpregset.
	(fill_fpregset): Use right_fill_reg, correctly compute FP offsets.

Index: ppc-linux-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-nat.c,v
retrieving revision 1.28
diff -u -r1.28 ppc-linux-nat.c
--- ppc-linux-nat.c	8 Mar 2004 01:45:02 -0000	1.28
+++ ppc-linux-nat.c	15 Mar 2004 21:28:31 -0000
@@ -507,7 +507,24 @@
 void
 supply_gregset (gdb_gregset_t *gregsetp)
 {
-  ppc_linux_supply_gregset ((char *) gregsetp);
+  /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace
+     interface, and not the wordsize of the program's ABI.  */
+  int wordsize = sizeof (PTRACE_XFER_TYPE);
+  ppc_linux_supply_gregset (current_regcache, -1, gregsetp,
+			    sizeof (gdb_gregset_t), wordsize);
+}
+
+static void
+right_fill_reg (int regnum, void *reg)
+{
+  /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace
+     interface, and not the wordsize of the program's ABI.  */
+  int wordsize = sizeof (PTRACE_XFER_TYPE);
+  /* Right fill the register.  */
+  regcache_raw_collect (current_regcache, regnum,
+			((bfd_byte *) reg
+			 + wordsize
+			 - register_size (current_gdbarch, regnum)));
 }

 void
@@ -516,36 +533,42 @@
   int regi;
   elf_greg_t *regp = (elf_greg_t *) gregsetp;
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  const int elf_ngreg = 48;
+
+
+  /* Start with zeros.  */
+  memset (regp, 0, elf_ngreg * sizeof (*regp));

   for (regi = 0; regi < 32; regi++)
     {
       if ((regno == -1) || regno == regi)
-        regcache_collect (regi, regp + PT_R0 + regi);
+	right_fill_reg (regi, (regp + PT_R0 + regi));
     }

   if ((regno == -1) || regno == PC_REGNUM)
-    regcache_collect (PC_REGNUM, regp + PT_NIP);
+    right_fill_reg (PC_REGNUM, regp + PT_NIP);
   if ((regno == -1) || regno == tdep->ppc_lr_regnum)
-    regcache_collect (tdep->ppc_lr_regnum, regp + PT_LNK);
+    right_fill_reg (tdep->ppc_lr_regnum, regp + PT_LNK);
   if ((regno == -1) || regno == tdep->ppc_cr_regnum)
     regcache_collect (tdep->ppc_cr_regnum, regp + PT_CCR);
   if ((regno == -1) || regno == tdep->ppc_xer_regnum)
     regcache_collect (tdep->ppc_xer_regnum, regp + PT_XER);
   if ((regno == -1) || regno == tdep->ppc_ctr_regnum)
-    regcache_collect (tdep->ppc_ctr_regnum, regp + PT_CTR);
+    right_fill_reg (tdep->ppc_ctr_regnum, regp + PT_CTR);
 #ifdef PT_MQ
   if (((regno == -1) || regno == tdep->ppc_mq_regnum)
       && (tdep->ppc_mq_regnum != -1))
-    regcache_collect (tdep->ppc_mq_regnum, regp + PT_MQ);
+    right_fill_reg (tdep->ppc_mq_regnum, regp + PT_MQ);
 #endif
   if ((regno == -1) || regno == tdep->ppc_ps_regnum)
-    regcache_collect (tdep->ppc_ps_regnum, regp + PT_MSR);
+    right_fill_reg (tdep->ppc_ps_regnum, regp + PT_MSR);
 }

 void
 supply_fpregset (gdb_fpregset_t * fpregsetp)
 {
-  ppc_linux_supply_fpregset ((char *) fpregsetp);
+  ppc_linux_supply_fpregset (NULL, current_regcache, -1, fpregsetp,
+			     sizeof (gdb_fpregset_t));
 }

 /* Given a pointer to a floating point register set in /proc format
@@ -557,12 +580,13 @@
 {
   int regi;
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  bfd_byte *fpp = (void *) fpregsetp;

   for (regi = 0; regi < 32; regi++)
     {
       if ((regno == -1) || (regno == FP0_REGNUM + regi))
-	regcache_collect (FP0_REGNUM + regi, (char *) (*fpregsetp + regi));
+	regcache_collect (FP0_REGNUM + regi, fpp + 8 * regi);
     }
   if ((regno == -1) || regno == tdep->ppc_fpscr_regnum)
-    regcache_collect (tdep->ppc_fpscr_regnum, (char *) (*fpregsetp + regi));
+    right_fill_reg (tdep->ppc_fpscr_regnum, (fpp + 8 * 32));
 }
Index: ppc-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-tdep.c,v
retrieving revision 1.50
diff -u -r1.50 ppc-linux-tdep.c
--- ppc-linux-tdep.c	16 Feb 2004 21:49:22 -0000	1.50
+++ ppc-linux-tdep.c	15 Mar 2004 21:28:31 -0000
@@ -32,7 +32,7 @@
 #include "regcache.h"
 #include "value.h"
 #include "osabi.h"
-
+#include "regset.h"
 #include "solib-svr4.h"
 #include "ppc-tdep.h"

@@ -959,81 +959,114 @@
 };

 enum {
-  ELF_GREGSET_SIZE = (ELF_NGREG * 4),
   ELF_FPREGSET_SIZE = (ELF_NFPREG * 8)
 };

+static void
+right_supply_register (struct regcache *regcache, int wordsize, int regnum,
+		       const bfd_byte *buf)
+{
+  regcache_raw_supply (regcache, regnum,
+		       (buf + wordsize
+			- register_size (current_gdbarch, regnum)));
+}
+
+/* Extract the register values found in the WORDSIZED ABI GREGSET,
+   storing their values in REGCACHE.  Note that some are left-aligned,
+   while others are right aligned.  */
+
 void
-ppc_linux_supply_gregset (char *buf)
+ppc_linux_supply_gregset (struct regcache *regcache,
+			  int regnum, const void *gregs, size_t size,
+			  int wordsize)
 {
   int regi;
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch *regcache_arch = get_regcache_arch (regcache);
+  struct gdbarch_tdep *regcache_tdep = gdbarch_tdep (regcache_arch);
+  const bfd_byte *buf = gregs;

   for (regi = 0; regi < 32; regi++)
-    supply_register (regi, buf + 4 * regi);
+    right_supply_register (regcache, wordsize, regi, buf + wordsize * regi);
+
+  right_supply_register (regcache, wordsize, gdbarch_pc_regnum (regcache_arch),
+			 buf + wordsize * PPC_LINUX_PT_NIP);
+  right_supply_register (regcache, wordsize, regcache_tdep->ppc_lr_regnum,
+			 buf + wordsize * PPC_LINUX_PT_LNK);
+  regcache_raw_supply (regcache, regcache_tdep->ppc_cr_regnum,
+		       buf + wordsize * PPC_LINUX_PT_CCR);
+  regcache_raw_supply (regcache, regcache_tdep->ppc_xer_regnum,
+		       buf + wordsize * PPC_LINUX_PT_XER);
+  regcache_raw_supply (regcache, regcache_tdep->ppc_ctr_regnum,
+		       buf + wordsize * PPC_LINUX_PT_CTR);
+  if (regcache_tdep->ppc_mq_regnum != -1)
+    right_supply_register (regcache, wordsize, regcache_tdep->ppc_mq_regnum,
+			   buf + wordsize * PPC_LINUX_PT_MQ);
+  right_supply_register (regcache, wordsize, regcache_tdep->ppc_ps_regnum,
+			 buf + wordsize * PPC_LINUX_PT_MSR);
+}

-  supply_register (PC_REGNUM, buf + 4 * PPC_LINUX_PT_NIP);
-  supply_register (tdep->ppc_lr_regnum, buf + 4 * PPC_LINUX_PT_LNK);
-  supply_register (tdep->ppc_cr_regnum, buf + 4 * PPC_LINUX_PT_CCR);
-  supply_register (tdep->ppc_xer_regnum, buf + 4 * PPC_LINUX_PT_XER);
-  supply_register (tdep->ppc_ctr_regnum, buf + 4 * PPC_LINUX_PT_CTR);
-  if (tdep->ppc_mq_regnum != -1)
-    supply_register (tdep->ppc_mq_regnum, buf + 4 * PPC_LINUX_PT_MQ);
-  supply_register (tdep->ppc_ps_regnum, buf + 4 * PPC_LINUX_PT_MSR);
+static void
+ppc32_linux_supply_gregset (const struct regset *regset,
+			    struct regcache *regcache,
+			    int regnum, const void *gregs, size_t size)
+{
+  ppc_linux_supply_gregset (regcache, regnum, gregs, size, 4);
 }

+static struct regset ppc32_linux_gregset = {
+  NULL, ppc32_linux_supply_gregset
+};
+
+static void
+ppc64_linux_supply_gregset (const struct regset *regset,
+			    struct regcache * regcache,
+			    int regnum, const void *gregs, size_t size)
+{
+  ppc_linux_supply_gregset (regcache, regnum, gregs, size, 8);
+}
+
+static struct regset ppc64_linux_gregset = {
+  NULL, ppc64_linux_supply_gregset
+};
+
 void
-ppc_linux_supply_fpregset (char *buf)
+ppc_linux_supply_fpregset (const struct regset *regset,
+			   struct regcache * regcache,
+			   int regnum, const void *fpset, size_t size)
 {
   int regi;
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch *regcache_arch = get_regcache_arch (regcache);
+  struct gdbarch_tdep *regcache_tdep = gdbarch_tdep (regcache_arch);
+  const bfd_byte *buf = fpset;

   for (regi = 0; regi < 32; regi++)
-    supply_register (FP0_REGNUM + regi, buf + 8 * regi);
+    regcache_raw_supply (regcache, FP0_REGNUM + regi, buf + 8 * regi);

   /* The FPSCR is stored in the low order word of the last doubleword in the
      fpregset.  */
-  supply_register (tdep->ppc_fpscr_regnum, buf + 8 * 32 + 4);
+  regcache_raw_supply (regcache, regcache_tdep->ppc_fpscr_regnum,
+		       buf + 8 * 32 + 4);
 }

-/*
-  Use a local version of this function to get the correct types for regsets.
-*/
+static struct regset ppc_linux_fpregset = { NULL, ppc_linux_supply_fpregset };

-static void
-fetch_core_registers (char *core_reg_sect,
-		      unsigned core_reg_size,
-		      int which,
-		      CORE_ADDR reg_addr)
+static const struct regset *
+ppc_linux_regset_from_core_section (struct gdbarch *core_arch,
+				    const char *sect_name, size_t sect_size)
 {
-  if (which == 0)
+  struct gdbarch_tdep *tdep = gdbarch_tdep (core_arch);
+  if (strcmp (sect_name, ".reg") == 0)
     {
-      if (core_reg_size == ELF_GREGSET_SIZE)
-	ppc_linux_supply_gregset (core_reg_sect);
+      if (tdep->wordsize == 4)
+	return &ppc32_linux_gregset;
       else
-	warning ("wrong size gregset struct in core file");
-    }
-  else if (which == 2)
-    {
-      if (core_reg_size == ELF_FPREGSET_SIZE)
-	ppc_linux_supply_fpregset (core_reg_sect);
-      else
-	warning ("wrong size fpregset struct in core file");
+	return &ppc64_linux_gregset;
     }
+  if (strcmp (sect_name, ".reg2") == 0)
+    return &ppc_linux_fpregset;
+  return NULL;
 }

-/* Register that we are able to handle ELF file formats using standard
-   procfs "regset" structures.  */
-
-static struct core_fns ppc_linux_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 */
-};
-
 static void
 ppc_linux_init_abi (struct gdbarch_info info,
                     struct gdbarch *gdbarch)
@@ -1086,6 +1119,7 @@
       /* PPC64 malloc's entry-point is called ".malloc".  */
       set_gdbarch_name_of_malloc (gdbarch, ".malloc");
     }
+  set_gdbarch_regset_from_core_section (gdbarch, ppc_linux_regset_from_core_section);
 }

 void
@@ -1099,5 +1133,4 @@
                          ppc_linux_init_abi);
   gdbarch_register_osabi (bfd_arch_rs6000, bfd_mach_rs6k, GDB_OSABI_LINUX,
                          ppc_linux_init_abi);
-  add_core_fns (&ppc_linux_regset_core_fns);
 }
Index: ppc-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/ppc-tdep.h,v
retrieving revision 1.25
diff -u -r1.25 ppc-tdep.h
--- ppc-tdep.h	10 Nov 2003 22:47:28 -0000	1.25
+++ ppc-tdep.h	15 Mar 2004 21:28:31 -0000
@@ -1,6 +1,7 @@
 /* Target-dependent code for GDB, the GNU debugger.
-   Copyright 2000, 2001, 2002, 2003
-   Free Software Foundation, Inc.
+
+   Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation,
+   Inc.

    This file is part of GDB.

@@ -62,8 +63,12 @@
 						    CORE_ADDR bpaddr);
 int ppc_linux_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache);
 struct link_map_offsets *ppc_linux_svr4_fetch_link_map_offsets (void);
-void ppc_linux_supply_gregset (char *buf);
-void ppc_linux_supply_fpregset (char *buf);
+void ppc_linux_supply_gregset (struct regcache *regcache,
+			       int regnum, const void *gregs, size_t size,
+			       int wordsize);
+void ppc_linux_supply_fpregset (const struct regset *regset,
+				struct regcache *regcache,
+				int regnum, const void *gregs, size_t size);

 enum return_value_convention ppc64_sysv_abi_return_value (struct gdbarch *gdbarch,
 							  struct type *valtype,
This commit is contained in:
Andrew Cagney 2004-03-15 21:35:25 +00:00
parent ed6edd9bf2
commit f9be684a36
4 changed files with 153 additions and 68 deletions

View file

@ -1,5 +1,28 @@
2004-03-15 Andrew Cagney <cagney@redhat.com>
* ppc-tdep.h: Update copyright.
(ppc_linux_supply_gregset, ppc_linux_supply_fpregset): Change
function signatures to match "regsets.h".
* ppc-linux-tdep.c: Include "regset.h".
(ELF_GREGSET_SIZE): Delete.
(right_supply_register): New function.
(ppc_linux_supply_fpregset, ppc_linux_supply_gregset): Rewrite
using right_supply_register.
(ppc32_linux_supply_gregset, ppc64_linux_supply_gregset): New
functions.
(ppc64_linux_gregset, ppc32_linux_gregset): Define.
(ppc_linux_init_abi): Register ppc_linux_regset_from_core_section.
(_initialize_ppc_linux_tdep): Do not register
ppc_linux_regset_core_fns.
(ppc_linux_regset_from_core_section): Replace
fetch_core_registers.
(ppc_linux_regset_core_fns): Delete.
* ppc-linux-nat.c: (right_fill_reg): New function.
(supply_gregset): Update call to ppc_linux_supply_gregset.
(fill_gregset): Clear the register set, use right_fill_reg.
(supply_fpregset): Update call to ppc_linux_supply_fpregset.
(fill_fpregset): Use right_fill_reg, correctly compute FP offsets.
* rs6000-tdep.c (rs6000_register_virtual_type): Make registers
unsigned.

View file

@ -507,7 +507,24 @@ store_inferior_registers (int regno)
void
supply_gregset (gdb_gregset_t *gregsetp)
{
ppc_linux_supply_gregset ((char *) gregsetp);
/* NOTE: cagney/2003-11-25: This is the word size used by the ptrace
interface, and not the wordsize of the program's ABI. */
int wordsize = sizeof (PTRACE_XFER_TYPE);
ppc_linux_supply_gregset (current_regcache, -1, gregsetp,
sizeof (gdb_gregset_t), wordsize);
}
static void
right_fill_reg (int regnum, void *reg)
{
/* NOTE: cagney/2003-11-25: This is the word size used by the ptrace
interface, and not the wordsize of the program's ABI. */
int wordsize = sizeof (PTRACE_XFER_TYPE);
/* Right fill the register. */
regcache_raw_collect (current_regcache, regnum,
((bfd_byte *) reg
+ wordsize
- register_size (current_gdbarch, regnum)));
}
void
@ -516,36 +533,42 @@ fill_gregset (gdb_gregset_t *gregsetp, int regno)
int regi;
elf_greg_t *regp = (elf_greg_t *) gregsetp;
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
const int elf_ngreg = 48;
/* Start with zeros. */
memset (regp, 0, elf_ngreg * sizeof (*regp));
for (regi = 0; regi < 32; regi++)
{
if ((regno == -1) || regno == regi)
regcache_collect (regi, regp + PT_R0 + regi);
right_fill_reg (regi, (regp + PT_R0 + regi));
}
if ((regno == -1) || regno == PC_REGNUM)
regcache_collect (PC_REGNUM, regp + PT_NIP);
right_fill_reg (PC_REGNUM, regp + PT_NIP);
if ((regno == -1) || regno == tdep->ppc_lr_regnum)
regcache_collect (tdep->ppc_lr_regnum, regp + PT_LNK);
right_fill_reg (tdep->ppc_lr_regnum, regp + PT_LNK);
if ((regno == -1) || regno == tdep->ppc_cr_regnum)
regcache_collect (tdep->ppc_cr_regnum, regp + PT_CCR);
if ((regno == -1) || regno == tdep->ppc_xer_regnum)
regcache_collect (tdep->ppc_xer_regnum, regp + PT_XER);
if ((regno == -1) || regno == tdep->ppc_ctr_regnum)
regcache_collect (tdep->ppc_ctr_regnum, regp + PT_CTR);
right_fill_reg (tdep->ppc_ctr_regnum, regp + PT_CTR);
#ifdef PT_MQ
if (((regno == -1) || regno == tdep->ppc_mq_regnum)
&& (tdep->ppc_mq_regnum != -1))
regcache_collect (tdep->ppc_mq_regnum, regp + PT_MQ);
right_fill_reg (tdep->ppc_mq_regnum, regp + PT_MQ);
#endif
if ((regno == -1) || regno == tdep->ppc_ps_regnum)
regcache_collect (tdep->ppc_ps_regnum, regp + PT_MSR);
right_fill_reg (tdep->ppc_ps_regnum, regp + PT_MSR);
}
void
supply_fpregset (gdb_fpregset_t * fpregsetp)
{
ppc_linux_supply_fpregset ((char *) fpregsetp);
ppc_linux_supply_fpregset (NULL, current_regcache, -1, fpregsetp,
sizeof (gdb_fpregset_t));
}
/* Given a pointer to a floating point register set in /proc format
@ -557,12 +580,13 @@ fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
{
int regi;
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
bfd_byte *fpp = (void *) fpregsetp;
for (regi = 0; regi < 32; regi++)
{
if ((regno == -1) || (regno == FP0_REGNUM + regi))
regcache_collect (FP0_REGNUM + regi, (char *) (*fpregsetp + regi));
regcache_collect (FP0_REGNUM + regi, fpp + 8 * regi);
}
if ((regno == -1) || regno == tdep->ppc_fpscr_regnum)
regcache_collect (tdep->ppc_fpscr_regnum, (char *) (*fpregsetp + regi));
right_fill_reg (tdep->ppc_fpscr_regnum, (fpp + 8 * 32));
}

View file

@ -32,7 +32,7 @@
#include "regcache.h"
#include "value.h"
#include "osabi.h"
#include "regset.h"
#include "solib-svr4.h"
#include "ppc-tdep.h"
@ -959,81 +959,114 @@ enum {
};
enum {
ELF_GREGSET_SIZE = (ELF_NGREG * 4),
ELF_FPREGSET_SIZE = (ELF_NFPREG * 8)
};
void
ppc_linux_supply_gregset (char *buf)
static void
right_supply_register (struct regcache *regcache, int wordsize, int regnum,
const bfd_byte *buf)
{
int regi;
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
for (regi = 0; regi < 32; regi++)
supply_register (regi, buf + 4 * regi);
supply_register (PC_REGNUM, buf + 4 * PPC_LINUX_PT_NIP);
supply_register (tdep->ppc_lr_regnum, buf + 4 * PPC_LINUX_PT_LNK);
supply_register (tdep->ppc_cr_regnum, buf + 4 * PPC_LINUX_PT_CCR);
supply_register (tdep->ppc_xer_regnum, buf + 4 * PPC_LINUX_PT_XER);
supply_register (tdep->ppc_ctr_regnum, buf + 4 * PPC_LINUX_PT_CTR);
if (tdep->ppc_mq_regnum != -1)
supply_register (tdep->ppc_mq_regnum, buf + 4 * PPC_LINUX_PT_MQ);
supply_register (tdep->ppc_ps_regnum, buf + 4 * PPC_LINUX_PT_MSR);
regcache_raw_supply (regcache, regnum,
(buf + wordsize
- register_size (current_gdbarch, regnum)));
}
/* Extract the register values found in the WORDSIZED ABI GREGSET,
storing their values in REGCACHE. Note that some are left-aligned,
while others are right aligned. */
void
ppc_linux_supply_fpregset (char *buf)
ppc_linux_supply_gregset (struct regcache *regcache,
int regnum, const void *gregs, size_t size,
int wordsize)
{
int regi;
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
struct gdbarch *regcache_arch = get_regcache_arch (regcache);
struct gdbarch_tdep *regcache_tdep = gdbarch_tdep (regcache_arch);
const bfd_byte *buf = gregs;
for (regi = 0; regi < 32; regi++)
supply_register (FP0_REGNUM + regi, buf + 8 * regi);
right_supply_register (regcache, wordsize, regi, buf + wordsize * regi);
right_supply_register (regcache, wordsize, gdbarch_pc_regnum (regcache_arch),
buf + wordsize * PPC_LINUX_PT_NIP);
right_supply_register (regcache, wordsize, regcache_tdep->ppc_lr_regnum,
buf + wordsize * PPC_LINUX_PT_LNK);
regcache_raw_supply (regcache, regcache_tdep->ppc_cr_regnum,
buf + wordsize * PPC_LINUX_PT_CCR);
regcache_raw_supply (regcache, regcache_tdep->ppc_xer_regnum,
buf + wordsize * PPC_LINUX_PT_XER);
regcache_raw_supply (regcache, regcache_tdep->ppc_ctr_regnum,
buf + wordsize * PPC_LINUX_PT_CTR);
if (regcache_tdep->ppc_mq_regnum != -1)
right_supply_register (regcache, wordsize, regcache_tdep->ppc_mq_regnum,
buf + wordsize * PPC_LINUX_PT_MQ);
right_supply_register (regcache, wordsize, regcache_tdep->ppc_ps_regnum,
buf + wordsize * PPC_LINUX_PT_MSR);
}
static void
ppc32_linux_supply_gregset (const struct regset *regset,
struct regcache *regcache,
int regnum, const void *gregs, size_t size)
{
ppc_linux_supply_gregset (regcache, regnum, gregs, size, 4);
}
static struct regset ppc32_linux_gregset = {
NULL, ppc32_linux_supply_gregset
};
static void
ppc64_linux_supply_gregset (const struct regset *regset,
struct regcache * regcache,
int regnum, const void *gregs, size_t size)
{
ppc_linux_supply_gregset (regcache, regnum, gregs, size, 8);
}
static struct regset ppc64_linux_gregset = {
NULL, ppc64_linux_supply_gregset
};
void
ppc_linux_supply_fpregset (const struct regset *regset,
struct regcache * regcache,
int regnum, const void *fpset, size_t size)
{
int regi;
struct gdbarch *regcache_arch = get_regcache_arch (regcache);
struct gdbarch_tdep *regcache_tdep = gdbarch_tdep (regcache_arch);
const bfd_byte *buf = fpset;
for (regi = 0; regi < 32; regi++)
regcache_raw_supply (regcache, FP0_REGNUM + regi, buf + 8 * regi);
/* The FPSCR is stored in the low order word of the last doubleword in the
fpregset. */
supply_register (tdep->ppc_fpscr_regnum, buf + 8 * 32 + 4);
regcache_raw_supply (regcache, regcache_tdep->ppc_fpscr_regnum,
buf + 8 * 32 + 4);
}
/*
Use a local version of this function to get the correct types for regsets.
*/
static struct regset ppc_linux_fpregset = { NULL, ppc_linux_supply_fpregset };
static void
fetch_core_registers (char *core_reg_sect,
unsigned core_reg_size,
int which,
CORE_ADDR reg_addr)
static const struct regset *
ppc_linux_regset_from_core_section (struct gdbarch *core_arch,
const char *sect_name, size_t sect_size)
{
if (which == 0)
struct gdbarch_tdep *tdep = gdbarch_tdep (core_arch);
if (strcmp (sect_name, ".reg") == 0)
{
if (core_reg_size == ELF_GREGSET_SIZE)
ppc_linux_supply_gregset (core_reg_sect);
if (tdep->wordsize == 4)
return &ppc32_linux_gregset;
else
warning ("wrong size gregset struct in core file");
}
else if (which == 2)
{
if (core_reg_size == ELF_FPREGSET_SIZE)
ppc_linux_supply_fpregset (core_reg_sect);
else
warning ("wrong size fpregset struct in core file");
return &ppc64_linux_gregset;
}
if (strcmp (sect_name, ".reg2") == 0)
return &ppc_linux_fpregset;
return NULL;
}
/* Register that we are able to handle ELF file formats using standard
procfs "regset" structures. */
static struct core_fns ppc_linux_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 */
};
static void
ppc_linux_init_abi (struct gdbarch_info info,
struct gdbarch *gdbarch)
@ -1086,6 +1119,7 @@ ppc_linux_init_abi (struct gdbarch_info info,
/* PPC64 malloc's entry-point is called ".malloc". */
set_gdbarch_name_of_malloc (gdbarch, ".malloc");
}
set_gdbarch_regset_from_core_section (gdbarch, ppc_linux_regset_from_core_section);
}
void
@ -1099,5 +1133,4 @@ _initialize_ppc_linux_tdep (void)
ppc_linux_init_abi);
gdbarch_register_osabi (bfd_arch_rs6000, bfd_mach_rs6k, GDB_OSABI_LINUX,
ppc_linux_init_abi);
add_core_fns (&ppc_linux_regset_core_fns);
}

View file

@ -1,6 +1,7 @@
/* Target-dependent code for GDB, the GNU debugger.
Copyright 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation,
Inc.
This file is part of GDB.
@ -62,8 +63,12 @@ CORE_ADDR ppc64_sysv_abi_adjust_breakpoint_address (struct gdbarch *gdbarch,
CORE_ADDR bpaddr);
int ppc_linux_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache);
struct link_map_offsets *ppc_linux_svr4_fetch_link_map_offsets (void);
void ppc_linux_supply_gregset (char *buf);
void ppc_linux_supply_fpregset (char *buf);
void ppc_linux_supply_gregset (struct regcache *regcache,
int regnum, const void *gregs, size_t size,
int wordsize);
void ppc_linux_supply_fpregset (const struct regset *regset,
struct regcache *regcache,
int regnum, const void *gregs, size_t size);
enum return_value_convention ppc64_sysv_abi_return_value (struct gdbarch *gdbarch,
struct type *valtype,