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