GDB (API)
|
00001 /* Native-dependent code for Unix SVR4 running on i386's. 00002 00003 Copyright (C) 1988-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #include "defs.h" 00021 #include "value.h" 00022 #include "inferior.h" 00023 #include "regcache.h" 00024 00025 #ifdef HAVE_SYS_REG_H 00026 #include <sys/reg.h> 00027 #endif 00028 00029 #include "i386-tdep.h" 00030 #include "i387-tdep.h" 00031 00032 #ifdef HAVE_SYS_PROCFS_H 00033 00034 #include <sys/procfs.h> 00035 00036 /* We must not compile this code for 64-bit Solaris x86. */ 00037 #if !defined (PR_MODEL_NATIVE) || (PR_MODEL_NATIVE == PR_MODEL_ILP32) 00038 00039 #include "gregset.h" 00040 00041 /* The `/proc' interface divides the target machine's register set up 00042 into two different sets, the general purpose register set (gregset) 00043 and the floating-point register set (fpregset). For each set, 00044 there is an ioctl to get the current register set and another ioctl 00045 to set the current values. 00046 00047 The actual structure passed through the ioctl interface is, of 00048 course, naturally machine dependent, and is different for each set 00049 of registers. For the i386 for example, the general-purpose 00050 register set is typically defined by: 00051 00052 typedef int gregset_t[19]; (in <sys/regset.h>) 00053 00054 #define GS 0 (in <sys/reg.h>) 00055 #define FS 1 00056 ... 00057 #define UESP 17 00058 #define SS 18 00059 00060 and the floating-point set by: 00061 00062 typedef struct fpregset { 00063 union { 00064 struct fpchip_state // fp extension state // 00065 { 00066 int state[27]; // 287/387 saved state // 00067 int status; // status word saved at // 00068 // exception // 00069 } fpchip_state; 00070 struct fp_emul_space // for emulators // 00071 { 00072 char fp_emul[246]; 00073 char fp_epad[2]; 00074 } fp_emul_space; 00075 int f_fpregs[62]; // union of the above // 00076 } fp_reg_set; 00077 long f_wregs[33]; // saved weitek state // 00078 } fpregset_t; 00079 00080 Incidentally fpchip_state contains the FPU state in the same format 00081 as used by the "fsave" instruction, and that's the only thing we 00082 support here. I don't know how the emulator stores it state. The 00083 Weitek stuff definitely isn't supported. 00084 00085 The routines defined here, provide the packing and unpacking of 00086 gregset_t and fpregset_t formatted data. */ 00087 00088 #ifdef HAVE_GREGSET_T 00089 00090 /* Mapping between the general-purpose registers in `/proc' 00091 format and GDB's register array layout. */ 00092 static int regmap[] = 00093 { 00094 EAX, ECX, EDX, EBX, 00095 UESP, EBP, ESI, EDI, 00096 EIP, EFL, CS, SS, 00097 DS, ES, FS, GS 00098 }; 00099 00100 /* Fill GDB's register array with the general-purpose register values 00101 in *GREGSETP. */ 00102 00103 void 00104 supply_gregset (struct regcache *regcache, const gregset_t *gregsetp) 00105 { 00106 const greg_t *regp = (const greg_t *) gregsetp; 00107 int regnum; 00108 00109 for (regnum = 0; regnum < I386_NUM_GREGS; regnum++) 00110 regcache_raw_supply (regcache, regnum, regp + regmap[regnum]); 00111 } 00112 00113 /* Fill register REGNUM (if it is a general-purpose register) in 00114 *GREGSETPS with the value in GDB's register array. If REGNUM is -1, 00115 do this for all registers. */ 00116 00117 void 00118 fill_gregset (const struct regcache *regcache, 00119 gregset_t *gregsetp, int regnum) 00120 { 00121 greg_t *regp = (greg_t *) gregsetp; 00122 int i; 00123 00124 for (i = 0; i < I386_NUM_GREGS; i++) 00125 if (regnum == -1 || regnum == i) 00126 regcache_raw_collect (regcache, i, regp + regmap[i]); 00127 } 00128 00129 #endif /* HAVE_GREGSET_T */ 00130 00131 #ifdef HAVE_FPREGSET_T 00132 00133 /* Fill GDB's register array with the floating-point register values in 00134 *FPREGSETP. */ 00135 00136 void 00137 supply_fpregset (struct regcache *regcache, const fpregset_t *fpregsetp) 00138 { 00139 if (gdbarch_fp0_regnum (get_regcache_arch (regcache)) == 0) 00140 return; 00141 00142 i387_supply_fsave (regcache, -1, fpregsetp); 00143 } 00144 00145 /* Fill register REGNO (if it is a floating-point register) in 00146 *FPREGSETP with the value in GDB's register array. If REGNO is -1, 00147 do this for all registers. */ 00148 00149 void 00150 fill_fpregset (const struct regcache *regcache, 00151 fpregset_t *fpregsetp, int regno) 00152 { 00153 if (gdbarch_fp0_regnum (get_regcache_arch (regcache)) == 0) 00154 return; 00155 00156 i387_collect_fsave (regcache, regno, fpregsetp); 00157 } 00158 00159 #endif /* HAVE_FPREGSET_T */ 00160 00161 #endif /* not 64-bit. */ 00162 00163 #endif /* HAVE_SYS_PROCFS_H */