OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [i386v4-nat.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* Native-dependent code for SVR4 Unix running on i386's, for GDB.
2
   Copyright 1988, 1989, 1991, 1992, 1996, 1997, 1998, 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 "value.h"
24
#include "inferior.h"
25
#include "regcache.h"
26
 
27
#ifdef HAVE_SYS_REG_H
28
#include <sys/reg.h>
29
#endif
30
 
31
 
32
#ifdef HAVE_SYS_PROCFS_H
33
 
34
#include <sys/procfs.h>
35
 
36
/* Prototypes for supply_gregset etc. */
37
#include "gregset.h"
38
 
39
/*  The /proc interface divides the target machine's register set up into
40
   two different sets, the general register set (gregset) and the floating
41
   point register set (fpregset).  For each set, there is an ioctl to get
42
   the current register set and another ioctl to set the current values.
43
 
44
   The actual structure passed through the ioctl interface is, of course,
45
   naturally machine dependent, and is different for each set of registers.
46
   For the i386 for example, the general register set is typically defined
47
   by:
48
 
49
   typedef int gregset_t[19];           (in <sys/regset.h>)
50
 
51
   #define GS   0                       (in <sys/reg.h>)
52
   #define FS   1
53
   ...
54
   #define UESP 17
55
   #define SS   18
56
 
57
   and the floating point set by:
58
 
59
   typedef struct fpregset
60
   {
61
   union
62
   {
63
   struct fpchip_state  // fp extension state //
64
   {
65
   int state[27];       // 287/387 saved state //
66
   int status;          // status word saved at exception //
67
   } fpchip_state;
68
   struct fp_emul_space // for emulators //
69
   {
70
   char fp_emul[246];
71
   char fp_epad[2];
72
   } fp_emul_space;
73
   int f_fpregs[62];    // union of the above //
74
   } fp_reg_set;
75
   long f_wregs[33];            // saved weitek state //
76
   } fpregset_t;
77
 
78
   These routines provide the packing and unpacking of gregset_t and
79
   fpregset_t formatted data.
80
 
81
 */
82
 
83
#ifdef HAVE_GREGSET_T
84
 
85
/* This is a duplicate of the table in i386-xdep.c. */
86
 
87
static int regmap[] =
88
{
89
  EAX, ECX, EDX, EBX,
90
  UESP, EBP, ESI, EDI,
91
  EIP, EFL, CS, SS,
92
  DS, ES, FS, GS,
93
};
94
 
95
/* Prototypes for local functions */
96
 
97
void fill_gregset (gregset_t *, int);
98
 
99
void supply_gregset (gregset_t *);
100
 
101
void supply_fpregset (fpregset_t *);
102
 
103
void fill_fpregset (fpregset_t *, int);
104
 
105
 
106
/*  FIXME:  These routine absolutely depends upon (NUM_REGS - NUM_FREGS)
107
   being less than or equal to the number of registers that can be stored
108
   in a gregset_t.  Note that with the current scheme there will typically
109
   be more registers actually stored in a gregset_t that what we know
110
   about.  This is bogus and should be fixed. */
111
 
112
/*  Given a pointer to a general register set in /proc format (gregset_t *),
113
   unpack the register contents and supply them as gdb's idea of the current
114
   register values. */
115
 
116
void
117
supply_gregset (gregset_t *gregsetp)
118
{
119
  register int regi;
120
  register greg_t *regp = (greg_t *) gregsetp;
121
  extern int regmap[];
122
 
123
  for (regi = 0; regi < (NUM_REGS - NUM_FREGS); regi++)
124
    {
125
      supply_register (regi, (char *) (regp + regmap[regi]));
126
    }
127
}
128
 
129
void
130
fill_gregset (gregset_t *gregsetp, int regno)
131
{
132
  int regi;
133
  register greg_t *regp = (greg_t *) gregsetp;
134
  extern int regmap[];
135
 
136
  for (regi = 0; regi < (NUM_REGS - NUM_FREGS); regi++)
137
    {
138
      if ((regno == -1) || (regno == regi))
139
        {
140
          *(regp + regmap[regi]) = *(int *) &registers[REGISTER_BYTE (regi)];
141
        }
142
    }
143
}
144
 
145
#endif /* HAVE_GREGSET_T */
146
 
147
#if defined (HAVE_FPREGSET_T)
148
 
149
/*  Given a pointer to a floating point register set in /proc format
150
   (fpregset_t *), unpack the register contents and supply them as gdb's
151
   idea of the current floating point register values. */
152
 
153
/* FIXME: Assumes that fpregsetp contains an i387 FSAVE area. */
154
static const int freg_offset_map[] =
155
{
156
#if !defined(FPREGSET_FSAVE_OFFSET)
157
#define FPREGSET_FSAVE_OFFSET   0
158
#endif
159
  FPREGSET_FSAVE_OFFSET + 28 + 0 * 10,
160
  FPREGSET_FSAVE_OFFSET + 28 + 1 * 10,
161
  FPREGSET_FSAVE_OFFSET + 28 + 2 * 10,
162
  FPREGSET_FSAVE_OFFSET + 28 + 3 * 10,
163
  FPREGSET_FSAVE_OFFSET + 28 + 4 * 10,
164
  FPREGSET_FSAVE_OFFSET + 28 + 5 * 10,
165
  FPREGSET_FSAVE_OFFSET + 28 + 6 * 10,
166
  FPREGSET_FSAVE_OFFSET + 28 + 7 * 10,
167
  FPREGSET_FSAVE_OFFSET + 0,
168
  FPREGSET_FSAVE_OFFSET + 4,
169
  FPREGSET_FSAVE_OFFSET + 8,
170
  FPREGSET_FSAVE_OFFSET + 16,
171
  FPREGSET_FSAVE_OFFSET + 12,
172
  FPREGSET_FSAVE_OFFSET + 24,
173
  FPREGSET_FSAVE_OFFSET + 20,
174
  FPREGSET_FSAVE_OFFSET + 16
175
};
176
 
177
void
178
supply_fpregset (fpregset_t *fpregsetp)
179
{
180
  int regi;
181
 
182
  if (NUM_FREGS == 0)
183
    return;
184
  for (regi = FP0_REGNUM; regi <= LAST_FPU_CTRL_REGNUM; regi++)
185
    {
186
      char tbuf[4];
187
      ULONGEST tval;
188
      char *from = (char *) fpregsetp + freg_offset_map[regi - FP0_REGNUM];
189
 
190
      if (regi == FCS_REGNUM)
191
        {
192
          tval = extract_unsigned_integer (from, 4) & 0xffff;
193
          store_unsigned_integer (tbuf, 4, tval);
194
          supply_register (regi, tbuf);
195
        }
196
      else if (regi == FOP_REGNUM)
197
        {
198
          tval = (extract_unsigned_integer (from, 4) >> 16) & ((1 << 11) - 1);
199
          store_unsigned_integer (tbuf, 4, tval);
200
          supply_register (regi, tbuf);
201
        }
202
      else
203
        supply_register (regi, from);
204
    }
205
}
206
 
207
/*  Given a pointer to a floating point register set in /proc format
208
   (fpregset_t *), update the register specified by REGNO from gdb's idea
209
   of the current floating point register set.  If REGNO is -1, update
210
   them all. */
211
 
212
void
213
fill_fpregset (fpregset_t *fpregsetp, int regno)
214
{
215
  int regi;
216
 
217
  if (NUM_FREGS == 0)
218
    return;
219
  for (regi = FP0_REGNUM; regi <= LAST_FPU_CTRL_REGNUM; regi++)
220
    {
221
      if ((regno == -1) || (regno == regi))
222
        {
223
          char *to = (char *) fpregsetp + freg_offset_map[regi - FP0_REGNUM];
224
          char *from = (char *) &registers[REGISTER_BYTE (regi)];
225
          ULONGEST valto;
226
          ULONGEST valfrom;
227
 
228
          if (regi == FCS_REGNUM)
229
            {
230
              valto = extract_unsigned_integer (to, 4);
231
              valfrom = extract_unsigned_integer (from, 4);
232
              valto = (valto & ~0xffff) | (valfrom & 0xffff);
233
              store_unsigned_integer (to, 4, valto);
234
            }
235
          else if (regi == FOP_REGNUM)
236
            {
237
              valto = extract_unsigned_integer (to, 4);
238
              valfrom = extract_unsigned_integer (from, 4);
239
              valto = (valto & 0xffff) | ((valfrom & ((1 << 11) - 1)) << 16);
240
              store_unsigned_integer (to, 4, valto);
241
            }
242
          else
243
            {
244
              memcpy (to, from, REGISTER_RAW_SIZE (regi));
245
            }
246
        }
247
    }
248
}
249
 
250
#endif /* defined (HAVE_FPREGSET_T) */
251
 
252
#endif /* HAVE_SYS_PROCFS_H */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.