GDB (API)
/home/stan/gdb/src/gdb/i386v4-nat.c
Go to the documentation of this file.
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 */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines