diff options
author | Andrew Cagney <cagney@redhat.com> | 2004-03-15 21:35:25 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2004-03-15 21:35:25 +0000 |
commit | 3c217a4773088c4d56a4d57d87a1b02d9e23619d (patch) | |
tree | 706d30c1723669cad7546eb838ab7864c022a052 /gdb/ppc-linux-tdep.c | |
parent | 78d06c92934e98a497e73b117cabba9b03a2d548 (diff) | |
download | gdb-3c217a4773088c4d56a4d57d87a1b02d9e23619d.tar.gz |
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,
Diffstat (limited to 'gdb/ppc-linux-tdep.c')
-rw-r--r-- | gdb/ppc-linux-tdep.c | 133 |
1 files changed, 83 insertions, 50 deletions
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c index 84eb742d8e2..a8173eaad14 100644 --- a/gdb/ppc-linux-tdep.c +++ b/gdb/ppc-linux-tdep.c @@ -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) }; +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); - - 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); + 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 (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 @@ 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); } |