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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [ppc-linux-nat.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* PPC GNU/Linux native support.
2
   Copyright 1988, 1989, 1991, 1992, 1994, 1996, 2000, 2001, 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
#include "frame.h"
24
#include "inferior.h"
25
#include "gdbcore.h"
26
#include "regcache.h"
27
 
28
#include <sys/types.h>
29
#include <sys/param.h>
30
#include <signal.h>
31
#include <sys/user.h>
32
#include <sys/ioctl.h>
33
#include <sys/wait.h>
34
#include <fcntl.h>
35
#include <sys/procfs.h>
36
#include <sys/ptrace.h>
37
 
38
/* Prototypes for supply_gregset etc. */
39
#include "gregset.h"
40
#include "ppc-tdep.h"
41
 
42
#ifndef PT_READ_U
43
#define PT_READ_U PTRACE_PEEKUSR
44
#endif
45
#ifndef PT_WRITE_U
46
#define PT_WRITE_U PTRACE_POKEUSR
47
#endif
48
 
49
/* Default the type of the ptrace transfer to int.  */
50
#ifndef PTRACE_XFER_TYPE
51
#define PTRACE_XFER_TYPE int
52
#endif
53
 
54
/* Glibc's headers don't define PTRACE_GETVRREGS so we cannot use a
55
   configure time check.  Some older glibc's (for instance 2.2.1)
56
   don't have a specific powerpc version of ptrace.h, and fall back on
57
   a generic one.  In such cases, sys/ptrace.h defines
58
   PTRACE_GETFPXREGS and PTRACE_SETFPXREGS to the same numbers that
59
   ppc kernel's asm/ptrace.h defines PTRACE_GETVRREGS and
60
   PTRACE_SETVRREGS to be.  This also makes a configury check pretty
61
   much useless.  */
62
 
63
/* These definitions should really come from the glibc header files,
64
   but Glibc doesn't know about the vrregs yet.  */
65
#ifndef PTRACE_GETVRREGS
66
#define PTRACE_GETVRREGS 18
67
#define PTRACE_SETVRREGS 19
68
#endif
69
 
70
/* This oddity is because the Linux kernel defines elf_vrregset_t as
71
   an array of 33 16 bytes long elements.  I.e. it leaves out vrsave.
72
   However the PTRACE_GETVRREGS and PTRACE_SETVRREGS requests return
73
   the vrsave as an extra 4 bytes at the end.  I opted for creating a
74
   flat array of chars, so that it is easier to manipulate for gdb.
75
 
76
   There are 32 vector registers 16 bytes longs, plus a VSCR register
77
   which is only 4 bytes long, but is fetched as a 16 bytes
78
   quantity. Up to here we have the elf_vrregset_t structure.
79
   Appended to this there is space for the VRSAVE register: 4 bytes.
80
   Even though this vrsave register is not included in the regset
81
   typedef, it is handled by the ptrace requests.
82
 
83
   Note that GNU/Linux doesn't support little endian PPC hardware,
84
   therefore the offset at which the real value of the VSCR register
85
   is located will be always 12 bytes.
86
 
87
   The layout is like this (where x is the actual value of the vscr reg): */
88
 
89
/* *INDENT-OFF* */
90
/*
91
   |.|.|.|.|.....|.|.|.|.||.|.|.|x||.|
92
   <------->     <-------><-------><->
93
     VR0           VR31     VSCR    VRSAVE
94
*/
95
/* *INDENT-ON* */
96
 
97
#define SIZEOF_VRREGS 33*16+4
98
 
99
typedef char gdb_vrregset_t[SIZEOF_VRREGS];
100
 
101
/* For runtime check of ptrace support for VRREGS.  */
102
int have_ptrace_getvrregs = 1;
103
 
104
int
105
kernel_u_size (void)
106
{
107
  return (sizeof (struct user));
108
}
109
 
110
/* *INDENT-OFF* */
111
/* registers layout, as presented by the ptrace interface:
112
PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5, PT_R6, PT_R7,
113
PT_R8, PT_R9, PT_R10, PT_R11, PT_R12, PT_R13, PT_R14, PT_R15,
114
PT_R16, PT_R17, PT_R18, PT_R19, PT_R20, PT_R21, PT_R22, PT_R23,
115
PT_R24, PT_R25, PT_R26, PT_R27, PT_R28, PT_R29, PT_R30, PT_R31,
116
PT_FPR0, PT_FPR0 + 2, PT_FPR0 + 4, PT_FPR0 + 6, PT_FPR0 + 8, PT_FPR0 + 10, PT_FPR0 + 12, PT_FPR0 + 14,
117
PT_FPR0 + 16, PT_FPR0 + 18, PT_FPR0 + 20, PT_FPR0 + 22, PT_FPR0 + 24, PT_FPR0 + 26, PT_FPR0 + 28, PT_FPR0 + 30,
118
PT_FPR0 + 32, PT_FPR0 + 34, PT_FPR0 + 36, PT_FPR0 + 38, PT_FPR0 + 40, PT_FPR0 + 42, PT_FPR0 + 44, PT_FPR0 + 46,
119
PT_FPR0 + 48, PT_FPR0 + 50, PT_FPR0 + 52, PT_FPR0 + 54, PT_FPR0 + 56, PT_FPR0 + 58, PT_FPR0 + 60, PT_FPR0 + 62,
120
PT_NIP, PT_MSR, PT_CCR, PT_LNK, PT_CTR, PT_XER, PT_MQ */
121
/* *INDENT_ON * */
122
 
123
static int
124
ppc_register_u_addr (int regno)
125
{
126
  int u_addr = -1;
127
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
128
 
129
  /* General purpose registers occupy 1 slot each in the buffer */
130
  if (regno >= tdep->ppc_gp0_regnum && regno <= tdep->ppc_gplast_regnum )
131
    u_addr =  ((PT_R0 + regno) * 4);
132
 
133
  /* Floating point regs: 2 slots each */
134
  if (regno >= FP0_REGNUM && regno <= FPLAST_REGNUM)
135
    u_addr = ((PT_FPR0 + (regno - FP0_REGNUM) * 2) * 4);
136
 
137
  /* UISA special purpose registers: 1 slot each */
138
  if (regno == PC_REGNUM)
139
    u_addr = PT_NIP * 4;
140
  if (regno == tdep->ppc_lr_regnum)
141
    u_addr = PT_LNK * 4;
142
  if (regno == tdep->ppc_cr_regnum)
143
    u_addr = PT_CCR * 4;
144
  if (regno == tdep->ppc_xer_regnum)
145
    u_addr = PT_XER * 4;
146
  if (regno == tdep->ppc_ctr_regnum)
147
    u_addr = PT_CTR * 4;
148
  if (regno == tdep->ppc_mq_regnum)
149
    u_addr = PT_MQ * 4;
150
  if (regno == tdep->ppc_ps_regnum)
151
    u_addr = PT_MSR * 4;
152
  if (regno == tdep->ppc_fpscr_regnum)
153
    u_addr = PT_FPSCR * 4;
154
 
155
  return u_addr;
156
}
157
 
158
static int
159
ppc_ptrace_cannot_fetch_store_register (int regno)
160
{
161
  return (ppc_register_u_addr (regno) == -1);
162
}
163
 
164
/* The Linux kernel ptrace interface for AltiVec registers uses the
165
   registers set mechanism, as opposed to the interface for all the
166
   other registers, that stores/fetches each register individually.  */
167
static void
168
fetch_altivec_register (int tid, int regno)
169
{
170
  int ret;
171
  int offset = 0;
172
  gdb_vrregset_t regs;
173
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
174
  int vrregsize = REGISTER_RAW_SIZE (tdep->ppc_vr0_regnum);
175
 
176
  ret = ptrace (PTRACE_GETVRREGS, tid, 0, &regs);
177
  if (ret < 0)
178
    {
179
      if (errno == EIO)
180
        {
181
          have_ptrace_getvrregs = 0;
182
          return;
183
        }
184
      perror_with_name ("Unable to fetch AltiVec register");
185
    }
186
 
187
  /* VSCR is fetched as a 16 bytes quantity, but it is really 4 bytes
188
     long on the hardware.  We deal only with the lower 4 bytes of the
189
     vector.  VRSAVE is at the end of the array in a 4 bytes slot, so
190
     there is no need to define an offset for it.  */
191
  if (regno == (tdep->ppc_vrsave_regnum - 1))
192
    offset = vrregsize - REGISTER_RAW_SIZE (tdep->ppc_vrsave_regnum);
193
 
194
  supply_register (regno,
195
                   regs + (regno - tdep->ppc_vr0_regnum) * vrregsize + offset);
196
}
197
 
198
static void
199
fetch_register (int tid, int regno)
200
{
201
  /* This isn't really an address.  But ptrace thinks of it as one.  */
202
  char mess[128];              /* For messages */
203
  register int i;
204
  unsigned int offset;         /* Offset of registers within the u area. */
205
  char *buf = alloca (MAX_REGISTER_RAW_SIZE);
206
  CORE_ADDR regaddr = ppc_register_u_addr (regno);
207
 
208
  if (altivec_register_p (regno))
209
    {
210
      /* If this is the first time through, or if it is not the first
211
         time through, and we have comfirmed that there is kernel
212
         support for such a ptrace request, then go and fetch the
213
         register.  */
214
      if (have_ptrace_getvrregs)
215
       {
216
         fetch_altivec_register (tid, regno);
217
         return;
218
       }
219
     /* If we have discovered that there is no ptrace support for
220
        AltiVec registers, fall through and return zeroes, because
221
        regaddr will be -1 in this case.  */
222
    }
223
 
224
  if (regaddr == -1)
225
    {
226
      memset (buf, '\0', REGISTER_RAW_SIZE (regno));   /* Supply zeroes */
227
      supply_register (regno, buf);
228
      return;
229
    }
230
 
231
  for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
232
    {
233
      errno = 0;
234
      *(PTRACE_XFER_TYPE *) & buf[i] = ptrace (PT_READ_U, tid,
235
                                               (PTRACE_ARG3_TYPE) regaddr, 0);
236
      regaddr += sizeof (PTRACE_XFER_TYPE);
237
      if (errno != 0)
238
        {
239
          sprintf (mess, "reading register %s (#%d)",
240
                   REGISTER_NAME (regno), regno);
241
          perror_with_name (mess);
242
        }
243
    }
244
  supply_register (regno, buf);
245
}
246
 
247
static void
248
supply_vrregset (gdb_vrregset_t *vrregsetp)
249
{
250
  int i;
251
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
252
  int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1;
253
  int vrregsize = REGISTER_RAW_SIZE (tdep->ppc_vr0_regnum);
254
  int offset = vrregsize - REGISTER_RAW_SIZE (tdep->ppc_vrsave_regnum);
255
 
256
  for (i = 0; i < num_of_vrregs; i++)
257
    {
258
      /* The last 2 registers of this set are only 32 bit long, not
259
         128.  However an offset is necessary only for VSCR because it
260
         occupies a whole vector, while VRSAVE occupies a full 4 bytes
261
         slot.  */
262
      if (i == (num_of_vrregs - 2))
263
        supply_register (tdep->ppc_vr0_regnum + i,
264
                         *vrregsetp + i * vrregsize + offset);
265
      else
266
        supply_register (tdep->ppc_vr0_regnum + i, *vrregsetp + i * vrregsize);
267
    }
268
}
269
 
270
static void
271
fetch_altivec_registers (int tid)
272
{
273
  int ret;
274
  gdb_vrregset_t regs;
275
 
276
  ret = ptrace (PTRACE_GETVRREGS, tid, 0, &regs);
277
  if (ret < 0)
278
    {
279
      if (errno == EIO)
280
        {
281
          have_ptrace_getvrregs = 0;
282
          return;
283
        }
284
      perror_with_name ("Unable to fetch AltiVec registers");
285
    }
286
  supply_vrregset (&regs);
287
}
288
 
289
static void
290
fetch_ppc_registers (int tid)
291
{
292
  int i;
293
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
294
 
295
  for (i = 0; i <= tdep->ppc_fpscr_regnum; i++)
296
    fetch_register (tid, i);
297
  if (tdep->ppc_mq_regnum != -1)
298
    fetch_register (tid, tdep->ppc_mq_regnum);
299
  if (have_ptrace_getvrregs)
300
    if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
301
      fetch_altivec_registers (tid);
302
}
303
 
304
/* Fetch registers from the child process.  Fetch all registers if
305
   regno == -1, otherwise fetch all general registers or all floating
306
   point registers depending upon the value of regno.  */
307
void
308
fetch_inferior_registers (int regno)
309
{
310
  /* Overload thread id onto process id */
311
  int tid = TIDGET (inferior_ptid);
312
 
313
  /* No thread id, just use process id */
314
  if (tid == 0)
315
    tid = PIDGET (inferior_ptid);
316
 
317
  if (regno == -1)
318
    fetch_ppc_registers (tid);
319
  else
320
    fetch_register (tid, regno);
321
}
322
 
323
/* Store one register. */
324
static void
325
store_altivec_register (int tid, int regno)
326
{
327
  int ret;
328
  int offset = 0;
329
  gdb_vrregset_t regs;
330
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
331
  int vrregsize = REGISTER_RAW_SIZE (tdep->ppc_vr0_regnum);
332
 
333
  ret = ptrace (PTRACE_GETVRREGS, tid, 0, &regs);
334
  if (ret < 0)
335
    {
336
      if (errno == EIO)
337
        {
338
          have_ptrace_getvrregs = 0;
339
          return;
340
        }
341
      perror_with_name ("Unable to fetch AltiVec register");
342
    }
343
 
344
  /* VSCR is fetched as a 16 bytes quantity, but it is really 4 bytes
345
     long on the hardware.  */
346
  if (regno == (tdep->ppc_vrsave_regnum - 1))
347
    offset = vrregsize - REGISTER_RAW_SIZE (tdep->ppc_vrsave_regnum);
348
 
349
  regcache_collect (regno,
350
                    regs + (regno - tdep->ppc_vr0_regnum) * vrregsize + offset);
351
 
352
  ret = ptrace (PTRACE_SETVRREGS, tid, 0, &regs);
353
  if (ret < 0)
354
    perror_with_name ("Unable to store AltiVec register");
355
}
356
 
357
static void
358
store_register (int tid, int regno)
359
{
360
  /* This isn't really an address.  But ptrace thinks of it as one.  */
361
  CORE_ADDR regaddr = ppc_register_u_addr (regno);
362
  char mess[128];              /* For messages */
363
  register int i;
364
  unsigned int offset;         /* Offset of registers within the u area.  */
365
  char *buf = alloca (MAX_REGISTER_RAW_SIZE);
366
 
367
  if (altivec_register_p (regno))
368
    {
369
      store_altivec_register (tid, regno);
370
      return;
371
    }
372
 
373
  if (regaddr == -1)
374
    return;
375
 
376
  regcache_collect (regno, buf);
377
  for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
378
    {
379
      errno = 0;
380
      ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr,
381
              *(PTRACE_XFER_TYPE *) & buf[i]);
382
      regaddr += sizeof (PTRACE_XFER_TYPE);
383
 
384
      if (errno == EIO
385
          && regno == gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum)
386
        {
387
          /* Some older kernel versions don't allow fpscr to be written.  */
388
          continue;
389
        }
390
 
391
      if (errno != 0)
392
        {
393
          sprintf (mess, "writing register %s (#%d)",
394
                   REGISTER_NAME (regno), regno);
395
          perror_with_name (mess);
396
        }
397
    }
398
}
399
 
