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