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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [i386bsd-nat.c] - Blame information for rev 578

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

Line No. Rev Author Line
1 578 markom
/* Native-dependent code for modern i386 BSD's.
2
   Copyright 2000, 2001 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 "inferior.h"
23
#include "regcache.h"
24
 
25
#include "gdb_assert.h"
26
#include <sys/types.h>
27
#include <sys/ptrace.h>
28
#include <machine/reg.h>
29
#include <machine/frame.h>
30
 
31
#ifdef HAVE_SYS_PROCFS_H
32
#include <sys/procfs.h>
33
#endif
34
 
35
#ifndef HAVE_GREGSET_T
36
typedef struct reg gregset_t;
37
#endif
38
 
39
#ifndef HAVE_FPREGSET_T
40
typedef struct fpreg fpregset_t;
41
#endif
42
 
43
#include "gregset.h"
44
 
45
 
46
/* In older BSD versions we cannot get at some of the segment
47
   registers.  FreeBSD for example didn't support the %fs and %gs
48
   registers until the 3.0 release.  We have autoconf checks for their
49
   presence, and deal gracefully with their absence.  */
50
 
51
/* Registers we shouldn't try to fetch.  */
52
#if !defined (CANNOT_FETCH_REGISTER)
53
#define CANNOT_FETCH_REGISTER(regno) cannot_fetch_register (regno)
54
#endif
55
 
56
/* Registers we shouldn't try to store.  */
57
#if !defined (CANNOT_STORE_REGISTER)
58
#define CANNOT_STORE_REGISTER(regno) cannot_fetch_register (regno)
59
#endif
60
 
61
/* Offset to the gregset_t location where REG is stored.  */
62
#define REG_OFFSET(reg) offsetof (gregset_t, reg)
63
 
64
/* At reg_offset[REGNO] you'll find the offset to the gregset_t
65
   location where the GDB register REGNO is stored.  Unsupported
66
   registers are marked with `-1'.  */
67
static int reg_offset[] =
68
{
69
  REG_OFFSET (r_eax),
70
  REG_OFFSET (r_ecx),
71
  REG_OFFSET (r_edx),
72
  REG_OFFSET (r_edx),
73
  REG_OFFSET (r_esp),
74
  REG_OFFSET (r_ebp),
75
  REG_OFFSET (r_esi),
76
  REG_OFFSET (r_edi),
77
  REG_OFFSET (r_eip),
78
  REG_OFFSET (r_eflags),
79
  REG_OFFSET (r_cs),
80
  REG_OFFSET (r_ss),
81
  REG_OFFSET (r_ds),
82
  REG_OFFSET (r_es),
83
#ifdef HAVE_STRUCT_REG_R_FS
84
  REG_OFFSET (r_fs),
85
#else
86
  -1,
87
#endif
88
#ifdef HAVE_STRUCT_REG_R_GS
89
  REG_OFFSET (r_gs)
90
#else
91
  -1
92
#endif
93
};
94
 
95
#define REG_ADDR(regset, regno) ((char *) (regset) + reg_offset[regno])
96
 
97
/* Return nonzero if we shouldn't try to fetch register REGNO.  */
98
 
99
static int
100
cannot_fetch_register (int regno)
101
{
102
  return (reg_offset[regno] == -1);
103
}
104
 
105
 
106
/* Transfering the registers between GDB, inferiors and core files.  */
107
 
108
/* Fill GDB's register array with the general-purpose register values
109
   in *GREGSETP.  */
110
 
111
void
112
supply_gregset (gregset_t *gregsetp)
113
{
114
  int i;
115
 
116
  for (i = 0; i < NUM_GREGS; i++)
117
    {
118
      if (CANNOT_FETCH_REGISTER (i))
119
        supply_register (i, NULL);
120
      else
121
        supply_register (i, REG_ADDR (gregsetp, i));
122
    }
123
}
124
 
125
/* Fill register REGNO (if it is a general-purpose register) in
126
   *GREGSETPS with the value in GDB's register array.  If REGNO is -1,
127
   do this for all registers.  */
128
 
129
void
130
fill_gregset (gregset_t *gregsetp, int regno)
131
{
132
  int i;
133
 
134
  for (i = 0; i < NUM_GREGS; i++)
135
    if ((regno == -1 || regno == i) && ! CANNOT_STORE_REGISTER (i))
136
      memcpy (REG_ADDR (gregsetp, i), &registers[REGISTER_BYTE (i)],
137
              REGISTER_RAW_SIZE (i));
138
}
139
 
140
#include "i387-nat.h"
141
 
142
/* Fill GDB's register array with the floating-point register values
143
   in *FPREGSETP.  */
144
 
145
void
146
supply_fpregset (fpregset_t *fpregsetp)
147
{
148
  i387_supply_fsave ((char *) fpregsetp);
149
}
150
 
151
/* Fill register REGNO (if it is a floating-point register) in
152
   *FPREGSETP with the value in GDB's register array.  If REGNO is -1,
153
   do this for all registers.  */
154
 
155
void
156
fill_fpregset (fpregset_t *fpregsetp, int regno)
157
{
158
  i387_fill_fsave ((char *) fpregsetp, regno);
159
}
160
 
