OLD | NEW |
1 /* GNU/Linux/MIPS specific low level interface, for the remote server for GDB. | 1 /* GNU/Linux/MIPS specific low level interface, for the remote server for GDB. |
2 Copyright (C) 1995-1996, 1998-2002, 2005-2012 Free Software | 2 Copyright (C) 1995-1996, 1998-2002, 2005-2012 Free Software |
3 Foundation, Inc. | 3 Foundation, Inc. |
4 | 4 |
5 This file is part of GDB. | 5 This file is part of GDB. |
6 | 6 |
7 This program is free software; you can redistribute it and/or modify | 7 This program is free software; you can redistribute it and/or modify |
8 it under the terms of the GNU General Public License as published by | 8 it under the terms of the GNU General Public License as published by |
9 the Free Software Foundation; either version 3 of the License, or | 9 the Free Software Foundation; either version 3 of the License, or |
10 (at your option) any later version. | 10 (at your option) any later version. |
11 | 11 |
12 This program is distributed in the hope that it will be useful, | 12 This program is distributed in the hope that it will be useful, |
13 but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 GNU General Public License for more details. | 15 GNU General Public License for more details. |
16 | 16 |
17 You should have received a copy of the GNU General Public License | 17 You should have received a copy of the GNU General Public License |
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ | 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
19 | 19 |
20 #include "server.h" | 20 #include "server.h" |
21 #include "linux-low.h" | 21 #include "linux-low.h" |
22 | 22 |
23 #include <sys/ptrace.h> | 23 #include <sys/ptrace.h> |
24 #include <endian.h> | 24 #include <endian.h> |
25 | 25 |
26 #include "gdb_proc_service.h" | 26 #include "gdb_proc_service.h" |
27 | 27 |
28 /* Defined in auto-generated file mips-linux.c. */ | 28 /* Defined in auto-generated file mips-linux.c. */ |
29 void init_registers_mips_linux (void); | 29 void init_registers_mips_linux (void); |
| 30 /* Defined in auto-generated file mips-dsp-linux.c. */ |
| 31 void init_registers_mips_dsp_linux (void); |
30 /* Defined in auto-generated file mips64-linux.c. */ | 32 /* Defined in auto-generated file mips64-linux.c. */ |
31 void init_registers_mips64_linux (void); | 33 void init_registers_mips64_linux (void); |
| 34 /* Defined in auto-generated file mips64-dsp-linux.c. */ |
| 35 void init_registers_mips64_dsp_linux (void); |
| 36 |
| 37 #ifdef __mips64 |
| 38 #define init_registers_mips_linux init_registers_mips64_linux |
| 39 #define init_registers_mips_dsp_linux init_registers_mips64_dsp_linux |
| 40 #endif |
32 | 41 |
33 #ifndef PTRACE_GET_THREAD_AREA | 42 #ifndef PTRACE_GET_THREAD_AREA |
34 #define PTRACE_GET_THREAD_AREA 25 | 43 #define PTRACE_GET_THREAD_AREA 25 |
35 #endif | 44 #endif |
36 | 45 |
37 #ifdef HAVE_SYS_REG_H | 46 #ifdef HAVE_SYS_REG_H |
38 #include <sys/reg.h> | 47 #include <sys/reg.h> |
39 #endif | 48 #endif |
40 | 49 |
41 #define mips_num_regs 73 | 50 #define mips_num_regs 73 |
| 51 #define mips_dsp_num_regs 80 |
42 | 52 |
43 #include <asm/ptrace.h> | 53 #include <asm/ptrace.h> |
44 | 54 |
| 55 #ifndef DSP_BASE |
| 56 #define DSP_BASE 71 |
| 57 #define DSP_CONTROL 77 |
| 58 #endif |
| 59 |
45 union mips_register | 60 union mips_register |
46 { | 61 { |
47 unsigned char buf[8]; | 62 unsigned char buf[8]; |
48 | 63 |
49 /* Deliberately signed, for proper sign extension. */ | 64 /* Deliberately signed, for proper sign extension. */ |
50 int reg32; | 65 int reg32; |
51 long long reg64; | 66 long long reg64; |
52 }; | 67 }; |
53 | 68 |
54 /* Return the ptrace ``address'' of register REGNO. */ | 69 /* Return the ptrace ``address'' of register REGNO. */ |
55 | 70 |
56 static int mips_regmap[] = { | 71 #define mips_base_regs» » » » » » » \ |
57 -1, 1, 2, 3, 4, 5, 6, 7, | 72 -1, 1, 2, 3, 4, 5, 6, 7,» » » » » \ |
58 8, 9, 10, 11, 12, 13, 14, 15, | 73 8, 9, 10, 11, 12, 13, 14, 15,» » » » » \ |
59 16, 17, 18, 19, 20, 21, 22, 23, | 74 16, 17, 18, 19, 20, 21, 22, 23,» » » » » \ |
60 24, 25, 26, 27, 28, 29, 30, 31, | 75 24, 25, 26, 27, 28, 29, 30, 31,» » » » » \ |
| 76 » » » » » » » » » \ |
| 77 -1, MMLO, MMHI, BADVADDR, CAUSE, PC,» » » » » \ |
| 78 » » » » » » » » » \ |
| 79 FPR_BASE, FPR_BASE + 1, FPR_BASE + 2, FPR_BASE + 3,» » \ |
| 80 FPR_BASE + 4, FPR_BASE + 5, FPR_BASE + 6, FPR_BASE + 7,» » \ |
| 81 FPR_BASE + 8, FPR_BASE + 9, FPR_BASE + 10, FPR_BASE + 11,» » \ |
| 82 FPR_BASE + 12, FPR_BASE + 13, FPR_BASE + 14, FPR_BASE + 15,» » \ |
| 83 FPR_BASE + 16, FPR_BASE + 17, FPR_BASE + 18, FPR_BASE + 19,» » \ |
| 84 FPR_BASE + 20, FPR_BASE + 21, FPR_BASE + 22, FPR_BASE + 23,» » \ |
| 85 FPR_BASE + 24, FPR_BASE + 25, FPR_BASE + 26, FPR_BASE + 27,» » \ |
| 86 FPR_BASE + 28, FPR_BASE + 29, FPR_BASE + 30, FPR_BASE + 31,» » \ |
| 87 FPC_CSR, FPC_EIR |
61 | 88 |
62 -1, MMLO, MMHI, BADVADDR, CAUSE, PC, | 89 #define mips_dsp_regs» » » » » » » \ |
| 90 DSP_BASE, DSP_BASE + 1, DSP_BASE + 2, DSP_BASE + 3,» » \ |
| 91 DSP_BASE + 4, DSP_BASE + 5,» » » » » » \ |
| 92 DSP_CONTROL |
63 | 93 |
64 FPR_BASE, FPR_BASE + 1, FPR_BASE + 2, FPR_BASE + 3, | 94 static int mips_regmap[mips_num_regs] = { |
65 FPR_BASE + 4, FPR_BASE + 5, FPR_BASE + 6, FPR_BASE + 7, | 95 mips_base_regs, |
66 FPR_BASE + 8, FPR_BASE + 8, FPR_BASE + 10, FPR_BASE + 11, | |
67 FPR_BASE + 12, FPR_BASE + 13, FPR_BASE + 14, FPR_BASE + 15, | |
68 FPR_BASE + 16, FPR_BASE + 17, FPR_BASE + 18, FPR_BASE + 19, | |
69 FPR_BASE + 20, FPR_BASE + 21, FPR_BASE + 22, FPR_BASE + 23, | |
70 FPR_BASE + 24, FPR_BASE + 25, FPR_BASE + 26, FPR_BASE + 27, | |
71 FPR_BASE + 28, FPR_BASE + 29, FPR_BASE + 30, FPR_BASE + 31, | |
72 FPC_CSR, FPC_EIR, | |
73 | |
74 0 | 96 0 |
75 }; | 97 }; |
76 | 98 |
| 99 static int mips_dsp_regmap[mips_dsp_num_regs] = { |
| 100 mips_base_regs, |
| 101 mips_dsp_regs, |
| 102 0 |
| 103 }; |
| 104 |
| 105 /* DSP registers are not in any regset and can only be accessed |
| 106 individually. */ |
| 107 |
| 108 static unsigned char mips_dsp_regset_bitmap[(mips_dsp_num_regs + 7) / 8] = { |
| 109 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x80 |
| 110 }; |
| 111 |
| 112 /* Try peeking at an arbitrarily chosen DSP register and pick the available |
| 113 user register set accordingly. */ |
| 114 |
| 115 static void |
| 116 mips_arch_setup (void) |
| 117 { |
| 118 static void (*init_registers) (void); |
| 119 |
| 120 gdb_assert (current_inferior); |
| 121 |
| 122 if (init_registers == NULL) |
| 123 { |
| 124 int pid = lwpid_of (get_thread_lwp (current_inferior)); |
| 125 |
| 126 ptrace (PTRACE_PEEKUSER, pid, DSP_CONTROL, 0); |
| 127 switch (errno) |
| 128 { |
| 129 case 0: |
| 130 the_low_target.num_regs = mips_dsp_num_regs; |
| 131 the_low_target.regmap = mips_dsp_regmap; |
| 132 the_low_target.regset_bitmap = mips_dsp_regset_bitmap; |
| 133 init_registers = init_registers_mips_dsp_linux; |
| 134 break; |
| 135 case EIO: |
| 136 the_low_target.num_regs = mips_num_regs; |
| 137 the_low_target.regmap = mips_regmap; |
| 138 the_low_target.regset_bitmap = NULL; |
| 139 init_registers = init_registers_mips_linux; |
| 140 break; |
| 141 default: |
| 142 perror_with_name ("ptrace"); |
| 143 break; |
| 144 } |
| 145 } |
| 146 init_registers (); |
| 147 } |
| 148 |
77 /* From mips-linux-nat.c. */ | 149 /* From mips-linux-nat.c. */ |
78 | 150 |
79 /* Pseudo registers can not be read. ptrace does not provide a way to | 151 /* Pseudo registers can not be read. ptrace does not provide a way to |
80 read (or set) PS_REGNUM, and there's no point in reading or setting | 152 read (or set) PS_REGNUM, and there's no point in reading or setting |
81 ZERO_REGNUM. We also can not set BADVADDR, CAUSE, or FCRIR via | 153 ZERO_REGNUM. We also can not set BADVADDR, CAUSE, or FCRIR via |
82 ptrace(). */ | 154 ptrace(). */ |
83 | 155 |
84 static int | 156 static int |
85 mips_cannot_fetch_register (int regno) | 157 mips_cannot_fetch_register (int regno) |
86 { | 158 { |
87 if (mips_regmap[regno] == -1) | 159 if (the_low_target.regmap[regno] == -1) |
88 return 1; | 160 return 1; |
89 | 161 |
90 if (find_regno ("r0") == regno) | 162 if (find_regno ("r0") == regno) |
91 return 1; | 163 return 1; |
92 | 164 |
93 return 0; | 165 return 0; |
94 } | 166 } |
95 | 167 |
96 static int | 168 static int |
97 mips_cannot_store_register (int regno) | 169 mips_cannot_store_register (int regno) |
98 { | 170 { |
99 if (mips_regmap[regno] == -1) | 171 if (the_low_target.regmap[regno] == -1) |
100 return 1; | 172 return 1; |
101 | 173 |
102 if (find_regno ("r0") == regno) | 174 if (find_regno ("r0") == regno) |
103 return 1; | 175 return 1; |
104 | 176 |
105 if (find_regno ("cause") == regno) | 177 if (find_regno ("cause") == regno) |
106 return 1; | 178 return 1; |
107 | 179 |
108 if (find_regno ("badvaddr") == regno) | 180 if (find_regno ("badvaddr") == regno) |
109 return 1; | 181 return 1; |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 #ifdef HAVE_PTRACE_GETREGS | 417 #ifdef HAVE_PTRACE_GETREGS |
346 { PTRACE_GETREGS, PTRACE_SETREGS, 0, 38 * 8, GENERAL_REGS, | 418 { PTRACE_GETREGS, PTRACE_SETREGS, 0, 38 * 8, GENERAL_REGS, |
347 mips_fill_gregset, mips_store_gregset }, | 419 mips_fill_gregset, mips_store_gregset }, |
348 { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 0, 33 * 8, FP_REGS, | 420 { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 0, 33 * 8, FP_REGS, |
349 mips_fill_fpregset, mips_store_fpregset }, | 421 mips_fill_fpregset, mips_store_fpregset }, |
350 #endif /* HAVE_PTRACE_GETREGS */ | 422 #endif /* HAVE_PTRACE_GETREGS */ |
351 { 0, 0, 0, -1, -1, NULL, NULL } | 423 { 0, 0, 0, -1, -1, NULL, NULL } |
352 }; | 424 }; |
353 | 425 |
354 struct linux_target_ops the_low_target = { | 426 struct linux_target_ops the_low_target = { |
355 #ifdef __mips64 | 427 mips_arch_setup, |
356 init_registers_mips64_linux, | 428 -1, |
357 #else | 429 NULL, |
358 init_registers_mips_linux, | 430 NULL, |
359 #endif | |
360 mips_num_regs, | |
361 mips_regmap, | |
362 mips_cannot_fetch_register, | 431 mips_cannot_fetch_register, |
363 mips_cannot_store_register, | 432 mips_cannot_store_register, |
| 433 NULL, /* fetch_register */ |
364 mips_get_pc, | 434 mips_get_pc, |
365 mips_set_pc, | 435 mips_set_pc, |
366 (const unsigned char *) &mips_breakpoint, | 436 (const unsigned char *) &mips_breakpoint, |
367 mips_breakpoint_len, | 437 mips_breakpoint_len, |
368 mips_reinsert_addr, | 438 mips_reinsert_addr, |
369 0, | 439 0, |
370 mips_breakpoint_at, | 440 mips_breakpoint_at, |
371 }; | 441 }; |
OLD | NEW |