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