2002-12-05 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"
23#include "frame.h"
24#include "inferior.h"
25#include "gdbcore.h"
4e052eda 26#include "regcache.h"
c877c8e6
KB
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>
45229ea4 36#include <sys/ptrace.h>
c877c8e6 37
c60c0f5f
MS
38/* Prototypes for supply_gregset etc. */
39#include "gregset.h"
16333c4f 40#include "ppc-tdep.h"
c60c0f5f 41
45229ea4
EZ
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
9abe5450
EZ
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
99typedef char gdb_vrregset_t[SIZEOF_VRREGS];
100
101/* For runtime check of ptrace support for VRREGS. */
102int have_ptrace_getvrregs = 1;
103
c877c8e6 104int
fba45db2 105kernel_u_size (void)
c877c8e6
KB
106{
107 return (sizeof (struct user));
108}
109
16333c4f
EZ
110/* *INDENT-OFF* */
111/* registers layout, as presented by the ptrace interface:
112PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5, PT_R6, PT_R7,
113PT_R8, PT_R9, PT_R10, PT_R11, PT_R12, PT_R13, PT_R14, PT_R15,
114PT_R16, PT_R17, PT_R18, PT_R19, PT_R20, PT_R21, PT_R22, PT_R23,
115PT_R24, PT_R25, PT_R26, PT_R27, PT_R28, PT_R29, PT_R30, PT_R31,
116PT_FPR0, PT_FPR0 + 2, PT_FPR0 + 4, PT_FPR0 + 6, PT_FPR0 + 8, PT_FPR0 + 10, PT_FPR0 + 12, PT_FPR0 + 14,
117PT_FPR0 + 16, PT_FPR0 + 18, PT_FPR0 + 20, PT_FPR0 + 22, PT_FPR0 + 24, PT_FPR0 + 26, PT_FPR0 + 28, PT_FPR0 + 30,
118PT_FPR0 + 32, PT_FPR0 + 34, PT_FPR0 + 36, PT_FPR0 + 38, PT_FPR0 + 40, PT_FPR0 + 42, PT_FPR0 + 44, PT_FPR0 + 46,
119PT_FPR0 + 48, PT_FPR0 + 50, PT_FPR0 + 52, PT_FPR0 + 54, PT_FPR0 + 56, PT_FPR0 + 58, PT_FPR0 + 60, PT_FPR0 + 62,
120PT_NIP, PT_MSR, PT_CCR, PT_LNK, PT_CTR, PT_XER, PT_MQ */
121/* *INDENT_ON * */
c877c8e6 122
45229ea4
EZ
123static int
124ppc_register_u_addr (int regno)
c877c8e6 125{
16333c4f 126 int u_addr = -1;
dc5cfeb6 127 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
16333c4f
EZ
128
129 /* General purpose registers occupy 1 slot each in the buffer */
dc5cfeb6 130 if (regno >= tdep->ppc_gp0_regnum && regno <= tdep->ppc_gplast_regnum )
45229ea4 131 u_addr = ((PT_R0 + regno) * 4);
16333c4f
EZ
132
133 /* Floating point regs: 2 slots each */
134 if (regno >= FP0_REGNUM && regno <= FPLAST_REGNUM)
45229ea4 135 u_addr = ((PT_FPR0 + (regno - FP0_REGNUM) * 2) * 4);
16333c4f
EZ
136
137 /* UISA special purpose registers: 1 slot each */
138 if (regno == PC_REGNUM)
45229ea4 139 u_addr = PT_NIP * 4;
dc5cfeb6 140 if (regno == tdep->ppc_lr_regnum)
45229ea4 141 u_addr = PT_LNK * 4;
dc5cfeb6 142 if (regno == tdep->ppc_cr_regnum)
45229ea4 143 u_addr = PT_CCR * 4;
dc5cfeb6 144 if (regno == tdep->ppc_xer_regnum)
45229ea4 145 u_addr = PT_XER * 4;
dc5cfeb6 146 if (regno == tdep->ppc_ctr_regnum)
45229ea4 147 u_addr = PT_CTR * 4;
dc5cfeb6 148 if (regno == tdep->ppc_mq_regnum)
45229ea4 149 u_addr = PT_MQ * 4;
dc5cfeb6 150 if (regno == tdep->ppc_ps_regnum)
45229ea4 151 u_addr = PT_MSR * 4;
e3f36dbd
KB
152 if (regno == tdep->ppc_fpscr_regnum)
153 u_addr = PT_FPSCR * 4;
16333c4f
EZ
154
155 return u_addr;
c877c8e6
KB
156}
157
45229ea4
EZ
158static int
159ppc_ptrace_cannot_fetch_store_register (int regno)
160{
161 return (ppc_register_u_addr (regno) == -1);
162}
163
9abe5450
EZ
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. */
167static void
168fetch_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
45229ea4 198static void
05f13b9c 199fetch_register (int tid, int regno)
45229ea4
EZ
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);
45229ea4
EZ
206 CORE_ADDR regaddr = ppc_register_u_addr (regno);
207
9abe5450
EZ
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
45229ea4
EZ
224 if (regaddr == -1)
225 {
226 memset (buf, '\0', REGISTER_RAW_SIZE (regno)); /* Supply zeroes */
227 supply_register (regno, buf);
228 return;
229 }
230
45229ea4
EZ
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
9abe5450
EZ
247static void
248supply_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
270static void
271fetch_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
45229ea4 289static void
05f13b9c 290fetch_ppc_registers (int tid)
45229ea4
EZ
291{
292 int i;
9abe5450
EZ
293 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
294
e3f36dbd 295 for (i = 0; i <= tdep->ppc_fpscr_regnum; i++)
05f13b9c 296 fetch_register (tid, i);
e3f36dbd
KB
297 if (tdep->ppc_mq_regnum != -1)
298 fetch_register (tid, tdep->ppc_mq_regnum);
9abe5450
EZ
299 if (have_ptrace_getvrregs)
300 if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
301 fetch_altivec_registers (tid);
45229ea4
EZ
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. */
307void
308fetch_inferior_registers (int regno)
309{
9abe5450 310 /* Overload thread id onto process id */
05f13b9c
EZ
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
9abe5450 317 if (regno == -1)
05f13b9c 318 fetch_ppc_registers (tid);
45229ea4 319 else
05f13b9c 320 fetch_register (tid, regno);
45229ea4
EZ
321}
322
323/* Store one register. */
9abe5450
EZ
324static void
325store_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
45229ea4 357static void
05f13b9c 358store_register (int tid, int regno)
45229ea4
EZ
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. */
45229ea4
EZ
365 char *buf = alloca (MAX_REGISTER_RAW_SIZE);
366
9abe5450 367 if (altivec_register_p (regno))
45229ea4 368 {
9abe5450 369 store_altivec_register (tid, regno);
45229ea4
EZ
370 return;
371 }
372
9abe5450
EZ
373 if (regaddr == -1)
374 return;
375
45229ea4
EZ
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);
e3f36dbd
KB
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
45229ea4
EZ
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
9abe5450
EZ
400static void
401fill_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
421static void
422store_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
45229ea4 444static void
05f13b9c 445store_ppc_registers (int tid)
45229ea4
EZ
446{
447 int i;
9abe5450 448 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
45229ea4 449
e3f36dbd 450 for (i = 0; i <= tdep->ppc_fpscr_regnum; i++)
05f13b9c 451 store_register (tid, i);
e3f36dbd
KB
452 if (tdep->ppc_mq_regnum != -1)
453 store_register (tid, tdep->ppc_mq_regnum);
9abe5450
EZ
454 if (have_ptrace_getvrregs)
455 if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
456 store_altivec_registers (tid);
45229ea4
EZ
457}
458
459void
460store_inferior_registers (int regno)
461{
05f13b9c
EZ
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
45229ea4 469 if (regno >= 0)
05f13b9c 470 store_register (tid, regno);
45229ea4 471 else
05f13b9c 472 store_ppc_registers (tid);
45229ea4
EZ
473}
474
50c9bd31 475void
8ae45c11 476supply_gregset (gdb_gregset_t *gregsetp)
c877c8e6 477{
2fda4977 478 ppc_linux_supply_gregset ((char *) gregsetp);
c877c8e6
KB
479}
480
fdb28ac4 481void
8ae45c11 482fill_gregset (gdb_gregset_t *gregsetp, int regno)
fdb28ac4
KB
483{
484 int regi;
2ac44c70 485 elf_greg_t *regp = (elf_greg_t *) gregsetp;
dc5cfeb6 486 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
fdb28ac4 487
fdb28ac4
KB
488 for (regi = 0; regi < 32; regi++)
489 {
16333c4f
EZ
490 if ((regno == -1) || regno == regi)
491 regcache_collect (regi, regp + PT_R0 + regi);
fdb28ac4
KB
492 }
493
16333c4f
EZ
494 if ((regno == -1) || regno == PC_REGNUM)
495 regcache_collect (PC_REGNUM, regp + PT_NIP);
05f13b9c 496 if ((regno == -1) || regno == tdep->ppc_lr_regnum)
dc5cfeb6 497 regcache_collect (tdep->ppc_lr_regnum, regp + PT_LNK);
05f13b9c 498 if ((regno == -1) || regno == tdep->ppc_cr_regnum)
dc5cfeb6 499 regcache_collect (tdep->ppc_cr_regnum, regp + PT_CCR);
05f13b9c 500 if ((regno == -1) || regno == tdep->ppc_xer_regnum)
dc5cfeb6 501 regcache_collect (tdep->ppc_xer_regnum, regp + PT_XER);
05f13b9c 502 if ((regno == -1) || regno == tdep->ppc_ctr_regnum)
dc5cfeb6 503 regcache_collect (tdep->ppc_ctr_regnum, regp + PT_CTR);
e3f36dbd
KB
504 if (((regno == -1) || regno == tdep->ppc_mq_regnum)
505 && (tdep->ppc_mq_regnum != -1))
dc5cfeb6 506 regcache_collect (tdep->ppc_mq_regnum, regp + PT_MQ);
05f13b9c 507 if ((regno == -1) || regno == tdep->ppc_ps_regnum)
dc5cfeb6 508 regcache_collect (tdep->ppc_ps_regnum, regp + PT_MSR);
fdb28ac4
KB
509}
510
50c9bd31 511void
8ae45c11 512supply_fpregset (gdb_fpregset_t * fpregsetp)
c877c8e6 513{
2fda4977 514 ppc_linux_supply_fpregset ((char *) fpregsetp);
c877c8e6 515}
fdb28ac4 516
9abe5450
EZ
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. */
fdb28ac4 521void
8ae45c11 522fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
fdb28ac4
KB
523{
524 int regi;
e3f36dbd 525 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
fdb28ac4
KB
526
527 for (regi = 0; regi < 32; regi++)
528 {
529 if ((regno == -1) || (regno == FP0_REGNUM + regi))
f00d3753 530 regcache_collect (FP0_REGNUM + regi, (char *) (*fpregsetp + regi));
fdb28ac4 531 }
e3f36dbd
KB
532 if ((regno == -1) || regno == tdep->ppc_fpscr_regnum)
533 regcache_collect (tdep->ppc_fpscr_regnum, (char *) (*fpregsetp + regi));
fdb28ac4 534}
This page took 0.268823 seconds and 4 git commands to generate.