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