diff options
author | Jim Blandy <jimb@codesourcery.com> | 2004-09-01 18:09:58 +0000 |
---|---|---|
committer | Jim Blandy <jimb@codesourcery.com> | 2004-09-01 18:09:58 +0000 |
commit | 5b8919bf5f6cad5b72516e20bf1e80fb9713c5a1 (patch) | |
tree | 416df583986ba60bde3cbfc97bc520cc6a860461 | |
parent | 2b6538ed8eba1c07f12efb198940a1cb853dc6d1 (diff) | |
download | gdb-5b8919bf5f6cad5b72516e20bf1e80fb9713c5a1.tar.gz |
Allow access to all 64 bits of the SPE GPR's in multi-threaded
programs.
* ppc-tdep.h (struct speregset): New struct type.
* ppc-linux-tdep.c: #include "gdb_assert.h".
(ppc_linux_supply_speregset, ppc_linux_collect_speregset): New
functions.
(ppc_linux_speregset): New structure.
(ppc_linux_init_abi): Describe how to pass the full 64-bit values
of the SPE GPRs across the thread-db interface.
* ppc-linux-nat.c (struct gdb_evrregset_t): Doc fix.
* Makefile.in (ppc-linux-tdep.o): Update dependencies.
Allow targets to specify an extended register set, to be passed
through libthread_db via its 'xregs' functions.
* gdbarch.sh (XREGS_REGSET, XREGS_SIZE, XREGS_NAME): New gdbarch
members.
* gdbarch.c, gdbarch.h: Regenerated.
* proc-service.c: #include "regset.h" and "regcache.h".
(ps_lgetxregsize, ps_lgetxregs, ps_lsetxregs): Fill in real
implementations of these functions.
* thread-db.c: #include "regset.h".
(td_thr_getxregsize_p, td_thr_getxregs_p, td_thr_setxregs_p): New
variables.
(thread_db_load): Initialize them.
(warned_xregs_not_implemented): New variable.
(thread_db_new_objfile): Clear it here.
(thread_db_fetch_registers, thread_db_store_registers): Supply and
collect the xregset, too, if the architecture says it has one, and
libthread_db seems to be able to support it.
* Makefile.in (proc-service.o, thread-db.o): Update dependencies.
-rw-r--r-- | gdb/ChangeLog | 33 | ||||
-rw-r--r-- | gdb/ppc-linux-nat.c | 7 | ||||
-rw-r--r-- | gdb/ppc-linux-tdep.c | 105 |
3 files changed, 144 insertions, 1 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index faeb4c79aa8..e0de9328b70 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,36 @@ +2004-09-01 Jim Blandy <jimb@redhat.com> + + Allow access to all 64 bits of the SPE GPR's in multi-threaded + programs. + * ppc-tdep.h (struct speregset): New struct type. + * ppc-linux-tdep.c: #include "gdb_assert.h". + (ppc_linux_supply_speregset, ppc_linux_collect_speregset): New + functions. + (ppc_linux_speregset): New structure. + (ppc_linux_init_abi): Describe how to pass the full 64-bit values + of the SPE GPRs across the thread-db interface. + * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fix. + * Makefile.in (ppc-linux-tdep.o): Update dependencies. + + Allow targets to specify an extended register set, to be passed + through libthread_db via its 'xregs' functions. + * gdbarch.sh (XREGS_REGSET, XREGS_SIZE, XREGS_NAME): New gdbarch + members. + * gdbarch.c, gdbarch.h: Regenerated. + * proc-service.c: #include "regset.h" and "regcache.h". + (ps_lgetxregsize, ps_lgetxregs, ps_lsetxregs): Fill in real + implementations of these functions. + * thread-db.c: #include "regset.h". + (td_thr_getxregsize_p, td_thr_getxregs_p, td_thr_setxregs_p): New + variables. + (thread_db_load): Initialize them. + (warned_xregs_not_implemented): New variable. + (thread_db_new_objfile): Clear it here. + (thread_db_fetch_registers, thread_db_store_registers): Supply and + collect the xregset, too, if the architecture says it has one, and + libthread_db seems to be able to support it. + * Makefile.in (proc-service.o, thread-db.o): Update dependencies. + 2004-08-25 Jim Blandy <jimb@redhat.com> Merge changes from trunk: diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c index c98bb93f879..e57f742ad9a 100644 --- a/gdb/ppc-linux-nat.c +++ b/gdb/ppc-linux-nat.c @@ -129,7 +129,12 @@ typedef char gdb_vrregset_t[SIZEOF_VRREGS]; bottom halves together. This is the structure filled in by PTRACE_GETEVRREGS and written to - the inferior's registers by PTRACE_SETEVRREGS. */ + the inferior's registers by PTRACE_SETEVRREGS. + + Note that this is not the same as 'struct speregset', which + describes how the ABI says the kernel dumps SPE-style 64-bit GPR's + in core files. It would be nicer if PTRACE_{GET,SET}EVRREGS and + core files used the same layout, but they don't. */ struct gdb_evrregset_t { unsigned long evr[32]; diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c index 585260bf416..f9f2d84ff28 100644 --- a/gdb/ppc-linux-tdep.c +++ b/gdb/ppc-linux-tdep.c @@ -37,6 +37,7 @@ #include "ppc-tdep.h" #include "trad-frame.h" #include "frame-unwind.h" +#include "gdb_assert.h" /* The following instructions are used in the signal trampoline code on GNU/Linux PPC. The kernel used to use magic syscalls 0x6666 and @@ -1058,6 +1059,98 @@ ppc_linux_regset_from_core_section (struct gdbarch *core_arch, } static void +ppc_linux_supply_speregset (const struct regset *regset, + struct regcache *regcache, + int regnum, + const void *buf, + size_t len) +{ + struct gdbarch *arch = get_regcache_arch (regcache); + struct gdbarch_tdep *tdep = gdbarch_tdep (arch); + const struct speregset *speregset = buf; + + gdb_assert (len == sizeof (*speregset)); + gdb_assert (register_size (arch, tdep->ppc_ev0_regnum) + == sizeof (speregset->gpr[0])); + gdb_assert (register_size (arch, tdep->ppc_acc_regnum) + == sizeof (speregset->acc)); + gdb_assert (register_size (arch, tdep->ppc_spefscr_regnum) + == sizeof (speregset->spefscr)); + + if (regnum == -1) + { + int i; + + for (i = 0; i < 32; i++) + regcache_raw_supply (regcache, tdep->ppc_ev0_regnum + i, + &speregset->gpr[i]); + } + else if (tdep->ppc_ev0_regnum <= regnum + && regnum <= tdep->ppc_ev31_regnum) + regcache_raw_supply (regcache, tdep->ppc_ev0_regnum + regnum, + &speregset->gpr[regnum - tdep->ppc_ev0_regnum]); + + if (regnum == tdep->ppc_acc_regnum + || regnum == -1) + regcache_raw_supply (regcache, tdep->ppc_acc_regnum, + &speregset->acc); + + if (regnum == tdep->ppc_spefscr_regnum + || regnum == -1) + regcache_raw_supply (regcache, tdep->ppc_spefscr_regnum, + &speregset->spefscr); +} + +static void +ppc_linux_collect_speregset (const struct regset *regset, + const struct regcache *regcache, + int regnum, + void *buf, + size_t len) +{ + struct gdbarch *arch = get_regcache_arch (regcache); + struct gdbarch_tdep *tdep = gdbarch_tdep (arch); + struct speregset *speregset = buf; + + gdb_assert (len == sizeof (*speregset)); + gdb_assert (register_size (arch, tdep->ppc_ev0_regnum) + == sizeof (speregset->gpr[0])); + gdb_assert (register_size (arch, tdep->ppc_acc_regnum) + == sizeof (speregset->acc)); + gdb_assert (register_size (arch, tdep->ppc_spefscr_regnum) + == sizeof (speregset->spefscr)); + + if (regnum == -1) + { + int i; + + for (i = 0; i < 32; i++) + regcache_raw_collect (regcache, tdep->ppc_ev0_regnum + i, + &speregset->gpr[i]); + } + else if (tdep->ppc_ev0_regnum <= regnum + && regnum <= tdep->ppc_ev31_regnum) + regcache_raw_collect (regcache, regnum, + &speregset->gpr[regnum - tdep->ppc_ev0_regnum]); + + if (regnum == tdep->ppc_acc_regnum + || regnum == -1) + regcache_raw_collect (regcache, tdep->ppc_acc_regnum, &speregset->acc); + + if (regnum == tdep->ppc_spefscr_regnum + || regnum == -1) + regcache_raw_collect (regcache, tdep->ppc_spefscr_regnum, + &speregset->spefscr); +} + +static const struct regset ppc_linux_speregset = +{ + 0, + ppc_linux_supply_speregset, + ppc_linux_collect_speregset +}; + +static void ppc_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { @@ -1093,6 +1186,18 @@ ppc_linux_init_abi (struct gdbarch_info info, set_solib_svr4_fetch_link_map_offsets (gdbarch, ppc_linux_svr4_fetch_link_map_offsets); } + + if (info.bfd_arch_info->arch == bfd_arch_powerpc + && info.bfd_arch_info->mach == bfd_mach_ppc_e500) + { + /* On the e500, the GPR's are really 64 bits long. However, we + continue to treat the gpr's as if they were 32 bits long, and + handle the upper haves separately. This means that we need a + special way to pass the upper halves through thread_db. */ + set_gdbarch_xregs_regset (gdbarch, &ppc_linux_speregset); + set_gdbarch_xregs_size (gdbarch, sizeof (struct speregset)); + set_gdbarch_xregs_name (gdbarch, "SPE vector"); + } if (tdep->wordsize == 8) { |