1/* Host-dependent code for Sun-3 for GDB, the GNU debugger. 2 Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1996, 1999, 2000, 2001 3 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 59 Temple Place - Suite 330, 20 Boston, MA 02111-1307, USA. */ 21 22#include "defs.h" 23#include "inferior.h" 24#include "gdbcore.h" 25#include "regcache.h" 26 27#include <sys/ptrace.h> 28#define KERNEL /* To get floating point reg definitions */ 29#include <machine/reg.h> 30 31static void fetch_core_registers (char *, unsigned, int, CORE_ADDR); 32 33void 34fetch_inferior_registers (int regno) 35{ 36 struct regs inferior_registers; 37 struct fp_status inferior_fp_registers; 38 39 deprecated_registers_fetched (); 40 41 ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid), 42 (PTRACE_ARG3_TYPE) & inferior_registers); 43 44 if (FP0_REGNUM >= 0) 45 ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid), 46 (PTRACE_ARG3_TYPE) & inferior_fp_registers); 47 48 memcpy (deprecated_registers, &inferior_registers, 16 * 4); 49 if (FP0_REGNUM >= 0) 50 memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], 51 &inferior_fp_registers, sizeof inferior_fp_registers.fps_regs); 52 53 *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps; 54 *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc; 55 if (FP0_REGNUM >= 0) 56 memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FPC_REGNUM)], 57 &inferior_fp_registers.fps_control, 58 sizeof inferior_fp_registers - 59 sizeof inferior_fp_registers.fps_regs); 60} 61 62/* Store our register values back into the inferior. 63 If REGNO is -1, do this for all registers. 64 Otherwise, REGNO specifies which register (so we can save time). */ 65 66void 67store_inferior_registers (int regno) 68{ 69 struct regs inferior_registers; 70 struct fp_status inferior_fp_registers; 71 72 memcpy (&inferior_registers, deprecated_registers, 16 * 4); 73 if (FP0_REGNUM >= 0) 74 memcpy (&inferior_fp_registers, 75 &deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], 76 sizeof inferior_fp_registers.fps_regs); 77 78 inferior_registers.r_ps = *(int *) &&deprecated_registers[DEPRECATED_REGISTER_BYTE (PS_REGNUM)]; 79 inferior_registers.r_pc = *(int *) &&deprecated_registers[DEPRECATED_REGISTER_BYTE (PC_REGNUM)]; 80 81 if (FP0_REGNUM >= 0) 82 memcpy (&inferior_fp_registers.fps_control, 83 &&deprecated_registers[DEPRECATED_REGISTER_BYTE (FPC_REGNUM)], 84 sizeof inferior_fp_registers - 85 sizeof inferior_fp_registers.fps_regs); 86 87 ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid), 88 (PTRACE_ARG3_TYPE) & inferior_registers); 89 if (FP0_REGNUM >= 0) 90 ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid), 91 (PTRACE_ARG3_TYPE) & inferior_fp_registers); 92} 93 94 95/* All of this stuff is only relevant if both host and target are sun3. */ 96 97/* Provide registers to GDB from a core file. 98 99 CORE_REG_SECT points to an array of bytes, which were obtained from 100 a core file which BFD thinks might contain register contents. 101 CORE_REG_SIZE is its size. 102 103 WHICH says which register set corelow suspects this is: 104 0 --- the general-purpose register set 105 2 --- the floating-point register set 106 107 REG_ADDR isn't used. */ 108 109static void 110fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, 111 int which, CORE_ADDR reg_addr) 112{ 113 struct regs *regs = (struct regs *) core_reg_sect; 114 115 if (which == 0) 116 { 117 if (core_reg_size < sizeof (struct regs)) 118 error ("Can't find registers in core file"); 119 120 memcpy (&deprecated_registers, (char *) regs, 16 * 4); 121 supply_register (PS_REGNUM, (char *) ®s->r_ps); 122 supply_register (PC_REGNUM, (char *) ®s->r_pc); 123 124 } 125 else if (which == 2) 126 { 127 128#define fpustruct ((struct fpu *) core_reg_sect) 129 130 if (core_reg_size >= sizeof (struct fpu)) 131 { 132 if (FP0_REGNUM >= 0) 133 { 134 memcpy (&&deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], 135 fpustruct->f_fpstatus.fps_regs, 136 sizeof fpustruct->f_fpstatus.fps_regs); 137 memcpy (&&deprecated_registers[DEPRECATED_REGISTER_BYTE (FPC_REGNUM)], 138 &fpustruct->f_fpstatus.fps_control, 139 sizeof fpustruct->f_fpstatus - 140 sizeof fpustruct->f_fpstatus.fps_regs); 141 } 142 } 143 else 144 fprintf_unfiltered (gdb_stderr, 145 "Couldn't read float regs from core file\n"); 146 } 147} 148 149 150/* Register that we are able to handle sun3 core file formats. 151 FIXME: is this really bfd_target_unknown_flavour? */ 152 153static struct core_fns sun3_core_fns = 154{ 155 bfd_target_unknown_flavour, /* core_flavour */ 156 default_check_format, /* check_format */ 157 default_core_sniffer, /* core_sniffer */ 158 fetch_core_registers, /* core_read_registers */ 159 NULL /* next */ 160}; 161 162void 163_initialize_core_sun3 (void) 164{ 165 add_core_fns (&sun3_core_fns); 166} 167