1130812Smarcel/* Native-dependent code for SVR4 Unix running on i386's. 2130812Smarcel Copyright 1988, 1989, 1991, 1992, 1996, 1997, 1998, 1999, 2000, 3130812Smarcel 2001, 2002 4130812Smarcel Free Software Foundation, Inc. 5130812Smarcel 6130812Smarcel This file is part of GDB. 7130812Smarcel 8130812Smarcel This program is free software; you can redistribute it and/or modify 9130812Smarcel it under the terms of the GNU General Public License as published by 10130812Smarcel the Free Software Foundation; either version 2 of the License, or 11130812Smarcel (at your option) any later version. 12130812Smarcel 13130812Smarcel This program is distributed in the hope that it will be useful, 14130812Smarcel but WITHOUT ANY WARRANTY; without even the implied warranty of 15130812Smarcel MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16130812Smarcel GNU General Public License for more details. 17130812Smarcel 18130812Smarcel You should have received a copy of the GNU General Public License 19130812Smarcel along with this program; if not, write to the Free Software 20130812Smarcel Foundation, Inc., 59 Temple Place - Suite 330, 21130812Smarcel Boston, MA 02111-1307, USA. */ 22130812Smarcel 23130812Smarcel#include "defs.h" 24130812Smarcel#include "value.h" 25130812Smarcel#include "inferior.h" 26130812Smarcel#include "regcache.h" 27130812Smarcel 28130812Smarcel#ifdef HAVE_SYS_REG_H 29130812Smarcel#include <sys/reg.h> 30130812Smarcel#endif 31130812Smarcel 32130812Smarcel#include "i386-tdep.h" 33130812Smarcel#include "i387-tdep.h" 34130812Smarcel 35130812Smarcel#ifdef HAVE_SYS_PROCFS_H 36130812Smarcel 37130812Smarcel#include <sys/procfs.h> 38130812Smarcel 39130812Smarcel/* Prototypes for supply_gregset etc. */ 40130812Smarcel#include "gregset.h" 41130812Smarcel 42130812Smarcel/* The `/proc' interface divides the target machine's register set up 43130812Smarcel into two different sets, the general purpose register set (gregset) 44130812Smarcel and the floating-point register set (fpregset). For each set, 45130812Smarcel there is an ioctl to get the current register set and another ioctl 46130812Smarcel to set the current values. 47130812Smarcel 48130812Smarcel The actual structure passed through the ioctl interface is, of 49130812Smarcel course, naturally machine dependent, and is different for each set 50130812Smarcel of registers. For the i386 for example, the general-purpose 51130812Smarcel register set is typically defined by: 52130812Smarcel 53130812Smarcel typedef int gregset_t[19]; (in <sys/regset.h>) 54130812Smarcel 55130812Smarcel #define GS 0 (in <sys/reg.h>) 56130812Smarcel #define FS 1 57130812Smarcel ... 58130812Smarcel #define UESP 17 59130812Smarcel #define SS 18 60130812Smarcel 61130812Smarcel and the floating-point set by: 62130812Smarcel 63130812Smarcel typedef struct fpregset { 64130812Smarcel union { 65130812Smarcel struct fpchip_state // fp extension state // 66130812Smarcel { 67130812Smarcel int state[27]; // 287/387 saved state // 68130812Smarcel int status; // status word saved at // 69130812Smarcel // exception // 70130812Smarcel } fpchip_state; 71130812Smarcel struct fp_emul_space // for emulators // 72130812Smarcel { 73130812Smarcel char fp_emul[246]; 74130812Smarcel char fp_epad[2]; 75130812Smarcel } fp_emul_space; 76130812Smarcel int f_fpregs[62]; // union of the above // 77130812Smarcel } fp_reg_set; 78130812Smarcel long f_wregs[33]; // saved weitek state // 79130812Smarcel } fpregset_t; 80130812Smarcel 81130812Smarcel Incidentally fpchip_state contains the FPU state in the same format 82130812Smarcel as used by the "fsave" instruction, and that's the only thing we 83130812Smarcel support here. I don't know how the emulator stores it state. The 84130812Smarcel Weitek stuff definitely isn't supported. 85130812Smarcel 86130812Smarcel The routines defined here, provide the packing and unpacking of 87130812Smarcel gregset_t and fpregset_t formatted data. */ 88130812Smarcel 89130812Smarcel#ifdef HAVE_GREGSET_T 90130812Smarcel 91130812Smarcel/* Mapping between the general-purpose registers in `/proc' 92130812Smarcel format and GDB's register array layout. */ 93130812Smarcelstatic int regmap[] = 94130812Smarcel{ 95130812Smarcel EAX, ECX, EDX, EBX, 96130812Smarcel UESP, EBP, ESI, EDI, 97130812Smarcel EIP, EFL, CS, SS, 98130812Smarcel DS, ES, FS, GS, 99130812Smarcel}; 100130812Smarcel 101130812Smarcel/* Fill GDB's register array with the general-purpose register values 102130812Smarcel in *GREGSETP. */ 103130812Smarcel 104130812Smarcelvoid 105130812Smarcelsupply_gregset (gregset_t *gregsetp) 106130812Smarcel{ 107130812Smarcel greg_t *regp = (greg_t *) gregsetp; 108130812Smarcel int i; 109130812Smarcel 110130812Smarcel for (i = 0; i < I386_NUM_GREGS; i++) 111130812Smarcel supply_register (i, (char *) (regp + regmap[i])); 112130812Smarcel} 113130812Smarcel 114130812Smarcel/* Fill register REGNO (if it is a general-purpose register) in 115130812Smarcel *GREGSETPS with the value in GDB's register array. If REGNO is -1, 116130812Smarcel do this for all registers. */ 117130812Smarcel 118130812Smarcelvoid 119130812Smarcelfill_gregset (gregset_t *gregsetp, int regno) 120130812Smarcel{ 121130812Smarcel greg_t *regp = (greg_t *) gregsetp; 122130812Smarcel int i; 123130812Smarcel 124130812Smarcel for (i = 0; i < I386_NUM_GREGS; i++) 125130812Smarcel if (regno == -1 || regno == i) 126130812Smarcel regcache_collect (i, regp + regmap[i]); 127130812Smarcel} 128130812Smarcel 129130812Smarcel#endif /* HAVE_GREGSET_T */ 130130812Smarcel 131130812Smarcel#ifdef HAVE_FPREGSET_T 132130812Smarcel 133130812Smarcel/* Fill GDB's register array with the floating-point register values in 134130812Smarcel *FPREGSETP. */ 135130812Smarcel 136130812Smarcelvoid 137130812Smarcelsupply_fpregset (fpregset_t *fpregsetp) 138130812Smarcel{ 139130812Smarcel if (FP0_REGNUM == 0) 140130812Smarcel return; 141130812Smarcel 142130812Smarcel i387_supply_fsave (current_regcache, -1, fpregsetp); 143130812Smarcel} 144130812Smarcel 145130812Smarcel/* Fill register REGNO (if it is a floating-point register) in 146130812Smarcel *FPREGSETP with the value in GDB's register array. If REGNO is -1, 147130812Smarcel do this for all registers. */ 148130812Smarcel 149130812Smarcelvoid 150130812Smarcelfill_fpregset (fpregset_t *fpregsetp, int regno) 151130812Smarcel{ 152130812Smarcel if (FP0_REGNUM == 0) 153130812Smarcel return; 154130812Smarcel 155130812Smarcel i387_fill_fsave ((char *) fpregsetp, regno); 156130812Smarcel} 157130812Smarcel 158130812Smarcel#endif /* HAVE_FPREGSET_T */ 159130812Smarcel 160130812Smarcel#endif /* HAVE_SYS_PROCFS_H */ 161