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, ®s[i]); 68 69 collect_register (regcache, ARM_PS_REGNUM, ®s[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, ®s[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