xref: /netbsd-src/external/gpl3/gdb/dist/gdbserver/linux-mips-low.cc (revision 64f917f5a88990e32dd65fcd4348042fa7f852b9)
1 /* GNU/Linux/MIPS specific low level interface, for the remote server for GDB.
2    Copyright (C) 1995-2024 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 "linux-low.h"
20 
21 #include "nat/gdb_ptrace.h"
22 #include <endian.h>
23 
24 #include "nat/mips-linux-watch.h"
25 #include "gdb_proc_service.h"
26 
27 /* Linux target op definitions for the MIPS architecture.  */
28 
29 class mips_target : public linux_process_target
30 {
31 public:
32 
33   const regs_info *get_regs_info () override;
34 
35   const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override;
36 
37   bool supports_z_point_type (char z_type) override;
38 
39 protected:
40 
41   void low_arch_setup () override;
42 
43   bool low_cannot_fetch_register (int regno) override;
44 
45   bool low_cannot_store_register (int regno) override;
46 
47   bool low_fetch_register (regcache *regcache, int regno) override;
48 
49   bool low_supports_breakpoints () override;
50 
51   CORE_ADDR low_get_pc (regcache *regcache) override;
52 
53   void low_set_pc (regcache *regcache, CORE_ADDR newpc) override;
54 
55   bool low_breakpoint_at (CORE_ADDR pc) override;
56 
57   int low_insert_point (raw_bkpt_type type, CORE_ADDR addr,
58 			int size, raw_breakpoint *bp) override;
59 
60   int low_remove_point (raw_bkpt_type type, CORE_ADDR addr,
61 			int size, raw_breakpoint *bp) override;
62 
63   bool low_stopped_by_watchpoint () override;
64 
65   CORE_ADDR low_stopped_data_address () override;
66 
67   void low_collect_ptrace_register (regcache *regcache, int regno,
68 				    char *buf) override;
69 
70   void low_supply_ptrace_register (regcache *regcache, int regno,
71 				   const char *buf) override;
72 
73   arch_process_info *low_new_process () override;
74 
75   void low_delete_process (arch_process_info *info) override;
76 
77   void low_new_thread (lwp_info *) override;
78 
79   void low_delete_thread (arch_lwp_info *) override;
80 
81   void low_new_fork (process_info *parent, process_info *child) override;
82 
83   void low_prepare_to_resume (lwp_info *lwp) override;
84 };
85 
86 /* The singleton target ops object.  */
87 
88 static mips_target the_mips_target;
89 
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;
93 
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;
97 
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;
101 
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;
105 
106 #ifdef __mips64
107 #define tdesc_mips_linux tdesc_mips64_linux
108 #define tdesc_mips_dsp_linux tdesc_mips64_dsp_linux
109 #endif
110 
111 #ifndef PTRACE_GET_THREAD_AREA
112 #define PTRACE_GET_THREAD_AREA 25
113 #endif
114 
115 #ifdef HAVE_SYS_REG_H
116 #include <sys/reg.h>
117 #endif
118 
119 #define mips_num_regs 73
120 #define mips_dsp_num_regs 80
121 
122 #include <asm/ptrace.h>
123 
124 #ifndef DSP_BASE
125 #define DSP_BASE 71
126 #define DSP_CONTROL 77
127 #endif
128 
129 union mips_register
130 {
131   unsigned char buf[8];
132 
133   /* Deliberately signed, for proper sign extension.  */
134   int reg32;
135   long long reg64;
136 };
137 
138 /* Return the ptrace ``address'' of register REGNO. */
139 
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,					\
145 									\
146   -1, MMLO, MMHI, BADVADDR, CAUSE, PC,					\
147 									\
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
157 
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
162 
163 static int mips_regmap[mips_num_regs] = {
164   mips_base_regs,
165   0
166 };
167 
168 static int mips_dsp_regmap[mips_dsp_num_regs] = {
169   mips_base_regs,
170   mips_dsp_regs,
171   0
172 };
173 
174 /* DSP registers are not in any regset and can only be accessed
175    individually.  */
176 
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
179 };
180 
181 static int have_dsp = -1;
182 
183 /* Try peeking at an arbitrarily chosen DSP register and pick the available
184    user register set accordingly.  */
185 
186 static const struct target_desc *
187 mips_read_description (void)
188 {
189   if (have_dsp < 0)
190     {
191       int pid = lwpid_of (current_thread);
192 
193       errno = 0;
194       ptrace (PTRACE_PEEKUSER, pid, DSP_CONTROL, 0);
195       switch (errno)
196 	{
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;
206 	}
207     }
208 
209   return have_dsp ? tdesc_mips_dsp_linux : tdesc_mips_linux;
210 }
211 
212 void
213 mips_target::low_arch_setup ()
214 {
215   current_process ()->tdesc = mips_read_description ();
216 }
217 
218 /* Per-process arch-specific data we want to keep.  */
219 
220 struct arch_process_info
221 {
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.  */
226 
227   int watch_readback_valid;
228 
229   /* Cached watch register read values.  */
230 
231   struct pt_watch_regs watch_readback;
232 
233   /* Current watchpoint requests for this process.  */
234 
235   struct mips_watchpoint *current_watches;
236 
237   /* The current set of watch register values for writing the
238      registers.  */
239 
240   struct pt_watch_regs watch_mirror;
241 };
242 
243 /* Per-thread arch-specific data we want to keep.  */
244 
245 struct arch_lwp_info
246 {
247   /* Non-zero if our copy differs from what's recorded in the thread.  */
248   int watch_registers_changed;
249 };
250 
251 /* From mips-linux-nat.c.  */
252 
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().  */
257 
258 bool
259 mips_target::low_cannot_fetch_register (int regno)
260 {
261   const struct target_desc *tdesc;
262 
263   if (get_regs_info ()->usrregs->regmap[regno] == -1)
264     return true;
265 
266   tdesc = current_process ()->tdesc;
267 
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;
271 
272   if (find_regno (tdesc, "r0") == regno)
273     return true;
274 
275   return false;
276 }
277 
278 bool
279 mips_target::low_cannot_store_register (int regno)
280 {
281   const struct target_desc *tdesc;
282 
283   if (get_regs_info ()->usrregs->regmap[regno] == -1)
284     return true;
285 
286   tdesc = current_process ()->tdesc;
287 
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;
291 
292   if (find_regno (tdesc, "r0") == regno)
293     return true;
294 
295   if (find_regno (tdesc, "cause") == regno)
296     return true;
297 
298   if (find_regno (tdesc, "badvaddr") == regno)
299     return true;
300 
301   if (find_regno (tdesc, "fir") == regno)
302     return true;
303 
304   return false;
305 }
306 
307 bool
308 mips_target::low_fetch_register (regcache *regcache, int regno)
309 {
310   const struct target_desc *tdesc = current_process ()->tdesc;
311 
312   if (find_regno (tdesc, "r0") == regno)
313     {
314       supply_register_zeroed (regcache, regno);
315       return true;
316     }
317 
318   return false;
319 }
320 
321 bool
322 mips_target::low_supports_breakpoints ()
323 {
324   return true;
325 }
326 
327 CORE_ADDR
328 mips_target::low_get_pc (regcache *regcache)
329 {
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;
333 }
334 
335 void
336 mips_target::low_set_pc (regcache *regcache, CORE_ADDR pc)
337 {
338   union mips_register newpc;
339   if (register_size (regcache->tdesc, 0) == 4)
340     newpc.reg32 = pc;
341   else
342     newpc.reg64 = pc;
343 
344   supply_register_by_name (regcache, "pc", newpc.buf);
345 }
346 
347 /* Correct in either endianness.  */
348 static const unsigned int mips_breakpoint = 0x0005000d;
349 #define mips_breakpoint_len 4
350 
351 /* Implementation of target ops method "sw_breakpoint_from_kind".  */
352 
353 const gdb_byte *
354 mips_target::sw_breakpoint_from_kind (int kind, int *size)
355 {
356   *size = mips_breakpoint_len;
357   return (const gdb_byte *) &mips_breakpoint;
358 }
359 
360 bool
361 mips_target::low_breakpoint_at (CORE_ADDR where)
362 {
363   unsigned int insn;
364 
365   read_memory (where, (unsigned char *) &insn, 4);
366   if (insn == mips_breakpoint)
367     return true;
368 
369   /* If necessary, recognize more trap instructions here.  GDB only uses the
370      one.  */
371   return false;
372 }
373 
374 /* Mark the watch registers of lwp, represented by ENTRY, as changed.  */
375 
376 static void
377 update_watch_registers_callback (thread_info *thread)
378 {
379   struct lwp_info *lwp = get_thread_lwp (thread);
380 
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;
384 
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);
389 }
390 
391 /* This is the implementation of linux target ops method
392    low_new_process.  */
393 
394 arch_process_info *
395 mips_target::low_new_process ()
396 {
397   struct arch_process_info *info = XCNEW (struct arch_process_info);
398 
399   return info;
400 }
401 
402 /* This is the implementation of linux target ops method
403    low_delete_process.  */
404 
405 void
406 mips_target::low_delete_process (arch_process_info *info)
407 {
408   xfree (info);
409 }
410 
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.  */
414 
415 void
416 mips_target::low_new_thread (lwp_info *lwp)
417 {
418   struct arch_lwp_info *info = XCNEW (struct arch_lwp_info);
419 
420   info->watch_registers_changed = 1;
421 
422   lwp->arch_private = info;
423 }
424 
425 /* Function to call when a thread is being deleted.  */
426 
427 void
428 mips_target::low_delete_thread (arch_lwp_info *arch_lwp)
429 {
430   xfree (arch_lwp);
431 }
432 
433 /* Create a new mips_watchpoint and add it to the list.  */
434 
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)
438 {
439   struct mips_watchpoint *new_watch;
440   struct mips_watchpoint **pw;
441 
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;
447 
448   pw = &priv->current_watches;
449   while (*pw != NULL)
450     pw = &(*pw)->next;
451   *pw = new_watch;
452 }
453 
454 /* Hook to call when a new fork is attached.  */
455 
456 void
457 mips_target::low_new_fork (process_info *parent,
458 			   process_info *child)
459 {
460   struct arch_process_info *parent_private;
461   struct arch_process_info *child_private;
462   struct mips_watchpoint *wp;
463 
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);
469 
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.
475 
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.  */
483 
484   parent_private = parent->priv->arch_private;
485   child_private = child->priv->arch_private;
486 
487   child_private->watch_readback_valid = parent_private->watch_readback_valid;
488   child_private->watch_readback = parent_private->watch_readback;
489 
490   for (wp = parent_private->current_watches; wp != NULL; wp = wp->next)
491     mips_add_watchpoint (child_private, wp->addr, wp->len, wp->type);
492 
493   child_private->watch_mirror = parent_private->watch_mirror;
494 }
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.  */
498 
499 void
500 mips_target::low_prepare_to_resume (lwp_info *lwp)
501 {
502   ptid_t ptid = ptid_of (get_lwp_thread (lwp));
503   struct process_info *proc = find_process_pid (ptid.pid ());
504   struct arch_process_info *priv = proc->priv->arch_private;
505 
506   if (lwp->arch_private->watch_registers_changed)
507     {
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)
511 	{
512 	  /* Write the mirrored watch register values.  */
513 	  int tid = ptid.lwp ();
514 
515 	  if (-1 == ptrace (PTRACE_SET_WATCH_REGS, tid,
516 			    &priv->watch_mirror, NULL))
517 	    perror_with_name ("Couldn't write watch register");
518 	}
519 
520       lwp->arch_private->watch_registers_changed = 0;
521     }
522 }
523 
524 bool
525 mips_target::supports_z_point_type (char z_type)
526 {
527   switch (z_type)
528     {
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;
535     }
536 }
537 
538 /* This is the implementation of linux target ops method
539    low_insert_point.  */
540 
541 int
542 mips_target::low_insert_point (raw_bkpt_type type, CORE_ADDR addr,
543 			       int len, raw_breakpoint *bp)
544 {
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;
549   enum target_hw_bp_type watch_type;
550   uint32_t irw;
551 
552   lwpid = lwpid_of (current_thread);
553   if (!mips_linux_read_watch_registers (lwpid,
554 					&priv->watch_readback,
555 					&priv->watch_readback_valid,
556 					0))
557     return -1;
558 
559   if (len <= 0)
560     return -1;
561 
562   regs = priv->watch_readback;
563   /* Add the current watches.  */
564   mips_linux_watch_populate_regs (priv->current_watches, &regs);
565 
566   /* Now try to add the new watch.  */
567   watch_type = raw_bkpt_type_to_target_hw_bp_type (type);
568   irw = mips_linux_watch_type_to_irw (watch_type);
569   if (!mips_linux_watch_try_one_watch (&regs, addr, len, irw))
570     return -1;
571 
572   /* It fit.  Stick it on the end of the list.  */
573   mips_add_watchpoint (priv, addr, len, watch_type);
574 
575   priv->watch_mirror = regs;
576 
577   /* Only update the threads of this process.  */
578   for_each_thread (proc->pid, update_watch_registers_callback);
579 
580   return 0;
581 }
582 
583 /* This is the implementation of linux target ops method
584    low_remove_point.  */
585 
586 int
587 mips_target::low_remove_point (raw_bkpt_type type, CORE_ADDR addr,
588 			       int len, raw_breakpoint *bp)
589 {
590   struct process_info *proc = current_process ();
591   struct arch_process_info *priv = proc->priv->arch_private;
592 
593   int deleted_one;
594   enum target_hw_bp_type watch_type;
595 
596   struct mips_watchpoint **pw;
597   struct mips_watchpoint *w;
598 
599   /* Search for a known watch that matches.  Then unlink and free it.  */
600   watch_type = raw_bkpt_type_to_target_hw_bp_type (type);
601   deleted_one = 0;
602   pw = &priv->current_watches;
603   while ((w = *pw))
604     {
605       if (w->addr == addr && w->len == len && w->type == watch_type)
606 	{
607 	  *pw = w->next;
608 	  free (w);
609 	  deleted_one = 1;
610 	  break;
611 	}
612       pw = &(w->next);
613     }
614 
615   if (!deleted_one)
616     return -1;  /* We don't know about it, fail doing nothing.  */
617 
618   /* At this point watch_readback is known to be valid because we
619      could not have added the watch without reading it.  */
620   gdb_assert (priv->watch_readback_valid == 1);
621 
622   priv->watch_mirror = priv->watch_readback;
623   mips_linux_watch_populate_regs (priv->current_watches,
624 				  &priv->watch_mirror);
625 
626   /* Only update the threads of this process.  */
627   for_each_thread (proc->pid, update_watch_registers_callback);
628 
629   return 0;
630 }
631 
632 /* This is the implementation of linux target ops method
633    low_stopped_by_watchpoint.  The watchhi R and W bits indicate
634    the watch register triggered. */
635 
636 bool
637 mips_target::low_stopped_by_watchpoint ()
638 {
639   struct process_info *proc = current_process ();
640   struct arch_process_info *priv = proc->priv->arch_private;
641   int n;
642   int num_valid;
643   long lwpid = lwpid_of (current_thread);
644 
645   if (!mips_linux_read_watch_registers (lwpid,
646 					&priv->watch_readback,
647 					&priv->watch_readback_valid,
648 					1))
649     return 0;
650 
651   num_valid = mips_linux_watch_get_num_valid (&priv->watch_readback);
652 
653   for (n = 0; n < MAX_DEBUG_REGISTER && n < num_valid; n++)
654     if (mips_linux_watch_get_watchhi (&priv->watch_readback, n)
655 	& (R_MASK | W_MASK))
656       return true;
657 
658   return false;
659 }
660 
661 /* This is the implementation of linux target ops method
662    low_stopped_data_address.  */
663 
664 CORE_ADDR
665 mips_target::low_stopped_data_address ()
666 {
667   struct process_info *proc = current_process ();
668   struct arch_process_info *priv = proc->priv->arch_private;
669   int n;
670   int num_valid;
671   long lwpid = lwpid_of (current_thread);
672 
673   /* On MIPS we don't know the low order 3 bits of the data address.
674      GDB does not support remote targets that can't report the
675      watchpoint address.  So, make our best guess; return the starting
676      address of a watchpoint request which overlaps the one that
677      triggered.  */
678 
679   if (!mips_linux_read_watch_registers (lwpid,
680 					&priv->watch_readback,
681 					&priv->watch_readback_valid,
682 					0))
683     return 0;
684 
685   num_valid = mips_linux_watch_get_num_valid (&priv->watch_readback);
686 
687   for (n = 0; n < MAX_DEBUG_REGISTER && n < num_valid; n++)
688     if (mips_linux_watch_get_watchhi (&priv->watch_readback, n)
689 	& (R_MASK | W_MASK))
690       {
691 	CORE_ADDR t_low, t_hi;
692 	int t_irw;
693 	struct mips_watchpoint *watch;
694 
695 	t_low = mips_linux_watch_get_watchlo (&priv->watch_readback, n);
696 	t_irw = t_low & IRW_MASK;
697 	t_hi = (mips_linux_watch_get_watchhi (&priv->watch_readback, n)
698 		| IRW_MASK);
699 	t_low &= ~(CORE_ADDR)t_hi;
700 
701 	for (watch = priv->current_watches;
702 	     watch != NULL;
703 	     watch = watch->next)
704 	  {
705 	    CORE_ADDR addr = watch->addr;
706 	    CORE_ADDR last_byte = addr + watch->len - 1;
707 
708 	    if ((t_irw & mips_linux_watch_type_to_irw (watch->type)) == 0)
709 	      {
710 		/* Different type.  */
711 		continue;
712 	      }
713 	    /* Check for overlap of even a single byte.  */
714 	    if (last_byte >= t_low && addr <= t_low + t_hi)
715 	      return addr;
716 	  }
717       }
718 
719   /* Shouldn't happen.  */
720   return 0;
721 }
722 
723 /* Fetch the thread-local storage pointer for libthread_db.  */
724 
725 ps_err_e
726 ps_get_thread_area (struct ps_prochandle *ph,
727 		    lwpid_t lwpid, int idx, void **base)
728 {
729   if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
730     return PS_ERR;
731 
732   /* IDX is the bias from the thread pointer to the beginning of the
733      thread descriptor.  It has to be subtracted due to implementation
734      quirks in libthread_db.  */
735   *base = (void *) ((char *)*base - idx);
736 
737   return PS_OK;
738 }
739 
740 static void
741 mips_collect_register (struct regcache *regcache,
742 		       int use_64bit, int regno, union mips_register *reg)
743 {
744   union mips_register tmp_reg;
745 
746   if (use_64bit)
747     {
748       collect_register (regcache, regno, &tmp_reg.reg64);
749       *reg = tmp_reg;
750     }
751   else
752     {
753       collect_register (regcache, regno, &tmp_reg.reg32);
754       reg->reg64 = tmp_reg.reg32;
755     }
756 }
757 
758 static void
759 mips_supply_register (struct regcache *regcache,
760 		      int use_64bit, int regno, const union mips_register *reg)
761 {
762   int offset = 0;
763 
764   /* For big-endian 32-bit targets, ignore the high four bytes of each
765      eight-byte slot.  */
766   if (__BYTE_ORDER == __BIG_ENDIAN && !use_64bit)
767     offset = 4;
768 
769   supply_register (regcache, regno, reg->buf + offset);
770 }
771 
772 #ifdef HAVE_PTRACE_GETREGS
773 
774 static void
775 mips_collect_register_32bit (struct regcache *regcache,
776 			     int use_64bit, int regno, unsigned char *buf)
777 {
778   union mips_register tmp_reg;
779   int reg32;
780 
781   mips_collect_register (regcache, use_64bit, regno, &tmp_reg);
782   reg32 = tmp_reg.reg64;
783   memcpy (buf, &reg32, 4);
784 }
785 
786 static void
787 mips_supply_register_32bit (struct regcache *regcache,
788 			    int use_64bit, int regno, const unsigned char *buf)
789 {
790   union mips_register tmp_reg;
791   int reg32;
792 
793   memcpy (&reg32, buf, 4);
794   tmp_reg.reg64 = reg32;
795   mips_supply_register (regcache, use_64bit, regno, &tmp_reg);
796 }
797 
798 static void
799 mips_fill_gregset (struct regcache *regcache, void *buf)
800 {
801   union mips_register *regset = (union mips_register *) buf;
802   int i, use_64bit;
803   const struct target_desc *tdesc = regcache->tdesc;
804 
805   use_64bit = (register_size (tdesc, 0) == 8);
806 
807   for (i = 1; i < 32; i++)
808     mips_collect_register (regcache, use_64bit, i, regset + i);
809 
810   mips_collect_register (regcache, use_64bit,
811 			 find_regno (tdesc, "lo"), regset + 32);
812   mips_collect_register (regcache, use_64bit,
813 			 find_regno (tdesc, "hi"), regset + 33);
814   mips_collect_register (regcache, use_64bit,
815 			 find_regno (tdesc, "pc"), regset + 34);
816   mips_collect_register (regcache, use_64bit,
817 			 find_regno (tdesc, "badvaddr"), regset + 35);
818   mips_collect_register (regcache, use_64bit,
819 			 find_regno (tdesc, "status"), regset + 36);
820   mips_collect_register (regcache, use_64bit,
821 			 find_regno (tdesc, "cause"), regset + 37);
822 
823   mips_collect_register (regcache, use_64bit,
824 			 find_regno (tdesc, "restart"), regset + 0);
825 }
826 
827 static void
828 mips_store_gregset (struct regcache *regcache, const void *buf)
829 {
830   const union mips_register *regset = (const union mips_register *) buf;
831   int i, use_64bit;
832 
833   use_64bit = (register_size (regcache->tdesc, 0) == 8);
834 
835   supply_register_by_name_zeroed (regcache, "r0");
836 
837   for (i = 1; i < 32; i++)
838     mips_supply_register (regcache, use_64bit, i, regset + i);
839 
840   mips_supply_register (regcache, use_64bit,
841 			find_regno (regcache->tdesc, "lo"), regset + 32);
842   mips_supply_register (regcache, use_64bit,
843 			find_regno (regcache->tdesc, "hi"), regset + 33);
844   mips_supply_register (regcache, use_64bit,
845 			find_regno (regcache->tdesc, "pc"), regset + 34);
846   mips_supply_register (regcache, use_64bit,
847 			find_regno (regcache->tdesc, "badvaddr"), regset + 35);
848   mips_supply_register (regcache, use_64bit,
849 			find_regno (regcache->tdesc, "status"), regset + 36);
850   mips_supply_register (regcache, use_64bit,
851 			find_regno (regcache->tdesc, "cause"), regset + 37);
852 
853   mips_supply_register (regcache, use_64bit,
854 			find_regno (regcache->tdesc, "restart"), regset + 0);
855 }
856 
857 static void
858 mips_fill_fpregset (struct regcache *regcache, void *buf)
859 {
860   union mips_register *regset = (union mips_register *) buf;
861   int i, use_64bit, first_fp, big_endian;
862 
863   use_64bit = (register_size (regcache->tdesc, 0) == 8);
864   first_fp = find_regno (regcache->tdesc, "f0");
865   big_endian = (__BYTE_ORDER == __BIG_ENDIAN);
866 
867   /* See GDB for a discussion of this peculiar layout.  */
868   for (i = 0; i < 32; i++)
869     if (use_64bit)
870       collect_register (regcache, first_fp + i, regset[i].buf);
871     else
872       collect_register (regcache, first_fp + i,
873 			regset[i & ~1].buf + 4 * (big_endian != (i & 1)));
874 
875   mips_collect_register_32bit (regcache, use_64bit,
876 			       find_regno (regcache->tdesc, "fcsr"), regset[32].buf);
877   mips_collect_register_32bit (regcache, use_64bit,
878 			       find_regno (regcache->tdesc, "fir"),
879 			       regset[32].buf + 4);
880 }
881 
882 static void
883 mips_store_fpregset (struct regcache *regcache, const void *buf)
884 {
885   const union mips_register *regset = (const union mips_register *) buf;
886   int i, use_64bit, first_fp, big_endian;
887 
888   use_64bit = (register_size (regcache->tdesc, 0) == 8);
889   first_fp = find_regno (regcache->tdesc, "f0");
890   big_endian = (__BYTE_ORDER == __BIG_ENDIAN);
891 
892   /* See GDB for a discussion of this peculiar layout.  */
893   for (i = 0; i < 32; i++)
894     if (use_64bit)
895       supply_register (regcache, first_fp + i, regset[i].buf);
896     else
897       supply_register (regcache, first_fp + i,
898 		       regset[i & ~1].buf + 4 * (big_endian != (i & 1)));
899 
900   mips_supply_register_32bit (regcache, use_64bit,
901 			      find_regno (regcache->tdesc, "fcsr"),
902 			      regset[32].buf);
903   mips_supply_register_32bit (regcache, use_64bit,
904 			      find_regno (regcache->tdesc, "fir"),
905 			      regset[32].buf + 4);
906 }
907 #endif /* HAVE_PTRACE_GETREGS */
908 
909 /* Take care of 32-bit registers with 64-bit ptrace, POKEUSER side.  */
910 
911 void
912 mips_target::low_collect_ptrace_register (regcache *regcache, int regno,
913 					  char *buf)
914 {
915   int use_64bit = sizeof (PTRACE_XFER_TYPE) == 8;
916 
917   if (use_64bit && register_size (regcache->tdesc, regno) == 4)
918     {
919       union mips_register reg;
920 
921       mips_collect_register (regcache, 0, regno, &reg);
922       memcpy (buf, &reg, sizeof (reg));
923     }
924   else
925     collect_register (regcache, regno, buf);
926 }
927 
928 /* Take care of 32-bit registers with 64-bit ptrace, PEEKUSER side.  */
929 
930 void
931 mips_target::low_supply_ptrace_register (regcache *regcache, int regno,
932 					 const char *buf)
933 {
934   int use_64bit = sizeof (PTRACE_XFER_TYPE) == 8;
935 
936   if (use_64bit && register_size (regcache->tdesc, regno) == 4)
937     {
938       union mips_register reg;
939 
940       memcpy (&reg, buf, sizeof (reg));
941       mips_supply_register (regcache, 0, regno, &reg);
942     }
943   else
944     supply_register (regcache, regno, buf);
945 }
946 
947 static struct regset_info mips_regsets[] = {
948 #ifdef HAVE_PTRACE_GETREGS
949   { PTRACE_GETREGS, PTRACE_SETREGS, 0, 38 * 8, GENERAL_REGS,
950     mips_fill_gregset, mips_store_gregset },
951   { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 0, 33 * 8, FP_REGS,
952     mips_fill_fpregset, mips_store_fpregset },
953 #endif /* HAVE_PTRACE_GETREGS */
954   NULL_REGSET
955 };
956 
957 static struct regsets_info mips_regsets_info =
958   {
959     mips_regsets, /* regsets */
960     0, /* num_regsets */
961     NULL, /* disabled_regsets */
962   };
963 
964 static struct usrregs_info mips_dsp_usrregs_info =
965   {
966     mips_dsp_num_regs,
967     mips_dsp_regmap,
968   };
969 
970 static struct usrregs_info mips_usrregs_info =
971   {
972     mips_num_regs,
973     mips_regmap,
974   };
975 
976 static struct regs_info dsp_regs_info =
977   {
978     mips_dsp_regset_bitmap,
979     &mips_dsp_usrregs_info,
980     &mips_regsets_info
981   };
982 
983 static struct regs_info myregs_info =
984   {
985     NULL, /* regset_bitmap */
986     &mips_usrregs_info,
987     &mips_regsets_info
988   };
989 
990 const regs_info *
991 mips_target::get_regs_info ()
992 {
993   if (have_dsp)
994     return &dsp_regs_info;
995   else
996     return &myregs_info;
997 }
998 
999 /* The linux target ops object.  */
1000 
1001 linux_process_target *the_linux_target = &the_mips_target;
1002 
1003 void
1004 initialize_low_arch (void)
1005 {
1006   /* Initialize the Linux target descriptions.  */
1007   init_registers_mips_linux ();
1008   init_registers_mips_dsp_linux ();
1009   init_registers_mips64_linux ();
1010   init_registers_mips64_dsp_linux ();
1011 
1012   initialize_regsets_info (&mips_regsets_info);
1013 }
1014