PR binutils/18257: Properly decode x86/Intel mask instructions.
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-aarch64-low.c
1 /* GNU/Linux/AArch64 specific low level interface, for the remote server for
2 GDB.
3
4 Copyright (C) 2009-2015 Free Software Foundation, Inc.
5 Contributed by ARM Ltd.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21
22 #include "server.h"
23 #include "linux-low.h"
24 #include "nat/aarch64-linux-hw-point.h"
25 #include "linux-aarch32-low.h"
26 #include "elf/common.h"
27
28 #include <signal.h>
29 #include <sys/user.h>
30 #include "nat/gdb_ptrace.h"
31 #include <asm/ptrace.h>
32 #include <sys/uio.h>
33
34 #include "gdb_proc_service.h"
35
36 /* Defined in auto-generated files. */
37 void init_registers_aarch64 (void);
38 extern const struct target_desc *tdesc_aarch64;
39
40 #ifdef HAVE_SYS_REG_H
41 #include <sys/reg.h>
42 #endif
43
44 #define AARCH64_X_REGS_NUM 31
45 #define AARCH64_V_REGS_NUM 32
46 #define AARCH64_X0_REGNO 0
47 #define AARCH64_SP_REGNO 31
48 #define AARCH64_PC_REGNO 32
49 #define AARCH64_CPSR_REGNO 33
50 #define AARCH64_V0_REGNO 34
51 #define AARCH64_FPSR_REGNO (AARCH64_V0_REGNO + AARCH64_V_REGS_NUM)
52 #define AARCH64_FPCR_REGNO (AARCH64_V0_REGNO + AARCH64_V_REGS_NUM + 1)
53
54 #define AARCH64_NUM_REGS (AARCH64_V0_REGNO + AARCH64_V_REGS_NUM + 2)
55
56 /* Per-process arch-specific data we want to keep. */
57
58 struct arch_process_info
59 {
60 /* Hardware breakpoint/watchpoint data.
61 The reason for them to be per-process rather than per-thread is
62 due to the lack of information in the gdbserver environment;
63 gdbserver is not told that whether a requested hardware
64 breakpoint/watchpoint is thread specific or not, so it has to set
65 each hw bp/wp for every thread in the current process. The
66 higher level bp/wp management in gdb will resume a thread if a hw
67 bp/wp trap is not expected for it. Since the hw bp/wp setting is
68 same for each thread, it is reasonable for the data to live here.
69 */
70 struct aarch64_debug_reg_state debug_reg_state;
71 };
72
73 /* Return true if the size of register 0 is 8 byte. */
74
75 static int
76 is_64bit_tdesc (void)
77 {
78 struct regcache *regcache = get_thread_regcache (current_thread, 0);
79
80 return register_size (regcache->tdesc, 0) == 8;
81 }
82
83 /* Implementation of linux_target_ops method "cannot_store_register". */
84
85 static int
86 aarch64_cannot_store_register (int regno)
87 {
88 return regno >= AARCH64_NUM_REGS;
89 }
90
91 /* Implementation of linux_target_ops method "cannot_fetch_register". */
92
93 static int
94 aarch64_cannot_fetch_register (int regno)
95 {
96 return regno >= AARCH64_NUM_REGS;
97 }
98
99 static void
100 aarch64_fill_gregset (struct regcache *regcache, void *buf)
101 {
102 struct user_pt_regs *regset = buf;
103 int i;
104
105 for (i = 0; i < AARCH64_X_REGS_NUM; i++)
106 collect_register (regcache, AARCH64_X0_REGNO + i, &regset->regs[i]);
107 collect_register (regcache, AARCH64_SP_REGNO, &regset->sp);
108 collect_register (regcache, AARCH64_PC_REGNO, &regset->pc);
109 collect_register (regcache, AARCH64_CPSR_REGNO, &regset->pstate);
110 }
111
112 static void
113 aarch64_store_gregset (struct regcache *regcache, const void *buf)
114 {
115 const struct user_pt_regs *regset = buf;
116 int i;
117
118 for (i = 0; i < AARCH64_X_REGS_NUM; i++)
119 supply_register (regcache, AARCH64_X0_REGNO + i, &regset->regs[i]);
120 supply_register (regcache, AARCH64_SP_REGNO, &regset->sp);
121 supply_register (regcache, AARCH64_PC_REGNO, &regset->pc);
122 supply_register (regcache, AARCH64_CPSR_REGNO, &regset->pstate);
123 }
124
125 static void
126 aarch64_fill_fpregset (struct regcache *regcache, void *buf)
127 {
128 struct user_fpsimd_state *regset = buf;
129 int i;
130
131 for (i = 0; i < AARCH64_V_REGS_NUM; i++)
132 collect_register (regcache, AARCH64_V0_REGNO + i, &regset->vregs[i]);
133 collect_register (regcache, AARCH64_FPSR_REGNO, &regset->fpsr);
134 collect_register (regcache, AARCH64_FPCR_REGNO, &regset->fpcr);
135 }
136
137 static void
138 aarch64_store_fpregset (struct regcache *regcache, const void *buf)
139 {
140 const struct user_fpsimd_state *regset = buf;
141 int i;
142
143 for (i = 0; i < AARCH64_V_REGS_NUM; i++)
144 supply_register (regcache, AARCH64_V0_REGNO + i, &regset->vregs[i]);
145 supply_register (regcache, AARCH64_FPSR_REGNO, &regset->fpsr);
146 supply_register (regcache, AARCH64_FPCR_REGNO, &regset->fpcr);
147 }
148
149 /* Enable miscellaneous debugging output. The name is historical - it
150 was originally used to debug LinuxThreads support. */
151 extern int debug_threads;
152
153 /* Implementation of linux_target_ops method "get_pc". */
154
155 static CORE_ADDR
156 aarch64_get_pc (struct regcache *regcache)
157 {
158 if (register_size (regcache->tdesc, 0) == 8)
159 {
160 unsigned long pc;
161
162 collect_register_by_name (regcache, "pc", &pc);
163 if (debug_threads)
164 debug_printf ("stop pc is %08lx\n", pc);
165 return pc;
166 }
167 else
168 {
169 unsigned int pc;
170
171 collect_register_by_name (regcache, "pc", &pc);
172 if (debug_threads)
173 debug_printf ("stop pc is %04x\n", pc);
174 return pc;
175 }
176 }
177
178 /* Implementation of linux_target_ops method "set_pc". */
179
180 static void
181 aarch64_set_pc (struct regcache *regcache, CORE_ADDR pc)
182 {
183 if (register_size (regcache->tdesc, 0) == 8)
184 {
185 unsigned long newpc = pc;
186 supply_register_by_name (regcache, "pc", &newpc);
187 }
188 else
189 {
190 unsigned int newpc = pc;
191 supply_register_by_name (regcache, "pc", &newpc);
192 }
193 }
194
195 #define aarch64_breakpoint_len 4
196
197 /* AArch64 BRK software debug mode instruction.
198 This instruction needs to match gdb/aarch64-tdep.c
199 (aarch64_default_breakpoint). */
200 static const gdb_byte aarch64_breakpoint[] = {0x00, 0x00, 0x20, 0xd4};
201
202 /* Implementation of linux_target_ops method "breakpoint_at". */
203
204 static int
205 aarch64_breakpoint_at (CORE_ADDR where)
206 {
207 gdb_byte insn[aarch64_breakpoint_len];
208
209 (*the_target->read_memory) (where, (unsigned char *) &insn,
210 aarch64_breakpoint_len);
211 if (memcmp (insn, aarch64_breakpoint, aarch64_breakpoint_len) == 0)
212 return 1;
213
214 return 0;
215 }
216
217 static void
218 aarch64_init_debug_reg_state (struct aarch64_debug_reg_state *state)
219 {
220 int i;
221
222 for (i = 0; i < AARCH64_HBP_MAX_NUM; ++i)
223 {
224 state->dr_addr_bp[i] = 0;
225 state->dr_ctrl_bp[i] = 0;
226 state->dr_ref_count_bp[i] = 0;
227 }
228
229 for (i = 0; i < AARCH64_HWP_MAX_NUM; ++i)
230 {
231 state->dr_addr_wp[i] = 0;
232 state->dr_ctrl_wp[i] = 0;
233 state->dr_ref_count_wp[i] = 0;
234 }
235 }
236
237 struct aarch64_dr_update_callback_param
238 {
239 int pid;
240 int is_watchpoint;
241 unsigned int idx;
242 };
243
244 /* Callback function which records the information about the change of
245 one hardware breakpoint/watchpoint setting for the thread ENTRY.
246 The information is passed in via PTR.
247 N.B. The actual updating of hardware debug registers is not
248 carried out until the moment the thread is resumed. */
249
250 static int
251 debug_reg_change_callback (struct inferior_list_entry *entry, void *ptr)
252 {
253 struct thread_info *thread = (struct thread_info *) entry;
254 struct lwp_info *lwp = get_thread_lwp (thread);
255 struct aarch64_dr_update_callback_param *param_p
256 = (struct aarch64_dr_update_callback_param *) ptr;
257 int pid = param_p->pid;
258 int idx = param_p->idx;
259 int is_watchpoint = param_p->is_watchpoint;
260 struct arch_lwp_info *info = lwp->arch_private;
261 dr_changed_t *dr_changed_ptr;
262 dr_changed_t dr_changed;
263
264 if (show_debug_regs)
265 {
266 fprintf (stderr, "debug_reg_change_callback: \n\tOn entry:\n");
267 fprintf (stderr, "\tpid%d, tid: %ld, dr_changed_bp=0x%llx, "
268 "dr_changed_wp=0x%llx\n",
269 pid, lwpid_of (thread), info->dr_changed_bp,
270 info->dr_changed_wp);
271 }
272
273 dr_changed_ptr = is_watchpoint ? &info->dr_changed_wp
274 : &info->dr_changed_bp;
275 dr_changed = *dr_changed_ptr;
276
277 /* Only update the threads of this process. */
278 if (pid_of (thread) == pid)
279 {
280 gdb_assert (idx >= 0
281 && (idx <= (is_watchpoint ? aarch64_num_wp_regs
282 : aarch64_num_bp_regs)));
283
284 /* The following assertion is not right, as there can be changes
285 that have not been made to the hardware debug registers
286 before new changes overwrite the old ones. This can happen,
287 for instance, when the breakpoint/watchpoint hit one of the
288 threads and the user enters continue; then what happens is:
289 1) all breakpoints/watchpoints are removed for all threads;
290 2) a single step is carried out for the thread that was hit;
291 3) all of the points are inserted again for all threads;
292 4) all threads are resumed.
293 The 2nd step will only affect the one thread in which the
294 bp/wp was hit, which means only that one thread is resumed;
295 remember that the actual updating only happen in
296 aarch64_linux_prepare_to_resume, so other threads remain
297 stopped during the removal and insertion of bp/wp. Therefore
298 for those threads, the change of insertion of the bp/wp
299 overwrites that of the earlier removals. (The situation may
300 be different when bp/wp is steppable, or in the non-stop
301 mode.) */
302 /* gdb_assert (DR_N_HAS_CHANGED (dr_changed, idx) == 0); */
303
304 /* The actual update is done later just before resuming the lwp,
305 we just mark that one register pair needs updating. */
306 DR_MARK_N_CHANGED (dr_changed, idx);
307 *dr_changed_ptr = dr_changed;
308
309 /* If the lwp isn't stopped, force it to momentarily pause, so
310 we can update its debug registers. */
311 if (!lwp->stopped)
312 linux_stop_lwp (lwp);
313 }
314
315 if (show_debug_regs)
316 {
317 fprintf (stderr, "\tOn exit:\n\tpid%d, tid: %ld, dr_changed_bp=0x%llx, "
318 "dr_changed_wp=0x%llx\n",
319 pid, lwpid_of (thread), info->dr_changed_bp,
320 info->dr_changed_wp);
321 }
322
323 return 0;
324 }
325
326 /* Notify each thread that their IDXth breakpoint/watchpoint register
327 pair needs to be updated. The message will be recorded in each
328 thread's arch-specific data area, the actual updating will be done
329 when the thread is resumed. */
330
331 void
332 aarch64_notify_debug_reg_change (const struct aarch64_debug_reg_state *state,
333 int is_watchpoint, unsigned int idx)
334 {
335 struct aarch64_dr_update_callback_param param;
336
337 /* Only update the threads of this process. */
338 param.pid = pid_of (current_thread);
339
340 param.is_watchpoint = is_watchpoint;
341 param.idx = idx;
342
343 find_inferior (&all_threads, debug_reg_change_callback, (void *) &param);
344 }
345
346
347 /* Return the pointer to the debug register state structure in the
348 current process' arch-specific data area. */
349
350 static struct aarch64_debug_reg_state *
351 aarch64_get_debug_reg_state ()
352 {
353 struct process_info *proc;
354
355 proc = current_process ();
356 return &proc->priv->arch_private->debug_reg_state;
357 }
358
359 /* Implementation of linux_target_ops method "supports_z_point_type". */
360
361 static int
362 aarch64_supports_z_point_type (char z_type)
363 {
364 switch (z_type)
365 {
366 case Z_PACKET_SW_BP:
367 {
368 if (!extended_protocol && is_64bit_tdesc ())
369 {
370 /* Only enable Z0 packet in non-multi-arch debugging. If
371 extended protocol is used, don't enable Z0 packet because
372 GDBserver may attach to 32-bit process. */
373 return 1;
374 }
375 else
376 {
377 /* Disable Z0 packet so that GDBserver doesn't have to handle
378 different breakpoint instructions (aarch64, arm, thumb etc)
379 in multi-arch debugging. */
380 return 0;
381 }
382 }
383 case Z_PACKET_HW_BP:
384 case Z_PACKET_WRITE_WP:
385 case Z_PACKET_READ_WP:
386 case Z_PACKET_ACCESS_WP:
387 return 1;
388 default:
389 return 0;
390 }
391 }
392
393 /* Implementation of linux_target_ops method "insert_point".
394
395 It actually only records the info of the to-be-inserted bp/wp;
396 the actual insertion will happen when threads are resumed. */
397
398 static int
399 aarch64_insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
400 int len, struct raw_breakpoint *bp)
401 {
402 int ret;
403 enum target_hw_bp_type targ_type;
404 struct aarch64_debug_reg_state *state = aarch64_get_debug_reg_state ();
405
406 if (show_debug_regs)
407 fprintf (stderr, "insert_point on entry (addr=0x%08lx, len=%d)\n",
408 (unsigned long) addr, len);
409
410 /* Determine the type from the raw breakpoint type. */
411 targ_type = raw_bkpt_type_to_target_hw_bp_type (type);
412
413 if (targ_type != hw_execute)
414 ret =
415 aarch64_handle_watchpoint (targ_type, addr, len, 1 /* is_insert */,
416 state);
417 else
418 ret =
419 aarch64_handle_breakpoint (targ_type, addr, len, 1 /* is_insert */,
420 state);
421
422 if (show_debug_regs)
423 aarch64_show_debug_reg_state (aarch64_get_debug_reg_state (),
424 "insert_point", addr, len, targ_type);
425
426 return ret;
427 }
428
429 /* Implementation of linux_target_ops method "remove_point".
430
431 It actually only records the info of the to-be-removed bp/wp,
432 the actual removal will be done when threads are resumed. */
433
434 static int
435 aarch64_remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
436 int len, struct raw_breakpoint *bp)
437 {
438 int ret;
439 enum target_hw_bp_type targ_type;
440 struct aarch64_debug_reg_state *state = aarch64_get_debug_reg_state ();
441
442 if (show_debug_regs)
443 fprintf (stderr, "remove_point on entry (addr=0x%08lx, len=%d)\n",
444 (unsigned long) addr, len);
445
446 /* Determine the type from the raw breakpoint type. */
447 targ_type = raw_bkpt_type_to_target_hw_bp_type (type);
448
449 /* Set up state pointers. */
450 if (targ_type != hw_execute)
451 ret =
452 aarch64_handle_watchpoint (targ_type, addr, len, 0 /* is_insert */,
453 state);
454 else
455 ret =
456 aarch64_handle_breakpoint (targ_type, addr, len, 0 /* is_insert */,
457 state);
458
459 if (show_debug_regs)
460 aarch64_show_debug_reg_state (aarch64_get_debug_reg_state (),
461 "remove_point", addr, len, targ_type);
462
463 return ret;
464 }
465
466 /* Implementation of linux_target_ops method "stopped_data_address". */
467
468 static CORE_ADDR
469 aarch64_stopped_data_address (void)
470 {
471 siginfo_t siginfo;
472 int pid, i;
473 struct aarch64_debug_reg_state *state;
474
475 pid = lwpid_of (current_thread);
476
477 /* Get the siginfo. */
478 if (ptrace (PTRACE_GETSIGINFO, pid, NULL, &siginfo) != 0)
479 return (CORE_ADDR) 0;
480
481 /* Need to be a hardware breakpoint/watchpoint trap. */
482 if (siginfo.si_signo != SIGTRAP
483 || (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
484 return (CORE_ADDR) 0;
485
486 /* Check if the address matches any watched address. */
487 state = aarch64_get_debug_reg_state ();
488 for (i = aarch64_num_wp_regs - 1; i >= 0; --i)
489 {
490 const unsigned int len = aarch64_watchpoint_length (state->dr_ctrl_wp[i]);
491 const CORE_ADDR addr_trap = (CORE_ADDR) siginfo.si_addr;
492 const CORE_ADDR addr_watch = state->dr_addr_wp[i];
493 if (state->dr_ref_count_wp[i]
494 && DR_CONTROL_ENABLED (state->dr_ctrl_wp[i])
495 && addr_trap >= addr_watch
496 && addr_trap < addr_watch + len)
497 return addr_trap;
498 }
499
500 return (CORE_ADDR) 0;
501 }
502
503 /* Implementation of linux_target_ops method "stopped_by_watchpoint". */
504
505 static int
506 aarch64_stopped_by_watchpoint (void)
507 {
508 if (aarch64_stopped_data_address () != 0)
509 return 1;
510 else
511 return 0;
512 }
513
514 /* Fetch the thread-local storage pointer for libthread_db. */
515
516 ps_err_e
517 ps_get_thread_area (const struct ps_prochandle *ph,
518 lwpid_t lwpid, int idx, void **base)
519 {
520 struct iovec iovec;
521 uint64_t reg;
522
523 iovec.iov_base = &reg;
524 iovec.iov_len = sizeof (reg);
525
526 if (ptrace (PTRACE_GETREGSET, lwpid, NT_ARM_TLS, &iovec) != 0)
527 return PS_ERR;
528
529 /* IDX is the bias from the thread pointer to the beginning of the
530 thread descriptor. It has to be subtracted due to implementation
531 quirks in libthread_db. */
532 *base = (void *) (reg - idx);
533
534 return PS_OK;
535 }
536
537 /* Implementation of linux_target_ops method "linux_new_process". */
538
539 static struct arch_process_info *
540 aarch64_linux_new_process (void)
541 {
542 struct arch_process_info *info = xcalloc (1, sizeof (*info));
543
544 aarch64_init_debug_reg_state (&info->debug_reg_state);
545
546 return info;
547 }
548
549 /* Implementation of linux_target_ops method "linux_new_thread". */
550
551 static void
552 aarch64_linux_new_thread (struct lwp_info *lwp)
553 {
554 struct arch_lwp_info *info = xcalloc (1, sizeof (*info));
555
556 /* Mark that all the hardware breakpoint/watchpoint register pairs
557 for this thread need to be initialized (with data from
558 aarch_process_info.debug_reg_state). */
559 DR_MARK_ALL_CHANGED (info->dr_changed_bp, aarch64_num_bp_regs);
560 DR_MARK_ALL_CHANGED (info->dr_changed_wp, aarch64_num_wp_regs);
561
562 lwp->arch_private = info;
563 }
564
565 /* Implementation of linux_target_ops method "linux_new_fork". */
566
567 static void
568 aarch64_linux_new_fork (struct process_info *parent,
569 struct process_info *child)
570 {
571 /* These are allocated by linux_add_process. */
572 gdb_assert (parent->priv != NULL
573 && parent->priv->arch_private != NULL);
574 gdb_assert (child->priv != NULL
575 && child->priv->arch_private != NULL);
576
577 /* Linux kernel before 2.6.33 commit
578 72f674d203cd230426437cdcf7dd6f681dad8b0d
579 will inherit hardware debug registers from parent
580 on fork/vfork/clone. Newer Linux kernels create such tasks with
581 zeroed debug registers.
582
583 GDB core assumes the child inherits the watchpoints/hw
584 breakpoints of the parent, and will remove them all from the
585 forked off process. Copy the debug registers mirrors into the
586 new process so that all breakpoints and watchpoints can be
587 removed together. The debug registers mirror will become zeroed
588 in the end before detaching the forked off process, thus making
589 this compatible with older Linux kernels too. */
590
591 *child->priv->arch_private = *parent->priv->arch_private;
592 }
593
594 /* Implementation of linux_target_ops method "linux_prepare_to_resume".
595
596 If the debug regs have changed, update the thread's copies. */
597
598 static void
599 aarch64_linux_prepare_to_resume (struct lwp_info *lwp)
600 {
601 struct thread_info *thread = get_lwp_thread (lwp);
602 ptid_t ptid = ptid_of (thread);
603 struct arch_lwp_info *info = lwp->arch_private;
604
605 if (DR_HAS_CHANGED (info->dr_changed_bp)
606 || DR_HAS_CHANGED (info->dr_changed_wp))
607 {
608 int tid = ptid_get_lwp (ptid);
609 struct process_info *proc = find_process_pid (ptid_get_pid (ptid));
610 struct aarch64_debug_reg_state *state
611 = &proc->priv->arch_private->debug_reg_state;
612
613 if (show_debug_regs)
614 fprintf (stderr, "prepare_to_resume thread %ld\n", lwpid_of (thread));
615
616 /* Watchpoints. */
617 if (DR_HAS_CHANGED (info->dr_changed_wp))
618 {
619 aarch64_linux_set_debug_regs (state, tid, 1);
620 DR_CLEAR_CHANGED (info->dr_changed_wp);
621 }
622
623 /* Breakpoints. */
624 if (DR_HAS_CHANGED (info->dr_changed_bp))
625 {
626 aarch64_linux_set_debug_regs (state, tid, 0);
627 DR_CLEAR_CHANGED (info->dr_changed_bp);
628 }
629 }
630 }
631
632 /* Return the right target description according to the ELF file of
633 current thread. */
634
635 static const struct target_desc *
636 aarch64_linux_read_description (void)
637 {
638 unsigned int machine;
639 int is_elf64;
640 int tid;
641
642 tid = lwpid_of (current_thread);
643
644 is_elf64 = linux_pid_exe_is_elf_64_file (tid, &machine);
645
646 if (is_elf64)
647 return tdesc_aarch64;
648 else
649 return tdesc_arm_with_neon;
650 }
651
652 /* Implementation of linux_target_ops method "arch_setup". */
653
654 static void
655 aarch64_arch_setup (void)
656 {
657 current_process ()->tdesc = aarch64_linux_read_description ();
658
659 aarch64_linux_get_debug_reg_capacity (lwpid_of (current_thread));
660 }
661
662 static struct regset_info aarch64_regsets[] =
663 {
664 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS,
665 sizeof (struct user_pt_regs), GENERAL_REGS,
666 aarch64_fill_gregset, aarch64_store_gregset },
667 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_FPREGSET,
668 sizeof (struct user_fpsimd_state), FP_REGS,
669 aarch64_fill_fpregset, aarch64_store_fpregset
670 },
671 { 0, 0, 0, -1, -1, NULL, NULL }
672 };
673
674 static struct regsets_info aarch64_regsets_info =
675 {
676 aarch64_regsets, /* regsets */
677 0, /* num_regsets */
678 NULL, /* disabled_regsets */
679 };
680
681 static struct regs_info regs_info_aarch64 =
682 {
683 NULL, /* regset_bitmap */
684 NULL, /* usrregs */
685 &aarch64_regsets_info,
686 };
687
688 /* Implementation of linux_target_ops method "regs_info". */
689
690 static const struct regs_info *
691 aarch64_regs_info (void)
692 {
693 if (is_64bit_tdesc ())
694 return &regs_info_aarch64;
695 else
696 return &regs_info_aarch32;
697 }
698
699 /* Implementation of linux_target_ops method "supports_tracepoints". */
700
701 static int
702 aarch64_supports_tracepoints (void)
703 {
704 if (current_thread == NULL)
705 return 1;
706 else
707 {
708 /* We don't support tracepoints on aarch32 now. */
709 return is_64bit_tdesc ();
710 }
711 }
712
713 /* Implementation of linux_target_ops method "supports_range_stepping". */
714
715 static int
716 aarch64_supports_range_stepping (void)
717 {
718 return 1;
719 }
720
721 struct linux_target_ops the_low_target =
722 {
723 aarch64_arch_setup,
724 aarch64_regs_info,
725 aarch64_cannot_fetch_register,
726 aarch64_cannot_store_register,
727 NULL, /* fetch_register */
728 aarch64_get_pc,
729 aarch64_set_pc,
730 (const unsigned char *) &aarch64_breakpoint,
731 aarch64_breakpoint_len,
732 NULL, /* breakpoint_reinsert_addr */
733 0, /* decr_pc_after_break */
734 aarch64_breakpoint_at,
735 aarch64_supports_z_point_type,
736 aarch64_insert_point,
737 aarch64_remove_point,
738 aarch64_stopped_by_watchpoint,
739 aarch64_stopped_data_address,
740 NULL, /* collect_ptrace_register */
741 NULL, /* supply_ptrace_register */
742 NULL, /* siginfo_fixup */
743 aarch64_linux_new_process,
744 aarch64_linux_new_thread,
745 aarch64_linux_new_fork,
746 aarch64_linux_prepare_to_resume,
747 NULL, /* process_qsupported */
748 aarch64_supports_tracepoints,
749 NULL, /* get_thread_area */
750 NULL, /* install_fast_tracepoint_jump_pad */
751 NULL, /* emit_ops */
752 NULL, /* get_min_fast_tracepoint_insn_len */
753 aarch64_supports_range_stepping,
754 };
755
756 void
757 initialize_low_arch (void)
758 {
759 init_registers_aarch64 ();
760
761 initialize_low_arch_aarch32 ();
762
763 initialize_regsets_info (&aarch64_regsets_info);
764 }
This page took 0.060187 seconds and 4 git commands to generate.