gdb/
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-mips-low.c
... / ...
CommitLineData
1/* GNU/Linux/MIPS specific low level interface, for the remote server for GDB.
2 Copyright (C) 1995-2013 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18
19#include "server.h"
20#include "linux-low.h"
21
22#include <sys/ptrace.h>
23#include <endian.h>
24
25#include "gdb_proc_service.h"
26
27/* Defined in auto-generated file mips-linux.c. */
28void init_registers_mips_linux (void);
29extern const struct target_desc *tdesc_mips_linux;
30
31/* Defined in auto-generated file mips-dsp-linux.c. */
32void init_registers_mips_dsp_linux (void);
33extern const struct target_desc *tdesc_mips_dsp_linux;
34
35/* Defined in auto-generated file mips64-linux.c. */
36void init_registers_mips64_linux (void);
37extern const struct target_desc *tdesc_mips64_linux;
38
39/* Defined in auto-generated file mips64-dsp-linux.c. */
40void init_registers_mips64_dsp_linux (void);
41extern const struct target_desc *tdesc_mips64_dsp_linux;
42
43#ifdef __mips64
44#define tdesc_mips_linux tdesc_mips64_linux
45#define tdesc_mips_dsp_linux tdesc_mips64_dsp_linux
46#endif
47
48#ifndef PTRACE_GET_THREAD_AREA
49#define PTRACE_GET_THREAD_AREA 25
50#endif
51
52#ifdef HAVE_SYS_REG_H
53#include <sys/reg.h>
54#endif
55
56#define mips_num_regs 73
57#define mips_dsp_num_regs 80
58
59#include <asm/ptrace.h>
60
61#ifndef DSP_BASE
62#define DSP_BASE 71
63#define DSP_CONTROL 77
64#endif
65
66union mips_register
67{
68 unsigned char buf[8];
69
70 /* Deliberately signed, for proper sign extension. */
71 int reg32;
72 long long reg64;
73};
74
75/* Return the ptrace ``address'' of register REGNO. */
76
77#define mips_base_regs \
78 -1, 1, 2, 3, 4, 5, 6, 7, \
79 8, 9, 10, 11, 12, 13, 14, 15, \
80 16, 17, 18, 19, 20, 21, 22, 23, \
81 24, 25, 26, 27, 28, 29, 30, 31, \
82 \
83 -1, MMLO, MMHI, BADVADDR, CAUSE, PC, \
84 \
85 FPR_BASE, FPR_BASE + 1, FPR_BASE + 2, FPR_BASE + 3, \
86 FPR_BASE + 4, FPR_BASE + 5, FPR_BASE + 6, FPR_BASE + 7, \
87 FPR_BASE + 8, FPR_BASE + 9, FPR_BASE + 10, FPR_BASE + 11, \
88 FPR_BASE + 12, FPR_BASE + 13, FPR_BASE + 14, FPR_BASE + 15, \
89 FPR_BASE + 16, FPR_BASE + 17, FPR_BASE + 18, FPR_BASE + 19, \
90 FPR_BASE + 20, FPR_BASE + 21, FPR_BASE + 22, FPR_BASE + 23, \
91 FPR_BASE + 24, FPR_BASE + 25, FPR_BASE + 26, FPR_BASE + 27, \
92 FPR_BASE + 28, FPR_BASE + 29, FPR_BASE + 30, FPR_BASE + 31, \
93 FPC_CSR, FPC_EIR
94
95#define mips_dsp_regs \
96 DSP_BASE, DSP_BASE + 1, DSP_BASE + 2, DSP_BASE + 3, \
97 DSP_BASE + 4, DSP_BASE + 5, \
98 DSP_CONTROL
99
100static int mips_regmap[mips_num_regs] = {
101 mips_base_regs,
102 0
103};
104
105static int mips_dsp_regmap[mips_dsp_num_regs] = {
106 mips_base_regs,
107 mips_dsp_regs,
108 0
109};
110
111/* DSP registers are not in any regset and can only be accessed
112 individually. */
113
114static unsigned char mips_dsp_regset_bitmap[(mips_dsp_num_regs + 7) / 8] = {
115 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x80
116};
117
118static int have_dsp = -1;
119
120/* Try peeking at an arbitrarily chosen DSP register and pick the available
121 user register set accordingly. */
122
123static const struct target_desc *
124mips_read_description (void)
125{
126 if (have_dsp < 0)
127 {
128 int pid = lwpid_of (get_thread_lwp (current_inferior));
129
130 ptrace (PTRACE_PEEKUSER, pid, DSP_CONTROL, 0);
131 switch (errno)
132 {
133 case 0:
134 have_dsp = 1;
135 break;
136 case EIO:
137 have_dsp = 0;
138 break;
139 default:
140 perror_with_name ("ptrace");
141 break;
142 }
143 }
144
145 return have_dsp ? tdesc_mips_dsp_linux : tdesc_mips_linux;
146}
147
148static void
149mips_arch_setup (void)
150{
151 current_process ()->tdesc = mips_read_description ();
152}
153
154static struct usrregs_info *
155get_usrregs_info (void)
156{
157 const struct regs_info *regs_info = the_low_target.regs_info ();
158
159 return regs_info->usrregs;
160}
161
162/* From mips-linux-nat.c. */
163
164/* Pseudo registers can not be read. ptrace does not provide a way to
165 read (or set) PS_REGNUM, and there's no point in reading or setting
166 ZERO_REGNUM. We also can not set BADVADDR, CAUSE, or FCRIR via
167 ptrace(). */
168
169static int
170mips_cannot_fetch_register (int regno)
171{
172 const struct target_desc *tdesc;
173
174 if (get_usrregs_info ()->regmap[regno] == -1)
175 return 1;
176
177 tdesc = current_process ()->tdesc;
178
179 if (find_regno (tdesc, "r0") == regno)
180 return 1;
181
182 return 0;
183}
184
185static int
186mips_cannot_store_register (int regno)
187{
188 const struct target_desc *tdesc;
189
190 if (get_usrregs_info ()->regmap[regno] == -1)
191 return 1;
192
193 tdesc = current_process ()->tdesc;
194
195 if (find_regno (tdesc, "r0") == regno)
196 return 1;
197
198 if (find_regno (tdesc, "cause") == regno)
199 return 1;
200
201 if (find_regno (tdesc, "badvaddr") == regno)
202 return 1;
203
204 if (find_regno (tdesc, "fir") == regno)
205 return 1;
206
207 return 0;
208}
209
210static CORE_ADDR
211mips_get_pc (struct regcache *regcache)
212{
213 union mips_register pc;
214 collect_register_by_name (regcache, "pc", pc.buf);
215 return register_size (regcache->tdesc, 0) == 4 ? pc.reg32 : pc.reg64;
216}
217
218static void
219mips_set_pc (struct regcache *regcache, CORE_ADDR pc)
220{
221 union mips_register newpc;
222 if (register_size (regcache->tdesc, 0) == 4)
223 newpc.reg32 = pc;
224 else
225 newpc.reg64 = pc;
226
227 supply_register_by_name (regcache, "pc", newpc.buf);
228}
229
230/* Correct in either endianness. */
231static const unsigned int mips_breakpoint = 0x0005000d;
232#define mips_breakpoint_len 4
233
234/* We only place breakpoints in empty marker functions, and thread locking
235 is outside of the function. So rather than importing software single-step,
236 we can just run until exit. */
237static CORE_ADDR
238mips_reinsert_addr (void)
239{
240 struct regcache *regcache = get_thread_regcache (current_inferior, 1);
241 union mips_register ra;
242 collect_register_by_name (regcache, "r31", ra.buf);
243 return register_size (regcache->tdesc, 0) == 4 ? ra.reg32 : ra.reg64;
244}
245
246static int
247mips_breakpoint_at (CORE_ADDR where)
248{
249 unsigned int insn;
250
251 (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
252 if (insn == mips_breakpoint)
253 return 1;
254
255 /* If necessary, recognize more trap instructions here. GDB only uses the
256 one. */
257 return 0;
258}
259
260/* Fetch the thread-local storage pointer for libthread_db. */
261
262ps_err_e
263ps_get_thread_area (const struct ps_prochandle *ph,
264 lwpid_t lwpid, int idx, void **base)
265{
266 if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
267 return PS_ERR;
268
269 /* IDX is the bias from the thread pointer to the beginning of the
270 thread descriptor. It has to be subtracted due to implementation
271 quirks in libthread_db. */
272 *base = (void *) ((char *)*base - idx);
273
274 return PS_OK;
275}
276
277#ifdef HAVE_PTRACE_GETREGS
278
279static void
280mips_collect_register (struct regcache *regcache,
281 int use_64bit, int regno, union mips_register *reg)
282{
283 union mips_register tmp_reg;
284
285 if (use_64bit)
286 {
287 collect_register (regcache, regno, &tmp_reg.reg64);
288 *reg = tmp_reg;
289 }
290 else
291 {
292 collect_register (regcache, regno, &tmp_reg.reg32);
293 reg->reg64 = tmp_reg.reg32;
294 }
295}
296
297static void
298mips_supply_register (struct regcache *regcache,
299 int use_64bit, int regno, const union mips_register *reg)
300{
301 int offset = 0;
302
303 /* For big-endian 32-bit targets, ignore the high four bytes of each
304 eight-byte slot. */
305 if (__BYTE_ORDER == __BIG_ENDIAN && !use_64bit)
306 offset = 4;
307
308 supply_register (regcache, regno, reg->buf + offset);
309}
310
311static void
312mips_collect_register_32bit (struct regcache *regcache,
313 int use_64bit, int regno, unsigned char *buf)
314{
315 union mips_register tmp_reg;
316 int reg32;
317
318 mips_collect_register (regcache, use_64bit, regno, &tmp_reg);
319 reg32 = tmp_reg.reg64;
320 memcpy (buf, &reg32, 4);
321}
322
323static void
324mips_supply_register_32bit (struct regcache *regcache,
325 int use_64bit, int regno, const unsigned char *buf)
326{
327 union mips_register tmp_reg;
328 int reg32;
329
330 memcpy (&reg32, buf, 4);
331 tmp_reg.reg64 = reg32;
332 mips_supply_register (regcache, use_64bit, regno, &tmp_reg);
333}
334
335static void
336mips_fill_gregset (struct regcache *regcache, void *buf)
337{
338 union mips_register *regset = buf;
339 int i, use_64bit;
340 const struct target_desc *tdesc = regcache->tdesc;
341
342 use_64bit = (register_size (tdesc, 0) == 8);
343
344 for (i = 1; i < 32; i++)
345 mips_collect_register (regcache, use_64bit, i, regset + i);
346
347 mips_collect_register (regcache, use_64bit,
348 find_regno (tdesc, "lo"), regset + 32);
349 mips_collect_register (regcache, use_64bit,
350 find_regno (tdesc, "hi"), regset + 33);
351 mips_collect_register (regcache, use_64bit,
352 find_regno (tdesc, "pc"), regset + 34);
353 mips_collect_register (regcache, use_64bit,
354 find_regno (tdesc, "badvaddr"), regset + 35);
355 mips_collect_register (regcache, use_64bit,
356 find_regno (tdesc, "status"), regset + 36);
357 mips_collect_register (regcache, use_64bit,
358 find_regno (tdesc, "cause"), regset + 37);
359
360 mips_collect_register (regcache, use_64bit,
361 find_regno (tdesc, "restart"), regset + 0);
362}
363
364static void
365mips_store_gregset (struct regcache *regcache, const void *buf)
366{
367 const union mips_register *regset = buf;
368 int i, use_64bit;
369
370 use_64bit = (register_size (regcache->tdesc, 0) == 8);
371
372 for (i = 0; i < 32; i++)
373 mips_supply_register (regcache, use_64bit, i, regset + i);
374
375 mips_supply_register (regcache, use_64bit,
376 find_regno (regcache->tdesc, "lo"), regset + 32);
377 mips_supply_register (regcache, use_64bit,
378 find_regno (regcache->tdesc, "hi"), regset + 33);
379 mips_supply_register (regcache, use_64bit,
380 find_regno (regcache->tdesc, "pc"), regset + 34);
381 mips_supply_register (regcache, use_64bit,
382 find_regno (regcache->tdesc, "badvaddr"), regset + 35);
383 mips_supply_register (regcache, use_64bit,
384 find_regno (regcache->tdesc, "status"), regset + 36);
385 mips_supply_register (regcache, use_64bit,
386 find_regno (regcache->tdesc, "cause"), regset + 37);
387
388 mips_supply_register (regcache, use_64bit,
389 find_regno (regcache->tdesc, "restart"), regset + 0);
390}
391
392static void
393mips_fill_fpregset (struct regcache *regcache, void *buf)
394{
395 union mips_register *regset = buf;
396 int i, use_64bit, first_fp, big_endian;
397
398 use_64bit = (register_size (regcache->tdesc, 0) == 8);
399 first_fp = find_regno (regcache->tdesc, "f0");
400 big_endian = (__BYTE_ORDER == __BIG_ENDIAN);
401
402 /* See GDB for a discussion of this peculiar layout. */
403 for (i = 0; i < 32; i++)
404 if (use_64bit)
405 collect_register (regcache, first_fp + i, regset[i].buf);
406 else
407 collect_register (regcache, first_fp + i,
408 regset[i & ~1].buf + 4 * (big_endian != (i & 1)));
409
410 mips_collect_register_32bit (regcache, use_64bit,
411 find_regno (regcache->tdesc, "fcsr"), regset[32].buf);
412 mips_collect_register_32bit (regcache, use_64bit,
413 find_regno (regcache->tdesc, "fir"),
414 regset[32].buf + 4);
415}
416
417static void
418mips_store_fpregset (struct regcache *regcache, const void *buf)
419{
420 const union mips_register *regset = buf;
421 int i, use_64bit, first_fp, big_endian;
422
423 use_64bit = (register_size (regcache->tdesc, 0) == 8);
424 first_fp = find_regno (regcache->tdesc, "f0");
425 big_endian = (__BYTE_ORDER == __BIG_ENDIAN);
426
427 /* See GDB for a discussion of this peculiar layout. */
428 for (i = 0; i < 32; i++)
429 if (use_64bit)
430 supply_register (regcache, first_fp + i, regset[i].buf);
431 else
432 supply_register (regcache, first_fp + i,
433 regset[i & ~1].buf + 4 * (big_endian != (i & 1)));
434
435 mips_supply_register_32bit (regcache, use_64bit,
436 find_regno (regcache->tdesc, "fcsr"),
437 regset[32].buf);
438 mips_supply_register_32bit (regcache, use_64bit,
439 find_regno (regcache->tdesc, "fir"),
440 regset[32].buf + 4);
441}
442#endif /* HAVE_PTRACE_GETREGS */
443
444static struct regset_info mips_regsets[] = {
445#ifdef HAVE_PTRACE_GETREGS
446 { PTRACE_GETREGS, PTRACE_SETREGS, 0, 38 * 8, GENERAL_REGS,
447 mips_fill_gregset, mips_store_gregset },
448 { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 0, 33 * 8, FP_REGS,
449 mips_fill_fpregset, mips_store_fpregset },
450#endif /* HAVE_PTRACE_GETREGS */
451 { 0, 0, 0, -1, -1, NULL, NULL }
452};
453
454static struct regsets_info mips_regsets_info =
455 {
456 mips_regsets, /* regsets */
457 0, /* num_regsets */
458 NULL, /* disabled_regsets */
459 };
460
461static struct usrregs_info mips_dsp_usrregs_info =
462 {
463 mips_dsp_num_regs,
464 mips_dsp_regmap,
465 };
466
467static struct usrregs_info mips_usrregs_info =
468 {
469 mips_num_regs,
470 mips_regmap,
471 };
472
473static struct regs_info dsp_regs_info =
474 {
475 mips_dsp_regset_bitmap,
476 &mips_dsp_usrregs_info,
477 &mips_regsets_info
478 };
479
480static struct regs_info regs_info =
481 {
482 NULL, /* regset_bitmap */
483 &mips_usrregs_info,
484 &mips_regsets_info
485 };
486
487static const struct regs_info *
488mips_regs_info (void)
489{
490 if (have_dsp)
491 return &dsp_regs_info;
492 else
493 return &regs_info;
494}
495
496struct linux_target_ops the_low_target = {
497 mips_arch_setup,
498 mips_regs_info,
499 mips_cannot_fetch_register,
500 mips_cannot_store_register,
501 NULL, /* fetch_register */
502 mips_get_pc,
503 mips_set_pc,
504 (const unsigned char *) &mips_breakpoint,
505 mips_breakpoint_len,
506 mips_reinsert_addr,
507 0,
508 mips_breakpoint_at,
509};
510
511void
512initialize_low_arch (void)
513{
514 /* Initialize the Linux target descriptions. */
515 init_registers_mips_linux ();
516 init_registers_mips_dsp_linux ();
517 init_registers_mips64_linux ();
518 init_registers_mips64_dsp_linux ();
519
520 initialize_regsets_info (&mips_regsets_info);
521}
This page took 0.025471 seconds and 4 git commands to generate.