161
/* Fetch register REGNO from the inferior.  If REGNO is -1, do this
162
   for all registers (including the floating point registers).  */
163
 
164
void
165
fetch_inferior_registers (int regno)
166
{
167
  gregset_t gregs;
168
 
169
  if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
170
              (PTRACE_ARG3_TYPE) &gregs, 0) == -1)
171
    perror_with_name ("Couldn't get registers");
172
 
173
  supply_gregset (&gregs);
174
 
175
  if (regno == -1 || regno >= FP0_REGNUM)
176
    {
177
      fpregset_t fpregs;
178
 
179
      if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
180
                  (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
181
        perror_with_name ("Couldn't get floating point status");
182
 
183
      supply_fpregset (&fpregs);
184
    }
185
}
186
 
187
/* Store register REGNO back into the inferior.  If REGNO is -1, do
188
   this for all registers (including the floating point registers).  */
189
 
190
void
191
store_inferior_registers (int regno)
192
{
193
  gregset_t gregs;
194
 
195
  if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
196
              (PTRACE_ARG3_TYPE) &gregs, 0) == -1)
197
    perror_with_name ("Couldn't get registers");
198
 
199
  fill_gregset (&gregs, regno);
200
 
201
  if (ptrace (PT_SETREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) &gregs, 0) == -1)
202
    perror_with_name ("Couldn't write registers");
203
 
204
  if (regno == -1 || regno >= FP0_REGNUM)
205
    {
206
      fpregset_t fpregs;
207
 
208
      if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
209
                  (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
210
        perror_with_name ("Couldn't get floating point status");
211
 
212
      fill_fpregset (&fpregs, regno);
213
 
214
      if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
215
                  (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
216
        perror_with_name ("Couldn't write floating point status");
217
    }
218
}
219
 
220
 
221
/* Support for debug registers.  */
222
 
223
#ifdef HAVE_PT_GETDBREGS
224
 
225
/* Not all versions of FreeBSD/i386 that support the debug registers
226
   have this macro.  */
227
#ifndef DBREG_DRX
228
#define DBREG_DRX(d, x) ((&d->dr0)[x])
229
#endif
230
 
231
static void
232
i386bsd_dr_set (int regnum, unsigned int value)
233
{
234
  struct dbreg dbregs;
235
 
236
  if (ptrace (PT_GETDBREGS, PIDGET (inferior_ptid),
237
              (PTRACE_ARG3_TYPE) &dbregs, 0) == -1)
238
    perror_with_name ("Couldn't get debug registers");
239
 
240
  /* For some mysterious reason, some of the reserved bits in the
241
     debug control register get set.  Mask these off, otherwise the
242
     ptrace call below will fail.  */
243
  dbregs.dr7 &= ~(0x0000fc00);
244
 
245
  DBREG_DRX ((&dbregs), regnum) = value;
246
 
247
  if (ptrace (PT_SETDBREGS, PIDGET (inferior_ptid),
248
              (PTRACE_ARG3_TYPE) &dbregs, 0) == -1)
249
    perror_with_name ("Couldn't write debug registers");
250
}
251
 
252
void
253
i386bsd_dr_set_control (unsigned long control)
254
{
255
  i386bsd_dr_set (7, control);
256
}
257
 
258
void
259
i386bsd_dr_set_addr (int regnum, CORE_ADDR addr)
260
{
261
  gdb_assert (regnum >= 0 && regnum <= 4);
262
 
263
  i386bsd_dr_set (regnum, addr);
264
}
265
 
266
void
267
i386bsd_dr_reset_addr (int regnum)
268
{
269
  gdb_assert (regnum >= 0 && regnum <= 4);
270
 
271
  i386bsd_dr_set (regnum, 0);
272
}
273
 
274
unsigned long
275
i386bsd_dr_get_status (void)
276
{
277
  struct dbreg dbregs;
278
 
279
  /* FIXME: kettenis/2001-03-31: Calling perror_with_name if the
280
     ptrace call fails breaks debugging remote targets.  The correct
281
     way to fix this is to add the hardware breakpoint and watchpoint
282
     stuff to the target vectore.  For now, just return zero if the
283
     ptrace call fails.  */
284
  if (ptrace (PT_GETDBREGS, PIDGET (inferior_ptid),
285
              (PTRACE_ARG3_TYPE) & dbregs, 0) == -1)
286
#if 0
287
    perror_with_name ("Couldn't read debug registers");
288
#else
289
    return 0;
290
#endif
291
 
292
  return dbregs.dr6;
293
}
294
 
295
#endif /* PT_GETDBREGS */
296
 
297
 
298
/* Support for the user struct.  */
299
 
300
/* Return the address register REGNO.  BLOCKEND is the value of
301
   u.u_ar0, which should point to the registers.  */
302
 
303
CORE_ADDR
304
register_u_addr (CORE_ADDR blockend, int regno)
305
{
306
  return (CORE_ADDR) REG_ADDR (blockend, regno);
307
}
308
 
309
#include <sys/param.h>
310
#include <sys/user.h>
311
 
312
/* Return the size of the user struct.  */
313
 
314
int
315
kernel_u_size (void)
316
{
317
  return (sizeof (struct user));
318
}

powered by: WebSVN 2.1.0

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