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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [armnbsd-nat.c] - Blame information for rev 842

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* Native-dependent code for BSD Unix running on ARM's, for GDB.
2
 
3
   Copyright (C) 1988, 1989, 1991, 1992, 1994, 1996, 1999, 2002, 2004, 2007,
4
   2008, 2009, 2010 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 "gdbcore.h"
23
#include "inferior.h"
24
#include "regcache.h"
25
#include "target.h"
26
 
27
#include "gdb_string.h"
28
#include <sys/types.h>
29
#include <sys/ptrace.h>
30
#include <machine/reg.h>
31
#include <machine/frame.h>
32
 
33
#include "arm-tdep.h"
34
#include "inf-ptrace.h"
35
 
36
extern int arm_apcs_32;
37
 
38
static void
39
arm_supply_gregset (struct regcache *regcache, struct reg *gregset)
40
{
41
  int regno;
42
  CORE_ADDR r_pc;
43
 
44
  /* Integer registers.  */
45
  for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
46
    regcache_raw_supply (regcache, regno, (char *) &gregset->r[regno]);
47
 
48
  regcache_raw_supply (regcache, ARM_SP_REGNUM,
49
                       (char *) &gregset->r_sp);
50
  regcache_raw_supply (regcache, ARM_LR_REGNUM,
51
                       (char *) &gregset->r_lr);
52
  /* This is ok: we're running native...  */
53
  r_pc = gdbarch_addr_bits_remove (get_regcache_arch (regcache), gregset->r_pc);
54
  regcache_raw_supply (regcache, ARM_PC_REGNUM, (char *) &r_pc);
55
 
56
  if (arm_apcs_32)
57
    regcache_raw_supply (regcache, ARM_PS_REGNUM,
58
                         (char *) &gregset->r_cpsr);
59
  else
60
    regcache_raw_supply (regcache, ARM_PS_REGNUM,
61
                         (char *) &gregset->r_pc);
62
}
63
 
64
static void
65
arm_supply_fparegset (struct regcache *regcache, struct fpreg *fparegset)
66
{
67
  int regno;
68
 
69
  for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
70
    regcache_raw_supply (regcache, regno,
71
                         (char *) &fparegset->fpr[regno - ARM_F0_REGNUM]);
72
 
73
  regcache_raw_supply (regcache, ARM_FPS_REGNUM,
74
                       (char *) &fparegset->fpr_fpsr);
75
}
76
 
77
static void
78
fetch_register (struct regcache *regcache, int regno)
79
{
80
  struct reg inferior_registers;
81
  int ret;
82
 
83
  ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
84
                (PTRACE_TYPE_ARG3) &inferior_registers, 0);
85
 
86
  if (ret < 0)
87
    {
88
      warning (_("unable to fetch general register"));
89
      return;
90
    }
91
 
92
  switch (regno)
93
    {
94
    case ARM_SP_REGNUM:
95
      regcache_raw_supply (regcache, ARM_SP_REGNUM,
96
                           (char *) &inferior_registers.r_sp);
97
      break;
98
 
99
    case ARM_LR_REGNUM:
100
      regcache_raw_supply (regcache, ARM_LR_REGNUM,
101
                           (char *) &inferior_registers.r_lr);
102
      break;
103
 
104
    case ARM_PC_REGNUM:
105
      /* This is ok: we're running native... */
106
      inferior_registers.r_pc = gdbarch_addr_bits_remove
107
                                  (get_regcache_arch (regcache),
108
                                   inferior_registers.r_pc);
109
      regcache_raw_supply (regcache, ARM_PC_REGNUM,
110
                           (char *) &inferior_registers.r_pc);
111
      break;
112
 
113
    case ARM_PS_REGNUM:
114
      if (arm_apcs_32)
115
        regcache_raw_supply (regcache, ARM_PS_REGNUM,
116
                             (char *) &inferior_registers.r_cpsr);
117
      else
118
        regcache_raw_supply (regcache, ARM_PS_REGNUM,
119
                             (char *) &inferior_registers.r_pc);
120
      break;
121
 
122
    default:
123
      regcache_raw_supply (regcache, regno,
124
                           (char *) &inferior_registers.r[regno]);
125
      break;
126
    }
