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