OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.2/] [gdb/] [i386bsd-nat.c] - Blame information for rev 631

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

Line No. Rev Author Line
1 330 jeremybenn
/* Native-dependent code for modern i386 BSD's.
2
 
3
   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
4
   Free Software Foundation, Inc.
5
 
6
   This file is part of GDB.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
 
21
#include "defs.h"
22
#include "inferior.h"
23
#include "regcache.h"
24
 
25
#include "gdb_assert.h"
26
#include <signal.h>
27
#include <stddef.h>
28
#include <sys/types.h>
29
#include <sys/ptrace.h>
30
#include <machine/reg.h>
31
#include <machine/frame.h>
32
 
33
#include "i386-tdep.h"
34
#include "i387-tdep.h"
35
#include "i386bsd-nat.h"
36
#include "inf-ptrace.h"
37
 
38
 
39
/* In older BSD versions we cannot get at some of the segment
40
   registers.  FreeBSD for example didn't support the %fs and %gs
41
   registers until the 3.0 release.  We have autoconf checks for their
42
   presence, and deal gracefully with their absence.  */
43
 
44
/* Offset in `struct reg' where MEMBER is stored.  */
45
#define REG_OFFSET(member) offsetof (struct reg, member)
46
 
47
/* At i386bsd_reg_offset[REGNUM] you'll find the offset in `struct
48
   reg' where the GDB register REGNUM is stored.  Unsupported
49
   registers are marked with `-1'.  */
50
static int i386bsd_r_reg_offset[] =
51
{
52
  REG_OFFSET (r_eax),
53
  REG_OFFSET (r_ecx),
54
  REG_OFFSET (r_edx),
55
  REG_OFFSET (r_ebx),
56
  REG_OFFSET (r_esp),
57
  REG_OFFSET (r_ebp),
58
  REG_OFFSET (r_esi),
59
  REG_OFFSET (r_edi),
60
  REG_OFFSET (r_eip),
61
  REG_OFFSET (r_eflags),
62
  REG_OFFSET (r_cs),
63
  REG_OFFSET (r_ss),
64
  REG_OFFSET (r_ds),
65
  REG_OFFSET (r_es),
66
#ifdef HAVE_STRUCT_REG_R_FS
67
  REG_OFFSET (r_fs),
68
#else
69
  -1,
70
#endif
71
#ifdef HAVE_STRUCT_REG_R_GS
72
  REG_OFFSET (r_gs)
73
#else
74
  -1
75
#endif
76
};
77
 
78
/* Macro to determine if a register is fetched with PT_GETREGS.  */
79
#define GETREGS_SUPPLIES(regnum) \
80
  ((0 <= (regnum) && (regnum) <= 15))
81
 
82
#ifdef HAVE_PT_GETXMMREGS
83
/* Set to 1 if the kernel supports PT_GETXMMREGS.  Initialized to -1
84
   so that we try PT_GETXMMREGS the first time around.  */
85
static int have_ptrace_xmmregs = -1;
86
#endif
87
 
88
 
89
/* Supply the general-purpose registers in GREGS, to REGCACHE.  */
90
 
91
static void
92
i386bsd_supply_gregset (struct regcache *regcache, const void *gregs)
93
{
94
  const char *regs = gregs;
95
  int regnum;
96
 
97
  for (regnum = 0; regnum < ARRAY_SIZE (i386bsd_r_reg_offset); regnum++)
98
    {
99
      int offset = i386bsd_r_reg_offset[regnum];
100
 
101
      if (offset != -1)
102
        regcache_raw_supply (regcache, regnum, regs + offset);
103
    }
104
}
105
 
106
/* Collect register REGNUM from REGCACHE and store its contents in
107
   GREGS.  If REGNUM is -1, collect and store all appropriate
108
   registers.  */
109
 
110
static void
111
i386bsd_collect_gregset (const struct regcache *regcache,
112
                         void *gregs, int regnum)
113
{
114
  char *regs = gregs;
115
  int i;
116
 
117
  for (i = 0; i < ARRAY_SIZE (i386bsd_r_reg_offset); i++)
118
    {
119
      if (regnum == -1 || regnum == i)
120
        {
121
          int offset = i386bsd_r_reg_offset[i];
122
 
123
          if (offset != -1)
124
            regcache_raw_collect (regcache, i, regs + offset);
125
        }
126
    }
127
}
128
 
129
/* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
130
   for all registers (including the floating point registers).  */
131
 
132
static void
133
i386bsd_fetch_inferior_registers (struct target_ops *ops,
134
                                  struct regcache *regcache, int regnum)