127
}
128
 
129
static void
130
fetch_regs (struct regcache *regcache)
131
{
132
  struct reg inferior_registers;
133
  int ret;
134
  int regno;
135
 
136
  ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
137
                (PTRACE_TYPE_ARG3) &inferior_registers, 0);
138
 
139
  if (ret < 0)
140
    {
141
      warning (_("unable to fetch general registers"));
142
      return;
143
    }
144
 
145
  arm_supply_gregset (regcache, &inferior_registers);
146
}
147
 
148
static void
149
fetch_fp_register (struct regcache *regcache, int regno)
150
{
151
  struct fpreg inferior_fp_registers;
152
  int ret;
153
 
154
  ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
155
                (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
156
 
157
  if (ret < 0)
158
    {
159
      warning (_("unable to fetch floating-point register"));
160
      return;
161
    }
162
 
163
  switch (regno)
164
    {
165
    case ARM_FPS_REGNUM:
166
      regcache_raw_supply (regcache, ARM_FPS_REGNUM,
167
                           (char *) &inferior_fp_registers.fpr_fpsr);
168
      break;
169
 
170
    default:
171
      regcache_raw_supply (regcache, regno,
172
                           (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
173
      break;
174
    }
175
}
176
 
177
static void
178
fetch_fp_regs (struct regcache *regcache)
179
{
180
  struct fpreg inferior_fp_registers;
181
  int ret;
182
  int regno;
183
 
184
  ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
185
                (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
186
 
187
  if (ret < 0)
188
    {
189
      warning (_("unable to fetch general registers"));
190
      return;
191
    }
192
 
193
  arm_supply_fparegset (regcache, &inferior_fp_registers);
194
}
195
 
196
static void
197
armnbsd_fetch_registers (struct target_ops *ops,
198
                         struct regcache *regcache, int regno)
199
{
200
  if (regno >= 0)
201
    {
202
      if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
203
        fetch_register (regcache, regno);
204
      else
205
        fetch_fp_register (regcache, regno);
206
    }
207
  else
208
    {
209
      fetch_regs (regcache);
210
      fetch_fp_regs (regcache);
211
    }
212
}
213
 
214
 
215
static void
216
store_register (const struct regcache *regcache, int regno)
217
{
218
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
219
  struct reg inferior_registers;
220
  int ret;
221
 
222
  ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
223
                (PTRACE_TYPE_ARG3) &inferior_registers, 0);
224
 
225
  if (ret < 0)
226
    {
227
      warning (_("unable to fetch general registers"));
228
      return;
229
    }
230
 
231
  switch (regno)
232
    {
233
    case ARM_SP_REGNUM:
234
      regcache_raw_collect (regcache, ARM_SP_REGNUM,
235
                            (char *) &inferior_registers.r_sp);
236
      break;
237
 
238
    case ARM_LR_REGNUM:
239
      regcache_raw_collect (regcache, ARM_LR_REGNUM,
240
                            (char *) &inferior_registers.r_lr);
241
      break;
242
 
243
    case ARM_PC_REGNUM:
244
      if (arm_apcs_32)
245
        regcache_raw_collect (regcache, ARM_PC_REGNUM,
246
                              (char *) &inferior_registers.r_pc);
247
      else
248
        {
249
          unsigned pc_val;
250
 
251
          regcache_raw_collect (regcache, ARM_PC_REGNUM,
252
                                (char *) &pc_val);
253
 
254
          pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
255
          inferior_registers.r_pc ^= gdbarch_addr_bits_remove
256
                                       (gdbarch, inferior_registers.r_pc);
257
          inferior_registers.r_pc |= pc_val;
258
        }
259
      break;
260
 
261
    case ARM_PS_REGNUM:
262
      if (arm_apcs_32)
263
        regcache_raw_collect (regcache, ARM_PS_REGNUM,
264
                              (char *) &inferior_registers.r_cpsr);
265
      else
266
        {
267
          unsigned psr_val;
268
 
269
          regcache_raw_collect (regcache, ARM_PS_REGNUM,
270
                                (char *) &psr_val);
271
 
272
          psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
273
          inferior_registers.r_pc = gdbarch_addr_bits_remove
274
                                      (gdbarch, inferior_registers.r_pc);
275
          inferior_registers.r_pc |= psr_val;
276
        }
277
      break;
278
 
279
    default:
280
      regcache_raw_collect (regcache, regno,
281
                            (char *) &inferior_registers.r[regno]);
282
      break;
283
    }
284
 
285
  ret = ptrace (PT_SETREGS, PIDGET (inferior_ptid),
286
                (PTRACE_TYPE_ARG3) &inferior_registers, 0);
287
 
288
  if (ret < 0)
289
    warning (_("unable to write register %d to inferior"), regno);
290
}
291
 
292
static void
293
store_regs (const struct regcache *regcache)
294
{
295
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
296
  struct reg inferior_registers;
297
  int ret;
298
  int regno;
299
 
300
 
301
  for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
302
    regcache_raw_collect (regcache, regno,
303
                          (char *) &inferior_registers.r[regno]);
304
 
305
  regcache_raw_collect (regcache, ARM_SP_REGNUM,
306
                        (char *) &inferior_registers.r_sp);
307
  regcache_raw_collect (regcache, ARM_LR_REGNUM,
308
                        (char *) &inferior_registers.r_lr);
309
 
310
  if (arm_apcs_32)
311
    {
312
      regcache_raw_collect (regcache, ARM_PC_REGNUM,
313
                            (char *) &inferior_registers.r_pc);
314
      regcache_raw_collect (regcache, ARM_PS_REGNUM,
315
                            (char *) &inferior_registers.r_cpsr);
316
    }
317
  else
318
    {
319
      unsigned pc_val;
320
      unsigned psr_val;
321
 
322
      regcache_raw_collect (regcache, ARM_PC_REGNUM,
323
                            (char *) &pc_val);
324
      regcache_raw_collect (regcache, ARM_PS_REGNUM,
325
                            (char *) &psr_val);
326
 
327
      pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
328
      psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
329
 
330
      inferior_registers.r_pc = pc_val | psr_val;
331
    }
332
 
333
  ret = ptrace (PT_SETREGS, PIDGET (inferior_ptid),
334
                (PTRACE_TYPE_ARG3) &inferior_registers, 0);
335
 
336
  if (ret < 0)
337
    warning (_("unable to store general registers"));
338
}
339
 
340
static void
341
store_fp_register (const struct regcache *regcache, int regno)
342
{
343
  struct fpreg inferior_fp_registers;
344
  int ret;
345
 
346
  ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
347
                (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
348
 
349
  if (ret < 0)
350
    {
351
      warning (_("unable to fetch floating-point registers"));
352
      return;
353
    }
354
 
355
  switch (regno)
356
    {
357
    case ARM_FPS_REGNUM:
358
      regcache_raw_collect (regcache, ARM_FPS_REGNUM,
359
                            (char *) &inferior_fp_registers.fpr_fpsr);
360
      break;
361
 
362
    default:
363
      regcache_raw_collect (regcache, regno,
364
                            (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
365
      break;
366
    }
367
 
368
  ret = ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
369
                (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
370
 
371
  if (ret < 0)
372
    warning (_("unable to write register %d to inferior"), regno);
373
}
374
 
375
static void
376
store_fp_regs (const struct regcache *regcache)
377
{
378
  struct fpreg inferior_fp_registers;
379
  int ret;
380
  int regno;
381
 
382
 
383
  for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
384
    regcache_raw_collect (regcache, regno,
385
                          (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
386
 
387
  regcache_raw_collect (regcache, ARM_FPS_REGNUM,
388
                        (char *) &inferior_fp_registers.fpr_fpsr);
389
 
390
  ret = ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
391
                (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
392
 
393
  if (ret < 0)
394
    warning (_("unable to store floating-point registers"));
395
}
396
 
397
static void
398
armnbsd_store_registers (struct target_ops *ops,
399
                         struct regcache *regcache, int regno)
400
{
401
  if (regno >= 0)
402
    {
403
      if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
404
        store_register (regcache, regno);
405
      else
406
        store_fp_register (regcache, regno);
407
    }
408
  else
409
    {
410
      store_regs (regcache);
411
      store_fp_regs (regcache);
412
    }
413
}
414
 
415
struct md_core
416
{
417
  struct reg intreg;
418
  struct fpreg freg;
419
};
420
 
421
static void
422
fetch_core_registers (struct regcache *regcache,
423
                      char *core_reg_sect, unsigned core_reg_size,
424
                      int which, CORE_ADDR ignore)
425
{
426
  struct md_core *core_reg = (struct md_core *) core_reg_sect;
427
  int regno;
428
  CORE_ADDR r_pc;
429
 
430
  arm_supply_gregset (regcache, &core_reg->intreg);
431
  arm_supply_fparegset (regcache, &core_reg->freg);
432
}
433
 
434
static void
435
fetch_elfcore_registers (struct regcache *regcache,
436
                         char *core_reg_sect, unsigned core_reg_size,
437
                         int which, CORE_ADDR ignore)
438
{
439
  struct reg gregset;
440
  struct fpreg fparegset;
441
 
442
  switch (which)
443
    {
444
    case 0:      /* Integer registers.  */
445
      if (core_reg_size != sizeof (struct reg))
446
        warning (_("wrong size of register set in core file"));
447
      else
448
        {
449
          /* The memcpy may be unnecessary, but we can't really be sure
450
             of the alignment of the data in the core file.  */
451
          memcpy (&gregset, core_reg_sect, sizeof (gregset));
452
          arm_supply_gregset (regcache, &gregset);
453
        }
454
      break;
455
 
456
    case 2:
457
      if (core_reg_size != sizeof (struct fpreg))
458
        warning (_("wrong size of FPA register set in core file"));
459
      else
460
        {
461
          /* The memcpy may be unnecessary, but we can't really be sure
462
             of the alignment of the data in the core file.  */
463
          memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
464
          arm_supply_fparegset (regcache, &fparegset);
465
        }
466
      break;
467
 
468
    default:
469
      /* Don't know what kind of register request this is; just ignore it.  */
470
      break;
471
    }
472
}
473
 
474
static struct core_fns arm_netbsd_core_fns =
475
{
476
  bfd_target_unknown_flavour,           /* core_flovour.  */
477
  default_check_format,                 /* check_format.  */
478
  default_core_sniffer,                 /* core_sniffer.  */
479
  fetch_core_registers,                 /* core_read_registers.  */
480
  NULL
481
};
482
 
483
static struct core_fns arm_netbsd_elfcore_fns =
484
{
485
  bfd_target_elf_flavour,               /* core_flovour.  */
486
  default_check_format,                 /* check_format.  */
487
  default_core_sniffer,                 /* core_sniffer.  */
488
  fetch_elfcore_registers,              /* core_read_registers.  */
489
  NULL
490
};
491
 
492
void
493
_initialize_arm_netbsd_nat (void)
494
{
495
  struct target_ops *t;
496
 
497
  t = inf_ptrace_target ();
498
  t->to_fetch_registers = armnbsd_fetch_registers;
499
  t->to_store_registers = armnbsd_store_registers;
500
  add_target (t);
501
 
502
  deprecated_add_core_fns (&arm_netbsd_core_fns);
503
  deprecated_add_core_fns (&arm_netbsd_elfcore_fns);
504
}

powered by: WebSVN 2.1.0

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