1 1.1 christos /* Common target dependent code for GDB on AArch64 systems. 2 1.1 christos 3 1.11 christos Copyright (C) 2009-2024 Free Software Foundation, Inc. 4 1.1 christos Contributed by ARM Ltd. 5 1.1 christos 6 1.1 christos This file is part of GDB. 7 1.1 christos 8 1.1 christos This program is free software; you can redistribute it and/or modify 9 1.1 christos it under the terms of the GNU General Public License as published by 10 1.1 christos the Free Software Foundation; either version 3 of the License, or 11 1.1 christos (at your option) any later version. 12 1.1 christos 13 1.1 christos This program is distributed in the hope that it will be useful, 14 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 15 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 1.1 christos GNU General Public License for more details. 17 1.1 christos 18 1.1 christos You should have received a copy of the GNU General Public License 19 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20 1.1 christos 21 1.1 christos 22 1.11 christos #include "extract-store-integer.h" 23 1.1 christos #include "frame.h" 24 1.11 christos #include "language.h" 25 1.11 christos #include "cli/cli-cmds.h" 26 1.1 christos #include "gdbcore.h" 27 1.1 christos #include "dis-asm.h" 28 1.1 christos #include "regcache.h" 29 1.1 christos #include "reggroups.h" 30 1.1 christos #include "value.h" 31 1.1 christos #include "arch-utils.h" 32 1.1 christos #include "osabi.h" 33 1.1 christos #include "frame-unwind.h" 34 1.1 christos #include "frame-base.h" 35 1.1 christos #include "trad-frame.h" 36 1.1 christos #include "objfiles.h" 37 1.9 christos #include "dwarf2.h" 38 1.9 christos #include "dwarf2/frame.h" 39 1.1 christos #include "gdbtypes.h" 40 1.1 christos #include "prologue-value.h" 41 1.1 christos #include "target-descriptions.h" 42 1.1 christos #include "user-regs.h" 43 1.6 christos #include "ax-gdb.h" 44 1.9 christos #include "gdbsupport/selftest.h" 45 1.1 christos 46 1.1 christos #include "aarch64-tdep.h" 47 1.8 christos #include "aarch64-ravenscar-thread.h" 48 1.12 christos #include "arch/aarch64-mte.h" 49 1.1 christos 50 1.5 christos #include "record.h" 51 1.5 christos #include "record-full.h" 52 1.6 christos #include "arch/aarch64-insn.h" 53 1.9 christos #include "gdbarch.h" 54 1.6 christos 55 1.6 christos #include "opcode/aarch64.h" 56 1.7 christos #include <algorithm> 57 1.10 christos #include <unordered_map> 58 1.6 christos 59 1.11 christos /* For inferior_ptid and current_inferior (). */ 60 1.11 christos #include "inferior.h" 61 1.11 christos /* For std::sqrt and std::pow. */ 62 1.11 christos #include <cmath> 63 1.11 christos 64 1.8 christos /* A Homogeneous Floating-Point or Short-Vector Aggregate may have at most 65 1.8 christos four members. */ 66 1.8 christos #define HA_MAX_NUM_FLDS 4 67 1.8 christos 68 1.8 christos /* All possible aarch64 target descriptors. */ 69 1.10 christos static std::unordered_map <aarch64_features, target_desc *> tdesc_aarch64_map; 70 1.1 christos 71 1.11 christos /* The standard register names, and all the valid aliases for them. 72 1.11 christos We're not adding fp here, that name is already taken, see 73 1.11 christos _initialize_frame_reg. */ 74 1.1 christos static const struct 75 1.1 christos { 76 1.1 christos const char *const name; 77 1.1 christos int regnum; 78 1.1 christos } aarch64_register_aliases[] = 79 1.1 christos { 80 1.11 christos /* Link register alias for x30. */ 81 1.1 christos {"lr", AARCH64_LR_REGNUM}, 82 1.11 christos /* SP is the canonical name for x31 according to aarch64_r_register_names, 83 1.11 christos so we're adding an x31 alias for sp. */ 84 1.11 christos {"x31", AARCH64_SP_REGNUM}, 85 1.1 christos /* specials */ 86 1.1 christos {"ip0", AARCH64_X0_REGNUM + 16}, 87 1.1 christos {"ip1", AARCH64_X0_REGNUM + 17} 88 1.1 christos }; 89 1.1 christos 90 1.1 christos /* The required core 'R' registers. */ 91 1.1 christos static const char *const aarch64_r_register_names[] = 92 1.1 christos { 93 1.1 christos /* These registers must appear in consecutive RAW register number 94 1.1 christos order and they must begin with AARCH64_X0_REGNUM! */ 95 1.1 christos "x0", "x1", "x2", "x3", 96 1.1 christos "x4", "x5", "x6", "x7", 97 1.1 christos "x8", "x9", "x10", "x11", 98 1.1 christos "x12", "x13", "x14", "x15", 99 1.1 christos "x16", "x17", "x18", "x19", 100 1.1 christos "x20", "x21", "x22", "x23", 101 1.1 christos "x24", "x25", "x26", "x27", 102 1.1 christos "x28", "x29", "x30", "sp", 103 1.1 christos "pc", "cpsr" 104 1.1 christos }; 105 1.1 christos 106 1.1 christos /* The FP/SIMD 'V' registers. */ 107 1.1 christos static const char *const aarch64_v_register_names[] = 108 1.1 christos { 109 1.1 christos /* These registers must appear in consecutive RAW register number 110 1.1 christos order and they must begin with AARCH64_V0_REGNUM! */ 111 1.1 christos "v0", "v1", "v2", "v3", 112 1.1 christos "v4", "v5", "v6", "v7", 113 1.1 christos "v8", "v9", "v10", "v11", 114 1.1 christos "v12", "v13", "v14", "v15", 115 1.1 christos "v16", "v17", "v18", "v19", 116 1.1 christos "v20", "v21", "v22", "v23", 117 1.1 christos "v24", "v25", "v26", "v27", 118 1.1 christos "v28", "v29", "v30", "v31", 119 1.1 christos "fpsr", 120 1.1 christos "fpcr" 121 1.1 christos }; 122 1.1 christos 123 1.8 christos /* The SVE 'Z' and 'P' registers. */ 124 1.8 christos static const char *const aarch64_sve_register_names[] = 125 1.8 christos { 126 1.8 christos /* These registers must appear in consecutive RAW register number 127 1.8 christos order and they must begin with AARCH64_SVE_Z0_REGNUM! */ 128 1.8 christos "z0", "z1", "z2", "z3", 129 1.8 christos "z4", "z5", "z6", "z7", 130 1.8 christos "z8", "z9", "z10", "z11", 131 1.8 christos "z12", "z13", "z14", "z15", 132 1.8 christos "z16", "z17", "z18", "z19", 133 1.8 christos "z20", "z21", "z22", "z23", 134 1.8 christos "z24", "z25", "z26", "z27", 135 1.8 christos "z28", "z29", "z30", "z31", 136 1.8 christos "fpsr", "fpcr", 137 1.8 christos "p0", "p1", "p2", "p3", 138 1.8 christos "p4", "p5", "p6", "p7", 139 1.8 christos "p8", "p9", "p10", "p11", 140 1.8 christos "p12", "p13", "p14", "p15", 141 1.8 christos "ffr", "vg" 142 1.8 christos }; 143 1.8 christos 144 1.9 christos static const char *const aarch64_pauth_register_names[] = 145 1.9 christos { 146 1.11 christos /* Authentication mask for data pointer, low half/user pointers. */ 147 1.9 christos "pauth_dmask", 148 1.11 christos /* Authentication mask for code pointer, low half/user pointers. */ 149 1.11 christos "pauth_cmask", 150 1.11 christos /* Authentication mask for data pointer, high half / kernel pointers. */ 151 1.11 christos "pauth_dmask_high", 152 1.11 christos /* Authentication mask for code pointer, high half / kernel pointers. */ 153 1.11 christos "pauth_cmask_high" 154 1.9 christos }; 155 1.9 christos 156 1.10 christos static const char *const aarch64_mte_register_names[] = 157 1.10 christos { 158 1.10 christos /* Tag Control Register. */ 159 1.10 christos "tag_ctl" 160 1.10 christos }; 161 1.10 christos 162 1.11 christos static int aarch64_stack_frame_destroyed_p (struct gdbarch *, CORE_ADDR); 163 1.11 christos 164 1.1 christos /* AArch64 prologue cache structure. */ 165 1.1 christos struct aarch64_prologue_cache 166 1.1 christos { 167 1.6 christos /* The program counter at the start of the function. It is used to 168 1.6 christos identify this frame as a prologue frame. */ 169 1.6 christos CORE_ADDR func; 170 1.6 christos 171 1.6 christos /* The program counter at the time this frame was created; i.e. where 172 1.6 christos this function was called from. It is used to identify this frame as a 173 1.6 christos stub frame. */ 174 1.6 christos CORE_ADDR prev_pc; 175 1.6 christos 176 1.1 christos /* The stack pointer at the time this frame was created; i.e. the 177 1.1 christos caller's stack pointer when this function was called. It is used 178 1.1 christos to identify this frame. */ 179 1.1 christos CORE_ADDR prev_sp; 180 1.1 christos 181 1.6 christos /* Is the target available to read from? */ 182 1.6 christos int available_p; 183 1.6 christos 184 1.1 christos /* The frame base for this frame is just prev_sp - frame size. 185 1.1 christos FRAMESIZE is the distance from the frame pointer to the 186 1.1 christos initial stack pointer. */ 187 1.1 christos int framesize; 188 1.1 christos 189 1.1 christos /* The register used to hold the frame pointer for this frame. */ 190 1.1 christos int framereg; 191 1.1 christos 192 1.1 christos /* Saved register offsets. */ 193 1.10 christos trad_frame_saved_reg *saved_regs; 194 1.1 christos }; 195 1.1 christos 196 1.11 christos /* Holds information used to read/write from/to ZA 197 1.11 christos pseudo-registers. 198 1.11 christos 199 1.11 christos With this information, the read/write code can be simplified so it 200 1.11 christos deals only with the required information to map a ZA pseudo-register 201 1.11 christos to the exact bytes into the ZA contents buffer. Otherwise we'd need 202 1.11 christos to use a lot of conditionals. */ 203 1.11 christos 204 1.11 christos struct za_offsets 205 1.11 christos { 206 1.11 christos /* Offset, into ZA, of the starting byte of the pseudo-register. */ 207 1.11 christos size_t starting_offset; 208 1.11 christos /* The size of the contiguous chunks of the pseudo-register. */ 209 1.11 christos size_t chunk_size; 210 1.11 christos /* The number of pseudo-register chunks contained in ZA. */ 211 1.11 christos size_t chunks; 212 1.11 christos /* The offset between each contiguous chunk. */ 213 1.11 christos size_t stride_size; 214 1.11 christos }; 215 1.11 christos 216 1.11 christos /* Holds data that is helpful to determine the individual fields that make 217 1.11 christos up the names of the ZA pseudo-registers. It is also very helpful to 218 1.11 christos determine offsets, stride and sizes for reading ZA tiles and tile 219 1.11 christos slices. */ 220 1.11 christos 221 1.11 christos struct za_pseudo_encoding 222 1.11 christos { 223 1.11 christos /* The slice index (0 ~ svl). Only used for tile slices. */ 224 1.11 christos uint8_t slice_index; 225 1.11 christos /* The tile number (0 ~ 15). */ 226 1.11 christos uint8_t tile_index; 227 1.11 christos /* Direction (horizontal/vertical). Only used for tile slices. */ 228 1.11 christos bool horizontal; 229 1.11 christos /* Qualifier index (0 ~ 4). These map to B, H, S, D and Q. */ 230 1.11 christos uint8_t qualifier_index; 231 1.11 christos }; 232 1.11 christos 233 1.1 christos static void 234 1.1 christos show_aarch64_debug (struct ui_file *file, int from_tty, 235 1.10 christos struct cmd_list_element *c, const char *value) 236 1.1 christos { 237 1.10 christos gdb_printf (file, _("AArch64 debugging is %s.\n"), value); 238 1.1 christos } 239 1.1 christos 240 1.7 christos namespace { 241 1.7 christos 242 1.7 christos /* Abstract instruction reader. */ 243 1.7 christos 244 1.7 christos class abstract_instruction_reader 245 1.7 christos { 246 1.7 christos public: 247 1.7 christos /* Read in one instruction. */ 248 1.7 christos virtual ULONGEST read (CORE_ADDR memaddr, int len, 249 1.7 christos enum bfd_endian byte_order) = 0; 250 1.7 christos }; 251 1.7 christos 252 1.7 christos /* Instruction reader from real target. */ 253 1.7 christos 254 1.7 christos class instruction_reader : public abstract_instruction_reader 255 1.7 christos { 256 1.7 christos public: 257 1.7 christos ULONGEST read (CORE_ADDR memaddr, int len, enum bfd_endian byte_order) 258 1.8 christos override 259 1.7 christos { 260 1.7 christos return read_code_unsigned_integer (memaddr, len, byte_order); 261 1.7 christos } 262 1.7 christos }; 263 1.7 christos 264 1.7 christos } // namespace 265 1.7 christos 266 1.9 christos /* If address signing is enabled, mask off the signature bits from the link 267 1.9 christos register, which is passed by value in ADDR, using the register values in 268 1.9 christos THIS_FRAME. */ 269 1.9 christos 270 1.9 christos static CORE_ADDR 271 1.10 christos aarch64_frame_unmask_lr (aarch64_gdbarch_tdep *tdep, 272 1.11 christos const frame_info_ptr &this_frame, CORE_ADDR addr) 273 1.9 christos { 274 1.9 christos if (tdep->has_pauth () 275 1.9 christos && frame_unwind_register_unsigned (this_frame, 276 1.10 christos tdep->ra_sign_state_regnum)) 277 1.9 christos { 278 1.11 christos /* VA range select (bit 55) tells us whether to use the low half masks 279 1.11 christos or the high half masks. */ 280 1.11 christos int cmask_num; 281 1.11 christos if (tdep->pauth_reg_count > 2 && addr & VA_RANGE_SELECT_BIT_MASK) 282 1.11 christos cmask_num = AARCH64_PAUTH_CMASK_HIGH_REGNUM (tdep->pauth_reg_base); 283 1.11 christos else 284 1.11 christos cmask_num = AARCH64_PAUTH_CMASK_REGNUM (tdep->pauth_reg_base); 285 1.11 christos 286 1.11 christos /* By default, we assume TBI and discard the top 8 bits plus the VA range 287 1.11 christos select bit (55). */ 288 1.11 christos CORE_ADDR mask = AARCH64_TOP_BITS_MASK; 289 1.11 christos mask |= frame_unwind_register_unsigned (this_frame, cmask_num); 290 1.11 christos addr = aarch64_remove_top_bits (addr, mask); 291 1.9 christos 292 1.9 christos /* Record in the frame that the link register required unmasking. */ 293 1.9 christos set_frame_previous_pc_masked (this_frame); 294 1.9 christos } 295 1.9 christos 296 1.9 christos return addr; 297 1.9 christos } 298 1.9 christos 299 1.9 christos /* Implement the "get_pc_address_flags" gdbarch method. */ 300 1.9 christos 301 1.9 christos static std::string 302 1.11 christos aarch64_get_pc_address_flags (const frame_info_ptr &frame, CORE_ADDR pc) 303 1.9 christos { 304 1.9 christos if (pc != 0 && get_frame_pc_masked (frame)) 305 1.9 christos return "PAC"; 306 1.9 christos 307 1.9 christos return ""; 308 1.9 christos } 309 1.9 christos 310 1.1 christos /* Analyze a prologue, looking for a recognizable stack frame 311 1.1 christos and frame pointer. Scan until we encounter a store that could 312 1.1 christos clobber the stack frame unexpectedly, or an unknown instruction. */ 313 1.1 christos 314 1.1 christos static CORE_ADDR 315 1.1 christos aarch64_analyze_prologue (struct gdbarch *gdbarch, 316 1.1 christos CORE_ADDR start, CORE_ADDR limit, 317 1.7 christos struct aarch64_prologue_cache *cache, 318 1.7 christos abstract_instruction_reader& reader) 319 1.1 christos { 320 1.1 christos enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); 321 1.1 christos int i; 322 1.9 christos 323 1.9 christos /* Whether the stack has been set. This should be true when we notice a SP 324 1.9 christos to FP move or if we are using the SP as the base register for storing 325 1.11 christos data, in case the FP is omitted. */ 326 1.9 christos bool seen_stack_set = false; 327 1.9 christos 328 1.7 christos /* Track X registers and D registers in prologue. */ 329 1.7 christos pv_t regs[AARCH64_X_REGISTER_COUNT + AARCH64_D_REGISTER_COUNT]; 330 1.1 christos 331 1.7 christos for (i = 0; i < AARCH64_X_REGISTER_COUNT + AARCH64_D_REGISTER_COUNT; i++) 332 1.1 christos regs[i] = pv_register (i, 0); 333 1.8 christos pv_area stack (AARCH64_SP_REGNUM, gdbarch_addr_bit (gdbarch)); 334 1.1 christos 335 1.1 christos for (; start < limit; start += 4) 336 1.1 christos { 337 1.1 christos uint32_t insn; 338 1.6 christos aarch64_inst inst; 339 1.1 christos 340 1.7 christos insn = reader.read (start, 4, byte_order_for_code); 341 1.1 christos 342 1.8 christos if (aarch64_decode_insn (insn, &inst, 1, NULL) != 0) 343 1.6 christos break; 344 1.6 christos 345 1.6 christos if (inst.opcode->iclass == addsub_imm 346 1.6 christos && (inst.opcode->op == OP_ADD 347 1.6 christos || strcmp ("sub", inst.opcode->name) == 0)) 348 1.6 christos { 349 1.6 christos unsigned rd = inst.operands[0].reg.regno; 350 1.6 christos unsigned rn = inst.operands[1].reg.regno; 351 1.6 christos 352 1.6 christos gdb_assert (aarch64_num_of_operands (inst.opcode) == 3); 353 1.6 christos gdb_assert (inst.operands[0].type == AARCH64_OPND_Rd_SP); 354 1.6 christos gdb_assert (inst.operands[1].type == AARCH64_OPND_Rn_SP); 355 1.6 christos gdb_assert (inst.operands[2].type == AARCH64_OPND_AIMM); 356 1.6 christos 357 1.6 christos if (inst.opcode->op == OP_ADD) 358 1.6 christos { 359 1.6 christos regs[rd] = pv_add_constant (regs[rn], 360 1.6 christos inst.operands[2].imm.value); 361 1.6 christos } 362 1.6 christos else 363 1.6 christos { 364 1.6 christos regs[rd] = pv_add_constant (regs[rn], 365 1.6 christos -inst.operands[2].imm.value); 366 1.6 christos } 367 1.9 christos 368 1.9 christos /* Did we move SP to FP? */ 369 1.9 christos if (rn == AARCH64_SP_REGNUM && rd == AARCH64_FP_REGNUM) 370 1.9 christos seen_stack_set = true; 371 1.6 christos } 372 1.10 christos else if (inst.opcode->iclass == addsub_ext 373 1.10 christos && strcmp ("sub", inst.opcode->name) == 0) 374 1.6 christos { 375 1.10 christos unsigned rd = inst.operands[0].reg.regno; 376 1.10 christos unsigned rn = inst.operands[1].reg.regno; 377 1.10 christos unsigned rm = inst.operands[2].reg.regno; 378 1.10 christos 379 1.10 christos gdb_assert (aarch64_num_of_operands (inst.opcode) == 3); 380 1.10 christos gdb_assert (inst.operands[0].type == AARCH64_OPND_Rd_SP); 381 1.10 christos gdb_assert (inst.operands[1].type == AARCH64_OPND_Rn_SP); 382 1.10 christos gdb_assert (inst.operands[2].type == AARCH64_OPND_Rm_EXT); 383 1.6 christos 384 1.10 christos regs[rd] = pv_subtract (regs[rn], regs[rm]); 385 1.6 christos } 386 1.6 christos else if (inst.opcode->iclass == branch_imm) 387 1.1 christos { 388 1.1 christos /* Stop analysis on branch. */ 389 1.1 christos break; 390 1.1 christos } 391 1.6 christos else if (inst.opcode->iclass == condbranch) 392 1.1 christos { 393 1.1 christos /* Stop analysis on branch. */ 394 1.1 christos break; 395 1.1 christos } 396 1.6 christos else if (inst.opcode->iclass == branch_reg) 397 1.1 christos { 398 1.1 christos /* Stop analysis on branch. */ 399 1.1 christos break; 400 1.1 christos } 401 1.6 christos else if (inst.opcode->iclass == compbranch) 402 1.1 christos { 403 1.1 christos /* Stop analysis on branch. */ 404 1.1 christos break; 405 1.1 christos } 406 1.6 christos else if (inst.opcode->op == OP_MOVZ) 407 1.1 christos { 408 1.10 christos unsigned rd = inst.operands[0].reg.regno; 409 1.10 christos 410 1.10 christos gdb_assert (aarch64_num_of_operands (inst.opcode) == 2); 411 1.6 christos gdb_assert (inst.operands[0].type == AARCH64_OPND_Rd); 412 1.10 christos gdb_assert (inst.operands[1].type == AARCH64_OPND_HALF); 413 1.10 christos gdb_assert (inst.operands[1].shifter.kind == AARCH64_MOD_LSL); 414 1.9 christos 415 1.9 christos /* If this shows up before we set the stack, keep going. Otherwise 416 1.9 christos stop the analysis. */ 417 1.9 christos if (seen_stack_set) 418 1.9 christos break; 419 1.9 christos 420 1.10 christos regs[rd] = pv_constant (inst.operands[1].imm.value 421 1.10 christos << inst.operands[1].shifter.amount); 422 1.1 christos } 423 1.6 christos else if (inst.opcode->iclass == log_shift 424 1.6 christos && strcmp (inst.opcode->name, "orr") == 0) 425 1.1 christos { 426 1.6 christos unsigned rd = inst.operands[0].reg.regno; 427 1.6 christos unsigned rn = inst.operands[1].reg.regno; 428 1.6 christos unsigned rm = inst.operands[2].reg.regno; 429 1.6 christos 430 1.6 christos gdb_assert (inst.operands[0].type == AARCH64_OPND_Rd); 431 1.6 christos gdb_assert (inst.operands[1].type == AARCH64_OPND_Rn); 432 1.6 christos gdb_assert (inst.operands[2].type == AARCH64_OPND_Rm_SFT); 433 1.6 christos 434 1.6 christos if (inst.operands[2].shifter.amount == 0 435 1.6 christos && rn == AARCH64_SP_REGNUM) 436 1.1 christos regs[rd] = regs[rm]; 437 1.1 christos else 438 1.1 christos { 439 1.10 christos aarch64_debug_printf ("prologue analysis gave up " 440 1.10 christos "addr=%s opcode=0x%x (orr x register)", 441 1.10 christos core_addr_to_string_nz (start), insn); 442 1.10 christos 443 1.1 christos break; 444 1.1 christos } 445 1.1 christos } 446 1.6 christos else if (inst.opcode->op == OP_STUR) 447 1.1 christos { 448 1.6 christos unsigned rt = inst.operands[0].reg.regno; 449 1.6 christos unsigned rn = inst.operands[1].addr.base_regno; 450 1.9 christos int size = aarch64_get_qualifier_esize (inst.operands[0].qualifier); 451 1.6 christos 452 1.6 christos gdb_assert (aarch64_num_of_operands (inst.opcode) == 2); 453 1.6 christos gdb_assert (inst.operands[0].type == AARCH64_OPND_Rt); 454 1.6 christos gdb_assert (inst.operands[1].type == AARCH64_OPND_ADDR_SIMM9); 455 1.6 christos gdb_assert (!inst.operands[1].addr.offset.is_reg); 456 1.6 christos 457 1.9 christos stack.store 458 1.9 christos (pv_add_constant (regs[rn], inst.operands[1].addr.offset.imm), 459 1.9 christos size, regs[rt]); 460 1.9 christos 461 1.9 christos /* Are we storing with SP as a base? */ 462 1.9 christos if (rn == AARCH64_SP_REGNUM) 463 1.9 christos seen_stack_set = true; 464 1.1 christos } 465 1.6 christos else if ((inst.opcode->iclass == ldstpair_off 466 1.6 christos || (inst.opcode->iclass == ldstpair_indexed 467 1.6 christos && inst.operands[2].addr.preind)) 468 1.6 christos && strcmp ("stp", inst.opcode->name) == 0) 469 1.6 christos { 470 1.6 christos /* STP with addressing mode Pre-indexed and Base register. */ 471 1.7 christos unsigned rt1; 472 1.7 christos unsigned rt2; 473 1.6 christos unsigned rn = inst.operands[2].addr.base_regno; 474 1.6 christos int32_t imm = inst.operands[2].addr.offset.imm; 475 1.9 christos int size = aarch64_get_qualifier_esize (inst.operands[0].qualifier); 476 1.6 christos 477 1.7 christos gdb_assert (inst.operands[0].type == AARCH64_OPND_Rt 478 1.7 christos || inst.operands[0].type == AARCH64_OPND_Ft); 479 1.7 christos gdb_assert (inst.operands[1].type == AARCH64_OPND_Rt2 480 1.7 christos || inst.operands[1].type == AARCH64_OPND_Ft2); 481 1.6 christos gdb_assert (inst.operands[2].type == AARCH64_OPND_ADDR_SIMM7); 482 1.6 christos gdb_assert (!inst.operands[2].addr.offset.is_reg); 483 1.6 christos 484 1.1 christos /* If recording this store would invalidate the store area 485 1.1 christos (perhaps because rn is not known) then we should abandon 486 1.1 christos further prologue analysis. */ 487 1.8 christos if (stack.store_would_trash (pv_add_constant (regs[rn], imm))) 488 1.1 christos break; 489 1.1 christos 490 1.8 christos if (stack.store_would_trash (pv_add_constant (regs[rn], imm + 8))) 491 1.1 christos break; 492 1.1 christos 493 1.7 christos rt1 = inst.operands[0].reg.regno; 494 1.7 christos rt2 = inst.operands[1].reg.regno; 495 1.7 christos if (inst.operands[0].type == AARCH64_OPND_Ft) 496 1.7 christos { 497 1.7 christos rt1 += AARCH64_X_REGISTER_COUNT; 498 1.7 christos rt2 += AARCH64_X_REGISTER_COUNT; 499 1.7 christos } 500 1.7 christos 501 1.9 christos stack.store (pv_add_constant (regs[rn], imm), size, regs[rt1]); 502 1.9 christos stack.store (pv_add_constant (regs[rn], imm + size), size, regs[rt2]); 503 1.1 christos 504 1.6 christos if (inst.operands[2].addr.writeback) 505 1.6 christos regs[rn] = pv_add_constant (regs[rn], imm); 506 1.1 christos 507 1.9 christos /* Ignore the instruction that allocates stack space and sets 508 1.9 christos the SP. */ 509 1.9 christos if (rn == AARCH64_SP_REGNUM && !inst.operands[2].addr.writeback) 510 1.9 christos seen_stack_set = true; 511 1.1 christos } 512 1.7 christos else if ((inst.opcode->iclass == ldst_imm9 /* Signed immediate. */ 513 1.7 christos || (inst.opcode->iclass == ldst_pos /* Unsigned immediate. */ 514 1.7 christos && (inst.opcode->op == OP_STR_POS 515 1.7 christos || inst.opcode->op == OP_STRF_POS))) 516 1.7 christos && inst.operands[1].addr.base_regno == AARCH64_SP_REGNUM 517 1.7 christos && strcmp ("str", inst.opcode->name) == 0) 518 1.7 christos { 519 1.7 christos /* STR (immediate) */ 520 1.7 christos unsigned int rt = inst.operands[0].reg.regno; 521 1.7 christos int32_t imm = inst.operands[1].addr.offset.imm; 522 1.7 christos unsigned int rn = inst.operands[1].addr.base_regno; 523 1.9 christos int size = aarch64_get_qualifier_esize (inst.operands[0].qualifier); 524 1.7 christos gdb_assert (inst.operands[0].type == AARCH64_OPND_Rt 525 1.7 christos || inst.operands[0].type == AARCH64_OPND_Ft); 526 1.7 christos 527 1.7 christos if (inst.operands[0].type == AARCH64_OPND_Ft) 528 1.9 christos rt += AARCH64_X_REGISTER_COUNT; 529 1.7 christos 530 1.9 christos stack.store (pv_add_constant (regs[rn], imm), size, regs[rt]); 531 1.7 christos if (inst.operands[1].addr.writeback) 532 1.7 christos regs[rn] = pv_add_constant (regs[rn], imm); 533 1.9 christos 534 1.9 christos /* Are we storing with SP as a base? */ 535 1.9 christos if (rn == AARCH64_SP_REGNUM) 536 1.9 christos seen_stack_set = true; 537 1.7 christos } 538 1.6 christos else if (inst.opcode->iclass == testbranch) 539 1.1 christos { 540 1.1 christos /* Stop analysis on branch. */ 541 1.1 christos break; 542 1.1 christos } 543 1.9 christos else if (inst.opcode->iclass == ic_system) 544 1.9 christos { 545 1.10 christos aarch64_gdbarch_tdep *tdep 546 1.10 christos = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 547 1.9 christos int ra_state_val = 0; 548 1.9 christos 549 1.9 christos if (insn == 0xd503233f /* paciasp. */ 550 1.9 christos || insn == 0xd503237f /* pacibsp. */) 551 1.9 christos { 552 1.9 christos /* Return addresses are mangled. */ 553 1.9 christos ra_state_val = 1; 554 1.9 christos } 555 1.9 christos else if (insn == 0xd50323bf /* autiasp. */ 556 1.9 christos || insn == 0xd50323ff /* autibsp. */) 557 1.9 christos { 558 1.9 christos /* Return addresses are not mangled. */ 559 1.9 christos ra_state_val = 0; 560 1.9 christos } 561 1.10 christos else if (IS_BTI (insn)) 562 1.10 christos /* We don't need to do anything special for a BTI instruction. */ 563 1.10 christos continue; 564 1.9 christos else 565 1.9 christos { 566 1.10 christos aarch64_debug_printf ("prologue analysis gave up addr=%s" 567 1.10 christos " opcode=0x%x (iclass)", 568 1.10 christos core_addr_to_string_nz (start), insn); 569 1.9 christos break; 570 1.9 christos } 571 1.9 christos 572 1.9 christos if (tdep->has_pauth () && cache != nullptr) 573 1.10 christos { 574 1.10 christos int regnum = tdep->ra_sign_state_regnum; 575 1.10 christos cache->saved_regs[regnum].set_value (ra_state_val); 576 1.10 christos } 577 1.9 christos } 578 1.1 christos else 579 1.1 christos { 580 1.10 christos aarch64_debug_printf ("prologue analysis gave up addr=%s" 581 1.10 christos " opcode=0x%x", 582 1.10 christos core_addr_to_string_nz (start), insn); 583 1.10 christos 584 1.1 christos break; 585 1.1 christos } 586 1.1 christos } 587 1.1 christos 588 1.1 christos if (cache == NULL) 589 1.8 christos return start; 590 1.1 christos 591 1.1 christos if (pv_is_register (regs[AARCH64_FP_REGNUM], AARCH64_SP_REGNUM)) 592 1.1 christos { 593 1.1 christos /* Frame pointer is fp. Frame size is constant. */ 594 1.1 christos cache->framereg = AARCH64_FP_REGNUM; 595 1.1 christos cache->framesize = -regs[AARCH64_FP_REGNUM].k; 596 1.1 christos } 597 1.1 christos else if (pv_is_register (regs[AARCH64_SP_REGNUM], AARCH64_SP_REGNUM)) 598 1.1 christos { 599 1.1 christos /* Try the stack pointer. */ 600 1.1 christos cache->framesize = -regs[AARCH64_SP_REGNUM].k; 601 1.1 christos cache->framereg = AARCH64_SP_REGNUM; 602 1.1 christos } 603 1.1 christos else 604 1.1 christos { 605 1.1 christos /* We're just out of luck. We don't know where the frame is. */ 606 1.1 christos cache->framereg = -1; 607 1.1 christos cache->framesize = 0; 608 1.1 christos } 609 1.1 christos 610 1.1 christos for (i = 0; i < AARCH64_X_REGISTER_COUNT; i++) 611 1.1 christos { 612 1.1 christos CORE_ADDR offset; 613 1.1 christos 614 1.8 christos if (stack.find_reg (gdbarch, i, &offset)) 615 1.10 christos cache->saved_regs[i].set_addr (offset); 616 1.1 christos } 617 1.1 christos 618 1.7 christos for (i = 0; i < AARCH64_D_REGISTER_COUNT; i++) 619 1.7 christos { 620 1.7 christos int regnum = gdbarch_num_regs (gdbarch); 621 1.7 christos CORE_ADDR offset; 622 1.7 christos 623 1.8 christos if (stack.find_reg (gdbarch, i + AARCH64_X_REGISTER_COUNT, 624 1.8 christos &offset)) 625 1.10 christos cache->saved_regs[i + regnum + AARCH64_D0_REGNUM].set_addr (offset); 626 1.7 christos } 627 1.7 christos 628 1.1 christos return start; 629 1.1 christos } 630 1.1 christos 631 1.7 christos static CORE_ADDR 632 1.7 christos aarch64_analyze_prologue (struct gdbarch *gdbarch, 633 1.7 christos CORE_ADDR start, CORE_ADDR limit, 634 1.7 christos struct aarch64_prologue_cache *cache) 635 1.7 christos { 636 1.7 christos instruction_reader reader; 637 1.7 christos 638 1.7 christos return aarch64_analyze_prologue (gdbarch, start, limit, cache, 639 1.7 christos reader); 640 1.7 christos } 641 1.7 christos 642 1.7 christos #if GDB_SELF_TEST 643 1.7 christos 644 1.7 christos namespace selftests { 645 1.7 christos 646 1.7 christos /* Instruction reader from manually cooked instruction sequences. */ 647 1.7 christos 648 1.7 christos class instruction_reader_test : public abstract_instruction_reader 649 1.7 christos { 650 1.7 christos public: 651 1.7 christos template<size_t SIZE> 652 1.7 christos explicit instruction_reader_test (const uint32_t (&insns)[SIZE]) 653 1.7 christos : m_insns (insns), m_insns_size (SIZE) 654 1.7 christos {} 655 1.7 christos 656 1.7 christos ULONGEST read (CORE_ADDR memaddr, int len, enum bfd_endian byte_order) 657 1.8 christos override 658 1.7 christos { 659 1.7 christos SELF_CHECK (len == 4); 660 1.7 christos SELF_CHECK (memaddr % 4 == 0); 661 1.7 christos SELF_CHECK (memaddr / 4 < m_insns_size); 662 1.7 christos 663 1.7 christos return m_insns[memaddr / 4]; 664 1.7 christos } 665 1.7 christos 666 1.7 christos private: 667 1.7 christos const uint32_t *m_insns; 668 1.7 christos size_t m_insns_size; 669 1.7 christos }; 670 1.7 christos 671 1.7 christos static void 672 1.7 christos aarch64_analyze_prologue_test (void) 673 1.7 christos { 674 1.7 christos struct gdbarch_info info; 675 1.7 christos 676 1.7 christos info.bfd_arch_info = bfd_scan_arch ("aarch64"); 677 1.7 christos 678 1.7 christos struct gdbarch *gdbarch = gdbarch_find_by_info (info); 679 1.7 christos SELF_CHECK (gdbarch != NULL); 680 1.7 christos 681 1.9 christos struct aarch64_prologue_cache cache; 682 1.9 christos cache.saved_regs = trad_frame_alloc_saved_regs (gdbarch); 683 1.9 christos 684 1.10 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 685 1.9 christos 686 1.7 christos /* Test the simple prologue in which frame pointer is used. */ 687 1.7 christos { 688 1.7 christos static const uint32_t insns[] = { 689 1.7 christos 0xa9af7bfd, /* stp x29, x30, [sp,#-272]! */ 690 1.7 christos 0x910003fd, /* mov x29, sp */ 691 1.7 christos 0x97ffffe6, /* bl 0x400580 */ 692 1.7 christos }; 693 1.7 christos instruction_reader_test reader (insns); 694 1.7 christos 695 1.7 christos CORE_ADDR end = aarch64_analyze_prologue (gdbarch, 0, 128, &cache, reader); 696 1.7 christos SELF_CHECK (end == 4 * 2); 697 1.7 christos 698 1.7 christos SELF_CHECK (cache.framereg == AARCH64_FP_REGNUM); 699 1.7 christos SELF_CHECK (cache.framesize == 272); 700 1.7 christos 701 1.7 christos for (int i = 0; i < AARCH64_X_REGISTER_COUNT; i++) 702 1.7 christos { 703 1.7 christos if (i == AARCH64_FP_REGNUM) 704 1.10 christos SELF_CHECK (cache.saved_regs[i].addr () == -272); 705 1.7 christos else if (i == AARCH64_LR_REGNUM) 706 1.10 christos SELF_CHECK (cache.saved_regs[i].addr () == -264); 707 1.7 christos else 708 1.10 christos SELF_CHECK (cache.saved_regs[i].is_realreg () 709 1.10 christos && cache.saved_regs[i].realreg () == i); 710 1.7 christos } 711 1.7 christos 712 1.7 christos for (int i = 0; i < AARCH64_D_REGISTER_COUNT; i++) 713 1.7 christos { 714 1.10 christos int num_regs = gdbarch_num_regs (gdbarch); 715 1.10 christos int regnum = i + num_regs + AARCH64_D0_REGNUM; 716 1.7 christos 717 1.10 christos SELF_CHECK (cache.saved_regs[regnum].is_realreg () 718 1.10 christos && cache.saved_regs[regnum].realreg () == regnum); 719 1.7 christos } 720 1.7 christos } 721 1.7 christos 722 1.7 christos /* Test a prologue in which STR is used and frame pointer is not 723 1.7 christos used. */ 724 1.7 christos { 725 1.7 christos static const uint32_t insns[] = { 726 1.7 christos 0xf81d0ff3, /* str x19, [sp, #-48]! */ 727 1.7 christos 0xb9002fe0, /* str w0, [sp, #44] */ 728 1.7 christos 0xf90013e1, /* str x1, [sp, #32]*/ 729 1.7 christos 0xfd000fe0, /* str d0, [sp, #24] */ 730 1.7 christos 0xaa0203f3, /* mov x19, x2 */ 731 1.7 christos 0xf94013e0, /* ldr x0, [sp, #32] */ 732 1.7 christos }; 733 1.7 christos instruction_reader_test reader (insns); 734 1.7 christos 735 1.9 christos trad_frame_reset_saved_regs (gdbarch, cache.saved_regs); 736 1.7 christos CORE_ADDR end = aarch64_analyze_prologue (gdbarch, 0, 128, &cache, reader); 737 1.7 christos 738 1.7 christos SELF_CHECK (end == 4 * 5); 739 1.7 christos 740 1.7 christos SELF_CHECK (cache.framereg == AARCH64_SP_REGNUM); 741 1.7 christos SELF_CHECK (cache.framesize == 48); 742 1.7 christos 743 1.7 christos for (int i = 0; i < AARCH64_X_REGISTER_COUNT; i++) 744 1.7 christos { 745 1.7 christos if (i == 1) 746 1.10 christos SELF_CHECK (cache.saved_regs[i].addr () == -16); 747 1.7 christos else if (i == 19) 748 1.10 christos SELF_CHECK (cache.saved_regs[i].addr () == -48); 749 1.7 christos else 750 1.10 christos SELF_CHECK (cache.saved_regs[i].is_realreg () 751 1.10 christos && cache.saved_regs[i].realreg () == i); 752 1.7 christos } 753 1.7 christos 754 1.7 christos for (int i = 0; i < AARCH64_D_REGISTER_COUNT; i++) 755 1.7 christos { 756 1.10 christos int num_regs = gdbarch_num_regs (gdbarch); 757 1.10 christos int regnum = i + num_regs + AARCH64_D0_REGNUM; 758 1.10 christos 759 1.7 christos 760 1.7 christos if (i == 0) 761 1.10 christos SELF_CHECK (cache.saved_regs[regnum].addr () == -24); 762 1.7 christos else 763 1.10 christos SELF_CHECK (cache.saved_regs[regnum].is_realreg () 764 1.10 christos && cache.saved_regs[regnum].realreg () == regnum); 765 1.7 christos } 766 1.7 christos } 767 1.9 christos 768 1.9 christos /* Test handling of movz before setting the frame pointer. */ 769 1.9 christos { 770 1.9 christos static const uint32_t insns[] = { 771 1.9 christos 0xa9bf7bfd, /* stp x29, x30, [sp, #-16]! */ 772 1.9 christos 0x52800020, /* mov w0, #0x1 */ 773 1.9 christos 0x910003fd, /* mov x29, sp */ 774 1.9 christos 0x528000a2, /* mov w2, #0x5 */ 775 1.9 christos 0x97fffff8, /* bl 6e4 */ 776 1.9 christos }; 777 1.9 christos 778 1.9 christos instruction_reader_test reader (insns); 779 1.9 christos 780 1.9 christos trad_frame_reset_saved_regs (gdbarch, cache.saved_regs); 781 1.9 christos CORE_ADDR end = aarch64_analyze_prologue (gdbarch, 0, 128, &cache, reader); 782 1.9 christos 783 1.9 christos /* We should stop at the 4th instruction. */ 784 1.9 christos SELF_CHECK (end == (4 - 1) * 4); 785 1.9 christos SELF_CHECK (cache.framereg == AARCH64_FP_REGNUM); 786 1.9 christos SELF_CHECK (cache.framesize == 16); 787 1.9 christos } 788 1.9 christos 789 1.9 christos /* Test handling of movz/stp when using the stack pointer as frame 790 1.9 christos pointer. */ 791 1.9 christos { 792 1.9 christos static const uint32_t insns[] = { 793 1.9 christos 0xa9bc7bfd, /* stp x29, x30, [sp, #-64]! */ 794 1.9 christos 0x52800020, /* mov w0, #0x1 */ 795 1.9 christos 0x290207e0, /* stp w0, w1, [sp, #16] */ 796 1.9 christos 0xa9018fe2, /* stp x2, x3, [sp, #24] */ 797 1.9 christos 0x528000a2, /* mov w2, #0x5 */ 798 1.9 christos 0x97fffff8, /* bl 6e4 */ 799 1.9 christos }; 800 1.9 christos 801 1.9 christos instruction_reader_test reader (insns); 802 1.9 christos 803 1.9 christos trad_frame_reset_saved_regs (gdbarch, cache.saved_regs); 804 1.9 christos CORE_ADDR end = aarch64_analyze_prologue (gdbarch, 0, 128, &cache, reader); 805 1.9 christos 806 1.9 christos /* We should stop at the 5th instruction. */ 807 1.9 christos SELF_CHECK (end == (5 - 1) * 4); 808 1.9 christos SELF_CHECK (cache.framereg == AARCH64_SP_REGNUM); 809 1.9 christos SELF_CHECK (cache.framesize == 64); 810 1.9 christos } 811 1.9 christos 812 1.9 christos /* Test handling of movz/str when using the stack pointer as frame 813 1.9 christos pointer */ 814 1.9 christos { 815 1.9 christos static const uint32_t insns[] = { 816 1.9 christos 0xa9bc7bfd, /* stp x29, x30, [sp, #-64]! */ 817 1.9 christos 0x52800020, /* mov w0, #0x1 */ 818 1.9 christos 0xb9002be4, /* str w4, [sp, #40] */ 819 1.9 christos 0xf9001be5, /* str x5, [sp, #48] */ 820 1.9 christos 0x528000a2, /* mov w2, #0x5 */ 821 1.9 christos 0x97fffff8, /* bl 6e4 */ 822 1.9 christos }; 823 1.9 christos 824 1.9 christos instruction_reader_test reader (insns); 825 1.9 christos 826 1.9 christos trad_frame_reset_saved_regs (gdbarch, cache.saved_regs); 827 1.9 christos CORE_ADDR end = aarch64_analyze_prologue (gdbarch, 0, 128, &cache, reader); 828 1.9 christos 829 1.9 christos /* We should stop at the 5th instruction. */ 830 1.9 christos SELF_CHECK (end == (5 - 1) * 4); 831 1.9 christos SELF_CHECK (cache.framereg == AARCH64_SP_REGNUM); 832 1.9 christos SELF_CHECK (cache.framesize == 64); 833 1.9 christos } 834 1.9 christos 835 1.9 christos /* Test handling of movz/stur when using the stack pointer as frame 836 1.9 christos pointer. */ 837 1.9 christos { 838 1.9 christos static const uint32_t insns[] = { 839 1.9 christos 0xa9bc7bfd, /* stp x29, x30, [sp, #-64]! */ 840 1.9 christos 0x52800020, /* mov w0, #0x1 */ 841 1.9 christos 0xb80343e6, /* stur w6, [sp, #52] */ 842 1.9 christos 0xf80383e7, /* stur x7, [sp, #56] */ 843 1.9 christos 0x528000a2, /* mov w2, #0x5 */ 844 1.9 christos 0x97fffff8, /* bl 6e4 */ 845 1.9 christos }; 846 1.9 christos 847 1.9 christos instruction_reader_test reader (insns); 848 1.9 christos 849 1.9 christos trad_frame_reset_saved_regs (gdbarch, cache.saved_regs); 850 1.9 christos CORE_ADDR end = aarch64_analyze_prologue (gdbarch, 0, 128, &cache, reader); 851 1.9 christos 852 1.9 christos /* We should stop at the 5th instruction. */ 853 1.9 christos SELF_CHECK (end == (5 - 1) * 4); 854 1.9 christos SELF_CHECK (cache.framereg == AARCH64_SP_REGNUM); 855 1.9 christos SELF_CHECK (cache.framesize == 64); 856 1.9 christos } 857 1.9 christos 858 1.9 christos /* Test handling of movz when there is no frame pointer set or no stack 859 1.9 christos pointer used. */ 860 1.9 christos { 861 1.9 christos static const uint32_t insns[] = { 862 1.9 christos 0xa9bf7bfd, /* stp x29, x30, [sp, #-16]! */ 863 1.9 christos 0x52800020, /* mov w0, #0x1 */ 864 1.9 christos 0x528000a2, /* mov w2, #0x5 */ 865 1.9 christos 0x97fffff8, /* bl 6e4 */ 866 1.9 christos }; 867 1.9 christos 868 1.9 christos instruction_reader_test reader (insns); 869 1.9 christos 870 1.9 christos trad_frame_reset_saved_regs (gdbarch, cache.saved_regs); 871 1.9 christos CORE_ADDR end = aarch64_analyze_prologue (gdbarch, 0, 128, &cache, reader); 872 1.9 christos 873 1.9 christos /* We should stop at the 4th instruction. */ 874 1.9 christos SELF_CHECK (end == (4 - 1) * 4); 875 1.9 christos SELF_CHECK (cache.framereg == AARCH64_SP_REGNUM); 876 1.9 christos SELF_CHECK (cache.framesize == 16); 877 1.9 christos } 878 1.9 christos 879 1.9 christos /* Test a prologue in which there is a return address signing instruction. */ 880 1.9 christos if (tdep->has_pauth ()) 881 1.9 christos { 882 1.9 christos static const uint32_t insns[] = { 883 1.9 christos 0xd503233f, /* paciasp */ 884 1.9 christos 0xa9bd7bfd, /* stp x29, x30, [sp, #-48]! */ 885 1.9 christos 0x910003fd, /* mov x29, sp */ 886 1.9 christos 0xf801c3f3, /* str x19, [sp, #28] */ 887 1.9 christos 0xb9401fa0, /* ldr x19, [x29, #28] */ 888 1.9 christos }; 889 1.9 christos instruction_reader_test reader (insns); 890 1.9 christos 891 1.9 christos trad_frame_reset_saved_regs (gdbarch, cache.saved_regs); 892 1.9 christos CORE_ADDR end = aarch64_analyze_prologue (gdbarch, 0, 128, &cache, 893 1.9 christos reader); 894 1.9 christos 895 1.9 christos SELF_CHECK (end == 4 * 4); 896 1.9 christos SELF_CHECK (cache.framereg == AARCH64_FP_REGNUM); 897 1.9 christos SELF_CHECK (cache.framesize == 48); 898 1.9 christos 899 1.9 christos for (int i = 0; i < AARCH64_X_REGISTER_COUNT; i++) 900 1.9 christos { 901 1.9 christos if (i == 19) 902 1.10 christos SELF_CHECK (cache.saved_regs[i].addr () == -20); 903 1.9 christos else if (i == AARCH64_FP_REGNUM) 904 1.10 christos SELF_CHECK (cache.saved_regs[i].addr () == -48); 905 1.9 christos else if (i == AARCH64_LR_REGNUM) 906 1.10 christos SELF_CHECK (cache.saved_regs[i].addr () == -40); 907 1.9 christos else 908 1.10 christos SELF_CHECK (cache.saved_regs[i].is_realreg () 909 1.10 christos && cache.saved_regs[i].realreg () == i); 910 1.9 christos } 911 1.9 christos 912 1.9 christos if (tdep->has_pauth ()) 913 1.9 christos { 914 1.10 christos int regnum = tdep->ra_sign_state_regnum; 915 1.10 christos SELF_CHECK (cache.saved_regs[regnum].is_value ()); 916 1.10 christos } 917 1.10 christos } 918 1.10 christos 919 1.10 christos /* Test a prologue with a BTI instruction. */ 920 1.10 christos { 921 1.10 christos static const uint32_t insns[] = { 922 1.10 christos 0xd503245f, /* bti */ 923 1.10 christos 0xa9bd7bfd, /* stp x29, x30, [sp, #-48]! */ 924 1.10 christos 0x910003fd, /* mov x29, sp */ 925 1.10 christos 0xf801c3f3, /* str x19, [sp, #28] */ 926 1.10 christos 0xb9401fa0, /* ldr x19, [x29, #28] */ 927 1.10 christos }; 928 1.10 christos instruction_reader_test reader (insns); 929 1.10 christos 930 1.10 christos trad_frame_reset_saved_regs (gdbarch, cache.saved_regs); 931 1.10 christos CORE_ADDR end = aarch64_analyze_prologue (gdbarch, 0, 128, &cache, 932 1.10 christos reader); 933 1.10 christos 934 1.10 christos SELF_CHECK (end == 4 * 4); 935 1.10 christos SELF_CHECK (cache.framereg == AARCH64_FP_REGNUM); 936 1.10 christos SELF_CHECK (cache.framesize == 48); 937 1.10 christos 938 1.10 christos for (int i = 0; i < AARCH64_X_REGISTER_COUNT; i++) 939 1.10 christos { 940 1.10 christos if (i == 19) 941 1.10 christos SELF_CHECK (cache.saved_regs[i].addr () == -20); 942 1.10 christos else if (i == AARCH64_FP_REGNUM) 943 1.10 christos SELF_CHECK (cache.saved_regs[i].addr () == -48); 944 1.10 christos else if (i == AARCH64_LR_REGNUM) 945 1.10 christos SELF_CHECK (cache.saved_regs[i].addr () == -40); 946 1.10 christos else 947 1.10 christos SELF_CHECK (cache.saved_regs[i].is_realreg () 948 1.10 christos && cache.saved_regs[i].realreg () == i); 949 1.9 christos } 950 1.9 christos } 951 1.7 christos } 952 1.7 christos } // namespace selftests 953 1.7 christos #endif /* GDB_SELF_TEST */ 954 1.7 christos 955 1.1 christos /* Implement the "skip_prologue" gdbarch method. */ 956 1.1 christos 957 1.1 christos static CORE_ADDR 958 1.1 christos aarch64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) 959 1.1 christos { 960 1.11 christos CORE_ADDR func_addr, func_end_addr, limit_pc; 961 1.1 christos 962 1.1 christos /* See if we can determine the end of the prologue via the symbol 963 1.1 christos table. If so, then return either PC, or the PC after the 964 1.1 christos prologue, whichever is greater. */ 965 1.11 christos bool func_addr_found 966 1.11 christos = find_pc_partial_function (pc, NULL, &func_addr, &func_end_addr); 967 1.11 christos 968 1.11 christos if (func_addr_found) 969 1.1 christos { 970 1.1 christos CORE_ADDR post_prologue_pc 971 1.1 christos = skip_prologue_using_sal (gdbarch, func_addr); 972 1.1 christos 973 1.1 christos if (post_prologue_pc != 0) 974 1.7 christos return std::max (pc, post_prologue_pc); 975 1.1 christos } 976 1.1 christos 977 1.1 christos /* Can't determine prologue from the symbol table, need to examine 978 1.1 christos instructions. */ 979 1.1 christos 980 1.1 christos /* Find an upper limit on the function prologue using the debug 981 1.1 christos information. If the debug information could not be used to 982 1.1 christos provide that bound, then use an arbitrary large number as the 983 1.1 christos upper bound. */ 984 1.1 christos limit_pc = skip_prologue_using_sal (gdbarch, pc); 985 1.1 christos if (limit_pc == 0) 986 1.1 christos limit_pc = pc + 128; /* Magic. */ 987 1.1 christos 988 1.11 christos limit_pc 989 1.11 christos = func_end_addr == 0 ? limit_pc : std::min (limit_pc, func_end_addr - 4); 990 1.11 christos 991 1.1 christos /* Try disassembling prologue. */ 992 1.1 christos return aarch64_analyze_prologue (gdbarch, pc, limit_pc, NULL); 993 1.1 christos } 994 1.1 christos 995 1.1 christos /* Scan the function prologue for THIS_FRAME and populate the prologue 996 1.1 christos cache CACHE. */ 997 1.1 christos 998 1.1 christos static void 999 1.11 christos aarch64_scan_prologue (const frame_info_ptr &this_frame, 1000 1.1 christos struct aarch64_prologue_cache *cache) 1001 1.1 christos { 1002 1.1 christos CORE_ADDR block_addr = get_frame_address_in_block (this_frame); 1003 1.1 christos CORE_ADDR prologue_start; 1004 1.1 christos CORE_ADDR prologue_end; 1005 1.1 christos CORE_ADDR prev_pc = get_frame_pc (this_frame); 1006 1.1 christos struct gdbarch *gdbarch = get_frame_arch (this_frame); 1007 1.1 christos 1008 1.6 christos cache->prev_pc = prev_pc; 1009 1.6 christos 1010 1.1 christos /* Assume we do not find a frame. */ 1011 1.1 christos cache->framereg = -1; 1012 1.1 christos cache->framesize = 0; 1013 1.1 christos 1014 1.1 christos if (find_pc_partial_function (block_addr, NULL, &prologue_start, 1015 1.1 christos &prologue_end)) 1016 1.1 christos { 1017 1.1 christos struct symtab_and_line sal = find_pc_line (prologue_start, 0); 1018 1.1 christos 1019 1.1 christos if (sal.line == 0) 1020 1.1 christos { 1021 1.1 christos /* No line info so use the current PC. */ 1022 1.1 christos prologue_end = prev_pc; 1023 1.1 christos } 1024 1.1 christos else if (sal.end < prologue_end) 1025 1.1 christos { 1026 1.1 christos /* The next line begins after the function end. */ 1027 1.1 christos prologue_end = sal.end; 1028 1.1 christos } 1029 1.1 christos 1030 1.7 christos prologue_end = std::min (prologue_end, prev_pc); 1031 1.1 christos aarch64_analyze_prologue (gdbarch, prologue_start, prologue_end, cache); 1032 1.1 christos } 1033 1.1 christos else 1034 1.1 christos { 1035 1.1 christos CORE_ADDR frame_loc; 1036 1.1 christos 1037 1.1 christos frame_loc = get_frame_register_unsigned (this_frame, AARCH64_FP_REGNUM); 1038 1.1 christos if (frame_loc == 0) 1039 1.1 christos return; 1040 1.1 christos 1041 1.1 christos cache->framereg = AARCH64_FP_REGNUM; 1042 1.1 christos cache->framesize = 16; 1043 1.10 christos cache->saved_regs[29].set_addr (0); 1044 1.10 christos cache->saved_regs[30].set_addr (8); 1045 1.1 christos } 1046 1.1 christos } 1047 1.1 christos 1048 1.6 christos /* Fill in *CACHE with information about the prologue of *THIS_FRAME. This 1049 1.6 christos function may throw an exception if the inferior's registers or memory is 1050 1.6 christos not available. */ 1051 1.1 christos 1052 1.6 christos static void 1053 1.11 christos aarch64_make_prologue_cache_1 (const frame_info_ptr &this_frame, 1054 1.6 christos struct aarch64_prologue_cache *cache) 1055 1.1 christos { 1056 1.1 christos CORE_ADDR unwound_fp; 1057 1.1 christos int reg; 1058 1.1 christos 1059 1.1 christos aarch64_scan_prologue (this_frame, cache); 1060 1.1 christos 1061 1.1 christos if (cache->framereg == -1) 1062 1.6 christos return; 1063 1.1 christos 1064 1.1 christos unwound_fp = get_frame_register_unsigned (this_frame, cache->framereg); 1065 1.1 christos if (unwound_fp == 0) 1066 1.6 christos return; 1067 1.1 christos 1068 1.11 christos cache->prev_sp = unwound_fp; 1069 1.11 christos if (!aarch64_stack_frame_destroyed_p (get_frame_arch (this_frame), 1070 1.11 christos cache->prev_pc)) 1071 1.11 christos cache->prev_sp += cache->framesize; 1072 1.1 christos 1073 1.1 christos /* Calculate actual addresses of saved registers using offsets 1074 1.1 christos determined by aarch64_analyze_prologue. */ 1075 1.1 christos for (reg = 0; reg < gdbarch_num_regs (get_frame_arch (this_frame)); reg++) 1076 1.10 christos if (cache->saved_regs[reg].is_addr ()) 1077 1.10 christos cache->saved_regs[reg].set_addr (cache->saved_regs[reg].addr () 1078 1.10 christos + cache->prev_sp); 1079 1.1 christos 1080 1.6 christos cache->func = get_frame_func (this_frame); 1081 1.6 christos 1082 1.6 christos cache->available_p = 1; 1083 1.6 christos } 1084 1.6 christos 1085 1.6 christos /* Allocate and fill in *THIS_CACHE with information about the prologue of 1086 1.6 christos *THIS_FRAME. Do not do this is if *THIS_CACHE was already allocated. 1087 1.6 christos Return a pointer to the current aarch64_prologue_cache in 1088 1.6 christos *THIS_CACHE. */ 1089 1.6 christos 1090 1.6 christos static struct aarch64_prologue_cache * 1091 1.11 christos aarch64_make_prologue_cache (const frame_info_ptr &this_frame, void **this_cache) 1092 1.6 christos { 1093 1.6 christos struct aarch64_prologue_cache *cache; 1094 1.6 christos 1095 1.6 christos if (*this_cache != NULL) 1096 1.6 christos return (struct aarch64_prologue_cache *) *this_cache; 1097 1.6 christos 1098 1.6 christos cache = FRAME_OBSTACK_ZALLOC (struct aarch64_prologue_cache); 1099 1.6 christos cache->saved_regs = trad_frame_alloc_saved_regs (this_frame); 1100 1.6 christos *this_cache = cache; 1101 1.6 christos 1102 1.9 christos try 1103 1.6 christos { 1104 1.6 christos aarch64_make_prologue_cache_1 (this_frame, cache); 1105 1.6 christos } 1106 1.9 christos catch (const gdb_exception_error &ex) 1107 1.6 christos { 1108 1.6 christos if (ex.error != NOT_AVAILABLE_ERROR) 1109 1.9 christos throw; 1110 1.6 christos } 1111 1.6 christos 1112 1.1 christos return cache; 1113 1.1 christos } 1114 1.1 christos 1115 1.6 christos /* Implement the "stop_reason" frame_unwind method. */ 1116 1.6 christos 1117 1.6 christos static enum unwind_stop_reason 1118 1.11 christos aarch64_prologue_frame_unwind_stop_reason (const frame_info_ptr &this_frame, 1119 1.6 christos void **this_cache) 1120 1.6 christos { 1121 1.6 christos struct aarch64_prologue_cache *cache 1122 1.6 christos = aarch64_make_prologue_cache (this_frame, this_cache); 1123 1.6 christos 1124 1.6 christos if (!cache->available_p) 1125 1.6 christos return UNWIND_UNAVAILABLE; 1126 1.6 christos 1127 1.6 christos /* Halt the backtrace at "_start". */ 1128 1.10 christos gdbarch *arch = get_frame_arch (this_frame); 1129 1.10 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (arch); 1130 1.10 christos if (cache->prev_pc <= tdep->lowest_pc) 1131 1.6 christos return UNWIND_OUTERMOST; 1132 1.6 christos 1133 1.6 christos /* We've hit a wall, stop. */ 1134 1.6 christos if (cache->prev_sp == 0) 1135 1.6 christos return UNWIND_OUTERMOST; 1136 1.6 christos 1137 1.6 christos return UNWIND_NO_REASON; 1138 1.6 christos } 1139 1.6 christos 1140 1.1 christos /* Our frame ID for a normal frame is the current function's starting 1141 1.1 christos PC and the caller's SP when we were called. */ 1142 1.1 christos 1143 1.1 christos static void 1144 1.11 christos aarch64_prologue_this_id (const frame_info_ptr &this_frame, 1145 1.1 christos void **this_cache, struct frame_id *this_id) 1146 1.1 christos { 1147 1.6 christos struct aarch64_prologue_cache *cache 1148 1.6 christos = aarch64_make_prologue_cache (this_frame, this_cache); 1149 1.1 christos 1150 1.6 christos if (!cache->available_p) 1151 1.6 christos *this_id = frame_id_build_unavailable_stack (cache->func); 1152 1.6 christos else 1153 1.6 christos *this_id = frame_id_build (cache->prev_sp, cache->func); 1154 1.1 christos } 1155 1.1 christos 1156 1.1 christos /* Implement the "prev_register" frame_unwind method. */ 1157 1.1 christos 1158 1.1 christos static struct value * 1159 1.11 christos aarch64_prologue_prev_register (const frame_info_ptr &this_frame, 1160 1.1 christos void **this_cache, int prev_regnum) 1161 1.1 christos { 1162 1.6 christos struct aarch64_prologue_cache *cache 1163 1.6 christos = aarch64_make_prologue_cache (this_frame, this_cache); 1164 1.1 christos 1165 1.1 christos /* If we are asked to unwind the PC, then we need to return the LR 1166 1.1 christos instead. The prologue may save PC, but it will point into this 1167 1.1 christos frame's prologue, not the next frame's resume location. */ 1168 1.1 christos if (prev_regnum == AARCH64_PC_REGNUM) 1169 1.1 christos { 1170 1.1 christos CORE_ADDR lr; 1171 1.9 christos struct gdbarch *gdbarch = get_frame_arch (this_frame); 1172 1.10 christos aarch64_gdbarch_tdep *tdep 1173 1.10 christos = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 1174 1.1 christos 1175 1.1 christos lr = frame_unwind_register_unsigned (this_frame, AARCH64_LR_REGNUM); 1176 1.9 christos 1177 1.9 christos if (tdep->has_pauth () 1178 1.10 christos && cache->saved_regs[tdep->ra_sign_state_regnum].is_value ()) 1179 1.9 christos lr = aarch64_frame_unmask_lr (tdep, this_frame, lr); 1180 1.9 christos 1181 1.1 christos return frame_unwind_got_constant (this_frame, prev_regnum, lr); 1182 1.1 christos } 1183 1.1 christos 1184 1.1 christos /* SP is generally not saved to the stack, but this frame is 1185 1.1 christos identified by the next frame's stack pointer at the time of the 1186 1.1 christos call. The value was already reconstructed into PREV_SP. */ 1187 1.1 christos /* 1188 1.10 christos +----------+ ^ 1189 1.10 christos | saved lr | | 1190 1.1 christos +->| saved fp |--+ 1191 1.1 christos | | | 1192 1.1 christos | | | <- Previous SP 1193 1.1 christos | +----------+ 1194 1.1 christos | | saved lr | 1195 1.1 christos +--| saved fp |<- FP 1196 1.10 christos | | 1197 1.10 christos | |<- SP 1198 1.10 christos +----------+ */ 1199 1.1 christos if (prev_regnum == AARCH64_SP_REGNUM) 1200 1.1 christos return frame_unwind_got_constant (this_frame, prev_regnum, 1201 1.1 christos cache->prev_sp); 1202 1.1 christos 1203 1.1 christos return trad_frame_get_prev_register (this_frame, cache->saved_regs, 1204 1.1 christos prev_regnum); 1205 1.1 christos } 1206 1.1 christos 1207 1.1 christos /* AArch64 prologue unwinder. */ 1208 1.10 christos static frame_unwind aarch64_prologue_unwind = 1209 1.1 christos { 1210 1.10 christos "aarch64 prologue", 1211 1.1 christos NORMAL_FRAME, 1212 1.6 christos aarch64_prologue_frame_unwind_stop_reason, 1213 1.1 christos aarch64_prologue_this_id, 1214 1.1 christos aarch64_prologue_prev_register, 1215 1.1 christos NULL, 1216 1.1 christos default_frame_sniffer 1217 1.1 christos }; 1218 1.1 christos 1219 1.6 christos /* Allocate and fill in *THIS_CACHE with information about the prologue of 1220 1.6 christos *THIS_FRAME. Do not do this is if *THIS_CACHE was already allocated. 1221 1.6 christos Return a pointer to the current aarch64_prologue_cache in 1222 1.6 christos *THIS_CACHE. */ 1223 1.1 christos 1224 1.1 christos static struct aarch64_prologue_cache * 1225 1.11 christos aarch64_make_stub_cache (const frame_info_ptr &this_frame, void **this_cache) 1226 1.1 christos { 1227 1.1 christos struct aarch64_prologue_cache *cache; 1228 1.6 christos 1229 1.6 christos if (*this_cache != NULL) 1230 1.6 christos return (struct aarch64_prologue_cache *) *this_cache; 1231 1.1 christos 1232 1.1 christos cache = FRAME_OBSTACK_ZALLOC (struct aarch64_prologue_cache); 1233 1.1 christos cache->saved_regs = trad_frame_alloc_saved_regs (this_frame); 1234 1.6 christos *this_cache = cache; 1235 1.1 christos 1236 1.9 christos try 1237 1.6 christos { 1238 1.6 christos cache->prev_sp = get_frame_register_unsigned (this_frame, 1239 1.6 christos AARCH64_SP_REGNUM); 1240 1.6 christos cache->prev_pc = get_frame_pc (this_frame); 1241 1.6 christos cache->available_p = 1; 1242 1.6 christos } 1243 1.9 christos catch (const gdb_exception_error &ex) 1244 1.6 christos { 1245 1.6 christos if (ex.error != NOT_AVAILABLE_ERROR) 1246 1.9 christos throw; 1247 1.6 christos } 1248 1.1 christos 1249 1.1 christos return cache; 1250 1.1 christos } 1251 1.1 christos 1252 1.6 christos /* Implement the "stop_reason" frame_unwind method. */ 1253 1.6 christos 1254 1.6 christos static enum unwind_stop_reason 1255 1.11 christos aarch64_stub_frame_unwind_stop_reason (const frame_info_ptr &this_frame, 1256 1.6 christos void **this_cache) 1257 1.6 christos { 1258 1.6 christos struct aarch64_prologue_cache *cache 1259 1.6 christos = aarch64_make_stub_cache (this_frame, this_cache); 1260 1.6 christos 1261 1.6 christos if (!cache->available_p) 1262 1.6 christos return UNWIND_UNAVAILABLE; 1263 1.6 christos 1264 1.6 christos return UNWIND_NO_REASON; 1265 1.6 christos } 1266 1.6 christos 1267 1.1 christos /* Our frame ID for a stub frame is the current SP and LR. */ 1268 1.1 christos 1269 1.1 christos static void 1270 1.11 christos aarch64_stub_this_id (const frame_info_ptr &this_frame, 1271 1.1 christos void **this_cache, struct frame_id *this_id) 1272 1.1 christos { 1273 1.6 christos struct aarch64_prologue_cache *cache 1274 1.6 christos = aarch64_make_stub_cache (this_frame, this_cache); 1275 1.1 christos 1276 1.6 christos if (cache->available_p) 1277 1.6 christos *this_id = frame_id_build (cache->prev_sp, cache->prev_pc); 1278 1.6 christos else 1279 1.6 christos *this_id = frame_id_build_unavailable_stack (cache->prev_pc); 1280 1.1 christos } 1281 1.1 christos 1282 1.1 christos /* Implement the "sniffer" frame_unwind method. */ 1283 1.1 christos 1284 1.1 christos static int 1285 1.1 christos aarch64_stub_unwind_sniffer (const struct frame_unwind *self, 1286 1.11 christos const frame_info_ptr &this_frame, 1287 1.1 christos void **this_prologue_cache) 1288 1.1 christos { 1289 1.1 christos CORE_ADDR addr_in_block; 1290 1.1 christos gdb_byte dummy[4]; 1291 1.1 christos 1292 1.1 christos addr_in_block = get_frame_address_in_block (this_frame); 1293 1.1 christos if (in_plt_section (addr_in_block) 1294 1.1 christos /* We also use the stub winder if the target memory is unreadable 1295 1.1 christos to avoid having the prologue unwinder trying to read it. */ 1296 1.1 christos || target_read_memory (get_frame_pc (this_frame), dummy, 4) != 0) 1297 1.1 christos return 1; 1298 1.1 christos 1299 1.1 christos return 0; 1300 1.1 christos } 1301 1.1 christos 1302 1.1 christos /* AArch64 stub unwinder. */ 1303 1.10 christos static frame_unwind aarch64_stub_unwind = 1304 1.1 christos { 1305 1.10 christos "aarch64 stub", 1306 1.1 christos NORMAL_FRAME, 1307 1.6 christos aarch64_stub_frame_unwind_stop_reason, 1308 1.1 christos aarch64_stub_this_id, 1309 1.1 christos aarch64_prologue_prev_register, 1310 1.1 christos NULL, 1311 1.1 christos aarch64_stub_unwind_sniffer 1312 1.1 christos }; 1313 1.1 christos 1314 1.1 christos /* Return the frame base address of *THIS_FRAME. */ 1315 1.1 christos 1316 1.1 christos static CORE_ADDR 1317 1.11 christos aarch64_normal_frame_base (const frame_info_ptr &this_frame, void **this_cache) 1318 1.1 christos { 1319 1.6 christos struct aarch64_prologue_cache *cache 1320 1.6 christos = aarch64_make_prologue_cache (this_frame, this_cache); 1321 1.1 christos 1322 1.1 christos return cache->prev_sp - cache->framesize; 1323 1.1 christos } 1324 1.1 christos 1325 1.1 christos /* AArch64 default frame base information. */ 1326 1.10 christos static frame_base aarch64_normal_base = 1327 1.1 christos { 1328 1.1 christos &aarch64_prologue_unwind, 1329 1.1 christos aarch64_normal_frame_base, 1330 1.1 christos aarch64_normal_frame_base, 1331 1.1 christos aarch64_normal_frame_base 1332 1.1 christos }; 1333 1.1 christos 1334 1.1 christos /* Return the value of the REGNUM register in the previous frame of 1335 1.1 christos *THIS_FRAME. */ 1336 1.1 christos 1337 1.1 christos static struct value * 1338 1.11 christos aarch64_dwarf2_prev_register (const frame_info_ptr &this_frame, 1339 1.1 christos void **this_cache, int regnum) 1340 1.1 christos { 1341 1.10 christos gdbarch *arch = get_frame_arch (this_frame); 1342 1.10 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (arch); 1343 1.1 christos CORE_ADDR lr; 1344 1.1 christos 1345 1.1 christos switch (regnum) 1346 1.1 christos { 1347 1.1 christos case AARCH64_PC_REGNUM: 1348 1.1 christos lr = frame_unwind_register_unsigned (this_frame, AARCH64_LR_REGNUM); 1349 1.9 christos lr = aarch64_frame_unmask_lr (tdep, this_frame, lr); 1350 1.1 christos return frame_unwind_got_constant (this_frame, regnum, lr); 1351 1.1 christos 1352 1.1 christos default: 1353 1.10 christos internal_error (_("Unexpected register %d"), regnum); 1354 1.1 christos } 1355 1.1 christos } 1356 1.1 christos 1357 1.9 christos static const unsigned char op_lit0 = DW_OP_lit0; 1358 1.9 christos static const unsigned char op_lit1 = DW_OP_lit1; 1359 1.9 christos 1360 1.1 christos /* Implement the "init_reg" dwarf2_frame_ops method. */ 1361 1.1 christos 1362 1.1 christos static void 1363 1.1 christos aarch64_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum, 1364 1.1 christos struct dwarf2_frame_state_reg *reg, 1365 1.11 christos const frame_info_ptr &this_frame) 1366 1.1 christos { 1367 1.10 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 1368 1.9 christos 1369 1.1 christos switch (regnum) 1370 1.1 christos { 1371 1.1 christos case AARCH64_PC_REGNUM: 1372 1.1 christos reg->how = DWARF2_FRAME_REG_FN; 1373 1.1 christos reg->loc.fn = aarch64_dwarf2_prev_register; 1374 1.9 christos return; 1375 1.9 christos 1376 1.1 christos case AARCH64_SP_REGNUM: 1377 1.1 christos reg->how = DWARF2_FRAME_REG_CFA; 1378 1.9 christos return; 1379 1.9 christos } 1380 1.9 christos 1381 1.9 christos /* Init pauth registers. */ 1382 1.9 christos if (tdep->has_pauth ()) 1383 1.9 christos { 1384 1.10 christos if (regnum == tdep->ra_sign_state_regnum) 1385 1.9 christos { 1386 1.9 christos /* Initialize RA_STATE to zero. */ 1387 1.9 christos reg->how = DWARF2_FRAME_REG_SAVED_VAL_EXP; 1388 1.9 christos reg->loc.exp.start = &op_lit0; 1389 1.9 christos reg->loc.exp.len = 1; 1390 1.9 christos return; 1391 1.9 christos } 1392 1.11 christos else if (regnum >= tdep->pauth_reg_base 1393 1.11 christos && regnum < tdep->pauth_reg_base + tdep->pauth_reg_count) 1394 1.9 christos { 1395 1.9 christos reg->how = DWARF2_FRAME_REG_SAME_VALUE; 1396 1.9 christos return; 1397 1.9 christos } 1398 1.9 christos } 1399 1.9 christos } 1400 1.9 christos 1401 1.9 christos /* Implement the execute_dwarf_cfa_vendor_op method. */ 1402 1.9 christos 1403 1.9 christos static bool 1404 1.9 christos aarch64_execute_dwarf_cfa_vendor_op (struct gdbarch *gdbarch, gdb_byte op, 1405 1.9 christos struct dwarf2_frame_state *fs) 1406 1.9 christos { 1407 1.10 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 1408 1.9 christos struct dwarf2_frame_state_reg *ra_state; 1409 1.9 christos 1410 1.9 christos if (op == DW_CFA_AARCH64_negate_ra_state) 1411 1.9 christos { 1412 1.9 christos /* On systems without pauth, treat as a nop. */ 1413 1.9 christos if (!tdep->has_pauth ()) 1414 1.9 christos return true; 1415 1.9 christos 1416 1.9 christos /* Allocate RA_STATE column if it's not allocated yet. */ 1417 1.10 christos fs->regs.alloc_regs (AARCH64_DWARF_RA_SIGN_STATE + 1); 1418 1.9 christos 1419 1.9 christos /* Toggle the status of RA_STATE between 0 and 1. */ 1420 1.10 christos ra_state = &(fs->regs.reg[AARCH64_DWARF_RA_SIGN_STATE]); 1421 1.9 christos ra_state->how = DWARF2_FRAME_REG_SAVED_VAL_EXP; 1422 1.9 christos 1423 1.9 christos if (ra_state->loc.exp.start == nullptr 1424 1.9 christos || ra_state->loc.exp.start == &op_lit0) 1425 1.9 christos ra_state->loc.exp.start = &op_lit1; 1426 1.9 christos else 1427 1.9 christos ra_state->loc.exp.start = &op_lit0; 1428 1.9 christos 1429 1.9 christos ra_state->loc.exp.len = 1; 1430 1.9 christos 1431 1.9 christos return true; 1432 1.9 christos } 1433 1.9 christos 1434 1.9 christos return false; 1435 1.9 christos } 1436 1.9 christos 1437 1.9 christos /* Used for matching BRK instructions for AArch64. */ 1438 1.9 christos static constexpr uint32_t BRK_INSN_MASK = 0xffe0001f; 1439 1.9 christos static constexpr uint32_t BRK_INSN_BASE = 0xd4200000; 1440 1.9 christos 1441 1.9 christos /* Implementation of gdbarch_program_breakpoint_here_p for aarch64. */ 1442 1.9 christos 1443 1.9 christos static bool 1444 1.9 christos aarch64_program_breakpoint_here_p (gdbarch *gdbarch, CORE_ADDR address) 1445 1.9 christos { 1446 1.9 christos const uint32_t insn_len = 4; 1447 1.9 christos gdb_byte target_mem[4]; 1448 1.9 christos 1449 1.9 christos /* Enable the automatic memory restoration from breakpoints while 1450 1.9 christos we read the memory. Otherwise we may find temporary breakpoints, ones 1451 1.9 christos inserted by GDB, and flag them as permanent breakpoints. */ 1452 1.9 christos scoped_restore restore_memory 1453 1.9 christos = make_scoped_restore_show_memory_breakpoints (0); 1454 1.9 christos 1455 1.9 christos if (target_read_memory (address, target_mem, insn_len) == 0) 1456 1.9 christos { 1457 1.9 christos uint32_t insn = 1458 1.9 christos (uint32_t) extract_unsigned_integer (target_mem, insn_len, 1459 1.9 christos gdbarch_byte_order_for_code (gdbarch)); 1460 1.9 christos 1461 1.9 christos /* Check if INSN is a BRK instruction pattern. There are multiple choices 1462 1.9 christos of such instructions with different immediate values. Different OS' 1463 1.9 christos may use a different variation, but they have the same outcome. */ 1464 1.9 christos return ((insn & BRK_INSN_MASK) == BRK_INSN_BASE); 1465 1.1 christos } 1466 1.9 christos 1467 1.9 christos return false; 1468 1.1 christos } 1469 1.1 christos 1470 1.1 christos /* When arguments must be pushed onto the stack, they go on in reverse 1471 1.1 christos order. The code below implements a FILO (stack) to do this. */ 1472 1.1 christos 1473 1.9 christos struct stack_item_t 1474 1.1 christos { 1475 1.6 christos /* Value to pass on stack. It can be NULL if this item is for stack 1476 1.6 christos padding. */ 1477 1.6 christos const gdb_byte *data; 1478 1.1 christos 1479 1.1 christos /* Size in bytes of value to pass on stack. */ 1480 1.1 christos int len; 1481 1.9 christos }; 1482 1.1 christos 1483 1.9 christos /* Implement the gdbarch type alignment method, overrides the generic 1484 1.9 christos alignment algorithm for anything that is aarch64 specific. */ 1485 1.1 christos 1486 1.9 christos static ULONGEST 1487 1.9 christos aarch64_type_align (gdbarch *gdbarch, struct type *t) 1488 1.1 christos { 1489 1.1 christos t = check_typedef (t); 1490 1.10 christos if (t->code () == TYPE_CODE_ARRAY && t->is_vector ()) 1491 1.1 christos { 1492 1.9 christos /* Use the natural alignment for vector types (the same for 1493 1.9 christos scalar type), but the maximum alignment is 128-bit. */ 1494 1.10 christos if (t->length () > 16) 1495 1.9 christos return 16; 1496 1.6 christos else 1497 1.10 christos return t->length (); 1498 1.9 christos } 1499 1.1 christos 1500 1.9 christos /* Allow the common code to calculate the alignment. */ 1501 1.9 christos return 0; 1502 1.1 christos } 1503 1.1 christos 1504 1.8 christos /* Worker function for aapcs_is_vfp_call_or_return_candidate. 1505 1.8 christos 1506 1.8 christos Return the number of register required, or -1 on failure. 1507 1.8 christos 1508 1.8 christos When encountering a base element, if FUNDAMENTAL_TYPE is not set then set it 1509 1.8 christos to the element, else fail if the type of this element does not match the 1510 1.8 christos existing value. */ 1511 1.1 christos 1512 1.1 christos static int 1513 1.8 christos aapcs_is_vfp_call_or_return_candidate_1 (struct type *type, 1514 1.8 christos struct type **fundamental_type) 1515 1.1 christos { 1516 1.8 christos if (type == nullptr) 1517 1.8 christos return -1; 1518 1.8 christos 1519 1.9 christos switch (type->code ()) 1520 1.1 christos { 1521 1.8 christos case TYPE_CODE_FLT: 1522 1.10 christos case TYPE_CODE_DECFLOAT: 1523 1.10 christos if (type->length () > 16) 1524 1.8 christos return -1; 1525 1.8 christos 1526 1.8 christos if (*fundamental_type == nullptr) 1527 1.8 christos *fundamental_type = type; 1528 1.10 christos else if (type->length () != (*fundamental_type)->length () 1529 1.9 christos || type->code () != (*fundamental_type)->code ()) 1530 1.8 christos return -1; 1531 1.8 christos 1532 1.8 christos return 1; 1533 1.8 christos 1534 1.8 christos case TYPE_CODE_COMPLEX: 1535 1.8 christos { 1536 1.10 christos struct type *target_type = check_typedef (type->target_type ()); 1537 1.10 christos if (target_type->length () > 16) 1538 1.8 christos return -1; 1539 1.8 christos 1540 1.8 christos if (*fundamental_type == nullptr) 1541 1.8 christos *fundamental_type = target_type; 1542 1.10 christos else if (target_type->length () != (*fundamental_type)->length () 1543 1.9 christos || target_type->code () != (*fundamental_type)->code ()) 1544 1.8 christos return -1; 1545 1.8 christos 1546 1.8 christos return 2; 1547 1.8 christos } 1548 1.8 christos 1549 1.1 christos case TYPE_CODE_ARRAY: 1550 1.1 christos { 1551 1.10 christos if (type->is_vector ()) 1552 1.8 christos { 1553 1.10 christos if (type->length () != 8 && type->length () != 16) 1554 1.8 christos return -1; 1555 1.8 christos 1556 1.8 christos if (*fundamental_type == nullptr) 1557 1.8 christos *fundamental_type = type; 1558 1.10 christos else if (type->length () != (*fundamental_type)->length () 1559 1.9 christos || type->code () != (*fundamental_type)->code ()) 1560 1.8 christos return -1; 1561 1.6 christos 1562 1.8 christos return 1; 1563 1.8 christos } 1564 1.8 christos else 1565 1.8 christos { 1566 1.10 christos struct type *target_type = type->target_type (); 1567 1.8 christos int count = aapcs_is_vfp_call_or_return_candidate_1 1568 1.8 christos (target_type, fundamental_type); 1569 1.6 christos 1570 1.8 christos if (count == -1) 1571 1.8 christos return count; 1572 1.8 christos 1573 1.10 christos count *= (type->length () / target_type->length ()); 1574 1.8 christos return count; 1575 1.8 christos } 1576 1.1 christos } 1577 1.1 christos 1578 1.8 christos case TYPE_CODE_STRUCT: 1579 1.1 christos case TYPE_CODE_UNION: 1580 1.1 christos { 1581 1.8 christos int count = 0; 1582 1.8 christos 1583 1.9 christos for (int i = 0; i < type->num_fields (); i++) 1584 1.1 christos { 1585 1.8 christos /* Ignore any static fields. */ 1586 1.11 christos if (type->field (i).is_static ()) 1587 1.8 christos continue; 1588 1.8 christos 1589 1.9 christos struct type *member = check_typedef (type->field (i).type ()); 1590 1.8 christos 1591 1.8 christos int sub_count = aapcs_is_vfp_call_or_return_candidate_1 1592 1.8 christos (member, fundamental_type); 1593 1.8 christos if (sub_count == -1) 1594 1.8 christos return -1; 1595 1.8 christos count += sub_count; 1596 1.8 christos } 1597 1.1 christos 1598 1.8 christos /* Ensure there is no padding between the fields (allowing for empty 1599 1.8 christos zero length structs) */ 1600 1.8 christos int ftype_length = (*fundamental_type == nullptr) 1601 1.10 christos ? 0 : (*fundamental_type)->length (); 1602 1.10 christos if (count * ftype_length != type->length ()) 1603 1.8 christos return -1; 1604 1.8 christos 1605 1.8 christos return count; 1606 1.1 christos } 1607 1.1 christos 1608 1.1 christos default: 1609 1.1 christos break; 1610 1.1 christos } 1611 1.1 christos 1612 1.8 christos return -1; 1613 1.8 christos } 1614 1.8 christos 1615 1.8 christos /* Return true if an argument, whose type is described by TYPE, can be passed or 1616 1.8 christos returned in simd/fp registers, providing enough parameter passing registers 1617 1.8 christos are available. This is as described in the AAPCS64. 1618 1.8 christos 1619 1.8 christos Upon successful return, *COUNT returns the number of needed registers, 1620 1.8 christos *FUNDAMENTAL_TYPE contains the type of those registers. 1621 1.8 christos 1622 1.8 christos Candidate as per the AAPCS64 5.4.2.C is either a: 1623 1.8 christos - float. 1624 1.8 christos - short-vector. 1625 1.8 christos - HFA (Homogeneous Floating-point Aggregate, 4.3.5.1). A Composite type where 1626 1.8 christos all the members are floats and has at most 4 members. 1627 1.8 christos - HVA (Homogeneous Short-vector Aggregate, 4.3.5.2). A Composite type where 1628 1.8 christos all the members are short vectors and has at most 4 members. 1629 1.8 christos - Complex (7.1.1) 1630 1.8 christos 1631 1.8 christos Note that HFAs and HVAs can include nested structures and arrays. */ 1632 1.8 christos 1633 1.8 christos static bool 1634 1.8 christos aapcs_is_vfp_call_or_return_candidate (struct type *type, int *count, 1635 1.8 christos struct type **fundamental_type) 1636 1.8 christos { 1637 1.8 christos if (type == nullptr) 1638 1.8 christos return false; 1639 1.8 christos 1640 1.8 christos *fundamental_type = nullptr; 1641 1.8 christos 1642 1.8 christos int ag_count = aapcs_is_vfp_call_or_return_candidate_1 (type, 1643 1.8 christos fundamental_type); 1644 1.8 christos 1645 1.8 christos if (ag_count > 0 && ag_count <= HA_MAX_NUM_FLDS) 1646 1.8 christos { 1647 1.8 christos *count = ag_count; 1648 1.8 christos return true; 1649 1.8 christos } 1650 1.8 christos else 1651 1.8 christos return false; 1652 1.1 christos } 1653 1.1 christos 1654 1.1 christos /* AArch64 function call information structure. */ 1655 1.1 christos struct aarch64_call_info 1656 1.1 christos { 1657 1.1 christos /* the current argument number. */ 1658 1.9 christos unsigned argnum = 0; 1659 1.1 christos 1660 1.1 christos /* The next general purpose register number, equivalent to NGRN as 1661 1.1 christos described in the AArch64 Procedure Call Standard. */ 1662 1.9 christos unsigned ngrn = 0; 1663 1.1 christos 1664 1.1 christos /* The next SIMD and floating point register number, equivalent to 1665 1.1 christos NSRN as described in the AArch64 Procedure Call Standard. */ 1666 1.9 christos unsigned nsrn = 0; 1667 1.1 christos 1668 1.1 christos /* The next stacked argument address, equivalent to NSAA as 1669 1.1 christos described in the AArch64 Procedure Call Standard. */ 1670 1.9 christos unsigned nsaa = 0; 1671 1.1 christos 1672 1.1 christos /* Stack item vector. */ 1673 1.9 christos std::vector<stack_item_t> si; 1674 1.1 christos }; 1675 1.1 christos 1676 1.1 christos /* Pass a value in a sequence of consecutive X registers. The caller 1677 1.9 christos is responsible for ensuring sufficient registers are available. */ 1678 1.1 christos 1679 1.1 christos static void 1680 1.1 christos pass_in_x (struct gdbarch *gdbarch, struct regcache *regcache, 1681 1.1 christos struct aarch64_call_info *info, struct type *type, 1682 1.6 christos struct value *arg) 1683 1.1 christos { 1684 1.1 christos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 1685 1.10 christos int len = type->length (); 1686 1.9 christos enum type_code typecode = type->code (); 1687 1.1 christos int regnum = AARCH64_X0_REGNUM + info->ngrn; 1688 1.11 christos const bfd_byte *buf = arg->contents ().data (); 1689 1.1 christos 1690 1.1 christos info->argnum++; 1691 1.1 christos 1692 1.1 christos while (len > 0) 1693 1.1 christos { 1694 1.1 christos int partial_len = len < X_REGISTER_SIZE ? len : X_REGISTER_SIZE; 1695 1.1 christos CORE_ADDR regval = extract_unsigned_integer (buf, partial_len, 1696 1.1 christos byte_order); 1697 1.1 christos 1698 1.1 christos 1699 1.1 christos /* Adjust sub-word struct/union args when big-endian. */ 1700 1.1 christos if (byte_order == BFD_ENDIAN_BIG 1701 1.1 christos && partial_len < X_REGISTER_SIZE 1702 1.1 christos && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)) 1703 1.1 christos regval <<= ((X_REGISTER_SIZE - partial_len) * TARGET_CHAR_BIT); 1704 1.1 christos 1705 1.10 christos aarch64_debug_printf ("arg %d in %s = 0x%s", info->argnum, 1706 1.10 christos gdbarch_register_name (gdbarch, regnum), 1707 1.10 christos phex (regval, X_REGISTER_SIZE)); 1708 1.10 christos 1709 1.1 christos regcache_cooked_write_unsigned (regcache, regnum, regval); 1710 1.1 christos len -= partial_len; 1711 1.1 christos buf += partial_len; 1712 1.1 christos regnum++; 1713 1.1 christos } 1714 1.1 christos } 1715 1.1 christos 1716 1.1 christos /* Attempt to marshall a value in a V register. Return 1 if 1717 1.1 christos successful, or 0 if insufficient registers are available. This 1718 1.1 christos function, unlike the equivalent pass_in_x() function does not 1719 1.1 christos handle arguments spread across multiple registers. */ 1720 1.1 christos 1721 1.1 christos static int 1722 1.1 christos pass_in_v (struct gdbarch *gdbarch, 1723 1.1 christos struct regcache *regcache, 1724 1.1 christos struct aarch64_call_info *info, 1725 1.6 christos int len, const bfd_byte *buf) 1726 1.1 christos { 1727 1.1 christos if (info->nsrn < 8) 1728 1.1 christos { 1729 1.1 christos int regnum = AARCH64_V0_REGNUM + info->nsrn; 1730 1.8 christos /* Enough space for a full vector register. */ 1731 1.12 christos gdb::byte_vector reg (register_size (gdbarch, regnum), 0); 1732 1.12 christos gdb_assert (len <= reg.size ()); 1733 1.1 christos 1734 1.1 christos info->argnum++; 1735 1.1 christos info->nsrn++; 1736 1.1 christos 1737 1.6 christos /* PCS C.1, the argument is allocated to the least significant 1738 1.6 christos bits of V register. */ 1739 1.12 christos memcpy (reg.data (), buf, len); 1740 1.8 christos regcache->cooked_write (regnum, reg); 1741 1.6 christos 1742 1.10 christos aarch64_debug_printf ("arg %d in %s", info->argnum, 1743 1.10 christos gdbarch_register_name (gdbarch, regnum)); 1744 1.10 christos 1745 1.1 christos return 1; 1746 1.1 christos } 1747 1.1 christos info->nsrn = 8; 1748 1.1 christos return 0; 1749 1.1 christos } 1750 1.1 christos 1751 1.1 christos /* Marshall an argument onto the stack. */ 1752 1.1 christos 1753 1.1 christos static void 1754 1.1 christos pass_on_stack (struct aarch64_call_info *info, struct type *type, 1755 1.6 christos struct value *arg) 1756 1.1 christos { 1757 1.11 christos const bfd_byte *buf = arg->contents ().data (); 1758 1.10 christos int len = type->length (); 1759 1.1 christos int align; 1760 1.1 christos stack_item_t item; 1761 1.1 christos 1762 1.1 christos info->argnum++; 1763 1.1 christos 1764 1.9 christos align = type_align (type); 1765 1.1 christos 1766 1.1 christos /* PCS C.17 Stack should be aligned to the larger of 8 bytes or the 1767 1.1 christos Natural alignment of the argument's type. */ 1768 1.1 christos align = align_up (align, 8); 1769 1.1 christos 1770 1.1 christos /* The AArch64 PCS requires at most doubleword alignment. */ 1771 1.1 christos if (align > 16) 1772 1.1 christos align = 16; 1773 1.1 christos 1774 1.10 christos aarch64_debug_printf ("arg %d len=%d @ sp + %d\n", info->argnum, len, 1775 1.10 christos info->nsaa); 1776 1.1 christos 1777 1.1 christos item.len = len; 1778 1.1 christos item.data = buf; 1779 1.9 christos info->si.push_back (item); 1780 1.1 christos 1781 1.1 christos info->nsaa += len; 1782 1.1 christos if (info->nsaa & (align - 1)) 1783 1.1 christos { 1784 1.1 christos /* Push stack alignment padding. */ 1785 1.1 christos int pad = align - (info->nsaa & (align - 1)); 1786 1.1 christos 1787 1.1 christos item.len = pad; 1788 1.6 christos item.data = NULL; 1789 1.1 christos 1790 1.9 christos info->si.push_back (item); 1791 1.1 christos info->nsaa += pad; 1792 1.1 christos } 1793 1.1 christos } 1794 1.1 christos 1795 1.1 christos /* Marshall an argument into a sequence of one or more consecutive X 1796 1.1 christos registers or, if insufficient X registers are available then onto 1797 1.1 christos the stack. */ 1798 1.1 christos 1799 1.1 christos static void 1800 1.1 christos pass_in_x_or_stack (struct gdbarch *gdbarch, struct regcache *regcache, 1801 1.1 christos struct aarch64_call_info *info, struct type *type, 1802 1.6 christos struct value *arg) 1803 1.1 christos { 1804 1.10 christos int len = type->length (); 1805 1.1 christos int nregs = (len + X_REGISTER_SIZE - 1) / X_REGISTER_SIZE; 1806 1.1 christos 1807 1.1 christos /* PCS C.13 - Pass in registers if we have enough spare */ 1808 1.1 christos if (info->ngrn + nregs <= 8) 1809 1.1 christos { 1810 1.6 christos pass_in_x (gdbarch, regcache, info, type, arg); 1811 1.1 christos info->ngrn += nregs; 1812 1.1 christos } 1813 1.1 christos else 1814 1.1 christos { 1815 1.1 christos info->ngrn = 8; 1816 1.6 christos pass_on_stack (info, type, arg); 1817 1.1 christos } 1818 1.1 christos } 1819 1.1 christos 1820 1.8 christos /* Pass a value, which is of type arg_type, in a V register. Assumes value is a 1821 1.8 christos aapcs_is_vfp_call_or_return_candidate and there are enough spare V 1822 1.8 christos registers. A return value of false is an error state as the value will have 1823 1.8 christos been partially passed to the stack. */ 1824 1.8 christos static bool 1825 1.8 christos pass_in_v_vfp_candidate (struct gdbarch *gdbarch, struct regcache *regcache, 1826 1.8 christos struct aarch64_call_info *info, struct type *arg_type, 1827 1.8 christos struct value *arg) 1828 1.8 christos { 1829 1.9 christos switch (arg_type->code ()) 1830 1.8 christos { 1831 1.8 christos case TYPE_CODE_FLT: 1832 1.10 christos case TYPE_CODE_DECFLOAT: 1833 1.10 christos return pass_in_v (gdbarch, regcache, info, arg_type->length (), 1834 1.11 christos arg->contents ().data ()); 1835 1.8 christos break; 1836 1.1 christos 1837 1.8 christos case TYPE_CODE_COMPLEX: 1838 1.8 christos { 1839 1.11 christos const bfd_byte *buf = arg->contents ().data (); 1840 1.10 christos struct type *target_type = check_typedef (arg_type->target_type ()); 1841 1.8 christos 1842 1.10 christos if (!pass_in_v (gdbarch, regcache, info, target_type->length (), 1843 1.8 christos buf)) 1844 1.8 christos return false; 1845 1.8 christos 1846 1.10 christos return pass_in_v (gdbarch, regcache, info, target_type->length (), 1847 1.10 christos buf + target_type->length ()); 1848 1.8 christos } 1849 1.8 christos 1850 1.8 christos case TYPE_CODE_ARRAY: 1851 1.10 christos if (arg_type->is_vector ()) 1852 1.10 christos return pass_in_v (gdbarch, regcache, info, arg_type->length (), 1853 1.11 christos arg->contents ().data ()); 1854 1.11 christos [[fallthrough]]; 1855 1.8 christos 1856 1.8 christos case TYPE_CODE_STRUCT: 1857 1.8 christos case TYPE_CODE_UNION: 1858 1.9 christos for (int i = 0; i < arg_type->num_fields (); i++) 1859 1.8 christos { 1860 1.8 christos /* Don't include static fields. */ 1861 1.11 christos if (arg_type->field (i).is_static ()) 1862 1.8 christos continue; 1863 1.8 christos 1864 1.11 christos struct value *field = arg->primitive_field (0, i, arg_type); 1865 1.11 christos struct type *field_type = check_typedef (field->type ()); 1866 1.8 christos 1867 1.8 christos if (!pass_in_v_vfp_candidate (gdbarch, regcache, info, field_type, 1868 1.8 christos field)) 1869 1.8 christos return false; 1870 1.8 christos } 1871 1.8 christos return true; 1872 1.8 christos 1873 1.8 christos default: 1874 1.8 christos return false; 1875 1.8 christos } 1876 1.1 christos } 1877 1.1 christos 1878 1.1 christos /* Implement the "push_dummy_call" gdbarch method. */ 1879 1.1 christos 1880 1.1 christos static CORE_ADDR 1881 1.1 christos aarch64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, 1882 1.1 christos struct regcache *regcache, CORE_ADDR bp_addr, 1883 1.1 christos int nargs, 1884 1.8 christos struct value **args, CORE_ADDR sp, 1885 1.8 christos function_call_return_method return_method, 1886 1.1 christos CORE_ADDR struct_addr) 1887 1.1 christos { 1888 1.1 christos int argnum; 1889 1.1 christos struct aarch64_call_info info; 1890 1.1 christos 1891 1.1 christos /* We need to know what the type of the called function is in order 1892 1.1 christos to determine the number of named/anonymous arguments for the 1893 1.1 christos actual argument placement, and the return type in order to handle 1894 1.1 christos return value correctly. 1895 1.1 christos 1896 1.1 christos The generic code above us views the decision of return in memory 1897 1.1 christos or return in registers as a two stage processes. The language 1898 1.1 christos handler is consulted first and may decide to return in memory (eg 1899 1.1 christos class with copy constructor returned by value), this will cause 1900 1.1 christos the generic code to allocate space AND insert an initial leading 1901 1.1 christos argument. 1902 1.1 christos 1903 1.1 christos If the language code does not decide to pass in memory then the 1904 1.1 christos target code is consulted. 1905 1.1 christos 1906 1.1 christos If the language code decides to pass in memory we want to move 1907 1.1 christos the pointer inserted as the initial argument from the argument 1908 1.1 christos list and into X8, the conventional AArch64 struct return pointer 1909 1.8 christos register. */ 1910 1.1 christos 1911 1.1 christos /* Set the return address. For the AArch64, the return breakpoint 1912 1.1 christos is always at BP_ADDR. */ 1913 1.1 christos regcache_cooked_write_unsigned (regcache, AARCH64_LR_REGNUM, bp_addr); 1914 1.1 christos 1915 1.8 christos /* If we were given an initial argument for the return slot, lose it. */ 1916 1.8 christos if (return_method == return_method_hidden_param) 1917 1.1 christos { 1918 1.1 christos args++; 1919 1.1 christos nargs--; 1920 1.1 christos } 1921 1.1 christos 1922 1.1 christos /* The struct_return pointer occupies X8. */ 1923 1.8 christos if (return_method != return_method_normal) 1924 1.1 christos { 1925 1.10 christos aarch64_debug_printf ("struct return in %s = 0x%s", 1926 1.10 christos gdbarch_register_name 1927 1.10 christos (gdbarch, AARCH64_STRUCT_RETURN_REGNUM), 1928 1.10 christos paddress (gdbarch, struct_addr)); 1929 1.10 christos 1930 1.1 christos regcache_cooked_write_unsigned (regcache, AARCH64_STRUCT_RETURN_REGNUM, 1931 1.1 christos struct_addr); 1932 1.1 christos } 1933 1.1 christos 1934 1.1 christos for (argnum = 0; argnum < nargs; argnum++) 1935 1.1 christos { 1936 1.1 christos struct value *arg = args[argnum]; 1937 1.8 christos struct type *arg_type, *fundamental_type; 1938 1.8 christos int len, elements; 1939 1.1 christos 1940 1.11 christos arg_type = check_typedef (arg->type ()); 1941 1.10 christos len = arg_type->length (); 1942 1.1 christos 1943 1.8 christos /* If arg can be passed in v registers as per the AAPCS64, then do so if 1944 1.8 christos if there are enough spare registers. */ 1945 1.8 christos if (aapcs_is_vfp_call_or_return_candidate (arg_type, &elements, 1946 1.8 christos &fundamental_type)) 1947 1.8 christos { 1948 1.8 christos if (info.nsrn + elements <= 8) 1949 1.8 christos { 1950 1.8 christos /* We know that we have sufficient registers available therefore 1951 1.8 christos this will never need to fallback to the stack. */ 1952 1.8 christos if (!pass_in_v_vfp_candidate (gdbarch, regcache, &info, arg_type, 1953 1.8 christos arg)) 1954 1.8 christos gdb_assert_not_reached ("Failed to push args"); 1955 1.8 christos } 1956 1.8 christos else 1957 1.8 christos { 1958 1.8 christos info.nsrn = 8; 1959 1.8 christos pass_on_stack (&info, arg_type, arg); 1960 1.8 christos } 1961 1.8 christos continue; 1962 1.8 christos } 1963 1.8 christos 1964 1.9 christos switch (arg_type->code ()) 1965 1.1 christos { 1966 1.1 christos case TYPE_CODE_INT: 1967 1.1 christos case TYPE_CODE_BOOL: 1968 1.1 christos case TYPE_CODE_CHAR: 1969 1.1 christos case TYPE_CODE_RANGE: 1970 1.1 christos case TYPE_CODE_ENUM: 1971 1.10 christos if (len < 4 && !is_fixed_point_type (arg_type)) 1972 1.1 christos { 1973 1.1 christos /* Promote to 32 bit integer. */ 1974 1.10 christos if (arg_type->is_unsigned ()) 1975 1.1 christos arg_type = builtin_type (gdbarch)->builtin_uint32; 1976 1.1 christos else 1977 1.1 christos arg_type = builtin_type (gdbarch)->builtin_int32; 1978 1.1 christos arg = value_cast (arg_type, arg); 1979 1.1 christos } 1980 1.6 christos pass_in_x_or_stack (gdbarch, regcache, &info, arg_type, arg); 1981 1.1 christos break; 1982 1.1 christos 1983 1.1 christos case TYPE_CODE_STRUCT: 1984 1.1 christos case TYPE_CODE_ARRAY: 1985 1.1 christos case TYPE_CODE_UNION: 1986 1.8 christos if (len > 16) 1987 1.1 christos { 1988 1.1 christos /* PCS B.7 Aggregates larger than 16 bytes are passed by 1989 1.1 christos invisible reference. */ 1990 1.1 christos 1991 1.1 christos /* Allocate aligned storage. */ 1992 1.1 christos sp = align_down (sp - len, 16); 1993 1.1 christos 1994 1.1 christos /* Write the real data into the stack. */ 1995 1.11 christos write_memory (sp, arg->contents ().data (), len); 1996 1.1 christos 1997 1.1 christos /* Construct the indirection. */ 1998 1.1 christos arg_type = lookup_pointer_type (arg_type); 1999 1.1 christos arg = value_from_pointer (arg_type, sp); 2000 1.6 christos pass_in_x_or_stack (gdbarch, regcache, &info, arg_type, arg); 2001 1.1 christos } 2002 1.1 christos else 2003 1.1 christos /* PCS C.15 / C.18 multiple values pass. */ 2004 1.6 christos pass_in_x_or_stack (gdbarch, regcache, &info, arg_type, arg); 2005 1.1 christos break; 2006 1.1 christos 2007 1.1 christos default: 2008 1.6 christos pass_in_x_or_stack (gdbarch, regcache, &info, arg_type, arg); 2009 1.1 christos break; 2010 1.1 christos } 2011 1.1 christos } 2012 1.1 christos 2013 1.1 christos /* Make sure stack retains 16 byte alignment. */ 2014 1.1 christos if (info.nsaa & 15) 2015 1.1 christos sp -= 16 - (info.nsaa & 15); 2016 1.1 christos 2017 1.9 christos while (!info.si.empty ()) 2018 1.1 christos { 2019 1.9 christos const stack_item_t &si = info.si.back (); 2020 1.1 christos 2021 1.9 christos sp -= si.len; 2022 1.9 christos if (si.data != NULL) 2023 1.9 christos write_memory (sp, si.data, si.len); 2024 1.9 christos info.si.pop_back (); 2025 1.1 christos } 2026 1.1 christos 2027 1.1 christos /* Finally, update the SP register. */ 2028 1.1 christos regcache_cooked_write_unsigned (regcache, AARCH64_SP_REGNUM, sp); 2029 1.1 christos 2030 1.1 christos return sp; 2031 1.1 christos } 2032 1.1 christos 2033 1.1 christos /* Implement the "frame_align" gdbarch method. */ 2034 1.1 christos 2035 1.1 christos static CORE_ADDR 2036 1.1 christos aarch64_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp) 2037 1.1 christos { 2038 1.1 christos /* Align the stack to sixteen bytes. */ 2039 1.1 christos return sp & ~(CORE_ADDR) 15; 2040 1.1 christos } 2041 1.1 christos 2042 1.1 christos /* Return the type for an AdvSISD Q register. */ 2043 1.1 christos 2044 1.1 christos static struct type * 2045 1.1 christos aarch64_vnq_type (struct gdbarch *gdbarch) 2046 1.1 christos { 2047 1.10 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 2048 1.1 christos 2049 1.1 christos if (tdep->vnq_type == NULL) 2050 1.1 christos { 2051 1.1 christos struct type *t; 2052 1.1 christos struct type *elem; 2053 1.1 christos 2054 1.1 christos t = arch_composite_type (gdbarch, "__gdb_builtin_type_vnq", 2055 1.1 christos TYPE_CODE_UNION); 2056 1.1 christos 2057 1.1 christos elem = builtin_type (gdbarch)->builtin_uint128; 2058 1.1 christos append_composite_type_field (t, "u", elem); 2059 1.1 christos 2060 1.1 christos elem = builtin_type (gdbarch)->builtin_int128; 2061 1.1 christos append_composite_type_field (t, "s", elem); 2062 1.1 christos 2063 1.1 christos tdep->vnq_type = t; 2064 1.1 christos } 2065 1.1 christos 2066 1.1 christos return tdep->vnq_type; 2067 1.1 christos } 2068 1.1 christos 2069 1.1 christos /* Return the type for an AdvSISD D register. */ 2070 1.1 christos 2071 1.1 christos static struct type * 2072 1.1 christos aarch64_vnd_type (struct gdbarch *gdbarch) 2073 1.1 christos { 2074 1.10 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 2075 1.1 christos 2076 1.1 christos if (tdep->vnd_type == NULL) 2077 1.1 christos { 2078 1.1 christos struct type *t; 2079 1.1 christos struct type *elem; 2080 1.1 christos 2081 1.1 christos t = arch_composite_type (gdbarch, "__gdb_builtin_type_vnd", 2082 1.1 christos TYPE_CODE_UNION); 2083 1.1 christos 2084 1.1 christos elem = builtin_type (gdbarch)->builtin_double; 2085 1.1 christos append_composite_type_field (t, "f", elem); 2086 1.1 christos 2087 1.1 christos elem = builtin_type (gdbarch)->builtin_uint64; 2088 1.1 christos append_composite_type_field (t, "u", elem); 2089 1.1 christos 2090 1.1 christos elem = builtin_type (gdbarch)->builtin_int64; 2091 1.1 christos append_composite_type_field (t, "s", elem); 2092 1.1 christos 2093 1.1 christos tdep->vnd_type = t; 2094 1.1 christos } 2095 1.1 christos 2096 1.1 christos return tdep->vnd_type; 2097 1.1 christos } 2098 1.1 christos 2099 1.1 christos /* Return the type for an AdvSISD S register. */ 2100 1.1 christos 2101 1.1 christos static struct type * 2102 1.1 christos aarch64_vns_type (struct gdbarch *gdbarch) 2103 1.1 christos { 2104 1.10 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 2105 1.1 christos 2106 1.1 christos if (tdep->vns_type == NULL) 2107 1.1 christos { 2108 1.1 christos struct type *t; 2109 1.1 christos struct type *elem; 2110 1.1 christos 2111 1.1 christos t = arch_composite_type (gdbarch, "__gdb_builtin_type_vns", 2112 1.1 christos TYPE_CODE_UNION); 2113 1.1 christos 2114 1.1 christos elem = builtin_type (gdbarch)->builtin_float; 2115 1.1 christos append_composite_type_field (t, "f", elem); 2116 1.1 christos 2117 1.1 christos elem = builtin_type (gdbarch)->builtin_uint32; 2118 1.1 christos append_composite_type_field (t, "u", elem); 2119 1.1 christos 2120 1.1 christos elem = builtin_type (gdbarch)->builtin_int32; 2121 1.1 christos append_composite_type_field (t, "s", elem); 2122 1.1 christos 2123 1.1 christos tdep->vns_type = t; 2124 1.1 christos } 2125 1.1 christos 2126 1.1 christos return tdep->vns_type; 2127 1.1 christos } 2128 1.1 christos 2129 1.1 christos /* Return the type for an AdvSISD H register. */ 2130 1.1 christos 2131 1.1 christos static struct type * 2132 1.1 christos aarch64_vnh_type (struct gdbarch *gdbarch) 2133 1.1 christos { 2134 1.10 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 2135 1.1 christos 2136 1.1 christos if (tdep->vnh_type == NULL) 2137 1.1 christos { 2138 1.1 christos struct type *t; 2139 1.1 christos struct type *elem; 2140 1.1 christos 2141 1.1 christos t = arch_composite_type (gdbarch, "__gdb_builtin_type_vnh", 2142 1.1 christos TYPE_CODE_UNION); 2143 1.1 christos 2144 1.10 christos elem = builtin_type (gdbarch)->builtin_bfloat16; 2145 1.10 christos append_composite_type_field (t, "bf", elem); 2146 1.10 christos 2147 1.9 christos elem = builtin_type (gdbarch)->builtin_half; 2148 1.9 christos append_composite_type_field (t, "f", elem); 2149 1.9 christos 2150 1.1 christos elem = builtin_type (gdbarch)->builtin_uint16; 2151 1.1 christos append_composite_type_field (t, "u", elem); 2152 1.1 christos 2153 1.1 christos elem = builtin_type (gdbarch)->builtin_int16; 2154 1.1 christos append_composite_type_field (t, "s", elem); 2155 1.1 christos 2156 1.1 christos tdep->vnh_type = t; 2157 1.1 christos } 2158 1.1 christos 2159 1.1 christos return tdep->vnh_type; 2160 1.1 christos } 2161 1.1 christos 2162 1.1 christos /* Return the type for an AdvSISD B register. */ 2163 1.1 christos 2164 1.1 christos static struct type * 2165 1.1 christos aarch64_vnb_type (struct gdbarch *gdbarch) 2166 1.1 christos { 2167 1.10 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 2168 1.1 christos 2169 1.1 christos if (tdep->vnb_type == NULL) 2170 1.1 christos { 2171 1.1 christos struct type *t; 2172 1.1 christos struct type *elem; 2173 1.1 christos 2174 1.1 christos t = arch_composite_type (gdbarch, "__gdb_builtin_type_vnb", 2175 1.1 christos TYPE_CODE_UNION); 2176 1.1 christos 2177 1.1 christos elem = builtin_type (gdbarch)->builtin_uint8; 2178 1.1 christos append_composite_type_field (t, "u", elem); 2179 1.1 christos 2180 1.1 christos elem = builtin_type (gdbarch)->builtin_int8; 2181 1.1 christos append_composite_type_field (t, "s", elem); 2182 1.1 christos 2183 1.1 christos tdep->vnb_type = t; 2184 1.1 christos } 2185 1.1 christos 2186 1.1 christos return tdep->vnb_type; 2187 1.1 christos } 2188 1.1 christos 2189 1.11 christos /* Return TRUE if REGNUM is a ZA tile slice pseudo-register number. Return 2190 1.11 christos FALSE otherwise. */ 2191 1.11 christos 2192 1.11 christos static bool 2193 1.11 christos is_sme_tile_slice_pseudo_register (struct gdbarch *gdbarch, int regnum) 2194 1.11 christos { 2195 1.11 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 2196 1.11 christos 2197 1.11 christos gdb_assert (tdep->has_sme ()); 2198 1.11 christos gdb_assert (tdep->sme_svq > 0); 2199 1.11 christos gdb_assert (tdep->sme_pseudo_base <= regnum); 2200 1.11 christos gdb_assert (regnum < tdep->sme_pseudo_base + tdep->sme_pseudo_count); 2201 1.11 christos 2202 1.11 christos if (tdep->sme_tile_slice_pseudo_base <= regnum 2203 1.11 christos && regnum < tdep->sme_tile_slice_pseudo_base 2204 1.11 christos + tdep->sme_tile_slice_pseudo_count) 2205 1.11 christos return true; 2206 1.11 christos 2207 1.11 christos return false; 2208 1.11 christos } 2209 1.11 christos 2210 1.11 christos /* Given REGNUM, a ZA pseudo-register number, return, in ENCODING, the 2211 1.11 christos decoded fields that make up its name. */ 2212 1.11 christos 2213 1.11 christos static void 2214 1.11 christos aarch64_za_decode_pseudos (struct gdbarch *gdbarch, int regnum, 2215 1.11 christos struct za_pseudo_encoding &encoding) 2216 1.11 christos { 2217 1.11 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 2218 1.11 christos 2219 1.11 christos gdb_assert (tdep->has_sme ()); 2220 1.11 christos gdb_assert (tdep->sme_svq > 0); 2221 1.11 christos gdb_assert (tdep->sme_pseudo_base <= regnum); 2222 1.11 christos gdb_assert (regnum < tdep->sme_pseudo_base + tdep->sme_pseudo_count); 2223 1.11 christos 2224 1.11 christos if (is_sme_tile_slice_pseudo_register (gdbarch, regnum)) 2225 1.11 christos { 2226 1.11 christos /* Calculate the tile slice pseudo-register offset relative to the other 2227 1.11 christos tile slice pseudo-registers. */ 2228 1.11 christos int offset = regnum - tdep->sme_tile_slice_pseudo_base; 2229 1.11 christos 2230 1.11 christos /* Fetch the qualifier. We can have 160 to 2560 possible tile slice 2231 1.11 christos pseudo-registers. Each qualifier (we have 5 of them: B, H, S, D 2232 1.11 christos and Q) covers 32 * svq pseudo-registers, so we divide the offset by 2233 1.11 christos that constant. */ 2234 1.11 christos size_t qualifier = offset / (tdep->sme_svq * 32); 2235 1.11 christos encoding.qualifier_index = qualifier; 2236 1.11 christos 2237 1.11 christos /* Prepare to fetch the direction (d), tile number (t) and slice 2238 1.11 christos number (s). */ 2239 1.11 christos int dts = offset % (tdep->sme_svq * 32); 2240 1.11 christos 2241 1.11 christos /* The direction is represented by the even/odd numbers. Even-numbered 2242 1.11 christos pseudo-registers are horizontal tile slices and odd-numbered 2243 1.11 christos pseudo-registers are vertical tile slices. */ 2244 1.11 christos encoding.horizontal = !(dts & 1); 2245 1.11 christos 2246 1.11 christos /* Fetch the tile number. The tile number is closely related to the 2247 1.11 christos qualifier. B has 1 tile, H has 2 tiles, S has 4 tiles, D has 8 tiles 2248 1.11 christos and Q has 16 tiles. */ 2249 1.11 christos encoding.tile_index = (dts >> 1) & ((1 << qualifier) - 1); 2250 1.11 christos 2251 1.11 christos /* Fetch the slice number. The slice number is closely related to the 2252 1.11 christos qualifier and the svl. */ 2253 1.11 christos encoding.slice_index = dts >> (qualifier + 1); 2254 1.11 christos } 2255 1.11 christos else 2256 1.11 christos { 2257 1.11 christos /* Calculate the tile pseudo-register offset relative to the other 2258 1.11 christos tile pseudo-registers. */ 2259 1.11 christos int offset = regnum - tdep->sme_tile_pseudo_base; 2260 1.11 christos 2261 1.11 christos encoding.qualifier_index = std::floor (std::log2 (offset + 1)); 2262 1.11 christos /* Calculate the tile number. */ 2263 1.11 christos encoding.tile_index = (offset + 1) - (1 << encoding.qualifier_index); 2264 1.11 christos /* Direction and slice index don't get used for tiles. Set them to 2265 1.11 christos 0/false values. */ 2266 1.11 christos encoding.slice_index = 0; 2267 1.11 christos encoding.horizontal = false; 2268 1.11 christos } 2269 1.11 christos } 2270 1.11 christos 2271 1.11 christos /* Return the type for a ZA tile slice pseudo-register based on ENCODING. */ 2272 1.11 christos 2273 1.11 christos static struct type * 2274 1.11 christos aarch64_za_tile_slice_type (struct gdbarch *gdbarch, 2275 1.11 christos const struct za_pseudo_encoding &encoding) 2276 1.11 christos { 2277 1.11 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 2278 1.11 christos 2279 1.11 christos gdb_assert (tdep->has_sme ()); 2280 1.11 christos gdb_assert (tdep->sme_svq > 0); 2281 1.11 christos 2282 1.11 christos if (tdep->sme_tile_slice_type_q == nullptr) 2283 1.11 christos { 2284 1.11 christos /* Q tile slice type. */ 2285 1.11 christos tdep->sme_tile_slice_type_q 2286 1.11 christos = init_vector_type (builtin_type (gdbarch)->builtin_uint128, 2287 1.11 christos tdep->sme_svq); 2288 1.11 christos /* D tile slice type. */ 2289 1.11 christos tdep->sme_tile_slice_type_d 2290 1.11 christos = init_vector_type (builtin_type (gdbarch)->builtin_uint64, 2291 1.11 christos tdep->sme_svq * 2); 2292 1.11 christos /* S tile slice type. */ 2293 1.11 christos tdep->sme_tile_slice_type_s 2294 1.11 christos = init_vector_type (builtin_type (gdbarch)->builtin_uint32, 2295 1.11 christos tdep->sme_svq * 4); 2296 1.11 christos /* H tile slice type. */ 2297 1.11 christos tdep->sme_tile_slice_type_h 2298 1.11 christos = init_vector_type (builtin_type (gdbarch)->builtin_uint16, 2299 1.11 christos tdep->sme_svq * 8); 2300 1.11 christos /* B tile slice type. */ 2301 1.11 christos tdep->sme_tile_slice_type_b 2302 1.11 christos = init_vector_type (builtin_type (gdbarch)->builtin_uint8, 2303 1.11 christos tdep->sme_svq * 16); 2304 1.11 christos } 2305 1.11 christos 2306 1.11 christos switch (encoding.qualifier_index) 2307 1.11 christos { 2308 1.11 christos case 4: 2309 1.11 christos return tdep->sme_tile_slice_type_q; 2310 1.11 christos case 3: 2311 1.11 christos return tdep->sme_tile_slice_type_d; 2312 1.11 christos case 2: 2313 1.11 christos return tdep->sme_tile_slice_type_s; 2314 1.11 christos case 1: 2315 1.11 christos return tdep->sme_tile_slice_type_h; 2316 1.11 christos case 0: 2317 1.11 christos return tdep->sme_tile_slice_type_b; 2318 1.11 christos default: 2319 1.11 christos error (_("Invalid qualifier index %s for tile slice pseudo register."), 2320 1.11 christos pulongest (encoding.qualifier_index)); 2321 1.11 christos } 2322 1.11 christos 2323 1.11 christos gdb_assert_not_reached ("Unknown qualifier for ZA tile slice register"); 2324 1.11 christos } 2325 1.11 christos 2326 1.11 christos /* Return the type for a ZA tile pseudo-register based on ENCODING. */ 2327 1.11 christos 2328 1.11 christos static struct type * 2329 1.11 christos aarch64_za_tile_type (struct gdbarch *gdbarch, 2330 1.11 christos const struct za_pseudo_encoding &encoding) 2331 1.11 christos { 2332 1.11 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 2333 1.11 christos 2334 1.11 christos gdb_assert (tdep->has_sme ()); 2335 1.11 christos gdb_assert (tdep->sme_svq > 0); 2336 1.11 christos 2337 1.11 christos if (tdep->sme_tile_type_q == nullptr) 2338 1.11 christos { 2339 1.11 christos struct type *inner_vectors_type; 2340 1.11 christos 2341 1.11 christos /* Q tile type. */ 2342 1.11 christos inner_vectors_type 2343 1.11 christos = init_vector_type (builtin_type (gdbarch)->builtin_uint128, 2344 1.11 christos tdep->sme_svq); 2345 1.11 christos tdep->sme_tile_type_q 2346 1.11 christos = init_vector_type (inner_vectors_type, tdep->sme_svq); 2347 1.11 christos 2348 1.11 christos /* D tile type. */ 2349 1.11 christos inner_vectors_type 2350 1.11 christos = init_vector_type (builtin_type (gdbarch)->builtin_uint64, 2351 1.11 christos tdep->sme_svq * 2); 2352 1.11 christos tdep->sme_tile_type_d 2353 1.11 christos = init_vector_type (inner_vectors_type, tdep->sme_svq * 2); 2354 1.11 christos 2355 1.11 christos /* S tile type. */ 2356 1.11 christos inner_vectors_type 2357 1.11 christos = init_vector_type (builtin_type (gdbarch)->builtin_uint32, 2358 1.11 christos tdep->sme_svq * 4); 2359 1.11 christos tdep->sme_tile_type_s 2360 1.11 christos = init_vector_type (inner_vectors_type, tdep->sme_svq * 4); 2361 1.11 christos 2362 1.11 christos /* H tile type. */ 2363 1.11 christos inner_vectors_type 2364 1.11 christos = init_vector_type (builtin_type (gdbarch)->builtin_uint16, 2365 1.11 christos tdep->sme_svq * 8); 2366 1.11 christos tdep->sme_tile_type_h 2367 1.11 christos = init_vector_type (inner_vectors_type, tdep->sme_svq * 8); 2368 1.11 christos 2369 1.11 christos /* B tile type. */ 2370 1.11 christos inner_vectors_type 2371 1.11 christos = init_vector_type (builtin_type (gdbarch)->builtin_uint8, 2372 1.11 christos tdep->sme_svq * 16); 2373 1.11 christos tdep->sme_tile_type_b 2374 1.11 christos = init_vector_type (inner_vectors_type, tdep->sme_svq * 16); 2375 1.11 christos } 2376 1.11 christos 2377 1.11 christos switch (encoding.qualifier_index) 2378 1.11 christos { 2379 1.11 christos case 4: 2380 1.11 christos return tdep->sme_tile_type_q; 2381 1.11 christos case 3: 2382 1.11 christos return tdep->sme_tile_type_d; 2383 1.11 christos case 2: 2384 1.11 christos return tdep->sme_tile_type_s; 2385 1.11 christos case 1: 2386 1.11 christos return tdep->sme_tile_type_h; 2387 1.11 christos case 0: 2388 1.11 christos return tdep->sme_tile_type_b; 2389 1.11 christos default: 2390 1.11 christos error (_("Invalid qualifier index %s for ZA tile pseudo register."), 2391 1.11 christos pulongest (encoding.qualifier_index)); 2392 1.11 christos } 2393 1.11 christos 2394 1.11 christos gdb_assert_not_reached ("unknown qualifier for tile pseudo-register"); 2395 1.11 christos } 2396 1.11 christos 2397 1.8 christos /* Return the type for an AdvSISD V register. */ 2398 1.8 christos 2399 1.8 christos static struct type * 2400 1.8 christos aarch64_vnv_type (struct gdbarch *gdbarch) 2401 1.8 christos { 2402 1.10 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 2403 1.8 christos 2404 1.8 christos if (tdep->vnv_type == NULL) 2405 1.8 christos { 2406 1.9 christos /* The other AArch64 pseudo registers (Q,D,H,S,B) refer to a single value 2407 1.9 christos slice from the non-pseudo vector registers. However NEON V registers 2408 1.9 christos are always vector registers, and need constructing as such. */ 2409 1.9 christos const struct builtin_type *bt = builtin_type (gdbarch); 2410 1.9 christos 2411 1.8 christos struct type *t = arch_composite_type (gdbarch, "__gdb_builtin_type_vnv", 2412 1.8 christos TYPE_CODE_UNION); 2413 1.8 christos 2414 1.9 christos struct type *sub = arch_composite_type (gdbarch, "__gdb_builtin_type_vnd", 2415 1.9 christos TYPE_CODE_UNION); 2416 1.9 christos append_composite_type_field (sub, "f", 2417 1.9 christos init_vector_type (bt->builtin_double, 2)); 2418 1.9 christos append_composite_type_field (sub, "u", 2419 1.9 christos init_vector_type (bt->builtin_uint64, 2)); 2420 1.9 christos append_composite_type_field (sub, "s", 2421 1.9 christos init_vector_type (bt->builtin_int64, 2)); 2422 1.9 christos append_composite_type_field (t, "d", sub); 2423 1.9 christos 2424 1.9 christos sub = arch_composite_type (gdbarch, "__gdb_builtin_type_vns", 2425 1.9 christos TYPE_CODE_UNION); 2426 1.9 christos append_composite_type_field (sub, "f", 2427 1.9 christos init_vector_type (bt->builtin_float, 4)); 2428 1.9 christos append_composite_type_field (sub, "u", 2429 1.9 christos init_vector_type (bt->builtin_uint32, 4)); 2430 1.9 christos append_composite_type_field (sub, "s", 2431 1.9 christos init_vector_type (bt->builtin_int32, 4)); 2432 1.9 christos append_composite_type_field (t, "s", sub); 2433 1.9 christos 2434 1.9 christos sub = arch_composite_type (gdbarch, "__gdb_builtin_type_vnh", 2435 1.9 christos TYPE_CODE_UNION); 2436 1.10 christos append_composite_type_field (sub, "bf", 2437 1.10 christos init_vector_type (bt->builtin_bfloat16, 8)); 2438 1.9 christos append_composite_type_field (sub, "f", 2439 1.9 christos init_vector_type (bt->builtin_half, 8)); 2440 1.9 christos append_composite_type_field (sub, "u", 2441 1.9 christos init_vector_type (bt->builtin_uint16, 8)); 2442 1.9 christos append_composite_type_field (sub, "s", 2443 1.9 christos init_vector_type (bt->builtin_int16, 8)); 2444 1.9 christos append_composite_type_field (t, "h", sub); 2445 1.9 christos 2446 1.9 christos sub = arch_composite_type (gdbarch, "__gdb_builtin_type_vnb", 2447 1.9 christos TYPE_CODE_UNION); 2448 1.9 christos append_composite_type_field (sub, "u", 2449 1.9 christos init_vector_type (bt->builtin_uint8, 16)); 2450 1.9 christos append_composite_type_field (sub, "s", 2451 1.9 christos init_vector_type (bt->builtin_int8, 16)); 2452 1.9 christos append_composite_type_field (t, "b", sub); 2453 1.9 christos 2454 1.9 christos sub = arch_composite_type (gdbarch, "__gdb_builtin_type_vnq", 2455 1.9 christos TYPE_CODE_UNION); 2456 1.9 christos append_composite_type_field (sub, "u", 2457 1.9 christos init_vector_type (bt->builtin_uint128, 1)); 2458 1.9 christos append_composite_type_field (sub, "s", 2459 1.9 christos init_vector_type (bt->builtin_int128, 1)); 2460 1.9 christos append_composite_type_field (t, "q", sub); 2461 1.8 christos 2462 1.8 christos tdep->vnv_type = t; 2463 1.8 christos } 2464 1.8 christos 2465 1.8 christos return tdep->vnv_type; 2466 1.8 christos } 2467 1.8 christos 2468 1.1 christos /* Implement the "dwarf2_reg_to_regnum" gdbarch method. */ 2469 1.1 christos 2470 1.1 christos static int 2471 1.1 christos aarch64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) 2472 1.1 christos { 2473 1.10 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 2474 1.9 christos 2475 1.1 christos if (reg >= AARCH64_DWARF_X0 && reg <= AARCH64_DWARF_X0 + 30) 2476 1.1 christos return AARCH64_X0_REGNUM + reg - AARCH64_DWARF_X0; 2477 1.1 christos 2478 1.1 christos if (reg == AARCH64_DWARF_SP) 2479 1.1 christos return AARCH64_SP_REGNUM; 2480 1.1 christos 2481 1.10 christos if (reg == AARCH64_DWARF_PC) 2482 1.10 christos return AARCH64_PC_REGNUM; 2483 1.10 christos 2484 1.1 christos if (reg >= AARCH64_DWARF_V0 && reg <= AARCH64_DWARF_V0 + 31) 2485 1.1 christos return AARCH64_V0_REGNUM + reg - AARCH64_DWARF_V0; 2486 1.1 christos 2487 1.8 christos if (reg == AARCH64_DWARF_SVE_VG) 2488 1.8 christos return AARCH64_SVE_VG_REGNUM; 2489 1.8 christos 2490 1.8 christos if (reg == AARCH64_DWARF_SVE_FFR) 2491 1.8 christos return AARCH64_SVE_FFR_REGNUM; 2492 1.8 christos 2493 1.8 christos if (reg >= AARCH64_DWARF_SVE_P0 && reg <= AARCH64_DWARF_SVE_P0 + 15) 2494 1.8 christos return AARCH64_SVE_P0_REGNUM + reg - AARCH64_DWARF_SVE_P0; 2495 1.8 christos 2496 1.8 christos if (reg >= AARCH64_DWARF_SVE_Z0 && reg <= AARCH64_DWARF_SVE_Z0 + 15) 2497 1.8 christos return AARCH64_SVE_Z0_REGNUM + reg - AARCH64_DWARF_SVE_Z0; 2498 1.8 christos 2499 1.9 christos if (tdep->has_pauth ()) 2500 1.9 christos { 2501 1.10 christos if (reg == AARCH64_DWARF_RA_SIGN_STATE) 2502 1.10 christos return tdep->ra_sign_state_regnum; 2503 1.9 christos } 2504 1.9 christos 2505 1.1 christos return -1; 2506 1.1 christos } 2507 1.1 christos 2508 1.1 christos /* Implement the "print_insn" gdbarch method. */ 2509 1.1 christos 2510 1.1 christos static int 2511 1.1 christos aarch64_gdb_print_insn (bfd_vma memaddr, disassemble_info *info) 2512 1.1 christos { 2513 1.1 christos info->symbols = NULL; 2514 1.8 christos return default_print_insn (memaddr, info); 2515 1.1 christos } 2516 1.1 christos 2517 1.1 christos /* AArch64 BRK software debug mode instruction. 2518 1.1 christos Note that AArch64 code is always little-endian. 2519 1.1 christos 1101.0100.0010.0000.0000.0000.0000.0000 = 0xd4200000. */ 2520 1.7 christos constexpr gdb_byte aarch64_default_breakpoint[] = {0x00, 0x00, 0x20, 0xd4}; 2521 1.1 christos 2522 1.7 christos typedef BP_MANIPULATION (aarch64_default_breakpoint) aarch64_breakpoint; 2523 1.1 christos 2524 1.1 christos /* Extract from an array REGS containing the (raw) register state a 2525 1.1 christos function return value of type TYPE, and copy that, in virtual 2526 1.1 christos format, into VALBUF. */ 2527 1.1 christos 2528 1.1 christos static void 2529 1.1 christos aarch64_extract_return_value (struct type *type, struct regcache *regs, 2530 1.1 christos gdb_byte *valbuf) 2531 1.1 christos { 2532 1.8 christos struct gdbarch *gdbarch = regs->arch (); 2533 1.1 christos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 2534 1.8 christos int elements; 2535 1.8 christos struct type *fundamental_type; 2536 1.1 christos 2537 1.8 christos if (aapcs_is_vfp_call_or_return_candidate (type, &elements, 2538 1.8 christos &fundamental_type)) 2539 1.1 christos { 2540 1.10 christos int len = fundamental_type->length (); 2541 1.8 christos 2542 1.8 christos for (int i = 0; i < elements; i++) 2543 1.8 christos { 2544 1.8 christos int regno = AARCH64_V0_REGNUM + i; 2545 1.8 christos /* Enough space for a full vector register. */ 2546 1.12 christos gdb::byte_vector buf (register_size (gdbarch, regno)); 2547 1.12 christos gdb_assert (len <= buf.size ()); 2548 1.8 christos 2549 1.10 christos aarch64_debug_printf 2550 1.10 christos ("read HFA or HVA return value element %d from %s", 2551 1.10 christos i + 1, gdbarch_register_name (gdbarch, regno)); 2552 1.10 christos 2553 1.8 christos regs->cooked_read (regno, buf); 2554 1.1 christos 2555 1.12 christos memcpy (valbuf, buf.data (), len); 2556 1.8 christos valbuf += len; 2557 1.8 christos } 2558 1.1 christos } 2559 1.9 christos else if (type->code () == TYPE_CODE_INT 2560 1.9 christos || type->code () == TYPE_CODE_CHAR 2561 1.9 christos || type->code () == TYPE_CODE_BOOL 2562 1.9 christos || type->code () == TYPE_CODE_PTR 2563 1.7 christos || TYPE_IS_REFERENCE (type) 2564 1.9 christos || type->code () == TYPE_CODE_ENUM) 2565 1.1 christos { 2566 1.8 christos /* If the type is a plain integer, then the access is 2567 1.1 christos straight-forward. Otherwise we have to play around a bit 2568 1.1 christos more. */ 2569 1.10 christos int len = type->length (); 2570 1.1 christos int regno = AARCH64_X0_REGNUM; 2571 1.1 christos ULONGEST tmp; 2572 1.1 christos 2573 1.1 christos while (len > 0) 2574 1.1 christos { 2575 1.1 christos /* By using store_unsigned_integer we avoid having to do 2576 1.1 christos anything special for small big-endian values. */ 2577 1.1 christos regcache_cooked_read_unsigned (regs, regno++, &tmp); 2578 1.1 christos store_unsigned_integer (valbuf, 2579 1.1 christos (len > X_REGISTER_SIZE 2580 1.1 christos ? X_REGISTER_SIZE : len), byte_order, tmp); 2581 1.1 christos len -= X_REGISTER_SIZE; 2582 1.1 christos valbuf += X_REGISTER_SIZE; 2583 1.1 christos } 2584 1.1 christos } 2585 1.1 christos else 2586 1.1 christos { 2587 1.12 christos /* For a structure or union the behavior is as if the value had 2588 1.10 christos been stored to word-aligned memory and then loaded into 2589 1.10 christos registers with 64-bit load instruction(s). */ 2590 1.10 christos int len = type->length (); 2591 1.1 christos int regno = AARCH64_X0_REGNUM; 2592 1.1 christos bfd_byte buf[X_REGISTER_SIZE]; 2593 1.1 christos 2594 1.1 christos while (len > 0) 2595 1.1 christos { 2596 1.8 christos regs->cooked_read (regno++, buf); 2597 1.1 christos memcpy (valbuf, buf, len > X_REGISTER_SIZE ? X_REGISTER_SIZE : len); 2598 1.1 christos len -= X_REGISTER_SIZE; 2599 1.1 christos valbuf += X_REGISTER_SIZE; 2600 1.1 christos } 2601 1.1 christos } 2602 1.1 christos } 2603 1.1 christos 2604 1.1 christos 2605 1.1 christos /* Will a function return an aggregate type in memory or in a 2606 1.1 christos register? Return 0 if an aggregate type can be returned in a 2607 1.1 christos register, 1 if it must be returned in memory. */ 2608 1.1 christos 2609 1.1 christos static int 2610 1.1 christos aarch64_return_in_memory (struct gdbarch *gdbarch, struct type *type) 2611 1.1 christos { 2612 1.6 christos type = check_typedef (type); 2613 1.8 christos int elements; 2614 1.8 christos struct type *fundamental_type; 2615 1.1 christos 2616 1.11 christos if (TYPE_HAS_DYNAMIC_LENGTH (type)) 2617 1.11 christos return 1; 2618 1.11 christos 2619 1.8 christos if (aapcs_is_vfp_call_or_return_candidate (type, &elements, 2620 1.8 christos &fundamental_type)) 2621 1.1 christos { 2622 1.6 christos /* v0-v7 are used to return values and one register is allocated 2623 1.6 christos for one member. However, HFA or HVA has at most four members. */ 2624 1.1 christos return 0; 2625 1.1 christos } 2626 1.1 christos 2627 1.10 christos if (type->length () > 16 2628 1.10 christos || !language_pass_by_reference (type).trivially_copyable) 2629 1.1 christos { 2630 1.1 christos /* PCS B.6 Aggregates larger than 16 bytes are passed by 2631 1.10 christos invisible reference. */ 2632 1.1 christos 2633 1.1 christos return 1; 2634 1.1 christos } 2635 1.1 christos 2636 1.1 christos return 0; 2637 1.1 christos } 2638 1.1 christos 2639 1.1 christos /* Write into appropriate registers a function return value of type 2640 1.1 christos TYPE, given in virtual format. */ 2641 1.1 christos 2642 1.1 christos static void 2643 1.1 christos aarch64_store_return_value (struct type *type, struct regcache *regs, 2644 1.1 christos const gdb_byte *valbuf) 2645 1.1 christos { 2646 1.8 christos struct gdbarch *gdbarch = regs->arch (); 2647 1.1 christos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 2648 1.8 christos int elements; 2649 1.8 christos struct type *fundamental_type; 2650 1.1 christos 2651 1.8 christos if (aapcs_is_vfp_call_or_return_candidate (type, &elements, 2652 1.8 christos &fundamental_type)) 2653 1.1 christos { 2654 1.10 christos int len = fundamental_type->length (); 2655 1.8 christos 2656 1.8 christos for (int i = 0; i < elements; i++) 2657 1.8 christos { 2658 1.8 christos int regno = AARCH64_V0_REGNUM + i; 2659 1.8 christos /* Enough space for a full vector register. */ 2660 1.12 christos gdb::byte_vector tmpbuf (register_size (gdbarch, regno)); 2661 1.12 christos gdb_assert (len <= tmpbuf.size ()); 2662 1.8 christos 2663 1.10 christos aarch64_debug_printf 2664 1.10 christos ("write HFA or HVA return value element %d to %s", 2665 1.10 christos i + 1, gdbarch_register_name (gdbarch, regno)); 2666 1.1 christos 2667 1.11 christos /* Depending on whether the target supports SVE or not, the V 2668 1.11 christos registers may report a size > 16 bytes. In that case, read the 2669 1.11 christos original contents of the register before overriding it with a new 2670 1.11 christos value that has a potential size <= 16 bytes. */ 2671 1.11 christos regs->cooked_read (regno, tmpbuf); 2672 1.12 christos memcpy (tmpbuf.data (), valbuf, 2673 1.8 christos len > V_REGISTER_SIZE ? V_REGISTER_SIZE : len); 2674 1.8 christos regs->cooked_write (regno, tmpbuf); 2675 1.8 christos valbuf += len; 2676 1.8 christos } 2677 1.1 christos } 2678 1.9 christos else if (type->code () == TYPE_CODE_INT 2679 1.9 christos || type->code () == TYPE_CODE_CHAR 2680 1.9 christos || type->code () == TYPE_CODE_BOOL 2681 1.9 christos || type->code () == TYPE_CODE_PTR 2682 1.7 christos || TYPE_IS_REFERENCE (type) 2683 1.9 christos || type->code () == TYPE_CODE_ENUM) 2684 1.1 christos { 2685 1.10 christos if (type->length () <= X_REGISTER_SIZE) 2686 1.1 christos { 2687 1.1 christos /* Values of one word or less are zero/sign-extended and 2688 1.1 christos returned in r0. */ 2689 1.1 christos bfd_byte tmpbuf[X_REGISTER_SIZE]; 2690 1.1 christos LONGEST val = unpack_long (type, valbuf); 2691 1.1 christos 2692 1.1 christos store_signed_integer (tmpbuf, X_REGISTER_SIZE, byte_order, val); 2693 1.8 christos regs->cooked_write (AARCH64_X0_REGNUM, tmpbuf); 2694 1.1 christos } 2695 1.1 christos else 2696 1.1 christos { 2697 1.1 christos /* Integral values greater than one word are stored in 2698 1.1 christos consecutive registers starting with r0. This will always 2699 1.1 christos be a multiple of the regiser size. */ 2700 1.10 christos int len = type->length (); 2701 1.1 christos int regno = AARCH64_X0_REGNUM; 2702 1.1 christos 2703 1.1 christos while (len > 0) 2704 1.1 christos { 2705 1.8 christos regs->cooked_write (regno++, valbuf); 2706 1.1 christos len -= X_REGISTER_SIZE; 2707 1.1 christos valbuf += X_REGISTER_SIZE; 2708 1.1 christos } 2709 1.1 christos } 2710 1.1 christos } 2711 1.1 christos else 2712 1.1 christos { 2713 1.12 christos /* For a structure or union the behavior is as if the value had 2714 1.1 christos been stored to word-aligned memory and then loaded into 2715 1.1 christos registers with 64-bit load instruction(s). */ 2716 1.10 christos int len = type->length (); 2717 1.1 christos int regno = AARCH64_X0_REGNUM; 2718 1.1 christos bfd_byte tmpbuf[X_REGISTER_SIZE]; 2719 1.1 christos 2720 1.1 christos while (len > 0) 2721 1.1 christos { 2722 1.1 christos memcpy (tmpbuf, valbuf, 2723 1.1 christos len > X_REGISTER_SIZE ? X_REGISTER_SIZE : len); 2724 1.8 christos regs->cooked_write (regno++, tmpbuf); 2725 1.1 christos len -= X_REGISTER_SIZE; 2726 1.1 christos valbuf += X_REGISTER_SIZE; 2727 1.1 christos } 2728 1.1 christos } 2729 1.1 christos } 2730 1.1 christos 2731 1.1 christos /* Implement the "return_value" gdbarch method. */ 2732 1.1 christos 2733 1.1 christos static enum return_value_convention 2734 1.1 christos aarch64_return_value (struct gdbarch *gdbarch, struct value *func_value, 2735 1.1 christos struct type *valtype, struct regcache *regcache, 2736 1.11 christos struct value **read_value, const gdb_byte *writebuf) 2737 1.1 christos { 2738 1.9 christos if (valtype->code () == TYPE_CODE_STRUCT 2739 1.9 christos || valtype->code () == TYPE_CODE_UNION 2740 1.9 christos || valtype->code () == TYPE_CODE_ARRAY) 2741 1.1 christos { 2742 1.1 christos if (aarch64_return_in_memory (gdbarch, valtype)) 2743 1.1 christos { 2744 1.10 christos /* From the AAPCS64's Result Return section: 2745 1.10 christos 2746 1.10 christos "Otherwise, the caller shall reserve a block of memory of 2747 1.10 christos sufficient size and alignment to hold the result. The address 2748 1.10 christos of the memory block shall be passed as an additional argument to 2749 1.10 christos the function in x8. */ 2750 1.10 christos 2751 1.10 christos aarch64_debug_printf ("return value in memory"); 2752 1.10 christos 2753 1.11 christos if (read_value != nullptr) 2754 1.10 christos { 2755 1.10 christos CORE_ADDR addr; 2756 1.10 christos 2757 1.10 christos regcache->cooked_read (AARCH64_STRUCT_RETURN_REGNUM, &addr); 2758 1.11 christos *read_value = value_at_non_lval (valtype, addr); 2759 1.10 christos } 2760 1.10 christos 2761 1.10 christos return RETURN_VALUE_ABI_RETURNS_ADDRESS; 2762 1.1 christos } 2763 1.1 christos } 2764 1.1 christos 2765 1.1 christos if (writebuf) 2766 1.1 christos aarch64_store_return_value (valtype, regcache, writebuf); 2767 1.1 christos 2768 1.11 christos if (read_value) 2769 1.11 christos { 2770 1.11 christos *read_value = value::allocate (valtype); 2771 1.11 christos aarch64_extract_return_value (valtype, regcache, 2772 1.11 christos (*read_value)->contents_raw ().data ()); 2773 1.11 christos } 2774 1.1 christos 2775 1.10 christos aarch64_debug_printf ("return value in registers"); 2776 1.1 christos 2777 1.1 christos return RETURN_VALUE_REGISTER_CONVENTION; 2778 1.1 christos } 2779 1.1 christos 2780 1.1 christos /* Implement the "get_longjmp_target" gdbarch method. */ 2781 1.1 christos 2782 1.1 christos static int 2783 1.11 christos aarch64_get_longjmp_target (const frame_info_ptr &frame, CORE_ADDR *pc) 2784 1.1 christos { 2785 1.1 christos CORE_ADDR jb_addr; 2786 1.1 christos gdb_byte buf[X_REGISTER_SIZE]; 2787 1.1 christos struct gdbarch *gdbarch = get_frame_arch (frame); 2788 1.10 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 2789 1.1 christos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 2790 1.1 christos 2791 1.1 christos jb_addr = get_frame_register_unsigned (frame, AARCH64_X0_REGNUM); 2792 1.1 christos 2793 1.1 christos if (target_read_memory (jb_addr + tdep->jb_pc * tdep->jb_elt_size, buf, 2794 1.1 christos X_REGISTER_SIZE)) 2795 1.1 christos return 0; 2796 1.1 christos 2797 1.1 christos *pc = extract_unsigned_integer (buf, X_REGISTER_SIZE, byte_order); 2798 1.1 christos return 1; 2799 1.1 christos } 2800 1.6 christos 2801 1.6 christos /* Implement the "gen_return_address" gdbarch method. */ 2802 1.6 christos 2803 1.6 christos static void 2804 1.6 christos aarch64_gen_return_address (struct gdbarch *gdbarch, 2805 1.6 christos struct agent_expr *ax, struct axs_value *value, 2806 1.6 christos CORE_ADDR scope) 2807 1.6 christos { 2808 1.6 christos value->type = register_type (gdbarch, AARCH64_LR_REGNUM); 2809 1.6 christos value->kind = axs_lvalue_register; 2810 1.6 christos value->u.reg = AARCH64_LR_REGNUM; 2811 1.6 christos } 2812 1.1 christos 2813 1.1 christos 2815 1.10 christos /* Return TRUE if REGNUM is a W pseudo-register number. Return FALSE 2816 1.10 christos otherwise. */ 2817 1.10 christos 2818 1.10 christos static bool 2819 1.10 christos is_w_pseudo_register (struct gdbarch *gdbarch, int regnum) 2820 1.10 christos { 2821 1.10 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 2822 1.10 christos 2823 1.10 christos if (tdep->w_pseudo_base <= regnum 2824 1.10 christos && regnum < tdep->w_pseudo_base + tdep->w_pseudo_count) 2825 1.10 christos return true; 2826 1.10 christos 2827 1.10 christos return false; 2828 1.10 christos } 2829 1.11 christos 2830 1.11 christos /* Return TRUE if REGNUM is a SME pseudo-register number. Return FALSE 2831 1.11 christos otherwise. */ 2832 1.11 christos 2833 1.11 christos static bool 2834 1.11 christos is_sme_pseudo_register (struct gdbarch *gdbarch, int regnum) 2835 1.11 christos { 2836 1.11 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 2837 1.11 christos 2838 1.11 christos if (tdep->has_sme () && tdep->sme_pseudo_base <= regnum 2839 1.11 christos && regnum < tdep->sme_pseudo_base + tdep->sme_pseudo_count) 2840 1.11 christos return true; 2841 1.11 christos 2842 1.11 christos return false; 2843 1.11 christos } 2844 1.11 christos 2845 1.11 christos /* Convert ENCODING into a ZA tile slice name. */ 2846 1.11 christos 2847 1.11 christos static const std::string 2848 1.11 christos aarch64_za_tile_slice_name (const struct za_pseudo_encoding &encoding) 2849 1.11 christos { 2850 1.11 christos gdb_assert (encoding.qualifier_index >= 0); 2851 1.11 christos gdb_assert (encoding.qualifier_index <= 4); 2852 1.11 christos gdb_assert (encoding.tile_index >= 0); 2853 1.11 christos gdb_assert (encoding.tile_index <= 15); 2854 1.11 christos gdb_assert (encoding.slice_index >= 0); 2855 1.11 christos gdb_assert (encoding.slice_index <= 255); 2856 1.11 christos 2857 1.11 christos const char orientation = encoding.horizontal ? 'h' : 'v'; 2858 1.11 christos 2859 1.11 christos const char qualifiers[6] = "bhsdq"; 2860 1.11 christos const char qualifier = qualifiers [encoding.qualifier_index]; 2861 1.11 christos return string_printf ("za%d%c%c%d", encoding.tile_index, orientation, 2862 1.11 christos qualifier, encoding.slice_index); 2863 1.11 christos } 2864 1.11 christos 2865 1.11 christos /* Convert ENCODING into a ZA tile name. */ 2866 1.11 christos 2867 1.11 christos static const std::string 2868 1.11 christos aarch64_za_tile_name (const struct za_pseudo_encoding &encoding) 2869 1.11 christos { 2870 1.11 christos /* Tiles don't use the slice number and the direction fields. */ 2871 1.11 christos gdb_assert (encoding.qualifier_index >= 0); 2872 1.11 christos gdb_assert (encoding.qualifier_index <= 4); 2873 1.11 christos gdb_assert (encoding.tile_index >= 0); 2874 1.11 christos gdb_assert (encoding.tile_index <= 15); 2875 1.11 christos 2876 1.11 christos const char qualifiers[6] = "bhsdq"; 2877 1.11 christos const char qualifier = qualifiers [encoding.qualifier_index]; 2878 1.11 christos return (string_printf ("za%d%c", encoding.tile_index, qualifier)); 2879 1.11 christos } 2880 1.11 christos 2881 1.11 christos /* Given a SME pseudo-register REGNUM, return its type. */ 2882 1.11 christos 2883 1.11 christos static struct type * 2884 1.11 christos aarch64_sme_pseudo_register_type (struct gdbarch *gdbarch, int regnum) 2885 1.11 christos { 2886 1.11 christos struct za_pseudo_encoding encoding; 2887 1.11 christos 2888 1.11 christos /* Decode the SME pseudo-register number. */ 2889 1.11 christos aarch64_za_decode_pseudos (gdbarch, regnum, encoding); 2890 1.11 christos 2891 1.11 christos if (is_sme_tile_slice_pseudo_register (gdbarch, regnum)) 2892 1.11 christos return aarch64_za_tile_slice_type (gdbarch, encoding); 2893 1.11 christos else 2894 1.11 christos return aarch64_za_tile_type (gdbarch, encoding); 2895 1.11 christos } 2896 1.1 christos 2897 1.1 christos /* Return the pseudo register name corresponding to register regnum. */ 2898 1.1 christos 2899 1.1 christos static const char * 2900 1.1 christos aarch64_pseudo_register_name (struct gdbarch *gdbarch, int regnum) 2901 1.10 christos { 2902 1.10 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 2903 1.10 christos 2904 1.10 christos /* W pseudo-registers. Bottom halves of the X registers. */ 2905 1.10 christos static const char *const w_name[] = 2906 1.10 christos { 2907 1.10 christos "w0", "w1", "w2", "w3", 2908 1.10 christos "w4", "w5", "w6", "w7", 2909 1.10 christos "w8", "w9", "w10", "w11", 2910 1.10 christos "w12", "w13", "w14", "w15", 2911 1.10 christos "w16", "w17", "w18", "w19", 2912 1.10 christos "w20", "w21", "w22", "w23", 2913 1.10 christos "w24", "w25", "w26", "w27", 2914 1.10 christos "w28", "w29", "w30", 2915 1.8 christos }; 2916 1.1 christos 2917 1.1 christos static const char *const q_name[] = 2918 1.1 christos { 2919 1.1 christos "q0", "q1", "q2", "q3", 2920 1.1 christos "q4", "q5", "q6", "q7", 2921 1.1 christos "q8", "q9", "q10", "q11", 2922 1.1 christos "q12", "q13", "q14", "q15", 2923 1.1 christos "q16", "q17", "q18", "q19", 2924 1.1 christos "q20", "q21", "q22", "q23", 2925 1.1 christos "q24", "q25", "q26", "q27", 2926 1.1 christos "q28", "q29", "q30", "q31", 2927 1.1 christos }; 2928 1.1 christos 2929 1.1 christos static const char *const d_name[] = 2930 1.1 christos { 2931 1.1 christos "d0", "d1", "d2", "d3", 2932 1.1 christos "d4", "d5", "d6", "d7", 2933 1.1 christos "d8", "d9", "d10", "d11", 2934 1.1 christos "d12", "d13", "d14", "d15", 2935 1.1 christos "d16", "d17", "d18", "d19", 2936 1.1 christos "d20", "d21", "d22", "d23", 2937 1.1 christos "d24", "d25", "d26", "d27", 2938 1.1 christos "d28", "d29", "d30", "d31", 2939 1.1 christos }; 2940 1.1 christos 2941 1.1 christos static const char *const s_name[] = 2942 1.1 christos { 2943 1.1 christos "s0", "s1", "s2", "s3", 2944 1.1 christos "s4", "s5", "s6", "s7", 2945 1.1 christos "s8", "s9", "s10", "s11", 2946 1.1 christos "s12", "s13", "s14", "s15", 2947 1.1 christos "s16", "s17", "s18", "s19", 2948 1.1 christos "s20", "s21", "s22", "s23", 2949 1.1 christos "s24", "s25", "s26", "s27", 2950 1.1 christos "s28", "s29", "s30", "s31", 2951 1.1 christos }; 2952 1.1 christos 2953 1.1 christos static const char *const h_name[] = 2954 1.1 christos { 2955 1.1 christos "h0", "h1", "h2", "h3", 2956 1.1 christos "h4", "h5", "h6", "h7", 2957 1.1 christos "h8", "h9", "h10", "h11", 2958 1.1 christos "h12", "h13", "h14", "h15", 2959 1.1 christos "h16", "h17", "h18", "h19", 2960 1.1 christos "h20", "h21", "h22", "h23", 2961 1.1 christos "h24", "h25", "h26", "h27", 2962 1.1 christos "h28", "h29", "h30", "h31", 2963 1.1 christos }; 2964 1.1 christos 2965 1.1 christos static const char *const b_name[] = 2966 1.1 christos { 2967 1.1 christos "b0", "b1", "b2", "b3", 2968 1.1 christos "b4", "b5", "b6", "b7", 2969 1.1 christos "b8", "b9", "b10", "b11", 2970 1.1 christos "b12", "b13", "b14", "b15", 2971 1.1 christos "b16", "b17", "b18", "b19", 2972 1.1 christos "b20", "b21", "b22", "b23", 2973 1.1 christos "b24", "b25", "b26", "b27", 2974 1.1 christos "b28", "b29", "b30", "b31", 2975 1.1 christos }; 2976 1.9 christos 2977 1.1 christos int p_regnum = regnum - gdbarch_num_regs (gdbarch); 2978 1.9 christos 2979 1.9 christos if (p_regnum >= AARCH64_Q0_REGNUM && p_regnum < AARCH64_Q0_REGNUM + 32) 2980 1.1 christos return q_name[p_regnum - AARCH64_Q0_REGNUM]; 2981 1.9 christos 2982 1.9 christos if (p_regnum >= AARCH64_D0_REGNUM && p_regnum < AARCH64_D0_REGNUM + 32) 2983 1.1 christos return d_name[p_regnum - AARCH64_D0_REGNUM]; 2984 1.9 christos 2985 1.9 christos if (p_regnum >= AARCH64_S0_REGNUM && p_regnum < AARCH64_S0_REGNUM + 32) 2986 1.1 christos return s_name[p_regnum - AARCH64_S0_REGNUM]; 2987 1.9 christos 2988 1.9 christos if (p_regnum >= AARCH64_H0_REGNUM && p_regnum < AARCH64_H0_REGNUM + 32) 2989 1.1 christos return h_name[p_regnum - AARCH64_H0_REGNUM]; 2990 1.9 christos 2991 1.9 christos if (p_regnum >= AARCH64_B0_REGNUM && p_regnum < AARCH64_B0_REGNUM + 32) 2992 1.1 christos return b_name[p_regnum - AARCH64_B0_REGNUM]; 2993 1.10 christos 2994 1.10 christos /* W pseudo-registers? */ 2995 1.10 christos if (is_w_pseudo_register (gdbarch, regnum)) 2996 1.10 christos return w_name[regnum - tdep->w_pseudo_base]; 2997 1.8 christos 2998 1.8 christos if (tdep->has_sve ()) 2999 1.8 christos { 3000 1.8 christos static const char *const sve_v_name[] = 3001 1.8 christos { 3002 1.8 christos "v0", "v1", "v2", "v3", 3003 1.8 christos "v4", "v5", "v6", "v7", 3004 1.8 christos "v8", "v9", "v10", "v11", 3005 1.8 christos "v12", "v13", "v14", "v15", 3006 1.8 christos "v16", "v17", "v18", "v19", 3007 1.8 christos "v20", "v21", "v22", "v23", 3008 1.8 christos "v24", "v25", "v26", "v27", 3009 1.8 christos "v28", "v29", "v30", "v31", 3010 1.8 christos }; 3011 1.9 christos 3012 1.9 christos if (p_regnum >= AARCH64_SVE_V0_REGNUM 3013 1.9 christos && p_regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM) 3014 1.8 christos return sve_v_name[p_regnum - AARCH64_SVE_V0_REGNUM]; 3015 1.8 christos } 3016 1.11 christos 3017 1.11 christos if (is_sme_pseudo_register (gdbarch, regnum)) 3018 1.11 christos return tdep->sme_pseudo_names[regnum - tdep->sme_pseudo_base].c_str (); 3019 1.9 christos 3020 1.9 christos /* RA_STATE is used for unwinding only. Do not assign it a name - this 3021 1.9 christos prevents it from being read by methods such as 3022 1.10 christos mi_cmd_trace_frame_collected. */ 3023 1.9 christos if (tdep->has_pauth () && regnum == tdep->ra_sign_state_regnum) 3024 1.9 christos return ""; 3025 1.10 christos 3026 1.9 christos internal_error (_("aarch64_pseudo_register_name: bad register number %d"), 3027 1.1 christos p_regnum); 3028 1.1 christos } 3029 1.1 christos 3030 1.1 christos /* Implement the "pseudo_register_type" tdesc_arch_data method. */ 3031 1.1 christos 3032 1.1 christos static struct type * 3033 1.1 christos aarch64_pseudo_register_type (struct gdbarch *gdbarch, int regnum) 3034 1.10 christos { 3035 1.8 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 3036 1.9 christos 3037 1.1 christos int p_regnum = regnum - gdbarch_num_regs (gdbarch); 3038 1.9 christos 3039 1.1 christos if (p_regnum >= AARCH64_Q0_REGNUM && p_regnum < AARCH64_Q0_REGNUM + 32) 3040 1.1 christos return aarch64_vnq_type (gdbarch); 3041 1.9 christos 3042 1.1 christos if (p_regnum >= AARCH64_D0_REGNUM && p_regnum < AARCH64_D0_REGNUM + 32) 3043 1.1 christos return aarch64_vnd_type (gdbarch); 3044 1.9 christos 3045 1.1 christos if (p_regnum >= AARCH64_S0_REGNUM && p_regnum < AARCH64_S0_REGNUM + 32) 3046 1.1 christos return aarch64_vns_type (gdbarch); 3047 1.9 christos 3048 1.1 christos if (p_regnum >= AARCH64_H0_REGNUM && p_regnum < AARCH64_H0_REGNUM + 32) 3049 1.1 christos return aarch64_vnh_type (gdbarch); 3050 1.9 christos 3051 1.1 christos if (p_regnum >= AARCH64_B0_REGNUM && p_regnum < AARCH64_B0_REGNUM + 32) 3052 1.1 christos return aarch64_vnb_type (gdbarch); 3053 1.9 christos 3054 1.9 christos if (tdep->has_sve () && p_regnum >= AARCH64_SVE_V0_REGNUM 3055 1.8 christos && p_regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM) 3056 1.8 christos return aarch64_vnv_type (gdbarch); 3057 1.10 christos 3058 1.10 christos /* W pseudo-registers are 32-bit. */ 3059 1.10 christos if (is_w_pseudo_register (gdbarch, regnum)) 3060 1.10 christos return builtin_type (gdbarch)->builtin_uint32; 3061 1.11 christos 3062 1.11 christos if (is_sme_pseudo_register (gdbarch, regnum)) 3063 1.11 christos return aarch64_sme_pseudo_register_type (gdbarch, regnum); 3064 1.10 christos 3065 1.9 christos if (tdep->has_pauth () && regnum == tdep->ra_sign_state_regnum) 3066 1.9 christos return builtin_type (gdbarch)->builtin_uint64; 3067 1.10 christos 3068 1.9 christos internal_error (_("aarch64_pseudo_register_type: bad register number %d"), 3069 1.1 christos p_regnum); 3070 1.1 christos } 3071 1.1 christos 3072 1.1 christos /* Implement the "pseudo_register_reggroup_p" tdesc_arch_data method. */ 3073 1.1 christos 3074 1.1 christos static int 3075 1.10 christos aarch64_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum, 3076 1.1 christos const struct reggroup *group) 3077 1.10 christos { 3078 1.8 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 3079 1.9 christos 3080 1.1 christos int p_regnum = regnum - gdbarch_num_regs (gdbarch); 3081 1.9 christos 3082 1.1 christos if (p_regnum >= AARCH64_Q0_REGNUM && p_regnum < AARCH64_Q0_REGNUM + 32) 3083 1.9 christos return group == all_reggroup || group == vector_reggroup; 3084 1.1 christos else if (p_regnum >= AARCH64_D0_REGNUM && p_regnum < AARCH64_D0_REGNUM + 32) 3085 1.1 christos return (group == all_reggroup || group == vector_reggroup 3086 1.9 christos || group == float_reggroup); 3087 1.1 christos else if (p_regnum >= AARCH64_S0_REGNUM && p_regnum < AARCH64_S0_REGNUM + 32) 3088 1.1 christos return (group == all_reggroup || group == vector_reggroup 3089 1.9 christos || group == float_reggroup); 3090 1.1 christos else if (p_regnum >= AARCH64_H0_REGNUM && p_regnum < AARCH64_H0_REGNUM + 32) 3091 1.9 christos return group == all_reggroup || group == vector_reggroup; 3092 1.1 christos else if (p_regnum >= AARCH64_B0_REGNUM && p_regnum < AARCH64_B0_REGNUM + 32) 3093 1.9 christos return group == all_reggroup || group == vector_reggroup; 3094 1.9 christos else if (tdep->has_sve () && p_regnum >= AARCH64_SVE_V0_REGNUM 3095 1.8 christos && p_regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM) 3096 1.11 christos return group == all_reggroup || group == vector_reggroup; 3097 1.11 christos else if (is_sme_pseudo_register (gdbarch, regnum)) 3098 1.9 christos return group == all_reggroup || group == vector_reggroup; 3099 1.10 christos /* RA_STATE is used for unwinding only. Do not assign it to any groups. */ 3100 1.9 christos if (tdep->has_pauth () && regnum == tdep->ra_sign_state_regnum) 3101 1.1 christos return 0; 3102 1.1 christos 3103 1.1 christos return group == all_reggroup; 3104 1.1 christos } 3105 1.8 christos 3106 1.8 christos /* Helper for aarch64_pseudo_read_value. */ 3107 1.11 christos 3108 1.11 christos static value * 3109 1.11 christos aarch64_pseudo_read_value_1 (const frame_info_ptr &next_frame, 3110 1.11 christos const int pseudo_reg_num, int raw_regnum_offset) 3111 1.11 christos { 3112 1.11 christos unsigned v_regnum = AARCH64_V0_REGNUM + raw_regnum_offset; 3113 1.11 christos 3114 1.11 christos return pseudo_from_raw_part (next_frame, pseudo_reg_num, v_regnum, 0); 3115 1.11 christos } 3116 1.11 christos 3117 1.11 christos /* Helper function for reading/writing ZA pseudo-registers. Given REGNUM, 3118 1.11 christos a ZA pseudo-register number, return the information on positioning of the 3119 1.11 christos bytes that must be read from/written to. */ 3120 1.11 christos 3121 1.11 christos static za_offsets 3122 1.8 christos aarch64_za_offsets_from_regnum (struct gdbarch *gdbarch, int regnum) 3123 1.11 christos { 3124 1.8 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 3125 1.11 christos 3126 1.11 christos gdb_assert (tdep->has_sme ()); 3127 1.11 christos gdb_assert (tdep->sme_svq > 0); 3128 1.11 christos gdb_assert (tdep->sme_pseudo_base <= regnum); 3129 1.11 christos gdb_assert (regnum < tdep->sme_pseudo_base + tdep->sme_pseudo_count); 3130 1.11 christos 3131 1.11 christos struct za_pseudo_encoding encoding; 3132 1.11 christos 3133 1.11 christos /* Decode the ZA pseudo-register number. */ 3134 1.11 christos aarch64_za_decode_pseudos (gdbarch, regnum, encoding); 3135 1.11 christos 3136 1.11 christos /* Fetch the streaming vector length. */ 3137 1.11 christos size_t svl = sve_vl_from_vq (tdep->sme_svq); 3138 1.11 christos za_offsets offsets; 3139 1.11 christos 3140 1.11 christos if (is_sme_tile_slice_pseudo_register (gdbarch, regnum)) 3141 1.11 christos { 3142 1.11 christos if (encoding.horizontal) 3143 1.11 christos { 3144 1.11 christos /* Horizontal tile slices are contiguous ranges of svl bytes. */ 3145 1.11 christos 3146 1.11 christos /* The starting offset depends on the tile index (to locate the tile 3147 1.11 christos in the ZA buffer), the slice index (to locate the slice within the 3148 1.11 christos tile) and the qualifier. */ 3149 1.11 christos offsets.starting_offset 3150 1.11 christos = encoding.tile_index * svl + encoding.slice_index 3151 1.11 christos * (svl >> encoding.qualifier_index); 3152 1.11 christos /* Horizontal tile slice data is contiguous and thus doesn't have 3153 1.11 christos a stride. */ 3154 1.11 christos offsets.stride_size = 0; 3155 1.11 christos /* Horizontal tile slice data is contiguous and thus only has 1 3156 1.11 christos chunk. */ 3157 1.11 christos offsets.chunks = 1; 3158 1.11 christos /* The chunk size is always svl bytes. */ 3159 1.11 christos offsets.chunk_size = svl; 3160 1.11 christos } 3161 1.11 christos else 3162 1.11 christos { 3163 1.11 christos /* Vertical tile slices are non-contiguous ranges of 3164 1.8 christos (1 << qualifier_index) bytes. */ 3165 1.11 christos 3166 1.11 christos /* The starting offset depends on the tile number (to locate the 3167 1.11 christos tile in the ZA buffer), the slice index (to locate the element 3168 1.11 christos within the tile slice) and the qualifier. */ 3169 1.11 christos offsets.starting_offset 3170 1.11 christos = encoding.tile_index * svl + encoding.slice_index 3171 1.11 christos * (1 << encoding.qualifier_index); 3172 1.11 christos /* The offset between vertical tile slices depends on the qualifier 3173 1.11 christos and svl. */ 3174 1.11 christos offsets.stride_size = svl << encoding.qualifier_index; 3175 1.11 christos /* The number of chunks depends on svl and the qualifier size. */ 3176 1.11 christos offsets.chunks = svl >> encoding.qualifier_index; 3177 1.11 christos /* The chunk size depends on the qualifier. */ 3178 1.11 christos offsets.chunk_size = 1 << encoding.qualifier_index; 3179 1.11 christos } 3180 1.8 christos } 3181 1.11 christos else 3182 1.11 christos { 3183 1.11 christos /* ZA tile pseudo-register. */ 3184 1.11 christos 3185 1.11 christos /* Starting offset depends on the tile index and qualifier. */ 3186 1.11 christos offsets.starting_offset = encoding.tile_index * svl; 3187 1.11 christos /* The offset between tile slices depends on the qualifier and svl. */ 3188 1.11 christos offsets.stride_size = svl << encoding.qualifier_index; 3189 1.11 christos /* The number of chunks depends on the qualifier and svl. */ 3190 1.11 christos offsets.chunks = svl >> encoding.qualifier_index; 3191 1.11 christos /* The chunk size is always svl bytes. */ 3192 1.11 christos offsets.chunk_size = svl; 3193 1.11 christos } 3194 1.11 christos 3195 1.11 christos return offsets; 3196 1.8 christos } 3197 1.11 christos 3198 1.11 christos /* Given REGNUM, a SME pseudo-register number, return its value in RESULT. */ 3199 1.11 christos 3200 1.11 christos static value * 3201 1.11 christos aarch64_sme_pseudo_register_read (gdbarch *gdbarch, const frame_info_ptr &next_frame, 3202 1.11 christos const int pseudo_reg_num) 3203 1.11 christos { 3204 1.11 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 3205 1.11 christos 3206 1.11 christos gdb_assert (tdep->has_sme ()); 3207 1.11 christos gdb_assert (tdep->sme_svq > 0); 3208 1.11 christos gdb_assert (tdep->sme_pseudo_base <= pseudo_reg_num); 3209 1.11 christos gdb_assert (pseudo_reg_num < tdep->sme_pseudo_base + tdep->sme_pseudo_count); 3210 1.11 christos 3211 1.11 christos /* Fetch the offsets that we need in order to read from the correct blocks 3212 1.11 christos of ZA. */ 3213 1.11 christos za_offsets offsets 3214 1.11 christos = aarch64_za_offsets_from_regnum (gdbarch, pseudo_reg_num); 3215 1.11 christos 3216 1.11 christos /* Fetch the contents of ZA. */ 3217 1.11 christos value *za_value = value_of_register (tdep->sme_za_regnum, next_frame); 3218 1.11 christos value *result = value::allocate_register (next_frame, pseudo_reg_num); 3219 1.11 christos 3220 1.11 christos /* Copy the requested data. */ 3221 1.11 christos for (int chunks = 0; chunks < offsets.chunks; chunks++) 3222 1.11 christos { 3223 1.11 christos int src_offset = offsets.starting_offset + chunks * offsets.stride_size; 3224 1.11 christos int dst_offset = chunks * offsets.chunk_size; 3225 1.11 christos za_value->contents_copy (result, dst_offset, src_offset, 3226 1.11 christos offsets.chunk_size); 3227 1.11 christos } 3228 1.11 christos 3229 1.11 christos return result; 3230 1.8 christos } 3231 1.1 christos 3232 1.1 christos /* Implement the "pseudo_register_read_value" gdbarch method. */ 3233 1.11 christos 3234 1.11 christos static value * 3235 1.11 christos aarch64_pseudo_read_value (gdbarch *gdbarch, const frame_info_ptr &next_frame, 3236 1.1 christos const int pseudo_reg_num) 3237 1.10 christos { 3238 1.1 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 3239 1.11 christos 3240 1.10 christos if (is_w_pseudo_register (gdbarch, pseudo_reg_num)) 3241 1.10 christos { 3242 1.10 christos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 3243 1.10 christos /* Default offset for little endian. */ 3244 1.10 christos int offset = 0; 3245 1.10 christos 3246 1.10 christos if (byte_order == BFD_ENDIAN_BIG) 3247 1.10 christos offset = 4; 3248 1.10 christos 3249 1.11 christos /* Find the correct X register to extract the data from. */ 3250 1.11 christos int x_regnum 3251 1.10 christos = AARCH64_X0_REGNUM + (pseudo_reg_num - tdep->w_pseudo_base); 3252 1.10 christos 3253 1.11 christos /* Read the bottom 4 bytes of X. */ 3254 1.11 christos return pseudo_from_raw_part (next_frame, pseudo_reg_num, x_regnum, 3255 1.10 christos offset); 3256 1.11 christos } 3257 1.11 christos else if (is_sme_pseudo_register (gdbarch, pseudo_reg_num)) 3258 1.11 christos return aarch64_sme_pseudo_register_read (gdbarch, next_frame, 3259 1.11 christos pseudo_reg_num); 3260 1.11 christos 3261 1.11 christos /* Offset in the "pseudo-register space". */ 3262 1.11 christos int pseudo_offset = pseudo_reg_num - gdbarch_num_regs (gdbarch); 3263 1.11 christos 3264 1.11 christos if (pseudo_offset >= AARCH64_Q0_REGNUM 3265 1.11 christos && pseudo_offset < AARCH64_Q0_REGNUM + 32) 3266 1.11 christos return aarch64_pseudo_read_value_1 (next_frame, pseudo_reg_num, 3267 1.11 christos pseudo_offset - AARCH64_Q0_REGNUM); 3268 1.11 christos 3269 1.11 christos if (pseudo_offset >= AARCH64_D0_REGNUM 3270 1.11 christos && pseudo_offset < AARCH64_D0_REGNUM + 32) 3271 1.11 christos return aarch64_pseudo_read_value_1 (next_frame, pseudo_reg_num, 3272 1.11 christos pseudo_offset - AARCH64_D0_REGNUM); 3273 1.11 christos 3274 1.11 christos if (pseudo_offset >= AARCH64_S0_REGNUM 3275 1.11 christos && pseudo_offset < AARCH64_S0_REGNUM + 32) 3276 1.11 christos return aarch64_pseudo_read_value_1 (next_frame, pseudo_reg_num, 3277 1.11 christos pseudo_offset - AARCH64_S0_REGNUM); 3278 1.11 christos 3279 1.11 christos if (pseudo_offset >= AARCH64_H0_REGNUM 3280 1.11 christos && pseudo_offset < AARCH64_H0_REGNUM + 32) 3281 1.11 christos return aarch64_pseudo_read_value_1 (next_frame, pseudo_reg_num, 3282 1.11 christos pseudo_offset - AARCH64_H0_REGNUM); 3283 1.11 christos 3284 1.11 christos if (pseudo_offset >= AARCH64_B0_REGNUM 3285 1.11 christos && pseudo_offset < AARCH64_B0_REGNUM + 32) 3286 1.11 christos return aarch64_pseudo_read_value_1 (next_frame, pseudo_reg_num, 3287 1.11 christos pseudo_offset - AARCH64_B0_REGNUM); 3288 1.11 christos 3289 1.11 christos if (tdep->has_sve () && pseudo_offset >= AARCH64_SVE_V0_REGNUM 3290 1.11 christos && pseudo_offset < AARCH64_SVE_V0_REGNUM + 32) 3291 1.11 christos return aarch64_pseudo_read_value_1 (next_frame, pseudo_reg_num, 3292 1.1 christos pseudo_offset - AARCH64_SVE_V0_REGNUM); 3293 1.1 christos 3294 1.1 christos gdb_assert_not_reached ("regnum out of bound"); 3295 1.1 christos } 3296 1.8 christos 3297 1.1 christos /* Helper for aarch64_pseudo_write. */ 3298 1.1 christos 3299 1.11 christos static void 3300 1.11 christos aarch64_pseudo_write_1 (gdbarch *gdbarch, const frame_info_ptr &next_frame, 3301 1.11 christos int regnum_offset, 3302 1.1 christos gdb::array_view<const gdb_byte> buf) 3303 1.11 christos { 3304 1.8 christos unsigned raw_regnum = AARCH64_V0_REGNUM + regnum_offset; 3305 1.12 christos 3306 1.1 christos /* Enough space for a full vector register. 3307 1.12 christos 3308 1.1 christos Ensure the register buffer is zero, we want gdb writes of the 3309 1.1 christos various 'scalar' pseudo registers to behavior like architectural 3310 1.1 christos writes, register width bytes are written the remainder are set to 3311 1.12 christos zero. */ 3312 1.12 christos gdb::byte_vector raw_buf (register_size (gdbarch, raw_regnum), 0); 3313 1.8 christos static_assert (AARCH64_V0_REGNUM == AARCH64_SVE_Z0_REGNUM); 3314 1.12 christos 3315 1.11 christos gdb::array_view<gdb_byte> raw_view (raw_buf); 3316 1.11 christos copy (buf, raw_view.slice (0, buf.size ())); 3317 1.11 christos put_frame_register (next_frame, raw_regnum, raw_view); 3318 1.11 christos } 3319 1.11 christos 3320 1.11 christos /* Given REGNUM, a SME pseudo-register number, store the bytes from DATA to the 3321 1.11 christos pseudo-register. */ 3322 1.11 christos 3323 1.11 christos static void 3324 1.11 christos aarch64_sme_pseudo_register_write (gdbarch *gdbarch, const frame_info_ptr &next_frame, 3325 1.11 christos const int regnum, 3326 1.11 christos gdb::array_view<const gdb_byte> data) 3327 1.11 christos { 3328 1.11 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 3329 1.11 christos 3330 1.11 christos gdb_assert (tdep->has_sme ()); 3331 1.11 christos gdb_assert (tdep->sme_svq > 0); 3332 1.11 christos gdb_assert (tdep->sme_pseudo_base <= regnum); 3333 1.11 christos gdb_assert (regnum < tdep->sme_pseudo_base + tdep->sme_pseudo_count); 3334 1.11 christos 3335 1.11 christos /* Fetch the offsets that we need in order to write to the correct blocks 3336 1.11 christos of ZA. */ 3337 1.11 christos za_offsets offsets = aarch64_za_offsets_from_regnum (gdbarch, regnum); 3338 1.11 christos 3339 1.11 christos /* Fetch the contents of ZA. */ 3340 1.11 christos value *za_value = value_of_register (tdep->sme_za_regnum, next_frame); 3341 1.11 christos 3342 1.11 christos { 3343 1.11 christos /* Create a view only on the portion of za we want to write. */ 3344 1.11 christos gdb::array_view<gdb_byte> za_view 3345 1.11 christos = za_value->contents_writeable ().slice (offsets.starting_offset); 3346 1.11 christos 3347 1.11 christos /* Copy the requested data. */ 3348 1.11 christos for (int chunks = 0; chunks < offsets.chunks; chunks++) 3349 1.11 christos { 3350 1.11 christos gdb::array_view<const gdb_byte> src 3351 1.11 christos = data.slice (chunks * offsets.chunk_size, offsets.chunk_size); 3352 1.11 christos gdb::array_view<gdb_byte> dst 3353 1.11 christos = za_view.slice (chunks * offsets.stride_size, offsets.chunk_size); 3354 1.11 christos copy (src, dst); 3355 1.11 christos } 3356 1.11 christos } 3357 1.11 christos 3358 1.11 christos /* Write back to ZA. */ 3359 1.11 christos put_frame_register (next_frame, tdep->sme_za_regnum, 3360 1.8 christos za_value->contents_raw ()); 3361 1.1 christos } 3362 1.8 christos 3363 1.8 christos /* Implement the "pseudo_register_write" gdbarch method. */ 3364 1.8 christos 3365 1.11 christos static void 3366 1.11 christos aarch64_pseudo_write (gdbarch *gdbarch, const frame_info_ptr &next_frame, 3367 1.11 christos const int pseudo_reg_num, 3368 1.8 christos gdb::array_view<const gdb_byte> buf) 3369 1.10 christos { 3370 1.10 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 3371 1.11 christos 3372 1.10 christos if (is_w_pseudo_register (gdbarch, pseudo_reg_num)) 3373 1.10 christos { 3374 1.10 christos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 3375 1.10 christos /* Default offset for little endian. */ 3376 1.10 christos int offset = 0; 3377 1.10 christos 3378 1.10 christos if (byte_order == BFD_ENDIAN_BIG) 3379 1.10 christos offset = 4; 3380 1.10 christos 3381 1.11 christos /* Find the correct X register to extract the data from. */ 3382 1.10 christos int x_regnum = AARCH64_X0_REGNUM + (pseudo_reg_num - tdep->w_pseudo_base); 3383 1.10 christos 3384 1.11 christos /* First zero-out the contents of X. */ 3385 1.11 christos gdb_byte bytes[8] {}; 3386 1.11 christos gdb::array_view<gdb_byte> bytes_view (bytes); 3387 1.11 christos copy (buf, bytes_view.slice (offset, 4)); 3388 1.10 christos 3389 1.11 christos /* Write to the bottom 4 bytes of X. */ 3390 1.11 christos put_frame_register (next_frame, x_regnum, bytes_view); 3391 1.11 christos return; 3392 1.11 christos } 3393 1.11 christos else if (is_sme_pseudo_register (gdbarch, pseudo_reg_num)) 3394 1.11 christos { 3395 1.11 christos aarch64_sme_pseudo_register_write (gdbarch, next_frame, pseudo_reg_num, 3396 1.10 christos buf); 3397 1.10 christos return; 3398 1.10 christos } 3399 1.11 christos 3400 1.11 christos /* Offset in the "pseudo-register space". */ 3401 1.1 christos int pseudo_offset = pseudo_reg_num - gdbarch_num_regs (gdbarch); 3402 1.11 christos 3403 1.11 christos if (pseudo_offset >= AARCH64_Q0_REGNUM 3404 1.11 christos && pseudo_offset < AARCH64_Q0_REGNUM + 32) 3405 1.11 christos return aarch64_pseudo_write_1 (gdbarch, next_frame, 3406 1.11 christos pseudo_offset - AARCH64_Q0_REGNUM, buf); 3407 1.11 christos 3408 1.11 christos if (pseudo_offset >= AARCH64_D0_REGNUM 3409 1.11 christos && pseudo_offset < AARCH64_D0_REGNUM + 32) 3410 1.11 christos return aarch64_pseudo_write_1 (gdbarch, next_frame, 3411 1.11 christos pseudo_offset - AARCH64_D0_REGNUM, buf); 3412 1.11 christos 3413 1.11 christos if (pseudo_offset >= AARCH64_S0_REGNUM 3414 1.11 christos && pseudo_offset < AARCH64_S0_REGNUM + 32) 3415 1.11 christos return aarch64_pseudo_write_1 (gdbarch, next_frame, 3416 1.11 christos pseudo_offset - AARCH64_S0_REGNUM, buf); 3417 1.11 christos 3418 1.11 christos if (pseudo_offset >= AARCH64_H0_REGNUM 3419 1.11 christos && pseudo_offset < AARCH64_H0_REGNUM + 32) 3420 1.11 christos return aarch64_pseudo_write_1 (gdbarch, next_frame, 3421 1.11 christos pseudo_offset - AARCH64_H0_REGNUM, buf); 3422 1.11 christos 3423 1.11 christos if (pseudo_offset >= AARCH64_B0_REGNUM 3424 1.11 christos && pseudo_offset < AARCH64_B0_REGNUM + 32) 3425 1.11 christos return aarch64_pseudo_write_1 (gdbarch, next_frame, 3426 1.11 christos pseudo_offset - AARCH64_B0_REGNUM, buf); 3427 1.11 christos 3428 1.11 christos if (tdep->has_sve () && pseudo_offset >= AARCH64_SVE_V0_REGNUM 3429 1.11 christos && pseudo_offset < AARCH64_SVE_V0_REGNUM + 32) 3430 1.11 christos return aarch64_pseudo_write_1 (gdbarch, next_frame, 3431 1.1 christos pseudo_offset - AARCH64_SVE_V0_REGNUM, buf); 3432 1.1 christos 3433 1.1 christos gdb_assert_not_reached ("regnum out of bound"); 3434 1.1 christos } 3435 1.1 christos 3436 1.1 christos /* Callback function for user_reg_add. */ 3437 1.1 christos 3438 1.11 christos static struct value * 3439 1.1 christos value_of_aarch64_user_reg (const frame_info_ptr &frame, const void *baton) 3440 1.6 christos { 3441 1.1 christos const int *reg_p = (const int *) baton; 3442 1.11 christos 3443 1.1 christos return value_of_register (*reg_p, get_next_frame_sentinel_okay (frame)); 3444 1.1 christos } 3445 1.3 christos 3446 1.3 christos /* Implement the "software_single_step" gdbarch method, needed to 3447 1.3 christos single step through atomic sequences on AArch64. */ 3448 1.8 christos 3449 1.7 christos static std::vector<CORE_ADDR> 3450 1.3 christos aarch64_software_single_step (struct regcache *regcache) 3451 1.8 christos { 3452 1.3 christos struct gdbarch *gdbarch = regcache->arch (); 3453 1.3 christos enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); 3454 1.3 christos const int insn_size = 4; 3455 1.7 christos const int atomic_sequence_length = 16; /* Instruction sequence length. */ 3456 1.8 christos CORE_ADDR pc = regcache_read_pc (regcache); 3457 1.3 christos CORE_ADDR breaks[2] = { CORE_ADDR_MAX, CORE_ADDR_MAX }; 3458 1.3 christos CORE_ADDR loc = pc; 3459 1.10 christos CORE_ADDR closing_insn = 0; 3460 1.10 christos 3461 1.10 christos ULONGEST insn_from_memory; 3462 1.10 christos if (!safe_read_memory_unsigned_integer (loc, insn_size, 3463 1.10 christos byte_order_for_code, 3464 1.10 christos &insn_from_memory)) 3465 1.10 christos { 3466 1.10 christos /* Assume we don't have a atomic sequence, as we couldn't read the 3467 1.10 christos instruction in this location. */ 3468 1.10 christos return {}; 3469 1.10 christos } 3470 1.10 christos 3471 1.3 christos uint32_t insn = insn_from_memory; 3472 1.3 christos int index; 3473 1.3 christos int insn_count; 3474 1.3 christos int bc_insn_count = 0; /* Conditional branch instruction count. */ 3475 1.6 christos int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */ 3476 1.6 christos aarch64_inst inst; 3477 1.8 christos 3478 1.8 christos if (aarch64_decode_insn (insn, &inst, 1, NULL) != 0) 3479 1.3 christos return {}; 3480 1.3 christos 3481 1.6 christos /* Look for a Load Exclusive instruction which begins the sequence. */ 3482 1.8 christos if (inst.opcode->iclass != ldstexcl || bit (insn, 22) == 0) 3483 1.3 christos return {}; 3484 1.3 christos 3485 1.3 christos for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count) 3486 1.3 christos { 3487 1.3 christos loc += insn_size; 3488 1.10 christos 3489 1.10 christos if (!safe_read_memory_unsigned_integer (loc, insn_size, 3490 1.10 christos byte_order_for_code, 3491 1.10 christos &insn_from_memory)) 3492 1.10 christos { 3493 1.10 christos /* Assume we don't have a atomic sequence, as we couldn't read the 3494 1.10 christos instruction in this location. */ 3495 1.10 christos return {}; 3496 1.10 christos } 3497 1.10 christos 3498 1.8 christos insn = insn_from_memory; 3499 1.8 christos if (aarch64_decode_insn (insn, &inst, 1, NULL) != 0) 3500 1.3 christos return {}; 3501 1.6 christos /* Check if the instruction is a conditional branch. */ 3502 1.3 christos if (inst.opcode->iclass == condbranch) 3503 1.6 christos { 3504 1.6 christos gdb_assert (inst.operands[0].type == AARCH64_OPND_ADDR_PCREL19); 3505 1.3 christos 3506 1.8 christos if (bc_insn_count >= 1) 3507 1.3 christos return {}; 3508 1.3 christos 3509 1.6 christos /* It is, so we'll try to set a breakpoint at the destination. */ 3510 1.3 christos breaks[1] = loc + inst.operands[0].imm.value; 3511 1.3 christos 3512 1.3 christos bc_insn_count++; 3513 1.3 christos last_breakpoint++; 3514 1.3 christos } 3515 1.3 christos 3516 1.6 christos /* Look for the Store Exclusive which closes the atomic sequence. */ 3517 1.3 christos if (inst.opcode->iclass == ldstexcl && bit (insn, 22) == 0) 3518 1.3 christos { 3519 1.3 christos closing_insn = loc; 3520 1.3 christos break; 3521 1.3 christos } 3522 1.3 christos } 3523 1.3 christos 3524 1.3 christos /* We didn't find a closing Store Exclusive instruction, fall back. */ 3525 1.8 christos if (!closing_insn) 3526 1.3 christos return {}; 3527 1.3 christos 3528 1.3 christos /* Insert breakpoint after the end of the atomic sequence. */ 3529 1.3 christos breaks[0] = loc + insn_size; 3530 1.3 christos 3531 1.3 christos /* Check for duplicated breakpoints, and also check that the second 3532 1.3 christos breakpoint is not within the atomic sequence. */ 3533 1.3 christos if (last_breakpoint 3534 1.3 christos && (breaks[1] == breaks[0] 3535 1.3 christos || (breaks[1] >= pc && breaks[1] <= closing_insn))) 3536 1.3 christos last_breakpoint = 0; 3537 1.8 christos 3538 1.8 christos std::vector<CORE_ADDR> next_pcs; 3539 1.3 christos 3540 1.3 christos /* Insert the breakpoint at the end of the sequence, and one at the 3541 1.3 christos destination of the conditional branch, if it exists. */ 3542 1.8 christos for (index = 0; index <= last_breakpoint; index++) 3543 1.3 christos next_pcs.push_back (breaks[index]); 3544 1.7 christos 3545 1.3 christos return next_pcs; 3546 1.3 christos } 3547 1.10 christos 3548 1.10 christos struct aarch64_displaced_step_copy_insn_closure 3549 1.6 christos : public displaced_step_copy_insn_closure 3550 1.6 christos { 3551 1.6 christos /* It is true when condition instruction, such as B.CON, TBZ, etc, 3552 1.9 christos is being displaced stepping. */ 3553 1.6 christos bool cond = false; 3554 1.9 christos 3555 1.9 christos /* PC adjustment offset after displaced stepping. If 0, then we don't 3556 1.8 christos write the PC back, assuming the PC is already the right address. */ 3557 1.6 christos int32_t pc_adjust = 0; 3558 1.6 christos }; 3559 1.6 christos 3560 1.6 christos /* Data when visiting instructions for displaced stepping. */ 3561 1.6 christos 3562 1.6 christos struct aarch64_displaced_step_data 3563 1.6 christos { 3564 1.6 christos struct aarch64_insn_data base; 3565 1.6 christos 3566 1.6 christos /* The address where the instruction will be executed at. */ 3567 1.6 christos CORE_ADDR new_addr; 3568 1.9 christos /* Buffer of instructions to be copied to NEW_ADDR to execute. */ 3569 1.6 christos uint32_t insn_buf[AARCH64_DISPLACED_MODIFIED_INSNS]; 3570 1.6 christos /* Number of instructions in INSN_BUF. */ 3571 1.6 christos unsigned insn_count; 3572 1.6 christos /* Registers when doing displaced stepping. */ 3573 1.6 christos struct regcache *regs; 3574 1.10 christos 3575 1.6 christos aarch64_displaced_step_copy_insn_closure *dsc; 3576 1.6 christos }; 3577 1.6 christos 3578 1.6 christos /* Implementation of aarch64_insn_visitor method "b". */ 3579 1.6 christos 3580 1.6 christos static void 3581 1.6 christos aarch64_displaced_step_b (const int is_bl, const int32_t offset, 3582 1.6 christos struct aarch64_insn_data *data) 3583 1.6 christos { 3584 1.6 christos struct aarch64_displaced_step_data *dsd 3585 1.6 christos = (struct aarch64_displaced_step_data *) data; 3586 1.6 christos int64_t new_offset = data->insn_addr - dsd->new_addr + offset; 3587 1.6 christos 3588 1.6 christos if (can_encode_int32 (new_offset, 28)) 3589 1.6 christos { 3590 1.6 christos /* Emit B rather than BL, because executing BL on a new address 3591 1.6 christos will get the wrong address into LR. In order to avoid this, 3592 1.6 christos we emit B, and update LR if the instruction is BL. */ 3593 1.6 christos emit_b (dsd->insn_buf, 0, new_offset); 3594 1.6 christos dsd->insn_count++; 3595 1.6 christos } 3596 1.6 christos else 3597 1.6 christos { 3598 1.6 christos /* Write NOP. */ 3599 1.6 christos emit_nop (dsd->insn_buf); 3600 1.6 christos dsd->insn_count++; 3601 1.6 christos dsd->dsc->pc_adjust = offset; 3602 1.6 christos } 3603 1.6 christos 3604 1.6 christos if (is_bl) 3605 1.6 christos { 3606 1.6 christos /* Update LR. */ 3607 1.6 christos regcache_cooked_write_unsigned (dsd->regs, AARCH64_LR_REGNUM, 3608 1.6 christos data->insn_addr + 4); 3609 1.6 christos } 3610 1.6 christos } 3611 1.6 christos 3612 1.6 christos /* Implementation of aarch64_insn_visitor method "b_cond". */ 3613 1.6 christos 3614 1.6 christos static void 3615 1.6 christos aarch64_displaced_step_b_cond (const unsigned cond, const int32_t offset, 3616 1.6 christos struct aarch64_insn_data *data) 3617 1.6 christos { 3618 1.6 christos struct aarch64_displaced_step_data *dsd 3619 1.6 christos = (struct aarch64_displaced_step_data *) data; 3620 1.6 christos 3621 1.6 christos /* GDB has to fix up PC after displaced step this instruction 3622 1.6 christos differently according to the condition is true or false. Instead 3623 1.6 christos of checking COND against conditional flags, we can use 3624 1.6 christos the following instructions, and GDB can tell how to fix up PC 3625 1.6 christos according to the PC value. 3626 1.6 christos 3627 1.6 christos B.COND TAKEN ; If cond is true, then jump to TAKEN. 3628 1.6 christos INSN1 ; 3629 1.6 christos TAKEN: 3630 1.6 christos INSN2 3631 1.6 christos */ 3632 1.6 christos 3633 1.9 christos emit_bcond (dsd->insn_buf, cond, 8); 3634 1.6 christos dsd->dsc->cond = true; 3635 1.6 christos dsd->dsc->pc_adjust = offset; 3636 1.6 christos dsd->insn_count = 1; 3637 1.6 christos } 3638 1.6 christos 3639 1.6 christos /* Dynamically allocate a new register. If we know the register 3640 1.6 christos statically, we should make it a global as above instead of using this 3641 1.6 christos helper function. */ 3642 1.6 christos 3643 1.6 christos static struct aarch64_register 3644 1.6 christos aarch64_register (unsigned num, int is64) 3645 1.6 christos { 3646 1.6 christos return (struct aarch64_register) { num, is64 }; 3647 1.6 christos } 3648 1.6 christos 3649 1.6 christos /* Implementation of aarch64_insn_visitor method "cb". */ 3650 1.6 christos 3651 1.6 christos static void 3652 1.6 christos aarch64_displaced_step_cb (const int32_t offset, const int is_cbnz, 3653 1.6 christos const unsigned rn, int is64, 3654 1.6 christos struct aarch64_insn_data *data) 3655 1.6 christos { 3656 1.6 christos struct aarch64_displaced_step_data *dsd 3657 1.6 christos = (struct aarch64_displaced_step_data *) data; 3658 1.6 christos 3659 1.6 christos /* The offset is out of range for a compare and branch 3660 1.6 christos instruction. We can use the following instructions instead: 3661 1.6 christos 3662 1.6 christos CBZ xn, TAKEN ; xn == 0, then jump to TAKEN. 3663 1.6 christos INSN1 ; 3664 1.6 christos TAKEN: 3665 1.6 christos INSN2 3666 1.6 christos */ 3667 1.6 christos emit_cb (dsd->insn_buf, is_cbnz, aarch64_register (rn, is64), 8); 3668 1.9 christos dsd->insn_count = 1; 3669 1.6 christos dsd->dsc->cond = true; 3670 1.6 christos dsd->dsc->pc_adjust = offset; 3671 1.6 christos } 3672 1.6 christos 3673 1.6 christos /* Implementation of aarch64_insn_visitor method "tb". */ 3674 1.6 christos 3675 1.6 christos static void 3676 1.6 christos aarch64_displaced_step_tb (const int32_t offset, int is_tbnz, 3677 1.6 christos const unsigned rt, unsigned bit, 3678 1.6 christos struct aarch64_insn_data *data) 3679 1.6 christos { 3680 1.6 christos struct aarch64_displaced_step_data *dsd 3681 1.6 christos = (struct aarch64_displaced_step_data *) data; 3682 1.6 christos 3683 1.6 christos /* The offset is out of range for a test bit and branch 3684 1.6 christos instruction We can use the following instructions instead: 3685 1.6 christos 3686 1.6 christos TBZ xn, #bit, TAKEN ; xn[bit] == 0, then jump to TAKEN. 3687 1.6 christos INSN1 ; 3688 1.6 christos TAKEN: 3689 1.6 christos INSN2 3690 1.6 christos 3691 1.6 christos */ 3692 1.6 christos emit_tb (dsd->insn_buf, is_tbnz, bit, aarch64_register (rt, 1), 8); 3693 1.9 christos dsd->insn_count = 1; 3694 1.6 christos dsd->dsc->cond = true; 3695 1.6 christos dsd->dsc->pc_adjust = offset; 3696 1.6 christos } 3697 1.6 christos 3698 1.6 christos /* Implementation of aarch64_insn_visitor method "adr". */ 3699 1.6 christos 3700 1.6 christos static void 3701 1.6 christos aarch64_displaced_step_adr (const int32_t offset, const unsigned rd, 3702 1.6 christos const int is_adrp, struct aarch64_insn_data *data) 3703 1.6 christos { 3704 1.6 christos struct aarch64_displaced_step_data *dsd 3705 1.6 christos = (struct aarch64_displaced_step_data *) data; 3706 1.6 christos /* We know exactly the address the ADR{P,} instruction will compute. 3707 1.6 christos We can just write it to the destination register. */ 3708 1.6 christos CORE_ADDR address = data->insn_addr + offset; 3709 1.6 christos 3710 1.6 christos if (is_adrp) 3711 1.6 christos { 3712 1.6 christos /* Clear the lower 12 bits of the offset to get the 4K page. */ 3713 1.6 christos regcache_cooked_write_unsigned (dsd->regs, AARCH64_X0_REGNUM + rd, 3714 1.6 christos address & ~0xfff); 3715 1.6 christos } 3716 1.6 christos else 3717 1.6 christos regcache_cooked_write_unsigned (dsd->regs, AARCH64_X0_REGNUM + rd, 3718 1.6 christos address); 3719 1.6 christos 3720 1.6 christos dsd->dsc->pc_adjust = 4; 3721 1.6 christos emit_nop (dsd->insn_buf); 3722 1.6 christos dsd->insn_count = 1; 3723 1.6 christos } 3724 1.6 christos 3725 1.6 christos /* Implementation of aarch64_insn_visitor method "ldr_literal". */ 3726 1.6 christos 3727 1.6 christos static void 3728 1.6 christos aarch64_displaced_step_ldr_literal (const int32_t offset, const int is_sw, 3729 1.6 christos const unsigned rt, const int is64, 3730 1.6 christos struct aarch64_insn_data *data) 3731 1.6 christos { 3732 1.6 christos struct aarch64_displaced_step_data *dsd 3733 1.6 christos = (struct aarch64_displaced_step_data *) data; 3734 1.6 christos CORE_ADDR address = data->insn_addr + offset; 3735 1.6 christos struct aarch64_memory_operand zero = { MEMORY_OPERAND_OFFSET, 0 }; 3736 1.6 christos 3737 1.6 christos regcache_cooked_write_unsigned (dsd->regs, AARCH64_X0_REGNUM + rt, 3738 1.6 christos address); 3739 1.6 christos 3740 1.6 christos if (is_sw) 3741 1.6 christos dsd->insn_count = emit_ldrsw (dsd->insn_buf, aarch64_register (rt, 1), 3742 1.6 christos aarch64_register (rt, 1), zero); 3743 1.6 christos else 3744 1.6 christos dsd->insn_count = emit_ldr (dsd->insn_buf, aarch64_register (rt, is64), 3745 1.6 christos aarch64_register (rt, 1), zero); 3746 1.6 christos 3747 1.6 christos dsd->dsc->pc_adjust = 4; 3748 1.6 christos } 3749 1.6 christos 3750 1.6 christos /* Implementation of aarch64_insn_visitor method "others". */ 3751 1.6 christos 3752 1.6 christos static void 3753 1.6 christos aarch64_displaced_step_others (const uint32_t insn, 3754 1.6 christos struct aarch64_insn_data *data) 3755 1.6 christos { 3756 1.6 christos struct aarch64_displaced_step_data *dsd 3757 1.6 christos = (struct aarch64_displaced_step_data *) data; 3758 1.10 christos 3759 1.10 christos uint32_t masked_insn = (insn & CLEAR_Rn_MASK); 3760 1.10 christos if (masked_insn == BLR) 3761 1.10 christos { 3762 1.10 christos /* Emit a BR to the same register and then update LR to the original 3763 1.10 christos address (similar to aarch64_displaced_step_b). */ 3764 1.10 christos aarch64_emit_insn (dsd->insn_buf, insn & 0xffdfffff); 3765 1.10 christos regcache_cooked_write_unsigned (dsd->regs, AARCH64_LR_REGNUM, 3766 1.10 christos data->insn_addr + 4); 3767 1.10 christos } 3768 1.10 christos else 3769 1.6 christos aarch64_emit_insn (dsd->insn_buf, insn); 3770 1.6 christos dsd->insn_count = 1; 3771 1.10 christos 3772 1.10 christos if (masked_insn == RET || masked_insn == BR || masked_insn == BLR) 3773 1.6 christos dsd->dsc->pc_adjust = 0; 3774 1.6 christos else 3775 1.6 christos dsd->dsc->pc_adjust = 4; 3776 1.6 christos } 3777 1.6 christos 3778 1.6 christos static const struct aarch64_insn_visitor visitor = 3779 1.6 christos { 3780 1.6 christos aarch64_displaced_step_b, 3781 1.6 christos aarch64_displaced_step_b_cond, 3782 1.6 christos aarch64_displaced_step_cb, 3783 1.6 christos aarch64_displaced_step_tb, 3784 1.6 christos aarch64_displaced_step_adr, 3785 1.6 christos aarch64_displaced_step_ldr_literal, 3786 1.6 christos aarch64_displaced_step_others, 3787 1.6 christos }; 3788 1.6 christos 3789 1.6 christos /* Implement the "displaced_step_copy_insn" gdbarch method. */ 3790 1.10 christos 3791 1.6 christos displaced_step_copy_insn_closure_up 3792 1.6 christos aarch64_displaced_step_copy_insn (struct gdbarch *gdbarch, 3793 1.6 christos CORE_ADDR from, CORE_ADDR to, 3794 1.6 christos struct regcache *regs) 3795 1.6 christos { 3796 1.6 christos enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); 3797 1.6 christos struct aarch64_displaced_step_data dsd; 3798 1.10 christos aarch64_inst inst; 3799 1.10 christos ULONGEST insn_from_memory; 3800 1.10 christos 3801 1.10 christos if (!safe_read_memory_unsigned_integer (from, 4, byte_order_for_code, 3802 1.10 christos &insn_from_memory)) 3803 1.10 christos return nullptr; 3804 1.10 christos 3805 1.6 christos uint32_t insn = insn_from_memory; 3806 1.8 christos 3807 1.6 christos if (aarch64_decode_insn (insn, &inst, 1, NULL) != 0) 3808 1.6 christos return NULL; 3809 1.11 christos 3810 1.11 christos /* Look for a Load Exclusive instruction which begins the sequence, 3811 1.11 christos or for a MOPS instruction. */ 3812 1.11 christos if ((inst.opcode->iclass == ldstexcl && bit (insn, 22)) 3813 1.6 christos || AARCH64_CPU_HAS_FEATURE (*inst.opcode->avariant, MOPS)) 3814 1.11 christos { 3815 1.6 christos /* We can't displaced step atomic sequences nor MOPS instructions. */ 3816 1.6 christos return NULL; 3817 1.6 christos } 3818 1.10 christos 3819 1.10 christos std::unique_ptr<aarch64_displaced_step_copy_insn_closure> dsc 3820 1.6 christos (new aarch64_displaced_step_copy_insn_closure); 3821 1.6 christos dsd.base.insn_addr = from; 3822 1.6 christos dsd.new_addr = to; 3823 1.8 christos dsd.regs = regs; 3824 1.6 christos dsd.dsc = dsc.get (); 3825 1.6 christos dsd.insn_count = 0; 3826 1.6 christos aarch64_relocate_instruction (insn, &visitor, 3827 1.9 christos (struct aarch64_insn_data *) &dsd); 3828 1.6 christos gdb_assert (dsd.insn_count <= AARCH64_DISPLACED_MODIFIED_INSNS); 3829 1.6 christos 3830 1.6 christos if (dsd.insn_count != 0) 3831 1.6 christos { 3832 1.6 christos int i; 3833 1.6 christos 3834 1.6 christos /* Instruction can be relocated to scratch pad. Copy 3835 1.6 christos relocated instruction(s) there. */ 3836 1.6 christos for (i = 0; i < dsd.insn_count; i++) 3837 1.10 christos { 3838 1.10 christos displaced_debug_printf ("writing insn %.8x at %s", 3839 1.10 christos dsd.insn_buf[i], 3840 1.10 christos paddress (gdbarch, to + i * 4)); 3841 1.6 christos 3842 1.6 christos write_memory_unsigned_integer (to + i * 4, 4, byte_order_for_code, 3843 1.6 christos (ULONGEST) dsd.insn_buf[i]); 3844 1.6 christos } 3845 1.6 christos } 3846 1.6 christos else 3847 1.6 christos { 3848 1.6 christos dsc = NULL; 3849 1.6 christos } 3850 1.9 christos 3851 1.10 christos /* This is a work around for a problem with g++ 4.8. */ 3852 1.6 christos return displaced_step_copy_insn_closure_up (dsc.release ()); 3853 1.6 christos } 3854 1.6 christos 3855 1.6 christos /* Implement the "displaced_step_fixup" gdbarch method. */ 3856 1.6 christos 3857 1.6 christos void 3858 1.10 christos aarch64_displaced_step_fixup (struct gdbarch *gdbarch, 3859 1.6 christos struct displaced_step_copy_insn_closure *dsc_, 3860 1.11 christos CORE_ADDR from, CORE_ADDR to, 3861 1.6 christos struct regcache *regs, bool completed_p) 3862 1.11 christos { 3863 1.11 christos CORE_ADDR pc = regcache_read_pc (regs); 3864 1.11 christos 3865 1.11 christos /* If the displaced instruction didn't complete successfully then all we 3866 1.11 christos need to do is restore the program counter. */ 3867 1.11 christos if (!completed_p) 3868 1.11 christos { 3869 1.11 christos pc = from + (pc - to); 3870 1.11 christos regcache_write_pc (regs, pc); 3871 1.11 christos return; 3872 1.11 christos } 3873 1.10 christos 3874 1.10 christos aarch64_displaced_step_copy_insn_closure *dsc 3875 1.8 christos = (aarch64_displaced_step_copy_insn_closure *) dsc_; 3876 1.10 christos 3877 1.10 christos displaced_debug_printf ("PC after stepping: %s (was %s).", 3878 1.9 christos paddress (gdbarch, pc), paddress (gdbarch, to)); 3879 1.6 christos 3880 1.6 christos if (dsc->cond) 3881 1.10 christos { 3882 1.10 christos displaced_debug_printf ("[Conditional] pc_adjust before: %d", 3883 1.6 christos dsc->pc_adjust); 3884 1.6 christos 3885 1.6 christos if (pc - to == 8) 3886 1.6 christos { 3887 1.6 christos /* Condition is true. */ 3888 1.6 christos } 3889 1.6 christos else if (pc - to == 4) 3890 1.6 christos { 3891 1.6 christos /* Condition is false. */ 3892 1.6 christos dsc->pc_adjust = 4; 3893 1.6 christos } 3894 1.6 christos else 3895 1.9 christos gdb_assert_not_reached ("Unexpected PC value after displaced stepping"); 3896 1.10 christos 3897 1.10 christos displaced_debug_printf ("[Conditional] pc_adjust after: %d", 3898 1.6 christos dsc->pc_adjust); 3899 1.6 christos } 3900 1.10 christos 3901 1.10 christos displaced_debug_printf ("%s PC by %d", 3902 1.10 christos dsc->pc_adjust ? "adjusting" : "not adjusting", 3903 1.9 christos dsc->pc_adjust); 3904 1.6 christos 3905 1.6 christos if (dsc->pc_adjust != 0) 3906 1.9 christos { 3907 1.9 christos /* Make sure the previous instruction was executed (that is, the PC 3908 1.9 christos has changed). If the PC didn't change, then discard the adjustment 3909 1.9 christos offset. Otherwise we may skip an instruction before its execution 3910 1.9 christos took place. */ 3911 1.9 christos if ((pc - to) == 0) 3912 1.10 christos { 3913 1.9 christos displaced_debug_printf ("PC did not move. Discarding PC adjustment."); 3914 1.9 christos dsc->pc_adjust = 0; 3915 1.9 christos } 3916 1.10 christos 3917 1.10 christos displaced_debug_printf ("fixup: set PC to %s:%d", 3918 1.10 christos paddress (gdbarch, from), dsc->pc_adjust); 3919 1.6 christos 3920 1.6 christos regcache_cooked_write_unsigned (regs, AARCH64_PC_REGNUM, 3921 1.6 christos from + dsc->pc_adjust); 3922 1.6 christos } 3923 1.6 christos } 3924 1.6 christos 3925 1.6 christos /* Implement the "displaced_step_hw_singlestep" gdbarch method. */ 3926 1.10 christos 3927 1.10 christos bool 3928 1.6 christos aarch64_displaced_step_hw_singlestep (struct gdbarch *gdbarch) 3929 1.10 christos { 3930 1.6 christos return true; 3931 1.6 christos } 3932 1.8 christos 3933 1.8 christos /* Get the correct target description for the given VQ value. 3934 1.10 christos If VQ is zero then it is assumed SVE is not supported. 3935 1.10 christos (It is not possible to set VQ to zero on an SVE system). 3936 1.10 christos 3937 1.10 christos MTE_P indicates the presence of the Memory Tagging Extension feature. 3938 1.10 christos 3939 1.8 christos TLS_P indicates the presence of the Thread Local Storage feature. */ 3940 1.8 christos 3941 1.10 christos const target_desc * 3942 1.8 christos aarch64_read_description (const aarch64_features &features) 3943 1.10 christos { 3944 1.10 christos if (features.vq > AARCH64_MAX_SVE_VQ) 3945 1.8 christos error (_("VQ is %" PRIu64 ", maximum supported value is %d"), features.vq, 3946 1.8 christos AARCH64_MAX_SVE_VQ); 3947 1.10 christos 3948 1.8 christos struct target_desc *tdesc = tdesc_aarch64_map[features]; 3949 1.8 christos 3950 1.8 christos if (tdesc == NULL) 3951 1.10 christos { 3952 1.10 christos tdesc = aarch64_create_target_description (features); 3953 1.8 christos tdesc_aarch64_map[features] = tdesc; 3954 1.8 christos } 3955 1.8 christos 3956 1.8 christos return tdesc; 3957 1.8 christos } 3958 1.8 christos 3959 1.8 christos /* Return the VQ used when creating the target description TDESC. */ 3960 1.8 christos 3961 1.8 christos static uint64_t 3962 1.8 christos aarch64_get_tdesc_vq (const struct target_desc *tdesc) 3963 1.8 christos { 3964 1.8 christos const struct tdesc_feature *feature_sve; 3965 1.8 christos 3966 1.8 christos if (!tdesc_has_registers (tdesc)) 3967 1.8 christos return 0; 3968 1.8 christos 3969 1.8 christos feature_sve = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.sve"); 3970 1.8 christos 3971 1.8 christos if (feature_sve == nullptr) 3972 1.8 christos return 0; 3973 1.8 christos 3974 1.8 christos uint64_t vl = tdesc_register_bitsize (feature_sve, 3975 1.8 christos aarch64_sve_register_names[0]) / 8; 3976 1.8 christos return sve_vq_from_vl (vl); 3977 1.8 christos } 3978 1.11 christos 3979 1.11 christos 3980 1.11 christos /* Return the svq (streaming vector quotient) used when creating the target 3981 1.11 christos description TDESC. */ 3982 1.11 christos 3983 1.11 christos static uint64_t 3984 1.11 christos aarch64_get_tdesc_svq (const struct target_desc *tdesc) 3985 1.11 christos { 3986 1.11 christos const struct tdesc_feature *feature_sme; 3987 1.11 christos 3988 1.11 christos if (!tdesc_has_registers (tdesc)) 3989 1.11 christos return 0; 3990 1.11 christos 3991 1.11 christos feature_sme = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.sme"); 3992 1.11 christos 3993 1.11 christos if (feature_sme == nullptr) 3994 1.11 christos return 0; 3995 1.11 christos 3996 1.11 christos size_t svl_squared = tdesc_register_bitsize (feature_sme, "za"); 3997 1.11 christos 3998 1.11 christos /* We have the total size of the ZA matrix, in bits. Figure out the svl 3999 1.11 christos value. */ 4000 1.11 christos size_t svl = std::sqrt (svl_squared / 8); 4001 1.11 christos 4002 1.11 christos /* Now extract svq. */ 4003 1.11 christos return sve_vq_from_vl (svl); 4004 1.11 christos } 4005 1.10 christos 4006 1.8 christos /* Get the AArch64 features present in the given target description. */ 4007 1.10 christos 4008 1.10 christos aarch64_features 4009 1.8 christos aarch64_features_from_target_desc (const struct target_desc *tdesc) 4010 1.10 christos { 4011 1.10 christos aarch64_features features; 4012 1.10 christos 4013 1.10 christos if (tdesc == nullptr) 4014 1.10 christos return features; 4015 1.10 christos 4016 1.11 christos features.vq = aarch64_get_tdesc_vq (tdesc); 4017 1.11 christos 4018 1.10 christos /* We need to look for a couple pauth feature name variations. */ 4019 1.10 christos features.pauth 4020 1.11 christos = (tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.pauth") != nullptr); 4021 1.11 christos 4022 1.11 christos if (!features.pauth) 4023 1.11 christos features.pauth = (tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.pauth_v2") 4024 1.11 christos != nullptr); 4025 1.10 christos 4026 1.10 christos features.mte 4027 1.10 christos = (tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.mte") != nullptr); 4028 1.10 christos 4029 1.10 christos const struct tdesc_feature *tls_feature 4030 1.10 christos = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.tls"); 4031 1.10 christos 4032 1.10 christos if (tls_feature != nullptr) 4033 1.10 christos { 4034 1.10 christos /* We have TLS registers. Find out how many. */ 4035 1.10 christos if (tdesc_unnumbered_register (tls_feature, "tpidr2")) 4036 1.10 christos features.tls = 2; 4037 1.10 christos else 4038 1.10 christos features.tls = 1; 4039 1.10 christos } 4040 1.11 christos 4041 1.11 christos features.svq = aarch64_get_tdesc_svq (tdesc); 4042 1.11 christos 4043 1.11 christos /* Check for the SME2 feature. */ 4044 1.11 christos features.sme2 = (tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.sme2") 4045 1.11 christos != nullptr); 4046 1.10 christos 4047 1.8 christos return features; 4048 1.8 christos } 4049 1.9 christos 4050 1.9 christos /* Implement the "cannot_store_register" gdbarch method. */ 4051 1.9 christos 4052 1.9 christos static int 4053 1.9 christos aarch64_cannot_store_register (struct gdbarch *gdbarch, int regnum) 4054 1.10 christos { 4055 1.9 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 4056 1.9 christos 4057 1.9 christos if (!tdep->has_pauth ()) 4058 1.9 christos return 0; 4059 1.9 christos 4060 1.11 christos /* Pointer authentication registers are read-only. */ 4061 1.11 christos return (regnum >= tdep->pauth_reg_base 4062 1.9 christos && regnum < tdep->pauth_reg_base + tdep->pauth_reg_count); 4063 1.9 christos } 4064 1.10 christos 4065 1.10 christos /* Implement the stack_frame_destroyed_p gdbarch method. */ 4066 1.10 christos 4067 1.10 christos static int 4068 1.10 christos aarch64_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc) 4069 1.10 christos { 4070 1.10 christos CORE_ADDR func_start, func_end; 4071 1.10 christos if (!find_pc_partial_function (pc, NULL, &func_start, &func_end)) 4072 1.10 christos return 0; 4073 1.10 christos 4074 1.10 christos enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); 4075 1.10 christos 4076 1.10 christos ULONGEST insn_from_memory; 4077 1.10 christos if (!safe_read_memory_unsigned_integer (pc, 4, byte_order_for_code, 4078 1.10 christos &insn_from_memory)) 4079 1.10 christos return 0; 4080 1.10 christos 4081 1.10 christos uint32_t insn = insn_from_memory; 4082 1.10 christos 4083 1.10 christos aarch64_inst inst; 4084 1.10 christos if (aarch64_decode_insn (insn, &inst, 1, nullptr) != 0) 4085 1.10 christos return 0; 4086 1.10 christos 4087 1.10 christos return streq (inst.opcode->name, "ret"); 4088 1.10 christos } 4089 1.12 christos 4090 1.12 christos /* Helper to get the allocation tag from a 64-bit ADDRESS. 4091 1.12 christos 4092 1.12 christos Return the allocation tag if successful and nullopt otherwise. */ 4093 1.12 christos 4094 1.12 christos std::optional<CORE_ADDR> 4095 1.12 christos aarch64_mte_get_atag (CORE_ADDR address) 4096 1.12 christos { 4097 1.12 christos gdb::byte_vector tags; 4098 1.12 christos 4099 1.12 christos /* Attempt to fetch the allocation tag. */ 4100 1.12 christos if (!target_fetch_memtags (address, 1, tags, 4101 1.12 christos static_cast<int> (memtag_type::allocation))) 4102 1.12 christos return {}; 4103 1.12 christos 4104 1.12 christos /* Only one tag should've been returned. Make sure we got exactly that. */ 4105 1.12 christos if (tags.size () != 1) 4106 1.12 christos error (_("Target returned an unexpected number of tags.")); 4107 1.12 christos 4108 1.12 christos /* Although our tags are 4 bits in size, they are stored in a 4109 1.12 christos byte. */ 4110 1.12 christos return tags[0]; 4111 1.12 christos } 4112 1.12 christos 4113 1.12 christos /* Implement the memtag_matches_p gdbarch method. */ 4114 1.12 christos 4115 1.12 christos static bool 4116 1.12 christos aarch64_memtag_matches_p (struct gdbarch *gdbarch, 4117 1.12 christos struct value *address) 4118 1.12 christos { 4119 1.12 christos gdb_assert (address != nullptr); 4120 1.12 christos 4121 1.12 christos CORE_ADDR addr = value_as_address (address); 4122 1.12 christos 4123 1.12 christos /* Fetch the allocation tag for ADDRESS. */ 4124 1.12 christos std::optional<CORE_ADDR> atag 4125 1.12 christos = aarch64_mte_get_atag (aarch64_remove_non_address_bits (gdbarch, addr)); 4126 1.12 christos 4127 1.12 christos if (!atag.has_value ()) 4128 1.12 christos return true; 4129 1.12 christos 4130 1.12 christos /* Fetch the logical tag for ADDRESS. */ 4131 1.12 christos gdb_byte ltag = aarch64_mte_get_ltag (addr); 4132 1.12 christos 4133 1.12 christos /* Are the tags the same? */ 4134 1.12 christos return ltag == *atag; 4135 1.12 christos } 4136 1.12 christos 4137 1.12 christos /* Implement the set_memtags gdbarch method. */ 4138 1.12 christos 4139 1.12 christos static bool 4140 1.12 christos aarch64_set_memtags (struct gdbarch *gdbarch, struct value *address, 4141 1.12 christos size_t length, const gdb::byte_vector &tags, 4142 1.12 christos memtag_type tag_type) 4143 1.12 christos { 4144 1.12 christos gdb_assert (!tags.empty ()); 4145 1.12 christos gdb_assert (address != nullptr); 4146 1.12 christos 4147 1.12 christos CORE_ADDR addr = value_as_address (address); 4148 1.12 christos 4149 1.12 christos /* Set the logical tag or the allocation tag. */ 4150 1.12 christos if (tag_type == memtag_type::logical) 4151 1.12 christos { 4152 1.12 christos /* When setting logical tags, we don't care about the length, since 4153 1.12 christos we are only setting a single logical tag. */ 4154 1.12 christos addr = aarch64_mte_set_ltag (addr, tags[0]); 4155 1.12 christos 4156 1.12 christos /* Update the value's content with the tag. */ 4157 1.12 christos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 4158 1.12 christos gdb_byte *srcbuf = address->contents_raw ().data (); 4159 1.12 christos store_unsigned_integer (srcbuf, sizeof (addr), byte_order, addr); 4160 1.12 christos } 4161 1.12 christos else 4162 1.12 christos { 4163 1.12 christos /* Remove the top byte. */ 4164 1.12 christos addr = aarch64_remove_non_address_bits (gdbarch, addr); 4165 1.12 christos 4166 1.12 christos /* With G being the number of tag granules and N the number of tags 4167 1.12 christos passed in, we can have the following cases: 4168 1.12 christos 4169 1.12 christos 1 - G == N: Store all the N tags to memory. 4170 1.12 christos 4171 1.12 christos 2 - G < N : Warn about having more tags than granules, but write G 4172 1.12 christos tags. 4173 1.12 christos 4174 1.12 christos 3 - G > N : This is a "fill tags" operation. We should use the tags 4175 1.12 christos as a pattern to fill the granules repeatedly until we have 4176 1.12 christos written G tags to memory. 4177 1.12 christos */ 4178 1.12 christos 4179 1.12 christos size_t g = aarch64_mte_get_tag_granules (addr, length, 4180 1.12 christos AARCH64_MTE_GRANULE_SIZE); 4181 1.12 christos size_t n = tags.size (); 4182 1.12 christos 4183 1.12 christos if (g < n) 4184 1.12 christos warning (_("Got more tags than memory granules. Tags will be " 4185 1.12 christos "truncated.")); 4186 1.12 christos else if (g > n) 4187 1.12 christos warning (_("Using tag pattern to fill memory range.")); 4188 1.12 christos 4189 1.12 christos if (!target_store_memtags (addr, length, tags, 4190 1.12 christos static_cast<int> (memtag_type::allocation))) 4191 1.12 christos return false; 4192 1.12 christos } 4193 1.12 christos return true; 4194 1.12 christos } 4195 1.12 christos 4196 1.12 christos /* Implement the get_memtag gdbarch method. */ 4197 1.12 christos 4198 1.12 christos static struct value * 4199 1.12 christos aarch64_get_memtag (struct gdbarch *gdbarch, struct value *address, 4200 1.12 christos memtag_type tag_type) 4201 1.12 christos { 4202 1.12 christos gdb_assert (address != nullptr); 4203 1.12 christos 4204 1.12 christos CORE_ADDR addr = value_as_address (address); 4205 1.12 christos CORE_ADDR tag = 0; 4206 1.12 christos 4207 1.12 christos /* Get the logical tag or the allocation tag. */ 4208 1.12 christos if (tag_type == memtag_type::logical) 4209 1.12 christos tag = aarch64_mte_get_ltag (addr); 4210 1.12 christos else 4211 1.12 christos { 4212 1.12 christos /* Remove the top byte. */ 4213 1.12 christos addr = aarch64_remove_non_address_bits (gdbarch, addr); 4214 1.12 christos std::optional<CORE_ADDR> atag = aarch64_mte_get_atag (addr); 4215 1.12 christos 4216 1.12 christos if (!atag.has_value ()) 4217 1.12 christos return nullptr; 4218 1.12 christos 4219 1.12 christos tag = *atag; 4220 1.12 christos } 4221 1.12 christos 4222 1.12 christos /* Convert the tag to a value. */ 4223 1.12 christos return value_from_ulongest (builtin_type (gdbarch)->builtin_unsigned_int, 4224 1.12 christos tag); 4225 1.12 christos } 4226 1.12 christos 4227 1.11 christos /* Implement the memtag_to_string gdbarch method. */ 4228 1.12 christos 4229 1.12 christos static std::string 4230 1.12 christos aarch64_memtag_to_string (struct gdbarch *gdbarch, struct value *tag_value) 4231 1.12 christos { 4232 1.12 christos if (tag_value == nullptr) 4233 1.12 christos return ""; 4234 1.12 christos 4235 1.12 christos CORE_ADDR tag = value_as_address (tag_value); 4236 1.12 christos 4237 1.12 christos return string_printf ("0x%s", phex_nz (tag, sizeof (tag))); 4238 1.12 christos } 4239 1.12 christos 4240 1.12 christos /* See aarch64-tdep.h. */ 4241 1.12 christos 4242 1.11 christos CORE_ADDR 4243 1.11 christos aarch64_remove_non_address_bits (struct gdbarch *gdbarch, CORE_ADDR pointer) 4244 1.11 christos { 4245 1.11 christos /* By default, we assume TBI and discard the top 8 bits plus the VA range 4246 1.11 christos select bit (55). Below we try to fetch information about pointer 4247 1.11 christos authentication masks in order to make non-address removal more 4248 1.11 christos precise. */ 4249 1.11 christos CORE_ADDR mask = AARCH64_TOP_BITS_MASK; 4250 1.11 christos 4251 1.11 christos /* Check if we have an inferior first. If not, just use the default 4252 1.11 christos mask. 4253 1.11 christos 4254 1.11 christos We use the inferior_ptid here because the pointer authentication masks 4255 1.11 christos should be the same across threads of a process. Since we may not have 4256 1.11 christos access to the current thread (gdb may have switched to no inferiors 4257 1.11 christos momentarily), we use the inferior ptid. */ 4258 1.11 christos if (inferior_ptid != null_ptid) 4259 1.11 christos { 4260 1.11 christos /* If we do have an inferior, attempt to fetch its thread's thread_info 4261 1.11 christos struct. */ 4262 1.11 christos thread_info *thread = current_inferior ()->find_thread (inferior_ptid); 4263 1.11 christos 4264 1.11 christos /* If the thread is running, we will not be able to fetch the mask 4265 1.11 christos registers. */ 4266 1.11 christos if (thread != nullptr && thread->state != THREAD_RUNNING) 4267 1.11 christos { 4268 1.11 christos /* Otherwise, fetch the register cache and the masks. */ 4269 1.11 christos struct regcache *regs 4270 1.11 christos = get_thread_regcache (current_inferior ()->process_target (), 4271 1.11 christos inferior_ptid); 4272 1.11 christos 4273 1.11 christos /* Use the gdbarch from the register cache to check for pointer 4274 1.11 christos authentication support, as it matches the features found in 4275 1.11 christos that particular thread. */ 4276 1.11 christos aarch64_gdbarch_tdep *tdep 4277 1.11 christos = gdbarch_tdep<aarch64_gdbarch_tdep> (regs->arch ()); 4278 1.11 christos 4279 1.11 christos /* Is there pointer authentication support? */ 4280 1.11 christos if (tdep->has_pauth ()) 4281 1.11 christos { 4282 1.11 christos CORE_ADDR cmask, dmask; 4283 1.11 christos int dmask_regnum 4284 1.11 christos = AARCH64_PAUTH_DMASK_REGNUM (tdep->pauth_reg_base); 4285 1.11 christos int cmask_regnum 4286 1.11 christos = AARCH64_PAUTH_CMASK_REGNUM (tdep->pauth_reg_base); 4287 1.11 christos 4288 1.11 christos /* If we have a kernel address and we have kernel-mode address 4289 1.11 christos mask registers, use those instead. */ 4290 1.11 christos if (tdep->pauth_reg_count > 2 4291 1.11 christos && pointer & VA_RANGE_SELECT_BIT_MASK) 4292 1.11 christos { 4293 1.11 christos dmask_regnum 4294 1.11 christos = AARCH64_PAUTH_DMASK_HIGH_REGNUM (tdep->pauth_reg_base); 4295 1.11 christos cmask_regnum 4296 1.11 christos = AARCH64_PAUTH_CMASK_HIGH_REGNUM (tdep->pauth_reg_base); 4297 1.11 christos } 4298 1.11 christos 4299 1.11 christos /* We have both a code mask and a data mask. For now they are 4300 1.11 christos the same, but this may change in the future. */ 4301 1.11 christos if (regs->cooked_read (dmask_regnum, &dmask) != REG_VALID) 4302 1.11 christos dmask = mask; 4303 1.11 christos 4304 1.11 christos if (regs->cooked_read (cmask_regnum, &cmask) != REG_VALID) 4305 1.11 christos cmask = mask; 4306 1.11 christos 4307 1.11 christos mask |= aarch64_mask_from_pac_registers (cmask, dmask); 4308 1.11 christos } 4309 1.11 christos } 4310 1.11 christos } 4311 1.11 christos 4312 1.11 christos return aarch64_remove_top_bits (pointer, mask); 4313 1.11 christos } 4314 1.11 christos 4315 1.11 christos /* Given NAMES, a vector of strings, initialize it with all the SME 4316 1.11 christos pseudo-register names for the current streaming vector length. */ 4317 1.11 christos 4318 1.11 christos static void 4319 1.11 christos aarch64_initialize_sme_pseudo_names (struct gdbarch *gdbarch, 4320 1.11 christos std::vector<std::string> &names) 4321 1.11 christos { 4322 1.11 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 4323 1.11 christos 4324 1.11 christos gdb_assert (tdep->has_sme ()); 4325 1.11 christos gdb_assert (tdep->sme_tile_slice_pseudo_base > 0); 4326 1.11 christos gdb_assert (tdep->sme_tile_pseudo_base > 0); 4327 1.11 christos 4328 1.11 christos for (int i = 0; i < tdep->sme_tile_slice_pseudo_count; i++) 4329 1.11 christos { 4330 1.11 christos int regnum = tdep->sme_tile_slice_pseudo_base + i; 4331 1.11 christos struct za_pseudo_encoding encoding; 4332 1.11 christos aarch64_za_decode_pseudos (gdbarch, regnum, encoding); 4333 1.11 christos names.push_back (aarch64_za_tile_slice_name (encoding)); 4334 1.11 christos } 4335 1.11 christos for (int i = 0; i < AARCH64_ZA_TILES_NUM; i++) 4336 1.11 christos { 4337 1.11 christos int regnum = tdep->sme_tile_pseudo_base + i; 4338 1.11 christos struct za_pseudo_encoding encoding; 4339 1.11 christos aarch64_za_decode_pseudos (gdbarch, regnum, encoding); 4340 1.11 christos names.push_back (aarch64_za_tile_name (encoding)); 4341 1.11 christos } 4342 1.11 christos } 4343 1.1 christos 4344 1.1 christos /* Initialize the current architecture based on INFO. If possible, 4345 1.1 christos re-use an architecture from ARCHES, which is a list of 4346 1.1 christos architectures already created during this debugging session. 4347 1.1 christos 4348 1.1 christos Called e.g. at program startup, when reading a core file, and when 4349 1.1 christos reading a binary file. */ 4350 1.1 christos 4351 1.1 christos static struct gdbarch * 4352 1.1 christos aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 4353 1.9 christos { 4354 1.9 christos const struct tdesc_feature *feature_core, *feature_fpu, *feature_sve; 4355 1.9 christos const struct tdesc_feature *feature_pauth; 4356 1.9 christos bool valid_p = true; 4357 1.10 christos int i, num_regs = 0, num_pseudo_regs = 0; 4358 1.10 christos int first_pauth_regnum = -1, ra_sign_state_offset = -1; 4359 1.10 christos int first_mte_regnum = -1, first_tls_regnum = -1; 4360 1.11 christos uint64_t vq = aarch64_get_tdesc_vq (info.target_desc); 4361 1.9 christos uint64_t svq = aarch64_get_tdesc_svq (info.target_desc); 4362 1.9 christos 4363 1.10 christos if (vq > AARCH64_MAX_SVE_VQ) 4364 1.9 christos internal_error (_("VQ out of bounds: %s (max %d)"), 4365 1.9 christos pulongest (vq), AARCH64_MAX_SVE_VQ); 4366 1.11 christos 4367 1.11 christos if (svq > AARCH64_MAX_SVE_VQ) 4368 1.11 christos internal_error (_("Streaming vector quotient (svq) out of bounds: %s" 4369 1.11 christos " (max %d)"), 4370 1.11 christos pulongest (svq), AARCH64_MAX_SVE_VQ); 4371 1.9 christos 4372 1.9 christos /* If there is already a candidate, use it. */ 4373 1.9 christos for (gdbarch_list *best_arch = gdbarch_list_lookup_by_info (arches, &info); 4374 1.9 christos best_arch != nullptr; 4375 1.9 christos best_arch = gdbarch_list_lookup_by_info (best_arch->next, &info)) 4376 1.10 christos { 4377 1.10 christos aarch64_gdbarch_tdep *tdep 4378 1.11 christos = gdbarch_tdep<aarch64_gdbarch_tdep> (best_arch->gdbarch); 4379 1.9 christos if (tdep && tdep->vq == vq && tdep->sme_svq == svq) 4380 1.9 christos return best_arch->gdbarch; 4381 1.9 christos } 4382 1.9 christos 4383 1.9 christos /* Ensure we always have a target descriptor, and that it is for the given VQ 4384 1.1 christos value. */ 4385 1.11 christos const struct target_desc *tdesc = info.target_desc; 4386 1.11 christos if (!tdesc_has_registers (tdesc) || vq != aarch64_get_tdesc_vq (tdesc) 4387 1.11 christos || svq != aarch64_get_tdesc_svq (tdesc)) 4388 1.11 christos { 4389 1.11 christos aarch64_features features; 4390 1.11 christos features.vq = vq; 4391 1.11 christos features.svq = svq; 4392 1.11 christos tdesc = aarch64_read_description (features); 4393 1.1 christos } 4394 1.1 christos gdb_assert (tdesc); 4395 1.9 christos 4396 1.8 christos feature_core = tdesc_find_feature (tdesc,"org.gnu.gdb.aarch64.core"); 4397 1.8 christos feature_fpu = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.fpu"); 4398 1.10 christos feature_sve = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.sve"); 4399 1.10 christos const struct tdesc_feature *feature_mte 4400 1.10 christos = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.mte"); 4401 1.10 christos const struct tdesc_feature *feature_tls 4402 1.1 christos = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.tls"); 4403 1.9 christos 4404 1.9 christos if (feature_core == nullptr) 4405 1.1 christos return nullptr; 4406 1.10 christos 4407 1.1 christos tdesc_arch_data_up tdesc_data = tdesc_data_alloc (); 4408 1.8 christos 4409 1.1 christos /* Validate the description provides the mandatory core R registers 4410 1.1 christos and allocate their numbers. */ 4411 1.10 christos for (i = 0; i < ARRAY_SIZE (aarch64_r_register_names); i++) 4412 1.8 christos valid_p &= tdesc_numbered_register (feature_core, tdesc_data.get (), 4413 1.8 christos AARCH64_X0_REGNUM + i, 4414 1.1 christos aarch64_r_register_names[i]); 4415 1.1 christos 4416 1.1 christos num_regs = AARCH64_X0_REGNUM + i; 4417 1.8 christos 4418 1.9 christos /* Add the V registers. */ 4419 1.1 christos if (feature_fpu != nullptr) 4420 1.9 christos { 4421 1.8 christos if (feature_sve != nullptr) 4422 1.8 christos error (_("Program contains both fpu and SVE features.")); 4423 1.8 christos 4424 1.8 christos /* Validate the description provides the mandatory V registers 4425 1.1 christos and allocate their numbers. */ 4426 1.10 christos for (i = 0; i < ARRAY_SIZE (aarch64_v_register_names); i++) 4427 1.8 christos valid_p &= tdesc_numbered_register (feature_fpu, tdesc_data.get (), 4428 1.8 christos AARCH64_V0_REGNUM + i, 4429 1.1 christos aarch64_v_register_names[i]); 4430 1.1 christos 4431 1.8 christos num_regs = AARCH64_V0_REGNUM + i; 4432 1.1 christos } 4433 1.8 christos 4434 1.9 christos /* Add the SVE registers. */ 4435 1.8 christos if (feature_sve != nullptr) 4436 1.8 christos { 4437 1.8 christos /* Validate the description provides the mandatory SVE registers 4438 1.8 christos and allocate their numbers. */ 4439 1.10 christos for (i = 0; i < ARRAY_SIZE (aarch64_sve_register_names); i++) 4440 1.8 christos valid_p &= tdesc_numbered_register (feature_sve, tdesc_data.get (), 4441 1.8 christos AARCH64_SVE_Z0_REGNUM + i, 4442 1.8 christos aarch64_sve_register_names[i]); 4443 1.8 christos 4444 1.8 christos num_regs = AARCH64_SVE_Z0_REGNUM + i; 4445 1.8 christos num_pseudo_regs += 32; /* add the Vn register pseudos. */ 4446 1.8 christos } 4447 1.9 christos 4448 1.8 christos if (feature_fpu != nullptr || feature_sve != nullptr) 4449 1.1 christos { 4450 1.1 christos num_pseudo_regs += 32; /* add the Qn scalar register pseudos */ 4451 1.1 christos num_pseudo_regs += 32; /* add the Dn scalar register pseudos */ 4452 1.1 christos num_pseudo_regs += 32; /* add the Sn scalar register pseudos */ 4453 1.1 christos num_pseudo_regs += 32; /* add the Hn scalar register pseudos */ 4454 1.1 christos num_pseudo_regs += 32; /* add the Bn scalar register pseudos */ 4455 1.1 christos } 4456 1.11 christos 4457 1.11 christos int first_sme_regnum = -1; 4458 1.11 christos int first_sme2_regnum = -1; 4459 1.11 christos int first_sme_pseudo_regnum = -1; 4460 1.11 christos const struct tdesc_feature *feature_sme 4461 1.11 christos = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.sme"); 4462 1.11 christos if (feature_sme != nullptr) 4463 1.11 christos { 4464 1.11 christos /* Record the first SME register. */ 4465 1.11 christos first_sme_regnum = num_regs; 4466 1.11 christos 4467 1.11 christos valid_p &= tdesc_numbered_register (feature_sme, tdesc_data.get (), 4468 1.11 christos num_regs++, "svg"); 4469 1.11 christos 4470 1.11 christos valid_p &= tdesc_numbered_register (feature_sme, tdesc_data.get (), 4471 1.11 christos num_regs++, "svcr"); 4472 1.11 christos 4473 1.11 christos valid_p &= tdesc_numbered_register (feature_sme, tdesc_data.get (), 4474 1.11 christos num_regs++, "za"); 4475 1.11 christos 4476 1.11 christos /* Record the first SME pseudo register. */ 4477 1.11 christos first_sme_pseudo_regnum = num_pseudo_regs; 4478 1.11 christos 4479 1.11 christos /* Add the ZA tile slice pseudo registers. The number of tile slice 4480 1.11 christos pseudo-registers depend on the svl, and is always a multiple of 5. */ 4481 1.11 christos num_pseudo_regs += (svq << 5) * 5; 4482 1.11 christos 4483 1.11 christos /* Add the ZA tile pseudo registers. */ 4484 1.11 christos num_pseudo_regs += AARCH64_ZA_TILES_NUM; 4485 1.11 christos 4486 1.11 christos /* Now check for the SME2 feature. SME2 is only available if SME is 4487 1.11 christos available. */ 4488 1.11 christos const struct tdesc_feature *feature_sme2 4489 1.11 christos = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.sme2"); 4490 1.11 christos if (feature_sme2 != nullptr) 4491 1.11 christos { 4492 1.11 christos /* Record the first SME2 register. */ 4493 1.11 christos first_sme2_regnum = num_regs; 4494 1.11 christos 4495 1.11 christos valid_p &= tdesc_numbered_register (feature_sme2, tdesc_data.get (), 4496 1.11 christos num_regs++, "zt0"); 4497 1.11 christos } 4498 1.11 christos } 4499 1.10 christos 4500 1.10 christos /* Add the TLS register. */ 4501 1.10 christos int tls_register_count = 0; 4502 1.10 christos if (feature_tls != nullptr) 4503 1.10 christos { 4504 1.10 christos first_tls_regnum = num_regs; 4505 1.10 christos 4506 1.10 christos /* Look for the TLS registers. tpidr is required, but tpidr2 is 4507 1.10 christos optional. */ 4508 1.10 christos valid_p 4509 1.10 christos = tdesc_numbered_register (feature_tls, tdesc_data.get (), 4510 1.10 christos first_tls_regnum, "tpidr"); 4511 1.10 christos 4512 1.10 christos if (valid_p) 4513 1.10 christos { 4514 1.10 christos tls_register_count++; 4515 1.10 christos 4516 1.10 christos bool has_tpidr2 4517 1.10 christos = tdesc_numbered_register (feature_tls, tdesc_data.get (), 4518 1.10 christos first_tls_regnum + tls_register_count, 4519 1.10 christos "tpidr2"); 4520 1.10 christos 4521 1.10 christos /* Figure out how many TLS registers we have. */ 4522 1.10 christos if (has_tpidr2) 4523 1.10 christos tls_register_count++; 4524 1.10 christos 4525 1.10 christos num_regs += tls_register_count; 4526 1.10 christos } 4527 1.10 christos else 4528 1.10 christos { 4529 1.10 christos warning (_("Provided TLS register feature doesn't contain " 4530 1.10 christos "required tpidr register.")); 4531 1.10 christos return nullptr; 4532 1.10 christos } 4533 1.10 christos } 4534 1.11 christos 4535 1.11 christos /* We have two versions of the pauth target description due to a past bug 4536 1.11 christos where GDB would crash when seeing the first version of the pauth target 4537 1.11 christos description. */ 4538 1.11 christos feature_pauth = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.pauth"); 4539 1.11 christos if (feature_pauth == nullptr) 4540 1.11 christos feature_pauth = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.pauth_v2"); 4541 1.9 christos 4542 1.11 christos /* Add the pauth registers. */ 4543 1.9 christos int pauth_masks = 0; 4544 1.9 christos if (feature_pauth != NULL) 4545 1.9 christos { 4546 1.10 christos first_pauth_regnum = num_regs; 4547 1.11 christos ra_sign_state_offset = num_pseudo_regs; 4548 1.11 christos 4549 1.11 christos /* Size of the expected register set with all 4 masks. */ 4550 1.11 christos int set_size = ARRAY_SIZE (aarch64_pauth_register_names); 4551 1.11 christos 4552 1.11 christos /* QEMU exposes a couple additional masks for the high half of the 4553 1.11 christos address. We should either have 2 registers or 4 registers. */ 4554 1.11 christos if (tdesc_unnumbered_register (feature_pauth, 4555 1.11 christos "pauth_dmask_high") == 0) 4556 1.11 christos { 4557 1.11 christos /* We did not find pauth_dmask_high, assume we only have 4558 1.11 christos 2 masks. We are not dealing with QEMU/Emulators then. */ 4559 1.11 christos set_size -= 2; 4560 1.11 christos } 4561 1.9 christos 4562 1.9 christos /* Validate the descriptor provides the mandatory PAUTH registers and 4563 1.11 christos allocate their numbers. */ 4564 1.10 christos for (i = 0; i < set_size; i++) 4565 1.9 christos valid_p &= tdesc_numbered_register (feature_pauth, tdesc_data.get (), 4566 1.9 christos first_pauth_regnum + i, 4567 1.9 christos aarch64_pauth_register_names[i]); 4568 1.9 christos 4569 1.9 christos num_regs += i; 4570 1.11 christos num_pseudo_regs += 1; /* Count RA_STATE pseudo register. */ 4571 1.9 christos pauth_masks = set_size; 4572 1.9 christos } 4573 1.10 christos 4574 1.10 christos /* Add the MTE registers. */ 4575 1.1 christos if (feature_mte != NULL) 4576 1.10 christos { 4577 1.10 christos first_mte_regnum = num_regs; 4578 1.10 christos /* Validate the descriptor provides the mandatory MTE registers and 4579 1.10 christos allocate their numbers. */ 4580 1.10 christos for (i = 0; i < ARRAY_SIZE (aarch64_mte_register_names); i++) 4581 1.10 christos valid_p &= tdesc_numbered_register (feature_mte, tdesc_data.get (), 4582 1.10 christos first_mte_regnum + i, 4583 1.10 christos aarch64_mte_register_names[i]); 4584 1.10 christos 4585 1.1 christos num_regs += i; 4586 1.10 christos } 4587 1.10 christos /* W pseudo-registers */ 4588 1.10 christos int first_w_regnum = num_pseudo_regs; 4589 1.10 christos num_pseudo_regs += 31; 4590 1.10 christos 4591 1.10 christos if (!valid_p) 4592 1.1 christos return nullptr; 4593 1.1 christos 4594 1.1 christos /* AArch64 code is always little-endian. */ 4595 1.1 christos info.byte_order_for_code = BFD_ENDIAN_LITTLE; 4596 1.11 christos 4597 1.11 christos gdbarch *gdbarch 4598 1.11 christos = gdbarch_alloc (&info, gdbarch_tdep_up (new aarch64_gdbarch_tdep)); 4599 1.1 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 4600 1.1 christos 4601 1.1 christos /* This should be low enough for everything. */ 4602 1.1 christos tdep->lowest_pc = 0x20; 4603 1.1 christos tdep->jb_pc = -1; /* Longjump support not enabled by default. */ 4604 1.9 christos tdep->jb_elt_size = 8; 4605 1.9 christos tdep->vq = vq; 4606 1.11 christos tdep->pauth_reg_base = first_pauth_regnum; 4607 1.10 christos tdep->pauth_reg_count = pauth_masks; 4608 1.10 christos tdep->ra_sign_state_regnum = -1; 4609 1.10 christos tdep->mte_reg_base = first_mte_regnum; 4610 1.10 christos tdep->tls_regnum_base = first_tls_regnum; 4611 1.1 christos tdep->tls_register_count = tls_register_count; 4612 1.11 christos 4613 1.11 christos /* Set the SME register set details. The pseudo-registers will be adjusted 4614 1.11 christos later. */ 4615 1.11 christos tdep->sme_reg_base = first_sme_regnum; 4616 1.11 christos tdep->sme_svg_regnum = first_sme_regnum; 4617 1.11 christos tdep->sme_svcr_regnum = first_sme_regnum + 1; 4618 1.11 christos tdep->sme_za_regnum = first_sme_regnum + 2; 4619 1.11 christos tdep->sme_svq = svq; 4620 1.11 christos 4621 1.11 christos /* Set the SME2 register set details. */ 4622 1.11 christos tdep->sme2_zt0_regnum = first_sme2_regnum; 4623 1.1 christos 4624 1.1 christos set_gdbarch_push_dummy_call (gdbarch, aarch64_push_dummy_call); 4625 1.1 christos set_gdbarch_frame_align (gdbarch, aarch64_frame_align); 4626 1.1 christos 4627 1.1 christos /* Advance PC across function entry code. */ 4628 1.1 christos set_gdbarch_skip_prologue (gdbarch, aarch64_skip_prologue); 4629 1.1 christos 4630 1.1 christos /* The stack grows downward. */ 4631 1.1 christos set_gdbarch_inner_than (gdbarch, core_addr_lessthan); 4632 1.1 christos 4633 1.7 christos /* Breakpoint manipulation. */ 4634 1.7 christos set_gdbarch_breakpoint_kind_from_pc (gdbarch, 4635 1.7 christos aarch64_breakpoint::kind_from_pc); 4636 1.7 christos set_gdbarch_sw_breakpoint_from_kind (gdbarch, 4637 1.1 christos aarch64_breakpoint::bp_from_kind); 4638 1.3 christos set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1); 4639 1.1 christos set_gdbarch_software_single_step (gdbarch, aarch64_software_single_step); 4640 1.1 christos 4641 1.1 christos /* Information about registers, etc. */ 4642 1.1 christos set_gdbarch_sp_regnum (gdbarch, AARCH64_SP_REGNUM); 4643 1.1 christos set_gdbarch_pc_regnum (gdbarch, AARCH64_PC_REGNUM); 4644 1.1 christos set_gdbarch_num_regs (gdbarch, num_regs); 4645 1.1 christos 4646 1.1 christos set_gdbarch_num_pseudo_regs (gdbarch, num_pseudo_regs); 4647 1.1 christos set_gdbarch_pseudo_register_read_value (gdbarch, aarch64_pseudo_read_value); 4648 1.1 christos set_gdbarch_pseudo_register_write (gdbarch, aarch64_pseudo_write); 4649 1.1 christos set_tdesc_pseudo_register_name (gdbarch, aarch64_pseudo_register_name); 4650 1.1 christos set_tdesc_pseudo_register_type (gdbarch, aarch64_pseudo_register_type); 4651 1.1 christos set_tdesc_pseudo_register_reggroup_p (gdbarch, 4652 1.9 christos aarch64_pseudo_register_reggroup_p); 4653 1.1 christos set_gdbarch_cannot_store_register (gdbarch, aarch64_cannot_store_register); 4654 1.12 christos 4655 1.12 christos /* Set the allocation tag granule size to 16 bytes. */ 4656 1.12 christos set_gdbarch_memtag_granule_size (gdbarch, AARCH64_MTE_GRANULE_SIZE); 4657 1.12 christos 4658 1.12 christos /* Register a hook for checking if there is a memory tag match. */ 4659 1.12 christos set_gdbarch_memtag_matches_p (gdbarch, aarch64_memtag_matches_p); 4660 1.12 christos 4661 1.12 christos /* Register a hook for setting the logical/allocation tags for 4662 1.12 christos a range of addresses. */ 4663 1.12 christos set_gdbarch_set_memtags (gdbarch, aarch64_set_memtags); 4664 1.12 christos 4665 1.12 christos /* Register a hook for extracting the logical/allocation tag from an 4666 1.12 christos address. */ 4667 1.12 christos set_gdbarch_get_memtag (gdbarch, aarch64_get_memtag); 4668 1.12 christos 4669 1.12 christos /* Register a hook for converting a memory tag to a string. */ 4670 1.12 christos set_gdbarch_memtag_to_string (gdbarch, aarch64_memtag_to_string); 4671 1.1 christos 4672 1.1 christos /* ABI */ 4673 1.1 christos set_gdbarch_short_bit (gdbarch, 16); 4674 1.1 christos set_gdbarch_int_bit (gdbarch, 32); 4675 1.1 christos set_gdbarch_float_bit (gdbarch, 32); 4676 1.1 christos set_gdbarch_double_bit (gdbarch, 64); 4677 1.1 christos set_gdbarch_long_double_bit (gdbarch, 128); 4678 1.1 christos set_gdbarch_long_bit (gdbarch, 64); 4679 1.1 christos set_gdbarch_long_long_bit (gdbarch, 64); 4680 1.1 christos set_gdbarch_ptr_bit (gdbarch, 64); 4681 1.7 christos set_gdbarch_char_signed (gdbarch, 0); 4682 1.1 christos set_gdbarch_wchar_signed (gdbarch, 0); 4683 1.1 christos set_gdbarch_float_format (gdbarch, floatformats_ieee_single); 4684 1.10 christos set_gdbarch_double_format (gdbarch, floatformats_ieee_double); 4685 1.9 christos set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad); 4686 1.1 christos set_gdbarch_type_align (gdbarch, aarch64_type_align); 4687 1.10 christos 4688 1.10 christos /* Detect whether PC is at a point where the stack has been destroyed. */ 4689 1.10 christos set_gdbarch_stack_frame_destroyed_p (gdbarch, aarch64_stack_frame_destroyed_p); 4690 1.1 christos 4691 1.1 christos /* Internal <-> external register number maps. */ 4692 1.1 christos set_gdbarch_dwarf2_reg_to_regnum (gdbarch, aarch64_dwarf_reg_to_regnum); 4693 1.1 christos 4694 1.11 christos /* Returning results. */ 4695 1.1 christos set_gdbarch_return_value_as_value (gdbarch, aarch64_return_value); 4696 1.1 christos 4697 1.1 christos /* Disassembly. */ 4698 1.1 christos set_gdbarch_print_insn (gdbarch, aarch64_gdb_print_insn); 4699 1.1 christos 4700 1.1 christos /* Virtual tables. */ 4701 1.1 christos set_gdbarch_vbit_in_delta (gdbarch, 1); 4702 1.1 christos 4703 1.1 christos /* Hook in the ABI-specific overrides, if they have been registered. */ 4704 1.10 christos info.target_desc = tdesc; 4705 1.1 christos info.tdesc_data = tdesc_data.get (); 4706 1.1 christos gdbarch_init_osabi (info, gdbarch); 4707 1.1 christos 4708 1.9 christos dwarf2_frame_set_init_reg (gdbarch, aarch64_dwarf2_frame_init_reg); 4709 1.9 christos /* Register DWARF CFA vendor handler. */ 4710 1.9 christos set_gdbarch_execute_dwarf_cfa_vendor_op (gdbarch, 4711 1.9 christos aarch64_execute_dwarf_cfa_vendor_op); 4712 1.9 christos 4713 1.9 christos /* Permanent/Program breakpoint handling. */ 4714 1.9 christos set_gdbarch_program_breakpoint_here_p (gdbarch, 4715 1.1 christos aarch64_program_breakpoint_here_p); 4716 1.1 christos 4717 1.1 christos /* Add some default predicates. */ 4718 1.1 christos frame_unwind_append_unwinder (gdbarch, &aarch64_stub_unwind); 4719 1.1 christos dwarf2_append_unwinders (gdbarch); 4720 1.1 christos frame_unwind_append_unwinder (gdbarch, &aarch64_prologue_unwind); 4721 1.1 christos 4722 1.1 christos frame_base_set_default (gdbarch, &aarch64_normal_base); 4723 1.1 christos 4724 1.1 christos /* Now we have tuned the configuration, set a few final things, 4725 1.1 christos based on what the OS ABI has told us. */ 4726 1.1 christos 4727 1.1 christos if (tdep->jb_pc >= 0) 4728 1.1 christos set_gdbarch_get_longjmp_target (gdbarch, aarch64_get_longjmp_target); 4729 1.6 christos 4730 1.6 christos set_gdbarch_gen_return_address (gdbarch, aarch64_gen_return_address); 4731 1.9 christos 4732 1.9 christos set_gdbarch_get_pc_address_flags (gdbarch, aarch64_get_pc_address_flags); 4733 1.10 christos 4734 1.10 christos tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data)); 4735 1.10 christos 4736 1.10 christos /* Fetch the updated number of registers after we're done adding all 4737 1.10 christos entries from features we don't explicitly care about. This is the case 4738 1.10 christos for bare metal debugging stubs that include a lot of system registers. */ 4739 1.10 christos num_regs = gdbarch_num_regs (gdbarch); 4740 1.10 christos 4741 1.10 christos /* With the number of real registers updated, setup the pseudo-registers and 4742 1.10 christos record their numbers. */ 4743 1.10 christos 4744 1.10 christos /* Setup W pseudo-register numbers. */ 4745 1.10 christos tdep->w_pseudo_base = first_w_regnum + num_regs; 4746 1.10 christos tdep->w_pseudo_count = 31; 4747 1.10 christos 4748 1.10 christos /* Pointer authentication pseudo-registers. */ 4749 1.10 christos if (tdep->has_pauth ()) 4750 1.1 christos tdep->ra_sign_state_regnum = ra_sign_state_offset + num_regs; 4751 1.11 christos 4752 1.12 christos /* Architecture hook to remove bits of a pointer that are not part of the 4753 1.12 christos address, like memory tags (MTE) and pointer authentication signatures. 4754 1.12 christos Configure address adjustment for watchpoints, breakpoints and memory 4755 1.12 christos transfer. */ 4756 1.12 christos set_gdbarch_remove_non_address_bits_watchpoint 4757 1.12 christos (gdbarch, aarch64_remove_non_address_bits); 4758 1.12 christos set_gdbarch_remove_non_address_bits_breakpoint 4759 1.12 christos (gdbarch, aarch64_remove_non_address_bits); 4760 1.12 christos set_gdbarch_remove_non_address_bits_memory 4761 1.11 christos (gdbarch, aarch64_remove_non_address_bits); 4762 1.11 christos 4763 1.11 christos /* SME pseudo-registers. */ 4764 1.11 christos if (tdep->has_sme ()) 4765 1.11 christos { 4766 1.11 christos tdep->sme_pseudo_base = num_regs + first_sme_pseudo_regnum; 4767 1.11 christos tdep->sme_tile_slice_pseudo_base = tdep->sme_pseudo_base; 4768 1.11 christos tdep->sme_tile_slice_pseudo_count = (svq * 32) * 5; 4769 1.11 christos tdep->sme_tile_pseudo_base 4770 1.11 christos = tdep->sme_pseudo_base + tdep->sme_tile_slice_pseudo_count; 4771 1.11 christos tdep->sme_pseudo_count 4772 1.11 christos = tdep->sme_tile_slice_pseudo_count + AARCH64_ZA_TILES_NUM; 4773 1.11 christos 4774 1.11 christos /* The SME ZA pseudo-registers are a set of 160 to 2560 pseudo-registers 4775 1.11 christos depending on the value of svl. 4776 1.11 christos 4777 1.11 christos The tile pseudo-registers are organized around their qualifiers 4778 1.11 christos (b, h, s, d and q). Their numbers are distributed as follows: 4779 1.11 christos 4780 1.11 christos b 0 4781 1.11 christos h 1~2 4782 1.11 christos s 3~6 4783 1.11 christos d 7~14 4784 1.11 christos q 15~30 4785 1.11 christos 4786 1.11 christos The naming of the tile pseudo-registers follows the pattern za<t><q>, 4787 1.11 christos where: 4788 1.11 christos 4789 1.11 christos <t> is the tile number, with the following possible values based on 4790 1.11 christos the qualifiers: 4791 1.11 christos 4792 1.11 christos Qualifier - Allocated indexes 4793 1.11 christos 4794 1.11 christos b - 0 4795 1.11 christos h - 0~1 4796 1.11 christos s - 0~3 4797 1.11 christos d - 0~7 4798 1.11 christos q - 0~15 4799 1.11 christos 4800 1.11 christos <q> is the qualifier: b, h, s, d and q. 4801 1.11 christos 4802 1.11 christos The tile slice pseudo-registers are organized around their 4803 1.11 christos qualifiers as well (b, h, s, d and q), but also around their 4804 1.11 christos direction (h - horizontal and v - vertical). 4805 1.11 christos 4806 1.11 christos Even-numbered tile slice pseudo-registers are horizontally-oriented 4807 1.11 christos and odd-numbered tile slice pseudo-registers are vertically-oriented. 4808 1.11 christos 4809 1.11 christos Their numbers are distributed as follows: 4810 1.11 christos 4811 1.11 christos Qualifier - Allocated indexes 4812 1.11 christos 4813 1.11 christos b tile slices - 0~511 4814 1.11 christos h tile slices - 512~1023 4815 1.11 christos s tile slices - 1024~1535 4816 1.11 christos d tile slices - 1536~2047 4817 1.11 christos q tile slices - 2048~2559 4818 1.11 christos 4819 1.11 christos The naming of the tile slice pseudo-registers follows the pattern 4820 1.11 christos za<t><d><q><s>, where: 4821 1.11 christos 4822 1.11 christos <t> is the tile number as described for the tile pseudo-registers. 4823 1.11 christos <d> is the direction of the tile slice (h or v) 4824 1.11 christos <q> is the qualifier of the tile slice (b, h, s, d or q) 4825 1.11 christos <s> is the slice number, defined as follows: 4826 1.11 christos 4827 1.11 christos Qualifier - Allocated indexes 4828 1.11 christos 4829 1.11 christos b - 0~15 4830 1.11 christos h - 0~7 4831 1.11 christos s - 0~3 4832 1.11 christos d - 0~1 4833 1.11 christos q - 0 4834 1.11 christos 4835 1.11 christos We have helper functions to translate to/from register index from/to 4836 1.11 christos the set of fields that make the pseudo-register names. */ 4837 1.11 christos 4838 1.11 christos /* Build the array of pseudo-register names available for this 4839 1.11 christos particular gdbarch configuration. */ 4840 1.11 christos aarch64_initialize_sme_pseudo_names (gdbarch, tdep->sme_pseudo_names); 4841 1.11 christos } 4842 1.1 christos 4843 1.1 christos /* Add standard register aliases. */ 4844 1.1 christos for (i = 0; i < ARRAY_SIZE (aarch64_register_aliases); i++) 4845 1.1 christos user_reg_add (gdbarch, aarch64_register_aliases[i].name, 4846 1.1 christos value_of_aarch64_user_reg, 4847 1.1 christos &aarch64_register_aliases[i].regnum); 4848 1.8 christos 4849 1.8 christos register_aarch64_ravenscar_ops (gdbarch); 4850 1.1 christos 4851 1.1 christos return gdbarch; 4852 1.1 christos } 4853 1.1 christos 4854 1.1 christos static void 4855 1.1 christos aarch64_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) 4856 1.10 christos { 4857 1.1 christos aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); 4858 1.1 christos 4859 1.1 christos if (tdep == NULL) 4860 1.1 christos return; 4861 1.10 christos 4862 1.10 christos gdb_printf (file, _("aarch64_dump_tdep: Lowest pc = 0x%s\n"), 4863 1.11 christos paddress (gdbarch, tdep->lowest_pc)); 4864 1.11 christos 4865 1.11 christos /* SME fields. */ 4866 1.11 christos gdb_printf (file, _("aarch64_dump_tdep: sme_tile_type_q = %s\n"), 4867 1.11 christos host_address_to_string (tdep->sme_tile_type_q)); 4868 1.11 christos gdb_printf (file, _("aarch64_dump_tdep: sme_tile_type_d = %s\n"), 4869 1.11 christos host_address_to_string (tdep->sme_tile_type_d)); 4870 1.11 christos gdb_printf (file, _("aarch64_dump_tdep: sme_tile_type_s = %s\n"), 4871 1.11 christos host_address_to_string (tdep->sme_tile_type_s)); 4872 1.11 christos gdb_printf (file, _("aarch64_dump_tdep: sme_tile_type_h = %s\n"), 4873 1.11 christos host_address_to_string (tdep->sme_tile_type_h)); 4874 1.11 christos gdb_printf (file, _("aarch64_dump_tdep: sme_tile_type_n = %s\n"), 4875 1.11 christos host_address_to_string (tdep->sme_tile_type_b)); 4876 1.11 christos gdb_printf (file, _("aarch64_dump_tdep: sme_tile_slice_type_q = %s\n"), 4877 1.11 christos host_address_to_string (tdep->sme_tile_slice_type_q)); 4878 1.11 christos gdb_printf (file, _("aarch64_dump_tdep: sme_tile_slice_type_d = %s\n"), 4879 1.11 christos host_address_to_string (tdep->sme_tile_slice_type_d)); 4880 1.11 christos gdb_printf (file, _("aarch64_dump_tdep: sme_tile_slice_type_s = %s\n"), 4881 1.11 christos host_address_to_string (tdep->sme_tile_slice_type_s)); 4882 1.11 christos gdb_printf (file, _("aarch64_dump_tdep: sme_tile_slice_type_h = %s\n"), 4883 1.11 christos host_address_to_string (tdep->sme_tile_slice_type_h)); 4884 1.11 christos gdb_printf (file, _("aarch64_dump_tdep: sme_tile_slice_type_b = %s\n"), 4885 1.11 christos host_address_to_string (tdep->sme_tile_slice_type_b)); 4886 1.11 christos gdb_printf (file, _("aarch64_dump_tdep: sme_reg_base = %s\n"), 4887 1.11 christos pulongest (tdep->sme_reg_base)); 4888 1.11 christos gdb_printf (file, _("aarch64_dump_tdep: sme_svg_regnum = %s\n"), 4889 1.11 christos pulongest (tdep->sme_svg_regnum)); 4890 1.11 christos gdb_printf (file, _("aarch64_dump_tdep: sme_svcr_regnum = %s\n"), 4891 1.11 christos pulongest (tdep->sme_svcr_regnum)); 4892 1.11 christos gdb_printf (file, _("aarch64_dump_tdep: sme_za_regnum = %s\n"), 4893 1.11 christos pulongest (tdep->sme_za_regnum)); 4894 1.11 christos gdb_printf (file, _("aarch64_dump_tdep: sme_pseudo_base = %s\n"), 4895 1.11 christos pulongest (tdep->sme_pseudo_base)); 4896 1.11 christos gdb_printf (file, _("aarch64_dump_tdep: sme_pseudo_count = %s\n"), 4897 1.11 christos pulongest (tdep->sme_pseudo_count)); 4898 1.11 christos gdb_printf (file, _("aarch64_dump_tdep: sme_tile_slice_pseudo_base = %s\n"), 4899 1.11 christos pulongest (tdep->sme_tile_slice_pseudo_base)); 4900 1.11 christos gdb_printf (file, _("aarch64_dump_tdep: sme_tile_slice_pseudo_count = %s\n"), 4901 1.11 christos pulongest (tdep->sme_tile_slice_pseudo_count)); 4902 1.11 christos gdb_printf (file, _("aarch64_dump_tdep: sme_tile_pseudo_base = %s\n"), 4903 1.11 christos pulongest (tdep->sme_tile_pseudo_base)); 4904 1.11 christos gdb_printf (file, _("aarch64_dump_tdep: sme_svq = %s\n"), 4905 1.1 christos pulongest (tdep->sme_svq)); 4906 1.1 christos } 4907 1.7 christos 4908 1.7 christos #if GDB_SELF_TEST 4909 1.7 christos namespace selftests 4910 1.7 christos { 4911 1.7 christos static void aarch64_process_record_test (void); 4912 1.7 christos } 4913 1.7 christos #endif 4914 1.9 christos 4915 1.1 christos void _initialize_aarch64_tdep (); 4916 1.9 christos void 4917 1.1 christos _initialize_aarch64_tdep () 4918 1.1 christos { 4919 1.1 christos gdbarch_register (bfd_arch_aarch64, aarch64_gdbarch_init, 4920 1.1 christos aarch64_dump_tdep); 4921 1.1 christos 4922 1.1 christos /* Debug this file's internals. */ 4923 1.1 christos add_setshow_boolean_cmd ("aarch64", class_maintenance, &aarch64_debug, _("\ 4924 1.1 christos Set AArch64 debugging."), _("\ 4925 1.1 christos Show AArch64 debugging."), _("\ 4926 1.1 christos When on, AArch64 specific debugging is enabled."), 4927 1.1 christos NULL, 4928 1.1 christos show_aarch64_debug, 4929 1.7 christos &setdebuglist, &showdebuglist); 4930 1.7 christos 4931 1.8 christos #if GDB_SELF_TEST 4932 1.8 christos selftests::register_test ("aarch64-analyze-prologue", 4933 1.8 christos selftests::aarch64_analyze_prologue_test); 4934 1.8 christos selftests::register_test ("aarch64-process-record", 4935 1.7 christos selftests::aarch64_process_record_test); 4936 1.1 christos #endif 4937 1.5 christos } 4938 1.5 christos 4939 1.5 christos /* AArch64 process record-replay related structures, defines etc. */ 4940 1.5 christos 4941 1.10 christos #define REG_ALLOC(REGS, LENGTH, RECORD_BUF) \ 4942 1.10 christos do \ 4943 1.10 christos { \ 4944 1.10 christos unsigned int reg_len = LENGTH; \ 4945 1.10 christos if (reg_len) \ 4946 1.10 christos { \ 4947 1.10 christos REGS = XNEWVEC (uint32_t, reg_len); \ 4948 1.10 christos memcpy(®S[0], &RECORD_BUF[0], sizeof(uint32_t)*LENGTH); \ 4949 1.10 christos } \ 4950 1.10 christos } \ 4951 1.5 christos while (0) 4952 1.5 christos 4953 1.10 christos #define MEM_ALLOC(MEMS, LENGTH, RECORD_BUF) \ 4954 1.10 christos do \ 4955 1.10 christos { \ 4956 1.10 christos unsigned int mem_len = LENGTH; \ 4957 1.10 christos if (mem_len) \ 4958 1.10 christos { \ 4959 1.10 christos MEMS = XNEWVEC (struct aarch64_mem_r, mem_len); \ 4960 1.10 christos memcpy(MEMS, &RECORD_BUF[0], \ 4961 1.10 christos sizeof(struct aarch64_mem_r) * LENGTH); \ 4962 1.10 christos } \ 4963 1.10 christos } \ 4964 1.5 christos while (0) 4965 1.5 christos 4966 1.5 christos /* AArch64 record/replay structures and enumerations. */ 4967 1.5 christos 4968 1.5 christos struct aarch64_mem_r 4969 1.5 christos { 4970 1.5 christos uint64_t len; /* Record length. */ 4971 1.5 christos uint64_t addr; /* Memory address. */ 4972 1.5 christos }; 4973 1.5 christos 4974 1.5 christos enum aarch64_record_result 4975 1.5 christos { 4976 1.5 christos AARCH64_RECORD_SUCCESS, 4977 1.5 christos AARCH64_RECORD_UNSUPPORTED, 4978 1.5 christos AARCH64_RECORD_UNKNOWN 4979 1.5 christos }; 4980 1.10 christos 4981 1.5 christos struct aarch64_insn_decode_record 4982 1.5 christos { 4983 1.5 christos struct gdbarch *gdbarch; 4984 1.5 christos struct regcache *regcache; 4985 1.5 christos CORE_ADDR this_addr; /* Address of insn to be recorded. */ 4986 1.5 christos uint32_t aarch64_insn; /* Insn to be recorded. */ 4987 1.5 christos uint32_t mem_rec_count; /* Count of memory records. */ 4988 1.5 christos uint32_t reg_rec_count; /* Count of register records. */ 4989 1.5 christos uint32_t *aarch64_regs; /* Registers to be recorded. */ 4990 1.10 christos struct aarch64_mem_r *aarch64_mems; /* Memory locations to be recorded. */ 4991 1.5 christos }; 4992 1.5 christos 4993 1.5 christos /* Record handler for data processing - register instructions. */ 4994 1.5 christos 4995 1.10 christos static unsigned int 4996 1.5 christos aarch64_record_data_proc_reg (aarch64_insn_decode_record *aarch64_insn_r) 4997 1.5 christos { 4998 1.5 christos uint8_t reg_rd, insn_bits24_27, insn_bits21_23; 4999 1.5 christos uint32_t record_buf[4]; 5000 1.5 christos 5001 1.5 christos reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4); 5002 1.5 christos insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27); 5003 1.5 christos insn_bits21_23 = bits (aarch64_insn_r->aarch64_insn, 21, 23); 5004 1.5 christos 5005 1.5 christos if (!bit (aarch64_insn_r->aarch64_insn, 28)) 5006 1.5 christos { 5007 1.5 christos uint8_t setflags; 5008 1.5 christos 5009 1.5 christos /* Logical (shifted register). */ 5010 1.5 christos if (insn_bits24_27 == 0x0a) 5011 1.5 christos setflags = (bits (aarch64_insn_r->aarch64_insn, 29, 30) == 0x03); 5012 1.5 christos /* Add/subtract. */ 5013 1.5 christos else if (insn_bits24_27 == 0x0b) 5014 1.5 christos setflags = bit (aarch64_insn_r->aarch64_insn, 29); 5015 1.5 christos else 5016 1.5 christos return AARCH64_RECORD_UNKNOWN; 5017 1.5 christos 5018 1.5 christos record_buf[0] = reg_rd; 5019 1.5 christos aarch64_insn_r->reg_rec_count = 1; 5020 1.5 christos if (setflags) 5021 1.5 christos record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_CPSR_REGNUM; 5022 1.5 christos } 5023 1.5 christos else 5024 1.5 christos { 5025 1.5 christos if (insn_bits24_27 == 0x0b) 5026 1.5 christos { 5027 1.5 christos /* Data-processing (3 source). */ 5028 1.5 christos record_buf[0] = reg_rd; 5029 1.5 christos aarch64_insn_r->reg_rec_count = 1; 5030 1.5 christos } 5031 1.5 christos else if (insn_bits24_27 == 0x0a) 5032 1.5 christos { 5033 1.5 christos if (insn_bits21_23 == 0x00) 5034 1.5 christos { 5035 1.5 christos /* Add/subtract (with carry). */ 5036 1.5 christos record_buf[0] = reg_rd; 5037 1.5 christos aarch64_insn_r->reg_rec_count = 1; 5038 1.5 christos if (bit (aarch64_insn_r->aarch64_insn, 29)) 5039 1.5 christos { 5040 1.5 christos record_buf[1] = AARCH64_CPSR_REGNUM; 5041 1.5 christos aarch64_insn_r->reg_rec_count = 2; 5042 1.5 christos } 5043 1.5 christos } 5044 1.5 christos else if (insn_bits21_23 == 0x02) 5045 1.5 christos { 5046 1.5 christos /* Conditional compare (register) and conditional compare 5047 1.5 christos (immediate) instructions. */ 5048 1.5 christos record_buf[0] = AARCH64_CPSR_REGNUM; 5049 1.5 christos aarch64_insn_r->reg_rec_count = 1; 5050 1.5 christos } 5051 1.5 christos else if (insn_bits21_23 == 0x04 || insn_bits21_23 == 0x06) 5052 1.9 christos { 5053 1.5 christos /* Conditional select. */ 5054 1.5 christos /* Data-processing (2 source). */ 5055 1.5 christos /* Data-processing (1 source). */ 5056 1.5 christos record_buf[0] = reg_rd; 5057 1.5 christos aarch64_insn_r->reg_rec_count = 1; 5058 1.5 christos } 5059 1.5 christos else 5060 1.5 christos return AARCH64_RECORD_UNKNOWN; 5061 1.5 christos } 5062 1.5 christos } 5063 1.5 christos 5064 1.5 christos REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count, 5065 1.5 christos record_buf); 5066 1.5 christos return AARCH64_RECORD_SUCCESS; 5067 1.5 christos } 5068 1.5 christos 5069 1.5 christos /* Record handler for data processing - immediate instructions. */ 5070 1.5 christos 5071 1.10 christos static unsigned int 5072 1.5 christos aarch64_record_data_proc_imm (aarch64_insn_decode_record *aarch64_insn_r) 5073 1.6 christos { 5074 1.5 christos uint8_t reg_rd, insn_bit23, insn_bits24_27, setflags; 5075 1.5 christos uint32_t record_buf[4]; 5076 1.5 christos 5077 1.5 christos reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4); 5078 1.5 christos insn_bit23 = bit (aarch64_insn_r->aarch64_insn, 23); 5079 1.5 christos insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27); 5080 1.5 christos 5081 1.5 christos if (insn_bits24_27 == 0x00 /* PC rel addressing. */ 5082 1.5 christos || insn_bits24_27 == 0x03 /* Bitfield and Extract. */ 5083 1.5 christos || (insn_bits24_27 == 0x02 && insn_bit23)) /* Move wide (immediate). */ 5084 1.5 christos { 5085 1.5 christos record_buf[0] = reg_rd; 5086 1.5 christos aarch64_insn_r->reg_rec_count = 1; 5087 1.5 christos } 5088 1.5 christos else if (insn_bits24_27 == 0x01) 5089 1.5 christos { 5090 1.5 christos /* Add/Subtract (immediate). */ 5091 1.5 christos setflags = bit (aarch64_insn_r->aarch64_insn, 29); 5092 1.5 christos record_buf[0] = reg_rd; 5093 1.5 christos aarch64_insn_r->reg_rec_count = 1; 5094 1.5 christos if (setflags) 5095 1.5 christos record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_CPSR_REGNUM; 5096 1.5 christos } 5097 1.5 christos else if (insn_bits24_27 == 0x02 && !insn_bit23) 5098 1.5 christos { 5099 1.5 christos /* Logical (immediate). */ 5100 1.5 christos setflags = bits (aarch64_insn_r->aarch64_insn, 29, 30) == 0x03; 5101 1.5 christos record_buf[0] = reg_rd; 5102 1.5 christos aarch64_insn_r->reg_rec_count = 1; 5103 1.5 christos if (setflags) 5104 1.5 christos record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_CPSR_REGNUM; 5105 1.5 christos } 5106 1.5 christos else 5107 1.5 christos return AARCH64_RECORD_UNKNOWN; 5108 1.5 christos 5109 1.5 christos REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count, 5110 1.5 christos record_buf); 5111 1.5 christos return AARCH64_RECORD_SUCCESS; 5112 1.5 christos } 5113 1.5 christos 5114 1.5 christos /* Record handler for branch, exception generation and system instructions. */ 5115 1.5 christos 5116 1.10 christos static unsigned int 5117 1.5 christos aarch64_record_branch_except_sys (aarch64_insn_decode_record *aarch64_insn_r) 5118 1.10 christos { 5119 1.10 christos 5120 1.10 christos aarch64_gdbarch_tdep *tdep 5121 1.5 christos = gdbarch_tdep<aarch64_gdbarch_tdep> (aarch64_insn_r->gdbarch); 5122 1.5 christos uint8_t insn_bits24_27, insn_bits28_31, insn_bits22_23; 5123 1.5 christos uint32_t record_buf[4]; 5124 1.5 christos 5125 1.5 christos insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27); 5126 1.5 christos insn_bits28_31 = bits (aarch64_insn_r->aarch64_insn, 28, 31); 5127 1.5 christos insn_bits22_23 = bits (aarch64_insn_r->aarch64_insn, 22, 23); 5128 1.5 christos 5129 1.5 christos if (insn_bits28_31 == 0x0d) 5130 1.5 christos { 5131 1.5 christos /* Exception generation instructions. */ 5132 1.5 christos if (insn_bits24_27 == 0x04) 5133 1.5 christos { 5134 1.5 christos if (!bits (aarch64_insn_r->aarch64_insn, 2, 4) 5135 1.5 christos && !bits (aarch64_insn_r->aarch64_insn, 21, 23) 5136 1.5 christos && bits (aarch64_insn_r->aarch64_insn, 0, 1) == 0x01) 5137 1.5 christos { 5138 1.5 christos ULONGEST svc_number; 5139 1.5 christos 5140 1.5 christos regcache_raw_read_unsigned (aarch64_insn_r->regcache, 8, 5141 1.5 christos &svc_number); 5142 1.5 christos return tdep->aarch64_syscall_record (aarch64_insn_r->regcache, 5143 1.5 christos svc_number); 5144 1.5 christos } 5145 1.5 christos else 5146 1.5 christos return AARCH64_RECORD_UNSUPPORTED; 5147 1.5 christos } 5148 1.5 christos /* System instructions. */ 5149 1.5 christos else if (insn_bits24_27 == 0x05 && insn_bits22_23 == 0x00) 5150 1.5 christos { 5151 1.5 christos uint32_t reg_rt, reg_crn; 5152 1.5 christos 5153 1.5 christos reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4); 5154 1.5 christos reg_crn = bits (aarch64_insn_r->aarch64_insn, 12, 15); 5155 1.5 christos 5156 1.5 christos /* Record rt in case of sysl and mrs instructions. */ 5157 1.5 christos if (bit (aarch64_insn_r->aarch64_insn, 21)) 5158 1.5 christos { 5159 1.5 christos record_buf[0] = reg_rt; 5160 1.5 christos aarch64_insn_r->reg_rec_count = 1; 5161 1.5 christos } 5162 1.5 christos /* Record cpsr for hint and msr(immediate) instructions. */ 5163 1.5 christos else if (reg_crn == 0x02 || reg_crn == 0x04) 5164 1.5 christos { 5165 1.5 christos record_buf[0] = AARCH64_CPSR_REGNUM; 5166 1.5 christos aarch64_insn_r->reg_rec_count = 1; 5167 1.5 christos } 5168 1.5 christos } 5169 1.5 christos /* Unconditional branch (register). */ 5170 1.5 christos else if((insn_bits24_27 & 0x0e) == 0x06) 5171 1.5 christos { 5172 1.5 christos record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_PC_REGNUM; 5173 1.5 christos if (bits (aarch64_insn_r->aarch64_insn, 21, 22) == 0x01) 5174 1.5 christos record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_LR_REGNUM; 5175 1.5 christos } 5176 1.5 christos else 5177 1.5 christos return AARCH64_RECORD_UNKNOWN; 5178 1.5 christos } 5179 1.5 christos /* Unconditional branch (immediate). */ 5180 1.5 christos else if ((insn_bits28_31 & 0x07) == 0x01 && (insn_bits24_27 & 0x0c) == 0x04) 5181 1.5 christos { 5182 1.5 christos record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_PC_REGNUM; 5183 1.5 christos if (bit (aarch64_insn_r->aarch64_insn, 31)) 5184 1.5 christos record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_LR_REGNUM; 5185 1.5 christos } 5186 1.5 christos else 5187 1.5 christos /* Compare & branch (immediate), Test & branch (immediate) and 5188 1.5 christos Conditional branch (immediate). */ 5189 1.5 christos record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_PC_REGNUM; 5190 1.5 christos 5191 1.5 christos REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count, 5192 1.5 christos record_buf); 5193 1.5 christos return AARCH64_RECORD_SUCCESS; 5194 1.5 christos } 5195 1.5 christos 5196 1.5 christos /* Record handler for advanced SIMD load and store instructions. */ 5197 1.5 christos 5198 1.10 christos static unsigned int 5199 1.5 christos aarch64_record_asimd_load_store (aarch64_insn_decode_record *aarch64_insn_r) 5200 1.5 christos { 5201 1.5 christos CORE_ADDR address; 5202 1.5 christos uint64_t addr_offset = 0; 5203 1.12 christos uint32_t record_buf[24]; 5204 1.5 christos std::vector<uint64_t> record_buf_mem; 5205 1.12 christos uint32_t reg_rn, reg_rt; 5206 1.5 christos uint32_t reg_index = 0; 5207 1.5 christos uint8_t opcode_bits, size_bits; 5208 1.5 christos 5209 1.5 christos reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4); 5210 1.5 christos reg_rn = bits (aarch64_insn_r->aarch64_insn, 5, 9); 5211 1.5 christos size_bits = bits (aarch64_insn_r->aarch64_insn, 10, 11); 5212 1.5 christos opcode_bits = bits (aarch64_insn_r->aarch64_insn, 12, 15); 5213 1.5 christos regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, &address); 5214 1.5 christos 5215 1.6 christos if (record_debug) 5216 1.5 christos debug_printf ("Process record: Advanced SIMD load/store\n"); 5217 1.5 christos 5218 1.5 christos /* Load/store single structure. */ 5219 1.5 christos if (bit (aarch64_insn_r->aarch64_insn, 24)) 5220 1.5 christos { 5221 1.5 christos uint8_t sindex, scale, selem, esize, replicate = 0; 5222 1.5 christos scale = opcode_bits >> 2; 5223 1.10 christos selem = ((opcode_bits & 0x02) | 5224 1.5 christos bit (aarch64_insn_r->aarch64_insn, 21)) + 1; 5225 1.10 christos switch (scale) 5226 1.10 christos { 5227 1.10 christos case 1: 5228 1.10 christos if (size_bits & 0x01) 5229 1.10 christos return AARCH64_RECORD_UNKNOWN; 5230 1.10 christos break; 5231 1.10 christos case 2: 5232 1.10 christos if ((size_bits >> 1) & 0x01) 5233 1.10 christos return AARCH64_RECORD_UNKNOWN; 5234 1.10 christos if (size_bits & 0x01) 5235 1.10 christos { 5236 1.10 christos if (!((opcode_bits >> 1) & 0x01)) 5237 1.10 christos scale = 3; 5238 1.10 christos else 5239 1.10 christos return AARCH64_RECORD_UNKNOWN; 5240 1.10 christos } 5241 1.10 christos break; 5242 1.10 christos case 3: 5243 1.10 christos if (bit (aarch64_insn_r->aarch64_insn, 22) && !(opcode_bits & 0x01)) 5244 1.10 christos { 5245 1.10 christos scale = size_bits; 5246 1.10 christos replicate = 1; 5247 1.10 christos break; 5248 1.10 christos } 5249 1.10 christos else 5250 1.10 christos return AARCH64_RECORD_UNKNOWN; 5251 1.10 christos default: 5252 1.10 christos break; 5253 1.5 christos } 5254 1.5 christos esize = 8 << scale; 5255 1.10 christos if (replicate) 5256 1.10 christos for (sindex = 0; sindex < selem; sindex++) 5257 1.10 christos { 5258 1.10 christos record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM; 5259 1.10 christos reg_rt = (reg_rt + 1) % 32; 5260 1.5 christos } 5261 1.10 christos else 5262 1.10 christos { 5263 1.6 christos for (sindex = 0; sindex < selem; sindex++) 5264 1.6 christos { 5265 1.6 christos if (bit (aarch64_insn_r->aarch64_insn, 22)) 5266 1.6 christos record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM; 5267 1.6 christos else 5268 1.12 christos { 5269 1.12 christos record_buf_mem.push_back (esize / 8); 5270 1.6 christos record_buf_mem.push_back (address + addr_offset); 5271 1.6 christos } 5272 1.6 christos addr_offset = addr_offset + (esize / 8); 5273 1.6 christos reg_rt = (reg_rt + 1) % 32; 5274 1.10 christos } 5275 1.5 christos } 5276 1.5 christos } 5277 1.5 christos /* Load/store multiple structure. */ 5278 1.5 christos else 5279 1.5 christos { 5280 1.5 christos uint8_t selem, esize, rpt, elements; 5281 1.5 christos uint8_t eindex, rindex; 5282 1.5 christos 5283 1.5 christos esize = 8 << size_bits; 5284 1.10 christos if (bit (aarch64_insn_r->aarch64_insn, 30)) 5285 1.5 christos elements = 128 / esize; 5286 1.10 christos else 5287 1.5 christos elements = 64 / esize; 5288 1.5 christos 5289 1.10 christos switch (opcode_bits) 5290 1.10 christos { 5291 1.10 christos /*LD/ST4 (4 Registers). */ 5292 1.10 christos case 0: 5293 1.10 christos rpt = 1; 5294 1.10 christos selem = 4; 5295 1.10 christos break; 5296 1.10 christos /*LD/ST1 (4 Registers). */ 5297 1.10 christos case 2: 5298 1.10 christos rpt = 4; 5299 1.10 christos selem = 1; 5300 1.10 christos break; 5301 1.10 christos /*LD/ST3 (3 Registers). */ 5302 1.10 christos case 4: 5303 1.10 christos rpt = 1; 5304 1.10 christos selem = 3; 5305 1.10 christos break; 5306 1.10 christos /*LD/ST1 (3 Registers). */ 5307 1.10 christos case 6: 5308 1.10 christos rpt = 3; 5309 1.10 christos selem = 1; 5310 1.10 christos break; 5311 1.10 christos /*LD/ST1 (1 Register). */ 5312 1.10 christos case 7: 5313 1.10 christos rpt = 1; 5314 1.10 christos selem = 1; 5315 1.10 christos break; 5316 1.10 christos /*LD/ST2 (2 Registers). */ 5317 1.10 christos case 8: 5318 1.10 christos rpt = 1; 5319 1.10 christos selem = 2; 5320 1.10 christos break; 5321 1.10 christos /*LD/ST1 (2 Registers). */ 5322 1.10 christos case 10: 5323 1.10 christos rpt = 2; 5324 1.10 christos selem = 1; 5325 1.10 christos break; 5326 1.10 christos default: 5327 1.10 christos return AARCH64_RECORD_UNSUPPORTED; 5328 1.10 christos break; 5329 1.5 christos } 5330 1.10 christos for (rindex = 0; rindex < rpt; rindex++) 5331 1.10 christos for (eindex = 0; eindex < elements; eindex++) 5332 1.10 christos { 5333 1.10 christos uint8_t reg_tt, sindex; 5334 1.10 christos reg_tt = (reg_rt + rindex) % 32; 5335 1.10 christos for (sindex = 0; sindex < selem; sindex++) 5336 1.10 christos { 5337 1.10 christos if (bit (aarch64_insn_r->aarch64_insn, 22)) 5338 1.10 christos record_buf[reg_index++] = reg_tt + AARCH64_V0_REGNUM; 5339 1.10 christos else 5340 1.12 christos { 5341 1.12 christos record_buf_mem.push_back (esize / 8); 5342 1.10 christos record_buf_mem.push_back (address + addr_offset); 5343 1.10 christos } 5344 1.10 christos addr_offset = addr_offset + (esize / 8); 5345 1.10 christos reg_tt = (reg_tt + 1) % 32; 5346 1.10 christos } 5347 1.5 christos } 5348 1.5 christos } 5349 1.5 christos 5350 1.5 christos if (bit (aarch64_insn_r->aarch64_insn, 23)) 5351 1.5 christos record_buf[reg_index++] = reg_rn; 5352 1.5 christos 5353 1.12 christos aarch64_insn_r->reg_rec_count = reg_index; 5354 1.5 christos aarch64_insn_r->mem_rec_count = record_buf_mem.size () / 2; 5355 1.12 christos MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count, 5356 1.5 christos record_buf_mem.data ()); 5357 1.10 christos REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count, 5358 1.5 christos record_buf); 5359 1.5 christos return AARCH64_RECORD_SUCCESS; 5360 1.5 christos } 5361 1.11 christos 5362 1.11 christos /* Record handler for Memory Copy and Memory Set instructions. */ 5363 1.11 christos 5364 1.11 christos static unsigned int 5365 1.11 christos aarch64_record_memcopy_memset (aarch64_insn_decode_record *aarch64_insn_r) 5366 1.11 christos { 5367 1.11 christos if (record_debug) 5368 1.11 christos debug_printf ("Process record: memory copy and memory set\n"); 5369 1.11 christos 5370 1.11 christos uint8_t op1 = bits (aarch64_insn_r->aarch64_insn, 22, 23); 5371 1.11 christos uint8_t op2 = bits (aarch64_insn_r->aarch64_insn, 12, 15); 5372 1.11 christos uint32_t reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4); 5373 1.11 christos uint32_t reg_rn = bits (aarch64_insn_r->aarch64_insn, 5, 9); 5374 1.11 christos uint32_t record_buf[3]; 5375 1.11 christos uint64_t record_buf_mem[4]; 5376 1.11 christos 5377 1.11 christos if (op1 == 3 && op2 > 11) 5378 1.11 christos /* Unallocated instructions. */ 5379 1.11 christos return AARCH64_RECORD_UNKNOWN; 5380 1.11 christos 5381 1.11 christos /* Set instructions have two registers and one memory region to be 5382 1.11 christos recorded. */ 5383 1.11 christos record_buf[0] = reg_rd; 5384 1.11 christos record_buf[1] = reg_rn; 5385 1.11 christos aarch64_insn_r->reg_rec_count = 2; 5386 1.11 christos 5387 1.11 christos ULONGEST dest_addr; 5388 1.11 christos regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rd, &dest_addr); 5389 1.11 christos 5390 1.11 christos LONGEST length; 5391 1.11 christos regcache_raw_read_signed (aarch64_insn_r->regcache, reg_rn, &length); 5392 1.11 christos 5393 1.11 christos /* In one of the algorithm options a processor can implement, the length 5394 1.11 christos in Rn has an inverted sign. */ 5395 1.11 christos if (length < 0) 5396 1.11 christos length *= -1; 5397 1.11 christos 5398 1.11 christos record_buf_mem[0] = length; 5399 1.11 christos record_buf_mem[1] = dest_addr; 5400 1.11 christos aarch64_insn_r->mem_rec_count = 1; 5401 1.11 christos 5402 1.11 christos if (op1 != 3) 5403 1.11 christos { 5404 1.11 christos /* Copy instructions have an additional register and an additional 5405 1.11 christos memory region to be recorded. */ 5406 1.11 christos uint32_t reg_rs = bits (aarch64_insn_r->aarch64_insn, 16, 20); 5407 1.11 christos 5408 1.11 christos record_buf[2] = reg_rs; 5409 1.11 christos aarch64_insn_r->reg_rec_count++; 5410 1.11 christos 5411 1.11 christos ULONGEST source_addr; 5412 1.11 christos regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rs, 5413 1.11 christos &source_addr); 5414 1.11 christos 5415 1.11 christos record_buf_mem[2] = length; 5416 1.11 christos record_buf_mem[3] = source_addr; 5417 1.11 christos aarch64_insn_r->mem_rec_count++; 5418 1.11 christos } 5419 1.11 christos 5420 1.11 christos MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count, 5421 1.11 christos record_buf_mem); 5422 1.11 christos REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count, 5423 1.11 christos record_buf); 5424 1.11 christos return AARCH64_RECORD_SUCCESS; 5425 1.11 christos } 5426 1.5 christos 5427 1.5 christos /* Record handler for load and store instructions. */ 5428 1.5 christos 5429 1.10 christos static unsigned int 5430 1.5 christos aarch64_record_load_store (aarch64_insn_decode_record *aarch64_insn_r) 5431 1.5 christos { 5432 1.5 christos uint8_t insn_bits24_27, insn_bits28_29, insn_bits10_11; 5433 1.5 christos uint8_t insn_bit23, insn_bit21; 5434 1.5 christos uint8_t opc, size_bits, ld_flag, vector_flag; 5435 1.5 christos uint32_t reg_rn, reg_rt, reg_rt2; 5436 1.5 christos uint64_t datasize, offset; 5437 1.5 christos uint32_t record_buf[8]; 5438 1.5 christos uint64_t record_buf_mem[8]; 5439 1.5 christos CORE_ADDR address; 5440 1.5 christos 5441 1.5 christos insn_bits10_11 = bits (aarch64_insn_r->aarch64_insn, 10, 11); 5442 1.5 christos insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27); 5443 1.5 christos insn_bits28_29 = bits (aarch64_insn_r->aarch64_insn, 28, 29); 5444 1.5 christos insn_bit21 = bit (aarch64_insn_r->aarch64_insn, 21); 5445 1.5 christos insn_bit23 = bit (aarch64_insn_r->aarch64_insn, 23); 5446 1.5 christos ld_flag = bit (aarch64_insn_r->aarch64_insn, 22); 5447 1.5 christos vector_flag = bit (aarch64_insn_r->aarch64_insn, 26); 5448 1.5 christos reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4); 5449 1.5 christos reg_rn = bits (aarch64_insn_r->aarch64_insn, 5, 9); 5450 1.5 christos reg_rt2 = bits (aarch64_insn_r->aarch64_insn, 10, 14); 5451 1.5 christos size_bits = bits (aarch64_insn_r->aarch64_insn, 30, 31); 5452 1.5 christos 5453 1.5 christos /* Load/store exclusive. */ 5454 1.5 christos if (insn_bits24_27 == 0x08 && insn_bits28_29 == 0x00) 5455 1.5 christos { 5456 1.6 christos if (record_debug) 5457 1.5 christos debug_printf ("Process record: load/store exclusive\n"); 5458 1.5 christos 5459 1.5 christos if (ld_flag) 5460 1.5 christos { 5461 1.5 christos record_buf[0] = reg_rt; 5462 1.5 christos aarch64_insn_r->reg_rec_count = 1; 5463 1.5 christos if (insn_bit21) 5464 1.5 christos { 5465 1.5 christos record_buf[1] = reg_rt2; 5466 1.5 christos aarch64_insn_r->reg_rec_count = 2; 5467 1.5 christos } 5468 1.5 christos } 5469 1.5 christos else 5470 1.5 christos { 5471 1.5 christos if (insn_bit21) 5472 1.5 christos datasize = (8 << size_bits) * 2; 5473 1.5 christos else 5474 1.5 christos datasize = (8 << size_bits); 5475 1.5 christos regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, 5476 1.5 christos &address); 5477 1.5 christos record_buf_mem[0] = datasize / 8; 5478 1.5 christos record_buf_mem[1] = address; 5479 1.5 christos aarch64_insn_r->mem_rec_count = 1; 5480 1.5 christos if (!insn_bit23) 5481 1.5 christos { 5482 1.5 christos /* Save register rs. */ 5483 1.5 christos record_buf[0] = bits (aarch64_insn_r->aarch64_insn, 16, 20); 5484 1.5 christos aarch64_insn_r->reg_rec_count = 1; 5485 1.5 christos } 5486 1.5 christos } 5487 1.5 christos } 5488 1.5 christos /* Load register (literal) instructions decoding. */ 5489 1.5 christos else if ((insn_bits24_27 & 0x0b) == 0x08 && insn_bits28_29 == 0x01) 5490 1.5 christos { 5491 1.6 christos if (record_debug) 5492 1.5 christos debug_printf ("Process record: load register (literal)\n"); 5493 1.10 christos if (vector_flag) 5494 1.5 christos record_buf[0] = reg_rt + AARCH64_V0_REGNUM; 5495 1.10 christos else 5496 1.5 christos record_buf[0] = reg_rt; 5497 1.5 christos aarch64_insn_r->reg_rec_count = 1; 5498 1.5 christos } 5499 1.5 christos /* All types of load/store pair instructions decoding. */ 5500 1.5 christos else if ((insn_bits24_27 & 0x0a) == 0x08 && insn_bits28_29 == 0x02) 5501 1.5 christos { 5502 1.6 christos if (record_debug) 5503 1.5 christos debug_printf ("Process record: load/store pair\n"); 5504 1.5 christos 5505 1.10 christos if (ld_flag) 5506 1.10 christos { 5507 1.10 christos if (vector_flag) 5508 1.10 christos { 5509 1.10 christos record_buf[0] = reg_rt + AARCH64_V0_REGNUM; 5510 1.10 christos record_buf[1] = reg_rt2 + AARCH64_V0_REGNUM; 5511 1.10 christos } 5512 1.10 christos else 5513 1.10 christos { 5514 1.10 christos record_buf[0] = reg_rt; 5515 1.10 christos record_buf[1] = reg_rt2; 5516 1.10 christos } 5517 1.10 christos aarch64_insn_r->reg_rec_count = 2; 5518 1.5 christos } 5519 1.10 christos else 5520 1.10 christos { 5521 1.10 christos uint16_t imm7_off; 5522 1.10 christos imm7_off = bits (aarch64_insn_r->aarch64_insn, 15, 21); 5523 1.10 christos if (!vector_flag) 5524 1.10 christos size_bits = size_bits >> 1; 5525 1.10 christos datasize = 8 << (2 + size_bits); 5526 1.10 christos offset = (imm7_off & 0x40) ? (~imm7_off & 0x007f) + 1 : imm7_off; 5527 1.10 christos offset = offset << (2 + size_bits); 5528 1.10 christos regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, 5529 1.10 christos &address); 5530 1.10 christos if (!((insn_bits24_27 & 0x0b) == 0x08 && insn_bit23)) 5531 1.10 christos { 5532 1.10 christos if (imm7_off & 0x40) 5533 1.10 christos address = address - offset; 5534 1.10 christos else 5535 1.10 christos address = address + offset; 5536 1.10 christos } 5537 1.10 christos 5538 1.10 christos record_buf_mem[0] = datasize / 8; 5539 1.10 christos record_buf_mem[1] = address; 5540 1.10 christos record_buf_mem[2] = datasize / 8; 5541 1.10 christos record_buf_mem[3] = address + (datasize / 8); 5542 1.10 christos aarch64_insn_r->mem_rec_count = 2; 5543 1.5 christos } 5544 1.10 christos if (bit (aarch64_insn_r->aarch64_insn, 23)) 5545 1.5 christos record_buf[aarch64_insn_r->reg_rec_count++] = reg_rn; 5546 1.5 christos } 5547 1.5 christos /* Load/store register (unsigned immediate) instructions. */ 5548 1.5 christos else if ((insn_bits24_27 & 0x0b) == 0x09 && insn_bits28_29 == 0x03) 5549 1.5 christos { 5550 1.5 christos opc = bits (aarch64_insn_r->aarch64_insn, 22, 23); 5551 1.7 christos if (!(opc >> 1)) 5552 1.7 christos { 5553 1.7 christos if (opc & 0x01) 5554 1.7 christos ld_flag = 0x01; 5555 1.7 christos else 5556 1.7 christos ld_flag = 0x0; 5557 1.5 christos } 5558 1.7 christos else 5559 1.7 christos { 5560 1.7 christos if (size_bits == 0x3 && vector_flag == 0x0 && opc == 0x2) 5561 1.7 christos { 5562 1.7 christos /* PRFM (immediate) */ 5563 1.7 christos return AARCH64_RECORD_SUCCESS; 5564 1.7 christos } 5565 1.7 christos else if (size_bits == 0x2 && vector_flag == 0x0 && opc == 0x2) 5566 1.7 christos { 5567 1.7 christos /* LDRSW (immediate) */ 5568 1.7 christos ld_flag = 0x1; 5569 1.7 christos } 5570 1.7 christos else 5571 1.7 christos { 5572 1.7 christos if (opc & 0x01) 5573 1.7 christos ld_flag = 0x01; 5574 1.7 christos else 5575 1.7 christos ld_flag = 0x0; 5576 1.7 christos } 5577 1.5 christos } 5578 1.5 christos 5579 1.5 christos if (record_debug) 5580 1.6 christos { 5581 1.6 christos debug_printf ("Process record: load/store (unsigned immediate):" 5582 1.6 christos " size %x V %d opc %x\n", size_bits, vector_flag, 5583 1.5 christos opc); 5584 1.5 christos } 5585 1.5 christos 5586 1.10 christos if (!ld_flag) 5587 1.10 christos { 5588 1.10 christos offset = bits (aarch64_insn_r->aarch64_insn, 10, 21); 5589 1.10 christos datasize = 8 << size_bits; 5590 1.10 christos regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, 5591 1.10 christos &address); 5592 1.10 christos offset = offset << size_bits; 5593 1.10 christos address = address + offset; 5594 1.10 christos 5595 1.10 christos record_buf_mem[0] = datasize >> 3; 5596 1.10 christos record_buf_mem[1] = address; 5597 1.10 christos aarch64_insn_r->mem_rec_count = 1; 5598 1.5 christos } 5599 1.10 christos else 5600 1.10 christos { 5601 1.10 christos if (vector_flag) 5602 1.10 christos record_buf[0] = reg_rt + AARCH64_V0_REGNUM; 5603 1.10 christos else 5604 1.10 christos record_buf[0] = reg_rt; 5605 1.10 christos aarch64_insn_r->reg_rec_count = 1; 5606 1.5 christos } 5607 1.5 christos } 5608 1.5 christos /* Load/store register (register offset) instructions. */ 5609 1.5 christos else if ((insn_bits24_27 & 0x0b) == 0x08 && insn_bits28_29 == 0x03 5610 1.5 christos && insn_bits10_11 == 0x02 && insn_bit21) 5611 1.5 christos { 5612 1.6 christos if (record_debug) 5613 1.5 christos debug_printf ("Process record: load/store (register offset)\n"); 5614 1.5 christos opc = bits (aarch64_insn_r->aarch64_insn, 22, 23); 5615 1.10 christos if (!(opc >> 1)) 5616 1.10 christos if (opc & 0x01) 5617 1.10 christos ld_flag = 0x01; 5618 1.10 christos else 5619 1.5 christos ld_flag = 0x0; 5620 1.10 christos else 5621 1.10 christos if (size_bits != 0x03) 5622 1.10 christos ld_flag = 0x01; 5623 1.10 christos else 5624 1.5 christos return AARCH64_RECORD_UNKNOWN; 5625 1.5 christos 5626 1.10 christos if (!ld_flag) 5627 1.10 christos { 5628 1.6 christos ULONGEST reg_rm_val; 5629 1.10 christos 5630 1.10 christos regcache_raw_read_unsigned (aarch64_insn_r->regcache, 5631 1.10 christos bits (aarch64_insn_r->aarch64_insn, 16, 20), ®_rm_val); 5632 1.10 christos if (bit (aarch64_insn_r->aarch64_insn, 12)) 5633 1.10 christos offset = reg_rm_val << size_bits; 5634 1.10 christos else 5635 1.10 christos offset = reg_rm_val; 5636 1.10 christos datasize = 8 << size_bits; 5637 1.10 christos regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, 5638 1.10 christos &address); 5639 1.10 christos address = address + offset; 5640 1.10 christos record_buf_mem[0] = datasize >> 3; 5641 1.10 christos record_buf_mem[1] = address; 5642 1.10 christos aarch64_insn_r->mem_rec_count = 1; 5643 1.5 christos } 5644 1.10 christos else 5645 1.10 christos { 5646 1.10 christos if (vector_flag) 5647 1.10 christos record_buf[0] = reg_rt + AARCH64_V0_REGNUM; 5648 1.10 christos else 5649 1.10 christos record_buf[0] = reg_rt; 5650 1.10 christos aarch64_insn_r->reg_rec_count = 1; 5651 1.5 christos } 5652 1.5 christos } 5653 1.5 christos /* Load/store register (immediate and unprivileged) instructions. */ 5654 1.5 christos else if ((insn_bits24_27 & 0x0b) == 0x08 && insn_bits28_29 == 0x03 5655 1.5 christos && !insn_bit21) 5656 1.5 christos { 5657 1.5 christos if (record_debug) 5658 1.6 christos { 5659 1.6 christos debug_printf ("Process record: load/store " 5660 1.5 christos "(immediate and unprivileged)\n"); 5661 1.5 christos } 5662 1.5 christos opc = bits (aarch64_insn_r->aarch64_insn, 22, 23); 5663 1.10 christos if (!(opc >> 1)) 5664 1.10 christos if (opc & 0x01) 5665 1.10 christos ld_flag = 0x01; 5666 1.10 christos else 5667 1.5 christos ld_flag = 0x0; 5668 1.10 christos else 5669 1.10 christos if (size_bits != 0x03) 5670 1.10 christos ld_flag = 0x01; 5671 1.10 christos else 5672 1.5 christos return AARCH64_RECORD_UNKNOWN; 5673 1.5 christos 5674 1.10 christos if (!ld_flag) 5675 1.10 christos { 5676 1.10 christos uint16_t imm9_off; 5677 1.10 christos imm9_off = bits (aarch64_insn_r->aarch64_insn, 12, 20); 5678 1.10 christos offset = (imm9_off & 0x0100) ? (((~imm9_off) & 0x01ff) + 1) : imm9_off; 5679 1.10 christos datasize = 8 << size_bits; 5680 1.10 christos regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, 5681 1.10 christos &address); 5682 1.10 christos if (insn_bits10_11 != 0x01) 5683 1.10 christos { 5684 1.10 christos if (imm9_off & 0x0100) 5685 1.10 christos address = address - offset; 5686 1.10 christos else 5687 1.10 christos address = address + offset; 5688 1.10 christos } 5689 1.10 christos record_buf_mem[0] = datasize >> 3; 5690 1.10 christos record_buf_mem[1] = address; 5691 1.10 christos aarch64_insn_r->mem_rec_count = 1; 5692 1.5 christos } 5693 1.10 christos else 5694 1.10 christos { 5695 1.10 christos if (vector_flag) 5696 1.10 christos record_buf[0] = reg_rt + AARCH64_V0_REGNUM; 5697 1.10 christos else 5698 1.10 christos record_buf[0] = reg_rt; 5699 1.10 christos aarch64_insn_r->reg_rec_count = 1; 5700 1.5 christos } 5701 1.10 christos if (insn_bits10_11 == 0x01 || insn_bits10_11 == 0x03) 5702 1.5 christos record_buf[aarch64_insn_r->reg_rec_count++] = reg_rn; 5703 1.11 christos } 5704 1.11 christos /* Memory Copy and Memory Set instructions. */ 5705 1.11 christos else if ((insn_bits24_27 & 1) == 1 && insn_bits28_29 == 1 5706 1.11 christos && insn_bits10_11 == 1 && !insn_bit21) 5707 1.5 christos return aarch64_record_memcopy_memset (aarch64_insn_r); 5708 1.5 christos /* Advanced SIMD load/store instructions. */ 5709 1.5 christos else 5710 1.5 christos return aarch64_record_asimd_load_store (aarch64_insn_r); 5711 1.5 christos 5712 1.10 christos MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count, 5713 1.5 christos record_buf_mem); 5714 1.10 christos REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count, 5715 1.5 christos record_buf); 5716 1.5 christos return AARCH64_RECORD_SUCCESS; 5717 1.5 christos } 5718 1.5 christos 5719 1.5 christos /* Record handler for data processing SIMD and floating point instructions. */ 5720 1.5 christos 5721 1.10 christos static unsigned int 5722 1.5 christos aarch64_record_data_proc_simd_fp (aarch64_insn_decode_record *aarch64_insn_r) 5723 1.5 christos { 5724 1.5 christos uint8_t insn_bit21, opcode, rmode, reg_rd; 5725 1.5 christos uint8_t insn_bits24_27, insn_bits28_31, insn_bits10_11, insn_bits12_15; 5726 1.5 christos uint8_t insn_bits11_14; 5727 1.5 christos uint32_t record_buf[2]; 5728 1.5 christos 5729 1.5 christos insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27); 5730 1.5 christos insn_bits28_31 = bits (aarch64_insn_r->aarch64_insn, 28, 31); 5731 1.5 christos insn_bits10_11 = bits (aarch64_insn_r->aarch64_insn, 10, 11); 5732 1.5 christos insn_bits12_15 = bits (aarch64_insn_r->aarch64_insn, 12, 15); 5733 1.5 christos insn_bits11_14 = bits (aarch64_insn_r->aarch64_insn, 11, 14); 5734 1.5 christos opcode = bits (aarch64_insn_r->aarch64_insn, 16, 18); 5735 1.5 christos rmode = bits (aarch64_insn_r->aarch64_insn, 19, 20); 5736 1.5 christos reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4); 5737 1.5 christos insn_bit21 = bit (aarch64_insn_r->aarch64_insn, 21); 5738 1.5 christos 5739 1.6 christos if (record_debug) 5740 1.5 christos debug_printf ("Process record: data processing SIMD/FP: "); 5741 1.5 christos 5742 1.5 christos if ((insn_bits28_31 & 0x05) == 0x01 && insn_bits24_27 == 0x0e) 5743 1.5 christos { 5744 1.5 christos /* Floating point - fixed point conversion instructions. */ 5745 1.5 christos if (!insn_bit21) 5746 1.5 christos { 5747 1.6 christos if (record_debug) 5748 1.5 christos debug_printf ("FP - fixed point conversion"); 5749 1.5 christos 5750 1.5 christos if ((opcode >> 1) == 0x0 && rmode == 0x03) 5751 1.5 christos record_buf[0] = reg_rd; 5752 1.5 christos else 5753 1.5 christos record_buf[0] = reg_rd + AARCH64_V0_REGNUM; 5754 1.5 christos } 5755 1.5 christos /* Floating point - conditional compare instructions. */ 5756 1.5 christos else if (insn_bits10_11 == 0x01) 5757 1.5 christos { 5758 1.6 christos if (record_debug) 5759 1.5 christos debug_printf ("FP - conditional compare"); 5760 1.5 christos 5761 1.5 christos record_buf[0] = AARCH64_CPSR_REGNUM; 5762 1.5 christos } 5763 1.10 christos /* Floating point - data processing (2-source) and 5764 1.5 christos conditional select instructions. */ 5765 1.5 christos else if (insn_bits10_11 == 0x02 || insn_bits10_11 == 0x03) 5766 1.5 christos { 5767 1.6 christos if (record_debug) 5768 1.5 christos debug_printf ("FP - DP (2-source)"); 5769 1.5 christos 5770 1.5 christos record_buf[0] = reg_rd + AARCH64_V0_REGNUM; 5771 1.5 christos } 5772 1.5 christos else if (insn_bits10_11 == 0x00) 5773 1.5 christos { 5774 1.5 christos /* Floating point - immediate instructions. */ 5775 1.5 christos if ((insn_bits12_15 & 0x01) == 0x01 5776 1.5 christos || (insn_bits12_15 & 0x07) == 0x04) 5777 1.5 christos { 5778 1.6 christos if (record_debug) 5779 1.5 christos debug_printf ("FP - immediate"); 5780 1.5 christos record_buf[0] = reg_rd + AARCH64_V0_REGNUM; 5781 1.5 christos } 5782 1.5 christos /* Floating point - compare instructions. */ 5783 1.5 christos else if ((insn_bits12_15 & 0x03) == 0x02) 5784 1.5 christos { 5785 1.6 christos if (record_debug) 5786 1.5 christos debug_printf ("FP - immediate"); 5787 1.5 christos record_buf[0] = AARCH64_CPSR_REGNUM; 5788 1.5 christos } 5789 1.5 christos /* Floating point - integer conversions instructions. */ 5790 1.5 christos else if (insn_bits12_15 == 0x00) 5791 1.5 christos { 5792 1.5 christos /* Convert float to integer instruction. */ 5793 1.5 christos if (!(opcode >> 1) || ((opcode >> 1) == 0x02 && !rmode)) 5794 1.5 christos { 5795 1.6 christos if (record_debug) 5796 1.5 christos debug_printf ("float to int conversion"); 5797 1.5 christos 5798 1.5 christos record_buf[0] = reg_rd + AARCH64_X0_REGNUM; 5799 1.5 christos } 5800 1.5 christos /* Convert integer to float instruction. */ 5801 1.5 christos else if ((opcode >> 1) == 0x01 && !rmode) 5802 1.5 christos { 5803 1.6 christos if (record_debug) 5804 1.5 christos debug_printf ("int to float conversion"); 5805 1.5 christos 5806 1.5 christos record_buf[0] = reg_rd + AARCH64_V0_REGNUM; 5807 1.5 christos } 5808 1.5 christos /* Move float to integer instruction. */ 5809 1.5 christos else if ((opcode >> 1) == 0x03) 5810 1.5 christos { 5811 1.6 christos if (record_debug) 5812 1.5 christos debug_printf ("move float to int"); 5813 1.5 christos 5814 1.5 christos if (!(opcode & 0x01)) 5815 1.5 christos record_buf[0] = reg_rd + AARCH64_X0_REGNUM; 5816 1.5 christos else 5817 1.5 christos record_buf[0] = reg_rd + AARCH64_V0_REGNUM; 5818 1.5 christos } 5819 1.5 christos else 5820 1.10 christos return AARCH64_RECORD_UNKNOWN; 5821 1.5 christos } 5822 1.5 christos else 5823 1.10 christos return AARCH64_RECORD_UNKNOWN; 5824 1.5 christos } 5825 1.5 christos else 5826 1.5 christos return AARCH64_RECORD_UNKNOWN; 5827 1.5 christos } 5828 1.5 christos else if ((insn_bits28_31 & 0x09) == 0x00 && insn_bits24_27 == 0x0e) 5829 1.5 christos { 5830 1.6 christos if (record_debug) 5831 1.5 christos debug_printf ("SIMD copy"); 5832 1.5 christos 5833 1.5 christos /* Advanced SIMD copy instructions. */ 5834 1.5 christos if (!bits (aarch64_insn_r->aarch64_insn, 21, 23) 5835 1.5 christos && !bit (aarch64_insn_r->aarch64_insn, 15) 5836 1.5 christos && bit (aarch64_insn_r->aarch64_insn, 10)) 5837 1.5 christos { 5838 1.5 christos if (insn_bits11_14 == 0x05 || insn_bits11_14 == 0x07) 5839 1.5 christos record_buf[0] = reg_rd + AARCH64_X0_REGNUM; 5840 1.5 christos else 5841 1.5 christos record_buf[0] = reg_rd + AARCH64_V0_REGNUM; 5842 1.5 christos } 5843 1.5 christos else 5844 1.5 christos record_buf[0] = reg_rd + AARCH64_V0_REGNUM; 5845 1.5 christos } 5846 1.5 christos /* All remaining floating point or advanced SIMD instructions. */ 5847 1.5 christos else 5848 1.5 christos { 5849 1.6 christos if (record_debug) 5850 1.5 christos debug_printf ("all remain"); 5851 1.5 christos 5852 1.5 christos record_buf[0] = reg_rd + AARCH64_V0_REGNUM; 5853 1.5 christos } 5854 1.5 christos 5855 1.6 christos if (record_debug) 5856 1.5 christos debug_printf ("\n"); 5857 1.10 christos 5858 1.10 christos /* Record the V/X register. */ 5859 1.10 christos aarch64_insn_r->reg_rec_count++; 5860 1.10 christos 5861 1.10 christos /* Some of these instructions may set bits in the FPSR, so record it 5862 1.10 christos too. */ 5863 1.5 christos record_buf[1] = AARCH64_FPSR_REGNUM; 5864 1.10 christos aarch64_insn_r->reg_rec_count++; 5865 1.10 christos 5866 1.5 christos gdb_assert (aarch64_insn_r->reg_rec_count == 2); 5867 1.5 christos REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count, 5868 1.5 christos record_buf); 5869 1.5 christos return AARCH64_RECORD_SUCCESS; 5870 1.5 christos } 5871 1.5 christos 5872 1.5 christos /* Decodes insns type and invokes its record handler. */ 5873 1.5 christos 5874 1.10 christos static unsigned int 5875 1.5 christos aarch64_record_decode_insn_handler (aarch64_insn_decode_record *aarch64_insn_r) 5876 1.5 christos { 5877 1.5 christos uint32_t ins_bit25, ins_bit26, ins_bit27, ins_bit28; 5878 1.5 christos 5879 1.5 christos ins_bit25 = bit (aarch64_insn_r->aarch64_insn, 25); 5880 1.5 christos ins_bit26 = bit (aarch64_insn_r->aarch64_insn, 26); 5881 1.5 christos ins_bit27 = bit (aarch64_insn_r->aarch64_insn, 27); 5882 1.5 christos ins_bit28 = bit (aarch64_insn_r->aarch64_insn, 28); 5883 1.5 christos 5884 1.5 christos /* Data processing - immediate instructions. */ 5885 1.5 christos if (!ins_bit26 && !ins_bit27 && ins_bit28) 5886 1.5 christos return aarch64_record_data_proc_imm (aarch64_insn_r); 5887 1.5 christos 5888 1.5 christos /* Branch, exception generation and system instructions. */ 5889 1.5 christos if (ins_bit26 && !ins_bit27 && ins_bit28) 5890 1.5 christos return aarch64_record_branch_except_sys (aarch64_insn_r); 5891 1.5 christos 5892 1.5 christos /* Load and store instructions. */ 5893 1.5 christos if (!ins_bit25 && ins_bit27) 5894 1.5 christos return aarch64_record_load_store (aarch64_insn_r); 5895 1.5 christos 5896 1.5 christos /* Data processing - register instructions. */ 5897 1.5 christos if (ins_bit25 && !ins_bit26 && ins_bit27) 5898 1.5 christos return aarch64_record_data_proc_reg (aarch64_insn_r); 5899 1.5 christos 5900 1.5 christos /* Data processing - SIMD and floating point instructions. */ 5901 1.5 christos if (ins_bit25 && ins_bit26 && ins_bit27) 5902 1.5 christos return aarch64_record_data_proc_simd_fp (aarch64_insn_r); 5903 1.5 christos 5904 1.5 christos return AARCH64_RECORD_UNSUPPORTED; 5905 1.5 christos } 5906 1.5 christos 5907 1.5 christos /* Cleans up local record registers and memory allocations. */ 5908 1.5 christos 5909 1.10 christos static void 5910 1.5 christos deallocate_reg_mem (aarch64_insn_decode_record *record) 5911 1.5 christos { 5912 1.5 christos xfree (record->aarch64_regs); 5913 1.5 christos xfree (record->aarch64_mems); 5914 1.5 christos } 5915 1.7 christos 5916 1.7 christos #if GDB_SELF_TEST 5917 1.7 christos namespace selftests { 5918 1.7 christos 5919 1.7 christos static void 5920 1.7 christos aarch64_process_record_test (void) 5921 1.7 christos { 5922 1.7 christos struct gdbarch_info info; 5923 1.7 christos uint32_t ret; 5924 1.7 christos 5925 1.7 christos info.bfd_arch_info = bfd_scan_arch ("aarch64"); 5926 1.7 christos 5927 1.7 christos struct gdbarch *gdbarch = gdbarch_find_by_info (info); 5928 1.7 christos SELF_CHECK (gdbarch != NULL); 5929 1.10 christos 5930 1.7 christos aarch64_insn_decode_record aarch64_record; 5931 1.10 christos 5932 1.7 christos memset (&aarch64_record, 0, sizeof (aarch64_insn_decode_record)); 5933 1.7 christos aarch64_record.regcache = NULL; 5934 1.7 christos aarch64_record.this_addr = 0; 5935 1.7 christos aarch64_record.gdbarch = gdbarch; 5936 1.7 christos 5937 1.7 christos /* 20 00 80 f9 prfm pldl1keep, [x1] */ 5938 1.7 christos aarch64_record.aarch64_insn = 0xf9800020; 5939 1.7 christos ret = aarch64_record_decode_insn_handler (&aarch64_record); 5940 1.7 christos SELF_CHECK (ret == AARCH64_RECORD_SUCCESS); 5941 1.7 christos SELF_CHECK (aarch64_record.reg_rec_count == 0); 5942 1.7 christos SELF_CHECK (aarch64_record.mem_rec_count == 0); 5943 1.7 christos 5944 1.7 christos deallocate_reg_mem (&aarch64_record); 5945 1.7 christos } 5946 1.7 christos 5947 1.7 christos } // namespace selftests 5948 1.7 christos #endif /* GDB_SELF_TEST */ 5949 1.5 christos 5950 1.5 christos /* Parse the current instruction and record the values of the registers and 5951 1.5 christos memory that will be changed in current instruction to record_arch_list 5952 1.5 christos return -1 if something is wrong. */ 5953 1.5 christos 5954 1.5 christos int 5955 1.5 christos aarch64_process_record (struct gdbarch *gdbarch, struct regcache *regcache, 5956 1.5 christos CORE_ADDR insn_addr) 5957 1.5 christos { 5958 1.11 christos uint32_t rec_no = 0; 5959 1.5 christos const uint8_t insn_size = 4; 5960 1.5 christos uint32_t ret = 0; 5961 1.10 christos gdb_byte buf[insn_size]; 5962 1.5 christos aarch64_insn_decode_record aarch64_record; 5963 1.5 christos 5964 1.10 christos memset (&buf[0], 0, insn_size); 5965 1.5 christos memset (&aarch64_record, 0, sizeof (aarch64_insn_decode_record)); 5966 1.5 christos target_read_memory (insn_addr, &buf[0], insn_size); 5967 1.5 christos aarch64_record.aarch64_insn 5968 1.5 christos = (uint32_t) extract_unsigned_integer (&buf[0], 5969 1.5 christos insn_size, 5970 1.5 christos gdbarch_byte_order (gdbarch)); 5971 1.5 christos aarch64_record.regcache = regcache; 5972 1.5 christos aarch64_record.this_addr = insn_addr; 5973 1.5 christos aarch64_record.gdbarch = gdbarch; 5974 1.5 christos 5975 1.5 christos ret = aarch64_record_decode_insn_handler (&aarch64_record); 5976 1.5 christos if (ret == AARCH64_RECORD_UNSUPPORTED) 5977 1.10 christos { 5978 1.10 christos gdb_printf (gdb_stderr, 5979 1.10 christos _("Process record does not support instruction " 5980 1.10 christos "0x%0x at address %s.\n"), 5981 1.10 christos aarch64_record.aarch64_insn, 5982 1.5 christos paddress (gdbarch, insn_addr)); 5983 1.5 christos ret = -1; 5984 1.5 christos } 5985 1.5 christos 5986 1.5 christos if (0 == ret) 5987 1.5 christos { 5988 1.5 christos /* Record registers. */ 5989 1.5 christos record_full_arch_list_add_reg (aarch64_record.regcache, 5990 1.5 christos AARCH64_PC_REGNUM); 5991 1.5 christos /* Always record register CPSR. */ 5992 1.5 christos record_full_arch_list_add_reg (aarch64_record.regcache, 5993 1.5 christos AARCH64_CPSR_REGNUM); 5994 1.5 christos if (aarch64_record.aarch64_regs) 5995 1.5 christos for (rec_no = 0; rec_no < aarch64_record.reg_rec_count; rec_no++) 5996 1.5 christos if (record_full_arch_list_add_reg (aarch64_record.regcache, 5997 1.5 christos aarch64_record.aarch64_regs[rec_no])) 5998 1.5 christos ret = -1; 5999 1.5 christos 6000 1.5 christos /* Record memories. */ 6001 1.5 christos if (aarch64_record.aarch64_mems) 6002 1.5 christos for (rec_no = 0; rec_no < aarch64_record.mem_rec_count; rec_no++) 6003 1.5 christos if (record_full_arch_list_add_mem 6004 1.5 christos ((CORE_ADDR)aarch64_record.aarch64_mems[rec_no].addr, 6005 1.5 christos aarch64_record.aarch64_mems[rec_no].len)) 6006 1.5 christos ret = -1; 6007 1.5 christos 6008 1.5 christos if (record_full_arch_list_add_end ()) 6009 1.5 christos ret = -1; 6010 1.5 christos } 6011 1.5 christos 6012 1.5 christos deallocate_reg_mem (&aarch64_record); 6013 1.5 christos return ret; 6014 } 6015