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