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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [i386v4-nat.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

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