xref: /netbsd-src/external/gpl3/gdb/dist/gdbserver/linux-arm-low.cc (revision 8780886f61e6504b663cc999811abdddc42a06de)
18dffb485Schristos /* GNU/Linux/ARM specific low level interface, for the remote server for GDB.
2*8780886fSchristos    Copyright (C) 1995-2024 Free Software Foundation, Inc.
38dffb485Schristos 
48dffb485Schristos    This file is part of GDB.
58dffb485Schristos 
68dffb485Schristos    This program is free software; you can redistribute it and/or modify
78dffb485Schristos    it under the terms of the GNU General Public License as published by
88dffb485Schristos    the Free Software Foundation; either version 3 of the License, or
98dffb485Schristos    (at your option) any later version.
108dffb485Schristos 
118dffb485Schristos    This program is distributed in the hope that it will be useful,
128dffb485Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
138dffb485Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
148dffb485Schristos    GNU General Public License for more details.
158dffb485Schristos 
168dffb485Schristos    You should have received a copy of the GNU General Public License
178dffb485Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
188dffb485Schristos 
198dffb485Schristos #include "linux-low.h"
208dffb485Schristos #include "arch/arm.h"
218dffb485Schristos #include "arch/arm-linux.h"
228dffb485Schristos #include "arch/arm-get-next-pcs.h"
238dffb485Schristos #include "linux-aarch32-low.h"
248dffb485Schristos #include "linux-aarch32-tdesc.h"
258dffb485Schristos #include "linux-arm-tdesc.h"
26*8780886fSchristos #include "gdbsupport/gdb-checked-static-cast.h"
278dffb485Schristos 
288dffb485Schristos #include <sys/uio.h>
298dffb485Schristos /* Don't include elf.h if linux/elf.h got included by gdb_proc_service.h.
308dffb485Schristos    On Bionic elf.h and linux/elf.h have conflicting definitions.  */
318dffb485Schristos #ifndef ELFMAG0
328dffb485Schristos #include <elf.h>
338dffb485Schristos #endif
348dffb485Schristos #include "nat/gdb_ptrace.h"
358dffb485Schristos #include <signal.h>
368dffb485Schristos #include <sys/syscall.h>
378dffb485Schristos 
388dffb485Schristos #ifndef PTRACE_GET_THREAD_AREA
398dffb485Schristos #define PTRACE_GET_THREAD_AREA 22
408dffb485Schristos #endif
418dffb485Schristos 
428dffb485Schristos #ifndef PTRACE_GETWMMXREGS
438dffb485Schristos # define PTRACE_GETWMMXREGS 18
448dffb485Schristos # define PTRACE_SETWMMXREGS 19
458dffb485Schristos #endif
468dffb485Schristos 
478dffb485Schristos #ifndef PTRACE_GETVFPREGS
488dffb485Schristos # define PTRACE_GETVFPREGS 27
498dffb485Schristos # define PTRACE_SETVFPREGS 28
508dffb485Schristos #endif
518dffb485Schristos 
528dffb485Schristos #ifndef PTRACE_GETHBPREGS
538dffb485Schristos #define PTRACE_GETHBPREGS 29
548dffb485Schristos #define PTRACE_SETHBPREGS 30
558dffb485Schristos #endif
568dffb485Schristos 
578dffb485Schristos /* Linux target op definitions for the ARM architecture.  */
588dffb485Schristos 
598dffb485Schristos class arm_target : public linux_process_target
608dffb485Schristos {
618dffb485Schristos public:
628dffb485Schristos 
638dffb485Schristos   const regs_info *get_regs_info () override;
648dffb485Schristos 
658dffb485Schristos   int breakpoint_kind_from_pc (CORE_ADDR *pcptr) override;
668dffb485Schristos 
678dffb485Schristos   int breakpoint_kind_from_current_state (CORE_ADDR *pcptr) override;
688dffb485Schristos 
698dffb485Schristos   const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override;
708dffb485Schristos 
718dffb485Schristos   bool supports_software_single_step () override;
728dffb485Schristos 
738dffb485Schristos   bool supports_z_point_type (char z_type) override;
748dffb485Schristos 
758dffb485Schristos   bool supports_hardware_single_step () override;
768dffb485Schristos 
778dffb485Schristos protected:
788dffb485Schristos 
798dffb485Schristos   void low_arch_setup () override;
808dffb485Schristos 
818dffb485Schristos   bool low_cannot_fetch_register (int regno) override;
828dffb485Schristos 
838dffb485Schristos   bool low_cannot_store_register (int regno) override;
848dffb485Schristos 
858dffb485Schristos   bool low_supports_breakpoints () override;
868dffb485Schristos 
878dffb485Schristos   CORE_ADDR low_get_pc (regcache *regcache) override;
888dffb485Schristos 
898dffb485Schristos   void low_set_pc (regcache *regcache, CORE_ADDR newpc) override;
908dffb485Schristos 
918dffb485Schristos   std::vector<CORE_ADDR> low_get_next_pcs (regcache *regcache) override;
928dffb485Schristos 
938dffb485Schristos   bool low_breakpoint_at (CORE_ADDR pc) override;
948dffb485Schristos 
958dffb485Schristos   int low_insert_point (raw_bkpt_type type, CORE_ADDR addr,
968dffb485Schristos 			int size, raw_breakpoint *bp) override;
978dffb485Schristos 
988dffb485Schristos   int low_remove_point (raw_bkpt_type type, CORE_ADDR addr,
998dffb485Schristos 			int size, raw_breakpoint *bp) override;
1008dffb485Schristos 
1018dffb485Schristos   bool low_stopped_by_watchpoint () override;
1028dffb485Schristos 
1038dffb485Schristos   CORE_ADDR low_stopped_data_address () override;
1048dffb485Schristos 
1058dffb485Schristos   arch_process_info *low_new_process () override;
1068dffb485Schristos 
1078dffb485Schristos   void low_delete_process (arch_process_info *info) override;
1088dffb485Schristos 
1098dffb485Schristos   void low_new_thread (lwp_info *) override;
1108dffb485Schristos 
1118dffb485Schristos   void low_delete_thread (arch_lwp_info *) override;
1128dffb485Schristos 
1138dffb485Schristos   void low_new_fork (process_info *parent, process_info *child) override;
1148dffb485Schristos 
1158dffb485Schristos   void low_prepare_to_resume (lwp_info *lwp) override;
1168dffb485Schristos 
1178dffb485Schristos   bool low_supports_catch_syscall () override;
1188dffb485Schristos 
1198dffb485Schristos   void low_get_syscall_trapinfo (regcache *regcache, int *sysno) override;
1208dffb485Schristos };
1218dffb485Schristos 
1228dffb485Schristos /* The singleton target ops object.  */
1238dffb485Schristos 
1248dffb485Schristos static arm_target the_arm_target;
1258dffb485Schristos 
1268dffb485Schristos bool
1278dffb485Schristos arm_target::low_supports_breakpoints ()
1288dffb485Schristos {
1298dffb485Schristos   return true;
1308dffb485Schristos }
1318dffb485Schristos 
1328dffb485Schristos CORE_ADDR
1338dffb485Schristos arm_target::low_get_pc (regcache *regcache)
1348dffb485Schristos {
1358dffb485Schristos   return linux_get_pc_32bit (regcache);
1368dffb485Schristos }
1378dffb485Schristos 
1388dffb485Schristos void
1398dffb485Schristos arm_target::low_set_pc (regcache *regcache, CORE_ADDR pc)
1408dffb485Schristos {
1418dffb485Schristos   linux_set_pc_32bit (regcache, pc);
1428dffb485Schristos }
1438dffb485Schristos 
1448dffb485Schristos int
1458dffb485Schristos arm_target::breakpoint_kind_from_pc (CORE_ADDR *pcptr)
1468dffb485Schristos {
1478dffb485Schristos   return arm_breakpoint_kind_from_pc (pcptr);
1488dffb485Schristos }
1498dffb485Schristos 
1508dffb485Schristos int
1518dffb485Schristos arm_target::breakpoint_kind_from_current_state (CORE_ADDR *pcptr)
1528dffb485Schristos {
1538dffb485Schristos   return arm_breakpoint_kind_from_current_state (pcptr);
1548dffb485Schristos }
1558dffb485Schristos 
1568dffb485Schristos const gdb_byte *
1578dffb485Schristos arm_target::sw_breakpoint_from_kind (int kind, int *size)
1588dffb485Schristos {
1598dffb485Schristos   return arm_sw_breakpoint_from_kind (kind, size);
1608dffb485Schristos }
1618dffb485Schristos 
1628dffb485Schristos bool
1638dffb485Schristos arm_target::low_breakpoint_at (CORE_ADDR pc)
1648dffb485Schristos {
1658dffb485Schristos   return arm_breakpoint_at (pc);
1668dffb485Schristos }
1678dffb485Schristos 
1688dffb485Schristos /* Information describing the hardware breakpoint capabilities.  */
1698dffb485Schristos static struct
1708dffb485Schristos {
1718dffb485Schristos   unsigned char arch;
1728dffb485Schristos   unsigned char max_wp_length;
1738dffb485Schristos   unsigned char wp_count;
1748dffb485Schristos   unsigned char bp_count;
1758dffb485Schristos } arm_linux_hwbp_cap;
1768dffb485Schristos 
1778dffb485Schristos /* Enum describing the different types of ARM hardware break-/watch-points.  */
1788dffb485Schristos typedef enum
1798dffb485Schristos {
1808dffb485Schristos   arm_hwbp_break = 0,
1818dffb485Schristos   arm_hwbp_load = 1,
1828dffb485Schristos   arm_hwbp_store = 2,
1838dffb485Schristos   arm_hwbp_access = 3
1848dffb485Schristos } arm_hwbp_type;
1858dffb485Schristos 
1868dffb485Schristos /* Type describing an ARM Hardware Breakpoint Control register value.  */
1878dffb485Schristos typedef unsigned int arm_hwbp_control_t;
1888dffb485Schristos 
1898dffb485Schristos /* Structure used to keep track of hardware break-/watch-points.  */
1908dffb485Schristos struct arm_linux_hw_breakpoint
1918dffb485Schristos {
1928dffb485Schristos   /* Address to break on, or being watched.  */
1938dffb485Schristos   unsigned int address;
1948dffb485Schristos   /* Control register for break-/watch- point.  */
1958dffb485Schristos   arm_hwbp_control_t control;
1968dffb485Schristos };
1978dffb485Schristos 
1988dffb485Schristos /* Since we cannot dynamically allocate subfields of arch_process_info,
1998dffb485Schristos    assume a maximum number of supported break-/watchpoints.  */
2008dffb485Schristos #define MAX_BPTS 32
2018dffb485Schristos #define MAX_WPTS 32
2028dffb485Schristos 
2038dffb485Schristos /* Per-process arch-specific data we want to keep.  */
2048dffb485Schristos struct arch_process_info
2058dffb485Schristos {
2068dffb485Schristos   /* Hardware breakpoints for this process.  */
2078dffb485Schristos   struct arm_linux_hw_breakpoint bpts[MAX_BPTS];
2088dffb485Schristos   /* Hardware watchpoints for this process.  */
2098dffb485Schristos   struct arm_linux_hw_breakpoint wpts[MAX_WPTS];
2108dffb485Schristos };
2118dffb485Schristos 
2128dffb485Schristos /* Per-thread arch-specific data we want to keep.  */
2138dffb485Schristos struct arch_lwp_info
2148dffb485Schristos {
2158dffb485Schristos   /* Non-zero if our copy differs from what's recorded in the thread.  */
2168dffb485Schristos   char bpts_changed[MAX_BPTS];
2178dffb485Schristos   char wpts_changed[MAX_WPTS];
2188dffb485Schristos   /* Cached stopped data address.  */
2198dffb485Schristos   CORE_ADDR stopped_data_address;
2208dffb485Schristos };
2218dffb485Schristos 
2228dffb485Schristos /* These are in <asm/elf.h> in current kernels.  */
2238dffb485Schristos #define HWCAP_VFP       64
2248dffb485Schristos #define HWCAP_IWMMXT    512
2258dffb485Schristos #define HWCAP_NEON      4096
2268dffb485Schristos #define HWCAP_VFPv3     8192
2278dffb485Schristos #define HWCAP_VFPv3D16  16384
2288dffb485Schristos 
2298dffb485Schristos #ifdef HAVE_SYS_REG_H
2308dffb485Schristos #include <sys/reg.h>
2318dffb485Schristos #endif
2328dffb485Schristos 
2338dffb485Schristos #define arm_num_regs 26
2348dffb485Schristos 
2358dffb485Schristos static int arm_regmap[] = {
2368dffb485Schristos   0, 4, 8, 12, 16, 20, 24, 28,
2378dffb485Schristos   32, 36, 40, 44, 48, 52, 56, 60,
2388dffb485Schristos   -1, -1, -1, -1, -1, -1, -1, -1, -1,
2398dffb485Schristos   64
2408dffb485Schristos };
2418dffb485Schristos 
2428dffb485Schristos /* Forward declarations needed for get_next_pcs ops.  */
2438dffb485Schristos static ULONGEST get_next_pcs_read_memory_unsigned_integer (CORE_ADDR memaddr,
2448dffb485Schristos 							   int len,
2458dffb485Schristos 							   int byte_order);
2468dffb485Schristos 
2478dffb485Schristos static CORE_ADDR get_next_pcs_addr_bits_remove (struct arm_get_next_pcs *self,
2488dffb485Schristos 						CORE_ADDR val);
2498dffb485Schristos 
2508dffb485Schristos static CORE_ADDR get_next_pcs_syscall_next_pc (struct arm_get_next_pcs *self);
2518dffb485Schristos 
2528dffb485Schristos static int get_next_pcs_is_thumb (struct arm_get_next_pcs *self);
2538dffb485Schristos 
2548dffb485Schristos /* get_next_pcs operations.  */
2558dffb485Schristos static struct arm_get_next_pcs_ops get_next_pcs_ops = {
2568dffb485Schristos   get_next_pcs_read_memory_unsigned_integer,
2578dffb485Schristos   get_next_pcs_syscall_next_pc,
2588dffb485Schristos   get_next_pcs_addr_bits_remove,
2598dffb485Schristos   get_next_pcs_is_thumb,
2608dffb485Schristos   arm_linux_get_next_pcs_fixup,
2618dffb485Schristos };
2628dffb485Schristos 
2638dffb485Schristos bool
2648dffb485Schristos arm_target::low_cannot_store_register (int regno)
2658dffb485Schristos {
2668dffb485Schristos   return (regno >= arm_num_regs);
2678dffb485Schristos }
2688dffb485Schristos 
2698dffb485Schristos bool
2708dffb485Schristos arm_target::low_cannot_fetch_register (int regno)
2718dffb485Schristos {
2728dffb485Schristos   return (regno >= arm_num_regs);
2738dffb485Schristos }
2748dffb485Schristos 
2758dffb485Schristos static void
2768dffb485Schristos arm_fill_wmmxregset (struct regcache *regcache, void *buf)
2778dffb485Schristos {
2788dffb485Schristos   if (arm_linux_get_tdesc_fp_type (regcache->tdesc) != ARM_FP_TYPE_IWMMXT)
2798dffb485Schristos     return;
2808dffb485Schristos 
2818dffb485Schristos   for (int i = 0; i < 16; i++)
2828dffb485Schristos     collect_register (regcache, arm_num_regs + i, (char *) buf + i * 8);
2838dffb485Schristos 
2848dffb485Schristos   /* We only have access to wcssf, wcasf, and wcgr0-wcgr3.  */
2858dffb485Schristos   for (int i = 0; i < 6; i++)
2868dffb485Schristos     collect_register (regcache, arm_num_regs + i + 16,
2878dffb485Schristos 		      (char *) buf + 16 * 8 + i * 4);
2888dffb485Schristos }
2898dffb485Schristos 
2908dffb485Schristos static void
2918dffb485Schristos arm_store_wmmxregset (struct regcache *regcache, const void *buf)
2928dffb485Schristos {
2938dffb485Schristos   if (arm_linux_get_tdesc_fp_type (regcache->tdesc) != ARM_FP_TYPE_IWMMXT)
2948dffb485Schristos     return;
2958dffb485Schristos 
2968dffb485Schristos   for (int i = 0; i < 16; i++)
2978dffb485Schristos     supply_register (regcache, arm_num_regs + i, (char *) buf + i * 8);
2988dffb485Schristos 
2998dffb485Schristos   /* We only have access to wcssf, wcasf, and wcgr0-wcgr3.  */
3008dffb485Schristos   for (int i = 0; i < 6; i++)
3018dffb485Schristos     supply_register (regcache, arm_num_regs + i + 16,
3028dffb485Schristos 		     (char *) buf + 16 * 8 + i * 4);
3038dffb485Schristos }
3048dffb485Schristos 
3058dffb485Schristos static void
3068dffb485Schristos arm_fill_vfpregset (struct regcache *regcache, void *buf)
3078dffb485Schristos {
3088dffb485Schristos   int num;
3098dffb485Schristos 
3108dffb485Schristos   if (is_aarch32_linux_description (regcache->tdesc))
3118dffb485Schristos     num = 32;
3128dffb485Schristos   else
3138dffb485Schristos     {
3148dffb485Schristos       arm_fp_type fp_type = arm_linux_get_tdesc_fp_type (regcache->tdesc);
3158dffb485Schristos 
3168dffb485Schristos       if (fp_type == ARM_FP_TYPE_VFPV3)
3178dffb485Schristos 	num = 32;
3188dffb485Schristos       else if (fp_type == ARM_FP_TYPE_VFPV2)
3198dffb485Schristos 	num = 16;
3208dffb485Schristos       else
3218dffb485Schristos 	return;
3228dffb485Schristos     }
3238dffb485Schristos 
3248dffb485Schristos   arm_fill_vfpregset_num (regcache, buf, num);
3258dffb485Schristos }
3268dffb485Schristos 
3278dffb485Schristos /* Wrapper of UNMAKE_THUMB_ADDR for get_next_pcs.  */
3288dffb485Schristos static CORE_ADDR
3298dffb485Schristos get_next_pcs_addr_bits_remove (struct arm_get_next_pcs *self, CORE_ADDR val)
3308dffb485Schristos {
3318dffb485Schristos   return UNMAKE_THUMB_ADDR (val);
3328dffb485Schristos }
3338dffb485Schristos 
3348dffb485Schristos static void
3358dffb485Schristos arm_store_vfpregset (struct regcache *regcache, const void *buf)
3368dffb485Schristos {
3378dffb485Schristos   int num;
3388dffb485Schristos 
3398dffb485Schristos   if (is_aarch32_linux_description (regcache->tdesc))
3408dffb485Schristos     num = 32;
3418dffb485Schristos   else
3428dffb485Schristos     {
3438dffb485Schristos       arm_fp_type fp_type = arm_linux_get_tdesc_fp_type (regcache->tdesc);
3448dffb485Schristos 
3458dffb485Schristos       if (fp_type == ARM_FP_TYPE_VFPV3)
3468dffb485Schristos 	num = 32;
3478dffb485Schristos       else if (fp_type == ARM_FP_TYPE_VFPV2)
3488dffb485Schristos 	num = 16;
3498dffb485Schristos       else
3508dffb485Schristos 	return;
3518dffb485Schristos     }
3528dffb485Schristos 
3538dffb485Schristos   arm_store_vfpregset_num (regcache, buf, num);
3548dffb485Schristos }
3558dffb485Schristos 
3568dffb485Schristos /* Wrapper of arm_is_thumb_mode for get_next_pcs.  */
3578dffb485Schristos static int
3588dffb485Schristos get_next_pcs_is_thumb (struct arm_get_next_pcs *self)
3598dffb485Schristos {
3608dffb485Schristos   return arm_is_thumb_mode ();
3618dffb485Schristos }
3628dffb485Schristos 
3638dffb485Schristos /* Read memory from the inferior.
3648dffb485Schristos    BYTE_ORDER is ignored and there to keep compatiblity with GDB's
3658dffb485Schristos    read_memory_unsigned_integer. */
3668dffb485Schristos static ULONGEST
3678dffb485Schristos get_next_pcs_read_memory_unsigned_integer (CORE_ADDR memaddr,
3688dffb485Schristos 					   int len,
3698dffb485Schristos 					   int byte_order)
3708dffb485Schristos {
3718dffb485Schristos   ULONGEST res;
3728dffb485Schristos 
3738dffb485Schristos   res = 0;
3748dffb485Schristos   target_read_memory (memaddr, (unsigned char *) &res, len);
3758dffb485Schristos 
3768dffb485Schristos   return res;
3778dffb485Schristos }
3788dffb485Schristos 
3798dffb485Schristos /* Fetch the thread-local storage pointer for libthread_db.  */
3808dffb485Schristos 
3818dffb485Schristos ps_err_e
3828dffb485Schristos ps_get_thread_area (struct ps_prochandle *ph,
3838dffb485Schristos 		    lwpid_t lwpid, int idx, void **base)
3848dffb485Schristos {
3858dffb485Schristos   if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
3868dffb485Schristos     return PS_ERR;
3878dffb485Schristos 
3888dffb485Schristos   /* IDX is the bias from the thread pointer to the beginning of the
3898dffb485Schristos      thread descriptor.  It has to be subtracted due to implementation
3908dffb485Schristos      quirks in libthread_db.  */
3918dffb485Schristos   *base = (void *) ((char *)*base - idx);
3928dffb485Schristos 
3938dffb485Schristos   return PS_OK;
3948dffb485Schristos }
3958dffb485Schristos 
3968dffb485Schristos 
3978dffb485Schristos /* Query Hardware Breakpoint information for the target we are attached to
3988dffb485Schristos    (using PID as ptrace argument) and set up arm_linux_hwbp_cap.  */
3998dffb485Schristos static void
4008dffb485Schristos arm_linux_init_hwbp_cap (int pid)
4018dffb485Schristos {
4028dffb485Schristos   unsigned int val;
4038dffb485Schristos 
4048dffb485Schristos   if (ptrace (PTRACE_GETHBPREGS, pid, 0, &val) < 0)
4058dffb485Schristos     return;
4068dffb485Schristos 
4078dffb485Schristos   arm_linux_hwbp_cap.arch = (unsigned char)((val >> 24) & 0xff);
4088dffb485Schristos   if (arm_linux_hwbp_cap.arch == 0)
4098dffb485Schristos     return;
4108dffb485Schristos 
4118dffb485Schristos   arm_linux_hwbp_cap.max_wp_length = (unsigned char)((val >> 16) & 0xff);
4128dffb485Schristos   arm_linux_hwbp_cap.wp_count = (unsigned char)((val >> 8) & 0xff);
4138dffb485Schristos   arm_linux_hwbp_cap.bp_count = (unsigned char)(val & 0xff);
4148dffb485Schristos 
4158dffb485Schristos   if (arm_linux_hwbp_cap.wp_count > MAX_WPTS)
4164b169a6bSchristos     internal_error ("Unsupported number of watchpoints");
4178dffb485Schristos   if (arm_linux_hwbp_cap.bp_count > MAX_BPTS)
4184b169a6bSchristos     internal_error ("Unsupported number of breakpoints");
4198dffb485Schristos }
4208dffb485Schristos 
4218dffb485Schristos /* How many hardware breakpoints are available?  */
4228dffb485Schristos static int
4238dffb485Schristos arm_linux_get_hw_breakpoint_count (void)
4248dffb485Schristos {
4258dffb485Schristos   return arm_linux_hwbp_cap.bp_count;
4268dffb485Schristos }
4278dffb485Schristos 
4288dffb485Schristos /* How many hardware watchpoints are available?  */
4298dffb485Schristos static int
4308dffb485Schristos arm_linux_get_hw_watchpoint_count (void)
4318dffb485Schristos {
4328dffb485Schristos   return arm_linux_hwbp_cap.wp_count;
4338dffb485Schristos }
4348dffb485Schristos 
4358dffb485Schristos /* Maximum length of area watched by hardware watchpoint.  */
4368dffb485Schristos static int
4378dffb485Schristos arm_linux_get_hw_watchpoint_max_length (void)
4388dffb485Schristos {
4398dffb485Schristos   return arm_linux_hwbp_cap.max_wp_length;
4408dffb485Schristos }
4418dffb485Schristos 
4428dffb485Schristos /* Initialize an ARM hardware break-/watch-point control register value.
4438dffb485Schristos    BYTE_ADDRESS_SELECT is the mask of bytes to trigger on; HWBP_TYPE is the
4448dffb485Schristos    type of break-/watch-point; ENABLE indicates whether the point is enabled.
4458dffb485Schristos    */
4468dffb485Schristos static arm_hwbp_control_t
4478dffb485Schristos arm_hwbp_control_initialize (unsigned byte_address_select,
4488dffb485Schristos 			     arm_hwbp_type hwbp_type,
4498dffb485Schristos 			     int enable)
4508dffb485Schristos {
4518dffb485Schristos   gdb_assert ((byte_address_select & ~0xffU) == 0);
4528dffb485Schristos   gdb_assert (hwbp_type != arm_hwbp_break
4538dffb485Schristos 	      || ((byte_address_select & 0xfU) != 0));
4548dffb485Schristos 
4558dffb485Schristos   return (byte_address_select << 5) | (hwbp_type << 3) | (3 << 1) | enable;
4568dffb485Schristos }
4578dffb485Schristos 
4588dffb485Schristos /* Does the breakpoint control value CONTROL have the enable bit set?  */
4598dffb485Schristos static int
4608dffb485Schristos arm_hwbp_control_is_enabled (arm_hwbp_control_t control)
4618dffb485Schristos {
4628dffb485Schristos   return control & 0x1;
4638dffb485Schristos }
4648dffb485Schristos 
4658dffb485Schristos /* Is the breakpoint control value CONTROL initialized?  */
4668dffb485Schristos static int
4678dffb485Schristos arm_hwbp_control_is_initialized (arm_hwbp_control_t control)
4688dffb485Schristos {
4698dffb485Schristos   return control != 0;
4708dffb485Schristos }
4718dffb485Schristos 
4728dffb485Schristos /* Change a breakpoint control word so that it is in the disabled state.  */
4738dffb485Schristos static arm_hwbp_control_t
4748dffb485Schristos arm_hwbp_control_disable (arm_hwbp_control_t control)
4758dffb485Schristos {
4768dffb485Schristos   return control & ~0x1;
4778dffb485Schristos }
4788dffb485Schristos 
4798dffb485Schristos /* Are two break-/watch-points equal?  */
4808dffb485Schristos static int
4818dffb485Schristos arm_linux_hw_breakpoint_equal (const struct arm_linux_hw_breakpoint *p1,
4828dffb485Schristos 			       const struct arm_linux_hw_breakpoint *p2)
4838dffb485Schristos {
4848dffb485Schristos   return p1->address == p2->address && p1->control == p2->control;
4858dffb485Schristos }
4868dffb485Schristos 
4878dffb485Schristos /* Convert a raw breakpoint type to an enum arm_hwbp_type.  */
4888dffb485Schristos 
4898dffb485Schristos static arm_hwbp_type
4908dffb485Schristos raw_bkpt_type_to_arm_hwbp_type (enum raw_bkpt_type raw_type)
4918dffb485Schristos {
4928dffb485Schristos   switch (raw_type)
4938dffb485Schristos     {
4948dffb485Schristos     case raw_bkpt_type_hw:
4958dffb485Schristos       return arm_hwbp_break;
4968dffb485Schristos     case raw_bkpt_type_write_wp:
4978dffb485Schristos       return arm_hwbp_store;
4988dffb485Schristos     case raw_bkpt_type_read_wp:
4998dffb485Schristos       return arm_hwbp_load;
5008dffb485Schristos     case raw_bkpt_type_access_wp:
5018dffb485Schristos       return arm_hwbp_access;
5028dffb485Schristos     default:
5038dffb485Schristos       gdb_assert_not_reached ("unhandled raw type");
5048dffb485Schristos     }
5058dffb485Schristos }
5068dffb485Schristos 
5078dffb485Schristos /* Initialize the hardware breakpoint structure P for a breakpoint or
5088dffb485Schristos    watchpoint at ADDR to LEN.  The type of watchpoint is given in TYPE.
5098dffb485Schristos    Returns -1 if TYPE is unsupported, or -2 if the particular combination
5108dffb485Schristos    of ADDR and LEN cannot be implemented.  Otherwise, returns 0 if TYPE
5118dffb485Schristos    represents a breakpoint and 1 if type represents a watchpoint.  */
5128dffb485Schristos static int
5138dffb485Schristos arm_linux_hw_point_initialize (enum raw_bkpt_type raw_type, CORE_ADDR addr,
5148dffb485Schristos 			       int len, struct arm_linux_hw_breakpoint *p)
5158dffb485Schristos {
5168dffb485Schristos   arm_hwbp_type hwbp_type;
5178dffb485Schristos   unsigned mask;
5188dffb485Schristos 
5198dffb485Schristos   hwbp_type = raw_bkpt_type_to_arm_hwbp_type (raw_type);
5208dffb485Schristos 
5218dffb485Schristos   if (hwbp_type == arm_hwbp_break)
5228dffb485Schristos     {
5238dffb485Schristos       /* For breakpoints, the length field encodes the mode.  */
5248dffb485Schristos       switch (len)
5258dffb485Schristos 	{
5268dffb485Schristos 	case 2:	 /* 16-bit Thumb mode breakpoint */
5278dffb485Schristos 	case 3:  /* 32-bit Thumb mode breakpoint */
5288dffb485Schristos 	  mask = 0x3;
5298dffb485Schristos 	  addr &= ~1;
5308dffb485Schristos 	  break;
5318dffb485Schristos 	case 4:  /* 32-bit ARM mode breakpoint */
5328dffb485Schristos 	  mask = 0xf;
5338dffb485Schristos 	  addr &= ~3;
5348dffb485Schristos 	  break;
5358dffb485Schristos 	default:
5368dffb485Schristos 	  /* Unsupported. */
5378dffb485Schristos 	  return -2;
5388dffb485Schristos 	}
5398dffb485Schristos     }
5408dffb485Schristos   else
5418dffb485Schristos     {
5428dffb485Schristos       CORE_ADDR max_wp_length = arm_linux_get_hw_watchpoint_max_length ();
5438dffb485Schristos       CORE_ADDR aligned_addr;
5448dffb485Schristos 
5458dffb485Schristos       /* Can not set watchpoints for zero or negative lengths.  */
5468dffb485Schristos       if (len <= 0)
5478dffb485Schristos 	return -2;
5488dffb485Schristos       /* The current ptrace interface can only handle watchpoints that are a
5498dffb485Schristos 	 power of 2.  */
5508dffb485Schristos       if ((len & (len - 1)) != 0)
5518dffb485Schristos 	return -2;
5528dffb485Schristos 
5538dffb485Schristos       /* Test that the range [ADDR, ADDR + LEN) fits into the largest address
5548dffb485Schristos 	 range covered by a watchpoint.  */
5558dffb485Schristos       aligned_addr = addr & ~(max_wp_length - 1);
5568dffb485Schristos       if (aligned_addr + max_wp_length < addr + len)
5578dffb485Schristos 	return -2;
5588dffb485Schristos 
5598dffb485Schristos       mask = (1 << len) - 1;
5608dffb485Schristos     }
5618dffb485Schristos 
5628dffb485Schristos   p->address = (unsigned int) addr;
5638dffb485Schristos   p->control = arm_hwbp_control_initialize (mask, hwbp_type, 1);
5648dffb485Schristos 
5658dffb485Schristos   return hwbp_type != arm_hwbp_break;
5668dffb485Schristos }
5678dffb485Schristos 
5688dffb485Schristos /* Callback to mark a watch-/breakpoint to be updated in all threads of
5698dffb485Schristos    the current process.  */
5708dffb485Schristos 
5718dffb485Schristos static void
5728dffb485Schristos update_registers_callback (thread_info *thread, int watch, int i)
5738dffb485Schristos {
5748dffb485Schristos   struct lwp_info *lwp = get_thread_lwp (thread);
5758dffb485Schristos 
5768dffb485Schristos   /* The actual update is done later just before resuming the lwp,
5778dffb485Schristos      we just mark that the registers need updating.  */
5788dffb485Schristos   if (watch)
5798dffb485Schristos     lwp->arch_private->wpts_changed[i] = 1;
5808dffb485Schristos   else
5818dffb485Schristos     lwp->arch_private->bpts_changed[i] = 1;
5828dffb485Schristos 
5838dffb485Schristos   /* If the lwp isn't stopped, force it to momentarily pause, so
5848dffb485Schristos      we can update its breakpoint registers.  */
5858dffb485Schristos   if (!lwp->stopped)
5868dffb485Schristos     linux_stop_lwp (lwp);
5878dffb485Schristos }
5888dffb485Schristos 
5898dffb485Schristos bool
5908dffb485Schristos arm_target::supports_z_point_type (char z_type)
5918dffb485Schristos {
5928dffb485Schristos   switch (z_type)
5938dffb485Schristos     {
5948dffb485Schristos     case Z_PACKET_SW_BP:
5958dffb485Schristos     case Z_PACKET_HW_BP:
5968dffb485Schristos     case Z_PACKET_WRITE_WP:
5978dffb485Schristos     case Z_PACKET_READ_WP:
5988dffb485Schristos     case Z_PACKET_ACCESS_WP:
5998dffb485Schristos       return true;
6008dffb485Schristos     default:
6018dffb485Schristos       /* Leave the handling of sw breakpoints with the gdb client.  */
6028dffb485Schristos       return false;
6038dffb485Schristos     }
6048dffb485Schristos }
6058dffb485Schristos 
6068dffb485Schristos /* Insert hardware break-/watchpoint.  */
6078dffb485Schristos int
6088dffb485Schristos arm_target::low_insert_point (raw_bkpt_type type, CORE_ADDR addr,
6098dffb485Schristos 			      int len, raw_breakpoint *bp)
6108dffb485Schristos {
6118dffb485Schristos   struct process_info *proc = current_process ();
6128dffb485Schristos   struct arm_linux_hw_breakpoint p, *pts;
6138dffb485Schristos   int watch, i, count;
6148dffb485Schristos 
6158dffb485Schristos   watch = arm_linux_hw_point_initialize (type, addr, len, &p);
6168dffb485Schristos   if (watch < 0)
6178dffb485Schristos     {
6188dffb485Schristos       /* Unsupported.  */
6198dffb485Schristos       return watch == -1 ? 1 : -1;
6208dffb485Schristos     }
6218dffb485Schristos 
6228dffb485Schristos   if (watch)
6238dffb485Schristos     {
6248dffb485Schristos       count = arm_linux_get_hw_watchpoint_count ();
6258dffb485Schristos       pts = proc->priv->arch_private->wpts;
6268dffb485Schristos     }
6278dffb485Schristos   else
6288dffb485Schristos     {
6298dffb485Schristos       count = arm_linux_get_hw_breakpoint_count ();
6308dffb485Schristos       pts = proc->priv->arch_private->bpts;
6318dffb485Schristos     }
6328dffb485Schristos 
6338dffb485Schristos   for (i = 0; i < count; i++)
6348dffb485Schristos     if (!arm_hwbp_control_is_enabled (pts[i].control))
6358dffb485Schristos       {
6368dffb485Schristos 	pts[i] = p;
6378dffb485Schristos 
6388dffb485Schristos 	/* Only update the threads of the current process.  */
6398dffb485Schristos 	for_each_thread (current_thread->id.pid (), [&] (thread_info *thread)
6408dffb485Schristos 	  {
6418dffb485Schristos 	    update_registers_callback (thread, watch, i);
6428dffb485Schristos 	  });
6438dffb485Schristos 
6448dffb485Schristos 	return 0;
6458dffb485Schristos       }
6468dffb485Schristos 
6478dffb485Schristos   /* We're out of watchpoints.  */
6488dffb485Schristos   return -1;
6498dffb485Schristos }
6508dffb485Schristos 
6518dffb485Schristos /* Remove hardware break-/watchpoint.  */
6528dffb485Schristos int
6538dffb485Schristos arm_target::low_remove_point (raw_bkpt_type type, CORE_ADDR addr,
6548dffb485Schristos 			      int len, raw_breakpoint *bp)
6558dffb485Schristos {
6568dffb485Schristos   struct process_info *proc = current_process ();
6578dffb485Schristos   struct arm_linux_hw_breakpoint p, *pts;
6588dffb485Schristos   int watch, i, count;
6598dffb485Schristos 
6608dffb485Schristos   watch = arm_linux_hw_point_initialize (type, addr, len, &p);
6618dffb485Schristos   if (watch < 0)
6628dffb485Schristos     {
6638dffb485Schristos       /* Unsupported.  */
6648dffb485Schristos       return -1;
6658dffb485Schristos     }
6668dffb485Schristos 
6678dffb485Schristos   if (watch)
6688dffb485Schristos     {
6698dffb485Schristos       count = arm_linux_get_hw_watchpoint_count ();
6708dffb485Schristos       pts = proc->priv->arch_private->wpts;
6718dffb485Schristos     }
6728dffb485Schristos   else
6738dffb485Schristos     {
6748dffb485Schristos       count = arm_linux_get_hw_breakpoint_count ();
6758dffb485Schristos       pts = proc->priv->arch_private->bpts;
6768dffb485Schristos     }
6778dffb485Schristos 
6788dffb485Schristos   for (i = 0; i < count; i++)
6798dffb485Schristos     if (arm_linux_hw_breakpoint_equal (&p, pts + i))
6808dffb485Schristos       {
6818dffb485Schristos 	pts[i].control = arm_hwbp_control_disable (pts[i].control);
6828dffb485Schristos 
6838dffb485Schristos 	/* Only update the threads of the current process.  */
6848dffb485Schristos 	for_each_thread (current_thread->id.pid (), [&] (thread_info *thread)
6858dffb485Schristos 	  {
6868dffb485Schristos 	    update_registers_callback (thread, watch, i);
6878dffb485Schristos 	  });
6888dffb485Schristos 
6898dffb485Schristos 	return 0;
6908dffb485Schristos       }
6918dffb485Schristos 
6928dffb485Schristos   /* No watchpoint matched.  */
6938dffb485Schristos   return -1;
6948dffb485Schristos }
6958dffb485Schristos 
6968dffb485Schristos /* Return whether current thread is stopped due to a watchpoint.  */
6978dffb485Schristos bool
6988dffb485Schristos arm_target::low_stopped_by_watchpoint ()
6998dffb485Schristos {
7008dffb485Schristos   struct lwp_info *lwp = get_thread_lwp (current_thread);
7018dffb485Schristos   siginfo_t siginfo;
7028dffb485Schristos 
7038dffb485Schristos   /* We must be able to set hardware watchpoints.  */
7048dffb485Schristos   if (arm_linux_get_hw_watchpoint_count () == 0)
7058dffb485Schristos     return false;
7068dffb485Schristos 
7078dffb485Schristos   /* Retrieve siginfo.  */
7088dffb485Schristos   errno = 0;
7098dffb485Schristos   ptrace (PTRACE_GETSIGINFO, lwpid_of (current_thread), 0, &siginfo);
7108dffb485Schristos   if (errno != 0)
7118dffb485Schristos     return false;
7128dffb485Schristos 
7138dffb485Schristos   /* This must be a hardware breakpoint.  */
7148dffb485Schristos   if (siginfo.si_signo != SIGTRAP
7158dffb485Schristos       || (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
7168dffb485Schristos     return false;
7178dffb485Schristos 
7188dffb485Schristos   /* If we are in a positive slot then we're looking at a breakpoint and not
7198dffb485Schristos      a watchpoint.  */
7208dffb485Schristos   if (siginfo.si_errno >= 0)
7218dffb485Schristos     return false;
7228dffb485Schristos 
7238dffb485Schristos   /* Cache stopped data address for use by arm_stopped_data_address.  */
7248dffb485Schristos   lwp->arch_private->stopped_data_address
7258dffb485Schristos     = (CORE_ADDR) (uintptr_t) siginfo.si_addr;
7268dffb485Schristos 
7278dffb485Schristos   return true;
7288dffb485Schristos }
7298dffb485Schristos 
7308dffb485Schristos /* Return data address that triggered watchpoint.  Called only if
7318dffb485Schristos    low_stopped_by_watchpoint returned true.  */
7328dffb485Schristos CORE_ADDR
7338dffb485Schristos arm_target::low_stopped_data_address ()
7348dffb485Schristos {
7358dffb485Schristos   struct lwp_info *lwp = get_thread_lwp (current_thread);
7368dffb485Schristos   return lwp->arch_private->stopped_data_address;
7378dffb485Schristos }
7388dffb485Schristos 
7398dffb485Schristos /* Called when a new process is created.  */
7408dffb485Schristos arch_process_info *
7418dffb485Schristos arm_target::low_new_process ()
7428dffb485Schristos {
7438dffb485Schristos   struct arch_process_info *info = XCNEW (struct arch_process_info);
7448dffb485Schristos   return info;
7458dffb485Schristos }
7468dffb485Schristos 
7478dffb485Schristos /* Called when a process is being deleted.  */
7488dffb485Schristos 
7498dffb485Schristos void
7508dffb485Schristos arm_target::low_delete_process (arch_process_info *info)
7518dffb485Schristos {
7528dffb485Schristos   xfree (info);
7538dffb485Schristos }
7548dffb485Schristos 
7558dffb485Schristos /* Called when a new thread is detected.  */
7568dffb485Schristos void
7578dffb485Schristos arm_target::low_new_thread (lwp_info *lwp)
7588dffb485Schristos {
7598dffb485Schristos   struct arch_lwp_info *info = XCNEW (struct arch_lwp_info);
7608dffb485Schristos   int i;
7618dffb485Schristos 
7628dffb485Schristos   for (i = 0; i < MAX_BPTS; i++)
7638dffb485Schristos     info->bpts_changed[i] = 1;
7648dffb485Schristos   for (i = 0; i < MAX_WPTS; i++)
7658dffb485Schristos     info->wpts_changed[i] = 1;
7668dffb485Schristos 
7678dffb485Schristos   lwp->arch_private = info;
7688dffb485Schristos }
7698dffb485Schristos 
7708dffb485Schristos /* Function to call when a thread is being deleted.  */
7718dffb485Schristos 
7728dffb485Schristos void
7738dffb485Schristos arm_target::low_delete_thread (arch_lwp_info *arch_lwp)
7748dffb485Schristos {
7758dffb485Schristos   xfree (arch_lwp);
7768dffb485Schristos }
7778dffb485Schristos 
7788dffb485Schristos void
7798dffb485Schristos arm_target::low_new_fork (process_info *parent, process_info *child)
7808dffb485Schristos {
7818dffb485Schristos   struct arch_process_info *parent_proc_info;
7828dffb485Schristos   struct arch_process_info *child_proc_info;
7838dffb485Schristos   struct lwp_info *child_lwp;
7848dffb485Schristos   struct arch_lwp_info *child_lwp_info;
7858dffb485Schristos   int i;
7868dffb485Schristos 
7878dffb485Schristos   /* These are allocated by linux_add_process.  */
7888dffb485Schristos   gdb_assert (parent->priv != NULL
7898dffb485Schristos 	      && parent->priv->arch_private != NULL);
7908dffb485Schristos   gdb_assert (child->priv != NULL
7918dffb485Schristos 	      && child->priv->arch_private != NULL);
7928dffb485Schristos 
7938dffb485Schristos   parent_proc_info = parent->priv->arch_private;
7948dffb485Schristos   child_proc_info = child->priv->arch_private;
7958dffb485Schristos 
7968dffb485Schristos   /* Linux kernel before 2.6.33 commit
7978dffb485Schristos      72f674d203cd230426437cdcf7dd6f681dad8b0d
7988dffb485Schristos      will inherit hardware debug registers from parent
7998dffb485Schristos      on fork/vfork/clone.  Newer Linux kernels create such tasks with
8008dffb485Schristos      zeroed debug registers.
8018dffb485Schristos 
8028dffb485Schristos      GDB core assumes the child inherits the watchpoints/hw
8038dffb485Schristos      breakpoints of the parent, and will remove them all from the
8048dffb485Schristos      forked off process.  Copy the debug registers mirrors into the
8058dffb485Schristos      new process so that all breakpoints and watchpoints can be
8068dffb485Schristos      removed together.  The debug registers mirror will become zeroed
8078dffb485Schristos      in the end before detaching the forked off process, thus making
8088dffb485Schristos      this compatible with older Linux kernels too.  */
8098dffb485Schristos 
8108dffb485Schristos   *child_proc_info = *parent_proc_info;
8118dffb485Schristos 
8128dffb485Schristos   /* Mark all the hardware breakpoints and watchpoints as changed to
8138dffb485Schristos      make sure that the registers will be updated.  */
8148dffb485Schristos   child_lwp = find_lwp_pid (ptid_t (child->pid));
8158dffb485Schristos   child_lwp_info = child_lwp->arch_private;
8168dffb485Schristos   for (i = 0; i < MAX_BPTS; i++)
8178dffb485Schristos     child_lwp_info->bpts_changed[i] = 1;
8188dffb485Schristos   for (i = 0; i < MAX_WPTS; i++)
8198dffb485Schristos     child_lwp_info->wpts_changed[i] = 1;
8208dffb485Schristos }
8218dffb485Schristos 
8228dffb485Schristos /* Called when resuming a thread.
8238dffb485Schristos    If the debug regs have changed, update the thread's copies.  */
8248dffb485Schristos void
8258dffb485Schristos arm_target::low_prepare_to_resume (lwp_info *lwp)
8268dffb485Schristos {
8278dffb485Schristos   struct thread_info *thread = get_lwp_thread (lwp);
8288dffb485Schristos   int pid = lwpid_of (thread);
8298dffb485Schristos   struct process_info *proc = find_process_pid (pid_of (thread));
8308dffb485Schristos   struct arch_process_info *proc_info = proc->priv->arch_private;
8318dffb485Schristos   struct arch_lwp_info *lwp_info = lwp->arch_private;
8328dffb485Schristos   int i;
8338dffb485Schristos 
8348dffb485Schristos   for (i = 0; i < arm_linux_get_hw_breakpoint_count (); i++)
8358dffb485Schristos     if (lwp_info->bpts_changed[i])
8368dffb485Schristos       {
8378dffb485Schristos 	errno = 0;
8388dffb485Schristos 
8398dffb485Schristos 	if (arm_hwbp_control_is_enabled (proc_info->bpts[i].control))
8408dffb485Schristos 	  if (ptrace (PTRACE_SETHBPREGS, pid,
8418dffb485Schristos 		      (PTRACE_TYPE_ARG3) ((i << 1) + 1),
8428dffb485Schristos 		      &proc_info->bpts[i].address) < 0)
8438dffb485Schristos 	    perror_with_name ("Unexpected error setting breakpoint address");
8448dffb485Schristos 
8458dffb485Schristos 	if (arm_hwbp_control_is_initialized (proc_info->bpts[i].control))
8468dffb485Schristos 	  if (ptrace (PTRACE_SETHBPREGS, pid,
8478dffb485Schristos 		      (PTRACE_TYPE_ARG3) ((i << 1) + 2),
8488dffb485Schristos 		      &proc_info->bpts[i].control) < 0)
8498dffb485Schristos 	    perror_with_name ("Unexpected error setting breakpoint");
8508dffb485Schristos 
8518dffb485Schristos 	lwp_info->bpts_changed[i] = 0;
8528dffb485Schristos       }
8538dffb485Schristos 
8548dffb485Schristos   for (i = 0; i < arm_linux_get_hw_watchpoint_count (); i++)
8558dffb485Schristos     if (lwp_info->wpts_changed[i])
8568dffb485Schristos       {
8578dffb485Schristos 	errno = 0;
8588dffb485Schristos 
8598dffb485Schristos 	if (arm_hwbp_control_is_enabled (proc_info->wpts[i].control))
8608dffb485Schristos 	  if (ptrace (PTRACE_SETHBPREGS, pid,
8618dffb485Schristos 		      (PTRACE_TYPE_ARG3) -((i << 1) + 1),
8628dffb485Schristos 		      &proc_info->wpts[i].address) < 0)
8638dffb485Schristos 	    perror_with_name ("Unexpected error setting watchpoint address");
8648dffb485Schristos 
8658dffb485Schristos 	if (arm_hwbp_control_is_initialized (proc_info->wpts[i].control))
8668dffb485Schristos 	  if (ptrace (PTRACE_SETHBPREGS, pid,
8678dffb485Schristos 		      (PTRACE_TYPE_ARG3) -((i << 1) + 2),
8688dffb485Schristos 		      &proc_info->wpts[i].control) < 0)
8698dffb485Schristos 	    perror_with_name ("Unexpected error setting watchpoint");
8708dffb485Schristos 
8718dffb485Schristos 	lwp_info->wpts_changed[i] = 0;
8728dffb485Schristos       }
8738dffb485Schristos }
8748dffb485Schristos 
8758dffb485Schristos /* Find the next pc for a sigreturn or rt_sigreturn syscall.  In
8768dffb485Schristos    addition, set IS_THUMB depending on whether we will return to ARM
8778dffb485Schristos    or Thumb code.
8788dffb485Schristos    See arm-linux.h for stack layout details.  */
8798dffb485Schristos static CORE_ADDR
8808dffb485Schristos arm_sigreturn_next_pc (struct regcache *regcache, int svc_number,
8818dffb485Schristos 		       int *is_thumb)
8828dffb485Schristos {
8838dffb485Schristos   unsigned long sp;
8848dffb485Schristos   unsigned long sp_data;
8858dffb485Schristos   /* Offset of PC register.  */
8868dffb485Schristos   int pc_offset = 0;
8878dffb485Schristos   CORE_ADDR next_pc = 0;
8888dffb485Schristos   uint32_t cpsr;
8898dffb485Schristos 
8908dffb485Schristos   gdb_assert (svc_number == __NR_sigreturn || svc_number == __NR_rt_sigreturn);
8918dffb485Schristos 
8928dffb485Schristos   collect_register_by_name (regcache, "sp", &sp);
8938dffb485Schristos   the_target->read_memory (sp, (unsigned char *) &sp_data, 4);
8948dffb485Schristos 
8958dffb485Schristos   pc_offset = arm_linux_sigreturn_next_pc_offset
8968dffb485Schristos     (sp, sp_data, svc_number, __NR_sigreturn == svc_number ? 1 : 0);
8978dffb485Schristos 
8988dffb485Schristos   the_target->read_memory (sp + pc_offset, (unsigned char *) &next_pc, 4);
8998dffb485Schristos 
9008dffb485Schristos   /* Set IS_THUMB according the CPSR saved on the stack.  */
9018dffb485Schristos   the_target->read_memory (sp + pc_offset + 4, (unsigned char *) &cpsr, 4);
9028dffb485Schristos   *is_thumb = ((cpsr & CPSR_T) != 0);
9038dffb485Schristos 
9048dffb485Schristos   return next_pc;
9058dffb485Schristos }
9068dffb485Schristos 
9078dffb485Schristos /* When PC is at a syscall instruction, return the PC of the next
9088dffb485Schristos    instruction to be executed.  */
9098dffb485Schristos static CORE_ADDR
9108dffb485Schristos get_next_pcs_syscall_next_pc (struct arm_get_next_pcs *self)
9118dffb485Schristos {
9128dffb485Schristos   CORE_ADDR next_pc = 0;
9138dffb485Schristos   CORE_ADDR pc = regcache_read_pc (self->regcache);
9148dffb485Schristos   int is_thumb = arm_is_thumb_mode ();
9158dffb485Schristos   ULONGEST svc_number = 0;
916*8780886fSchristos   regcache *regcache
917*8780886fSchristos     = gdb::checked_static_cast<struct regcache *> (self->regcache);
9188dffb485Schristos 
9198dffb485Schristos   if (is_thumb)
9208dffb485Schristos     {
9218dffb485Schristos       collect_register (regcache, 7, &svc_number);
9228dffb485Schristos       next_pc = pc + 2;
9238dffb485Schristos     }
9248dffb485Schristos   else
9258dffb485Schristos     {
9268dffb485Schristos       unsigned long this_instr;
9278dffb485Schristos       unsigned long svc_operand;
9288dffb485Schristos 
9298dffb485Schristos       target_read_memory (pc, (unsigned char *) &this_instr, 4);
9308dffb485Schristos       svc_operand = (0x00ffffff & this_instr);
9318dffb485Schristos 
9328dffb485Schristos       if (svc_operand)  /* OABI.  */
9338dffb485Schristos 	{
9348dffb485Schristos 	  svc_number = svc_operand - 0x900000;
9358dffb485Schristos 	}
9368dffb485Schristos       else /* EABI.  */
9378dffb485Schristos 	{
9388dffb485Schristos 	  collect_register (regcache, 7, &svc_number);
9398dffb485Schristos 	}
9408dffb485Schristos 
9418dffb485Schristos       next_pc = pc + 4;
9428dffb485Schristos     }
9438dffb485Schristos 
9448dffb485Schristos   /* This is a sigreturn or sigreturn_rt syscall.  */
9458dffb485Schristos   if (svc_number == __NR_sigreturn || svc_number == __NR_rt_sigreturn)
9468dffb485Schristos     {
9478dffb485Schristos       /* SIGRETURN or RT_SIGRETURN may affect the arm thumb mode, so
9488dffb485Schristos 	 update IS_THUMB.   */
9498dffb485Schristos       next_pc = arm_sigreturn_next_pc (regcache, svc_number, &is_thumb);
9508dffb485Schristos     }
9518dffb485Schristos 
9528dffb485Schristos   /* Addresses for calling Thumb functions have the bit 0 set.  */
9538dffb485Schristos   if (is_thumb)
9548dffb485Schristos     next_pc = MAKE_THUMB_ADDR (next_pc);
9558dffb485Schristos 
9568dffb485Schristos   return next_pc;
9578dffb485Schristos }
9588dffb485Schristos 
9598dffb485Schristos static const struct target_desc *
9608dffb485Schristos arm_read_description (void)
9618dffb485Schristos {
962*8780886fSchristos   unsigned long arm_hwcap = linux_get_hwcap (current_thread->id.pid (), 4);
9638dffb485Schristos 
9648dffb485Schristos   if (arm_hwcap & HWCAP_IWMMXT)
9658dffb485Schristos     return arm_linux_read_description (ARM_FP_TYPE_IWMMXT);
9668dffb485Schristos 
9678dffb485Schristos   if (arm_hwcap & HWCAP_VFP)
9688dffb485Schristos     {
9698dffb485Schristos       /* Make sure that the kernel supports reading VFP registers.  Support was
9708dffb485Schristos 	 added in 2.6.30.  */
9718dffb485Schristos       int pid = lwpid_of (current_thread);
9728dffb485Schristos       errno = 0;
9738dffb485Schristos       char *buf = (char *) alloca (ARM_VFP3_REGS_SIZE);
9748dffb485Schristos       if (ptrace (PTRACE_GETVFPREGS, pid, 0, buf) < 0 && errno == EIO)
9758dffb485Schristos 	return arm_linux_read_description (ARM_FP_TYPE_NONE);
9768dffb485Schristos 
9778dffb485Schristos       /* NEON implies either no VFP, or VFPv3-D32.  We only support
9788dffb485Schristos 	 it with VFP.  */
9798dffb485Schristos       if (arm_hwcap & HWCAP_NEON)
9808dffb485Schristos 	return aarch32_linux_read_description ();
9818dffb485Schristos       else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPv3D16)) == HWCAP_VFPv3)
9828dffb485Schristos 	return arm_linux_read_description (ARM_FP_TYPE_VFPV3);
9838dffb485Schristos       else
9848dffb485Schristos 	return arm_linux_read_description (ARM_FP_TYPE_VFPV2);
9858dffb485Schristos     }
9868dffb485Schristos 
9878dffb485Schristos   /* The default configuration uses legacy FPA registers, probably
9888dffb485Schristos      simulated.  */
9898dffb485Schristos   return arm_linux_read_description (ARM_FP_TYPE_NONE);
9908dffb485Schristos }
9918dffb485Schristos 
9928dffb485Schristos void
9938dffb485Schristos arm_target::low_arch_setup ()
9948dffb485Schristos {
9958dffb485Schristos   int tid = lwpid_of (current_thread);
9968dffb485Schristos   int gpregs[18];
9978dffb485Schristos   struct iovec iov;
9988dffb485Schristos 
9998dffb485Schristos   /* Query hardware watchpoint/breakpoint capabilities.  */
10008dffb485Schristos   arm_linux_init_hwbp_cap (tid);
10018dffb485Schristos 
10028dffb485Schristos   current_process ()->tdesc = arm_read_description ();
10038dffb485Schristos 
10048dffb485Schristos   iov.iov_base = gpregs;
10058dffb485Schristos   iov.iov_len = sizeof (gpregs);
10068dffb485Schristos 
10078dffb485Schristos   /* Check if PTRACE_GETREGSET works.  */
10088dffb485Schristos   if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iov) == 0)
1009*8780886fSchristos     have_ptrace_getregset = TRIBOOL_TRUE;
10108dffb485Schristos   else
1011*8780886fSchristos     have_ptrace_getregset = TRIBOOL_FALSE;
10128dffb485Schristos }
10138dffb485Schristos 
10148dffb485Schristos bool
10158dffb485Schristos arm_target::supports_software_single_step ()
10168dffb485Schristos {
10178dffb485Schristos   return true;
10188dffb485Schristos }
10198dffb485Schristos 
10208dffb485Schristos /* Fetch the next possible PCs after the current instruction executes.  */
10218dffb485Schristos 
10228dffb485Schristos std::vector<CORE_ADDR>
10238dffb485Schristos arm_target::low_get_next_pcs (regcache *regcache)
10248dffb485Schristos {
10258dffb485Schristos   struct arm_get_next_pcs next_pcs_ctx;
10268dffb485Schristos 
10278dffb485Schristos   arm_get_next_pcs_ctor (&next_pcs_ctx,
10288dffb485Schristos 			 &get_next_pcs_ops,
10298dffb485Schristos 			 /* Byte order is ignored assumed as host.  */
10308dffb485Schristos 			 0,
10318dffb485Schristos 			 0,
10328dffb485Schristos 			 1,
10338dffb485Schristos 			 regcache);
10348dffb485Schristos 
10358dffb485Schristos   return arm_get_next_pcs (&next_pcs_ctx);
10368dffb485Schristos }
10378dffb485Schristos 
10388dffb485Schristos /* Support for hardware single step.  */
10398dffb485Schristos 
10408dffb485Schristos bool
10418dffb485Schristos arm_target::supports_hardware_single_step ()
10428dffb485Schristos {
10438dffb485Schristos   return false;
10448dffb485Schristos }
10458dffb485Schristos 
10468dffb485Schristos bool
10478dffb485Schristos arm_target::low_supports_catch_syscall ()
10488dffb485Schristos {
10498dffb485Schristos   return true;
10508dffb485Schristos }
10518dffb485Schristos 
10528dffb485Schristos /* Implementation of linux target ops method "low_get_syscall_trapinfo".  */
10538dffb485Schristos 
10548dffb485Schristos void
10558dffb485Schristos arm_target::low_get_syscall_trapinfo (regcache *regcache, int *sysno)
10568dffb485Schristos {
10578dffb485Schristos   if (arm_is_thumb_mode ())
10588dffb485Schristos     collect_register_by_name (regcache, "r7", sysno);
10598dffb485Schristos   else
10608dffb485Schristos     {
10618dffb485Schristos       unsigned long pc;
10628dffb485Schristos       unsigned long insn;
10638dffb485Schristos 
10648dffb485Schristos       collect_register_by_name (regcache, "pc", &pc);
10658dffb485Schristos 
10668dffb485Schristos       if (read_memory (pc - 4, (unsigned char *) &insn, 4))
10678dffb485Schristos 	*sysno = UNKNOWN_SYSCALL;
10688dffb485Schristos       else
10698dffb485Schristos 	{
10708dffb485Schristos 	  unsigned long svc_operand = (0x00ffffff & insn);
10718dffb485Schristos 
10728dffb485Schristos 	  if (svc_operand)
10738dffb485Schristos 	    {
10748dffb485Schristos 	      /* OABI */
10758dffb485Schristos 	      *sysno = svc_operand - 0x900000;
10768dffb485Schristos 	    }
10778dffb485Schristos 	  else
10788dffb485Schristos 	    {
10798dffb485Schristos 	      /* EABI */
10808dffb485Schristos 	      collect_register_by_name (regcache, "r7", sysno);
10818dffb485Schristos 	    }
10828dffb485Schristos 	}
10838dffb485Schristos     }
10848dffb485Schristos }
10858dffb485Schristos 
10868dffb485Schristos /* Register sets without using PTRACE_GETREGSET.  */
10878dffb485Schristos 
10888dffb485Schristos static struct regset_info arm_regsets[] = {
10898dffb485Schristos   { PTRACE_GETREGS, PTRACE_SETREGS, 0,
10908dffb485Schristos     ARM_CORE_REGS_SIZE + ARM_INT_REGISTER_SIZE, GENERAL_REGS,
10918dffb485Schristos     arm_fill_gregset, arm_store_gregset },
10928dffb485Schristos   { PTRACE_GETWMMXREGS, PTRACE_SETWMMXREGS, 0, IWMMXT_REGS_SIZE, EXTENDED_REGS,
10938dffb485Schristos     arm_fill_wmmxregset, arm_store_wmmxregset },
10948dffb485Schristos   { PTRACE_GETVFPREGS, PTRACE_SETVFPREGS, 0, ARM_VFP3_REGS_SIZE, EXTENDED_REGS,
10958dffb485Schristos     arm_fill_vfpregset, arm_store_vfpregset },
10968dffb485Schristos   NULL_REGSET
10978dffb485Schristos };
10988dffb485Schristos 
10998dffb485Schristos static struct regsets_info arm_regsets_info =
11008dffb485Schristos   {
11018dffb485Schristos     arm_regsets, /* regsets */
11028dffb485Schristos     0, /* num_regsets */
11038dffb485Schristos     NULL, /* disabled_regsets */
11048dffb485Schristos   };
11058dffb485Schristos 
11068dffb485Schristos static struct usrregs_info arm_usrregs_info =
11078dffb485Schristos   {
11088dffb485Schristos     arm_num_regs,
11098dffb485Schristos     arm_regmap,
11108dffb485Schristos   };
11118dffb485Schristos 
11128dffb485Schristos static struct regs_info regs_info_arm =
11138dffb485Schristos   {
11148dffb485Schristos     NULL, /* regset_bitmap */
11158dffb485Schristos     &arm_usrregs_info,
11168dffb485Schristos     &arm_regsets_info
11178dffb485Schristos   };
11188dffb485Schristos 
11198dffb485Schristos const regs_info *
11208dffb485Schristos arm_target::get_regs_info ()
11218dffb485Schristos {
11228dffb485Schristos   const struct target_desc *tdesc = current_process ()->tdesc;
11238dffb485Schristos 
1124*8780886fSchristos   if (have_ptrace_getregset == TRIBOOL_TRUE
11258dffb485Schristos       && (is_aarch32_linux_description (tdesc)
11268dffb485Schristos 	  || arm_linux_get_tdesc_fp_type (tdesc) == ARM_FP_TYPE_VFPV3))
11278dffb485Schristos     return &regs_info_aarch32;
11288dffb485Schristos 
11298dffb485Schristos   return &regs_info_arm;
11308dffb485Schristos }
11318dffb485Schristos 
11328dffb485Schristos /* The linux target ops object.  */
11338dffb485Schristos 
11348dffb485Schristos linux_process_target *the_linux_target = &the_arm_target;
11358dffb485Schristos 
11368dffb485Schristos void
11378dffb485Schristos initialize_low_arch (void)
11388dffb485Schristos {
11398dffb485Schristos   initialize_low_arch_aarch32 ();
11408dffb485Schristos   initialize_regsets_info (&arm_regsets_info);
11418dffb485Schristos }
1142