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