400
static void
401
fill_vrregset (gdb_vrregset_t *vrregsetp)
402
{
403
  int i;
404
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
405
  int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1;
406
  int vrregsize = REGISTER_RAW_SIZE (tdep->ppc_vr0_regnum);
407
  int offset = vrregsize - REGISTER_RAW_SIZE (tdep->ppc_vrsave_regnum);
408
 
409
  for (i = 0; i < num_of_vrregs; i++)
410
    {
411
      /* The last 2 registers of this set are only 32 bit long, not
412
         128, but only VSCR is fetched as a 16 bytes quantity.  */
413
      if (i == (num_of_vrregs - 2))
414
        regcache_collect (tdep->ppc_vr0_regnum + i,
415
                          *vrregsetp + i * vrregsize + offset);
416
      else
417
        regcache_collect (tdep->ppc_vr0_regnum + i, *vrregsetp + i * vrregsize);
418
    }
419
}
420
 
421
static void
422
store_altivec_registers (int tid)
423
{
424
  int ret;
425
  gdb_vrregset_t regs;
426
 
427
  ret = ptrace (PTRACE_GETVRREGS, tid, 0, (int) &regs);
428
  if (ret < 0)
429
    {
430
      if (errno == EIO)
431
        {
432
          have_ptrace_getvrregs = 0;
433
          return;
434
        }
435
      perror_with_name ("Couldn't get AltiVec registers");
436
    }
437
 
438
  fill_vrregset (&regs);
439
 
440
  if (ptrace (PTRACE_SETVRREGS, tid, 0, (int) &regs) < 0)
441
    perror_with_name ("Couldn't write AltiVec registers");
442
}
443
 
