]> Git Repo - binutils.git/blob - gdb/gdbserver/linux-ppc-low.c
ChangeLog:
[binutils.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 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 (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 (regno, buf + sizeof (long) - size);
180   else
181     collect_register (regno, buf);
182 }
183
184 static void
185 ppc_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
194 static CORE_ADDR
195 ppc_get_pc (void)
196 {
197   if (register_size (0) == 4)
198     {
199       unsigned int pc;
200       collect_register_by_name ("pc", &pc);
201       return (CORE_ADDR) pc;
202     }
203   else
204     {
205       unsigned long pc;
206       collect_register_by_name ("pc", &pc);
207       return (CORE_ADDR) pc;
208     }
209 }
210
211 static void
212 ppc_set_pc (CORE_ADDR pc)
213 {
214   if (register_size (0) == 4)
215     {
216       unsigned int newpc = pc;
217       supply_register_by_name ("pc", &newpc);
218     }
219   else
220     {
221       unsigned long newpc = pc;
222       supply_register_by_name ("pc", &newpc);
223     }
224 }
225
226
227 static int
228 ppc_get_hwcap (unsigned long *valp)
229 {
230   int wordsize = register_size (0);
231   unsigned char *data = alloca (2 * wordsize);
232   int offset = 0;
233
234   while ((*the_target->read_auxv) (offset, data, 2 * wordsize) == 2 * wordsize)
235     {
236       if (wordsize == 4)
237         {
238           unsigned int *data_p = (unsigned int *)data;
239           if (data_p[0] == AT_HWCAP)
240             {
241               *valp = data_p[1];
242               return 1;
243             }
244         }
245       else
246         {
247           unsigned long *data_p = (unsigned long *)data;
248           if (data_p[0] == AT_HWCAP)
249             {
250               *valp = data_p[1];
251               return 1;
252             }
253         }
254
255       offset += 2 * wordsize;
256     }
257
258   *valp = 0;
259   return 0;
260 }
261
262 static void
263 ppc_arch_setup (void)
264 {
265 #ifdef __powerpc64__
266   long msr;
267
268   /* On a 64-bit host, assume 64-bit inferior process with no
269      AltiVec registers.  Reset ppc_hwcap to ensure that the
270      collect_register call below does not fail.  */
271   init_registers_powerpc_64l ();
272   ppc_hwcap = 0;
273
274   /* Only if the high bit of the MSR is set, we actually have
275      a 64-bit inferior.  */
276   collect_register_by_name ("msr", &msr);
277   if (msr < 0)
278     {
279       ppc_get_hwcap (&ppc_hwcap);
280       if (ppc_hwcap & PPC_FEATURE_CELL)
281         init_registers_powerpc_cell64l ();
282       else if (ppc_hwcap & PPC_FEATURE_HAS_VSX)
283         {
284           /* Power ISA 2.05 (implemented by Power 6 and newer processors)
285              increases the FPSCR from 32 bits to 64 bits. Even though Power 7
286              supports this ISA version, it doesn't have PPC_FEATURE_ARCH_2_05
287              set, only PPC_FEATURE_ARCH_2_06.  Since for now the only bits
288              used in the higher half of the register are for Decimal Floating
289              Point, we check if that feature is available to decide the size
290              of the FPSCR.  */
291           if (ppc_hwcap & PPC_FEATURE_HAS_DFP)
292             init_registers_powerpc_isa205_vsx64l ();
293           else
294             init_registers_powerpc_vsx64l ();
295         }
296       else if (ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC)
297         {
298           if (ppc_hwcap & PPC_FEATURE_HAS_DFP)
299             init_registers_powerpc_isa205_altivec64l ();
300           else
301             init_registers_powerpc_altivec64l ();
302         }
303
304       return;
305     }
306 #endif
307
308   /* OK, we have a 32-bit inferior.  */
309   init_registers_powerpc_32l ();
310
311   ppc_get_hwcap (&ppc_hwcap);
312   if (ppc_hwcap & PPC_FEATURE_CELL)
313     init_registers_powerpc_cell32l ();
314   else if (ppc_hwcap & PPC_FEATURE_HAS_VSX)
315     {
316       if (ppc_hwcap & PPC_FEATURE_HAS_DFP)
317         init_registers_powerpc_isa205_vsx32l ();
318       else
319         init_registers_powerpc_vsx32l ();
320     }
321   else if (ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC)
322     {
323       if (ppc_hwcap & PPC_FEATURE_HAS_DFP)
324         init_registers_powerpc_isa205_altivec32l ();
325       else
326         init_registers_powerpc_altivec32l ();
327     }
328
329   /* On 32-bit machines, check for SPE registers.
330      Set the low target's regmap field as appropriately.  */
331 #ifndef __powerpc64__
332   the_low_target.regmap = ppc_regmap;
333   if (ppc_hwcap & PPC_FEATURE_HAS_SPE)
334     {
335       init_registers_powerpc_e500l ();
336       the_low_target.regmap = ppc_regmap_e500;
337    }
338
339   /* If the FPSCR is 64-bit wide, we need to fetch the whole 64-bit
340      slot and not just its second word.  The PT_FPSCR supplied in a
341      32-bit GDB compilation doesn't reflect this.  */
342   if (register_size (70) == 8)
343     ppc_regmap[70] = (48 + 2*32) * sizeof (long);
344 #endif
345 }
346
347 /* Correct in either endianness.
348    This instruction is "twge r2, r2", which GDB uses as a software
349    breakpoint.  */
350 static const unsigned int ppc_breakpoint = 0x7d821008;
351 #define ppc_breakpoint_len 4
352
353 static int
354 ppc_breakpoint_at (CORE_ADDR where)
355 {
356   unsigned int insn;
357
358   (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
359   if (insn == ppc_breakpoint)
360     return 1;
361   /* If necessary, recognize more trap instructions here.  GDB only uses the
362      one.  */
363   return 0;
364 }
365
366 /* Provide only a fill function for the general register set.  ps_lgetregs
367    will use this for NPTL support.  */
368
369 static void ppc_fill_gregset (void *buf)
370 {
371   int i;
372
373   for (i = 0; i < 32; i++)
374     ppc_collect_ptrace_register (i, (char *) buf + ppc_regmap[i]);
375
376   for (i = 64; i < 70; i++)
377     ppc_collect_ptrace_register (i, (char *) buf + ppc_regmap[i]);
378
379   for (i = 71; i < 73; i++)
380     ppc_collect_ptrace_register (i, (char *) buf + ppc_regmap[i]);
381 }
382
383 #ifndef PTRACE_GETVSXREGS
384 #define PTRACE_GETVSXREGS 27
385 #define PTRACE_SETVSXREGS 28
386 #endif
387
388 #define SIZEOF_VSXREGS 32*8
389
390 static void
391 ppc_fill_vsxregset (void *buf)
392 {
393   int i, base;
394   char *regset = buf;
395
396   if (!(ppc_hwcap & PPC_FEATURE_HAS_VSX))
397     return;
398
399   base = find_regno ("vs0h");
400   for (i = 0; i < 32; i++)
401     collect_register (base + i, &regset[i * 8]);
402 }
403
404 static void
405 ppc_store_vsxregset (const void *buf)
406 {
407   int i, base;
408   const char *regset = buf;
409
410   if (!(ppc_hwcap & PPC_FEATURE_HAS_VSX))
411     return;
412
413   base = find_regno ("vs0h");
414   for (i = 0; i < 32; i++)
415     supply_register (base + i, &regset[i * 8]);
416 }
417
418 #ifndef PTRACE_GETVRREGS
419 #define PTRACE_GETVRREGS 18
420 #define PTRACE_SETVRREGS 19
421 #endif
422
423 #define SIZEOF_VRREGS 33*16+4
424
425 static void
426 ppc_fill_vrregset (void *buf)
427 {
428   int i, base;
429   char *regset = buf;
430
431   if (!(ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC))
432     return;
433
434   base = find_regno ("vr0");
435   for (i = 0; i < 32; i++)
436     collect_register (base + i, &regset[i * 16]);
437
438   collect_register_by_name ("vscr", &regset[32 * 16 + 12]);
439   collect_register_by_name ("vrsave", &regset[33 * 16]);
440 }
441
442 static void
443 ppc_store_vrregset (const void *buf)
444 {
445   int i, base;
446   const char *regset = buf;
447
448   if (!(ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC))
449     return;
450
451   base = find_regno ("vr0");
452   for (i = 0; i < 32; i++)
453     supply_register (base + i, &regset[i * 16]);
454
455   supply_register_by_name ("vscr", &regset[32 * 16 + 12]);
456   supply_register_by_name ("vrsave", &regset[33 * 16]);
457 }
458
459 #ifndef PTRACE_GETEVRREGS
460 #define PTRACE_GETEVRREGS       20
461 #define PTRACE_SETEVRREGS       21
462 #endif
463
464 struct gdb_evrregset_t
465 {
466   unsigned long evr[32];
467   unsigned long long acc;
468   unsigned long spefscr;
469 };
470
471 static void
472 ppc_fill_evrregset (void *buf)
473 {
474   int i, ev0;
475   struct gdb_evrregset_t *regset = buf;
476
477   if (!(ppc_hwcap & PPC_FEATURE_HAS_SPE))
478     return;
479
480   ev0 = find_regno ("ev0h");
481   for (i = 0; i < 32; i++)
482     collect_register (ev0 + i, &regset->evr[i]);
483
484   collect_register_by_name ("acc", &regset->acc);
485   collect_register_by_name ("spefscr", &regset->spefscr);
486 }
487
488 static void
489 ppc_store_evrregset (const void *buf)
490 {
491   int i, ev0;
492   const struct gdb_evrregset_t *regset = buf;
493
494   if (!(ppc_hwcap & PPC_FEATURE_HAS_SPE))
495     return;
496
497   ev0 = find_regno ("ev0h");
498   for (i = 0; i < 32; i++)
499     supply_register (ev0 + i, &regset->evr[i]);
500
501   supply_register_by_name ("acc", &regset->acc);
502   supply_register_by_name ("spefscr", &regset->spefscr);
503 }
504
505 struct regset_info target_regsets[] = {
506   /* List the extra register sets before GENERAL_REGS.  That way we will
507      fetch them every time, but still fall back to PTRACE_PEEKUSER for the
508      general registers.  Some kernels support these, but not the newer
509      PPC_PTRACE_GETREGS.  */
510   { PTRACE_GETVSXREGS, PTRACE_SETVSXREGS, SIZEOF_VSXREGS, EXTENDED_REGS,
511   ppc_fill_vsxregset, ppc_store_vsxregset },
512   { PTRACE_GETVRREGS, PTRACE_SETVRREGS, SIZEOF_VRREGS, EXTENDED_REGS,
513     ppc_fill_vrregset, ppc_store_vrregset },
514   { PTRACE_GETEVRREGS, PTRACE_SETEVRREGS, 32 * 4 + 8 + 4, EXTENDED_REGS,
515     ppc_fill_evrregset, ppc_store_evrregset },
516   { 0, 0, 0, GENERAL_REGS, ppc_fill_gregset, NULL },
517   { 0, 0, -1, -1, NULL, NULL }
518 };
519
520 struct linux_target_ops the_low_target = {
521   ppc_arch_setup,
522   ppc_num_regs,
523   ppc_regmap,
524   ppc_cannot_fetch_register,
525   ppc_cannot_store_register,
526   ppc_get_pc,
527   ppc_set_pc,
528   (const unsigned char *) &ppc_breakpoint,
529   ppc_breakpoint_len,
530   NULL,
531   0,
532   ppc_breakpoint_at,
533   NULL,
534   NULL,
535   NULL,
536   NULL,
537   ppc_collect_ptrace_register,
538   ppc_supply_ptrace_register,
539 };
This page took 0.05481 seconds and 4 git commands to generate.