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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [armnbsd-nat.c] - Blame information for rev 1773

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

Line No. Rev Author Line
1 1181 sfurman
/* Native-dependent code for BSD Unix running on ARM's, for GDB.
2
   Copyright 1988, 1989, 1991, 1992, 1994, 1996, 1999, 2002
3
   Free Software Foundation, Inc.
4
 
5
   This file is part of GDB.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 2 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 59 Temple Place - Suite 330,
20
   Boston, MA 02111-1307, USA.  */
21
 
22
#include "defs.h"
23
 
24
#ifndef FETCH_INFERIOR_REGISTERS
25
#error Not FETCH_INFERIOR_REGISTERS 
26
#endif /* !FETCH_INFERIOR_REGISTERS */
27
 
28
#include "arm-tdep.h"
29
 
30
#include <sys/types.h>
31
#include <sys/ptrace.h>
32
#include <machine/reg.h>
33
#include <machine/frame.h>
34
#include "inferior.h"
35
#include "regcache.h"
36
#include "gdbcore.h"
37
 
38
extern int arm_apcs_32;
39
 
40
static void
41
supply_gregset (struct reg *gregset)
42
{
43
  int regno;
44
  CORE_ADDR r_pc;
45
 
46
  /* Integer registers.  */
47
  for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
48
    supply_register (regno, (char *) &gregset->r[regno]);
49
 
50
  supply_register (ARM_SP_REGNUM, (char *) &gregset->r_sp);
51
  supply_register (ARM_LR_REGNUM, (char *) &gregset->r_lr);
52
  /* This is ok: we're running native...  */
53
  r_pc = ADDR_BITS_REMOVE (gregset->r_pc);
54
  supply_register (ARM_PC_REGNUM, (char *) &r_pc);
55
 
56
  if (arm_apcs_32)
57
    supply_register (ARM_PS_REGNUM, (char *) &gregset->r_cpsr);
58
  else
59
    supply_register (ARM_PS_REGNUM, (char *) &gregset->r_pc);
60
}
61
 
62
static void
63
supply_fparegset (struct fpreg *fparegset)
64
{
65
  int regno;
66
 
67
  for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
68
    supply_register
69
      (regno, (char *) &fparegset->fpr[regno - ARM_F0_REGNUM]);
70
 
71
  supply_register (ARM_FPS_REGNUM, (char *) &fparegset->fpr_fpsr);
72
}
73
 
74
static void
75
fetch_register (int regno)
76
{
77
  struct reg inferior_registers;
78
  int ret;
79
 
80
  ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
81
                (PTRACE_ARG3_TYPE) &inferior_registers, 0);
82
 
83
  if (ret < 0)
84
    {
85
      warning ("unable to fetch general register");
86
      return;
87
    }
88
 
89
  switch (regno)