135
{
136
  if (regnum == -1 || GETREGS_SUPPLIES (regnum))
137
    {
138
      struct reg regs;
139
 
140
      if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
141
                  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
142
        perror_with_name (_("Couldn't get registers"));
143
 
144
      i386bsd_supply_gregset (regcache, &regs);
145
      if (regnum != -1)
146
        return;
147
    }
148
 
149
  if (regnum == -1 || regnum >= I386_ST0_REGNUM)
150
    {
151
      struct fpreg fpregs;
152
#ifdef HAVE_PT_GETXMMREGS
153
      char xmmregs[512];
154
 
155
      if (have_ptrace_xmmregs != 0
156
          && ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid),
157
                    (PTRACE_TYPE_ARG3) xmmregs, 0) == 0)
158
        {
159
          have_ptrace_xmmregs = 1;
160
          i387_supply_fxsave (regcache, -1, xmmregs);
161
        }
162
      else
163
        {
164
          if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
165
                      (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
166
            perror_with_name (_("Couldn't get floating point status"));
167
 
168
          i387_supply_fsave (regcache, -1, &fpregs);
169
        }
170
#else
171
      if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
172
                  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
173
        perror_with_name (_("Couldn't get floating point status"));
174
 
175
      i387_supply_fsave (regcache, -1, &fpregs);
176
#endif
177
    }
178
}
179
 
180
/* Store register REGNUM back into the inferior.  If REGNUM is -1, do
181
   this for all registers (including the floating point registers).  */
182
 
183
static void
184
i386bsd_store_inferior_registers (struct target_ops *ops,
185
                                  struct regcache *regcache, int regnum)
186
{
187
  if (regnum == -1 || GETREGS_SUPPLIES (regnum))
188
    {
189
      struct reg regs;
190
 
191
      if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
192
                  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
193
        perror_with_name (_("Couldn't get registers"));
194
 
195
      i386bsd_collect_gregset (regcache, &regs, regnum);
196
 
197
      if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
198
                  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
199
        perror_with_name (_("Couldn't write registers"));
200
 
201
      if (regnum != -1)
202
        return;
203
    }
204
 
205
  if (regnum == -1 || regnum >= I386_ST0_REGNUM)
206
    {
207
      struct fpreg fpregs;
208
#ifdef HAVE_PT_GETXMMREGS
209
      char xmmregs[512];
210
 
211
      if (have_ptrace_xmmregs != 0
212
          && ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid),
213
                    (PTRACE_TYPE_ARG3) xmmregs, 0) == 0)
214
        {
215
          have_ptrace_xmmregs = 1;
216
 
217
          i387_collect_fxsave (regcache, regnum, xmmregs);
218
 
219
          if (ptrace (PT_SETXMMREGS, PIDGET (inferior_ptid),
220
                      (PTRACE_TYPE_ARG3) xmmregs, 0) == -1)
221
            perror_with_name (_("Couldn't write XMM registers"));
222
        }
223
      else
224
        {
225
          have_ptrace_xmmregs = 0;
226
#endif
227
          if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
228
                      (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
229
            perror_with_name (_("Couldn't get floating point status"));
230
 
231
          i387_collect_fsave (regcache, regnum, &fpregs);
232
 
233
          if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
234
                      (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
235
            perror_with_name (_("Couldn't write floating point status"));
236
#ifdef HAVE_PT_GETXMMREGS
237
        }
238
#endif
239
    }
240
}
241
 
242
/* Create a prototype *BSD/i386 target.  The client can override it
243
   with local methods.  */
244
 
245
struct target_ops *
246
i386bsd_target (void)
247
{
248
  struct target_ops *t;
249
 
250
  t = inf_ptrace_target ();
251
  t->to_fetch_registers = i386bsd_fetch_inferior_registers;
252
  t->to_store_registers = i386bsd_store_inferior_registers;
253
  return t;
254
}
255
 
256
 
257
/* Support for debug registers.  */
258
 
259
#ifdef HAVE_PT_GETDBREGS
260
 
261
/* Not all versions of FreeBSD/i386 that support the debug registers
262
   have this macro.  */
263
#ifndef DBREG_DRX
264
#define DBREG_DRX(d, x) ((&d->dr0)[x])
265
#endif
266
 
