Re: nios2: Remove binutils support for Nios II target
[binutils-gdb.git] / gdbserver / linux-mips-low.cc
blob3fb668231a6c71f2e41883a9d9ee4cf604a323fb
1 /* GNU/Linux/MIPS specific low level interface, for the remote server for GDB.
2 Copyright (C) 1995-2024 Free Software Foundation, Inc.
4 This file is part of GDB.
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.
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.
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/>. */
19 #include "linux-low.h"
21 #include "nat/gdb_ptrace.h"
22 #include <endian.h>
24 #include "nat/mips-linux-watch.h"
25 #include "gdb_proc_service.h"
27 /* Linux target op definitions for the MIPS architecture. */
29 class mips_target : public linux_process_target
31 public:
33 const regs_info *get_regs_info () override;
35 const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override;
37 bool supports_z_point_type (char z_type) override;
39 protected:
41 void low_arch_setup () override;
43 bool low_cannot_fetch_register (int regno) override;
45 bool low_cannot_store_register (int regno) override;
47 bool low_fetch_register (regcache *regcache, int regno) override;
49 bool low_supports_breakpoints () override;
51 CORE_ADDR low_get_pc (regcache *regcache) override;
53 void low_set_pc (regcache *regcache, CORE_ADDR newpc) override;
55 bool low_breakpoint_at (CORE_ADDR pc) override;
57 int low_insert_point (raw_bkpt_type type, CORE_ADDR addr,
58 int size, raw_breakpoint *bp) override;
60 int low_remove_point (raw_bkpt_type type, CORE_ADDR addr,
61 int size, raw_breakpoint *bp) override;
63 bool low_stopped_by_watchpoint () override;
65 CORE_ADDR low_stopped_data_address () override;
67 void low_collect_ptrace_register (regcache *regcache, int regno,
68 char *buf) override;
70 void low_supply_ptrace_register (regcache *regcache, int regno,
71 const char *buf) override;
73 arch_process_info *low_new_process () override;
75 void low_delete_process (arch_process_info *info) override;
77 void low_new_thread (lwp_info *) override;
79 void low_delete_thread (arch_lwp_info *) override;
81 void low_new_fork (process_info *parent, process_info *child) override;
83 void low_prepare_to_resume (lwp_info *lwp) override;
86 /* The singleton target ops object. */
88 static mips_target the_mips_target;
90 /* Defined in auto-generated file mips-linux.c. */
91 void init_registers_mips_linux (void);
92 extern const struct target_desc *tdesc_mips_linux;
94 /* Defined in auto-generated file mips-dsp-linux.c. */
95 void init_registers_mips_dsp_linux (void);
96 extern const struct target_desc *tdesc_mips_dsp_linux;
98 /* Defined in auto-generated file mips64-linux.c. */
99 void init_registers_mips64_linux (void);
100 extern const struct target_desc *tdesc_mips64_linux;
102 /* Defined in auto-generated file mips64-dsp-linux.c. */
103 void init_registers_mips64_dsp_linux (void);
104 extern const struct target_desc *tdesc_mips64_dsp_linux;
106 #ifdef __mips64
107 #define tdesc_mips_linux tdesc_mips64_linux
108 #define tdesc_mips_dsp_linux tdesc_mips64_dsp_linux
109 #endif
111 #ifndef PTRACE_GET_THREAD_AREA
112 #define PTRACE_GET_THREAD_AREA 25
113 #endif
115 #ifdef HAVE_SYS_REG_H
116 #include <sys/reg.h>
117 #endif
119 #define mips_num_regs 73
120 #define mips_dsp_num_regs 80
122 #include <asm/ptrace.h>
124 #ifndef DSP_BASE
125 #define DSP_BASE 71
126 #define DSP_CONTROL 77
127 #endif
129 union mips_register
131 unsigned char buf[8];
133 /* Deliberately signed, for proper sign extension. */
134 int reg32;
135 long long reg64;
138 /* Return the ptrace ``address'' of register REGNO. */
140 #define mips_base_regs \
141 -1, 1, 2, 3, 4, 5, 6, 7, \
142 8, 9, 10, 11, 12, 13, 14, 15, \
143 16, 17, 18, 19, 20, 21, 22, 23, \
144 24, 25, 26, 27, 28, 29, 30, 31, \
146 -1, MMLO, MMHI, BADVADDR, CAUSE, PC, \
148 FPR_BASE, FPR_BASE + 1, FPR_BASE + 2, FPR_BASE + 3, \
149 FPR_BASE + 4, FPR_BASE + 5, FPR_BASE + 6, FPR_BASE + 7, \
150 FPR_BASE + 8, FPR_BASE + 9, FPR_BASE + 10, FPR_BASE + 11, \
151 FPR_BASE + 12, FPR_BASE + 13, FPR_BASE + 14, FPR_BASE + 15, \
152 FPR_BASE + 16, FPR_BASE + 17, FPR_BASE + 18, FPR_BASE + 19, \
153 FPR_BASE + 20, FPR_BASE + 21, FPR_BASE + 22, FPR_BASE + 23, \
154 FPR_BASE + 24, FPR_BASE + 25, FPR_BASE + 26, FPR_BASE + 27, \
155 FPR_BASE + 28, FPR_BASE + 29, FPR_BASE + 30, FPR_BASE + 31, \
156 FPC_CSR, FPC_EIR
158 #define mips_dsp_regs \
159 DSP_BASE, DSP_BASE + 1, DSP_BASE + 2, DSP_BASE + 3, \
160 DSP_BASE + 4, DSP_BASE + 5, \
161 DSP_CONTROL
163 static int mips_regmap[mips_num_regs] = {
164 mips_base_regs,
168 static int mips_dsp_regmap[mips_dsp_num_regs] = {
169 mips_base_regs,
170 mips_dsp_regs,
174 /* DSP registers are not in any regset and can only be accessed
175 individually. */
177 static unsigned char mips_dsp_regset_bitmap[(mips_dsp_num_regs + 7) / 8] = {
178 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x80
181 static int have_dsp = -1;
183 /* Try peeking at an arbitrarily chosen DSP register and pick the available
184 user register set accordingly. */
186 static const struct target_desc *
187 mips_read_description (void)
189 if (have_dsp < 0)
191 int pid = current_thread->id.lwp ();
193 errno = 0;
194 ptrace (PTRACE_PEEKUSER, pid, DSP_CONTROL, 0);
195 switch (errno)
197 case 0:
198 have_dsp = 1;
199 break;
200 case EIO:
201 have_dsp = 0;
202 break;
203 default:
204 perror_with_name ("ptrace");
205 break;
209 return have_dsp ? tdesc_mips_dsp_linux : tdesc_mips_linux;
212 void
213 mips_target::low_arch_setup ()
215 current_process ()->tdesc = mips_read_description ();
218 /* Per-process arch-specific data we want to keep. */
220 struct arch_process_info
222 /* -1 if the kernel and/or CPU do not support watch registers.
223 1 if watch_readback is valid and we can read style, num_valid
224 and the masks.
225 0 if we need to read the watch_readback. */
227 int watch_readback_valid;
229 /* Cached watch register read values. */
231 struct pt_watch_regs watch_readback;
233 /* Current watchpoint requests for this process. */
235 struct mips_watchpoint *current_watches;
237 /* The current set of watch register values for writing the
238 registers. */
240 struct pt_watch_regs watch_mirror;
243 /* Per-thread arch-specific data we want to keep. */
245 struct arch_lwp_info
247 /* Non-zero if our copy differs from what's recorded in the thread. */
248 int watch_registers_changed;
251 /* From mips-linux-nat.c. */
253 /* Pseudo registers can not be read. ptrace does not provide a way to
254 read (or set) PS_REGNUM, and there's no point in reading or setting
255 ZERO_REGNUM, it's always 0. We also can not set BADVADDR, CAUSE,
256 or FCRIR via ptrace(). */
258 bool
259 mips_target::low_cannot_fetch_register (int regno)
261 const struct target_desc *tdesc;
263 if (get_regs_info ()->usrregs->regmap[regno] == -1)
264 return true;
266 tdesc = current_process ()->tdesc;
268 /* On n32 we can't access 64-bit registers via PTRACE_PEEKUSR. */
269 if (register_size (tdesc, regno) > sizeof (PTRACE_XFER_TYPE))
270 return true;
272 if (find_regno (tdesc, "r0") == regno)
273 return true;
275 return false;
278 bool
279 mips_target::low_cannot_store_register (int regno)
281 const struct target_desc *tdesc;
283 if (get_regs_info ()->usrregs->regmap[regno] == -1)
284 return true;
286 tdesc = current_process ()->tdesc;
288 /* On n32 we can't access 64-bit registers via PTRACE_POKEUSR. */
289 if (register_size (tdesc, regno) > sizeof (PTRACE_XFER_TYPE))
290 return true;
292 if (find_regno (tdesc, "r0") == regno)
293 return true;
295 if (find_regno (tdesc, "cause") == regno)
296 return true;
298 if (find_regno (tdesc, "badvaddr") == regno)
299 return true;
301 if (find_regno (tdesc, "fir") == regno)
302 return true;
304 return false;
307 bool
308 mips_target::low_fetch_register (regcache *regcache, int regno)
310 const struct target_desc *tdesc = current_process ()->tdesc;
312 if (find_regno (tdesc, "r0") == regno)
314 supply_register_zeroed (regcache, regno);
315 return true;
318 return false;
321 bool
322 mips_target::low_supports_breakpoints ()
324 return true;
327 CORE_ADDR
328 mips_target::low_get_pc (regcache *regcache)
330 union mips_register pc;
331 collect_register_by_name (regcache, "pc", pc.buf);
332 return register_size (regcache->tdesc, 0) == 4 ? pc.reg32 : pc.reg64;
335 void
336 mips_target::low_set_pc (regcache *regcache, CORE_ADDR pc)
338 union mips_register newpc;
339 if (register_size (regcache->tdesc, 0) == 4)
340 newpc.reg32 = pc;
341 else
342 newpc.reg64 = pc;
344 supply_register_by_name (regcache, "pc", newpc.buf);
347 /* Correct in either endianness. */
348 static const unsigned int mips_breakpoint = 0x0005000d;
349 #define mips_breakpoint_len 4
351 /* Implementation of target ops method "sw_breakpoint_from_kind". */
353 const gdb_byte *
354 mips_target::sw_breakpoint_from_kind (int kind, int *size)
356 *size = mips_breakpoint_len;
357 return (const gdb_byte *) &mips_breakpoint;
360 bool
361 mips_target::low_breakpoint_at (CORE_ADDR where)
363 unsigned int insn;
365 read_memory (where, (unsigned char *) &insn, 4);
366 if (insn == mips_breakpoint)
367 return true;
369 /* If necessary, recognize more trap instructions here. GDB only uses the
370 one. */
371 return false;
374 /* Mark the watch registers of lwp, represented by ENTRY, as changed. */
376 static void
377 update_watch_registers_callback (thread_info *thread)
379 struct lwp_info *lwp = get_thread_lwp (thread);
381 /* The actual update is done later just before resuming the lwp,
382 we just mark that the registers need updating. */
383 lwp->arch_private->watch_registers_changed = 1;
385 /* If the lwp isn't stopped, force it to momentarily pause, so
386 we can update its watch registers. */
387 if (!lwp->stopped)
388 linux_stop_lwp (lwp);
391 /* This is the implementation of linux target ops method
392 low_new_process. */
394 arch_process_info *
395 mips_target::low_new_process ()
397 struct arch_process_info *info = XCNEW (struct arch_process_info);
399 return info;
402 /* This is the implementation of linux target ops method
403 low_delete_process. */
405 void
406 mips_target::low_delete_process (arch_process_info *info)
408 xfree (info);
411 /* This is the implementation of linux target ops method low_new_thread.
412 Mark the watch registers as changed, so the threads' copies will
413 be updated. */
415 void
416 mips_target::low_new_thread (lwp_info *lwp)
418 struct arch_lwp_info *info = XCNEW (struct arch_lwp_info);
420 info->watch_registers_changed = 1;
422 lwp->arch_private = info;
425 /* Function to call when a thread is being deleted. */
427 void
428 mips_target::low_delete_thread (arch_lwp_info *arch_lwp)
430 xfree (arch_lwp);
433 /* Create a new mips_watchpoint and add it to the list. */
435 static void
436 mips_add_watchpoint (struct arch_process_info *priv, CORE_ADDR addr, int len,
437 enum target_hw_bp_type watch_type)
439 struct mips_watchpoint *new_watch;
440 struct mips_watchpoint **pw;
442 new_watch = XNEW (struct mips_watchpoint);
443 new_watch->addr = addr;
444 new_watch->len = len;
445 new_watch->type = watch_type;
446 new_watch->next = NULL;
448 pw = &priv->current_watches;
449 while (*pw != NULL)
450 pw = &(*pw)->next;
451 *pw = new_watch;
454 /* Hook to call when a new fork is attached. */
456 void
457 mips_target::low_new_fork (process_info *parent,
458 process_info *child)
460 struct arch_process_info *parent_private;
461 struct arch_process_info *child_private;
462 struct mips_watchpoint *wp;
464 /* These are allocated by linux_add_process. */
465 gdb_assert (parent->priv != NULL
466 && parent->priv->arch_private != NULL);
467 gdb_assert (child->priv != NULL
468 && child->priv->arch_private != NULL);
470 /* Linux kernel before 2.6.33 commit
471 72f674d203cd230426437cdcf7dd6f681dad8b0d
472 will inherit hardware debug registers from parent
473 on fork/vfork/clone. Newer Linux kernels create such tasks with
474 zeroed debug registers.
476 GDB core assumes the child inherits the watchpoints/hw
477 breakpoints of the parent, and will remove them all from the
478 forked off process. Copy the debug registers mirrors into the
479 new process so that all breakpoints and watchpoints can be
480 removed together. The debug registers mirror will become zeroed
481 in the end before detaching the forked off process, thus making
482 this compatible with older Linux kernels too. */
484 parent_private = parent->priv->arch_private;
485 child_private = child->priv->arch_private;
487 child_private->watch_readback_valid = parent_private->watch_readback_valid;
488 child_private->watch_readback = parent_private->watch_readback;
490 for (wp = parent_private->current_watches; wp != NULL; wp = wp->next)
491 mips_add_watchpoint (child_private, wp->addr, wp->len, wp->type);
493 child_private->watch_mirror = parent_private->watch_mirror;
495 /* This is the implementation of linux target ops method
496 low_prepare_to_resume. If the watch regs have changed, update the
497 thread's copies. */
499 void
500 mips_target::low_prepare_to_resume (lwp_info *lwp)
502 ptid_t ptid = get_lwp_thread (lwp)->id;
503 struct process_info *proc = find_process_pid (ptid.pid ());
504 struct arch_process_info *priv = proc->priv->arch_private;
506 if (lwp->arch_private->watch_registers_changed)
508 /* Only update the watch registers if we have set or unset a
509 watchpoint already. */
510 if (mips_linux_watch_get_num_valid (&priv->watch_mirror) > 0)
512 /* Write the mirrored watch register values. */
513 int tid = ptid.lwp ();
515 if (-1 == ptrace (PTRACE_SET_WATCH_REGS, tid,
516 &priv->watch_mirror, NULL))
517 perror_with_name ("Couldn't write watch register");
520 lwp->arch_private->watch_registers_changed = 0;
524 bool
525 mips_target::supports_z_point_type (char z_type)
527 switch (z_type)
529 case Z_PACKET_WRITE_WP:
530 case Z_PACKET_READ_WP:
531 case Z_PACKET_ACCESS_WP:
532 return true;
533 default:
534 return false;
538 /* This is the implementation of linux target ops method
539 low_insert_point. */
542 mips_target::low_insert_point (raw_bkpt_type type, CORE_ADDR addr,
543 int len, raw_breakpoint *bp)
545 struct process_info *proc = current_process ();
546 struct arch_process_info *priv = proc->priv->arch_private;
547 struct pt_watch_regs regs;
548 long lwpid = current_thread->id.lwp ();
549 enum target_hw_bp_type watch_type;
550 uint32_t irw;
552 if (!mips_linux_read_watch_registers (lwpid,
553 &priv->watch_readback,
554 &priv->watch_readback_valid,
556 return -1;
558 if (len <= 0)
559 return -1;
561 regs = priv->watch_readback;
562 /* Add the current watches. */
563 mips_linux_watch_populate_regs (priv->current_watches, &regs);
565 /* Now try to add the new watch. */
566 watch_type = raw_bkpt_type_to_target_hw_bp_type (type);
567 irw = mips_linux_watch_type_to_irw (watch_type);
568 if (!mips_linux_watch_try_one_watch (&regs, addr, len, irw))
569 return -1;
571 /* It fit. Stick it on the end of the list. */
572 mips_add_watchpoint (priv, addr, len, watch_type);
574 priv->watch_mirror = regs;
576 /* Only update the threads of this process. */
577 proc->for_each_thread (update_watch_registers_callback);
579 return 0;
582 /* This is the implementation of linux target ops method
583 low_remove_point. */
586 mips_target::low_remove_point (raw_bkpt_type type, CORE_ADDR addr,
587 int len, raw_breakpoint *bp)
589 struct process_info *proc = current_process ();
590 struct arch_process_info *priv = proc->priv->arch_private;
592 int deleted_one;
593 enum target_hw_bp_type watch_type;
595 struct mips_watchpoint **pw;
596 struct mips_watchpoint *w;
598 /* Search for a known watch that matches. Then unlink and free it. */
599 watch_type = raw_bkpt_type_to_target_hw_bp_type (type);
600 deleted_one = 0;
601 pw = &priv->current_watches;
602 while ((w = *pw))
604 if (w->addr == addr && w->len == len && w->type == watch_type)
606 *pw = w->next;
607 free (w);
608 deleted_one = 1;
609 break;
611 pw = &(w->next);
614 if (!deleted_one)
615 return -1; /* We don't know about it, fail doing nothing. */
617 /* At this point watch_readback is known to be valid because we
618 could not have added the watch without reading it. */
619 gdb_assert (priv->watch_readback_valid == 1);
621 priv->watch_mirror = priv->watch_readback;
622 mips_linux_watch_populate_regs (priv->current_watches,
623 &priv->watch_mirror);
625 /* Only update the threads of this process. */
626 proc->for_each_thread (pid, update_watch_registers_callback);
628 return 0;
631 /* This is the implementation of linux target ops method
632 low_stopped_by_watchpoint. The watchhi R and W bits indicate
633 the watch register triggered. */
635 bool
636 mips_target::low_stopped_by_watchpoint ()
638 struct process_info *proc = current_process ();
639 struct arch_process_info *priv = proc->priv->arch_private;
640 int n;
641 int num_valid;
642 long lwpid = current_thread->id.lwp ();
644 if (!mips_linux_read_watch_registers (lwpid,
645 &priv->watch_readback,
646 &priv->watch_readback_valid,
648 return 0;
650 num_valid = mips_linux_watch_get_num_valid (&priv->watch_readback);
652 for (n = 0; n < MAX_DEBUG_REGISTER && n < num_valid; n++)
653 if (mips_linux_watch_get_watchhi (&priv->watch_readback, n)
654 & (R_MASK | W_MASK))
655 return true;
657 return false;
660 /* This is the implementation of linux target ops method
661 low_stopped_data_address. */
663 CORE_ADDR
664 mips_target::low_stopped_data_address ()
666 struct process_info *proc = current_process ();
667 struct arch_process_info *priv = proc->priv->arch_private;
668 int n;
669 int num_valid;
670 long lwpid = current_thread->id.lwp ();
672 /* On MIPS we don't know the low order 3 bits of the data address.
673 GDB does not support remote targets that can't report the
674 watchpoint address. So, make our best guess; return the starting
675 address of a watchpoint request which overlaps the one that
676 triggered. */
678 if (!mips_linux_read_watch_registers (lwpid,
679 &priv->watch_readback,
680 &priv->watch_readback_valid,
682 return 0;
684 num_valid = mips_linux_watch_get_num_valid (&priv->watch_readback);
686 for (n = 0; n < MAX_DEBUG_REGISTER && n < num_valid; n++)
687 if (mips_linux_watch_get_watchhi (&priv->watch_readback, n)
688 & (R_MASK | W_MASK))
690 CORE_ADDR t_low, t_hi;
691 int t_irw;
692 struct mips_watchpoint *watch;
694 t_low = mips_linux_watch_get_watchlo (&priv->watch_readback, n);
695 t_irw = t_low & IRW_MASK;
696 t_hi = (mips_linux_watch_get_watchhi (&priv->watch_readback, n)
697 | IRW_MASK);
698 t_low &= ~(CORE_ADDR)t_hi;
700 for (watch = priv->current_watches;
701 watch != NULL;
702 watch = watch->next)
704 CORE_ADDR addr = watch->addr;
705 CORE_ADDR last_byte = addr + watch->len - 1;
707 if ((t_irw & mips_linux_watch_type_to_irw (watch->type)) == 0)
709 /* Different type. */
710 continue;
712 /* Check for overlap of even a single byte. */
713 if (last_byte >= t_low && addr <= t_low + t_hi)
714 return addr;
718 /* Shouldn't happen. */
719 return 0;
722 /* Fetch the thread-local storage pointer for libthread_db. */
724 ps_err_e
725 ps_get_thread_area (struct ps_prochandle *ph,
726 lwpid_t lwpid, int idx, void **base)
728 if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
729 return PS_ERR;
731 /* IDX is the bias from the thread pointer to the beginning of the
732 thread descriptor. It has to be subtracted due to implementation
733 quirks in libthread_db. */
734 *base = (void *) ((char *)*base - idx);
736 return PS_OK;
739 static void
740 mips_collect_register (struct regcache *regcache,
741 int use_64bit, int regno, union mips_register *reg)
743 union mips_register tmp_reg;
745 if (use_64bit)
747 collect_register (regcache, regno, &tmp_reg.reg64);
748 *reg = tmp_reg;
750 else
752 collect_register (regcache, regno, &tmp_reg.reg32);
753 reg->reg64 = tmp_reg.reg32;
757 static void
758 mips_supply_register (struct regcache *regcache,
759 int use_64bit, int regno, const union mips_register *reg)
761 int offset = 0;
763 /* For big-endian 32-bit targets, ignore the high four bytes of each
764 eight-byte slot. */
765 if (__BYTE_ORDER == __BIG_ENDIAN && !use_64bit)
766 offset = 4;
768 supply_register (regcache, regno, reg->buf + offset);
771 #ifdef HAVE_PTRACE_GETREGS
773 static void
774 mips_collect_register_32bit (struct regcache *regcache,
775 int use_64bit, int regno, unsigned char *buf)
777 union mips_register tmp_reg;
778 int reg32;
780 mips_collect_register (regcache, use_64bit, regno, &tmp_reg);
781 reg32 = tmp_reg.reg64;
782 memcpy (buf, &reg32, 4);
785 static void
786 mips_supply_register_32bit (struct regcache *regcache,
787 int use_64bit, int regno, const unsigned char *buf)
789 union mips_register tmp_reg;
790 int reg32;
792 memcpy (&reg32, buf, 4);
793 tmp_reg.reg64 = reg32;
794 mips_supply_register (regcache, use_64bit, regno, &tmp_reg);
797 static void
798 mips_fill_gregset (struct regcache *regcache, void *buf)
800 union mips_register *regset = (union mips_register *) buf;
801 int i, use_64bit;
802 const struct target_desc *tdesc = regcache->tdesc;
804 use_64bit = (register_size (tdesc, 0) == 8);
806 for (i = 1; i < 32; i++)
807 mips_collect_register (regcache, use_64bit, i, regset + i);
809 mips_collect_register (regcache, use_64bit,
810 find_regno (tdesc, "lo"), regset + 32);
811 mips_collect_register (regcache, use_64bit,
812 find_regno (tdesc, "hi"), regset + 33);
813 mips_collect_register (regcache, use_64bit,
814 find_regno (tdesc, "pc"), regset + 34);
815 mips_collect_register (regcache, use_64bit,
816 find_regno (tdesc, "badvaddr"), regset + 35);
817 mips_collect_register (regcache, use_64bit,
818 find_regno (tdesc, "status"), regset + 36);
819 mips_collect_register (regcache, use_64bit,
820 find_regno (tdesc, "cause"), regset + 37);
822 mips_collect_register (regcache, use_64bit,
823 find_regno (tdesc, "restart"), regset + 0);
826 static void
827 mips_store_gregset (struct regcache *regcache, const void *buf)
829 const union mips_register *regset = (const union mips_register *) buf;
830 int i, use_64bit;
832 use_64bit = (register_size (regcache->tdesc, 0) == 8);
834 supply_register_by_name_zeroed (regcache, "r0");
836 for (i = 1; i < 32; i++)
837 mips_supply_register (regcache, use_64bit, i, regset + i);
839 mips_supply_register (regcache, use_64bit,
840 find_regno (regcache->tdesc, "lo"), regset + 32);
841 mips_supply_register (regcache, use_64bit,
842 find_regno (regcache->tdesc, "hi"), regset + 33);
843 mips_supply_register (regcache, use_64bit,
844 find_regno (regcache->tdesc, "pc"), regset + 34);
845 mips_supply_register (regcache, use_64bit,
846 find_regno (regcache->tdesc, "badvaddr"), regset + 35);
847 mips_supply_register (regcache, use_64bit,
848 find_regno (regcache->tdesc, "status"), regset + 36);
849 mips_supply_register (regcache, use_64bit,
850 find_regno (regcache->tdesc, "cause"), regset + 37);
852 mips_supply_register (regcache, use_64bit,
853 find_regno (regcache->tdesc, "restart"), regset + 0);
856 static void
857 mips_fill_fpregset (struct regcache *regcache, void *buf)
859 union mips_register *regset = (union mips_register *) buf;
860 int i, use_64bit, first_fp, big_endian;
862 use_64bit = (register_size (regcache->tdesc, 0) == 8);
863 first_fp = find_regno (regcache->tdesc, "f0");
864 big_endian = (__BYTE_ORDER == __BIG_ENDIAN);
866 /* See GDB for a discussion of this peculiar layout. */
867 for (i = 0; i < 32; i++)
868 if (use_64bit)
869 collect_register (regcache, first_fp + i, regset[i].buf);
870 else
871 collect_register (regcache, first_fp + i,
872 regset[i & ~1].buf + 4 * (big_endian != (i & 1)));
874 mips_collect_register_32bit (regcache, use_64bit,
875 find_regno (regcache->tdesc, "fcsr"), regset[32].buf);
876 mips_collect_register_32bit (regcache, use_64bit,
877 find_regno (regcache->tdesc, "fir"),
878 regset[32].buf + 4);
881 static void
882 mips_store_fpregset (struct regcache *regcache, const void *buf)
884 const union mips_register *regset = (const union mips_register *) buf;
885 int i, use_64bit, first_fp, big_endian;
887 use_64bit = (register_size (regcache->tdesc, 0) == 8);
888 first_fp = find_regno (regcache->tdesc, "f0");
889 big_endian = (__BYTE_ORDER == __BIG_ENDIAN);
891 /* See GDB for a discussion of this peculiar layout. */
892 for (i = 0; i < 32; i++)
893 if (use_64bit)
894 supply_register (regcache, first_fp + i, regset[i].buf);
895 else
896 supply_register (regcache, first_fp + i,
897 regset[i & ~1].buf + 4 * (big_endian != (i & 1)));
899 mips_supply_register_32bit (regcache, use_64bit,
900 find_regno (regcache->tdesc, "fcsr"),
901 regset[32].buf);
902 mips_supply_register_32bit (regcache, use_64bit,
903 find_regno (regcache->tdesc, "fir"),
904 regset[32].buf + 4);
906 #endif /* HAVE_PTRACE_GETREGS */
908 /* Take care of 32-bit registers with 64-bit ptrace, POKEUSER side. */
910 void
911 mips_target::low_collect_ptrace_register (regcache *regcache, int regno,
912 char *buf)
914 int use_64bit = sizeof (PTRACE_XFER_TYPE) == 8;
916 if (use_64bit && register_size (regcache->tdesc, regno) == 4)
918 union mips_register reg;
920 mips_collect_register (regcache, 0, regno, &reg);
921 memcpy (buf, &reg, sizeof (reg));
923 else
924 collect_register (regcache, regno, buf);
927 /* Take care of 32-bit registers with 64-bit ptrace, PEEKUSER side. */
929 void
930 mips_target::low_supply_ptrace_register (regcache *regcache, int regno,
931 const char *buf)
933 int use_64bit = sizeof (PTRACE_XFER_TYPE) == 8;
935 if (use_64bit && register_size (regcache->tdesc, regno) == 4)
937 union mips_register reg;
939 memcpy (&reg, buf, sizeof (reg));
940 mips_supply_register (regcache, 0, regno, &reg);
942 else
943 supply_register (regcache, regno, buf);
946 static struct regset_info mips_regsets[] = {
947 #ifdef HAVE_PTRACE_GETREGS
948 { PTRACE_GETREGS, PTRACE_SETREGS, 0, 38 * 8, GENERAL_REGS,
949 mips_fill_gregset, mips_store_gregset },
950 { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 0, 33 * 8, FP_REGS,
951 mips_fill_fpregset, mips_store_fpregset },
952 #endif /* HAVE_PTRACE_GETREGS */
953 NULL_REGSET
956 static struct regsets_info mips_regsets_info =
958 mips_regsets, /* regsets */
959 0, /* num_regsets */
960 NULL, /* disabled_regsets */
963 static struct usrregs_info mips_dsp_usrregs_info =
965 mips_dsp_num_regs,
966 mips_dsp_regmap,
969 static struct usrregs_info mips_usrregs_info =
971 mips_num_regs,
972 mips_regmap,
975 static struct regs_info dsp_regs_info =
977 mips_dsp_regset_bitmap,
978 &mips_dsp_usrregs_info,
979 &mips_regsets_info
982 static struct regs_info myregs_info =
984 NULL, /* regset_bitmap */
985 &mips_usrregs_info,
986 &mips_regsets_info
989 const regs_info *
990 mips_target::get_regs_info ()
992 if (have_dsp)
993 return &dsp_regs_info;
994 else
995 return &myregs_info;
998 /* The linux target ops object. */
1000 linux_process_target *the_linux_target = &the_mips_target;
1002 void
1003 initialize_low_arch (void)
1005 /* Initialize the Linux target descriptions. */
1006 init_registers_mips_linux ();
1007 init_registers_mips_dsp_linux ();
1008 init_registers_mips64_linux ();
1009 init_registers_mips64_dsp_linux ();
1011 initialize_regsets_info (&mips_regsets_info);