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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [gdb/] [armnbsd-nat.c] - Blame information for rev 25

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 25 jlechner
/* 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 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 regcache *regcache, int regno)
198
{
199
  if (regno >= 0)
200
    {
201
      if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
202
        fetch_register (regcache, regno);
203
      else
204
        fetch_fp_register (regcache, regno);
205
    }
206
  else
207
    {
208
      fetch_regs (regcache);
209
      fetch_fp_regs (regcache);
210
    }
211
}
212
 
213
 
214
static void
215
store_register (const struct regcache *regcache, int regno)
216
{
217
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
218
  struct reg inferior_registers;
219
  int ret;
220
 
221
  ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
222
                (PTRACE_TYPE_ARG3) &inferior_registers, 0);
223
 
224
  if (ret < 0)
225
    {
226
      warning (_("unable to fetch general registers"));
227
      return;
228
    }
229
 
230
  switch (regno)
231
    {
232
    case ARM_SP_REGNUM:
233
      regcache_raw_collect (regcache, ARM_SP_REGNUM,
234
                            (char *) &inferior_registers.r_sp);
235
      break;
236
 
237
    case ARM_LR_REGNUM:
238
      regcache_raw_collect (regcache, ARM_LR_REGNUM,
239
                            (char *) &inferior_registers.r_lr);
240
      break;
241
 
242
    case ARM_PC_REGNUM:
243
      if (arm_apcs_32)
244
        regcache_raw_collect (regcache, ARM_PC_REGNUM,
245
                              (char *) &inferior_registers.r_pc);
246
      else
247
        {
248
          unsigned pc_val;
249
 
250
          regcache_raw_collect (regcache, ARM_PC_REGNUM,
251
                                (char *) &pc_val);
252
 
253
          pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
254
          inferior_registers.r_pc ^= gdbarch_addr_bits_remove
255
                                       (gdbarch, inferior_registers.r_pc);
256
          inferior_registers.r_pc |= pc_val;
257
        }
258
      break;
259
 
260
    case ARM_PS_REGNUM:
261
      if (arm_apcs_32)
262
        regcache_raw_collect (regcache, ARM_PS_REGNUM,
263
                              (char *) &inferior_registers.r_cpsr);
264
      else
265
        {
266
          unsigned psr_val;
267
 
268
          regcache_raw_collect (regcache, ARM_PS_REGNUM,
269
                                (char *) &psr_val);
270
 
271
          psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
272
          inferior_registers.r_pc = gdbarch_addr_bits_remove
273
                                      (gdbarch, inferior_registers.r_pc);
274
          inferior_registers.r_pc |= psr_val;
275
        }
276
      break;
277
 
278
    default:
279
      regcache_raw_collect (regcache, regno,
280
                            (char *) &inferior_registers.r[regno]);
281
      break;
282
    }
283
 
284
  ret = ptrace (PT_SETREGS, PIDGET (inferior_ptid),
285
                (PTRACE_TYPE_ARG3) &inferior_registers, 0);
286
 
287
  if (ret < 0)
288
    warning (_("unable to write register %d to inferior"), regno);
289
}
290
 
291
static void
292
store_regs (const struct regcache *regcache)
293
{
294
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
295
  struct reg inferior_registers;
296
  int ret;
297
  int regno;
298
 
299
 
300
  for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
301
    regcache_raw_collect (regcache, regno,
302
                          (char *) &inferior_registers.r[regno]);
303
 
304
  regcache_raw_collect (regcache, ARM_SP_REGNUM,
305
                        (char *) &inferior_registers.r_sp);
306
  regcache_raw_collect (regcache, ARM_LR_REGNUM,
307
                        (char *) &inferior_registers.r_lr);
308
 
309
  if (arm_apcs_32)
310
    {
311
      regcache_raw_collect (regcache, ARM_PC_REGNUM,
312
                            (char *) &inferior_registers.r_pc);
313
      regcache_raw_collect (regcache, ARM_PS_REGNUM,
314
                            (char *) &inferior_registers.r_cpsr);
315
    }
316
  else
317
    {
318
      unsigned pc_val;
319
      unsigned psr_val;
320
 
321
      regcache_raw_collect (regcache, ARM_PC_REGNUM,
322
                            (char *) &pc_val);
323
      regcache_raw_collect (regcache, ARM_PS_REGNUM,
324
                            (char *) &psr_val);
325
 
326
      pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
327
      psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
328
 
329
      inferior_registers.r_pc = pc_val | psr_val;
330
    }
331
 
332
  ret = ptrace (PT_SETREGS, PIDGET (inferior_ptid),
333
                (PTRACE_TYPE_ARG3) &inferior_registers, 0);
334
 
335
  if (ret < 0)
336
    warning (_("unable to store general registers"));
337
}
338
 
339
static void
340
store_fp_register (const struct regcache *regcache, int regno)
341
{
342
  struct fpreg inferior_fp_registers;
343
  int ret;
344
 
345
  ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
346
                (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
347
 
348
  if (ret < 0)
349
    {
350
      warning (_("unable to fetch floating-point registers"));
351
      return;
352
    }
353
 
354
  switch (regno)
355
    {
356
    case ARM_FPS_REGNUM:
357
      regcache_raw_collect (regcache, ARM_FPS_REGNUM,
358
                            (char *) &inferior_fp_registers.fpr_fpsr);
359
      break;
360
 
361
    default:
362
      regcache_raw_collect (regcache, regno,
363
                            (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
364
      break;
365
    }
366
 
367
  ret = ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
368
                (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
369
 
370
  if (ret < 0)
371
    warning (_("unable to write register %d to inferior"), regno);
372
}
373
 
374
static void
375
store_fp_regs (const struct regcache *regcache)
376
{
377
  struct fpreg inferior_fp_registers;
378
  int ret;
379
  int regno;
380
 
381
 
382
  for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
383
    regcache_raw_collect (regcache, regno,
384
                          (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
385
 
386
  regcache_raw_collect (regcache, ARM_FPS_REGNUM,
387
                        (char *) &inferior_fp_registers.fpr_fpsr);
388
 
389
  ret = ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
390
                (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
391
 
392
  if (ret < 0)
393
    warning (_("unable to store floating-point registers"));
394
}
395
 
396
static void
397
armnbsd_store_registers (struct regcache *regcache, int regno)
398
{
399
  if (regno >= 0)
400
    {
401
      if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
402
        store_register (regcache, regno);
403
      else
404
        store_fp_register (regcache, regno);
405
    }
406
  else
407
    {
408
      store_regs (regcache);
409
      store_fp_regs (regcache);
410
    }
411
}
412
 
413
struct md_core
414
{
415
  struct reg intreg;
416
  struct fpreg freg;
417
};
418
 
419
static void
420
fetch_core_registers (struct regcache *regcache,
421
                      char *core_reg_sect, unsigned core_reg_size,
422
                      int which, CORE_ADDR ignore)
423
{
424
  struct md_core *core_reg = (struct md_core *) core_reg_sect;
425
  int regno;
426
  CORE_ADDR r_pc;
427
 
428
  arm_supply_gregset (regcache, &core_reg->intreg);
429
  arm_supply_fparegset (regcache, &core_reg->freg);
430
}
431
 
432
static void
433
fetch_elfcore_registers (struct regcache *regcache,
434
                         char *core_reg_sect, unsigned core_reg_size,
435
                         int which, CORE_ADDR ignore)
436
{
437
  struct reg gregset;
438
  struct fpreg fparegset;
439
 
440
  switch (which)
441
    {
442
    case 0:      /* Integer registers.  */