90
    {
91
    case ARM_SP_REGNUM:
92
      supply_register (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
93
      break;
94
 
95
    case ARM_LR_REGNUM:
96
      supply_register (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
97
      break;
98
 
99
    case ARM_PC_REGNUM:
100
      /* This is ok: we're running native... */
101
      inferior_registers.r_pc = ADDR_BITS_REMOVE (inferior_registers.r_pc);
102
      supply_register (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
103
      break;
104
 
105
    case ARM_PS_REGNUM:
106
      if (arm_apcs_32)
107
        supply_register (ARM_PS_REGNUM, (char *) &inferior_registers.r_cpsr);
108
      else
109
        supply_register (ARM_PS_REGNUM, (char *) &inferior_registers.r_pc);
110
      break;
111
 
112
    default:
113
      supply_register (regno, (char *) &inferior_registers.r[regno]);
114
      break;
115
    }
116
}
117
 
118
static void
119
fetch_regs (void)
120
{
121
  struct reg inferior_registers;
122
  int ret;
123
  int regno;
124
 
125
  ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
126
                (PTRACE_ARG3_TYPE) &inferior_registers, 0);
127
 
128
  if (ret < 0)
129
    {
130
      warning ("unable to fetch general registers");
131
      return;
132
    }
133
 
134
  supply_gregset (&inferior_registers);
135
}
136
 
137
static void
138
fetch_fp_register (int regno)
139
{
140
  struct fpreg inferior_fp_registers;
141
  int ret;
142
 
143
  ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
144
                (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
145
 
146
  if (ret < 0)
147
    {
148
      warning ("unable to fetch floating-point register");
149
      return;
150
    }
151
 
152
  switch (regno)
153
    {
154
    case ARM_FPS_REGNUM:
155
      supply_register (ARM_FPS_REGNUM,
156
                       (char *) &inferior_fp_registers.fpr_fpsr);
157
      break;
158
 
159
    default:
160
      supply_register
161
        (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
162
      break;
163
    }
164
}
165
 
166
static void
167
fetch_fp_regs (void)
168
{
169
  struct fpreg inferior_fp_registers;
170
  int ret;
171
  int regno;
172
 
173
  ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
174
                (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
175
 
176
  if (ret < 0)
177
    {
178
      warning ("unable to fetch general registers");
179
      return;
180
    }
181
 
182
  supply_fparegset (&inferior_fp_registers);
183
}
184
 
185
void
186
fetch_inferior_registers (int regno)
187
{
188
  if (regno >= 0)
189
    {
190
      if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
191
        fetch_register (regno);
192
      else
193
        fetch_fp_register (regno);
194
    }
195
  else
196
    {
197
      fetch_regs ();
198
      fetch_fp_regs ();
199
    }
200
}
201
 
202
 
203
static void
204
store_register (int regno)
205
{
206
  struct reg inferior_registers;
207
  int ret;
208
 
209
  ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
210
                (PTRACE_ARG3_TYPE) &inferior_registers, 0);
211
 
212
  if (ret < 0)
213
    {
214
      warning ("unable to fetch general registers");
215
      return;
216
    }
217
 
218
  switch (regno)
219
    {
220
    case ARM_SP_REGNUM:
221
      regcache_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
222
      break;
223
 
224
    case ARM_LR_REGNUM:
225
      regcache_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
226
      break;
227
 
228
    case ARM_PC_REGNUM:
229
      if (arm_apcs_32)
230
        regcache_collect (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
231
      else
232
        {
233
          unsigned pc_val;
234
 
235
          regcache_collect (ARM_PC_REGNUM, (char *) &pc_val);
236
 
237
          pc_val = ADDR_BITS_REMOVE (pc_val);
238
          inferior_registers.r_pc
239
            ^= ADDR_BITS_REMOVE (inferior_registers.r_pc);
240
          inferior_registers.r_pc |= pc_val;
241
        }
242
      break;
243
 
244
    case ARM_PS_REGNUM:
245
      if (arm_apcs_32)
246
        regcache_collect (ARM_PS_REGNUM, (char *) &inferior_registers.r_cpsr);
247
      else
248
        {
249
          unsigned psr_val;
250
 
251
          regcache_collect (ARM_PS_REGNUM, (char *) &psr_val);
252
 
253
          psr_val ^= ADDR_BITS_REMOVE (psr_val);
254
          inferior_registers.r_pc = ADDR_BITS_REMOVE (inferior_registers.r_pc);
255
          inferior_registers.r_pc |= psr_val;
256
        }
257
      break;
258
 
259
    default:
260
      regcache_collect (regno, (char *) &inferior_registers.r[regno]);
261
      break;
262
    }
263
 
264
  ret = ptrace (PT_SETREGS, PIDGET (inferior_ptid),
265
                (PTRACE_ARG3_TYPE) &inferior_registers, 0);
266
 
267
  if (ret < 0)
268
    warning ("unable to write register %d to inferior", regno);
269
}
270
 
271
static void
272
store_regs (void)
273
{
274
  struct reg inferior_registers;
275
  int ret;
276
  int regno;
277
 
278
 
279
  for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
280
    regcache_collect (regno, (char *) &inferior_registers.r[regno]);
281
 
282
  regcache_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
283
  regcache_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
284
 
285
  if (arm_apcs_32)
286
    {
287
      regcache_collect (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
288
      regcache_collect (ARM_PS_REGNUM, (char *) &inferior_registers.r_cpsr);
289
    }
290
  else
291
    {
292
      unsigned pc_val;
293
      unsigned psr_val;
294
 
295
      regcache_collect (ARM_PC_REGNUM, (char *) &pc_val);
296
      regcache_collect (ARM_PS_REGNUM, (char *) &psr_val);
297
 
298
      pc_val = ADDR_BITS_REMOVE (pc_val);
299
      psr_val ^= ADDR_BITS_REMOVE (psr_val);
300
 
301
      inferior_registers.r_pc = pc_val | psr_val;
302
    }
303
 
304
  ret = ptrace (PT_SETREGS, PIDGET (inferior_ptid),
305
                (PTRACE_ARG3_TYPE) &inferior_registers, 0);
306
 
307
  if (ret < 0)
308
    warning ("unable to store general registers");
309
}
310
 
311
static void
312
store_fp_register (int regno)
313
{
314
  struct fpreg inferior_fp_registers;
315
  int ret;
316
 
317
  ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
318
                (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
319
 
320
  if (ret < 0)
321
    {
322
      warning ("unable to fetch floating-point registers");
323
      return;
324
    }
325
 
326
  switch (regno)
327
    {
328
    case ARM_FPS_REGNUM:
329
      regcache_collect (ARM_FPS_REGNUM,
330
                        (char *) &inferior_fp_registers.fpr_fpsr);
331
      break;
332
 
333
    default:
334
      regcache_collect
335
        (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
336
      break;
337
    }
338
 
339
  ret = ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
340
                (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
341
 
342
  if (ret < 0)
343
    warning ("unable to write register %d to inferior", regno);
344
}
345
 
346
static void
347
store_fp_regs (void)
348
{
349
  struct fpreg inferior_fp_registers;
350
  int ret;
351
  int regno;
352
 
353
 
354
  for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
355
    regcache_collect
356
      (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
357
 
358
  regcache_collect (ARM_FPS_REGNUM, (char *) &inferior_fp_registers.fpr_fpsr);
359
 
360
  ret = ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
361
                (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
362
 
363
  if (ret < 0)
364
    warning ("unable to store floating-point registers");
365
}
366
 
367
void
368
store_inferior_registers (int regno)
369
{
370
  if (regno >= 0)
371
    {
372
      if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
373
        store_register (regno);
374
      else
375
        store_fp_register (regno);
376
    }
377
  else
378
    {
379
      store_regs ();
380
      store_fp_regs ();
381
    }
382
}
383
 
384
struct md_core
385
{
386
  struct reg intreg;
387
  struct fpreg freg;
388
};
389
 
390
static void
391
fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
392
                      int which, CORE_ADDR ignore)
393
{
394
  struct md_core *core_reg = (struct md_core *) core_reg_sect;
395
  int regno;
396
  CORE_ADDR r_pc;
397
 
398
  supply_gregset (&core_reg->intreg);
399
  supply_fparegset (&core_reg->freg);
400
}
401
 
402
static void
403
fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size,
404
                         int which, CORE_ADDR ignore)
405
{
406
  struct reg gregset;
407
  struct fpreg fparegset;
408
 
409
  switch (which)
410
    {
411
    case 0:      /* Integer registers.  */
412
      if (core_reg_size != sizeof (struct reg))
413
        warning ("wrong size of register set in core file");
414
      else
415
        {
416
          /* The memcpy may be unnecessary, but we can't really be sure
417
             of the alignment of the data in the core file.  */
418
          memcpy (&gregset, core_reg_sect, sizeof (gregset));
419
          supply_gregset (&gregset);
420
        }
421
      break;
422
 
423
    case 2:
424
      if (core_reg_size != sizeof (struct fpreg))
425
        warning ("wrong size of FPA register set in core file");
426
      else
427
        {
428
          /* The memcpy may be unnecessary, but we can't really be sure
429
             of the alignment of the data in the core file.  */
430
          memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
431
          supply_fparegset (&fparegset);
432
        }
433
      break;
434
 
435
    default:
436
      /* Don't know what kind of register request this is; just ignore it.  */
437
      break;
438
    }
439
}
440
 
441
static struct core_fns arm_netbsd_core_fns =
442
{
443
  bfd_target_unknown_flavour,           /* core_flovour.  */
444
  default_check_format,                 /* check_format.  */
445
  default_core_sniffer,                 /* core_sniffer.  */
446
  fetch_core_registers,                 /* core_read_registers.  */
447
  NULL
448
};
449
 
450
static struct core_fns arm_netbsd_elfcore_fns =
451
{
452
  bfd_target_elf_flavour,               /* core_flovour.  */
453
  default_check_format,                 /* check_format.  */
454
  default_core_sniffer,                 /* core_sniffer.  */
455
  fetch_elfcore_registers,              /* core_read_registers.  */
456
  NULL
457
};
458
 
459
void
460
_initialize_arm_netbsd_nat (void)
461
{
462
  add_core_fns (&arm_netbsd_core_fns);
463
  add_core_fns (&arm_netbsd_elfcore_fns);
464
}

powered by: WebSVN 2.1.0

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