]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/gdbserver/linux-ppc-low.c
2011-01-05 Michael Snyder <msnyder@msnyder-server.eng.vmware.com>
[thirdparty/binutils-gdb.git] / gdb / gdbserver / linux-ppc-low.c
1 /* GNU/Linux/PowerPC specific low level interface, for the remote server for
2 GDB.
3 Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2005, 2007, 2008,
4 2009, 2010, 2011 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 "server.h"
22 #include "linux-low.h"
23
24 #include <elf.h>
25 #include <asm/ptrace.h>
26
27 /* These are in <asm/cputable.h> in current kernels. */
28 #define PPC_FEATURE_HAS_VSX 0x00000080
29 #define PPC_FEATURE_HAS_ALTIVEC 0x10000000
30 #define PPC_FEATURE_HAS_SPE 0x00800000
31 #define PPC_FEATURE_CELL 0x00010000
32 #define PPC_FEATURE_HAS_DFP 0x00000400
33
34 static unsigned long ppc_hwcap;
35
36
37 /* Defined in auto-generated file powerpc-32l.c. */
38 void init_registers_powerpc_32l (void);
39 /* Defined in auto-generated file powerpc-altivec32l.c. */
40 void init_registers_powerpc_altivec32l (void);
41 /* Defined in auto-generated file powerpc-cell32l.c. */
42 void init_registers_powerpc_cell32l (void);
43 /* Defined in auto-generated file powerpc-vsx32l.c. */
44 void init_registers_powerpc_vsx32l (void);
45 /* Defined in auto-generated file powerpc-isa205-32l.c. */
46 void init_registers_powerpc_isa205_32l (void);
47 /* Defined in auto-generated file powerpc-isa205-altivec32l.c. */
48 void init_registers_powerpc_isa205_altivec32l (void);
49 /* Defined in auto-generated file powerpc-isa205-vsx32l.c. */
50 void init_registers_powerpc_isa205_vsx32l (void);
51 /* Defined in auto-generated file powerpc-e500l.c. */
52 void init_registers_powerpc_e500l (void);
53 /* Defined in auto-generated file powerpc-64l.c. */
54 void init_registers_powerpc_64l (void);
55 /* Defined in auto-generated file powerpc-altivec64l.c. */
56 void init_registers_powerpc_altivec64l (void);
57 /* Defined in auto-generated file powerpc-cell64l.c. */
58 void init_registers_powerpc_cell64l (void);
59 /* Defined in auto-generated file powerpc-vsx64l.c. */
60 void init_registers_powerpc_vsx64l (void);
61 /* Defined in auto-generated file powerpc-isa205-64l.c. */
62 void init_registers_powerpc_isa205_64l (void);
63 /* Defined in auto-generated file powerpc-isa205-altivec64l.c. */
64 void init_registers_powerpc_isa205_altivec64l (void);
65 /* Defined in auto-generated file powerpc-isa205-vsx64l.c. */
66 void init_registers_powerpc_isa205_vsx64l (void);
67
68 #define ppc_num_regs 73
69
70 /* This sometimes isn't defined. */
71 #ifndef PT_ORIG_R3
72 #define PT_ORIG_R3 34
73 #endif
74 #ifndef PT_TRAP
75 #define PT_TRAP 40
76 #endif
77
78 #ifdef __powerpc64__
79 /* We use a constant for FPSCR instead of PT_FPSCR, because
80 many shipped PPC64 kernels had the wrong value in ptrace.h. */
81 static int ppc_regmap[] =
82 {PT_R0 * 8, PT_R1 * 8, PT_R2 * 8, PT_R3 * 8,
83 PT_R4 * 8, PT_R5 * 8, PT_R6 * 8, PT_R7 * 8,
84 PT_R8 * 8, PT_R9 * 8, PT_R10 * 8, PT_R11 * 8,
85 PT_R12 * 8, PT_R13 * 8, PT_R14 * 8, PT_R15 * 8,
86 PT_R16 * 8, PT_R17 * 8, PT_R18 * 8, PT_R19 * 8,
87 PT_R20 * 8, PT_R21 * 8, PT_R22 * 8, PT_R23 * 8,
88 PT_R24 * 8, PT_R25 * 8, PT_R26 * 8, PT_R27 * 8,
89 PT_R28 * 8, PT_R29 * 8, PT_R30 * 8, PT_R31 * 8,
90 PT_FPR0*8, PT_FPR0*8 + 8, PT_FPR0*8+16, PT_FPR0*8+24,
91 PT_FPR0*8+32, PT_FPR0*8+40, PT_FPR0*8+48, PT_FPR0*8+56,
92 PT_FPR0*8+64, PT_FPR0*8+72, PT_FPR0*8+80, PT_FPR0*8+88,
93 PT_FPR0*8+96, PT_FPR0*8+104, PT_FPR0*8+112, PT_FPR0*8+120,
94 PT_FPR0*8+128, PT_FPR0*8+136, PT_FPR0*8+144, PT_FPR0*8+152,
95 PT_FPR0*8+160, PT_FPR0*8+168, PT_FPR0*8+176, PT_FPR0*8+184,
96 PT_FPR0*8+192, PT_FPR0*8+200, PT_FPR0*8+208, PT_FPR0*8+216,
97 PT_FPR0*8+224, PT_FPR0*8+232, PT_FPR0*8+240, PT_FPR0*8+248,
98 PT_NIP * 8, PT_MSR * 8, PT_CCR * 8, PT_LNK * 8,
99 PT_CTR * 8, PT_XER * 8, PT_FPR0*8 + 256,
100 PT_ORIG_R3 * 8, PT_TRAP * 8 };
101 #else
102 /* Currently, don't check/send MQ. */
103 static int ppc_regmap[] =
104 {PT_R0 * 4, PT_R1 * 4, PT_R2 * 4, PT_R3 * 4,
105 PT_R4 * 4, PT_R5 * 4, PT_R6 * 4, PT_R7 * 4,
106 PT_R8 * 4, PT_R9 * 4, PT_R10 * 4, PT_R11 * 4,
107 PT_R12 * 4, PT_R13 * 4, PT_R14 * 4, PT_R15 * 4,
108 PT_R16 * 4, PT_R17 * 4, PT_R18 * 4, PT_R19 * 4,
109 PT_R20 * 4, PT_R21 * 4, PT_R22 * 4, PT_R23 * 4,
110 PT_R24 * 4, PT_R25 * 4, PT_R26 * 4, PT_R27 * 4,
111 PT_R28 * 4, PT_R29 * 4, PT_R30 * 4, PT_R31 * 4,
112 PT_FPR0*4, PT_FPR0*4 + 8, PT_FPR0*4+16, PT_FPR0*4+24,
113 PT_FPR0*4+32, PT_FPR0*4+40, PT_FPR0*4+48, PT_FPR0*4+56,
114 PT_FPR0*4+64, PT_FPR0*4+72, PT_FPR0*4+80, PT_FPR0*4+88,
115 PT_FPR0*4+96, PT_FPR0*4+104, PT_FPR0*4+112, PT_FPR0*4+120,
116 PT_FPR0*4+128, PT_FPR0*4+136, PT_FPR0*4+144, PT_FPR0*4+152,
117 PT_FPR0*4+160, PT_FPR0*4+168, PT_FPR0*4+176, PT_FPR0*4+184,
118 PT_FPR0*4+192, PT_FPR0*4+200, PT_FPR0*4+208, PT_FPR0*4+216,
119 PT_FPR0*4+224, PT_FPR0*4+232, PT_FPR0*4+240, PT_FPR0*4+248,
120 PT_NIP * 4, PT_MSR * 4, PT_CCR * 4, PT_LNK * 4,
121 PT_CTR * 4, PT_XER * 4, PT_FPSCR * 4,
122 PT_ORIG_R3 * 4, PT_TRAP * 4
123 };
124
125 static int ppc_regmap_e500[] =
126 {PT_R0 * 4, PT_R1 * 4, PT_R2 * 4, PT_R3 * 4,
127 PT_R4 * 4, PT_R5 * 4, PT_R6 * 4, PT_R7 * 4,
128 PT_R8 * 4, PT_R9 * 4, PT_R10 * 4, PT_R11 * 4,
129 PT_R12 * 4, PT_R13 * 4, PT_R14 * 4, PT_R15 * 4,
130 PT_R16 * 4, PT_R17 * 4, PT_R18 * 4, PT_R19 * 4,
131 PT_R20 * 4, PT_R21 * 4, PT_R22 * 4, PT_R23 * 4,
132 PT_R24 * 4, PT_R25 * 4, PT_R26 * 4, PT_R27 * 4,
133 PT_R28 * 4, PT_R29 * 4, PT_R30 * 4, PT_R31 * 4,
134 -1, -1, -1, -1,
135 -1, -1, -1, -1,
136 -1, -1, -1, -1,
137 -1, -1, -1, -1,
138 -1, -1, -1, -1,
139 -1, -1, -1, -1,
140 -1, -1, -1, -1,
141 -1, -1, -1, -1,
142 PT_NIP * 4, PT_MSR * 4, PT_CCR * 4, PT_LNK * 4,
143 PT_CTR * 4, PT_XER * 4, -1,
144 PT_ORIG_R3 * 4, PT_TRAP * 4
145 };
146 #endif
147
148 static int
149 ppc_cannot_store_register (int regno)
150 {
151 #ifndef __powerpc64__
152 /* Some kernels do not allow us to store fpscr. */
153 if (!(ppc_hwcap & PPC_FEATURE_HAS_SPE) && regno == find_regno ("fpscr"))
154 return 2;
155 #endif
156
157 /* Some kernels do not allow us to store orig_r3 or trap. */
158 if (regno == find_regno ("orig_r3")
159 || regno == find_regno ("trap"))
160 return 2;
161
162 return 0;
163 }
164
165 static int
166 ppc_cannot_fetch_register (int regno)
167 {
168 return 0;
169 }
170
171 static void
172 ppc_collect_ptrace_register (struct regcache *regcache, int regno, char *buf)
173 {
174 int size = register_size (regno);
175
176 memset (buf, 0, sizeof (long));
177
178 if (size < sizeof (long))
179 collect_register (regcache, regno, buf + sizeof (long) - size);
180 else
181 collect_register (regcache, regno, buf);
182 }
183
184 static void
185 ppc_supply_ptrace_register (struct regcache *regcache,
186 int regno, const char *buf)
187 {
188 int size = register_size (regno);
189 if (size < sizeof (long))
190 supply_register (regcache, regno, buf + sizeof (long) - size);
191 else
192 supply_register (regcache, regno, buf);
193 }
194
195
196 #define INSTR_SC 0x44000002
197 #define NR_spu_run 0x0116
198
199 /* If the PPU thread is currently stopped on a spu_run system call,
200 return to FD and ADDR the file handle and NPC parameter address
201 used with the system call. Return non-zero if successful. */
202 static int
203 parse_spufs_run (struct regcache *regcache, int *fd, CORE_ADDR *addr)
204 {
205 CORE_ADDR curr_pc;
206 int curr_insn;
207 int curr_r0;
208
209 if (register_size (0) == 4)
210 {
211 unsigned int pc, r0, r3, r4;
212 collect_register_by_name (regcache, "pc", &pc);
213 collect_register_by_name (regcache, "r0", &r0);
214 collect_register_by_name (regcache, "orig_r3", &r3);
215 collect_register_by_name (regcache, "r4", &r4);
216 curr_pc = (CORE_ADDR) pc;
217 curr_r0 = (int) r0;
218 *fd = (int) r3;
219 *addr = (CORE_ADDR) r4;
220 }
221 else
222 {
223 unsigned long pc, r0, r3, r4;
224 collect_register_by_name (regcache, "pc", &pc);
225 collect_register_by_name (regcache, "r0", &r0);
226 collect_register_by_name (regcache, "orig_r3", &r3);
227 collect_register_by_name (regcache, "r4", &r4);
228 curr_pc = (CORE_ADDR) pc;
229 curr_r0 = (int) r0;
230 *fd = (int) r3;
231 *addr = (CORE_ADDR) r4;
232 }
233
234 /* Fetch instruction preceding current NIP. */
235 if ((*the_target->read_memory) (curr_pc - 4,
236 (unsigned char *) &curr_insn, 4) != 0)
237 return 0;
238 /* It should be a "sc" instruction. */
239 if (curr_insn != INSTR_SC)
240 return 0;
241 /* System call number should be NR_spu_run. */
242 if (curr_r0 != NR_spu_run)
243 return 0;
244
245 return 1;
246 }
247
248 static CORE_ADDR
249 ppc_get_pc (struct regcache *regcache)
250 {
251 CORE_ADDR addr;
252 int fd;
253
254 if (parse_spufs_run (regcache, &fd, &addr))
255 {
256 unsigned int pc;
257 (*the_target->read_memory) (addr, (unsigned char *) &pc, 4);
258 return ((CORE_ADDR)1 << 63)
259 | ((CORE_ADDR)fd << 32) | (CORE_ADDR) (pc - 4);
260 }
261 else if (register_size (0) == 4)
262 {
263 unsigned int pc;
264 collect_register_by_name (regcache, "pc", &pc);
265 return (CORE_ADDR) pc;
266 }
267 else
268 {
269 unsigned long pc;
270 collect_register_by_name (regcache, "pc", &pc);
271 return (CORE_ADDR) pc;
272 }
273 }
274
275 static void
276 ppc_set_pc (struct regcache *regcache, CORE_ADDR pc)
277 {
278 CORE_ADDR addr;
279 int fd;
280
281 if (parse_spufs_run (regcache, &fd, &addr))
282 {
283 unsigned int newpc = pc;
284 (*the_target->write_memory) (addr, (unsigned char *) &newpc, 4);
285 }
286 else if (register_size (0) == 4)
287 {
288 unsigned int newpc = pc;
289 supply_register_by_name (regcache, "pc", &newpc);
290 }
291 else
292 {
293 unsigned long newpc = pc;
294 supply_register_by_name (regcache, "pc", &newpc);
295 }
296 }
297
298
299 static int
300 ppc_get_hwcap (unsigned long *valp)
301 {
302 int wordsize = register_size (0);
303 unsigned char *data = alloca (2 * wordsize);
304 int offset = 0;
305
306 while ((*the_target->read_auxv) (offset, data, 2 * wordsize) == 2 * wordsize)
307 {
308 if (wordsize == 4)
309 {
310 unsigned int *data_p = (unsigned int *)data;
311 if (data_p[0] == AT_HWCAP)
312 {
313 *valp = data_p[1];
314 return 1;
315 }
316 }
317 else
318 {
319 unsigned long *data_p = (unsigned long *)data;
320 if (data_p[0] == AT_HWCAP)
321 {
322 *valp = data_p[1];
323 return 1;
324 }
325 }
326
327 offset += 2 * wordsize;
328 }
329
330 *valp = 0;
331 return 0;
332 }
333
334 static void
335 ppc_arch_setup (void)
336 {
337 #ifdef __powerpc64__
338 long msr;
339 struct regcache *regcache;
340
341 /* On a 64-bit host, assume 64-bit inferior process with no
342 AltiVec registers. Reset ppc_hwcap to ensure that the
343 collect_register call below does not fail. */
344 init_registers_powerpc_64l ();
345 ppc_hwcap = 0;
346
347 /* Only if the high bit of the MSR is set, we actually have
348 a 64-bit inferior. */
349 regcache = new_register_cache ();
350 fetch_inferior_registers (regcache, find_regno ("msr"));
351 collect_register_by_name (regcache, "msr", &msr);
352 free_register_cache (regcache);
353 if (msr < 0)
354 {
355 ppc_get_hwcap (&ppc_hwcap);
356 if (ppc_hwcap & PPC_FEATURE_CELL)
357 init_registers_powerpc_cell64l ();
358 else if (ppc_hwcap & PPC_FEATURE_HAS_VSX)
359 {
360 /* Power ISA 2.05 (implemented by Power 6 and newer processors)
361 increases the FPSCR from 32 bits to 64 bits. Even though Power 7
362 supports this ISA version, it doesn't have PPC_FEATURE_ARCH_2_05
363 set, only PPC_FEATURE_ARCH_2_06. Since for now the only bits
364 used in the higher half of the register are for Decimal Floating
365 Point, we check if that feature is available to decide the size
366 of the FPSCR. */
367 if (ppc_hwcap & PPC_FEATURE_HAS_DFP)
368 init_registers_powerpc_isa205_vsx64l ();
369 else
370 init_registers_powerpc_vsx64l ();
371 }
372 else if (ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC)
373 {
374 if (ppc_hwcap & PPC_FEATURE_HAS_DFP)
375 init_registers_powerpc_isa205_altivec64l ();
376 else
377 init_registers_powerpc_altivec64l ();
378 }
379
380 return;
381 }
382 #endif
383
384 /* OK, we have a 32-bit inferior. */
385 init_registers_powerpc_32l ();
386
387 ppc_get_hwcap (&ppc_hwcap);
388 if (ppc_hwcap & PPC_FEATURE_CELL)
389 init_registers_powerpc_cell32l ();
390 else if (ppc_hwcap & PPC_FEATURE_HAS_VSX)
391 {
392 if (ppc_hwcap & PPC_FEATURE_HAS_DFP)
393 init_registers_powerpc_isa205_vsx32l ();
394 else
395 init_registers_powerpc_vsx32l ();
396 }
397 else if (ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC)
398 {
399 if (ppc_hwcap & PPC_FEATURE_HAS_DFP)
400 init_registers_powerpc_isa205_altivec32l ();
401 else
402 init_registers_powerpc_altivec32l ();
403 }
404
405 /* On 32-bit machines, check for SPE registers.
406 Set the low target's regmap field as appropriately. */
407 #ifndef __powerpc64__
408 the_low_target.regmap = ppc_regmap;
409 if (ppc_hwcap & PPC_FEATURE_HAS_SPE)
410 {
411 init_registers_powerpc_e500l ();
412 the_low_target.regmap = ppc_regmap_e500;
413 }
414
415 /* If the FPSCR is 64-bit wide, we need to fetch the whole 64-bit
416 slot and not just its second word. The PT_FPSCR supplied in a
417 32-bit GDB compilation doesn't reflect this. */
418 if (register_size (70) == 8)
419 ppc_regmap[70] = (48 + 2*32) * sizeof (long);
420 #endif
421 }
422
423 /* Correct in either endianness.
424 This instruction is "twge r2, r2", which GDB uses as a software
425 breakpoint. */
426 static const unsigned int ppc_breakpoint = 0x7d821008;
427 #define ppc_breakpoint_len 4
428
429 static int
430 ppc_breakpoint_at (CORE_ADDR where)
431 {
432 unsigned int insn;
433
434 if (where & ((CORE_ADDR)1 << 63))
435 {
436 char mem_annex[32];
437 sprintf (mem_annex, "%d/mem", (int)((where >> 32) & 0x7fffffff));
438 (*the_target->qxfer_spu) (mem_annex, (unsigned char *) &insn,
439 NULL, where & 0xffffffff, 4);
440 if (insn == 0x3fff)
441 return 1;
442 }
443 else
444 {
445 (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
446 if (insn == ppc_breakpoint)
447 return 1;
448 /* If necessary, recognize more trap instructions here. GDB only uses
449 the one. */
450 }
451
452 return 0;
453 }
454
455 /* Provide only a fill function for the general register set. ps_lgetregs
456 will use this for NPTL support. */
457
458 static void ppc_fill_gregset (struct regcache *regcache, void *buf)
459 {
460 int i;
461
462 for (i = 0; i < 32; i++)
463 ppc_collect_ptrace_register (regcache, i, (char *) buf + ppc_regmap[i]);
464
465 for (i = 64; i < 70; i++)
466 ppc_collect_ptrace_register (regcache, i, (char *) buf + ppc_regmap[i]);
467
468 for (i = 71; i < 73; i++)
469 ppc_collect_ptrace_register (regcache, i, (char *) buf + ppc_regmap[i]);
470 }
471
472 #ifndef PTRACE_GETVSXREGS
473 #define PTRACE_GETVSXREGS 27
474 #define PTRACE_SETVSXREGS 28
475 #endif
476
477 #define SIZEOF_VSXREGS 32*8
478
479 static void
480 ppc_fill_vsxregset (struct regcache *regcache, void *buf)
481 {
482 int i, base;
483 char *regset = buf;
484
485 if (!(ppc_hwcap & PPC_FEATURE_HAS_VSX))
486 return;
487
488 base = find_regno ("vs0h");
489 for (i = 0; i < 32; i++)
490 collect_register (regcache, base + i, &regset[i * 8]);
491 }
492
493 static void
494 ppc_store_vsxregset (struct regcache *regcache, const void *buf)
495 {
496 int i, base;
497 const char *regset = buf;
498
499 if (!(ppc_hwcap & PPC_FEATURE_HAS_VSX))
500 return;
501
502 base = find_regno ("vs0h");
503 for (i = 0; i < 32; i++)
504 supply_register (regcache, base + i, &regset[i * 8]);
505 }
506
507 #ifndef PTRACE_GETVRREGS
508 #define PTRACE_GETVRREGS 18
509 #define PTRACE_SETVRREGS 19
510 #endif
511
512 #define SIZEOF_VRREGS 33*16+4
513
514 static void
515 ppc_fill_vrregset (struct regcache *regcache, void *buf)
516 {
517 int i, base;
518 char *regset = buf;
519
520 if (!(ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC))
521 return;
522
523 base = find_regno ("vr0");
524 for (i = 0; i < 32; i++)
525 collect_register (regcache, base + i, &regset[i * 16]);
526
527 collect_register_by_name (regcache, "vscr", &regset[32 * 16 + 12]);
528 collect_register_by_name (regcache, "vrsave", &regset[33 * 16]);
529 }
530
531 static void
532 ppc_store_vrregset (struct regcache *regcache, const void *buf)
533 {
534 int i, base;
535 const char *regset = buf;
536
537 if (!(ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC))
538 return;
539
540 base = find_regno ("vr0");
541 for (i = 0; i < 32; i++)
542 supply_register (regcache, base + i, &regset[i * 16]);
543
544 supply_register_by_name (regcache, "vscr", &regset[32 * 16 + 12]);
545 supply_register_by_name (regcache, "vrsave", &regset[33 * 16]);
546 }
547
548 #ifndef PTRACE_GETEVRREGS
549 #define PTRACE_GETEVRREGS 20
550 #define PTRACE_SETEVRREGS 21
551 #endif
552
553 struct gdb_evrregset_t
554 {
555 unsigned long evr[32];
556 unsigned long long acc;
557 unsigned long spefscr;
558 };
559
560 static void
561 ppc_fill_evrregset (struct regcache *regcache, void *buf)
562 {
563 int i, ev0;
564 struct gdb_evrregset_t *regset = buf;
565
566 if (!(ppc_hwcap & PPC_FEATURE_HAS_SPE))
567 return;
568
569 ev0 = find_regno ("ev0h");
570 for (i = 0; i < 32; i++)
571 collect_register (regcache, ev0 + i, &regset->evr[i]);
572
573 collect_register_by_name (regcache, "acc", &regset->acc);
574 collect_register_by_name (regcache, "spefscr", &regset->spefscr);
575 }
576
577 static void
578 ppc_store_evrregset (struct regcache *regcache, const void *buf)
579 {
580 int i, ev0;
581 const struct gdb_evrregset_t *regset = buf;
582
583 if (!(ppc_hwcap & PPC_FEATURE_HAS_SPE))
584 return;
585
586 ev0 = find_regno ("ev0h");
587 for (i = 0; i < 32; i++)
588 supply_register (regcache, ev0 + i, &regset->evr[i]);
589
590 supply_register_by_name (regcache, "acc", &regset->acc);
591 supply_register_by_name (regcache, "spefscr", &regset->spefscr);
592 }
593
594 struct regset_info target_regsets[] = {
595 /* List the extra register sets before GENERAL_REGS. That way we will
596 fetch them every time, but still fall back to PTRACE_PEEKUSER for the
597 general registers. Some kernels support these, but not the newer
598 PPC_PTRACE_GETREGS. */
599 { PTRACE_GETVSXREGS, PTRACE_SETVSXREGS, 0, SIZEOF_VSXREGS, EXTENDED_REGS,
600 ppc_fill_vsxregset, ppc_store_vsxregset },
601 { PTRACE_GETVRREGS, PTRACE_SETVRREGS, 0, SIZEOF_VRREGS, EXTENDED_REGS,
602 ppc_fill_vrregset, ppc_store_vrregset },
603 { PTRACE_GETEVRREGS, PTRACE_SETEVRREGS, 0, 32 * 4 + 8 + 4, EXTENDED_REGS,
604 ppc_fill_evrregset, ppc_store_evrregset },
605 { 0, 0, 0, 0, GENERAL_REGS, ppc_fill_gregset, NULL },
606 { 0, 0, 0, -1, -1, NULL, NULL }
607 };
608
609 struct linux_target_ops the_low_target = {
610 ppc_arch_setup,
611 ppc_num_regs,
612 ppc_regmap,
613 ppc_cannot_fetch_register,
614 ppc_cannot_store_register,
615 ppc_get_pc,
616 ppc_set_pc,
617 (const unsigned char *) &ppc_breakpoint,
618 ppc_breakpoint_len,
619 NULL,
620 0,
621 ppc_breakpoint_at,
622 NULL,
623 NULL,
624 NULL,
625 NULL,
626 ppc_collect_ptrace_register,
627 ppc_supply_ptrace_register,
628 };