443
      if (core_reg_size != sizeof (struct reg))
444
        warning (_("wrong size of register set in core file"));
445
      else
446
        {
447
          /* The memcpy may be unnecessary, but we can't really be sure
448
             of the alignment of the data in the core file.  */
449
          memcpy (&gregset, core_reg_sect, sizeof (gregset));
450
          arm_supply_gregset (regcache, &gregset);
451
        }
452
      break;
453
 
454
    case 2:
455
      if (core_reg_size != sizeof (struct fpreg))
456
        warning (_("wrong size of FPA register set in core file"));
457
      else
458
        {
459
          /* The memcpy may be unnecessary, but we can't really be sure
460
             of the alignment of the data in the core file.  */
461
          memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
462
          arm_supply_fparegset (regcache, &fparegset);
463
        }
464
      break;
465
 
466
    default:
467
      /* Don't know what kind of register request this is; just ignore it.  */
468
      break;
469
    }
470
}
471
 
472
static struct core_fns arm_netbsd_core_fns =
473
{
474
  bfd_target_unknown_flavour,           /* core_flovour.  */
475
  default_check_format,                 /* check_format.  */
476
  default_core_sniffer,                 /* core_sniffer.  */
477
  fetch_core_registers,                 /* core_read_registers.  */
478
  NULL
479
};
480
 
481
static struct core_fns arm_netbsd_elfcore_fns =
482
{
483
  bfd_target_elf_flavour,               /* core_flovour.  */
484
  default_check_format,                 /* check_format.  */
485
  default_core_sniffer,                 /* core_sniffer.  */
486
  fetch_elfcore_registers,              /* core_read_registers.  */
487
  NULL
488
};
489
 
490
void
491
_initialize_arm_netbsd_nat (void)
492
{
493
  struct target_ops *t;
494
 
495
  t = inf_ptrace_target ();
496
  t->to_fetch_registers = armnbsd_fetch_registers;
497
  t->to_store_registers = armnbsd_store_registers;
498
  add_target (t);
499
 
500
  deprecated_add_core_fns (&arm_netbsd_core_fns);
501
  deprecated_add_core_fns (&arm_netbsd_elfcore_fns);
502
}

powered by: WebSVN 2.1.0

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