Home | History | Annotate | Line # | Download | only in gdbserver
      1 /* Copyright (C) 1995-2024 Free Software Foundation, Inc.
      2 
      3    This file is part of GDB.
      4 
      5    This program is free software; you can redistribute it and/or modify
      6    it under the terms of the GNU General Public License as published by
      7    the Free Software Foundation; either version 3 of the License, or
      8    (at your option) any later version.
      9 
     10    This program is distributed in the hope that it will be useful,
     11    but WITHOUT ANY WARRANTY; without even the implied warranty of
     12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13    GNU General Public License for more details.
     14 
     15    You should have received a copy of the GNU General Public License
     16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     17 
     18 #include "arch/arm.h"
     19 #include "arch/arm-linux.h"
     20 #include "linux-low.h"
     21 #include "linux-aarch32-low.h"
     22 
     23 #include <sys/ptrace.h>
     24 /* Don't include elf.h if linux/elf.h got included by gdb_proc_service.h.
     25    On Bionic elf.h and linux/elf.h have conflicting definitions.  */
     26 #ifndef ELFMAG0
     27 #include <elf.h>
     28 #endif
     29 
     30 /* Correct in either endianness.  */
     31 #define arm_abi_breakpoint 0xef9f0001UL
     32 
     33 /* For new EABI binaries.  We recognize it regardless of which ABI
     34    is used for gdbserver, so single threaded debugging should work
     35    OK, but for multi-threaded debugging we only insert the current
     36    ABI's breakpoint instruction.  For now at least.  */
     37 #define arm_eabi_breakpoint 0xe7f001f0UL
     38 
     39 #if (defined __ARM_EABI__ || defined __aarch64__)
     40 static const unsigned long arm_breakpoint = arm_eabi_breakpoint;
     41 #else
     42 static const unsigned long arm_breakpoint = arm_abi_breakpoint;
     43 #endif
     44 
     45 #define arm_breakpoint_len 4
     46 static const unsigned short thumb_breakpoint = 0xde01;
     47 #define thumb_breakpoint_len 2
     48 static const unsigned short thumb2_breakpoint[] = { 0xf7f0, 0xa000 };
     49 #define thumb2_breakpoint_len 4
     50 
     51 /* Some older versions of GNU/Linux and Android do not define
     52    the following macros.  */
     53 #ifndef NT_ARM_VFP
     54 #define NT_ARM_VFP 0x400
     55 #endif
     56 
     57 /* Collect GP registers from REGCACHE to buffer BUF.  */
     58 
     59 void
     60 arm_fill_gregset (struct regcache *regcache, void *buf)
     61 {
     62   int i;
     63   uint32_t *regs = (uint32_t *) buf;
     64   uint32_t cpsr = regs[ARM_CPSR_GREGNUM];
     65 
     66   for (i = ARM_A1_REGNUM; i <= ARM_PC_REGNUM; i++)
     67     collect_register (regcache, i, &regs[i]);
     68 
     69   collect_register (regcache, ARM_PS_REGNUM, &regs[ARM_CPSR_GREGNUM]);
     70   /* Keep reserved bits bit 20 to bit 23.  */
     71   regs[ARM_CPSR_GREGNUM] = ((regs[ARM_CPSR_GREGNUM] & 0xff0fffff)
     72 			    | (cpsr & 0x00f00000));
     73 }
     74 
     75 /* Supply GP registers contents, stored in BUF, to REGCACHE.  */
     76 
     77 void
     78 arm_store_gregset (struct regcache *regcache, const void *buf)
     79 {
     80   int i;
     81   char zerobuf[8];
     82   const uint32_t *regs = (const uint32_t *) buf;
     83   uint32_t cpsr = regs[ARM_CPSR_GREGNUM];
     84 
     85   memset (zerobuf, 0, 8);
     86   for (i = ARM_A1_REGNUM; i <= ARM_PC_REGNUM; i++)
     87     supply_register (regcache, i, &regs[i]);
     88 
     89   for (; i < ARM_PS_REGNUM; i++)
     90     supply_register (regcache, i, zerobuf);
     91 
     92   /* Clear reserved bits bit 20 to bit 23.  */
     93   cpsr &= 0xff0fffff;
     94   supply_register (regcache, ARM_PS_REGNUM, &cpsr);
     95 }
     96 
     97 /* Collect NUM number of VFP registers from REGCACHE to buffer BUF.  */
     98 
     99 void
    100 arm_fill_vfpregset_num (struct regcache *regcache, void *buf, int num)
    101 {
    102   int i, base;
    103 
    104   gdb_assert (num == 16 || num == 32);
    105 
    106   base = find_regno (regcache->tdesc, "d0");
    107   for (i = 0; i < num; i++)
    108     collect_register (regcache, base + i, (char *) buf + i * 8);
    109 
    110   collect_register_by_name (regcache, "fpscr", (char *) buf + 32 * 8);
    111 }
    112 
    113 /* Supply NUM number of VFP registers contents, stored in BUF, to
    114    REGCACHE.  */
    115 
    116 void
    117 arm_store_vfpregset_num (struct regcache *regcache, const void *buf, int num)
    118 {
    119   int i, base;
    120 
    121   gdb_assert (num == 16 || num == 32);
    122 
    123   base = find_regno (regcache->tdesc, "d0");
    124   for (i = 0; i < num; i++)
    125     supply_register (regcache, base + i, (char *) buf + i * 8);
    126 
    127   supply_register_by_name (regcache, "fpscr", (char *) buf + 32 * 8);
    128 }
    129 
    130 static void
    131 arm_fill_vfpregset (struct regcache *regcache, void *buf)
    132 {
    133   arm_fill_vfpregset_num (regcache, buf, 32);
    134 }
    135 
    136 static void
    137 arm_store_vfpregset (struct regcache *regcache, const void *buf)
    138 {
    139   arm_store_vfpregset_num (regcache, buf, 32);
    140 }
    141 
    142 /* Register sets with using PTRACE_GETREGSET.  */
    143 
    144 static struct regset_info aarch32_regsets[] = {
    145   { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS,
    146     ARM_CORE_REGS_SIZE + ARM_INT_REGISTER_SIZE, GENERAL_REGS,
    147     arm_fill_gregset, arm_store_gregset },
    148   { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARM_VFP, ARM_VFP3_REGS_SIZE,
    149     EXTENDED_REGS,
    150     arm_fill_vfpregset, arm_store_vfpregset },
    151   NULL_REGSET
    152 };
    153 
    154 static struct regsets_info aarch32_regsets_info =
    155   {
    156     aarch32_regsets, /* regsets */
    157     0, /* num_regsets */
    158     NULL, /* disabled_regsets */
    159   };
    160 
    161 struct regs_info regs_info_aarch32 =
    162   {
    163     NULL, /* regset_bitmap */
    164     NULL, /* usrregs */
    165     &aarch32_regsets_info
    166   };
    167 
    168 /* Returns 1 if the current instruction set is thumb, 0 otherwise.  */
    169 
    170 int
    171 arm_is_thumb_mode (void)
    172 {
    173   struct regcache *regcache = get_thread_regcache (current_thread, 1);
    174   unsigned long cpsr;
    175 
    176   collect_register_by_name (regcache, "cpsr", &cpsr);
    177 
    178   if (cpsr & 0x20)
    179     return 1;
    180   else
    181     return 0;
    182 }
    183 
    184 /* Returns 1 if there is a software breakpoint at location.  */
    185 
    186 int
    187 arm_breakpoint_at (CORE_ADDR where)
    188 {
    189   if (arm_is_thumb_mode ())
    190     {
    191       /* Thumb mode.  */
    192       unsigned short insn;
    193 
    194       the_target->read_memory (where, (unsigned char *) &insn, 2);
    195       if (insn == thumb_breakpoint)
    196 	return 1;
    197 
    198       if (insn == thumb2_breakpoint[0])
    199 	{
    200 	  the_target->read_memory (where + 2, (unsigned char *) &insn, 2);
    201 	  if (insn == thumb2_breakpoint[1])
    202 	    return 1;
    203 	}
    204     }
    205   else
    206     {
    207       /* ARM mode.  */
    208       unsigned long insn;
    209 
    210       the_target->read_memory (where, (unsigned char *) &insn, 4);
    211       if (insn == arm_abi_breakpoint)
    212 	return 1;
    213 
    214       if (insn == arm_eabi_breakpoint)
    215 	return 1;
    216     }
    217 
    218   return 0;
    219 }
    220 
    221 /* Implementation of linux_target_ops method "breakpoint_kind_from_pc".
    222 
    223    Determine the type and size of breakpoint to insert at PCPTR.  Uses the
    224    program counter value to determine whether a 16-bit or 32-bit breakpoint
    225    should be used.  It returns the breakpoint's kind, and adjusts the program
    226    counter (if necessary) to point to the actual memory location where the
    227    breakpoint should be inserted.  */
    228 
    229 int
    230 arm_breakpoint_kind_from_pc (CORE_ADDR *pcptr)
    231 {
    232   if (IS_THUMB_ADDR (*pcptr))
    233     {
    234       gdb_byte buf[2];
    235 
    236       *pcptr = UNMAKE_THUMB_ADDR (*pcptr);
    237 
    238       /* Check whether we are replacing a thumb2 32-bit instruction.  */
    239       if (target_read_memory (*pcptr, buf, 2) == 0)
    240 	{
    241 	  unsigned short inst1 = 0;
    242 
    243 	  target_read_memory (*pcptr, (gdb_byte *) &inst1, 2);
    244 	  if (thumb_insn_size (inst1) == 4)
    245 	    return ARM_BP_KIND_THUMB2;
    246 	}
    247       return ARM_BP_KIND_THUMB;
    248     }
    249   else
    250     return ARM_BP_KIND_ARM;
    251 }
    252 
    253 /*  Implementation of the linux_target_ops method "sw_breakpoint_from_kind".  */
    254 
    255 const gdb_byte *
    256 arm_sw_breakpoint_from_kind (int kind , int *size)
    257 {
    258   *size = arm_breakpoint_len;
    259   /* Define an ARM-mode breakpoint; we only set breakpoints in the C
    260      library, which is most likely to be ARM.  If the kernel supports
    261      clone events, we will never insert a breakpoint, so even a Thumb
    262      C library will work; so will mixing EABI/non-EABI gdbserver and
    263      application.  */
    264   switch (kind)
    265     {
    266       case ARM_BP_KIND_THUMB:
    267 	*size = thumb_breakpoint_len;
    268 	return (gdb_byte *) &thumb_breakpoint;
    269       case ARM_BP_KIND_THUMB2:
    270 	*size = thumb2_breakpoint_len;
    271 	return (gdb_byte *) &thumb2_breakpoint;
    272       case ARM_BP_KIND_ARM:
    273 	*size = arm_breakpoint_len;
    274 	return (const gdb_byte *) &arm_breakpoint;
    275       default:
    276        return NULL;
    277     }
    278   return NULL;
    279 }
    280 
    281 /* Implementation of the linux_target_ops method
    282    "breakpoint_kind_from_current_state".  */
    283 
    284 int
    285 arm_breakpoint_kind_from_current_state (CORE_ADDR *pcptr)
    286 {
    287   if (arm_is_thumb_mode ())
    288     {
    289       *pcptr = MAKE_THUMB_ADDR (*pcptr);
    290       return arm_breakpoint_kind_from_pc (pcptr);
    291     }
    292   else
    293     {
    294       return arm_breakpoint_kind_from_pc (pcptr);
    295     }
    296 }
    297 
    298 void
    299 initialize_low_arch_aarch32 (void)
    300 {
    301   initialize_regsets_info (&aarch32_regsets_info);
    302 }
    303