444
static void
445
store_ppc_registers (int tid)
446
{
447
  int i;
448
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
449
 
450
  for (i = 0; i <= tdep->ppc_fpscr_regnum; i++)
451
    store_register (tid, i);
452
  if (tdep->ppc_mq_regnum != -1)
453
    store_register (tid, tdep->ppc_mq_regnum);
454
  if (have_ptrace_getvrregs)
455
    if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
456
      store_altivec_registers (tid);
457
}
458
 
459
void
460
store_inferior_registers (int regno)
461
{
462
  /* Overload thread id onto process id */
463
  int tid = TIDGET (inferior_ptid);
464
 
465
  /* No thread id, just use process id */
466
  if (tid == 0)
467
    tid = PIDGET (inferior_ptid);
468
 
469
  if (regno >= 0)
470
    store_register (tid, regno);
471
  else
472
    store_ppc_registers (tid);
473
}
474
 
475
void
476
supply_gregset (gdb_gregset_t *gregsetp)
477
{
478
  ppc_linux_supply_gregset ((char *) gregsetp);
479
}
480
 
481
void
482
fill_gregset (gdb_gregset_t *gregsetp, int regno)
483
{
484
  int regi;
485
  elf_greg_t *regp = (elf_greg_t *) gregsetp;
486
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
487
 
488
  for (regi = 0; regi < 32; regi++)
489
    {
490
      if ((regno == -1) || regno == regi)
491
        regcache_collect (regi, regp + PT_R0 + regi);
492
    }
493
 
494
  if ((regno == -1) || regno == PC_REGNUM)
495
    regcache_collect (PC_REGNUM, regp + PT_NIP);
496
  if ((regno == -1) || regno == tdep->ppc_lr_regnum)
497
    regcache_collect (tdep->ppc_lr_regnum, regp + PT_LNK);
498
  if ((regno == -1) || regno == tdep->ppc_cr_regnum)
499
    regcache_collect (tdep->ppc_cr_regnum, regp + PT_CCR);
500
  if ((regno == -1) || regno == tdep->ppc_xer_regnum)
501
    regcache_collect (tdep->ppc_xer_regnum, regp + PT_XER);
502
  if ((regno == -1) || regno == tdep->ppc_ctr_regnum)
503
    regcache_collect (tdep->ppc_ctr_regnum, regp + PT_CTR);
504
  if (((regno == -1) || regno == tdep->ppc_mq_regnum)
505
      && (tdep->ppc_mq_regnum != -1))
506
    regcache_collect (tdep->ppc_mq_regnum, regp + PT_MQ);
507
  if ((regno == -1) || regno == tdep->ppc_ps_regnum)
508
    regcache_collect (tdep->ppc_ps_regnum, regp + PT_MSR);
509
}
510
 
511
void
512
supply_fpregset (gdb_fpregset_t * fpregsetp)
513
{
514
  ppc_linux_supply_fpregset ((char *) fpregsetp);
515
}
516
 
517
/* Given a pointer to a floating point register set in /proc format
518
   (fpregset_t *), update the register specified by REGNO from gdb's
519
   idea of the current floating point register set.  If REGNO is -1,
520
   update them all.  */
521
void
522
fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
523
{
524
  int regi;
525
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
526
 
527
  for (regi = 0; regi < 32; regi++)
528
    {
529
      if ((regno == -1) || (regno == FP0_REGNUM + regi))
530
        regcache_collect (FP0_REGNUM + regi, (char *) (*fpregsetp + regi));
531
    }
532
  if ((regno == -1) || regno == tdep->ppc_fpscr_regnum)
533
    regcache_collect (tdep->ppc_fpscr_regnum, (char *) (*fpregsetp + regi));
534
}

powered by: WebSVN 2.1.0

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