ChangeLog:
[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.
9b254dd1 3 Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2005, 2007, 2008
0a30fbc4
DJ
4 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
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
UW
27/* These are in <asm/cputable.h> in current kernels. */
28#define PPC_FEATURE_HAS_ALTIVEC 0x10000000
29#define PPC_FEATURE_HAS_SPE 0x00800000
30
31static unsigned long ppc_hwcap;
32
33
7284e1be
UW
34/* Defined in auto-generated file powerpc-32l.c. */
35void init_registers_powerpc_32l (void);
36/* Defined in auto-generated file powerpc-altivec32l.c. */
37void init_registers_powerpc_altivec32l (void);
38/* Defined in auto-generated file powerpc-e500l.c. */
39void init_registers_powerpc_e500l (void);
40/* Defined in auto-generated file powerpc-64l.c. */
41void init_registers_powerpc_64l (void);
42/* Defined in auto-generated file powerpc-altivec64l.c. */
43void init_registers_powerpc_altivec64l (void);
44
45#define ppc_num_regs 73
46
47/* This sometimes isn't defined. */
48#ifndef PT_ORIG_R3
49#define PT_ORIG_R3 34
50#endif
51#ifndef PT_TRAP
52#define PT_TRAP 40
53#endif
0a30fbc4 54
5b0a002e
UW
55#ifdef __powerpc64__
56/* We use a constant for FPSCR instead of PT_FPSCR, because
57 many shipped PPC64 kernels had the wrong value in ptrace.h. */
58static int ppc_regmap[] =
59 {PT_R0 * 8, PT_R1 * 8, PT_R2 * 8, PT_R3 * 8,
60 PT_R4 * 8, PT_R5 * 8, PT_R6 * 8, PT_R7 * 8,
61 PT_R8 * 8, PT_R9 * 8, PT_R10 * 8, PT_R11 * 8,
62 PT_R12 * 8, PT_R13 * 8, PT_R14 * 8, PT_R15 * 8,
63 PT_R16 * 8, PT_R17 * 8, PT_R18 * 8, PT_R19 * 8,
64 PT_R20 * 8, PT_R21 * 8, PT_R22 * 8, PT_R23 * 8,
65 PT_R24 * 8, PT_R25 * 8, PT_R26 * 8, PT_R27 * 8,
66 PT_R28 * 8, PT_R29 * 8, PT_R30 * 8, PT_R31 * 8,
67 PT_FPR0*8, PT_FPR0*8 + 8, PT_FPR0*8+16, PT_FPR0*8+24,
68 PT_FPR0*8+32, PT_FPR0*8+40, PT_FPR0*8+48, PT_FPR0*8+56,
69 PT_FPR0*8+64, PT_FPR0*8+72, PT_FPR0*8+80, PT_FPR0*8+88,
70 PT_FPR0*8+96, PT_FPR0*8+104, PT_FPR0*8+112, PT_FPR0*8+120,
71 PT_FPR0*8+128, PT_FPR0*8+136, PT_FPR0*8+144, PT_FPR0*8+152,
72 PT_FPR0*8+160, PT_FPR0*8+168, PT_FPR0*8+176, PT_FPR0*8+184,
73 PT_FPR0*8+192, PT_FPR0*8+200, PT_FPR0*8+208, PT_FPR0*8+216,
74 PT_FPR0*8+224, PT_FPR0*8+232, PT_FPR0*8+240, PT_FPR0*8+248,
75 PT_NIP * 8, PT_MSR * 8, PT_CCR * 8, PT_LNK * 8,
7284e1be
UW
76 PT_CTR * 8, PT_XER * 8, PT_FPR0*8 + 256,
77 PT_ORIG_R3 * 8, PT_TRAP * 8 };
5b0a002e 78#else
0a30fbc4 79/* Currently, don't check/send MQ. */
2ec06d2e 80static int ppc_regmap[] =
0a30fbc4
DJ
81 {PT_R0 * 4, PT_R1 * 4, PT_R2 * 4, PT_R3 * 4,
82 PT_R4 * 4, PT_R5 * 4, PT_R6 * 4, PT_R7 * 4,
83 PT_R8 * 4, PT_R9 * 4, PT_R10 * 4, PT_R11 * 4,
84 PT_R12 * 4, PT_R13 * 4, PT_R14 * 4, PT_R15 * 4,
85 PT_R16 * 4, PT_R17 * 4, PT_R18 * 4, PT_R19 * 4,
86 PT_R20 * 4, PT_R21 * 4, PT_R22 * 4, PT_R23 * 4,
87 PT_R24 * 4, PT_R25 * 4, PT_R26 * 4, PT_R27 * 4,
88 PT_R28 * 4, PT_R29 * 4, PT_R30 * 4, PT_R31 * 4,
89 PT_FPR0*4, PT_FPR0*4 + 8, PT_FPR0*4+16, PT_FPR0*4+24,
90 PT_FPR0*4+32, PT_FPR0*4+40, PT_FPR0*4+48, PT_FPR0*4+56,
91 PT_FPR0*4+64, PT_FPR0*4+72, PT_FPR0*4+80, PT_FPR0*4+88,
92 PT_FPR0*4+96, PT_FPR0*4+104, PT_FPR0*4+112, PT_FPR0*4+120,
93 PT_FPR0*4+128, PT_FPR0*4+136, PT_FPR0*4+144, PT_FPR0*4+152,
94 PT_FPR0*4+160, PT_FPR0*4+168, PT_FPR0*4+176, PT_FPR0*4+184,
95 PT_FPR0*4+192, PT_FPR0*4+200, PT_FPR0*4+208, PT_FPR0*4+216,
96 PT_FPR0*4+224, PT_FPR0*4+232, PT_FPR0*4+240, PT_FPR0*4+248,
97 PT_NIP * 4, PT_MSR * 4, PT_CCR * 4, PT_LNK * 4,
7284e1be
UW
98 PT_CTR * 4, PT_XER * 4, PT_FPSCR * 4,
99 PT_ORIG_R3 * 4, PT_TRAP * 4
b6430ec3
UW
100 };
101
102static int ppc_regmap_e500[] =
103 {PT_R0 * 4, PT_R1 * 4, PT_R2 * 4, PT_R3 * 4,
104 PT_R4 * 4, PT_R5 * 4, PT_R6 * 4, PT_R7 * 4,
105 PT_R8 * 4, PT_R9 * 4, PT_R10 * 4, PT_R11 * 4,
106 PT_R12 * 4, PT_R13 * 4, PT_R14 * 4, PT_R15 * 4,
107 PT_R16 * 4, PT_R17 * 4, PT_R18 * 4, PT_R19 * 4,
108 PT_R20 * 4, PT_R21 * 4, PT_R22 * 4, PT_R23 * 4,
109 PT_R24 * 4, PT_R25 * 4, PT_R26 * 4, PT_R27 * 4,
110 PT_R28 * 4, PT_R29 * 4, PT_R30 * 4, PT_R31 * 4,
111 -1, -1, -1, -1,
112 -1, -1, -1, -1,
113 -1, -1, -1, -1,
114 -1, -1, -1, -1,
115 -1, -1, -1, -1,
116 -1, -1, -1, -1,
117 -1, -1, -1, -1,
118 -1, -1, -1, -1,
119 PT_NIP * 4, PT_MSR * 4, PT_CCR * 4, PT_LNK * 4,
7284e1be
UW
120 PT_CTR * 4, PT_XER * 4, -1,
121 PT_ORIG_R3 * 4, PT_TRAP * 4
30ed0a8f 122 };
5b0a002e 123#endif
0a30fbc4 124
2ec06d2e
DJ
125static int
126ppc_cannot_store_register (int regno)
0a30fbc4 127{
b6430ec3 128#ifndef __powerpc64__
bc1e36ca 129 /* Some kernels do not allow us to store fpscr. */
b6430ec3 130 if (!(ppc_hwcap & PPC_FEATURE_HAS_SPE) && regno == find_regno ("fpscr"))
bc1e36ca 131 return 2;
30ed0a8f 132#endif
bc1e36ca 133
7284e1be
UW
134 /* Some kernels do not allow us to store orig_r3 or trap. */
135 if (regno == find_regno ("orig_r3")
136 || regno == find_regno ("trap"))
137 return 2;
138
0a30fbc4
DJ
139 return 0;
140}
141
2ec06d2e
DJ
142static int
143ppc_cannot_fetch_register (int regno)
0a30fbc4
DJ
144{
145 return 0;
146}
147
5b0a002e
UW
148static void
149ppc_collect_ptrace_register (int regno, char *buf)
150{
151 int size = register_size (regno);
152 if (size < sizeof (long))
153 collect_register (regno, buf + sizeof (long) - size);
154 else
155 collect_register (regno, buf);
156}
157
158static void
159ppc_supply_ptrace_register (int regno, const char *buf)
160{
161 int size = register_size (regno);
162 if (size < sizeof (long))
163 supply_register (regno, buf + sizeof (long) - size);
164 else
165 supply_register (regno, buf);
166}
167
0d62e5e8
DJ
168static CORE_ADDR
169ppc_get_pc (void)
170{
6fe305f7
UW
171 if (register_size (0) == 4)
172 {
173 unsigned int pc;
174 collect_register_by_name ("pc", &pc);
175 return (CORE_ADDR) pc;
176 }
177 else
178 {
179 unsigned long pc;
180 collect_register_by_name ("pc", &pc);
181 return (CORE_ADDR) pc;
182 }
0d62e5e8
DJ
183}
184
185static void
186ppc_set_pc (CORE_ADDR pc)
187{
6fe305f7
UW
188 if (register_size (0) == 4)
189 {
190 unsigned int newpc = pc;
191 supply_register_by_name ("pc", &newpc);
192 }
193 else
194 {
195 unsigned long newpc = pc;
196 supply_register_by_name ("pc", &newpc);
197 }
198}
199
b6430ec3
UW
200
201static int
202ppc_get_hwcap (unsigned long *valp)
203{
204 int wordsize = register_size (0);
205 unsigned char *data = alloca (2 * wordsize);
206 int offset = 0;
207
208 while ((*the_target->read_auxv) (offset, data, 2 * wordsize) == 2 * wordsize)
209 {
210 if (wordsize == 4)
211 {
212 unsigned int *data_p = (unsigned int *)data;
213 if (data_p[0] == AT_HWCAP)
214 {
215 *valp = data_p[1];
216 return 1;
217 }
218 }
219 else
220 {
221 unsigned long *data_p = (unsigned long *)data;
222 if (data_p[0] == AT_HWCAP)
223 {
224 *valp = data_p[1];
225 return 1;
226 }
227 }
228
229 offset += 2 * wordsize;
230 }
231
232 *valp = 0;
233 return 0;
234}
235
6fe305f7
UW
236static void
237ppc_arch_setup (void)
238{
239#ifdef __powerpc64__
240 long msr;
0d62e5e8 241
c9b2f845
UW
242 /* On a 64-bit host, assume 64-bit inferior process with no
243 AltiVec registers. Reset ppc_hwcap to ensure that the
244 collect_register call below does not fail. */
7284e1be 245 init_registers_powerpc_64l ();
c9b2f845 246 ppc_hwcap = 0;
6fe305f7
UW
247
248 /* Only if the high bit of the MSR is set, we actually have
249 a 64-bit inferior. */
250 collect_register_by_name ("msr", &msr);
251 if (msr < 0)
b6430ec3
UW
252 {
253 ppc_get_hwcap (&ppc_hwcap);
254 if (ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC)
7284e1be 255 init_registers_powerpc_altivec64l ();
b6430ec3
UW
256
257 return;
258 }
6fe305f7
UW
259#endif
260
261 /* OK, we have a 32-bit inferior. */
7284e1be 262 init_registers_powerpc_32l ();
b6430ec3
UW
263
264 ppc_get_hwcap (&ppc_hwcap);
265 if (ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC)
7284e1be 266 init_registers_powerpc_altivec32l ();
b6430ec3
UW
267
268 /* On 32-bit machines, check for SPE registers.
269 Set the low target's regmap field as appropriately. */
270#ifndef __powerpc64__
271 the_low_target.regmap = ppc_regmap;
272 if (ppc_hwcap & PPC_FEATURE_HAS_SPE)
273 {
7284e1be 274 init_registers_powerpc_e500l ();
b6430ec3
UW
275 the_low_target.regmap = ppc_regmap_e500;
276 }
6fe305f7 277#endif
0d62e5e8
DJ
278}
279
5b0a002e 280/* Correct in either endianness.
0d62e5e8
DJ
281 This instruction is "twge r2, r2", which GDB uses as a software
282 breakpoint. */
5b0a002e 283static const unsigned int ppc_breakpoint = 0x7d821008;
0d62e5e8
DJ
284#define ppc_breakpoint_len 4
285
286static int
287ppc_breakpoint_at (CORE_ADDR where)
288{
5b0a002e 289 unsigned int insn;
0d62e5e8 290
f450004a 291 (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
0d62e5e8
DJ
292 if (insn == ppc_breakpoint)
293 return 1;
294 /* If necessary, recognize more trap instructions here. GDB only uses the
295 one. */
296 return 0;
297}
298
e9d25b98
DJ
299/* Provide only a fill function for the general register set. ps_lgetregs
300 will use this for NPTL support. */
301
302static void ppc_fill_gregset (void *buf)
303{
304 int i;
305
306 for (i = 0; i < 32; i++)
6fe305f7 307 ppc_collect_ptrace_register (i, (char *) buf + ppc_regmap[i]);
e9d25b98
DJ
308
309 for (i = 64; i < 70; i++)
6fe305f7 310 ppc_collect_ptrace_register (i, (char *) buf + ppc_regmap[i]);
7284e1be
UW
311
312 for (i = 71; i < 73; i++)
313 ppc_collect_ptrace_register (i, (char *) buf + ppc_regmap[i]);
e9d25b98
DJ
314}
315
30ed0a8f
DJ
316#ifndef PTRACE_GETVRREGS
317#define PTRACE_GETVRREGS 18
318#define PTRACE_SETVRREGS 19
319#endif
320
321#define SIZEOF_VRREGS 33*16+4
322
323static void
324ppc_fill_vrregset (void *buf)
325{
326 int i, base;
327 char *regset = buf;
328
b6430ec3
UW
329 if (!(ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC))
330 return;
331
30ed0a8f
DJ
332 base = find_regno ("vr0");
333 for (i = 0; i < 32; i++)
334 collect_register (base + i, &regset[i * 16]);
335
336 collect_register_by_name ("vscr", &regset[32 * 16 + 12]);
337 collect_register_by_name ("vrsave", &regset[33 * 16]);
338}
339
340static void
341ppc_store_vrregset (const void *buf)
342{
343 int i, base;
344 const char *regset = buf;
345
b6430ec3
UW
346 if (!(ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC))
347 return;
348
30ed0a8f
DJ
349 base = find_regno ("vr0");
350 for (i = 0; i < 32; i++)
351 supply_register (base + i, &regset[i * 16]);
352
353 supply_register_by_name ("vscr", &regset[32 * 16 + 12]);
354 supply_register_by_name ("vrsave", &regset[33 * 16]);
355}
356
30ed0a8f
DJ
357#ifndef PTRACE_GETEVRREGS
358#define PTRACE_GETEVRREGS 20
359#define PTRACE_SETEVRREGS 21
360#endif
361
362struct gdb_evrregset_t
363{
364 unsigned long evr[32];
365 unsigned long long acc;
366 unsigned long spefscr;
367};
368
369static void
370ppc_fill_evrregset (void *buf)
371{
372 int i, ev0;
373 struct gdb_evrregset_t *regset = buf;
374
b6430ec3
UW
375 if (!(ppc_hwcap & PPC_FEATURE_HAS_SPE))
376 return;
377
30ed0a8f
DJ
378 ev0 = find_regno ("ev0h");
379 for (i = 0; i < 32; i++)
380 collect_register (ev0 + i, &regset->evr[i]);
381
382 collect_register_by_name ("acc", &regset->acc);
383 collect_register_by_name ("spefscr", &regset->spefscr);
384}
385
386static void
387ppc_store_evrregset (const void *buf)
388{
389 int i, ev0;
390 const struct gdb_evrregset_t *regset = buf;
391
b6430ec3
UW
392 if (!(ppc_hwcap & PPC_FEATURE_HAS_SPE))
393 return;
394
30ed0a8f
DJ
395 ev0 = find_regno ("ev0h");
396 for (i = 0; i < 32; i++)
397 supply_register (ev0 + i, &regset->evr[i]);
398
399 supply_register_by_name ("acc", &regset->acc);
400 supply_register_by_name ("spefscr", &regset->spefscr);
401}
30ed0a8f 402
e9d25b98 403struct regset_info target_regsets[] = {
30ed0a8f
DJ
404 /* List the extra register sets before GENERAL_REGS. That way we will
405 fetch them every time, but still fall back to PTRACE_PEEKUSER for the
406 general registers. Some kernels support these, but not the newer
407 PPC_PTRACE_GETREGS. */
30ed0a8f
DJ
408 { PTRACE_GETVRREGS, PTRACE_SETVRREGS, SIZEOF_VRREGS, EXTENDED_REGS,
409 ppc_fill_vrregset, ppc_store_vrregset },
30ed0a8f
DJ
410 { PTRACE_GETEVRREGS, PTRACE_SETEVRREGS, 32 * 4 + 8 + 4, EXTENDED_REGS,
411 ppc_fill_evrregset, ppc_store_evrregset },
e9d25b98
DJ
412 { 0, 0, 0, GENERAL_REGS, ppc_fill_gregset, NULL },
413 { 0, 0, -1, -1, NULL, NULL }
414};
415
2ec06d2e 416struct linux_target_ops the_low_target = {
6fe305f7 417 ppc_arch_setup,
2ec06d2e
DJ
418 ppc_num_regs,
419 ppc_regmap,
420 ppc_cannot_fetch_register,
421 ppc_cannot_store_register,
0d62e5e8
DJ
422 ppc_get_pc,
423 ppc_set_pc,
f450004a 424 (const unsigned char *) &ppc_breakpoint,
0d62e5e8
DJ
425 ppc_breakpoint_len,
426 NULL,
427 0,
428 ppc_breakpoint_at,
5b0a002e
UW
429 NULL,
430 NULL,
431 NULL,
432 NULL,
433 ppc_collect_ptrace_register,
434 ppc_supply_ptrace_register,
2ec06d2e 435};
This page took 0.491399 seconds and 4 git commands to generate.