267
static void
268
i386bsd_dr_set (int regnum, unsigned int value)
269
{
270
  struct dbreg dbregs;
271
 
272
  if (ptrace (PT_GETDBREGS, PIDGET (inferior_ptid),
273
              (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
274
    perror_with_name (_("Couldn't get debug registers"));
275
 
276
  /* For some mysterious reason, some of the reserved bits in the
277
     debug control register get set.  Mask these off, otherwise the
278
     ptrace call below will fail.  */
279
  DBREG_DRX ((&dbregs), 7) &= ~(0x0000fc00);
280
 
281
  DBREG_DRX ((&dbregs), regnum) = value;
282
 
283
  if (ptrace (PT_SETDBREGS, PIDGET (inferior_ptid),
284
              (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
285
    perror_with_name (_("Couldn't write debug registers"));
286
}
287
 
288
void
289
i386bsd_dr_set_control (unsigned long control)
290
{
291
  i386bsd_dr_set (7, control);
292
}
293
 
294
void
295
i386bsd_dr_set_addr (int regnum, CORE_ADDR addr)
296
{
297
  gdb_assert (regnum >= 0 && regnum <= 4);
298
 
299
  i386bsd_dr_set (regnum, addr);
300
}
301
 
302
void
303
i386bsd_dr_reset_addr (int regnum)
304
{
305
  gdb_assert (regnum >= 0 && regnum <= 4);
306
 
307
  i386bsd_dr_set (regnum, 0);
308
}
309
 
310
unsigned long
311
i386bsd_dr_get_status (void)
312
{
313
  struct dbreg dbregs;
314
 
315
  /* FIXME: kettenis/2001-03-31: Calling perror_with_name if the
316
     ptrace call fails breaks debugging remote targets.  The correct
317
     way to fix this is to add the hardware breakpoint and watchpoint
318
     stuff to the target vector.  For now, just return zero if the
319
     ptrace call fails.  */
320
  if (ptrace (PT_GETDBREGS, PIDGET (inferior_ptid),
321
              (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
322
#if 0
323
    perror_with_name (_("Couldn't read debug registers"));
324
#else
325
    return 0;
326
#endif
327
 
328
  return DBREG_DRX ((&dbregs), 6);
329
}
330
 
331
#endif /* PT_GETDBREGS */
332
 
333
 
334
void
335
_initialize_i386bsd_nat (void)
336
{
337
  int offset;
338
 
339
  /* To support the recognition of signal handlers, i386bsd-tdep.c
340
     hardcodes some constants.  Inclusion of this file means that we
341
     are compiling a native debugger, which means that we can use the
342
     system header files and sysctl(3) to get at the relevant
343
     information.  */
344
 
345
#if defined (__FreeBSD_version) && __FreeBSD_version >= 400011
346
#define SC_REG_OFFSET i386fbsd4_sc_reg_offset
347
#elif defined (__FreeBSD_version) && __FreeBSD_version >= 300005
348
#define SC_REG_OFFSET i386fbsd_sc_reg_offset
349
#elif defined (NetBSD) || defined (__NetBSD_Version__)
350
#define SC_REG_OFFSET i386nbsd_sc_reg_offset
351
#elif defined (OpenBSD)
352
#define SC_REG_OFFSET i386obsd_sc_reg_offset
353
#endif
354
 
355
#ifdef SC_REG_OFFSET
356
 
357
  /* We only check the program counter, stack pointer and frame
358
     pointer since these members of `struct sigcontext' are essential
359
     for providing backtraces.  More checks could be added, but would
360
     involve adding configure checks for the appropriate structure
361
     members, since older BSD's don't provide all of them.  */
362
 
363
#define SC_PC_OFFSET SC_REG_OFFSET[I386_EIP_REGNUM]
364
#define SC_SP_OFFSET SC_REG_OFFSET[I386_ESP_REGNUM]
365
#define SC_FP_OFFSET SC_REG_OFFSET[I386_EBP_REGNUM]
366
 
367
  /* Override the default value for the offset of the program counter
368
     in the sigcontext structure.  */
369
  offset = offsetof (struct sigcontext, sc_pc);
370
 
371
  if (SC_PC_OFFSET != offset)
372
    {
373
      warning (_("\
374
offsetof (struct sigcontext, sc_pc) yields %d instead of %d.\n\
375
Please report this to <bug-gdb@gnu.org>."),
376
               offset, SC_PC_OFFSET);
377
    }
378
 
379
  SC_PC_OFFSET = offset;
380
 
381
  /* Likewise for the stack pointer.  */
382
  offset = offsetof (struct sigcontext, sc_sp);
383
 
384
  if (SC_SP_OFFSET != offset)
385
    {
386
      warning (_("\
387
offsetof (struct sigcontext, sc_sp) yields %d instead of %d.\n\
388
Please report this to <bug-gdb@gnu.org>."),
389
               offset, SC_SP_OFFSET);
390
    }
391
 
392
  SC_SP_OFFSET = offset;
393
 
394
  /* And the frame pointer.  */
395
  offset = offsetof (struct sigcontext, sc_fp);
396
 
397
  if (SC_FP_OFFSET != offset)
398
    {
399
      warning (_("\
400
offsetof (struct sigcontext, sc_fp) yields %d instead of %d.\n\
401
Please report this to <bug-gdb@gnu.org>."),
402
               offset, SC_FP_OFFSET);
403
    }
404
 
405
  SC_FP_OFFSET = offset;
406
 
407
#endif /* SC_REG_OFFSET */
408
}

powered by: WebSVN 2.1.0

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