1130803Smarcel/* Host-dependent code for Sun-3 for GDB, the GNU debugger. 2130803Smarcel Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1996, 1999, 2000, 2001 3130803Smarcel Free Software Foundation, Inc. 4130803Smarcel 5130803Smarcel This file is part of GDB. 6130803Smarcel 7130803Smarcel This program is free software; you can redistribute it and/or modify 8130803Smarcel it under the terms of the GNU General Public License as published by 9130803Smarcel the Free Software Foundation; either version 2 of the License, or 10130803Smarcel (at your option) any later version. 11130803Smarcel 12130803Smarcel This program is distributed in the hope that it will be useful, 13130803Smarcel but WITHOUT ANY WARRANTY; without even the implied warranty of 14130803Smarcel MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15130803Smarcel GNU General Public License for more details. 16130803Smarcel 17130803Smarcel You should have received a copy of the GNU General Public License 18130803Smarcel along with this program; if not, write to the Free Software 19130803Smarcel Foundation, Inc., 59 Temple Place - Suite 330, 20130803Smarcel Boston, MA 02111-1307, USA. */ 21130803Smarcel 22130803Smarcel#include "defs.h" 23130803Smarcel#include "inferior.h" 24130803Smarcel#include "gdbcore.h" 25130803Smarcel#include "regcache.h" 26130803Smarcel 27130803Smarcel#include <sys/ptrace.h> 28130803Smarcel#define KERNEL /* To get floating point reg definitions */ 29130803Smarcel#include <machine/reg.h> 30130803Smarcel 31130803Smarcelstatic void fetch_core_registers (char *, unsigned, int, CORE_ADDR); 32130803Smarcel 33130803Smarcelvoid 34130803Smarcelfetch_inferior_registers (int regno) 35130803Smarcel{ 36130803Smarcel struct regs inferior_registers; 37130803Smarcel struct fp_status inferior_fp_registers; 38130803Smarcel 39130803Smarcel deprecated_registers_fetched (); 40130803Smarcel 41130803Smarcel ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid), 42130803Smarcel (PTRACE_ARG3_TYPE) & inferior_registers); 43130803Smarcel 44130803Smarcel if (FP0_REGNUM >= 0) 45130803Smarcel ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid), 46130803Smarcel (PTRACE_ARG3_TYPE) & inferior_fp_registers); 47130803Smarcel 48130803Smarcel memcpy (deprecated_registers, &inferior_registers, 16 * 4); 49130803Smarcel if (FP0_REGNUM >= 0) 50130803Smarcel memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], 51130803Smarcel &inferior_fp_registers, sizeof inferior_fp_registers.fps_regs); 52130803Smarcel 53130803Smarcel *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps; 54130803Smarcel *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc; 55130803Smarcel if (FP0_REGNUM >= 0) 56130803Smarcel memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FPC_REGNUM)], 57130803Smarcel &inferior_fp_registers.fps_control, 58130803Smarcel sizeof inferior_fp_registers - 59130803Smarcel sizeof inferior_fp_registers.fps_regs); 60130803Smarcel} 61130803Smarcel 62130803Smarcel/* Store our register values back into the inferior. 63130803Smarcel If REGNO is -1, do this for all registers. 64130803Smarcel Otherwise, REGNO specifies which register (so we can save time). */ 65130803Smarcel 66130803Smarcelvoid 67130803Smarcelstore_inferior_registers (int regno) 68130803Smarcel{ 69130803Smarcel struct regs inferior_registers; 70130803Smarcel struct fp_status inferior_fp_registers; 71130803Smarcel 72130803Smarcel memcpy (&inferior_registers, deprecated_registers, 16 * 4); 73130803Smarcel if (FP0_REGNUM >= 0) 74130803Smarcel memcpy (&inferior_fp_registers, 75130803Smarcel &deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], 76130803Smarcel sizeof inferior_fp_registers.fps_regs); 77130803Smarcel 78130803Smarcel inferior_registers.r_ps = *(int *) &&deprecated_registers[DEPRECATED_REGISTER_BYTE (PS_REGNUM)]; 79130803Smarcel inferior_registers.r_pc = *(int *) &&deprecated_registers[DEPRECATED_REGISTER_BYTE (PC_REGNUM)]; 80130803Smarcel 81130803Smarcel if (FP0_REGNUM >= 0) 82130803Smarcel memcpy (&inferior_fp_registers.fps_control, 83130803Smarcel &&deprecated_registers[DEPRECATED_REGISTER_BYTE (FPC_REGNUM)], 84130803Smarcel sizeof inferior_fp_registers - 85130803Smarcel sizeof inferior_fp_registers.fps_regs); 86130803Smarcel 87130803Smarcel ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid), 88130803Smarcel (PTRACE_ARG3_TYPE) & inferior_registers); 89130803Smarcel if (FP0_REGNUM >= 0) 90130803Smarcel ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid), 91130803Smarcel (PTRACE_ARG3_TYPE) & inferior_fp_registers); 92130803Smarcel} 93130803Smarcel 94130803Smarcel 95130803Smarcel/* All of this stuff is only relevant if both host and target are sun3. */ 96130803Smarcel 97130803Smarcel/* Provide registers to GDB from a core file. 98130803Smarcel 99130803Smarcel CORE_REG_SECT points to an array of bytes, which were obtained from 100130803Smarcel a core file which BFD thinks might contain register contents. 101130803Smarcel CORE_REG_SIZE is its size. 102130803Smarcel 103130803Smarcel WHICH says which register set corelow suspects this is: 104130803Smarcel 0 --- the general-purpose register set 105130803Smarcel 2 --- the floating-point register set 106130803Smarcel 107130803Smarcel REG_ADDR isn't used. */ 108130803Smarcel 109130803Smarcelstatic void 110130803Smarcelfetch_core_registers (char *core_reg_sect, unsigned core_reg_size, 111130803Smarcel int which, CORE_ADDR reg_addr) 112130803Smarcel{ 113130803Smarcel struct regs *regs = (struct regs *) core_reg_sect; 114130803Smarcel 115130803Smarcel if (which == 0) 116130803Smarcel { 117130803Smarcel if (core_reg_size < sizeof (struct regs)) 118130803Smarcel error ("Can't find registers in core file"); 119130803Smarcel 120130803Smarcel memcpy (&deprecated_registers, (char *) regs, 16 * 4); 121130803Smarcel supply_register (PS_REGNUM, (char *) ®s->r_ps); 122130803Smarcel supply_register (PC_REGNUM, (char *) ®s->r_pc); 123130803Smarcel 124130803Smarcel } 125130803Smarcel else if (which == 2) 126130803Smarcel { 127130803Smarcel 128130803Smarcel#define fpustruct ((struct fpu *) core_reg_sect) 129130803Smarcel 130130803Smarcel if (core_reg_size >= sizeof (struct fpu)) 131130803Smarcel { 132130803Smarcel if (FP0_REGNUM >= 0) 133130803Smarcel { 134130803Smarcel memcpy (&&deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], 135130803Smarcel fpustruct->f_fpstatus.fps_regs, 136130803Smarcel sizeof fpustruct->f_fpstatus.fps_regs); 137130803Smarcel memcpy (&&deprecated_registers[DEPRECATED_REGISTER_BYTE (FPC_REGNUM)], 138130803Smarcel &fpustruct->f_fpstatus.fps_control, 139130803Smarcel sizeof fpustruct->f_fpstatus - 140130803Smarcel sizeof fpustruct->f_fpstatus.fps_regs); 141130803Smarcel } 142130803Smarcel } 143130803Smarcel else 144130803Smarcel fprintf_unfiltered (gdb_stderr, 145130803Smarcel "Couldn't read float regs from core file\n"); 146130803Smarcel } 147130803Smarcel} 148130803Smarcel 149130803Smarcel 150130803Smarcel/* Register that we are able to handle sun3 core file formats. 151130803Smarcel FIXME: is this really bfd_target_unknown_flavour? */ 152130803Smarcel 153130803Smarcelstatic struct core_fns sun3_core_fns = 154130803Smarcel{ 155130803Smarcel bfd_target_unknown_flavour, /* core_flavour */ 156130803Smarcel default_check_format, /* check_format */ 157130803Smarcel default_core_sniffer, /* core_sniffer */ 158130803Smarcel fetch_core_registers, /* core_read_registers */ 159130803Smarcel NULL /* next */ 160130803Smarcel}; 161130803Smarcel 162130803Smarcelvoid 163130803Smarcel_initialize_core_sun3 (void) 164130803Smarcel{ 165130803Smarcel add_core_fns (&sun3_core_fns); 166130803Smarcel} 167