This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
powerpc-linux biarch corefile support
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: gdb-patches at sourceware dot org
- Date: Tue, 23 Jan 2007 03:13:08 +1030
- Subject: powerpc-linux biarch corefile support
This patch updates the powerpc-linux backend to use the newer struct
regset collect_regset facility. Along with the BFD change in
http://sources.redhat.com/ml/binutils/2006-12/msg00205.html, this
gives better support for debugging 32-bit powerpc programs under a
64-bit gdb. A powerpc64-linux gdb running the gdb testsuite with -m32
shows the following improvements without any regressions. No
regressions on powerpc-linux either.
-FAIL: gdb.base/gcore.exp: where in corefile (pattern 1)
-FAIL: gdb.base/gcore.exp: corefile restored general registers
-FAIL: gdb.base/gcore.exp: capture_command_output failed on print array_func::local_array.
-FAIL: gdb.base/gcore.exp: corefile restored stack array
-FAIL: gdb.base/gcore.exp: corefile restored backtrace
-FAIL: gdb.base/multi-forks.exp: follow parent, print pids (timeout)
-FAIL: gdb.base/readline.exp: print 42
-FAIL: gdb.threads/gcore-thread.exp: a corefile thread is executing thread2
-FAIL: gdb.threads/gcore-thread.exp: thread2 is current thread in corefile
We do lose one feature of the old code, which took some pains to write
the whole register field in a gregset_t when gdb's idea of the
register size was smaller than space in the gregset_t. I figure this
is unimportant since the current gdb code doesn't make use of writing
a single field as far as I can tell. Even if it did, it would
presumably be writing into a buffer that had been initialised at some
point with a full gregset. When writing the full regset, we now clear
the buffer beforehand.
OK to apply?
* ppc-linux-nat.c (supply_gregset): Use ppc_supply_gregset.
(right_fill_reg): Delete.
(fill_gregset): Use ppc_collect_gregset.
(supply_fpregset): Use ppc_supply_fpregset.
(fill_fpregset): Use ppc_collect_fpregset.
* ppc-linux-tdep.c (PPC_LINUX_PT_*): Don't define.
(right_supply_register, ppc_linux_supply_gregset): Delete.
(ppc32_linux_supply_gregset, ppc64_linux_supply_gregset): Delete.
(ppc_linux_supply_fpregset): Delete.
(ppc32_linux_reg_offsets, ppc64_linux_reg_offsets): New.
(ppc64_32_linux_reg_offsets): New.
(ppc32_linux_gregset, ppc64_linux_gregset): Update to use reg offsets,
ppc_supply_gregset, and ppc_collect_gregset.
(ppc64_32_linux_gregset): New.
(ppc_linux_fpregset): Rename to ppc32_linux_fpregset and update.
(ppc_linux_gregset, ppc_linux_fpregset): New functions.
(ppc_linux_regset_from_core_section): Update.
* ppc-tdep.h (ppc_linux_gregset, ppc_linux_fpregset): Declare.
(ppc_linux_supply_gregset, ppc_linux_supply_fpregset): Delete.
(struct ppc_reg_offsets): Add "gpr_step" field.
* ppcnbsd-tdep.c (_initialize_ppcnbsd_tdep): Init gpr_step.
* ppcobsd-tdep.c (_initialize_ppcobsd_tdep): Likewise.
* rs6000-tdep.c (ppc_supply_gregset): Heed gpr_step. Fix xer reg
offset typo.
(ppc_collect_gregset): Heed gpr_step. Clear entire gregset before
filling if transferring all regs.
(ppc_collect_fpregset): Clear entire fpregset before filling if
transferring all regs.
Index: gdb/ppc-linux-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-nat.c,v
retrieving revision 1.62
diff -c -3 -p -r1.62 ppc-linux-nat.c
*** gdb/ppc-linux-nat.c 9 Jan 2007 17:58:55 -0000 1.62
--- gdb/ppc-linux-nat.c 22 Jan 2007 12:33:00 -0000
*************** ppc_linux_store_inferior_registers (int
*** 909,1005 ****
store_ppc_registers (tid);
}
void
supply_gregset (gdb_gregset_t *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 (long);
! 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 (long);
! /* Right fill the register. */
! regcache_raw_collect (current_regcache, regnum,
! ((bfd_byte *) reg
! + wordsize
! - register_size (current_gdbarch, regnum)));
}
void
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 < ppc_num_gprs; regi++)
! {
! if ((regno == -1) || regno == tdep->ppc_gp0_regnum + regi)
! right_fill_reg (tdep->ppc_gp0_regnum + regi, (regp + PT_R0 + regi));
! }
!
! if ((regno == -1) || regno == PC_REGNUM)
! right_fill_reg (PC_REGNUM, regp + PT_NIP);
! if ((regno == -1) || regno == tdep->ppc_lr_regnum)
! right_fill_reg (tdep->ppc_lr_regnum, regp + PT_LNK);
! if ((regno == -1) || regno == tdep->ppc_cr_regnum)
! regcache_raw_collect (current_regcache, tdep->ppc_cr_regnum,
! regp + PT_CCR);
! if ((regno == -1) || regno == tdep->ppc_xer_regnum)
! regcache_raw_collect (current_regcache, tdep->ppc_xer_regnum,
! regp + PT_XER);
! if ((regno == -1) || regno == tdep->ppc_ctr_regnum)
! 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))
! right_fill_reg (tdep->ppc_mq_regnum, regp + PT_MQ);
! #endif
! if ((regno == -1) || regno == tdep->ppc_ps_regnum)
! right_fill_reg (tdep->ppc_ps_regnum, regp + PT_MSR);
}
void
! supply_fpregset (gdb_fpregset_t * 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
- (fpregset_t *), update the register specified by REGNO from gdb's
- idea of the current floating point register set. If REGNO is -1,
- update them all. */
void
fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
{
! int regi;
! struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
! bfd_byte *fpp = (void *) fpregsetp;
!
! if (ppc_floating_point_unit_p (current_gdbarch))
! {
! for (regi = 0; regi < ppc_num_fprs; regi++)
! {
! if ((regno == -1) || (regno == tdep->ppc_fp0_regnum + regi))
! regcache_raw_collect (current_regcache, tdep->ppc_fp0_regnum + regi,
! fpp + 8 * regi);
! }
! if (regno == -1 || regno == tdep->ppc_fpscr_regnum)
! right_fill_reg (tdep->ppc_fpscr_regnum, (fpp + 8 * 32));
! }
}
void _initialize_ppc_linux_nat (void);
--- 909,960 ----
store_ppc_registers (tid);
}
+ /* Functions for transferring registers between a gregset_t or fpregset_t
+ (see sys/ucontext.h) and gdb's regcache. The word size is that used
+ by the ptrace interface, not the current program's ABI. eg. If a
+ powerpc64-linux gdb is being used to debug a powerpc32-linux app, we
+ read or write 64-bit gregsets. This is to suit the host libthread_db.
+
+ Note that the fill_gregset and fill_fpregset functions allow for
+ writing just one register into a gregset_t or fpregset_t buffer.
+ If it so happens that the field in the buffer is larger than gdb's
+ idea of the register size, then the high order bits of the field
+ will not be written. */
+
void
supply_gregset (gdb_gregset_t *gregsetp)
{
! const struct regset *regset = ppc_linux_gregset (current_gdbarch);
! ppc_supply_gregset (regset, current_regcache, -1,
! gregsetp, sizeof (*gregsetp));
}
void
fill_gregset (gdb_gregset_t *gregsetp, int regno)
{
! const struct regset *regset = ppc_linux_gregset (current_gdbarch);
!
! ppc_collect_gregset (regset, current_regcache, regno,
! gregsetp, sizeof (*gregsetp));
}
void
! supply_fpregset (gdb_fpregset_t *fpregsetp)
{
! const struct regset *regset = ppc_linux_fpregset (current_gdbarch);
!
! ppc_supply_fpregset (regset, current_regcache, -1,
! fpregsetp, sizeof (*fpregsetp));
}
void
fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
{
! const struct regset *regset = ppc_linux_fpregset (current_gdbarch);
!
! ppc_collect_fpregset (regset, current_regcache, regno,
! fpregsetp, sizeof (*fpregsetp));
}
void _initialize_ppc_linux_nat (void);
Index: gdb/ppc-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-tdep.c,v
retrieving revision 1.81
diff -c -3 -p -r1.81 ppc-linux-tdep.c
*** gdb/ppc-linux-tdep.c 9 Jan 2007 17:58:55 -0000 1.81
--- gdb/ppc-linux-tdep.c 22 Jan 2007 12:33:00 -0000
***************
*** 67,116 ****
offsetof(struct sigcontext_struct, handler) == 0x14 */
#define PPC_LINUX_HANDLER_PTR_OFFSET (PPC_LINUX_SIGNAL_FRAMESIZE + 0x14)
- /* From <asm/ptrace.h>, values for PT_NIP, PT_R1, and PT_LNK */
- #define PPC_LINUX_PT_R0 0
- #define PPC_LINUX_PT_R1 1
- #define PPC_LINUX_PT_R2 2
- #define PPC_LINUX_PT_R3 3
- #define PPC_LINUX_PT_R4 4
- #define PPC_LINUX_PT_R5 5
- #define PPC_LINUX_PT_R6 6
- #define PPC_LINUX_PT_R7 7
- #define PPC_LINUX_PT_R8 8
- #define PPC_LINUX_PT_R9 9
- #define PPC_LINUX_PT_R10 10
- #define PPC_LINUX_PT_R11 11
- #define PPC_LINUX_PT_R12 12
- #define PPC_LINUX_PT_R13 13
- #define PPC_LINUX_PT_R14 14
- #define PPC_LINUX_PT_R15 15
- #define PPC_LINUX_PT_R16 16
- #define PPC_LINUX_PT_R17 17
- #define PPC_LINUX_PT_R18 18
- #define PPC_LINUX_PT_R19 19
- #define PPC_LINUX_PT_R20 20
- #define PPC_LINUX_PT_R21 21
- #define PPC_LINUX_PT_R22 22
- #define PPC_LINUX_PT_R23 23
- #define PPC_LINUX_PT_R24 24
- #define PPC_LINUX_PT_R25 25
- #define PPC_LINUX_PT_R26 26
- #define PPC_LINUX_PT_R27 27
- #define PPC_LINUX_PT_R28 28
- #define PPC_LINUX_PT_R29 29
- #define PPC_LINUX_PT_R30 30
- #define PPC_LINUX_PT_R31 31
- #define PPC_LINUX_PT_NIP 32
- #define PPC_LINUX_PT_MSR 33
- #define PPC_LINUX_PT_CTR 35
- #define PPC_LINUX_PT_LNK 36
- #define PPC_LINUX_PT_XER 37
- #define PPC_LINUX_PT_CCR 38
- #define PPC_LINUX_PT_MQ 39
- #define PPC_LINUX_PT_FPR0 48 /* each FP reg occupies 2 slots in this space */
- #define PPC_LINUX_PT_FPR31 (PPC_LINUX_PT_FPR0 + 2*31)
- #define PPC_LINUX_PT_FPSCR (PPC_LINUX_PT_FPR0 + 2*32 + 1)
-
static int ppc_linux_at_sigtramp_return_path (CORE_ADDR pc);
/* Determine if pc is in a signal trampoline...
--- 67,72 ----
*************** ppc64_linux_convert_from_func_ptr_addr (
*** 762,860 ****
return addr;
}
! 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 (struct regcache *regcache,
! int regnum, const void *gregs, size_t size,
! int wordsize)
! {
! int regi;
! 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 < ppc_num_gprs; regi++)
! right_supply_register (regcache, wordsize,
! regcache_tdep->ppc_gp0_regnum + 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;
!
! if (! ppc_floating_point_unit_p (regcache_arch))
! return;
!
! for (regi = 0; regi < ppc_num_fprs; regi++)
! regcache_raw_supply (regcache,
! regcache_tdep->ppc_fp0_regnum + regi,
! buf + 8 * regi);
!
! /* The FPSCR is stored in the low order word of the last
! doubleword in the fpregset. */
! regcache_raw_supply (regcache, regcache_tdep->ppc_fpscr_regnum,
! buf + 8 * 32 + 4);
}
! static struct regset ppc_linux_fpregset = { NULL, ppc_linux_supply_fpregset };
static const struct regset *
ppc_linux_regset_from_core_section (struct gdbarch *core_arch,
--- 718,833 ----
return addr;
}
! /* Regset descriptions. */
! static const struct ppc_reg_offsets ppc32_linux_reg_offsets =
! {
! /* General-purpose registers. */
! .r0_offset = 0,
! .gpr_step = 4,
! .pc_offset = 128,
! .ps_offset = 132,
! .cr_offset = 152,
! .lr_offset = 144,
! .ctr_offset = 140,
! .xer_offset = 148,
! .mq_offset = 156,
!
! /* Floating-point registers. */
! .f0_offset = 0,
! .fpscr_offset = 256 + 4,
!
! /* AltiVec registers. */
! .vr0_offset = 0,
! .vrsave_offset = 512,
! .vscr_offset = 512 + 12
! };
! static const struct ppc_reg_offsets ppc64_linux_reg_offsets =
! {
! /* General-purpose registers. */
! .r0_offset = 0,
! .gpr_step = 8,
! .pc_offset = 256,
! .ps_offset = 264,
! .cr_offset = 304 + 4,
! .lr_offset = 288,
! .ctr_offset = 280,
! .xer_offset = 296 + 4,
! .mq_offset = 312 + 4,
!
! /* Floating-point registers. */
! .f0_offset = 0,
! .fpscr_offset = 256 + 4,
!
! /* AltiVec registers. */
! .vr0_offset = 0,
! .vrsave_offset = 528,
! .vscr_offset = 512 + 12
! };
! static const struct ppc_reg_offsets ppc64_32_linux_reg_offsets =
! {
! /* General-purpose registers. */
! .r0_offset = 0 + 4,
! .gpr_step = 8,
! .pc_offset = 256 + 4,
! .ps_offset = 264 + 4,
! .cr_offset = 304 + 4,
! .lr_offset = 288 + 4,
! .ctr_offset = 280 + 4,
! .xer_offset = 296 + 4,
! .mq_offset = 312 + 4,
!
! /* Floating-point registers. */
! .f0_offset = 0,
! .fpscr_offset = 256 + 4,
!
! /* AltiVec registers. */
! .vr0_offset = 0,
! .vrsave_offset = 528,
! .vscr_offset = 512 + 12
! };
static struct regset ppc32_linux_gregset = {
! &ppc32_linux_reg_offsets,
! ppc_supply_gregset,
! ppc_collect_gregset
};
static struct regset ppc64_linux_gregset = {
! &ppc64_linux_reg_offsets,
! ppc_supply_gregset,
! ppc_collect_gregset
};
! static struct regset ppc64_32_linux_gregset = {
! &ppc64_32_linux_reg_offsets,
! ppc_supply_gregset,
! ppc_collect_gregset
! };
!
! static struct regset ppc32_linux_fpregset = {
! &ppc32_linux_reg_offsets,
! ppc_supply_fpregset,
! ppc_collect_fpregset
! };
!
! const struct regset *
! ppc_linux_gregset (struct gdbarch *gdbarch)
! {
! struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
! if (tdep->wordsize == 8)
! return &ppc64_linux_gregset;
! if (sizeof (long) == 8)
! return &ppc64_32_linux_gregset;
! return &ppc32_linux_gregset;
}
! const struct regset *
! ppc_linux_fpregset (struct gdbarch *gdbarch)
! {
! return &ppc32_linux_fpregset;
! }
static const struct regset *
ppc_linux_regset_from_core_section (struct gdbarch *core_arch,
*************** ppc_linux_regset_from_core_section (stru
*** 869,875 ****
return &ppc64_linux_gregset;
}
if (strcmp (sect_name, ".reg2") == 0)
! return &ppc_linux_fpregset;
return NULL;
}
--- 842,848 ----
return &ppc64_linux_gregset;
}
if (strcmp (sect_name, ".reg2") == 0)
! return &ppc32_linux_fpregset;
return NULL;
}
Index: gdb/ppc-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/ppc-tdep.h,v
retrieving revision 1.52
diff -c -3 -p -r1.52 ppc-tdep.h
*** gdb/ppc-tdep.h 9 Jan 2007 17:58:55 -0000 1.52
--- gdb/ppc-tdep.h 22 Jan 2007 12:33:00 -0000
*************** CORE_ADDR ppc64_sysv_abi_adjust_breakpoi
*** 58,69 ****
CORE_ADDR bpaddr);
int ppc_linux_memory_remove_breakpoint (struct bp_target_info *bp_tgt);
struct link_map_offsets *ppc_linux_svr4_fetch_link_map_offsets (void);
! 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,
--- 58,65 ----
CORE_ADDR bpaddr);
int ppc_linux_memory_remove_breakpoint (struct bp_target_info *bp_tgt);
struct link_map_offsets *ppc_linux_svr4_fetch_link_map_offsets (void);
! const struct regset *ppc_linux_gregset (struct gdbarch *);
! const struct regset *ppc_linux_fpregset (struct gdbarch *);
enum return_value_convention ppc64_sysv_abi_return_value (struct gdbarch *gdbarch,
struct type *valtype,
*************** struct ppc_reg_offsets
*** 85,90 ****
--- 81,87 ----
{
/* General-purpose registers. */
int r0_offset;
+ int gpr_step;
int pc_offset;
int ps_offset;
int cr_offset;
Index: gdb/ppcnbsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppcnbsd-tdep.c,v
retrieving revision 1.31
diff -c -3 -p -r1.31 ppcnbsd-tdep.c
*** gdb/ppcnbsd-tdep.c 9 Jan 2007 17:58:55 -0000 1.31
--- gdb/ppcnbsd-tdep.c 22 Jan 2007 12:33:01 -0000
*************** _initialize_ppcnbsd_tdep (void)
*** 212,217 ****
--- 212,218 ----
{
/* General-purpose registers. */
ppcnbsd_reg_offsets.r0_offset = 0;
+ ppcnbsd_reg_offsets.gpr_step = 4;
ppcnbsd_reg_offsets.lr_offset = 128;
ppcnbsd_reg_offsets.cr_offset = 132;
ppcnbsd_reg_offsets.xer_offset = 136;
Index: gdb/ppcobsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppcobsd-tdep.c,v
retrieving revision 1.13
diff -c -3 -p -r1.13 ppcobsd-tdep.c
*** gdb/ppcobsd-tdep.c 9 Jan 2007 17:58:55 -0000 1.13
--- gdb/ppcobsd-tdep.c 22 Jan 2007 12:33:01 -0000
*************** _initialize_ppcobsd_tdep (void)
*** 331,336 ****
--- 331,337 ----
{
/* General-purpose registers. */
ppcobsd_reg_offsets.r0_offset = 0;
+ ppcobsd_reg_offsets.gpr_step = 4;
ppcobsd_reg_offsets.pc_offset = 384;
ppcobsd_reg_offsets.ps_offset = 388;
ppcobsd_reg_offsets.cr_offset = 392;
Index: gdb/rs6000-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-tdep.c,v
retrieving revision 1.260
diff -c -3 -p -r1.260 rs6000-tdep.c
*** gdb/rs6000-tdep.c 9 Jan 2007 17:58:57 -0000 1.260
--- gdb/rs6000-tdep.c 22 Jan 2007 12:33:03 -0000
*************** ppc_supply_gregset (const struct regset
*** 338,344 ****
for (i = tdep->ppc_gp0_regnum, offset = offsets->r0_offset;
i < tdep->ppc_gp0_regnum + ppc_num_gprs;
! i++, offset += 4)
{
if (regnum == -1 || regnum == i)
ppc_supply_reg (regcache, i, gregs, offset);
--- 338,344 ----
for (i = tdep->ppc_gp0_regnum, offset = offsets->r0_offset;
i < tdep->ppc_gp0_regnum + ppc_num_gprs;
! i++, offset += offsets->gpr_step)
{
if (regnum == -1 || regnum == i)
ppc_supply_reg (regcache, i, gregs, offset);
*************** ppc_supply_gregset (const struct regset
*** 360,366 ****
gregs, offsets->ctr_offset);
if (regnum == -1 || regnum == tdep->ppc_xer_regnum)
ppc_supply_reg (regcache, tdep->ppc_xer_regnum,
! gregs, offsets->cr_offset);
if (regnum == -1 || regnum == tdep->ppc_mq_regnum)
ppc_supply_reg (regcache, tdep->ppc_mq_regnum, gregs, offsets->mq_offset);
}
--- 360,366 ----
gregs, offsets->ctr_offset);
if (regnum == -1 || regnum == tdep->ppc_xer_regnum)
ppc_supply_reg (regcache, tdep->ppc_xer_regnum,
! gregs, offsets->xer_offset);
if (regnum == -1 || regnum == tdep->ppc_mq_regnum)
ppc_supply_reg (regcache, tdep->ppc_mq_regnum, gregs, offsets->mq_offset);
}
*************** ppc_supply_fpregset (const struct regset
*** 396,402 ****
}
/* 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. */
--- 396,402 ----
}
/* 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. */
*************** ppc_collect_gregset (const struct regset
*** 411,420 ****
size_t offset;
int i;
offset = offsets->r0_offset;
for (i = tdep->ppc_gp0_regnum;
i < tdep->ppc_gp0_regnum + ppc_num_gprs;
! i++, offset += 4)
{
if (regnum == -1 || regnum == i)
ppc_collect_reg (regcache, i, gregs, offset);
--- 411,423 ----
size_t offset;
int i;
+ if (regnum == -1)
+ memset (gregs, 0, len);
+
offset = offsets->r0_offset;
for (i = tdep->ppc_gp0_regnum;
i < tdep->ppc_gp0_regnum + ppc_num_gprs;
! i++, offset += offsets->gpr_step)
{
if (regnum == -1 || regnum == i)
ppc_collect_reg (regcache, i, gregs, offset);
*************** ppc_collect_gregset (const struct regset
*** 443,449 ****
}
/* Collect register REGNUM in the floating-point register set
! REGSET. from register cache REGCACHE into the buffer specified by
FPREGS and LEN. If REGNUM is -1, do this for all registers in
REGSET. */
--- 446,452 ----
}
/* Collect register REGNUM in the floating-point register set
! REGSET from register cache REGCACHE into the buffer specified by
FPREGS and LEN. If REGNUM is -1, do this for all registers in
REGSET. */
*************** ppc_collect_fpregset (const struct regse
*** 460,465 ****
--- 463,471 ----
gdb_assert (ppc_floating_point_unit_p (gdbarch));
+ if (regnum == -1)
+ memset (fpregs, 0, len);
+
offset = offsets->f0_offset;
for (i = tdep->ppc_fp0_regnum;
i <= tdep->ppc_fp0_regnum + ppc_num_fprs;
--
Alan Modra
IBM OzLabs - Linux Technology Centre