diff options
author | Mark Kettenis <kettenis@gnu.org> | 2004-01-03 10:08:45 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@gnu.org> | 2004-01-03 10:08:45 +0000 |
commit | 386c036baa78260724d16fb2672450b09b684dcb (patch) | |
tree | 7e8d71cf5289cfbda1f817bd13958f645d637206 /gdb/sparc-nat.c | |
parent | 06846494cea461fe8d487d2f8611cd4dd6fc3d36 (diff) | |
download | gdb-386c036baa78260724d16fb2672450b09b684dcb.zip gdb-386c036baa78260724d16fb2672450b09b684dcb.tar.gz gdb-386c036baa78260724d16fb2672450b09b684dcb.tar.bz2 |
* Makefile.in (ALLDEPFILES): Remove sparc-linux-nat.c and
sparcl-tdep.c. Add sparc-linux-tdep.c, sparc-sol2-nat.c,
sparc-sol2-tdep.c, sparc-sol2-nat.c, sparc-sol2-tdep.c,
sparc64-linux-nat.c, sparc64-linux-tdep.c, sparc64-nat.c,
sparc64-sol2-tdep.c, sparc64-tdep.c, sparc64fbsd-nat.c,
sparc64fbsd-tdep.c, sparcnbsd-nat.c, sparcnbsd-tdep.c.
(sparc_nat_h): New variable.
(sparcbsd_nat_h, sparcnbsd_tdep_h): Remove variables.
(tm-sun4os4.h): Remove dependency.
(sparcbsd-nat.o, sparc-linux-nat.o): Remove dependencies.
(sparc64fbsd-nat.o, sparc64fbsd-tdep.o, sparc64nbsd-nat.o,
sparc64-tdep.o, sparc-nat.o, sparcnbsd-nat.o, sparcnbsd-tdep.o,
sparc-tdep.o): Update dependencies.
(sparc-linux-tdep.o, sparc-sol2-nat.o, sparc-sol2-tdep.o,
sparc64-linux-nat.o, sparc64-linux-tdep.o, sparc64-nat.o,
sparc64-sol2-tdep.o, sparc64-tdep.o, sparc64nbsd-tdep.o): New
dependencies.
* configure.host: Remove existing sparc-*-lynxos*,
sparc-*-solaris*, sparc-*-sunos4*, sparc-*-sunos5*, sparc-*-*,
ultrasparc-*-freebsd, sparcv9-*-freebsd, sparc64-*-linux*,
sparcv9-*-* and sparc64-*-* triplets. Add new sparc64-*-linux*,
sparc-*-solaris2*, sparcv9-*-solaris2* and sparc64-*-solaris2*
triplets.
* configure.tgt: Remove exitsing sparc-*-aout*, sparc-*-coff*,
sparc-*-elf*, sparc*-lynxos*, sparc-*-solars2*, sparc-*-sunos4*,
sparc-*-sunos5*, sparc-*-vxworks*, sparc64-*linux*, sparc64-*-*,
sparcv9-*-* and commented out sparc64-*-solars2* triplets. Add
new sparc-*-solaris2.[0-6], sparc-*-solaris2.[0-6].*,
sparc64-*-linux, sparc-*-solaris2*, sparcv9-*-solaris*,
sparc64-*-solaris2* and sparc64-*-* triplets.
* sparc64-tdep.c: Update copyright year. Include "inferior.h",
"symtab.h" and "objfiles.h".
(BIAS): Remove define.
(X_OP, X_RD, X_A, X_COND, X_OP2, X_IMM22, X_OP3, X_I, X_DISP22)
(X_DISP19): Remove macros.
(sparc_fetch_instruction): Remove function.
(struct gdbarch_tdep): Remove definition.
(SPARC64_NUM_REGS, SPARC64_NUM_PSEUDO_REGS): Use ARRAY_SIZE.
(sparc_breakpoint_from_pc): Remove function.
(struct sparc64_frame_cache): Remove definition.
(sparc64_alloc_frame_cache, sparc64_analyze_prologue,
sparc64_unwind_pc): Remove functions.
(sparc64_skip_prologue): Use `struct sparc_frame_cache' instead of
`struct sparc64_frame_cache. Call sparc_analyze_prologue instead
of sparc64_analyze_prologue. Mark constant as ULL instead of UL.
(sparc64_frame_cache): Change return type to `struct
sparc_frame_cache *'. Simply call sparc_frame_cache.
(sparc64_frame_this_id, sparc64_frame_prev_register,
sparc64_frame_base_address): Use `struct sparc_frame_cache'
instead of `struct sparc64_frame_cache.
(sparc_unwind_dummy_id, sparc_extract_struct_value_address,
sparc_analyze_control_transfer, sparc_software_single_step,
sparc64_gdbarch_init, sparc_supply_rwindow, sparc_fill_rwindow,
_initialize_sparc64_tdep): Remove functions.
(TSTATE_CWP, TSTATE_ICC, TSTATE_XCC): New macros.
(PSR_S, PSR_ICC, PSR_VERS, PSR_IMPL, PSR_V8PLUS, PSR_XCC): New
macros.
(sparc64_supply_gregset, sparc64_collect_gregset,
sparc64_supply_fpregset, sparc64_collect_fpregset): New functions.
(sparc64_init_abi): New function.
* sparc64-tdep.h: Update copyright year. Fix typo in multiple
inclusion guard. Include "sparc-tdep.h".
(BIAS): Define.
(r_tstate_offset, r_fprs_offset): New defines.
(enum sparc_regnum): Remove defenition.
(enum sparc64_regnum): Reformat.
(sparc_supply_rwindow, sparc_fill_rwindow): Remove prototypes.
(sparc64_init_abi, sparc64_supply_gregset,
sparc64_collect_gregset, sparc64_supply_fpregset,
sparc64_collect_fpregset): New prototypes.
(sparc64_sol2_gregset, sparc64nbsd_gregset, sparc64fbsd_gregset):
Add extern declarations.
(sparc64_sol2_init_abi): New prototype.
(sparc64fbsd_supply_reg, sparc64fbsd_fill_reg)
(sparc64fbsd_supply_fpreg, sparc64fbsd_fill_fpreg): Remove
prototypes.
* sparc64fbsd-nat.c: Include "sparc-nat.h", don't include
"sparnbsd-nat.h".
(sparc64fbsd_reg_supplies_p, sparc64fbsd_fpreg_supplies_p): Remove
functions.
(_initialize_sparc64fbsd_nat): Remove initialization of
sparcbsd_supply_reg, sparcbsd_fill_reg, sparcbsd_supply_fpreg,
sparcbsd_fill_fpreg, sparcbsd_reg_supplies_p,
sparcbsd_fpreg_supplies_p. Initialize sparc_gregset.
* sparc64fbsd-tdep.c: Update copyright year. Include "frame.h",
"frame-unwind.h", "trad-frame.h" and "gdb_assert.h".
(sparc64fbsd_r_global_offset, sparc64fbsd_r_out_offset)
(sparc64fbsd_r_fprs_offset, sparc64fbsd_r_tnpc_offset)
(sparc64fbsd_r_tpc_offset, sparc64fbsd_r_tstate_offset)
(sparc64fbsd_r_y_offset): Remove variables.
(sparc64fbsd_sizeof_struct_reg, sparc64fbsd_sizeof_struct_fpreg):
Make static and const.
(sparc64fbsd_supply_reg, sparc64fbsd_fill_reg)
(sparc64fbsd_supply_fpreg, sparc64fbsd_fill_fpreg): Remove
functions.
(sparc64fbsd_gregset): New variable.
(fetch_core_registers): Replace calls to sparc64fbsd_supply_reg
and sparc64fbsd_supply_fpreg with calls to sparc64_supply_gregset
and sparc64_supply_fpregset.
(sparc64fbsd_pc_in_sigtramp, sparc64fbsd_sigtramp_frame_cache)
(sparc64fbsd_sigtramp_frame_this_id)
(sparc64fbsd_sigtramp_frame_prev_register): New functions.
(sparc64fbsd_sigtramp_frame_unwind): New variable.
(sparc64fbsd_sigtramp_frame_sniffer): New function.
(sparc64fbsd_init_abi): Set pc_in_sigtramp, append
sparc64fbsd_sigtramp_frame_sniffer. Call sparc64_init_abi.
* sparcnbsd-tdep.c: Update copyright year. Include
"floatformat.h", "frame.h", "frame-unwind.h", "symtab.h",
"trad-frame.h" and "gdb_assert.h", don't include "target.h",
"value.h" and "sparcnbsd-tdep.h".
(REG32_OFFSET_PSR, REG32_OFFSET_PC, REG32_OFFSET_NPC)
(REG32_OFFSET_Y, REG32_OFFSET_GLOBAL, REG32_OFFSET_OUT)
(REG64_OFFSET_TSTATE, REG64_OFFSET_PC, REG64_OFFSET_NPC)
(REG64_OFFSET_Y, REG64_OFFSET_GLOBAL, REG64_OFFSET_OUT): Remove
defines.
(sparcnbsd_gregset): New variable.
(sparcnbsd_supply_reg32, sparcnbsd_supply_reg64)
(sparcnbsd_fill_reg32, sparcnbsd_fill_reg64)
(sparcnbsd_supply_fpreg32, sparcnbsd_supply_fpreg64)
(sparcnbsd_fill_reg32, sparcnbsd_fill_reg64): Remove functions.
(sparc32nbsd_sigtramp_start, sparc32nbsd_sigtramp_end): New
variables.
(sparc32nbsd_pc_in_sigtramp, sparc32nbsd_sigcontext_frame_cache)
(sparc32nbsd_sigcontext_frame_this_id)
(sparc32nbsd_sigcontext_frame_prev_register): New functions.
(sparc32nbsd_sigcontext_frame_unwind): New variable.
(sparc32nbsd_sigtramp_frame_sniffer): New function.
(sparcnbsd_get_longjmp_target_32,
sparcnbsd_get_longjmp_target_64): Remove functions.
(sparcnbsd_aout_in_solib_call_trampoline): Rewrite.
(sparcnbsd_init_abi_common, sparcnbsd_init_aout,
sparcnbsd_init_elf): Remove.
(sparcnbsd_init_abi, sparcnbsd_aout_init_abi)
(sparcnbsd_elf_init_abi): New functions.
(_initialize_sparcnbsd_tdep): New prototype.
(_initialize_sparnbsd_tdep): Update.
* config/sparc/fbsd.mh (NATDEPFILES): Remove sparcbsd-nat.o and
corelow.o. Add sparc64-nat.o and sparc-nat.o.
* config/sparc/fbsd.mt (TDEPFILES): Add sparc-tdep.o and corelow.o.
* config/sparc/linux.mh: Update comment.
(XM_FILE, HOST_IPC): Remove variables.
(NATDEPFILES): Add sparc-sol2-nat.o and core-regset.o. Remove
sparc-linux-nat.o.
* config/sparc/linux.mt: Update comment.
(TDEPFILES): Add sparc-sol2-tdep.o and sparc-linux-tdep.o.
* config/sparc/nbsd.mt: Reformat.
* config/sparc/nbsd64.mh: Update comment.
(NATDEPFILES): Add sparc-nat.o.
* config/sparc/nbsd64.mt: Update comment.
(TDEPFILES): Add sparc64-tdep.o and sparc64nbsd-tdep.o.
(TM_FILE): Set to tm-nbsd.h.
* config/sparc/nbsdelf.mh: Update comment.
(NATDEPFILES): Add sparc-nat.o.
(XM_FILE): Delete.
* config/sparc/nbsdaout.mh: Update comment.
(NATDEPFILES): Add sparc-nat.o
(XM_FILE): Delete.
* config/sparc/nm-linux.h: Update copyright year. Don't include
"config/nm-svr4.h" and "solib.h". Add protection against multiple
inclusion.
(KERNEL_U_SIZE): Remove define.
(kernel_u_size): Remove prototype.
(PTRACE_ARG3_TYPE, PTRACE_XFER_TYPE): Define.
* config/sparc/nm-nbsd.h: Update copyright. Don't include
"regcache.h".
(CHILD_PREPARE_TO_STORE): Remove define.
* config/sparc/nm-nbsdaout.h: Tweak some comments.
* sparc-nat.c, sparc-tdep.c, sparc-tdep.h, sparc64nbsd-nat.c,
sparcnbsd-nat.c: Rewrite files.
* config/sparc/tm-linux.h, config/sparc/tm-nbsd.h: Rewrite files.
* sparc-linux-nat.c, sparcbsd-nat.c, sparcbsd-nat.h,
sparcnbsd-tdep.h: Remove files.
* config/sparc/nm-sparclynx.h, config/sparc/nm-sun4os4.h,
config/sparc/nm-sun4sol2.h, config/sparc/sp64.mt,
config/sparc/sp64linux.mt, config/sparc/sp64sol2.mt,
config/sparc/sparc-em.mt, config/sparc/sparclynx.mh,
config/sparc/sparclynx.mt, config/sparc/sun4os4.mh,
config/sparc/sun4os4.mt, config/sparc/sun4sol2.mh,
config/sparc/sun4sol2.mt, config/sparc/tm-sp64.h,
config/sparc/tm-sp64linux.h, config/sparc/tm-sparc.h,
config/sparc/tm-sparclynx.h, config/sparc/tm-spc-em.h,
config/sparc/tm-sun4os4.h, config/sparc/tm-sun4sol2.h,
config/sparc/tm-vxsparc.h, config/sparc/vxsparc.mt,
config/sparc/xm-linux.h, config/sparc/xm-sun4sol2.h: Remove files.
* sparc-linux-tdep.c, sparc-nat.h, sparc-sol2-nat.c,
sparc-sol2-tdep.c, sparc64-linux-nat.c, sparc64-linux-t dep.c,
sparc64-nat.c, sparc64-sol2-tdep.c, sparc64nbsd-tdep.c: New files.
* config/sparc/linux64.mh, config/sparc/linux64.mt,
config/sparc/nm-sol2.h, config/sparc/sol2-64.mt,
config/sparc/sol2.mh, config/sparc/sol2.mt, config/sparc/sparc.mt,
config/sparc/sparc64.mt, config/sparc/tm-sol2.h: New files.
Diffstat (limited to 'gdb/sparc-nat.c')
-rw-r--r-- | gdb/sparc-nat.c | 480 |
1 files changed, 184 insertions, 296 deletions
diff --git a/gdb/sparc-nat.c b/gdb/sparc-nat.c index a76d0e5..09ee7c6 100644 --- a/gdb/sparc-nat.c +++ b/gdb/sparc-nat.c @@ -1,7 +1,6 @@ -/* Functions specific to running gdb native on a SPARC running SunOS4. +/* Native-dependent code for SPARC. - Copyright 1989, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -22,46 +21,121 @@ #include "defs.h" #include "inferior.h" -#include "target.h" -#include "gdbcore.h" #include "regcache.h" -#include "sparc-tdep.h" - -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif #include <signal.h> +#include "gdb_string.h" #include <sys/ptrace.h> #include "gdb_wait.h" -#ifdef __linux__ -#include <asm/reg.h> -#else +#ifdef HAVE_MACHINE_REG_H #include <machine/reg.h> #endif -#include <sys/user.h> -/* We don't store all registers immediately when requested, since they - get sent over in large chunks anyway. Instead, we accumulate most - of the changes and send them over once. "deferred_stores" keeps - track of which sets of registers we have locally-changed copies of, - so we only need send the groups that have changed. */ +#include "sparc-tdep.h" +#include "sparc-nat.h" + +/* With some trickery we can use the code in this file for most (if + not all) ptrace(2) based SPARC systems, which includes SunOS 4, + Linux and the various SPARC BSD's. + + First, we need a data structure for use with ptrace(2). SunOS has + `struct regs' and `struct fp_status' in <machine/reg.h>. BSD's + have `struct reg' and `struct fpreg' in <machine/reg.h>. GNU/Linux + has the same structures as SunOS 4, but they're in <asm/reg.h>, + which is a kernel header. As a general rule we avoid including + GNU/Linux kernel headers. Fortunately GNU/Linux has a `gregset_t' + and a `fpregset_t' that are equivalent to `struct regs' and `struct + fp_status' in <sys/ucontext.h>, which is automatically included by + <signal.h>. Settling on using the `gregset_t' and `fpregset_t' + typedefs, providing them for the other systems, therefore solves + the puzzle. */ + +#ifdef HAVE_MACHINE_REG_H +#ifdef HAVE_STRUCT_REG +typedef struct reg gregset_t; +typedef struct fpreg fpregset_t; +#else +typedef struct regs gregset_t; +typedef struct fp_status fpregset_t; +#endif +#endif + +/* Second, we need to remap the BSD ptrace(2) requests to their SunOS + equivalents. GNU/Linux already follows SunOS here. */ -#define INT_REGS 1 -#define STACK_REGS 2 -#define FP_REGS 4 +#ifndef PTRACE_GETREGS +#define PTRACE_GETREGS PT_GETREGS +#endif + +#ifndef PTRACE_SETREGS +#define PTRACE_SETREGS PT_SETREGS +#endif -/* Fetch one or more registers from the inferior. REGNO == -1 to get - them all. We actually fetch more than requested, when convenient, - marking them as valid so we won't fetch them again. */ +#ifndef PTRACE_GETFPREGS +#define PTRACE_GETFPREGS PT_GETFPREGS +#endif + +#ifndef PTRACE_SETFPREGS +#define PTRACE_SETFPREGS PT_SETFPREGS +#endif + +/* Register set description. */ +const struct sparc_gregset *sparc_gregset; +void (*sparc_supply_gregset) (const struct sparc_gregset *, + struct regcache *, int , const void *); +void (*sparc_collect_gregset) (const struct sparc_gregset *, + const struct regcache *, int, void *); +void (*sparc_supply_fpregset) (struct regcache *, int , const void *); +void (*sparc_collect_fpregset) (const struct regcache *, int , void *); +int (*sparc_gregset_supplies_p) (int); +int (*sparc_fpregset_supplies_p) (int); + +/* Determine whether `gregset_t' contains register REGNUM. */ + +int +sparc32_gregset_supplies_p (int regnum) +{ + /* Integer registers. */ + if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_G7_REGNUM) + || (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM) + || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_L7_REGNUM) + || (regnum >= SPARC_I0_REGNUM && regnum <= SPARC_I7_REGNUM)) + return 1; + + /* Control registers. */ + if (regnum == SPARC32_PC_REGNUM + || regnum == SPARC32_NPC_REGNUM + || regnum == SPARC32_PSR_REGNUM + || regnum == SPARC32_Y_REGNUM) + return 1; + + return 0; +} + +/* Determine whether `fpregset_t' contains register REGNUM. */ + +int +sparc32_fpregset_supplies_p (int regnum) +{ + /* Floating-point registers. */ + if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM) + return 1; + + /* Control registers. */ + if (regnum == SPARC32_FSR_REGNUM) + return 1; + + return 0; +} + +/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this + for all registers (including the floating-point registers). */ void -fetch_inferior_registers (int regno) +fetch_inferior_registers (int regnum) { - struct regs inferior_registers; - struct fp_status inferior_fp_registers; - int i; - int fetch_pid; + struct regcache *regcache = current_regcache; + int pid; /* NOTE: cagney/2002-12-03: This code assumes that the currently selected light weight processes' registers can be written @@ -76,309 +150,123 @@ fetch_inferior_registers (int regno) These functions should instead be paramaterized with an explicit object (struct regcache, struct thread_info?) into which the LWPs registers can be written. */ + pid = TIDGET (inferior_ptid); + if (pid == 0) + pid = PIDGET (inferior_ptid); - fetch_pid = TIDGET (inferior_ptid); - if (fetch_pid == 0) - fetch_pid = PIDGET (inferior_ptid); - - /* We should never be called with deferred stores, because a prerequisite - for writing regs is to have fetched them all (PREPARE_TO_STORE), sigh. */ - if (deferred_stores) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - - DO_DEFERRED_STORES; - - /* Global and Out regs are fetched directly, as well as the control - registers. If we're getting one of the in or local regs, - and the stack pointer has not yet been fetched, - we have to do that first, since they're found in memory relative - to the stack pointer. */ - if (regno < O7_REGNUM /* including -1 */ - || regno >= Y_REGNUM - || (!deprecated_register_valid[SP_REGNUM] && regno < I7_REGNUM)) + if (regnum == SPARC_G0_REGNUM) { - if (0 != ptrace (PTRACE_GETREGS, fetch_pid, - (PTRACE_ARG3_TYPE) & inferior_registers, 0)) - perror ("ptrace_getregs"); - - deprecated_registers[DEPRECATED_REGISTER_BYTE (0)] = 0; - memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (1)], - &inferior_registers.r_g1, 15 * DEPRECATED_REGISTER_RAW_SIZE (G0_REGNUM)); - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (PS_REGNUM)] - = inferior_registers.r_ps; - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (PC_REGNUM)] - = inferior_registers.r_pc; - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (DEPRECATED_NPC_REGNUM)] - = inferior_registers.r_npc; - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y; - - for (i = G0_REGNUM; i <= O7_REGNUM; i++) - deprecated_register_valid[i] = 1; - deprecated_register_valid[Y_REGNUM] = 1; - deprecated_register_valid[PS_REGNUM] = 1; - deprecated_register_valid[PC_REGNUM] = 1; - deprecated_register_valid[DEPRECATED_NPC_REGNUM] = 1; - /* If we don't set these valid, read_register_bytes() rereads - all the regs every time it is called! FIXME. */ - deprecated_register_valid[WIM_REGNUM] = 1; /* Not true yet, FIXME */ - deprecated_register_valid[TBR_REGNUM] = 1; /* Not true yet, FIXME */ - deprecated_register_valid[CPS_REGNUM] = 1; /* Not true yet, FIXME */ + regcache_raw_supply (regcache, SPARC_G0_REGNUM, NULL); + return; } - /* Floating point registers */ - if (regno == -1 || - regno == FPS_REGNUM || - (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31)) + if (regnum == -1 || sparc_gregset_supplies_p (regnum)) { - if (0 != ptrace (PTRACE_GETFPREGS, fetch_pid, - (PTRACE_ARG3_TYPE) & inferior_fp_registers, - 0)) - perror ("ptrace_getfpregs"); - memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], - &inferior_fp_registers, sizeof inferior_fp_registers.fpu_fr); - memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FPS_REGNUM)], - &inferior_fp_registers.Fpu_fsr, sizeof (FPU_FSR_TYPE)); - for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++) - deprecated_register_valid[i] = 1; - deprecated_register_valid[FPS_REGNUM] = 1; - } + gregset_t regs; - /* These regs are saved on the stack by the kernel. Only read them - all (16 ptrace calls!) if we really need them. */ - if (regno == -1) - { - CORE_ADDR sp = *(unsigned int *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (SP_REGNUM)]; - target_read_memory (sp, &deprecated_registers[DEPRECATED_REGISTER_BYTE (L0_REGNUM)], - 16 * DEPRECATED_REGISTER_RAW_SIZE (L0_REGNUM)); - for (i = L0_REGNUM; i <= I7_REGNUM; i++) - deprecated_register_valid[i] = 1; + if (ptrace (PTRACE_GETREGS, pid, (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't get registers"); + + sparc_supply_gregset (sparc_gregset, regcache, -1, ®s); + if (regnum != -1) + return; } - else if (regno >= L0_REGNUM && regno <= I7_REGNUM) + + if (regnum == -1 || sparc_fpregset_supplies_p (regnum)) { - CORE_ADDR sp = *(unsigned int *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (SP_REGNUM)]; - i = DEPRECATED_REGISTER_BYTE (regno); - if (deprecated_register_valid[regno]) - printf_unfiltered ("register %d valid and read\n", regno); - target_read_memory (sp + i - DEPRECATED_REGISTER_BYTE (L0_REGNUM), - &deprecated_registers[i], DEPRECATED_REGISTER_RAW_SIZE (regno)); - deprecated_register_valid[regno] = 1; + fpregset_t fpregs; + + if (ptrace (PTRACE_GETFPREGS, pid, (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't get floating point status"); + + sparc_supply_fpregset (regcache, -1, &fpregs); } } -/* Store our register values back into the inferior. - If REGNO is -1, do this for all registers. - Otherwise, REGNO specifies which register (so we can save time). */ - void -store_inferior_registers (int regno) +store_inferior_registers (int regnum) { - struct regs inferior_registers; - struct fp_status inferior_fp_registers; - int wanna_store = INT_REGS + STACK_REGS + FP_REGS; - int store_pid; + struct regcache *regcache = current_regcache; + int pid; /* NOTE: cagney/2002-12-02: See comment in fetch_inferior_registers about threaded assumptions. */ - store_pid = TIDGET (inferior_ptid); - if (store_pid == 0) - store_pid = PIDGET (inferior_ptid); + pid = TIDGET (inferior_ptid); + if (pid == 0) + pid = PIDGET (inferior_ptid); - /* First decide which pieces of machine-state we need to modify. - Default for regno == -1 case is all pieces. */ - if (regno >= 0) + if (regnum == -1 || sparc_gregset_supplies_p (regnum)) { - if (FP0_REGNUM <= regno && regno < FP0_REGNUM + 32) - { - wanna_store = FP_REGS; - } - else - { - if (regno == SP_REGNUM) - wanna_store = INT_REGS + STACK_REGS; - else if (regno < L0_REGNUM || regno > I7_REGNUM) - wanna_store = INT_REGS; - else if (regno == FPS_REGNUM) - wanna_store = FP_REGS; - else - wanna_store = STACK_REGS; - } - } + gregset_t regs; - /* See if we're forcing the stores to happen now, or deferring. */ - if (regno == -2) - { - wanna_store = deferred_stores; - deferred_stores = 0; - } - else - { - if (wanna_store == STACK_REGS) - { - /* Fall through and just store one stack reg. If we deferred - it, we'd have to store them all, or remember more info. */ - } - else - { - deferred_stores |= wanna_store; - return; - } - } + if (ptrace (PTRACE_GETREGS, pid, (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't get registers"); - if (wanna_store & STACK_REGS) - { - CORE_ADDR sp = *(unsigned int *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (SP_REGNUM)]; + sparc_collect_gregset (sparc_gregset, regcache, regnum, ®s); - if (regno < 0 || regno == SP_REGNUM) - { - if (!deprecated_register_valid[L0_REGNUM + 5]) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - target_write_memory (sp, - &deprecated_registers[DEPRECATED_REGISTER_BYTE (L0_REGNUM)], - 16 * DEPRECATED_REGISTER_RAW_SIZE (L0_REGNUM)); - } - else - { - if (!deprecated_register_valid[regno]) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - target_write_memory (sp + DEPRECATED_REGISTER_BYTE (regno) - DEPRECATED_REGISTER_BYTE (L0_REGNUM), - &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)], - DEPRECATED_REGISTER_RAW_SIZE (regno)); - } + if (ptrace (PTRACE_SETREGS, pid, (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't write registers"); - } + /* Deal with the stack regs. */ + if (regnum == -1 || regnum == SPARC_SP_REGNUM + || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM)) + { + ULONGEST sp; - if (wanna_store & INT_REGS) - { - if (!deprecated_register_valid[G1_REGNUM]) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - - memcpy (&inferior_registers.r_g1, - &deprecated_registers[DEPRECATED_REGISTER_BYTE (G1_REGNUM)], - 15 * DEPRECATED_REGISTER_RAW_SIZE (G1_REGNUM)); - - inferior_registers.r_ps = - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (PS_REGNUM)]; - inferior_registers.r_pc = - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (PC_REGNUM)]; - inferior_registers.r_npc = - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (DEPRECATED_NPC_REGNUM)]; - inferior_registers.r_y = - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (Y_REGNUM)]; - - if (0 != ptrace (PTRACE_SETREGS, store_pid, - (PTRACE_ARG3_TYPE) & inferior_registers, 0)) - perror ("ptrace_setregs"); - } + regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp); + sparc_collect_rwindow (regcache, sp, regnum); + } - if (wanna_store & FP_REGS) - { - if (!deprecated_register_valid[FP0_REGNUM + 9]) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - memcpy (&inferior_fp_registers, - &deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], - sizeof inferior_fp_registers.fpu_fr); - memcpy (&inferior_fp_registers.Fpu_fsr, - &deprecated_registers[DEPRECATED_REGISTER_BYTE (FPS_REGNUM)], - sizeof (FPU_FSR_TYPE)); - if (0 != - ptrace (PTRACE_SETFPREGS, store_pid, - (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0)) - perror ("ptrace_setfpregs"); + if (regnum != -1) + return; } -} - -/* Provide registers to GDB from a core file. - - CORE_REG_SECT points to an array of bytes, which are the contents - of a `note' from a core file which BFD thinks might contain - register contents. CORE_REG_SIZE is its size. - - WHICH says which register set corelow suspects this is: - 0 --- the general-purpose register set - 2 --- the floating-point register set - - IGNORE is unused. */ - -static void -fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, - int which, CORE_ADDR ignore) -{ - if (which == 0) + if (regnum == -1 || sparc_fpregset_supplies_p (regnum)) { + fpregset_t fpregs, saved_fpregs; - /* Integer registers */ - -#define gregs ((struct regs *)core_reg_sect) - /* G0 *always* holds 0. */ - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (0)] = 0; - - /* The globals and output registers. */ - memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (G1_REGNUM)], &gregs->r_g1, - 15 * DEPRECATED_REGISTER_RAW_SIZE (G1_REGNUM)); - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (PS_REGNUM)] = gregs->r_ps; - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (PC_REGNUM)] = gregs->r_pc; - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (DEPRECATED_NPC_REGNUM)] = gregs->r_npc; - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (Y_REGNUM)] = gregs->r_y; - - /* My best guess at where to get the locals and input - registers is exactly where they usually are, right above - the stack pointer. If the core dump was caused by a bus error - from blowing away the stack pointer (as is possible) then this - won't work, but it's worth the try. */ - { - int sp; - - sp = *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (SP_REGNUM)]; - if (0 != target_read_memory (sp, - &deprecated_registers[DEPRECATED_REGISTER_BYTE (L0_REGNUM)], - 16 * DEPRECATED_REGISTER_RAW_SIZE (L0_REGNUM))) - { - /* fprintf_unfiltered so user can still use gdb */ - fprintf_unfiltered (gdb_stderr, - "Couldn't read input and local registers from core file\n"); - } - } - } - else if (which == 2) - { + if (ptrace (PTRACE_GETFPREGS, pid, (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't get floating-point registers"); - /* Floating point registers */ + memcpy (&saved_fpregs, &fpregs, sizeof (fpregs)); + sparc_collect_fpregset (regcache, regnum, &fpregs); -#define fpuregs ((struct fpu *) core_reg_sect) - if (core_reg_size >= sizeof (struct fpu)) + /* Writing the floating-point registers will fail on NetBSD with + EINVAL if the inferior process doesn't have an FPU state + (i.e. if it didn't use the FPU yet). Therefore we don't try + to write the registers if nothing changed. */ + if (memcmp (&saved_fpregs, &fpregs, sizeof (fpregs)) != 0) { - memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], - fpuregs->fpu_regs, sizeof (fpuregs->fpu_regs)); - memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FPS_REGNUM)], - &fpuregs->fpu_fsr, sizeof (FPU_FSR_TYPE)); + if (ptrace (PTRACE_SETFPREGS, pid, + (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't write floating-point registers"); } - else - fprintf_unfiltered (gdb_stderr, "Couldn't read float regs from core file\n"); - } -} -int -kernel_u_size (void) -{ - return (sizeof (struct user)); + if (regnum != -1) + return; + } } -/* Register that we are able to handle sparc core file formats. - FIXME: is this really bfd_target_unknown_flavour? */ - -static struct core_fns sparc_core_fns = -{ - bfd_target_unknown_flavour, /* core_flavour */ - default_check_format, /* check_format */ - default_core_sniffer, /* core_sniffer */ - fetch_core_registers, /* core_read_registers */ - NULL /* next */ -}; +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_sparc_nat (void); void -_initialize_core_sparc (void) +_initialize_sparc_nat (void) { - add_core_fns (&sparc_core_fns); + /* Deafult to using SunOS 4 register sets. */ + if (sparc_gregset == NULL) + sparc_gregset = &sparc32_sunos4_gregset; + if (sparc_supply_gregset == NULL) + sparc_supply_gregset = sparc32_supply_gregset; + if (sparc_collect_gregset == NULL) + sparc_collect_gregset = sparc32_collect_gregset; + if (sparc_supply_fpregset == NULL) + sparc_supply_fpregset = sparc32_supply_fpregset; + if (sparc_collect_fpregset == NULL) + sparc_collect_fpregset = sparc32_collect_fpregset; + if (sparc_gregset_supplies_p == NULL) + sparc_gregset_supplies_p = sparc32_gregset_supplies_p; + if (sparc_fpregset_supplies_p == NULL) + sparc_fpregset_supplies_p = sparc32_fpregset_supplies_p; } |