2012-03-28 Pedro Alves <palves@redhat.com>
[binutils-gdb.git] / gdb / gdbserver / linux-mips-low.c
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
3 Foundation, Inc.
4
5 This file is part of GDB.
6
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
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
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/>. */
19
20 #include "server.h"
21 #include "linux-low.h"
22
23 #include <sys/ptrace.h>
24 #include <endian.h>
25
26 #include "gdb_proc_service.h"
27
28 /* Defined in auto-generated file mips-linux.c. */
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);
32 /* Defined in auto-generated file mips64-linux.c. */
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
41
42 #ifndef PTRACE_GET_THREAD_AREA
43 #define PTRACE_GET_THREAD_AREA 25
44 #endif
45
46 #ifdef HAVE_SYS_REG_H
47 #include <sys/reg.h>
48 #endif
49
50 #define mips_num_regs 73
51 #define mips_dsp_num_regs 80
52
53 #include <asm/ptrace.h>
54
55 #ifndef DSP_BASE
56 #define DSP_BASE 71
57 #define DSP_CONTROL 77
58 #endif
59
60 union mips_register
61 {
62 unsigned char buf[8];
63
64 /* Deliberately signed, for proper sign extension. */
65 int reg32;
66 long long reg64;
67 };
68
69 /* Return the ptrace ``address'' of register REGNO. */
70
71 #define mips_base_regs \
72 -1, 1, 2, 3, 4, 5, 6, 7, \
73 8, 9, 10, 11, 12, 13, 14, 15, \
74 16, 17, 18, 19, 20, 21, 22, 23, \
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
88
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
93
94 static int mips_regmap[mips_num_regs] = {
95 mips_base_regs,
96 0
97 };
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
149 /* From mips-linux-nat.c. */
150
151 /* Pseudo registers can not be read. ptrace does not provide a way to
152 read (or set) PS_REGNUM, and there's no point in reading or setting
153 ZERO_REGNUM. We also can not set BADVADDR, CAUSE, or FCRIR via
154 ptrace(). */
155
156 static int
157 mips_cannot_fetch_register (int regno)
158 {
159 if (the_low_target.regmap[regno] == -1)
160 return 1;
161
162 if (find_regno ("r0") == regno)
163 return 1;
164
165 return 0;
166 }
167
168 static int
169 mips_cannot_store_register (int regno)
170 {
171 if (the_low_target.regmap[regno] == -1)
172 return 1;
173
174 if (find_regno ("r0") == regno)
175 return 1;
176
177 if (find_regno ("cause") == regno)
178 return 1;
179
180 if (find_regno ("badvaddr") == regno)
181 return 1;
182
183 if (find_regno ("fir") == regno)
184 return 1;
185
186 return 0;
187 }
188
189 static CORE_ADDR
190 mips_get_pc (struct regcache *regcache)
191 {
192 union mips_register pc;
193 collect_register_by_name (regcache, "pc", pc.buf);
194 return register_size (0) == 4 ? pc.reg32 : pc.reg64;
195 }
196
197 static void
198 mips_set_pc (struct regcache *regcache, CORE_ADDR pc)
199 {
200 union mips_register newpc;
201 if (register_size (0) == 4)
202 newpc.reg32 = pc;
203 else
204 newpc.reg64 = pc;
205
206 supply_register_by_name (regcache, "pc", newpc.buf);
207 }
208
209 /* Correct in either endianness. */
210 static const unsigned int mips_breakpoint = 0x0005000d;
211 #define mips_breakpoint_len 4
212
213 /* We only place breakpoints in empty marker functions, and thread locking
214 is outside of the function. So rather than importing software single-step,
215 we can just run until exit. */
216 static CORE_ADDR
217 mips_reinsert_addr (void)
218 {
219 struct regcache *regcache = get_thread_regcache (current_inferior, 1);
220 union mips_register ra;
221 collect_register_by_name (regcache, "r31", ra.buf);
222 return register_size (0) == 4 ? ra.reg32 : ra.reg64;
223 }
224
225 static int
226 mips_breakpoint_at (CORE_ADDR where)
227 {
228 unsigned int insn;
229
230 (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
231 if (insn == mips_breakpoint)
232 return 1;
233
234 /* If necessary, recognize more trap instructions here. GDB only uses the
235 one. */
236 return 0;
237 }
238
239 /* Fetch the thread-local storage pointer for libthread_db. */
240
241 ps_err_e
242 ps_get_thread_area (const struct ps_prochandle *ph,
243 lwpid_t lwpid, int idx, void **base)
244 {
245 if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
246 return PS_ERR;
247
248 /* IDX is the bias from the thread pointer to the beginning of the
249 thread descriptor. It has to be subtracted due to implementation
250 quirks in libthread_db. */
251 *base = (void *) ((char *)*base - idx);
252
253 return PS_OK;
254 }
255
256 #ifdef HAVE_PTRACE_GETREGS
257
258 static void
259 mips_collect_register (struct regcache *regcache,
260 int use_64bit, int regno, union mips_register *reg)
261 {
262 union mips_register tmp_reg;
263
264 if (use_64bit)
265 {
266 collect_register (regcache, regno, &tmp_reg.reg64);
267 *reg = tmp_reg;
268 }
269 else
270 {
271 collect_register (regcache, regno, &tmp_reg.reg32);
272 reg->reg64 = tmp_reg.reg32;
273 }
274 }
275
276 static void
277 mips_supply_register (struct regcache *regcache,
278 int use_64bit, int regno, const union mips_register *reg)
279 {
280 int offset = 0;
281
282 /* For big-endian 32-bit targets, ignore the high four bytes of each
283 eight-byte slot. */
284 if (__BYTE_ORDER == __BIG_ENDIAN && !use_64bit)
285 offset = 4;
286
287 supply_register (regcache, regno, reg->buf + offset);
288 }
289
290 static void
291 mips_collect_register_32bit (struct regcache *regcache,
292 int use_64bit, int regno, unsigned char *buf)
293 {
294 union mips_register tmp_reg;
295 int reg32;
296
297 mips_collect_register (regcache, use_64bit, regno, &tmp_reg);
298 reg32 = tmp_reg.reg64;
299 memcpy (buf, &reg32, 4);
300 }
301
302 static void
303 mips_supply_register_32bit (struct regcache *regcache,
304 int use_64bit, int regno, const unsigned char *buf)
305 {
306 union mips_register tmp_reg;
307 int reg32;
308
309 memcpy (&reg32, buf, 4);
310 tmp_reg.reg64 = reg32;
311 mips_supply_register (regcache, use_64bit, regno, &tmp_reg);
312 }
313
314 static void
315 mips_fill_gregset (struct regcache *regcache, void *buf)
316 {
317 union mips_register *regset = buf;
318 int i, use_64bit;
319
320 use_64bit = (register_size (0) == 8);
321
322 for (i = 1; i < 32; i++)
323 mips_collect_register (regcache, use_64bit, i, regset + i);
324
325 mips_collect_register (regcache, use_64bit,
326 find_regno ("lo"), regset + 32);
327 mips_collect_register (regcache, use_64bit,
328 find_regno ("hi"), regset + 33);
329 mips_collect_register (regcache, use_64bit,
330 find_regno ("pc"), regset + 34);
331 mips_collect_register (regcache, use_64bit,
332 find_regno ("badvaddr"), regset + 35);
333 mips_collect_register (regcache, use_64bit,
334 find_regno ("status"), regset + 36);
335 mips_collect_register (regcache, use_64bit,
336 find_regno ("cause"), regset + 37);
337
338 mips_collect_register (regcache, use_64bit,
339 find_regno ("restart"), regset + 0);
340 }
341
342 static void
343 mips_store_gregset (struct regcache *regcache, const void *buf)
344 {
345 const union mips_register *regset = buf;
346 int i, use_64bit;
347
348 use_64bit = (register_size (0) == 8);
349
350 for (i = 0; i < 32; i++)
351 mips_supply_register (regcache, use_64bit, i, regset + i);
352
353 mips_supply_register (regcache, use_64bit, find_regno ("lo"), regset + 32);
354 mips_supply_register (regcache, use_64bit, find_regno ("hi"), regset + 33);
355 mips_supply_register (regcache, use_64bit, find_regno ("pc"), regset + 34);
356 mips_supply_register (regcache, use_64bit,
357 find_regno ("badvaddr"), regset + 35);
358 mips_supply_register (regcache, use_64bit,
359 find_regno ("status"), regset + 36);
360 mips_supply_register (regcache, use_64bit,
361 find_regno ("cause"), regset + 37);
362
363 mips_supply_register (regcache, use_64bit,
364 find_regno ("restart"), regset + 0);
365 }
366
367 static void
368 mips_fill_fpregset (struct regcache *regcache, void *buf)
369 {
370 union mips_register *regset = buf;
371 int i, use_64bit, first_fp, big_endian;
372
373 use_64bit = (register_size (0) == 8);
374 first_fp = find_regno ("f0");
375 big_endian = (__BYTE_ORDER == __BIG_ENDIAN);
376
377 /* See GDB for a discussion of this peculiar layout. */
378 for (i = 0; i < 32; i++)
379 if (use_64bit)
380 collect_register (regcache, first_fp + i, regset[i].buf);
381 else
382 collect_register (regcache, first_fp + i,
383 regset[i & ~1].buf + 4 * (big_endian != (i & 1)));
384
385 mips_collect_register_32bit (regcache, use_64bit,
386 find_regno ("fcsr"), regset[32].buf);
387 mips_collect_register_32bit (regcache, use_64bit, find_regno ("fir"),
388 regset[32].buf + 4);
389 }
390
391 static void
392 mips_store_fpregset (struct regcache *regcache, const void *buf)
393 {
394 const union mips_register *regset = buf;
395 int i, use_64bit, first_fp, big_endian;
396
397 use_64bit = (register_size (0) == 8);
398 first_fp = find_regno ("f0");
399 big_endian = (__BYTE_ORDER == __BIG_ENDIAN);
400
401 /* See GDB for a discussion of this peculiar layout. */
402 for (i = 0; i < 32; i++)
403 if (use_64bit)
404 supply_register (regcache, first_fp + i, regset[i].buf);
405 else
406 supply_register (regcache, first_fp + i,
407 regset[i & ~1].buf + 4 * (big_endian != (i & 1)));
408
409 mips_supply_register_32bit (regcache, use_64bit,
410 find_regno ("fcsr"), regset[32].buf);
411 mips_supply_register_32bit (regcache, use_64bit, find_regno ("fir"),
412 regset[32].buf + 4);
413 }
414 #endif /* HAVE_PTRACE_GETREGS */
415
416 struct regset_info target_regsets[] = {
417 #ifdef HAVE_PTRACE_GETREGS
418 { PTRACE_GETREGS, PTRACE_SETREGS, 0, 38 * 8, GENERAL_REGS,
419 mips_fill_gregset, mips_store_gregset },
420 { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 0, 33 * 8, FP_REGS,
421 mips_fill_fpregset, mips_store_fpregset },
422 #endif /* HAVE_PTRACE_GETREGS */
423 { 0, 0, 0, -1, -1, NULL, NULL }
424 };
425
426 struct linux_target_ops the_low_target = {
427 mips_arch_setup,
428 -1,
429 NULL,
430 NULL,
431 mips_cannot_fetch_register,
432 mips_cannot_store_register,
433 NULL, /* fetch_register */
434 mips_get_pc,
435 mips_set_pc,
436 (const unsigned char *) &mips_breakpoint,
437 mips_breakpoint_len,
438 mips_reinsert_addr,
439 0,
440 mips_breakpoint_at,
441 };