Remove fake operand handling for extended mnemonics.
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-mips-low.c
CommitLineData
0a30fbc4 1/* GNU/Linux/MIPS specific low level interface, for the remote server for GDB.
e2882c85 2 Copyright (C) 1995-2018 Free Software Foundation, Inc.
0a30fbc4
DJ
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
a9762ec7 8 the Free Software Foundation; either version 3 of the License, or
0a30fbc4
DJ
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
a9762ec7 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
0a30fbc4
DJ
18
19#include "server.h"
58caa3dc 20#include "linux-low.h"
0a30fbc4 21
5826e159 22#include "nat/gdb_ptrace.h"
186947f7 23#include <endian.h>
21b0f40c 24
125f8a3d 25#include "nat/mips-linux-watch.h"
21b0f40c
DJ
26#include "gdb_proc_service.h"
27
d05b4ac3
UW
28/* Defined in auto-generated file mips-linux.c. */
29void init_registers_mips_linux (void);
3aee8918
PA
30extern const struct target_desc *tdesc_mips_linux;
31
1faeff08
MR
32/* Defined in auto-generated file mips-dsp-linux.c. */
33void init_registers_mips_dsp_linux (void);
3aee8918
PA
34extern const struct target_desc *tdesc_mips_dsp_linux;
35
d05b4ac3
UW
36/* Defined in auto-generated file mips64-linux.c. */
37void init_registers_mips64_linux (void);
3aee8918
PA
38extern const struct target_desc *tdesc_mips64_linux;
39
1faeff08
MR
40/* Defined in auto-generated file mips64-dsp-linux.c. */
41void init_registers_mips64_dsp_linux (void);
3aee8918 42extern const struct target_desc *tdesc_mips64_dsp_linux;
1faeff08
MR
43
44#ifdef __mips64
3aee8918
PA
45#define tdesc_mips_linux tdesc_mips64_linux
46#define tdesc_mips_dsp_linux tdesc_mips64_dsp_linux
1faeff08 47#endif
d05b4ac3 48
21b0f40c
DJ
49#ifndef PTRACE_GET_THREAD_AREA
50#define PTRACE_GET_THREAD_AREA 25
51#endif
52
0a30fbc4
DJ
53#ifdef HAVE_SYS_REG_H
54#include <sys/reg.h>
55#endif
56
117ce543 57#define mips_num_regs 73
1faeff08 58#define mips_dsp_num_regs 80
0a30fbc4
DJ
59
60#include <asm/ptrace.h>
61
1faeff08
MR
62#ifndef DSP_BASE
63#define DSP_BASE 71
64#define DSP_CONTROL 77
65#endif
66
186947f7
DJ
67union mips_register
68{
69 unsigned char buf[8];
70
71 /* Deliberately signed, for proper sign extension. */
72 int reg32;
73 long long reg64;
74};
75
0a30fbc4
DJ
76/* Return the ptrace ``address'' of register REGNO. */
77
1faeff08
MR
78#define mips_base_regs \
79 -1, 1, 2, 3, 4, 5, 6, 7, \
80 8, 9, 10, 11, 12, 13, 14, 15, \
81 16, 17, 18, 19, 20, 21, 22, 23, \
82 24, 25, 26, 27, 28, 29, 30, 31, \
83 \
84 -1, MMLO, MMHI, BADVADDR, CAUSE, PC, \
85 \
86 FPR_BASE, FPR_BASE + 1, FPR_BASE + 2, FPR_BASE + 3, \
87 FPR_BASE + 4, FPR_BASE + 5, FPR_BASE + 6, FPR_BASE + 7, \
88 FPR_BASE + 8, FPR_BASE + 9, FPR_BASE + 10, FPR_BASE + 11, \
89 FPR_BASE + 12, FPR_BASE + 13, FPR_BASE + 14, FPR_BASE + 15, \
90 FPR_BASE + 16, FPR_BASE + 17, FPR_BASE + 18, FPR_BASE + 19, \
91 FPR_BASE + 20, FPR_BASE + 21, FPR_BASE + 22, FPR_BASE + 23, \
92 FPR_BASE + 24, FPR_BASE + 25, FPR_BASE + 26, FPR_BASE + 27, \
93 FPR_BASE + 28, FPR_BASE + 29, FPR_BASE + 30, FPR_BASE + 31, \
94 FPC_CSR, FPC_EIR
95
96#define mips_dsp_regs \
97 DSP_BASE, DSP_BASE + 1, DSP_BASE + 2, DSP_BASE + 3, \
98 DSP_BASE + 4, DSP_BASE + 5, \
99 DSP_CONTROL
100
101static int mips_regmap[mips_num_regs] = {
102 mips_base_regs,
103 0
104};
0a30fbc4 105
1faeff08
MR
106static int mips_dsp_regmap[mips_dsp_num_regs] = {
107 mips_base_regs,
108 mips_dsp_regs,
109 0
110};
0a30fbc4 111
1faeff08
MR
112/* DSP registers are not in any regset and can only be accessed
113 individually. */
0a30fbc4 114
1faeff08
MR
115static unsigned char mips_dsp_regset_bitmap[(mips_dsp_num_regs + 7) / 8] = {
116 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x80
0a30fbc4
DJ
117};
118
3aee8918
PA
119static int have_dsp = -1;
120
1faeff08
MR
121/* Try peeking at an arbitrarily chosen DSP register and pick the available
122 user register set accordingly. */
123
3aee8918
PA
124static const struct target_desc *
125mips_read_description (void)
1faeff08 126{
3aee8918 127 if (have_dsp < 0)
1faeff08 128 {
0bfdf32f 129 int pid = lwpid_of (current_thread);
1faeff08 130
ac740bc7 131 errno = 0;
1faeff08
MR
132 ptrace (PTRACE_PEEKUSER, pid, DSP_CONTROL, 0);
133 switch (errno)
134 {
135 case 0:
3aee8918 136 have_dsp = 1;
1faeff08
MR
137 break;
138 case EIO:
3aee8918 139 have_dsp = 0;
1faeff08
MR
140 break;
141 default:
142 perror_with_name ("ptrace");
143 break;
144 }
145 }
3aee8918
PA
146
147 return have_dsp ? tdesc_mips_dsp_linux : tdesc_mips_linux;
148}
149
150static void
151mips_arch_setup (void)
152{
153 current_process ()->tdesc = mips_read_description ();
154}
155
156static struct usrregs_info *
157get_usrregs_info (void)
158{
159 const struct regs_info *regs_info = the_low_target.regs_info ();
160
161 return regs_info->usrregs;
1faeff08
MR
162}
163
7a60ad40
YQ
164/* Per-process arch-specific data we want to keep. */
165
166struct arch_process_info
167{
168 /* -1 if the kernel and/or CPU do not support watch registers.
169 1 if watch_readback is valid and we can read style, num_valid
170 and the masks.
171 0 if we need to read the watch_readback. */
172
173 int watch_readback_valid;
174
175 /* Cached watch register read values. */
176
177 struct pt_watch_regs watch_readback;
178
179 /* Current watchpoint requests for this process. */
180
181 struct mips_watchpoint *current_watches;
182
183 /* The current set of watch register values for writing the
184 registers. */
185
186 struct pt_watch_regs watch_mirror;
187};
188
189/* Per-thread arch-specific data we want to keep. */
190
191struct arch_lwp_info
192{
193 /* Non-zero if our copy differs from what's recorded in the thread. */
194 int watch_registers_changed;
195};
196
0a30fbc4
DJ
197/* From mips-linux-nat.c. */
198
199/* Pseudo registers can not be read. ptrace does not provide a way to
200 read (or set) PS_REGNUM, and there's no point in reading or setting
201 ZERO_REGNUM. We also can not set BADVADDR, CAUSE, or FCRIR via
202 ptrace(). */
203
2ec06d2e
DJ
204static int
205mips_cannot_fetch_register (int regno)
0a30fbc4 206{
3aee8918
PA
207 const struct target_desc *tdesc;
208
209 if (get_usrregs_info ()->regmap[regno] == -1)
0a30fbc4
DJ
210 return 1;
211
3aee8918
PA
212 tdesc = current_process ()->tdesc;
213
214 if (find_regno (tdesc, "r0") == regno)
0a30fbc4
DJ
215 return 1;
216
217 return 0;
218}
219
2ec06d2e
DJ
220static int
221mips_cannot_store_register (int regno)
0a30fbc4 222{
3aee8918
PA
223 const struct target_desc *tdesc;
224
225 if (get_usrregs_info ()->regmap[regno] == -1)
0a30fbc4
DJ
226 return 1;
227
3aee8918
PA
228 tdesc = current_process ()->tdesc;
229
230 if (find_regno (tdesc, "r0") == regno)
0a30fbc4
DJ
231 return 1;
232
3aee8918 233 if (find_regno (tdesc, "cause") == regno)
0a30fbc4
DJ
234 return 1;
235
3aee8918 236 if (find_regno (tdesc, "badvaddr") == regno)
0a30fbc4
DJ
237 return 1;
238
3aee8918 239 if (find_regno (tdesc, "fir") == regno)
0a30fbc4
DJ
240 return 1;
241
242 return 0;
243}
2ec06d2e 244
0d62e5e8 245static CORE_ADDR
442ea881 246mips_get_pc (struct regcache *regcache)
0d62e5e8 247{
186947f7 248 union mips_register pc;
442ea881 249 collect_register_by_name (regcache, "pc", pc.buf);
3aee8918 250 return register_size (regcache->tdesc, 0) == 4 ? pc.reg32 : pc.reg64;
0d62e5e8
DJ
251}
252
253static void
442ea881 254mips_set_pc (struct regcache *regcache, CORE_ADDR pc)
0d62e5e8 255{
186947f7 256 union mips_register newpc;
3aee8918 257 if (register_size (regcache->tdesc, 0) == 4)
186947f7
DJ
258 newpc.reg32 = pc;
259 else
260 newpc.reg64 = pc;
261
442ea881 262 supply_register_by_name (regcache, "pc", newpc.buf);
0d62e5e8
DJ
263}
264
265/* Correct in either endianness. */
186947f7 266static const unsigned int mips_breakpoint = 0x0005000d;
0d62e5e8
DJ
267#define mips_breakpoint_len 4
268
dd373349
AT
269/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
270
271static const gdb_byte *
272mips_sw_breakpoint_from_kind (int kind, int *size)
273{
274 *size = mips_breakpoint_len;
275 return (const gdb_byte *) &mips_breakpoint;
276}
277
0d62e5e8
DJ
278static int
279mips_breakpoint_at (CORE_ADDR where)
280{
186947f7 281 unsigned int insn;
0d62e5e8 282
f450004a 283 (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
0d62e5e8
DJ
284 if (insn == mips_breakpoint)
285 return 1;
286
287 /* If necessary, recognize more trap instructions here. GDB only uses the
288 one. */
289 return 0;
290}
291
da25033c 292/* Mark the watch registers of lwp, represented by ENTRY, as changed. */
7a60ad40 293
da25033c
SM
294static void
295update_watch_registers_callback (thread_info *thread)
7a60ad40 296{
d86d4aaf 297 struct lwp_info *lwp = get_thread_lwp (thread);
7a60ad40 298
da25033c
SM
299 /* The actual update is done later just before resuming the lwp,
300 we just mark that the registers need updating. */
301 lwp->arch_private->watch_registers_changed = 1;
7a60ad40 302
da25033c
SM
303 /* If the lwp isn't stopped, force it to momentarily pause, so
304 we can update its watch registers. */
305 if (!lwp->stopped)
306 linux_stop_lwp (lwp);
7a60ad40
YQ
307}
308
309/* This is the implementation of linux_target_ops method
310 new_process. */
311
312static struct arch_process_info *
313mips_linux_new_process (void)
314{
8d749320 315 struct arch_process_info *info = XCNEW (struct arch_process_info);
7a60ad40
YQ
316
317 return info;
318}
319
04ec7890
SM
320/* This is the implementation of linux_target_ops method
321 delete_process. */
322
323static void
324mips_linux_delete_process (struct arch_process_info *info)
325{
326 xfree (info);
327}
328
7a60ad40
YQ
329/* This is the implementation of linux_target_ops method new_thread.
330 Mark the watch registers as changed, so the threads' copies will
331 be updated. */
332
34c703da
GB
333static void
334mips_linux_new_thread (struct lwp_info *lwp)
7a60ad40 335{
8d749320 336 struct arch_lwp_info *info = XCNEW (struct arch_lwp_info);
7a60ad40
YQ
337
338 info->watch_registers_changed = 1;
339
34c703da 340 lwp->arch_private = info;
7a60ad40
YQ
341}
342
466eecee
SM
343/* Function to call when a thread is being deleted. */
344
345static void
346mips_linux_delete_thread (struct arch_lwp_info *arch_lwp)
347{
348 xfree (arch_lwp);
349}
350
3a8a0396
DB
351/* Create a new mips_watchpoint and add it to the list. */
352
353static void
cbec665b 354mips_add_watchpoint (struct arch_process_info *priv, CORE_ADDR addr, int len,
eb3e3c67 355 enum target_hw_bp_type watch_type)
3a8a0396
DB
356{
357 struct mips_watchpoint *new_watch;
358 struct mips_watchpoint **pw;
359
8d749320 360 new_watch = XNEW (struct mips_watchpoint);
3a8a0396
DB
361 new_watch->addr = addr;
362 new_watch->len = len;
363 new_watch->type = watch_type;
364 new_watch->next = NULL;
365
cbec665b 366 pw = &priv->current_watches;
3a8a0396
DB
367 while (*pw != NULL)
368 pw = &(*pw)->next;
369 *pw = new_watch;
370}
371
372/* Hook to call when a new fork is attached. */
373
374static void
375mips_linux_new_fork (struct process_info *parent,
376 struct process_info *child)
377{
378 struct arch_process_info *parent_private;
379 struct arch_process_info *child_private;
380 struct mips_watchpoint *wp;
381
382 /* These are allocated by linux_add_process. */
61a7418c
DB
383 gdb_assert (parent->priv != NULL
384 && parent->priv->arch_private != NULL);
385 gdb_assert (child->priv != NULL
386 && child->priv->arch_private != NULL);
3a8a0396
DB
387
388 /* Linux kernel before 2.6.33 commit
389 72f674d203cd230426437cdcf7dd6f681dad8b0d
390 will inherit hardware debug registers from parent
391 on fork/vfork/clone. Newer Linux kernels create such tasks with
392 zeroed debug registers.
393
394 GDB core assumes the child inherits the watchpoints/hw
395 breakpoints of the parent, and will remove them all from the
396 forked off process. Copy the debug registers mirrors into the
397 new process so that all breakpoints and watchpoints can be
398 removed together. The debug registers mirror will become zeroed
399 in the end before detaching the forked off process, thus making
400 this compatible with older Linux kernels too. */
401
61a7418c
DB
402 parent_private = parent->priv->arch_private;
403 child_private = child->priv->arch_private;
3a8a0396
DB
404
405 child_private->watch_readback_valid = parent_private->watch_readback_valid;
406 child_private->watch_readback = parent_private->watch_readback;
407
408 for (wp = parent_private->current_watches; wp != NULL; wp = wp->next)
409 mips_add_watchpoint (child_private, wp->addr, wp->len, wp->type);
410
411 child_private->watch_mirror = parent_private->watch_mirror;
412}
7a60ad40
YQ
413/* This is the implementation of linux_target_ops method
414 prepare_to_resume. If the watch regs have changed, update the
415 thread's copies. */
416
417static void
418mips_linux_prepare_to_resume (struct lwp_info *lwp)
419{
d86d4aaf 420 ptid_t ptid = ptid_of (get_lwp_thread (lwp));
7a60ad40 421 struct process_info *proc = find_process_pid (ptid_get_pid (ptid));
fe978cb0 422 struct arch_process_info *priv = proc->priv->arch_private;
7a60ad40
YQ
423
424 if (lwp->arch_private->watch_registers_changed)
425 {
426 /* Only update the watch registers if we have set or unset a
427 watchpoint already. */
fe978cb0 428 if (mips_linux_watch_get_num_valid (&priv->watch_mirror) > 0)
7a60ad40
YQ
429 {
430 /* Write the mirrored watch register values. */
431 int tid = ptid_get_lwp (ptid);
432
433 if (-1 == ptrace (PTRACE_SET_WATCH_REGS, tid,
aa58a496 434 &priv->watch_mirror, NULL))
7a60ad40
YQ
435 perror_with_name ("Couldn't write watch register");
436 }
437
438 lwp->arch_private->watch_registers_changed = 0;
439 }
440}
441
802e8e6d
PA
442static int
443mips_supports_z_point_type (char z_type)
444{
445 switch (z_type)
446 {
447 case Z_PACKET_WRITE_WP:
448 case Z_PACKET_READ_WP:
449 case Z_PACKET_ACCESS_WP:
450 return 1;
451 default:
452 return 0;
453 }
454}
455
7a60ad40
YQ
456/* This is the implementation of linux_target_ops method
457 insert_point. */
458
459static int
802e8e6d
PA
460mips_insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
461 int len, struct raw_breakpoint *bp)
7a60ad40
YQ
462{
463 struct process_info *proc = current_process ();
fe978cb0 464 struct arch_process_info *priv = proc->priv->arch_private;
7a60ad40 465 struct pt_watch_regs regs;
7a60ad40
YQ
466 long lwpid;
467 enum target_hw_bp_type watch_type;
468 uint32_t irw;
469
0bfdf32f 470 lwpid = lwpid_of (current_thread);
7a60ad40 471 if (!mips_linux_read_watch_registers (lwpid,
fe978cb0
PA
472 &priv->watch_readback,
473 &priv->watch_readback_valid,
7a60ad40
YQ
474 0))
475 return -1;
476
477 if (len <= 0)
478 return -1;
479
fe978cb0 480 regs = priv->watch_readback;
7a60ad40 481 /* Add the current watches. */
fe978cb0 482 mips_linux_watch_populate_regs (priv->current_watches, &regs);
7a60ad40
YQ
483
484 /* Now try to add the new watch. */
802e8e6d 485 watch_type = raw_bkpt_type_to_target_hw_bp_type (type);
7a60ad40
YQ
486 irw = mips_linux_watch_type_to_irw (watch_type);
487 if (!mips_linux_watch_try_one_watch (&regs, addr, len, irw))
488 return -1;
489
490 /* It fit. Stick it on the end of the list. */
3a8a0396 491 mips_add_watchpoint (priv, addr, len, watch_type);
7a60ad40 492
fe978cb0 493 priv->watch_mirror = regs;
7a60ad40
YQ
494
495 /* Only update the threads of this process. */
da25033c 496 for_each_thread (proc->pid, update_watch_registers_callback);
7a60ad40
YQ
497
498 return 0;
499}
500
501/* This is the implementation of linux_target_ops method
502 remove_point. */
503
504static int
802e8e6d
PA
505mips_remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
506 int len, struct raw_breakpoint *bp)
7a60ad40
YQ
507{
508 struct process_info *proc = current_process ();
fe978cb0 509 struct arch_process_info *priv = proc->priv->arch_private;
7a60ad40
YQ
510
511 int deleted_one;
7a60ad40
YQ
512 enum target_hw_bp_type watch_type;
513
514 struct mips_watchpoint **pw;
515 struct mips_watchpoint *w;
516
7a60ad40 517 /* Search for a known watch that matches. Then unlink and free it. */
802e8e6d 518 watch_type = raw_bkpt_type_to_target_hw_bp_type (type);
7a60ad40 519 deleted_one = 0;
fe978cb0 520 pw = &priv->current_watches;
7a60ad40
YQ
521 while ((w = *pw))
522 {
523 if (w->addr == addr && w->len == len && w->type == watch_type)
524 {
525 *pw = w->next;
526 free (w);
527 deleted_one = 1;
528 break;
529 }
530 pw = &(w->next);
531 }
532
533 if (!deleted_one)
534 return -1; /* We don't know about it, fail doing nothing. */
535
536 /* At this point watch_readback is known to be valid because we
537 could not have added the watch without reading it. */
fe978cb0 538 gdb_assert (priv->watch_readback_valid == 1);
7a60ad40 539
fe978cb0
PA
540 priv->watch_mirror = priv->watch_readback;
541 mips_linux_watch_populate_regs (priv->current_watches,
542 &priv->watch_mirror);
7a60ad40
YQ
543
544 /* Only update the threads of this process. */
da25033c
SM
545 for_each_thread (proc->pid, update_watch_registers_callback);
546
7a60ad40
YQ
547 return 0;
548}
549
550/* This is the implementation of linux_target_ops method
551 stopped_by_watchpoint. The watchhi R and W bits indicate
552 the watch register triggered. */
553
554static int
555mips_stopped_by_watchpoint (void)
556{
557 struct process_info *proc = current_process ();
fe978cb0 558 struct arch_process_info *priv = proc->priv->arch_private;
7a60ad40
YQ
559 int n;
560 int num_valid;
0bfdf32f 561 long lwpid = lwpid_of (current_thread);
7a60ad40
YQ
562
563 if (!mips_linux_read_watch_registers (lwpid,
fe978cb0
PA
564 &priv->watch_readback,
565 &priv->watch_readback_valid,
7a60ad40
YQ
566 1))
567 return 0;
568
fe978cb0 569 num_valid = mips_linux_watch_get_num_valid (&priv->watch_readback);
7a60ad40
YQ
570
571 for (n = 0; n < MAX_DEBUG_REGISTER && n < num_valid; n++)
fe978cb0 572 if (mips_linux_watch_get_watchhi (&priv->watch_readback, n)
7a60ad40
YQ
573 & (R_MASK | W_MASK))
574 return 1;
575
576 return 0;
577}
578
579/* This is the implementation of linux_target_ops method
580 stopped_data_address. */
581
582static CORE_ADDR
583mips_stopped_data_address (void)
584{
585 struct process_info *proc = current_process ();
fe978cb0 586 struct arch_process_info *priv = proc->priv->arch_private;
7a60ad40
YQ
587 int n;
588 int num_valid;
0bfdf32f 589 long lwpid = lwpid_of (current_thread);
7a60ad40
YQ
590
591 /* On MIPS we don't know the low order 3 bits of the data address.
592 GDB does not support remote targets that can't report the
593 watchpoint address. So, make our best guess; return the starting
594 address of a watchpoint request which overlaps the one that
595 triggered. */
596
597 if (!mips_linux_read_watch_registers (lwpid,
fe978cb0
PA
598 &priv->watch_readback,
599 &priv->watch_readback_valid,
7a60ad40
YQ
600 0))
601 return 0;
602
fe978cb0 603 num_valid = mips_linux_watch_get_num_valid (&priv->watch_readback);
7a60ad40
YQ
604
605 for (n = 0; n < MAX_DEBUG_REGISTER && n < num_valid; n++)
fe978cb0 606 if (mips_linux_watch_get_watchhi (&priv->watch_readback, n)
7a60ad40
YQ
607 & (R_MASK | W_MASK))
608 {
609 CORE_ADDR t_low, t_hi;
610 int t_irw;
611 struct mips_watchpoint *watch;
612
fe978cb0 613 t_low = mips_linux_watch_get_watchlo (&priv->watch_readback, n);
7a60ad40 614 t_irw = t_low & IRW_MASK;
fe978cb0 615 t_hi = (mips_linux_watch_get_watchhi (&priv->watch_readback, n)
7a60ad40
YQ
616 | IRW_MASK);
617 t_low &= ~(CORE_ADDR)t_hi;
618
fe978cb0 619 for (watch = priv->current_watches;
7a60ad40
YQ
620 watch != NULL;
621 watch = watch->next)
622 {
623 CORE_ADDR addr = watch->addr;
624 CORE_ADDR last_byte = addr + watch->len - 1;
625
626 if ((t_irw & mips_linux_watch_type_to_irw (watch->type)) == 0)
627 {
628 /* Different type. */
629 continue;
630 }
631 /* Check for overlap of even a single byte. */
632 if (last_byte >= t_low && addr <= t_low + t_hi)
633 return addr;
634 }
635 }
636
637 /* Shouldn't happen. */
638 return 0;
639}
640
21b0f40c
DJ
641/* Fetch the thread-local storage pointer for libthread_db. */
642
643ps_err_e
754653a7 644ps_get_thread_area (struct ps_prochandle *ph,
1b3f6016 645 lwpid_t lwpid, int idx, void **base)
21b0f40c
DJ
646{
647 if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
648 return PS_ERR;
649
650 /* IDX is the bias from the thread pointer to the beginning of the
651 thread descriptor. It has to be subtracted due to implementation
652 quirks in libthread_db. */
653 *base = (void *) ((char *)*base - idx);
654
655 return PS_OK;
656}
657
186947f7
DJ
658#ifdef HAVE_PTRACE_GETREGS
659
660static void
442ea881
PA
661mips_collect_register (struct regcache *regcache,
662 int use_64bit, int regno, union mips_register *reg)
186947f7
DJ
663{
664 union mips_register tmp_reg;
665
666 if (use_64bit)
667 {
442ea881 668 collect_register (regcache, regno, &tmp_reg.reg64);
186947f7
DJ
669 *reg = tmp_reg;
670 }
671 else
672 {
442ea881 673 collect_register (regcache, regno, &tmp_reg.reg32);
186947f7
DJ
674 reg->reg64 = tmp_reg.reg32;
675 }
676}
677
678static void
442ea881
PA
679mips_supply_register (struct regcache *regcache,
680 int use_64bit, int regno, const union mips_register *reg)
186947f7
DJ
681{
682 int offset = 0;
683
684 /* For big-endian 32-bit targets, ignore the high four bytes of each
685 eight-byte slot. */
686 if (__BYTE_ORDER == __BIG_ENDIAN && !use_64bit)
687 offset = 4;
688
442ea881 689 supply_register (regcache, regno, reg->buf + offset);
186947f7
DJ
690}
691
692static void
442ea881
PA
693mips_collect_register_32bit (struct regcache *regcache,
694 int use_64bit, int regno, unsigned char *buf)
186947f7
DJ
695{
696 union mips_register tmp_reg;
697 int reg32;
698
442ea881 699 mips_collect_register (regcache, use_64bit, regno, &tmp_reg);
186947f7
DJ
700 reg32 = tmp_reg.reg64;
701 memcpy (buf, &reg32, 4);
702}
703
704static void
442ea881
PA
705mips_supply_register_32bit (struct regcache *regcache,
706 int use_64bit, int regno, const unsigned char *buf)
186947f7
DJ
707{
708 union mips_register tmp_reg;
709 int reg32;
710
711 memcpy (&reg32, buf, 4);
712 tmp_reg.reg64 = reg32;
442ea881 713 mips_supply_register (regcache, use_64bit, regno, &tmp_reg);
186947f7
DJ
714}
715
716static void
442ea881 717mips_fill_gregset (struct regcache *regcache, void *buf)
186947f7 718{
1996e237 719 union mips_register *regset = (union mips_register *) buf;
186947f7 720 int i, use_64bit;
3aee8918 721 const struct target_desc *tdesc = regcache->tdesc;
186947f7 722
3aee8918 723 use_64bit = (register_size (tdesc, 0) == 8);
186947f7 724
117ce543 725 for (i = 1; i < 32; i++)
442ea881
PA
726 mips_collect_register (regcache, use_64bit, i, regset + i);
727
728 mips_collect_register (regcache, use_64bit,
3aee8918 729 find_regno (tdesc, "lo"), regset + 32);
442ea881 730 mips_collect_register (regcache, use_64bit,
3aee8918 731 find_regno (tdesc, "hi"), regset + 33);
442ea881 732 mips_collect_register (regcache, use_64bit,
3aee8918 733 find_regno (tdesc, "pc"), regset + 34);
442ea881 734 mips_collect_register (regcache, use_64bit,
3aee8918 735 find_regno (tdesc, "badvaddr"), regset + 35);
442ea881 736 mips_collect_register (regcache, use_64bit,
3aee8918 737 find_regno (tdesc, "status"), regset + 36);
442ea881 738 mips_collect_register (regcache, use_64bit,
3aee8918 739 find_regno (tdesc, "cause"), regset + 37);
442ea881
PA
740
741 mips_collect_register (regcache, use_64bit,
3aee8918 742 find_regno (tdesc, "restart"), regset + 0);
186947f7
DJ
743}
744
745static void
442ea881 746mips_store_gregset (struct regcache *regcache, const void *buf)
186947f7 747{
1996e237 748 const union mips_register *regset = (const union mips_register *) buf;
186947f7
DJ
749 int i, use_64bit;
750
3aee8918 751 use_64bit = (register_size (regcache->tdesc, 0) == 8);
186947f7
DJ
752
753 for (i = 0; i < 32; i++)
442ea881
PA
754 mips_supply_register (regcache, use_64bit, i, regset + i);
755
442ea881 756 mips_supply_register (regcache, use_64bit,
3aee8918
PA
757 find_regno (regcache->tdesc, "lo"), regset + 32);
758 mips_supply_register (regcache, use_64bit,
759 find_regno (regcache->tdesc, "hi"), regset + 33);
442ea881 760 mips_supply_register (regcache, use_64bit,
3aee8918 761 find_regno (regcache->tdesc, "pc"), regset + 34);
442ea881 762 mips_supply_register (regcache, use_64bit,
3aee8918
PA
763 find_regno (regcache->tdesc, "badvaddr"), regset + 35);
764 mips_supply_register (regcache, use_64bit,
765 find_regno (regcache->tdesc, "status"), regset + 36);
766 mips_supply_register (regcache, use_64bit,
767 find_regno (regcache->tdesc, "cause"), regset + 37);
442ea881
PA
768
769 mips_supply_register (regcache, use_64bit,
3aee8918 770 find_regno (regcache->tdesc, "restart"), regset + 0);
186947f7
DJ
771}
772
773static void
442ea881 774mips_fill_fpregset (struct regcache *regcache, void *buf)
186947f7 775{
1996e237 776 union mips_register *regset = (union mips_register *) buf;
186947f7
DJ
777 int i, use_64bit, first_fp, big_endian;
778
3aee8918
PA
779 use_64bit = (register_size (regcache->tdesc, 0) == 8);
780 first_fp = find_regno (regcache->tdesc, "f0");
186947f7
DJ
781 big_endian = (__BYTE_ORDER == __BIG_ENDIAN);
782
783 /* See GDB for a discussion of this peculiar layout. */
784 for (i = 0; i < 32; i++)
785 if (use_64bit)
442ea881 786 collect_register (regcache, first_fp + i, regset[i].buf);
186947f7 787 else
442ea881 788 collect_register (regcache, first_fp + i,
186947f7
DJ
789 regset[i & ~1].buf + 4 * (big_endian != (i & 1)));
790
442ea881 791 mips_collect_register_32bit (regcache, use_64bit,
3aee8918
PA
792 find_regno (regcache->tdesc, "fcsr"), regset[32].buf);
793 mips_collect_register_32bit (regcache, use_64bit,
794 find_regno (regcache->tdesc, "fir"),
186947f7
DJ
795 regset[32].buf + 4);
796}
797
798static void
442ea881 799mips_store_fpregset (struct regcache *regcache, const void *buf)
186947f7 800{
1996e237 801 const union mips_register *regset = (const union mips_register *) buf;
186947f7
DJ
802 int i, use_64bit, first_fp, big_endian;
803
3aee8918
PA
804 use_64bit = (register_size (regcache->tdesc, 0) == 8);
805 first_fp = find_regno (regcache->tdesc, "f0");
186947f7
DJ
806 big_endian = (__BYTE_ORDER == __BIG_ENDIAN);
807
808 /* See GDB for a discussion of this peculiar layout. */
809 for (i = 0; i < 32; i++)
810 if (use_64bit)
442ea881 811 supply_register (regcache, first_fp + i, regset[i].buf);
186947f7 812 else
442ea881 813 supply_register (regcache, first_fp + i,
186947f7
DJ
814 regset[i & ~1].buf + 4 * (big_endian != (i & 1)));
815
442ea881 816 mips_supply_register_32bit (regcache, use_64bit,
3aee8918
PA
817 find_regno (regcache->tdesc, "fcsr"),
818 regset[32].buf);
819 mips_supply_register_32bit (regcache, use_64bit,
820 find_regno (regcache->tdesc, "fir"),
186947f7
DJ
821 regset[32].buf + 4);
822}
823#endif /* HAVE_PTRACE_GETREGS */
824
3aee8918 825static struct regset_info mips_regsets[] = {
186947f7 826#ifdef HAVE_PTRACE_GETREGS
1570b33e 827 { PTRACE_GETREGS, PTRACE_SETREGS, 0, 38 * 8, GENERAL_REGS,
186947f7 828 mips_fill_gregset, mips_store_gregset },
1570b33e 829 { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 0, 33 * 8, FP_REGS,
186947f7
DJ
830 mips_fill_fpregset, mips_store_fpregset },
831#endif /* HAVE_PTRACE_GETREGS */
50bc912a 832 NULL_REGSET
186947f7
DJ
833};
834
3aee8918
PA
835static struct regsets_info mips_regsets_info =
836 {
837 mips_regsets, /* regsets */
838 0, /* num_regsets */
839 NULL, /* disabled_regsets */
840 };
841
842static struct usrregs_info mips_dsp_usrregs_info =
843 {
844 mips_dsp_num_regs,
845 mips_dsp_regmap,
846 };
847
848static struct usrregs_info mips_usrregs_info =
849 {
850 mips_num_regs,
851 mips_regmap,
852 };
853
854static struct regs_info dsp_regs_info =
855 {
856 mips_dsp_regset_bitmap,
857 &mips_dsp_usrregs_info,
858 &mips_regsets_info
859 };
860
861static struct regs_info regs_info =
862 {
863 NULL, /* regset_bitmap */
864 &mips_usrregs_info,
865 &mips_regsets_info
866 };
867
868static const struct regs_info *
869mips_regs_info (void)
870{
871 if (have_dsp)
872 return &dsp_regs_info;
873 else
874 return &regs_info;
875}
876
2ec06d2e 877struct linux_target_ops the_low_target = {
1faeff08 878 mips_arch_setup,
3aee8918 879 mips_regs_info,
2ec06d2e
DJ
880 mips_cannot_fetch_register,
881 mips_cannot_store_register,
c14dfd32 882 NULL, /* fetch_register */
0d62e5e8
DJ
883 mips_get_pc,
884 mips_set_pc,
dd373349
AT
885 NULL, /* breakpoint_kind_from_pc */
886 mips_sw_breakpoint_from_kind,
fa5308bd 887 NULL, /* get_next_pcs */
0d62e5e8
DJ
888 0,
889 mips_breakpoint_at,
802e8e6d 890 mips_supports_z_point_type,
7a60ad40
YQ
891 mips_insert_point,
892 mips_remove_point,
893 mips_stopped_by_watchpoint,
894 mips_stopped_data_address,
895 NULL,
896 NULL,
897 NULL, /* siginfo_fixup */
898 mips_linux_new_process,
04ec7890 899 mips_linux_delete_process,
7a60ad40 900 mips_linux_new_thread,
466eecee 901 mips_linux_delete_thread,
3a8a0396 902 mips_linux_new_fork,
7a60ad40 903 mips_linux_prepare_to_resume
2ec06d2e 904};
3aee8918
PA
905
906void
907initialize_low_arch (void)
908{
909 /* Initialize the Linux target descriptions. */
910 init_registers_mips_linux ();
911 init_registers_mips_dsp_linux ();
912 init_registers_mips64_linux ();
913 init_registers_mips64_dsp_linux ();
914
915 initialize_regsets_info (&mips_regsets_info);
916}
This page took 1.430987 seconds and 4 git commands to generate.