aarch64-tdep.c revision 1.7 1 1.1 christos /* Common target dependent code for GDB on AArch64 systems.
2 1.1 christos
3 1.7 christos Copyright (C) 2009-2017 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 #include "defs.h"
22 1.1 christos
23 1.1 christos #include "frame.h"
24 1.1 christos #include "inferior.h"
25 1.1 christos #include "gdbcmd.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 "doublest.h"
31 1.1 christos #include "value.h"
32 1.1 christos #include "arch-utils.h"
33 1.1 christos #include "osabi.h"
34 1.1 christos #include "frame-unwind.h"
35 1.1 christos #include "frame-base.h"
36 1.1 christos #include "trad-frame.h"
37 1.1 christos #include "objfiles.h"
38 1.1 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.1 christos #include "language.h"
44 1.1 christos #include "infcall.h"
45 1.6 christos #include "ax.h"
46 1.6 christos #include "ax-gdb.h"
47 1.7 christos #include "selftest.h"
48 1.1 christos
49 1.1 christos #include "aarch64-tdep.h"
50 1.1 christos
51 1.1 christos #include "elf-bfd.h"
52 1.1 christos #include "elf/aarch64.h"
53 1.1 christos
54 1.1 christos #include "vec.h"
55 1.1 christos
56 1.5 christos #include "record.h"
57 1.5 christos #include "record-full.h"
58 1.5 christos
59 1.1 christos #include "features/aarch64.c"
60 1.1 christos
61 1.6 christos #include "arch/aarch64-insn.h"
62 1.6 christos
63 1.6 christos #include "opcode/aarch64.h"
64 1.7 christos #include <algorithm>
65 1.6 christos
66 1.6 christos #define submask(x) ((1L << ((x) + 1)) - 1)
67 1.6 christos #define bit(obj,st) (((obj) >> (st)) & 1)
68 1.6 christos #define bits(obj,st,fn) (((obj) >> (st)) & submask ((fn) - (st)))
69 1.6 christos
70 1.1 christos /* Pseudo register base numbers. */
71 1.1 christos #define AARCH64_Q0_REGNUM 0
72 1.7 christos #define AARCH64_D0_REGNUM (AARCH64_Q0_REGNUM + AARCH64_D_REGISTER_COUNT)
73 1.1 christos #define AARCH64_S0_REGNUM (AARCH64_D0_REGNUM + 32)
74 1.1 christos #define AARCH64_H0_REGNUM (AARCH64_S0_REGNUM + 32)
75 1.1 christos #define AARCH64_B0_REGNUM (AARCH64_H0_REGNUM + 32)
76 1.1 christos
77 1.1 christos /* The standard register names, and all the valid aliases for them. */
78 1.1 christos static const struct
79 1.1 christos {
80 1.1 christos const char *const name;
81 1.1 christos int regnum;
82 1.1 christos } aarch64_register_aliases[] =
83 1.1 christos {
84 1.1 christos /* 64-bit register names. */
85 1.1 christos {"fp", AARCH64_FP_REGNUM},
86 1.1 christos {"lr", AARCH64_LR_REGNUM},
87 1.1 christos {"sp", AARCH64_SP_REGNUM},
88 1.1 christos
89 1.1 christos /* 32-bit register names. */
90 1.1 christos {"w0", AARCH64_X0_REGNUM + 0},
91 1.1 christos {"w1", AARCH64_X0_REGNUM + 1},
92 1.1 christos {"w2", AARCH64_X0_REGNUM + 2},
93 1.1 christos {"w3", AARCH64_X0_REGNUM + 3},
94 1.1 christos {"w4", AARCH64_X0_REGNUM + 4},
95 1.1 christos {"w5", AARCH64_X0_REGNUM + 5},
96 1.1 christos {"w6", AARCH64_X0_REGNUM + 6},
97 1.1 christos {"w7", AARCH64_X0_REGNUM + 7},
98 1.1 christos {"w8", AARCH64_X0_REGNUM + 8},
99 1.1 christos {"w9", AARCH64_X0_REGNUM + 9},
100 1.1 christos {"w10", AARCH64_X0_REGNUM + 10},
101 1.1 christos {"w11", AARCH64_X0_REGNUM + 11},
102 1.1 christos {"w12", AARCH64_X0_REGNUM + 12},
103 1.1 christos {"w13", AARCH64_X0_REGNUM + 13},
104 1.1 christos {"w14", AARCH64_X0_REGNUM + 14},
105 1.1 christos {"w15", AARCH64_X0_REGNUM + 15},
106 1.1 christos {"w16", AARCH64_X0_REGNUM + 16},
107 1.1 christos {"w17", AARCH64_X0_REGNUM + 17},
108 1.1 christos {"w18", AARCH64_X0_REGNUM + 18},
109 1.1 christos {"w19", AARCH64_X0_REGNUM + 19},
110 1.1 christos {"w20", AARCH64_X0_REGNUM + 20},
111 1.1 christos {"w21", AARCH64_X0_REGNUM + 21},
112 1.1 christos {"w22", AARCH64_X0_REGNUM + 22},
113 1.1 christos {"w23", AARCH64_X0_REGNUM + 23},
114 1.1 christos {"w24", AARCH64_X0_REGNUM + 24},
115 1.1 christos {"w25", AARCH64_X0_REGNUM + 25},
116 1.1 christos {"w26", AARCH64_X0_REGNUM + 26},
117 1.1 christos {"w27", AARCH64_X0_REGNUM + 27},
118 1.1 christos {"w28", AARCH64_X0_REGNUM + 28},
119 1.1 christos {"w29", AARCH64_X0_REGNUM + 29},
120 1.1 christos {"w30", AARCH64_X0_REGNUM + 30},
121 1.1 christos
122 1.1 christos /* specials */
123 1.1 christos {"ip0", AARCH64_X0_REGNUM + 16},
124 1.1 christos {"ip1", AARCH64_X0_REGNUM + 17}
125 1.1 christos };
126 1.1 christos
127 1.1 christos /* The required core 'R' registers. */
128 1.1 christos static const char *const aarch64_r_register_names[] =
129 1.1 christos {
130 1.1 christos /* These registers must appear in consecutive RAW register number
131 1.1 christos order and they must begin with AARCH64_X0_REGNUM! */
132 1.1 christos "x0", "x1", "x2", "x3",
133 1.1 christos "x4", "x5", "x6", "x7",
134 1.1 christos "x8", "x9", "x10", "x11",
135 1.1 christos "x12", "x13", "x14", "x15",
136 1.1 christos "x16", "x17", "x18", "x19",
137 1.1 christos "x20", "x21", "x22", "x23",
138 1.1 christos "x24", "x25", "x26", "x27",
139 1.1 christos "x28", "x29", "x30", "sp",
140 1.1 christos "pc", "cpsr"
141 1.1 christos };
142 1.1 christos
143 1.1 christos /* The FP/SIMD 'V' registers. */
144 1.1 christos static const char *const aarch64_v_register_names[] =
145 1.1 christos {
146 1.1 christos /* These registers must appear in consecutive RAW register number
147 1.1 christos order and they must begin with AARCH64_V0_REGNUM! */
148 1.1 christos "v0", "v1", "v2", "v3",
149 1.1 christos "v4", "v5", "v6", "v7",
150 1.1 christos "v8", "v9", "v10", "v11",
151 1.1 christos "v12", "v13", "v14", "v15",
152 1.1 christos "v16", "v17", "v18", "v19",
153 1.1 christos "v20", "v21", "v22", "v23",
154 1.1 christos "v24", "v25", "v26", "v27",
155 1.1 christos "v28", "v29", "v30", "v31",
156 1.1 christos "fpsr",
157 1.1 christos "fpcr"
158 1.1 christos };
159 1.1 christos
160 1.1 christos /* AArch64 prologue cache structure. */
161 1.1 christos struct aarch64_prologue_cache
162 1.1 christos {
163 1.6 christos /* The program counter at the start of the function. It is used to
164 1.6 christos identify this frame as a prologue frame. */
165 1.6 christos CORE_ADDR func;
166 1.6 christos
167 1.6 christos /* The program counter at the time this frame was created; i.e. where
168 1.6 christos this function was called from. It is used to identify this frame as a
169 1.6 christos stub frame. */
170 1.6 christos CORE_ADDR prev_pc;
171 1.6 christos
172 1.1 christos /* The stack pointer at the time this frame was created; i.e. the
173 1.1 christos caller's stack pointer when this function was called. It is used
174 1.1 christos to identify this frame. */
175 1.1 christos CORE_ADDR prev_sp;
176 1.1 christos
177 1.6 christos /* Is the target available to read from? */
178 1.6 christos int available_p;
179 1.6 christos
180 1.1 christos /* The frame base for this frame is just prev_sp - frame size.
181 1.1 christos FRAMESIZE is the distance from the frame pointer to the
182 1.1 christos initial stack pointer. */
183 1.1 christos int framesize;
184 1.1 christos
185 1.1 christos /* The register used to hold the frame pointer for this frame. */
186 1.1 christos int framereg;
187 1.1 christos
188 1.1 christos /* Saved register offsets. */
189 1.1 christos struct trad_frame_saved_reg *saved_regs;
190 1.1 christos };
191 1.1 christos
192 1.1 christos static void
193 1.1 christos show_aarch64_debug (struct ui_file *file, int from_tty,
194 1.1 christos struct cmd_list_element *c, const char *value)
195 1.1 christos {
196 1.1 christos fprintf_filtered (file, _("AArch64 debugging is %s.\n"), value);
197 1.1 christos }
198 1.1 christos
199 1.7 christos namespace {
200 1.7 christos
201 1.7 christos /* Abstract instruction reader. */
202 1.7 christos
203 1.7 christos class abstract_instruction_reader
204 1.7 christos {
205 1.7 christos public:
206 1.7 christos /* Read in one instruction. */
207 1.7 christos virtual ULONGEST read (CORE_ADDR memaddr, int len,
208 1.7 christos enum bfd_endian byte_order) = 0;
209 1.7 christos };
210 1.7 christos
211 1.7 christos /* Instruction reader from real target. */
212 1.7 christos
213 1.7 christos class instruction_reader : public abstract_instruction_reader
214 1.7 christos {
215 1.7 christos public:
216 1.7 christos ULONGEST read (CORE_ADDR memaddr, int len, enum bfd_endian byte_order)
217 1.7 christos {
218 1.7 christos return read_code_unsigned_integer (memaddr, len, byte_order);
219 1.7 christos }
220 1.7 christos };
221 1.7 christos
222 1.7 christos } // namespace
223 1.7 christos
224 1.1 christos /* Analyze a prologue, looking for a recognizable stack frame
225 1.1 christos and frame pointer. Scan until we encounter a store that could
226 1.1 christos clobber the stack frame unexpectedly, or an unknown instruction. */
227 1.1 christos
228 1.1 christos static CORE_ADDR
229 1.1 christos aarch64_analyze_prologue (struct gdbarch *gdbarch,
230 1.1 christos CORE_ADDR start, CORE_ADDR limit,
231 1.7 christos struct aarch64_prologue_cache *cache,
232 1.7 christos abstract_instruction_reader& reader)
233 1.1 christos {
234 1.1 christos enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
235 1.1 christos int i;
236 1.7 christos /* Track X registers and D registers in prologue. */
237 1.7 christos pv_t regs[AARCH64_X_REGISTER_COUNT + AARCH64_D_REGISTER_COUNT];
238 1.1 christos struct pv_area *stack;
239 1.1 christos struct cleanup *back_to;
240 1.1 christos
241 1.7 christos for (i = 0; i < AARCH64_X_REGISTER_COUNT + AARCH64_D_REGISTER_COUNT; i++)
242 1.1 christos regs[i] = pv_register (i, 0);
243 1.1 christos stack = make_pv_area (AARCH64_SP_REGNUM, gdbarch_addr_bit (gdbarch));
244 1.1 christos back_to = make_cleanup_free_pv_area (stack);
245 1.1 christos
246 1.1 christos for (; start < limit; start += 4)
247 1.1 christos {
248 1.1 christos uint32_t insn;
249 1.6 christos aarch64_inst inst;
250 1.1 christos
251 1.7 christos insn = reader.read (start, 4, byte_order_for_code);
252 1.1 christos
253 1.6 christos if (aarch64_decode_insn (insn, &inst, 1) != 0)
254 1.6 christos break;
255 1.6 christos
256 1.6 christos if (inst.opcode->iclass == addsub_imm
257 1.6 christos && (inst.opcode->op == OP_ADD
258 1.6 christos || strcmp ("sub", inst.opcode->name) == 0))
259 1.6 christos {
260 1.6 christos unsigned rd = inst.operands[0].reg.regno;
261 1.6 christos unsigned rn = inst.operands[1].reg.regno;
262 1.6 christos
263 1.6 christos gdb_assert (aarch64_num_of_operands (inst.opcode) == 3);
264 1.6 christos gdb_assert (inst.operands[0].type == AARCH64_OPND_Rd_SP);
265 1.6 christos gdb_assert (inst.operands[1].type == AARCH64_OPND_Rn_SP);
266 1.6 christos gdb_assert (inst.operands[2].type == AARCH64_OPND_AIMM);
267 1.6 christos
268 1.6 christos if (inst.opcode->op == OP_ADD)
269 1.6 christos {
270 1.6 christos regs[rd] = pv_add_constant (regs[rn],
271 1.6 christos inst.operands[2].imm.value);
272 1.6 christos }
273 1.6 christos else
274 1.6 christos {
275 1.6 christos regs[rd] = pv_add_constant (regs[rn],
276 1.6 christos -inst.operands[2].imm.value);
277 1.6 christos }
278 1.6 christos }
279 1.6 christos else if (inst.opcode->iclass == pcreladdr
280 1.6 christos && inst.operands[1].type == AARCH64_OPND_ADDR_ADRP)
281 1.6 christos {
282 1.6 christos gdb_assert (aarch64_num_of_operands (inst.opcode) == 2);
283 1.6 christos gdb_assert (inst.operands[0].type == AARCH64_OPND_Rd);
284 1.6 christos
285 1.6 christos regs[inst.operands[0].reg.regno] = pv_unknown ();
286 1.6 christos }
287 1.6 christos else if (inst.opcode->iclass == branch_imm)
288 1.1 christos {
289 1.1 christos /* Stop analysis on branch. */
290 1.1 christos break;
291 1.1 christos }
292 1.6 christos else if (inst.opcode->iclass == condbranch)
293 1.1 christos {
294 1.1 christos /* Stop analysis on branch. */
295 1.1 christos break;
296 1.1 christos }
297 1.6 christos else if (inst.opcode->iclass == branch_reg)
298 1.1 christos {
299 1.1 christos /* Stop analysis on branch. */
300 1.1 christos break;
301 1.1 christos }
302 1.6 christos else if (inst.opcode->iclass == compbranch)
303 1.1 christos {
304 1.1 christos /* Stop analysis on branch. */
305 1.1 christos break;
306 1.1 christos }
307 1.6 christos else if (inst.opcode->op == OP_MOVZ)
308 1.1 christos {
309 1.6 christos gdb_assert (inst.operands[0].type == AARCH64_OPND_Rd);
310 1.6 christos regs[inst.operands[0].reg.regno] = pv_unknown ();
311 1.1 christos }
312 1.6 christos else if (inst.opcode->iclass == log_shift
313 1.6 christos && strcmp (inst.opcode->name, "orr") == 0)
314 1.1 christos {
315 1.6 christos unsigned rd = inst.operands[0].reg.regno;
316 1.6 christos unsigned rn = inst.operands[1].reg.regno;
317 1.6 christos unsigned rm = inst.operands[2].reg.regno;
318 1.6 christos
319 1.6 christos gdb_assert (inst.operands[0].type == AARCH64_OPND_Rd);
320 1.6 christos gdb_assert (inst.operands[1].type == AARCH64_OPND_Rn);
321 1.6 christos gdb_assert (inst.operands[2].type == AARCH64_OPND_Rm_SFT);
322 1.6 christos
323 1.6 christos if (inst.operands[2].shifter.amount == 0
324 1.6 christos && rn == AARCH64_SP_REGNUM)
325 1.1 christos regs[rd] = regs[rm];
326 1.1 christos else
327 1.1 christos {
328 1.1 christos if (aarch64_debug)
329 1.6 christos {
330 1.6 christos debug_printf ("aarch64: prologue analysis gave up "
331 1.6 christos "addr=%s opcode=0x%x (orr x register)\n",
332 1.6 christos core_addr_to_string_nz (start), insn);
333 1.6 christos }
334 1.1 christos break;
335 1.1 christos }
336 1.1 christos }
337 1.6 christos else if (inst.opcode->op == OP_STUR)
338 1.1 christos {
339 1.6 christos unsigned rt = inst.operands[0].reg.regno;
340 1.6 christos unsigned rn = inst.operands[1].addr.base_regno;
341 1.6 christos int is64
342 1.6 christos = (aarch64_get_qualifier_esize (inst.operands[0].qualifier) == 8);
343 1.6 christos
344 1.6 christos gdb_assert (aarch64_num_of_operands (inst.opcode) == 2);
345 1.6 christos gdb_assert (inst.operands[0].type == AARCH64_OPND_Rt);
346 1.6 christos gdb_assert (inst.operands[1].type == AARCH64_OPND_ADDR_SIMM9);
347 1.6 christos gdb_assert (!inst.operands[1].addr.offset.is_reg);
348 1.6 christos
349 1.6 christos pv_area_store (stack, pv_add_constant (regs[rn],
350 1.6 christos inst.operands[1].addr.offset.imm),
351 1.1 christos is64 ? 8 : 4, regs[rt]);
352 1.1 christos }
353 1.6 christos else if ((inst.opcode->iclass == ldstpair_off
354 1.6 christos || (inst.opcode->iclass == ldstpair_indexed
355 1.6 christos && inst.operands[2].addr.preind))
356 1.6 christos && strcmp ("stp", inst.opcode->name) == 0)
357 1.6 christos {
358 1.6 christos /* STP with addressing mode Pre-indexed and Base register. */
359 1.7 christos unsigned rt1;
360 1.7 christos unsigned rt2;
361 1.6 christos unsigned rn = inst.operands[2].addr.base_regno;
362 1.6 christos int32_t imm = inst.operands[2].addr.offset.imm;
363 1.6 christos
364 1.7 christos gdb_assert (inst.operands[0].type == AARCH64_OPND_Rt
365 1.7 christos || inst.operands[0].type == AARCH64_OPND_Ft);
366 1.7 christos gdb_assert (inst.operands[1].type == AARCH64_OPND_Rt2
367 1.7 christos || inst.operands[1].type == AARCH64_OPND_Ft2);
368 1.6 christos gdb_assert (inst.operands[2].type == AARCH64_OPND_ADDR_SIMM7);
369 1.6 christos gdb_assert (!inst.operands[2].addr.offset.is_reg);
370 1.6 christos
371 1.1 christos /* If recording this store would invalidate the store area
372 1.1 christos (perhaps because rn is not known) then we should abandon
373 1.1 christos further prologue analysis. */
374 1.1 christos if (pv_area_store_would_trash (stack,
375 1.1 christos pv_add_constant (regs[rn], imm)))
376 1.1 christos break;
377 1.1 christos
378 1.1 christos if (pv_area_store_would_trash (stack,
379 1.1 christos pv_add_constant (regs[rn], imm + 8)))
380 1.1 christos break;
381 1.1 christos
382 1.7 christos rt1 = inst.operands[0].reg.regno;
383 1.7 christos rt2 = inst.operands[1].reg.regno;
384 1.7 christos if (inst.operands[0].type == AARCH64_OPND_Ft)
385 1.7 christos {
386 1.7 christos /* Only bottom 64-bit of each V register (D register) need
387 1.7 christos to be preserved. */
388 1.7 christos gdb_assert (inst.operands[0].qualifier == AARCH64_OPND_QLF_S_D);
389 1.7 christos rt1 += AARCH64_X_REGISTER_COUNT;
390 1.7 christos rt2 += AARCH64_X_REGISTER_COUNT;
391 1.7 christos }
392 1.7 christos
393 1.1 christos pv_area_store (stack, pv_add_constant (regs[rn], imm), 8,
394 1.1 christos regs[rt1]);
395 1.1 christos pv_area_store (stack, pv_add_constant (regs[rn], imm + 8), 8,
396 1.1 christos regs[rt2]);
397 1.1 christos
398 1.6 christos if (inst.operands[2].addr.writeback)
399 1.6 christos regs[rn] = pv_add_constant (regs[rn], imm);
400 1.1 christos
401 1.1 christos }
402 1.7 christos else if ((inst.opcode->iclass == ldst_imm9 /* Signed immediate. */
403 1.7 christos || (inst.opcode->iclass == ldst_pos /* Unsigned immediate. */
404 1.7 christos && (inst.opcode->op == OP_STR_POS
405 1.7 christos || inst.opcode->op == OP_STRF_POS)))
406 1.7 christos && inst.operands[1].addr.base_regno == AARCH64_SP_REGNUM
407 1.7 christos && strcmp ("str", inst.opcode->name) == 0)
408 1.7 christos {
409 1.7 christos /* STR (immediate) */
410 1.7 christos unsigned int rt = inst.operands[0].reg.regno;
411 1.7 christos int32_t imm = inst.operands[1].addr.offset.imm;
412 1.7 christos unsigned int rn = inst.operands[1].addr.base_regno;
413 1.7 christos bool is64
414 1.7 christos = (aarch64_get_qualifier_esize (inst.operands[0].qualifier) == 8);
415 1.7 christos gdb_assert (inst.operands[0].type == AARCH64_OPND_Rt
416 1.7 christos || inst.operands[0].type == AARCH64_OPND_Ft);
417 1.7 christos
418 1.7 christos if (inst.operands[0].type == AARCH64_OPND_Ft)
419 1.7 christos {
420 1.7 christos /* Only bottom 64-bit of each V register (D register) need
421 1.7 christos to be preserved. */
422 1.7 christos gdb_assert (inst.operands[0].qualifier == AARCH64_OPND_QLF_S_D);
423 1.7 christos rt += AARCH64_X_REGISTER_COUNT;
424 1.7 christos }
425 1.7 christos
426 1.7 christos pv_area_store (stack, pv_add_constant (regs[rn], imm),
427 1.7 christos is64 ? 8 : 4, regs[rt]);
428 1.7 christos if (inst.operands[1].addr.writeback)
429 1.7 christos regs[rn] = pv_add_constant (regs[rn], imm);
430 1.7 christos }
431 1.6 christos else if (inst.opcode->iclass == testbranch)
432 1.1 christos {
433 1.1 christos /* Stop analysis on branch. */
434 1.1 christos break;
435 1.1 christos }
436 1.1 christos else
437 1.1 christos {
438 1.1 christos if (aarch64_debug)
439 1.6 christos {
440 1.6 christos debug_printf ("aarch64: prologue analysis gave up addr=%s"
441 1.6 christos " opcode=0x%x\n",
442 1.6 christos core_addr_to_string_nz (start), insn);
443 1.6 christos }
444 1.1 christos break;
445 1.1 christos }
446 1.1 christos }
447 1.1 christos
448 1.1 christos if (cache == NULL)
449 1.1 christos {
450 1.1 christos do_cleanups (back_to);
451 1.1 christos return start;
452 1.1 christos }
453 1.1 christos
454 1.1 christos if (pv_is_register (regs[AARCH64_FP_REGNUM], AARCH64_SP_REGNUM))
455 1.1 christos {
456 1.1 christos /* Frame pointer is fp. Frame size is constant. */
457 1.1 christos cache->framereg = AARCH64_FP_REGNUM;
458 1.1 christos cache->framesize = -regs[AARCH64_FP_REGNUM].k;
459 1.1 christos }
460 1.1 christos else if (pv_is_register (regs[AARCH64_SP_REGNUM], AARCH64_SP_REGNUM))
461 1.1 christos {
462 1.1 christos /* Try the stack pointer. */
463 1.1 christos cache->framesize = -regs[AARCH64_SP_REGNUM].k;
464 1.1 christos cache->framereg = AARCH64_SP_REGNUM;
465 1.1 christos }
466 1.1 christos else
467 1.1 christos {
468 1.1 christos /* We're just out of luck. We don't know where the frame is. */
469 1.1 christos cache->framereg = -1;
470 1.1 christos cache->framesize = 0;
471 1.1 christos }
472 1.1 christos
473 1.1 christos for (i = 0; i < AARCH64_X_REGISTER_COUNT; i++)
474 1.1 christos {
475 1.1 christos CORE_ADDR offset;
476 1.1 christos
477 1.1 christos if (pv_area_find_reg (stack, gdbarch, i, &offset))
478 1.1 christos cache->saved_regs[i].addr = offset;
479 1.1 christos }
480 1.1 christos
481 1.7 christos for (i = 0; i < AARCH64_D_REGISTER_COUNT; i++)
482 1.7 christos {
483 1.7 christos int regnum = gdbarch_num_regs (gdbarch);
484 1.7 christos CORE_ADDR offset;
485 1.7 christos
486 1.7 christos if (pv_area_find_reg (stack, gdbarch, i + AARCH64_X_REGISTER_COUNT,
487 1.7 christos &offset))
488 1.7 christos cache->saved_regs[i + regnum + AARCH64_D0_REGNUM].addr = offset;
489 1.7 christos }
490 1.7 christos
491 1.1 christos do_cleanups (back_to);
492 1.1 christos return start;
493 1.1 christos }
494 1.1 christos
495 1.7 christos static CORE_ADDR
496 1.7 christos aarch64_analyze_prologue (struct gdbarch *gdbarch,
497 1.7 christos CORE_ADDR start, CORE_ADDR limit,
498 1.7 christos struct aarch64_prologue_cache *cache)
499 1.7 christos {
500 1.7 christos instruction_reader reader;
501 1.7 christos
502 1.7 christos return aarch64_analyze_prologue (gdbarch, start, limit, cache,
503 1.7 christos reader);
504 1.7 christos }
505 1.7 christos
506 1.7 christos #if GDB_SELF_TEST
507 1.7 christos
508 1.7 christos namespace selftests {
509 1.7 christos
510 1.7 christos /* Instruction reader from manually cooked instruction sequences. */
511 1.7 christos
512 1.7 christos class instruction_reader_test : public abstract_instruction_reader
513 1.7 christos {
514 1.7 christos public:
515 1.7 christos template<size_t SIZE>
516 1.7 christos explicit instruction_reader_test (const uint32_t (&insns)[SIZE])
517 1.7 christos : m_insns (insns), m_insns_size (SIZE)
518 1.7 christos {}
519 1.7 christos
520 1.7 christos ULONGEST read (CORE_ADDR memaddr, int len, enum bfd_endian byte_order)
521 1.7 christos {
522 1.7 christos SELF_CHECK (len == 4);
523 1.7 christos SELF_CHECK (memaddr % 4 == 0);
524 1.7 christos SELF_CHECK (memaddr / 4 < m_insns_size);
525 1.7 christos
526 1.7 christos return m_insns[memaddr / 4];
527 1.7 christos }
528 1.7 christos
529 1.7 christos private:
530 1.7 christos const uint32_t *m_insns;
531 1.7 christos size_t m_insns_size;
532 1.7 christos };
533 1.7 christos
534 1.7 christos static void
535 1.7 christos aarch64_analyze_prologue_test (void)
536 1.7 christos {
537 1.7 christos struct gdbarch_info info;
538 1.7 christos
539 1.7 christos gdbarch_info_init (&info);
540 1.7 christos info.bfd_arch_info = bfd_scan_arch ("aarch64");
541 1.7 christos
542 1.7 christos struct gdbarch *gdbarch = gdbarch_find_by_info (info);
543 1.7 christos SELF_CHECK (gdbarch != NULL);
544 1.7 christos
545 1.7 christos /* Test the simple prologue in which frame pointer is used. */
546 1.7 christos {
547 1.7 christos struct aarch64_prologue_cache cache;
548 1.7 christos cache.saved_regs = trad_frame_alloc_saved_regs (gdbarch);
549 1.7 christos
550 1.7 christos static const uint32_t insns[] = {
551 1.7 christos 0xa9af7bfd, /* stp x29, x30, [sp,#-272]! */
552 1.7 christos 0x910003fd, /* mov x29, sp */
553 1.7 christos 0x97ffffe6, /* bl 0x400580 */
554 1.7 christos };
555 1.7 christos instruction_reader_test reader (insns);
556 1.7 christos
557 1.7 christos CORE_ADDR end = aarch64_analyze_prologue (gdbarch, 0, 128, &cache, reader);
558 1.7 christos SELF_CHECK (end == 4 * 2);
559 1.7 christos
560 1.7 christos SELF_CHECK (cache.framereg == AARCH64_FP_REGNUM);
561 1.7 christos SELF_CHECK (cache.framesize == 272);
562 1.7 christos
563 1.7 christos for (int i = 0; i < AARCH64_X_REGISTER_COUNT; i++)
564 1.7 christos {
565 1.7 christos if (i == AARCH64_FP_REGNUM)
566 1.7 christos SELF_CHECK (cache.saved_regs[i].addr == -272);
567 1.7 christos else if (i == AARCH64_LR_REGNUM)
568 1.7 christos SELF_CHECK (cache.saved_regs[i].addr == -264);
569 1.7 christos else
570 1.7 christos SELF_CHECK (cache.saved_regs[i].addr == -1);
571 1.7 christos }
572 1.7 christos
573 1.7 christos for (int i = 0; i < AARCH64_D_REGISTER_COUNT; i++)
574 1.7 christos {
575 1.7 christos int regnum = gdbarch_num_regs (gdbarch);
576 1.7 christos
577 1.7 christos SELF_CHECK (cache.saved_regs[i + regnum + AARCH64_D0_REGNUM].addr
578 1.7 christos == -1);
579 1.7 christos }
580 1.7 christos }
581 1.7 christos
582 1.7 christos /* Test a prologue in which STR is used and frame pointer is not
583 1.7 christos used. */
584 1.7 christos {
585 1.7 christos struct aarch64_prologue_cache cache;
586 1.7 christos cache.saved_regs = trad_frame_alloc_saved_regs (gdbarch);
587 1.7 christos
588 1.7 christos static const uint32_t insns[] = {
589 1.7 christos 0xf81d0ff3, /* str x19, [sp, #-48]! */
590 1.7 christos 0xb9002fe0, /* str w0, [sp, #44] */
591 1.7 christos 0xf90013e1, /* str x1, [sp, #32]*/
592 1.7 christos 0xfd000fe0, /* str d0, [sp, #24] */
593 1.7 christos 0xaa0203f3, /* mov x19, x2 */
594 1.7 christos 0xf94013e0, /* ldr x0, [sp, #32] */
595 1.7 christos };
596 1.7 christos instruction_reader_test reader (insns);
597 1.7 christos
598 1.7 christos CORE_ADDR end = aarch64_analyze_prologue (gdbarch, 0, 128, &cache, reader);
599 1.7 christos
600 1.7 christos SELF_CHECK (end == 4 * 5);
601 1.7 christos
602 1.7 christos SELF_CHECK (cache.framereg == AARCH64_SP_REGNUM);
603 1.7 christos SELF_CHECK (cache.framesize == 48);
604 1.7 christos
605 1.7 christos for (int i = 0; i < AARCH64_X_REGISTER_COUNT; i++)
606 1.7 christos {
607 1.7 christos if (i == 1)
608 1.7 christos SELF_CHECK (cache.saved_regs[i].addr == -16);
609 1.7 christos else if (i == 19)
610 1.7 christos SELF_CHECK (cache.saved_regs[i].addr == -48);
611 1.7 christos else
612 1.7 christos SELF_CHECK (cache.saved_regs[i].addr == -1);
613 1.7 christos }
614 1.7 christos
615 1.7 christos for (int i = 0; i < AARCH64_D_REGISTER_COUNT; i++)
616 1.7 christos {
617 1.7 christos int regnum = gdbarch_num_regs (gdbarch);
618 1.7 christos
619 1.7 christos if (i == 0)
620 1.7 christos SELF_CHECK (cache.saved_regs[i + regnum + AARCH64_D0_REGNUM].addr
621 1.7 christos == -24);
622 1.7 christos else
623 1.7 christos SELF_CHECK (cache.saved_regs[i + regnum + AARCH64_D0_REGNUM].addr
624 1.7 christos == -1);
625 1.7 christos }
626 1.7 christos }
627 1.7 christos }
628 1.7 christos } // namespace selftests
629 1.7 christos #endif /* GDB_SELF_TEST */
630 1.7 christos
631 1.1 christos /* Implement the "skip_prologue" gdbarch method. */
632 1.1 christos
633 1.1 christos static CORE_ADDR
634 1.1 christos aarch64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
635 1.1 christos {
636 1.1 christos CORE_ADDR func_addr, limit_pc;
637 1.1 christos
638 1.1 christos /* See if we can determine the end of the prologue via the symbol
639 1.1 christos table. If so, then return either PC, or the PC after the
640 1.1 christos prologue, whichever is greater. */
641 1.1 christos if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
642 1.1 christos {
643 1.1 christos CORE_ADDR post_prologue_pc
644 1.1 christos = skip_prologue_using_sal (gdbarch, func_addr);
645 1.1 christos
646 1.1 christos if (post_prologue_pc != 0)
647 1.7 christos return std::max (pc, post_prologue_pc);
648 1.1 christos }
649 1.1 christos
650 1.1 christos /* Can't determine prologue from the symbol table, need to examine
651 1.1 christos instructions. */
652 1.1 christos
653 1.1 christos /* Find an upper limit on the function prologue using the debug
654 1.1 christos information. If the debug information could not be used to
655 1.1 christos provide that bound, then use an arbitrary large number as the
656 1.1 christos upper bound. */
657 1.1 christos limit_pc = skip_prologue_using_sal (gdbarch, pc);
658 1.1 christos if (limit_pc == 0)
659 1.1 christos limit_pc = pc + 128; /* Magic. */
660 1.1 christos
661 1.1 christos /* Try disassembling prologue. */
662 1.1 christos return aarch64_analyze_prologue (gdbarch, pc, limit_pc, NULL);
663 1.1 christos }
664 1.1 christos
665 1.1 christos /* Scan the function prologue for THIS_FRAME and populate the prologue
666 1.1 christos cache CACHE. */
667 1.1 christos
668 1.1 christos static void
669 1.1 christos aarch64_scan_prologue (struct frame_info *this_frame,
670 1.1 christos struct aarch64_prologue_cache *cache)
671 1.1 christos {
672 1.1 christos CORE_ADDR block_addr = get_frame_address_in_block (this_frame);
673 1.1 christos CORE_ADDR prologue_start;
674 1.1 christos CORE_ADDR prologue_end;
675 1.1 christos CORE_ADDR prev_pc = get_frame_pc (this_frame);
676 1.1 christos struct gdbarch *gdbarch = get_frame_arch (this_frame);
677 1.1 christos
678 1.6 christos cache->prev_pc = prev_pc;
679 1.6 christos
680 1.1 christos /* Assume we do not find a frame. */
681 1.1 christos cache->framereg = -1;
682 1.1 christos cache->framesize = 0;
683 1.1 christos
684 1.1 christos if (find_pc_partial_function (block_addr, NULL, &prologue_start,
685 1.1 christos &prologue_end))
686 1.1 christos {
687 1.1 christos struct symtab_and_line sal = find_pc_line (prologue_start, 0);
688 1.1 christos
689 1.1 christos if (sal.line == 0)
690 1.1 christos {
691 1.1 christos /* No line info so use the current PC. */
692 1.1 christos prologue_end = prev_pc;
693 1.1 christos }
694 1.1 christos else if (sal.end < prologue_end)
695 1.1 christos {
696 1.1 christos /* The next line begins after the function end. */
697 1.1 christos prologue_end = sal.end;
698 1.1 christos }
699 1.1 christos
700 1.7 christos prologue_end = std::min (prologue_end, prev_pc);
701 1.1 christos aarch64_analyze_prologue (gdbarch, prologue_start, prologue_end, cache);
702 1.1 christos }
703 1.1 christos else
704 1.1 christos {
705 1.1 christos CORE_ADDR frame_loc;
706 1.1 christos
707 1.1 christos frame_loc = get_frame_register_unsigned (this_frame, AARCH64_FP_REGNUM);
708 1.1 christos if (frame_loc == 0)
709 1.1 christos return;
710 1.1 christos
711 1.1 christos cache->framereg = AARCH64_FP_REGNUM;
712 1.1 christos cache->framesize = 16;
713 1.1 christos cache->saved_regs[29].addr = 0;
714 1.1 christos cache->saved_regs[30].addr = 8;
715 1.1 christos }
716 1.1 christos }
717 1.1 christos
718 1.6 christos /* Fill in *CACHE with information about the prologue of *THIS_FRAME. This
719 1.6 christos function may throw an exception if the inferior's registers or memory is
720 1.6 christos not available. */
721 1.1 christos
722 1.6 christos static void
723 1.6 christos aarch64_make_prologue_cache_1 (struct frame_info *this_frame,
724 1.6 christos struct aarch64_prologue_cache *cache)
725 1.1 christos {
726 1.1 christos CORE_ADDR unwound_fp;
727 1.1 christos int reg;
728 1.1 christos
729 1.1 christos aarch64_scan_prologue (this_frame, cache);
730 1.1 christos
731 1.1 christos if (cache->framereg == -1)
732 1.6 christos return;
733 1.1 christos
734 1.1 christos unwound_fp = get_frame_register_unsigned (this_frame, cache->framereg);
735 1.1 christos if (unwound_fp == 0)
736 1.6 christos return;
737 1.1 christos
738 1.1 christos cache->prev_sp = unwound_fp + cache->framesize;
739 1.1 christos
740 1.1 christos /* Calculate actual addresses of saved registers using offsets
741 1.1 christos determined by aarch64_analyze_prologue. */
742 1.1 christos for (reg = 0; reg < gdbarch_num_regs (get_frame_arch (this_frame)); reg++)
743 1.1 christos if (trad_frame_addr_p (cache->saved_regs, reg))
744 1.1 christos cache->saved_regs[reg].addr += cache->prev_sp;
745 1.1 christos
746 1.6 christos cache->func = get_frame_func (this_frame);
747 1.6 christos
748 1.6 christos cache->available_p = 1;
749 1.6 christos }
750 1.6 christos
751 1.6 christos /* Allocate and fill in *THIS_CACHE with information about the prologue of
752 1.6 christos *THIS_FRAME. Do not do this is if *THIS_CACHE was already allocated.
753 1.6 christos Return a pointer to the current aarch64_prologue_cache in
754 1.6 christos *THIS_CACHE. */
755 1.6 christos
756 1.6 christos static struct aarch64_prologue_cache *
757 1.6 christos aarch64_make_prologue_cache (struct frame_info *this_frame, void **this_cache)
758 1.6 christos {
759 1.6 christos struct aarch64_prologue_cache *cache;
760 1.6 christos
761 1.6 christos if (*this_cache != NULL)
762 1.6 christos return (struct aarch64_prologue_cache *) *this_cache;
763 1.6 christos
764 1.6 christos cache = FRAME_OBSTACK_ZALLOC (struct aarch64_prologue_cache);
765 1.6 christos cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
766 1.6 christos *this_cache = cache;
767 1.6 christos
768 1.6 christos TRY
769 1.6 christos {
770 1.6 christos aarch64_make_prologue_cache_1 (this_frame, cache);
771 1.6 christos }
772 1.6 christos CATCH (ex, RETURN_MASK_ERROR)
773 1.6 christos {
774 1.6 christos if (ex.error != NOT_AVAILABLE_ERROR)
775 1.6 christos throw_exception (ex);
776 1.6 christos }
777 1.6 christos END_CATCH
778 1.6 christos
779 1.1 christos return cache;
780 1.1 christos }
781 1.1 christos
782 1.6 christos /* Implement the "stop_reason" frame_unwind method. */
783 1.6 christos
784 1.6 christos static enum unwind_stop_reason
785 1.6 christos aarch64_prologue_frame_unwind_stop_reason (struct frame_info *this_frame,
786 1.6 christos void **this_cache)
787 1.6 christos {
788 1.6 christos struct aarch64_prologue_cache *cache
789 1.6 christos = aarch64_make_prologue_cache (this_frame, this_cache);
790 1.6 christos
791 1.6 christos if (!cache->available_p)
792 1.6 christos return UNWIND_UNAVAILABLE;
793 1.6 christos
794 1.6 christos /* Halt the backtrace at "_start". */
795 1.6 christos if (cache->prev_pc <= gdbarch_tdep (get_frame_arch (this_frame))->lowest_pc)
796 1.6 christos return UNWIND_OUTERMOST;
797 1.6 christos
798 1.6 christos /* We've hit a wall, stop. */
799 1.6 christos if (cache->prev_sp == 0)
800 1.6 christos return UNWIND_OUTERMOST;
801 1.6 christos
802 1.6 christos return UNWIND_NO_REASON;
803 1.6 christos }
804 1.6 christos
805 1.1 christos /* Our frame ID for a normal frame is the current function's starting
806 1.1 christos PC and the caller's SP when we were called. */
807 1.1 christos
808 1.1 christos static void
809 1.1 christos aarch64_prologue_this_id (struct frame_info *this_frame,
810 1.1 christos void **this_cache, struct frame_id *this_id)
811 1.1 christos {
812 1.6 christos struct aarch64_prologue_cache *cache
813 1.6 christos = aarch64_make_prologue_cache (this_frame, this_cache);
814 1.1 christos
815 1.6 christos if (!cache->available_p)
816 1.6 christos *this_id = frame_id_build_unavailable_stack (cache->func);
817 1.6 christos else
818 1.6 christos *this_id = frame_id_build (cache->prev_sp, cache->func);
819 1.1 christos }
820 1.1 christos
821 1.1 christos /* Implement the "prev_register" frame_unwind method. */
822 1.1 christos
823 1.1 christos static struct value *
824 1.1 christos aarch64_prologue_prev_register (struct frame_info *this_frame,
825 1.1 christos void **this_cache, int prev_regnum)
826 1.1 christos {
827 1.6 christos struct aarch64_prologue_cache *cache
828 1.6 christos = aarch64_make_prologue_cache (this_frame, this_cache);
829 1.1 christos
830 1.1 christos /* If we are asked to unwind the PC, then we need to return the LR
831 1.1 christos instead. The prologue may save PC, but it will point into this
832 1.1 christos frame's prologue, not the next frame's resume location. */
833 1.1 christos if (prev_regnum == AARCH64_PC_REGNUM)
834 1.1 christos {
835 1.1 christos CORE_ADDR lr;
836 1.1 christos
837 1.1 christos lr = frame_unwind_register_unsigned (this_frame, AARCH64_LR_REGNUM);
838 1.1 christos return frame_unwind_got_constant (this_frame, prev_regnum, lr);
839 1.1 christos }
840 1.1 christos
841 1.1 christos /* SP is generally not saved to the stack, but this frame is
842 1.1 christos identified by the next frame's stack pointer at the time of the
843 1.1 christos call. The value was already reconstructed into PREV_SP. */
844 1.1 christos /*
845 1.1 christos +----------+ ^
846 1.1 christos | saved lr | |
847 1.1 christos +->| saved fp |--+
848 1.1 christos | | |
849 1.1 christos | | | <- Previous SP
850 1.1 christos | +----------+
851 1.1 christos | | saved lr |
852 1.1 christos +--| saved fp |<- FP
853 1.1 christos | |
854 1.1 christos | |<- SP
855 1.1 christos +----------+ */
856 1.1 christos if (prev_regnum == AARCH64_SP_REGNUM)
857 1.1 christos return frame_unwind_got_constant (this_frame, prev_regnum,
858 1.1 christos cache->prev_sp);
859 1.1 christos
860 1.1 christos return trad_frame_get_prev_register (this_frame, cache->saved_regs,
861 1.1 christos prev_regnum);
862 1.1 christos }
863 1.1 christos
864 1.1 christos /* AArch64 prologue unwinder. */
865 1.1 christos struct frame_unwind aarch64_prologue_unwind =
866 1.1 christos {
867 1.1 christos NORMAL_FRAME,
868 1.6 christos aarch64_prologue_frame_unwind_stop_reason,
869 1.1 christos aarch64_prologue_this_id,
870 1.1 christos aarch64_prologue_prev_register,
871 1.1 christos NULL,
872 1.1 christos default_frame_sniffer
873 1.1 christos };
874 1.1 christos
875 1.6 christos /* Allocate and fill in *THIS_CACHE with information about the prologue of
876 1.6 christos *THIS_FRAME. Do not do this is if *THIS_CACHE was already allocated.
877 1.6 christos Return a pointer to the current aarch64_prologue_cache in
878 1.6 christos *THIS_CACHE. */
879 1.1 christos
880 1.1 christos static struct aarch64_prologue_cache *
881 1.6 christos aarch64_make_stub_cache (struct frame_info *this_frame, void **this_cache)
882 1.1 christos {
883 1.1 christos struct aarch64_prologue_cache *cache;
884 1.6 christos
885 1.6 christos if (*this_cache != NULL)
886 1.6 christos return (struct aarch64_prologue_cache *) *this_cache;
887 1.1 christos
888 1.1 christos cache = FRAME_OBSTACK_ZALLOC (struct aarch64_prologue_cache);
889 1.1 christos cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
890 1.6 christos *this_cache = cache;
891 1.1 christos
892 1.6 christos TRY
893 1.6 christos {
894 1.6 christos cache->prev_sp = get_frame_register_unsigned (this_frame,
895 1.6 christos AARCH64_SP_REGNUM);
896 1.6 christos cache->prev_pc = get_frame_pc (this_frame);
897 1.6 christos cache->available_p = 1;
898 1.6 christos }
899 1.6 christos CATCH (ex, RETURN_MASK_ERROR)
900 1.6 christos {
901 1.6 christos if (ex.error != NOT_AVAILABLE_ERROR)
902 1.6 christos throw_exception (ex);
903 1.6 christos }
904 1.6 christos END_CATCH
905 1.1 christos
906 1.1 christos return cache;
907 1.1 christos }
908 1.1 christos
909 1.6 christos /* Implement the "stop_reason" frame_unwind method. */
910 1.6 christos
911 1.6 christos static enum unwind_stop_reason
912 1.6 christos aarch64_stub_frame_unwind_stop_reason (struct frame_info *this_frame,
913 1.6 christos void **this_cache)
914 1.6 christos {
915 1.6 christos struct aarch64_prologue_cache *cache
916 1.6 christos = aarch64_make_stub_cache (this_frame, this_cache);
917 1.6 christos
918 1.6 christos if (!cache->available_p)
919 1.6 christos return UNWIND_UNAVAILABLE;
920 1.6 christos
921 1.6 christos return UNWIND_NO_REASON;
922 1.6 christos }
923 1.6 christos
924 1.1 christos /* Our frame ID for a stub frame is the current SP and LR. */
925 1.1 christos
926 1.1 christos static void
927 1.1 christos aarch64_stub_this_id (struct frame_info *this_frame,
928 1.1 christos void **this_cache, struct frame_id *this_id)
929 1.1 christos {
930 1.6 christos struct aarch64_prologue_cache *cache
931 1.6 christos = aarch64_make_stub_cache (this_frame, this_cache);
932 1.1 christos
933 1.6 christos if (cache->available_p)
934 1.6 christos *this_id = frame_id_build (cache->prev_sp, cache->prev_pc);
935 1.6 christos else
936 1.6 christos *this_id = frame_id_build_unavailable_stack (cache->prev_pc);
937 1.1 christos }
938 1.1 christos
939 1.1 christos /* Implement the "sniffer" frame_unwind method. */
940 1.1 christos
941 1.1 christos static int
942 1.1 christos aarch64_stub_unwind_sniffer (const struct frame_unwind *self,
943 1.1 christos struct frame_info *this_frame,
944 1.1 christos void **this_prologue_cache)
945 1.1 christos {
946 1.1 christos CORE_ADDR addr_in_block;
947 1.1 christos gdb_byte dummy[4];
948 1.1 christos
949 1.1 christos addr_in_block = get_frame_address_in_block (this_frame);
950 1.1 christos if (in_plt_section (addr_in_block)
951 1.1 christos /* We also use the stub winder if the target memory is unreadable
952 1.1 christos to avoid having the prologue unwinder trying to read it. */
953 1.1 christos || target_read_memory (get_frame_pc (this_frame), dummy, 4) != 0)
954 1.1 christos return 1;
955 1.1 christos
956 1.1 christos return 0;
957 1.1 christos }
958 1.1 christos
959 1.1 christos /* AArch64 stub unwinder. */
960 1.1 christos struct frame_unwind aarch64_stub_unwind =
961 1.1 christos {
962 1.1 christos NORMAL_FRAME,
963 1.6 christos aarch64_stub_frame_unwind_stop_reason,
964 1.1 christos aarch64_stub_this_id,
965 1.1 christos aarch64_prologue_prev_register,
966 1.1 christos NULL,
967 1.1 christos aarch64_stub_unwind_sniffer
968 1.1 christos };
969 1.1 christos
970 1.1 christos /* Return the frame base address of *THIS_FRAME. */
971 1.1 christos
972 1.1 christos static CORE_ADDR
973 1.1 christos aarch64_normal_frame_base (struct frame_info *this_frame, void **this_cache)
974 1.1 christos {
975 1.6 christos struct aarch64_prologue_cache *cache
976 1.6 christos = aarch64_make_prologue_cache (this_frame, this_cache);
977 1.1 christos
978 1.1 christos return cache->prev_sp - cache->framesize;
979 1.1 christos }
980 1.1 christos
981 1.1 christos /* AArch64 default frame base information. */
982 1.1 christos struct frame_base aarch64_normal_base =
983 1.1 christos {
984 1.1 christos &aarch64_prologue_unwind,
985 1.1 christos aarch64_normal_frame_base,
986 1.1 christos aarch64_normal_frame_base,
987 1.1 christos aarch64_normal_frame_base
988 1.1 christos };
989 1.1 christos
990 1.1 christos /* Assuming THIS_FRAME is a dummy, return the frame ID of that
991 1.1 christos dummy frame. The frame ID's base needs to match the TOS value
992 1.1 christos saved by save_dummy_frame_tos () and returned from
993 1.1 christos aarch64_push_dummy_call, and the PC needs to match the dummy
994 1.1 christos frame's breakpoint. */
995 1.1 christos
996 1.1 christos static struct frame_id
997 1.1 christos aarch64_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
998 1.1 christos {
999 1.1 christos return frame_id_build (get_frame_register_unsigned (this_frame,
1000 1.1 christos AARCH64_SP_REGNUM),
1001 1.1 christos get_frame_pc (this_frame));
1002 1.1 christos }
1003 1.1 christos
1004 1.1 christos /* Implement the "unwind_pc" gdbarch method. */
1005 1.1 christos
1006 1.1 christos static CORE_ADDR
1007 1.1 christos aarch64_unwind_pc (struct gdbarch *gdbarch, struct frame_info *this_frame)
1008 1.1 christos {
1009 1.1 christos CORE_ADDR pc
1010 1.1 christos = frame_unwind_register_unsigned (this_frame, AARCH64_PC_REGNUM);
1011 1.1 christos
1012 1.1 christos return pc;
1013 1.1 christos }
1014 1.1 christos
1015 1.1 christos /* Implement the "unwind_sp" gdbarch method. */
1016 1.1 christos
1017 1.1 christos static CORE_ADDR
1018 1.1 christos aarch64_unwind_sp (struct gdbarch *gdbarch, struct frame_info *this_frame)
1019 1.1 christos {
1020 1.1 christos return frame_unwind_register_unsigned (this_frame, AARCH64_SP_REGNUM);
1021 1.1 christos }
1022 1.1 christos
1023 1.1 christos /* Return the value of the REGNUM register in the previous frame of
1024 1.1 christos *THIS_FRAME. */
1025 1.1 christos
1026 1.1 christos static struct value *
1027 1.1 christos aarch64_dwarf2_prev_register (struct frame_info *this_frame,
1028 1.1 christos void **this_cache, int regnum)
1029 1.1 christos {
1030 1.1 christos CORE_ADDR lr;
1031 1.1 christos
1032 1.1 christos switch (regnum)
1033 1.1 christos {
1034 1.1 christos case AARCH64_PC_REGNUM:
1035 1.1 christos lr = frame_unwind_register_unsigned (this_frame, AARCH64_LR_REGNUM);
1036 1.1 christos return frame_unwind_got_constant (this_frame, regnum, lr);
1037 1.1 christos
1038 1.1 christos default:
1039 1.1 christos internal_error (__FILE__, __LINE__,
1040 1.1 christos _("Unexpected register %d"), regnum);
1041 1.1 christos }
1042 1.1 christos }
1043 1.1 christos
1044 1.1 christos /* Implement the "init_reg" dwarf2_frame_ops method. */
1045 1.1 christos
1046 1.1 christos static void
1047 1.1 christos aarch64_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
1048 1.1 christos struct dwarf2_frame_state_reg *reg,
1049 1.1 christos struct frame_info *this_frame)
1050 1.1 christos {
1051 1.1 christos switch (regnum)
1052 1.1 christos {
1053 1.1 christos case AARCH64_PC_REGNUM:
1054 1.1 christos reg->how = DWARF2_FRAME_REG_FN;
1055 1.1 christos reg->loc.fn = aarch64_dwarf2_prev_register;
1056 1.1 christos break;
1057 1.1 christos case AARCH64_SP_REGNUM:
1058 1.1 christos reg->how = DWARF2_FRAME_REG_CFA;
1059 1.1 christos break;
1060 1.1 christos }
1061 1.1 christos }
1062 1.1 christos
1063 1.1 christos /* When arguments must be pushed onto the stack, they go on in reverse
1064 1.1 christos order. The code below implements a FILO (stack) to do this. */
1065 1.1 christos
1066 1.1 christos typedef struct
1067 1.1 christos {
1068 1.6 christos /* Value to pass on stack. It can be NULL if this item is for stack
1069 1.6 christos padding. */
1070 1.6 christos const gdb_byte *data;
1071 1.1 christos
1072 1.1 christos /* Size in bytes of value to pass on stack. */
1073 1.1 christos int len;
1074 1.1 christos } stack_item_t;
1075 1.1 christos
1076 1.1 christos DEF_VEC_O (stack_item_t);
1077 1.1 christos
1078 1.1 christos /* Return the alignment (in bytes) of the given type. */
1079 1.1 christos
1080 1.1 christos static int
1081 1.1 christos aarch64_type_align (struct type *t)
1082 1.1 christos {
1083 1.1 christos int n;
1084 1.1 christos int align;
1085 1.1 christos int falign;
1086 1.1 christos
1087 1.1 christos t = check_typedef (t);
1088 1.1 christos switch (TYPE_CODE (t))
1089 1.1 christos {
1090 1.1 christos default:
1091 1.1 christos /* Should never happen. */
1092 1.1 christos internal_error (__FILE__, __LINE__, _("unknown type alignment"));
1093 1.1 christos return 4;
1094 1.1 christos
1095 1.1 christos case TYPE_CODE_PTR:
1096 1.1 christos case TYPE_CODE_ENUM:
1097 1.1 christos case TYPE_CODE_INT:
1098 1.1 christos case TYPE_CODE_FLT:
1099 1.1 christos case TYPE_CODE_SET:
1100 1.1 christos case TYPE_CODE_RANGE:
1101 1.1 christos case TYPE_CODE_BITSTRING:
1102 1.1 christos case TYPE_CODE_REF:
1103 1.7 christos case TYPE_CODE_RVALUE_REF:
1104 1.1 christos case TYPE_CODE_CHAR:
1105 1.1 christos case TYPE_CODE_BOOL:
1106 1.1 christos return TYPE_LENGTH (t);
1107 1.1 christos
1108 1.1 christos case TYPE_CODE_ARRAY:
1109 1.6 christos if (TYPE_VECTOR (t))
1110 1.6 christos {
1111 1.6 christos /* Use the natural alignment for vector types (the same for
1112 1.6 christos scalar type), but the maximum alignment is 128-bit. */
1113 1.6 christos if (TYPE_LENGTH (t) > 16)
1114 1.6 christos return 16;
1115 1.6 christos else
1116 1.6 christos return TYPE_LENGTH (t);
1117 1.6 christos }
1118 1.6 christos else
1119 1.6 christos return aarch64_type_align (TYPE_TARGET_TYPE (t));
1120 1.1 christos case TYPE_CODE_COMPLEX:
1121 1.1 christos return aarch64_type_align (TYPE_TARGET_TYPE (t));
1122 1.1 christos
1123 1.1 christos case TYPE_CODE_STRUCT:
1124 1.1 christos case TYPE_CODE_UNION:
1125 1.1 christos align = 1;
1126 1.1 christos for (n = 0; n < TYPE_NFIELDS (t); n++)
1127 1.1 christos {
1128 1.1 christos falign = aarch64_type_align (TYPE_FIELD_TYPE (t, n));
1129 1.1 christos if (falign > align)
1130 1.1 christos align = falign;
1131 1.1 christos }
1132 1.1 christos return align;
1133 1.1 christos }
1134 1.1 christos }
1135 1.1 christos
1136 1.6 christos /* Return 1 if *TY is a homogeneous floating-point aggregate or
1137 1.6 christos homogeneous short-vector aggregate as defined in the AAPCS64 ABI
1138 1.6 christos document; otherwise return 0. */
1139 1.1 christos
1140 1.1 christos static int
1141 1.6 christos is_hfa_or_hva (struct type *ty)
1142 1.1 christos {
1143 1.1 christos switch (TYPE_CODE (ty))
1144 1.1 christos {
1145 1.1 christos case TYPE_CODE_ARRAY:
1146 1.1 christos {
1147 1.1 christos struct type *target_ty = TYPE_TARGET_TYPE (ty);
1148 1.6 christos
1149 1.6 christos if (TYPE_VECTOR (ty))
1150 1.6 christos return 0;
1151 1.6 christos
1152 1.6 christos if (TYPE_LENGTH (ty) <= 4 /* HFA or HVA has at most 4 members. */
1153 1.6 christos && (TYPE_CODE (target_ty) == TYPE_CODE_FLT /* HFA */
1154 1.6 christos || (TYPE_CODE (target_ty) == TYPE_CODE_ARRAY /* HVA */
1155 1.6 christos && TYPE_VECTOR (target_ty))))
1156 1.1 christos return 1;
1157 1.1 christos break;
1158 1.1 christos }
1159 1.1 christos
1160 1.1 christos case TYPE_CODE_UNION:
1161 1.1 christos case TYPE_CODE_STRUCT:
1162 1.1 christos {
1163 1.6 christos /* HFA or HVA has at most four members. */
1164 1.1 christos if (TYPE_NFIELDS (ty) > 0 && TYPE_NFIELDS (ty) <= 4)
1165 1.1 christos {
1166 1.1 christos struct type *member0_type;
1167 1.1 christos
1168 1.1 christos member0_type = check_typedef (TYPE_FIELD_TYPE (ty, 0));
1169 1.6 christos if (TYPE_CODE (member0_type) == TYPE_CODE_FLT
1170 1.6 christos || (TYPE_CODE (member0_type) == TYPE_CODE_ARRAY
1171 1.6 christos && TYPE_VECTOR (member0_type)))
1172 1.1 christos {
1173 1.1 christos int i;
1174 1.1 christos
1175 1.1 christos for (i = 0; i < TYPE_NFIELDS (ty); i++)
1176 1.1 christos {
1177 1.1 christos struct type *member1_type;
1178 1.1 christos
1179 1.1 christos member1_type = check_typedef (TYPE_FIELD_TYPE (ty, i));
1180 1.1 christos if (TYPE_CODE (member0_type) != TYPE_CODE (member1_type)
1181 1.1 christos || (TYPE_LENGTH (member0_type)
1182 1.1 christos != TYPE_LENGTH (member1_type)))
1183 1.1 christos return 0;
1184 1.1 christos }
1185 1.1 christos return 1;
1186 1.1 christos }
1187 1.1 christos }
1188 1.1 christos return 0;
1189 1.1 christos }
1190 1.1 christos
1191 1.1 christos default:
1192 1.1 christos break;
1193 1.1 christos }
1194 1.1 christos
1195 1.1 christos return 0;
1196 1.1 christos }
1197 1.1 christos
1198 1.1 christos /* AArch64 function call information structure. */
1199 1.1 christos struct aarch64_call_info
1200 1.1 christos {
1201 1.1 christos /* the current argument number. */
1202 1.1 christos unsigned argnum;
1203 1.1 christos
1204 1.1 christos /* The next general purpose register number, equivalent to NGRN as
1205 1.1 christos described in the AArch64 Procedure Call Standard. */
1206 1.1 christos unsigned ngrn;
1207 1.1 christos
1208 1.1 christos /* The next SIMD and floating point register number, equivalent to
1209 1.1 christos NSRN as described in the AArch64 Procedure Call Standard. */
1210 1.1 christos unsigned nsrn;
1211 1.1 christos
1212 1.1 christos /* The next stacked argument address, equivalent to NSAA as
1213 1.1 christos described in the AArch64 Procedure Call Standard. */
1214 1.1 christos unsigned nsaa;
1215 1.1 christos
1216 1.1 christos /* Stack item vector. */
1217 1.1 christos VEC(stack_item_t) *si;
1218 1.1 christos };
1219 1.1 christos
1220 1.1 christos /* Pass a value in a sequence of consecutive X registers. The caller
1221 1.1 christos is responsbile for ensuring sufficient registers are available. */
1222 1.1 christos
1223 1.1 christos static void
1224 1.1 christos pass_in_x (struct gdbarch *gdbarch, struct regcache *regcache,
1225 1.1 christos struct aarch64_call_info *info, struct type *type,
1226 1.6 christos struct value *arg)
1227 1.1 christos {
1228 1.1 christos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1229 1.1 christos int len = TYPE_LENGTH (type);
1230 1.1 christos enum type_code typecode = TYPE_CODE (type);
1231 1.1 christos int regnum = AARCH64_X0_REGNUM + info->ngrn;
1232 1.6 christos const bfd_byte *buf = value_contents (arg);
1233 1.1 christos
1234 1.1 christos info->argnum++;
1235 1.1 christos
1236 1.1 christos while (len > 0)
1237 1.1 christos {
1238 1.1 christos int partial_len = len < X_REGISTER_SIZE ? len : X_REGISTER_SIZE;
1239 1.1 christos CORE_ADDR regval = extract_unsigned_integer (buf, partial_len,
1240 1.1 christos byte_order);
1241 1.1 christos
1242 1.1 christos
1243 1.1 christos /* Adjust sub-word struct/union args when big-endian. */
1244 1.1 christos if (byte_order == BFD_ENDIAN_BIG
1245 1.1 christos && partial_len < X_REGISTER_SIZE
1246 1.1 christos && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
1247 1.1 christos regval <<= ((X_REGISTER_SIZE - partial_len) * TARGET_CHAR_BIT);
1248 1.1 christos
1249 1.1 christos if (aarch64_debug)
1250 1.6 christos {
1251 1.6 christos debug_printf ("arg %d in %s = 0x%s\n", info->argnum,
1252 1.6 christos gdbarch_register_name (gdbarch, regnum),
1253 1.6 christos phex (regval, X_REGISTER_SIZE));
1254 1.6 christos }
1255 1.1 christos regcache_cooked_write_unsigned (regcache, regnum, regval);
1256 1.1 christos len -= partial_len;
1257 1.1 christos buf += partial_len;
1258 1.1 christos regnum++;
1259 1.1 christos }
1260 1.1 christos }
1261 1.1 christos
1262 1.1 christos /* Attempt to marshall a value in a V register. Return 1 if
1263 1.1 christos successful, or 0 if insufficient registers are available. This
1264 1.1 christos function, unlike the equivalent pass_in_x() function does not
1265 1.1 christos handle arguments spread across multiple registers. */
1266 1.1 christos
1267 1.1 christos static int
1268 1.1 christos pass_in_v (struct gdbarch *gdbarch,
1269 1.1 christos struct regcache *regcache,
1270 1.1 christos struct aarch64_call_info *info,
1271 1.6 christos int len, const bfd_byte *buf)
1272 1.1 christos {
1273 1.1 christos if (info->nsrn < 8)
1274 1.1 christos {
1275 1.1 christos int regnum = AARCH64_V0_REGNUM + info->nsrn;
1276 1.6 christos gdb_byte reg[V_REGISTER_SIZE];
1277 1.1 christos
1278 1.1 christos info->argnum++;
1279 1.1 christos info->nsrn++;
1280 1.1 christos
1281 1.6 christos memset (reg, 0, sizeof (reg));
1282 1.6 christos /* PCS C.1, the argument is allocated to the least significant
1283 1.6 christos bits of V register. */
1284 1.6 christos memcpy (reg, buf, len);
1285 1.6 christos regcache_cooked_write (regcache, regnum, reg);
1286 1.6 christos
1287 1.1 christos if (aarch64_debug)
1288 1.6 christos {
1289 1.6 christos debug_printf ("arg %d in %s\n", info->argnum,
1290 1.6 christos gdbarch_register_name (gdbarch, regnum));
1291 1.6 christos }
1292 1.1 christos return 1;
1293 1.1 christos }
1294 1.1 christos info->nsrn = 8;
1295 1.1 christos return 0;
1296 1.1 christos }
1297 1.1 christos
1298 1.1 christos /* Marshall an argument onto the stack. */
1299 1.1 christos
1300 1.1 christos static void
1301 1.1 christos pass_on_stack (struct aarch64_call_info *info, struct type *type,
1302 1.6 christos struct value *arg)
1303 1.1 christos {
1304 1.6 christos const bfd_byte *buf = value_contents (arg);
1305 1.1 christos int len = TYPE_LENGTH (type);
1306 1.1 christos int align;
1307 1.1 christos stack_item_t item;
1308 1.1 christos
1309 1.1 christos info->argnum++;
1310 1.1 christos
1311 1.1 christos align = aarch64_type_align (type);
1312 1.1 christos
1313 1.1 christos /* PCS C.17 Stack should be aligned to the larger of 8 bytes or the
1314 1.1 christos Natural alignment of the argument's type. */
1315 1.1 christos align = align_up (align, 8);
1316 1.1 christos
1317 1.1 christos /* The AArch64 PCS requires at most doubleword alignment. */
1318 1.1 christos if (align > 16)
1319 1.1 christos align = 16;
1320 1.1 christos
1321 1.1 christos if (aarch64_debug)
1322 1.6 christos {
1323 1.6 christos debug_printf ("arg %d len=%d @ sp + %d\n", info->argnum, len,
1324 1.6 christos info->nsaa);
1325 1.6 christos }
1326 1.1 christos
1327 1.1 christos item.len = len;
1328 1.1 christos item.data = buf;
1329 1.1 christos VEC_safe_push (stack_item_t, info->si, &item);
1330 1.1 christos
1331 1.1 christos info->nsaa += len;
1332 1.1 christos if (info->nsaa & (align - 1))
1333 1.1 christos {
1334 1.1 christos /* Push stack alignment padding. */
1335 1.1 christos int pad = align - (info->nsaa & (align - 1));
1336 1.1 christos
1337 1.1 christos item.len = pad;
1338 1.6 christos item.data = NULL;
1339 1.1 christos
1340 1.1 christos VEC_safe_push (stack_item_t, info->si, &item);
1341 1.1 christos info->nsaa += pad;
1342 1.1 christos }
1343 1.1 christos }
1344 1.1 christos
1345 1.1 christos /* Marshall an argument into a sequence of one or more consecutive X
1346 1.1 christos registers or, if insufficient X registers are available then onto
1347 1.1 christos the stack. */
1348 1.1 christos
1349 1.1 christos static void
1350 1.1 christos pass_in_x_or_stack (struct gdbarch *gdbarch, struct regcache *regcache,
1351 1.1 christos struct aarch64_call_info *info, struct type *type,
1352 1.6 christos struct value *arg)
1353 1.1 christos {
1354 1.1 christos int len = TYPE_LENGTH (type);
1355 1.1 christos int nregs = (len + X_REGISTER_SIZE - 1) / X_REGISTER_SIZE;
1356 1.1 christos
1357 1.1 christos /* PCS C.13 - Pass in registers if we have enough spare */
1358 1.1 christos if (info->ngrn + nregs <= 8)
1359 1.1 christos {
1360 1.6 christos pass_in_x (gdbarch, regcache, info, type, arg);
1361 1.1 christos info->ngrn += nregs;
1362 1.1 christos }
1363 1.1 christos else
1364 1.1 christos {
1365 1.1 christos info->ngrn = 8;
1366 1.6 christos pass_on_stack (info, type, arg);
1367 1.1 christos }
1368 1.1 christos }
1369 1.1 christos
1370 1.1 christos /* Pass a value in a V register, or on the stack if insufficient are
1371 1.1 christos available. */
1372 1.1 christos
1373 1.1 christos static void
1374 1.1 christos pass_in_v_or_stack (struct gdbarch *gdbarch,
1375 1.1 christos struct regcache *regcache,
1376 1.1 christos struct aarch64_call_info *info,
1377 1.1 christos struct type *type,
1378 1.6 christos struct value *arg)
1379 1.1 christos {
1380 1.6 christos if (!pass_in_v (gdbarch, regcache, info, TYPE_LENGTH (type),
1381 1.6 christos value_contents (arg)))
1382 1.6 christos pass_on_stack (info, type, arg);
1383 1.1 christos }
1384 1.1 christos
1385 1.1 christos /* Implement the "push_dummy_call" gdbarch method. */
1386 1.1 christos
1387 1.1 christos static CORE_ADDR
1388 1.1 christos aarch64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
1389 1.1 christos struct regcache *regcache, CORE_ADDR bp_addr,
1390 1.1 christos int nargs,
1391 1.1 christos struct value **args, CORE_ADDR sp, int struct_return,
1392 1.1 christos CORE_ADDR struct_addr)
1393 1.1 christos {
1394 1.1 christos int argnum;
1395 1.1 christos struct aarch64_call_info info;
1396 1.1 christos struct type *func_type;
1397 1.1 christos struct type *return_type;
1398 1.1 christos int lang_struct_return;
1399 1.1 christos
1400 1.1 christos memset (&info, 0, sizeof (info));
1401 1.1 christos
1402 1.1 christos /* We need to know what the type of the called function is in order
1403 1.1 christos to determine the number of named/anonymous arguments for the
1404 1.1 christos actual argument placement, and the return type in order to handle
1405 1.1 christos return value correctly.
1406 1.1 christos
1407 1.1 christos The generic code above us views the decision of return in memory
1408 1.1 christos or return in registers as a two stage processes. The language
1409 1.1 christos handler is consulted first and may decide to return in memory (eg
1410 1.1 christos class with copy constructor returned by value), this will cause
1411 1.1 christos the generic code to allocate space AND insert an initial leading
1412 1.1 christos argument.
1413 1.1 christos
1414 1.1 christos If the language code does not decide to pass in memory then the
1415 1.1 christos target code is consulted.
1416 1.1 christos
1417 1.1 christos If the language code decides to pass in memory we want to move
1418 1.1 christos the pointer inserted as the initial argument from the argument
1419 1.1 christos list and into X8, the conventional AArch64 struct return pointer
1420 1.1 christos register.
1421 1.1 christos
1422 1.1 christos This is slightly awkward, ideally the flag "lang_struct_return"
1423 1.1 christos would be passed to the targets implementation of push_dummy_call.
1424 1.1 christos Rather that change the target interface we call the language code
1425 1.1 christos directly ourselves. */
1426 1.1 christos
1427 1.1 christos func_type = check_typedef (value_type (function));
1428 1.1 christos
1429 1.1 christos /* Dereference function pointer types. */
1430 1.1 christos if (TYPE_CODE (func_type) == TYPE_CODE_PTR)
1431 1.1 christos func_type = TYPE_TARGET_TYPE (func_type);
1432 1.1 christos
1433 1.1 christos gdb_assert (TYPE_CODE (func_type) == TYPE_CODE_FUNC
1434 1.1 christos || TYPE_CODE (func_type) == TYPE_CODE_METHOD);
1435 1.1 christos
1436 1.1 christos /* If language_pass_by_reference () returned true we will have been
1437 1.1 christos given an additional initial argument, a hidden pointer to the
1438 1.1 christos return slot in memory. */
1439 1.1 christos return_type = TYPE_TARGET_TYPE (func_type);
1440 1.1 christos lang_struct_return = language_pass_by_reference (return_type);
1441 1.1 christos
1442 1.1 christos /* Set the return address. For the AArch64, the return breakpoint
1443 1.1 christos is always at BP_ADDR. */
1444 1.1 christos regcache_cooked_write_unsigned (regcache, AARCH64_LR_REGNUM, bp_addr);
1445 1.1 christos
1446 1.1 christos /* If we were given an initial argument for the return slot because
1447 1.1 christos lang_struct_return was true, lose it. */
1448 1.1 christos if (lang_struct_return)
1449 1.1 christos {
1450 1.1 christos args++;
1451 1.1 christos nargs--;
1452 1.1 christos }
1453 1.1 christos
1454 1.1 christos /* The struct_return pointer occupies X8. */
1455 1.1 christos if (struct_return || lang_struct_return)
1456 1.1 christos {
1457 1.1 christos if (aarch64_debug)
1458 1.6 christos {
1459 1.6 christos debug_printf ("struct return in %s = 0x%s\n",
1460 1.6 christos gdbarch_register_name (gdbarch,
1461 1.6 christos AARCH64_STRUCT_RETURN_REGNUM),
1462 1.6 christos paddress (gdbarch, struct_addr));
1463 1.6 christos }
1464 1.1 christos regcache_cooked_write_unsigned (regcache, AARCH64_STRUCT_RETURN_REGNUM,
1465 1.1 christos struct_addr);
1466 1.1 christos }
1467 1.1 christos
1468 1.1 christos for (argnum = 0; argnum < nargs; argnum++)
1469 1.1 christos {
1470 1.1 christos struct value *arg = args[argnum];
1471 1.1 christos struct type *arg_type;
1472 1.1 christos int len;
1473 1.1 christos
1474 1.1 christos arg_type = check_typedef (value_type (arg));
1475 1.1 christos len = TYPE_LENGTH (arg_type);
1476 1.1 christos
1477 1.1 christos switch (TYPE_CODE (arg_type))
1478 1.1 christos {
1479 1.1 christos case TYPE_CODE_INT:
1480 1.1 christos case TYPE_CODE_BOOL:
1481 1.1 christos case TYPE_CODE_CHAR:
1482 1.1 christos case TYPE_CODE_RANGE:
1483 1.1 christos case TYPE_CODE_ENUM:
1484 1.1 christos if (len < 4)
1485 1.1 christos {
1486 1.1 christos /* Promote to 32 bit integer. */
1487 1.1 christos if (TYPE_UNSIGNED (arg_type))
1488 1.1 christos arg_type = builtin_type (gdbarch)->builtin_uint32;
1489 1.1 christos else
1490 1.1 christos arg_type = builtin_type (gdbarch)->builtin_int32;
1491 1.1 christos arg = value_cast (arg_type, arg);
1492 1.1 christos }
1493 1.6 christos pass_in_x_or_stack (gdbarch, regcache, &info, arg_type, arg);
1494 1.1 christos break;
1495 1.1 christos
1496 1.1 christos case TYPE_CODE_COMPLEX:
1497 1.1 christos if (info.nsrn <= 6)
1498 1.1 christos {
1499 1.1 christos const bfd_byte *buf = value_contents (arg);
1500 1.1 christos struct type *target_type =
1501 1.1 christos check_typedef (TYPE_TARGET_TYPE (arg_type));
1502 1.1 christos
1503 1.1 christos pass_in_v (gdbarch, regcache, &info,
1504 1.6 christos TYPE_LENGTH (target_type), buf);
1505 1.6 christos pass_in_v (gdbarch, regcache, &info,
1506 1.6 christos TYPE_LENGTH (target_type),
1507 1.1 christos buf + TYPE_LENGTH (target_type));
1508 1.1 christos }
1509 1.1 christos else
1510 1.1 christos {
1511 1.1 christos info.nsrn = 8;
1512 1.6 christos pass_on_stack (&info, arg_type, arg);
1513 1.1 christos }
1514 1.1 christos break;
1515 1.1 christos case TYPE_CODE_FLT:
1516 1.6 christos pass_in_v_or_stack (gdbarch, regcache, &info, arg_type, arg);
1517 1.1 christos break;
1518 1.1 christos
1519 1.1 christos case TYPE_CODE_STRUCT:
1520 1.1 christos case TYPE_CODE_ARRAY:
1521 1.1 christos case TYPE_CODE_UNION:
1522 1.6 christos if (is_hfa_or_hva (arg_type))
1523 1.1 christos {
1524 1.1 christos int elements = TYPE_NFIELDS (arg_type);
1525 1.1 christos
1526 1.1 christos /* Homogeneous Aggregates */
1527 1.1 christos if (info.nsrn + elements < 8)
1528 1.1 christos {
1529 1.1 christos int i;
1530 1.1 christos
1531 1.1 christos for (i = 0; i < elements; i++)
1532 1.1 christos {
1533 1.1 christos /* We know that we have sufficient registers
1534 1.1 christos available therefore this will never fallback
1535 1.1 christos to the stack. */
1536 1.1 christos struct value *field =
1537 1.1 christos value_primitive_field (arg, 0, i, arg_type);
1538 1.1 christos struct type *field_type =
1539 1.1 christos check_typedef (value_type (field));
1540 1.1 christos
1541 1.6 christos pass_in_v_or_stack (gdbarch, regcache, &info,
1542 1.6 christos field_type, field);
1543 1.1 christos }
1544 1.1 christos }
1545 1.1 christos else
1546 1.1 christos {
1547 1.1 christos info.nsrn = 8;
1548 1.6 christos pass_on_stack (&info, arg_type, arg);
1549 1.1 christos }
1550 1.1 christos }
1551 1.6 christos else if (TYPE_CODE (arg_type) == TYPE_CODE_ARRAY
1552 1.6 christos && TYPE_VECTOR (arg_type) && (len == 16 || len == 8))
1553 1.6 christos {
1554 1.6 christos /* Short vector types are passed in V registers. */
1555 1.6 christos pass_in_v_or_stack (gdbarch, regcache, &info, arg_type, arg);
1556 1.6 christos }
1557 1.1 christos else if (len > 16)
1558 1.1 christos {
1559 1.1 christos /* PCS B.7 Aggregates larger than 16 bytes are passed by
1560 1.1 christos invisible reference. */
1561 1.1 christos
1562 1.1 christos /* Allocate aligned storage. */
1563 1.1 christos sp = align_down (sp - len, 16);
1564 1.1 christos
1565 1.1 christos /* Write the real data into the stack. */
1566 1.1 christos write_memory (sp, value_contents (arg), len);
1567 1.1 christos
1568 1.1 christos /* Construct the indirection. */
1569 1.1 christos arg_type = lookup_pointer_type (arg_type);
1570 1.1 christos arg = value_from_pointer (arg_type, sp);
1571 1.6 christos pass_in_x_or_stack (gdbarch, regcache, &info, arg_type, arg);
1572 1.1 christos }
1573 1.1 christos else
1574 1.1 christos /* PCS C.15 / C.18 multiple values pass. */
1575 1.6 christos pass_in_x_or_stack (gdbarch, regcache, &info, arg_type, arg);
1576 1.1 christos break;
1577 1.1 christos
1578 1.1 christos default:
1579 1.6 christos pass_in_x_or_stack (gdbarch, regcache, &info, arg_type, arg);
1580 1.1 christos break;
1581 1.1 christos }
1582 1.1 christos }
1583 1.1 christos
1584 1.1 christos /* Make sure stack retains 16 byte alignment. */
1585 1.1 christos if (info.nsaa & 15)
1586 1.1 christos sp -= 16 - (info.nsaa & 15);
1587 1.1 christos
1588 1.1 christos while (!VEC_empty (stack_item_t, info.si))
1589 1.1 christos {
1590 1.1 christos stack_item_t *si = VEC_last (stack_item_t, info.si);
1591 1.1 christos
1592 1.1 christos sp -= si->len;
1593 1.6 christos if (si->data != NULL)
1594 1.6 christos write_memory (sp, si->data, si->len);
1595 1.1 christos VEC_pop (stack_item_t, info.si);
1596 1.1 christos }
1597 1.1 christos
1598 1.1 christos VEC_free (stack_item_t, info.si);
1599 1.1 christos
1600 1.1 christos /* Finally, update the SP register. */
1601 1.1 christos regcache_cooked_write_unsigned (regcache, AARCH64_SP_REGNUM, sp);
1602 1.1 christos
1603 1.1 christos return sp;
1604 1.1 christos }
1605 1.1 christos
1606 1.1 christos /* Implement the "frame_align" gdbarch method. */
1607 1.1 christos
1608 1.1 christos static CORE_ADDR
1609 1.1 christos aarch64_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
1610 1.1 christos {
1611 1.1 christos /* Align the stack to sixteen bytes. */
1612 1.1 christos return sp & ~(CORE_ADDR) 15;
1613 1.1 christos }
1614 1.1 christos
1615 1.1 christos /* Return the type for an AdvSISD Q register. */
1616 1.1 christos
1617 1.1 christos static struct type *
1618 1.1 christos aarch64_vnq_type (struct gdbarch *gdbarch)
1619 1.1 christos {
1620 1.1 christos struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
1621 1.1 christos
1622 1.1 christos if (tdep->vnq_type == NULL)
1623 1.1 christos {
1624 1.1 christos struct type *t;
1625 1.1 christos struct type *elem;
1626 1.1 christos
1627 1.1 christos t = arch_composite_type (gdbarch, "__gdb_builtin_type_vnq",
1628 1.1 christos TYPE_CODE_UNION);
1629 1.1 christos
1630 1.1 christos elem = builtin_type (gdbarch)->builtin_uint128;
1631 1.1 christos append_composite_type_field (t, "u", elem);
1632 1.1 christos
1633 1.1 christos elem = builtin_type (gdbarch)->builtin_int128;
1634 1.1 christos append_composite_type_field (t, "s", elem);
1635 1.1 christos
1636 1.1 christos tdep->vnq_type = t;
1637 1.1 christos }
1638 1.1 christos
1639 1.1 christos return tdep->vnq_type;
1640 1.1 christos }
1641 1.1 christos
1642 1.1 christos /* Return the type for an AdvSISD D register. */
1643 1.1 christos
1644 1.1 christos static struct type *
1645 1.1 christos aarch64_vnd_type (struct gdbarch *gdbarch)
1646 1.1 christos {
1647 1.1 christos struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
1648 1.1 christos
1649 1.1 christos if (tdep->vnd_type == NULL)
1650 1.1 christos {
1651 1.1 christos struct type *t;
1652 1.1 christos struct type *elem;
1653 1.1 christos
1654 1.1 christos t = arch_composite_type (gdbarch, "__gdb_builtin_type_vnd",
1655 1.1 christos TYPE_CODE_UNION);
1656 1.1 christos
1657 1.1 christos elem = builtin_type (gdbarch)->builtin_double;
1658 1.1 christos append_composite_type_field (t, "f", elem);
1659 1.1 christos
1660 1.1 christos elem = builtin_type (gdbarch)->builtin_uint64;
1661 1.1 christos append_composite_type_field (t, "u", elem);
1662 1.1 christos
1663 1.1 christos elem = builtin_type (gdbarch)->builtin_int64;
1664 1.1 christos append_composite_type_field (t, "s", elem);
1665 1.1 christos
1666 1.1 christos tdep->vnd_type = t;
1667 1.1 christos }
1668 1.1 christos
1669 1.1 christos return tdep->vnd_type;
1670 1.1 christos }
1671 1.1 christos
1672 1.1 christos /* Return the type for an AdvSISD S register. */
1673 1.1 christos
1674 1.1 christos static struct type *
1675 1.1 christos aarch64_vns_type (struct gdbarch *gdbarch)
1676 1.1 christos {
1677 1.1 christos struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
1678 1.1 christos
1679 1.1 christos if (tdep->vns_type == NULL)
1680 1.1 christos {
1681 1.1 christos struct type *t;
1682 1.1 christos struct type *elem;
1683 1.1 christos
1684 1.1 christos t = arch_composite_type (gdbarch, "__gdb_builtin_type_vns",
1685 1.1 christos TYPE_CODE_UNION);
1686 1.1 christos
1687 1.1 christos elem = builtin_type (gdbarch)->builtin_float;
1688 1.1 christos append_composite_type_field (t, "f", elem);
1689 1.1 christos
1690 1.1 christos elem = builtin_type (gdbarch)->builtin_uint32;
1691 1.1 christos append_composite_type_field (t, "u", elem);
1692 1.1 christos
1693 1.1 christos elem = builtin_type (gdbarch)->builtin_int32;
1694 1.1 christos append_composite_type_field (t, "s", elem);
1695 1.1 christos
1696 1.1 christos tdep->vns_type = t;
1697 1.1 christos }
1698 1.1 christos
1699 1.1 christos return tdep->vns_type;
1700 1.1 christos }
1701 1.1 christos
1702 1.1 christos /* Return the type for an AdvSISD H register. */
1703 1.1 christos
1704 1.1 christos static struct type *
1705 1.1 christos aarch64_vnh_type (struct gdbarch *gdbarch)
1706 1.1 christos {
1707 1.1 christos struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
1708 1.1 christos
1709 1.1 christos if (tdep->vnh_type == NULL)
1710 1.1 christos {
1711 1.1 christos struct type *t;
1712 1.1 christos struct type *elem;
1713 1.1 christos
1714 1.1 christos t = arch_composite_type (gdbarch, "__gdb_builtin_type_vnh",
1715 1.1 christos TYPE_CODE_UNION);
1716 1.1 christos
1717 1.1 christos elem = builtin_type (gdbarch)->builtin_uint16;
1718 1.1 christos append_composite_type_field (t, "u", elem);
1719 1.1 christos
1720 1.1 christos elem = builtin_type (gdbarch)->builtin_int16;
1721 1.1 christos append_composite_type_field (t, "s", elem);
1722 1.1 christos
1723 1.1 christos tdep->vnh_type = t;
1724 1.1 christos }
1725 1.1 christos
1726 1.1 christos return tdep->vnh_type;
1727 1.1 christos }
1728 1.1 christos
1729 1.1 christos /* Return the type for an AdvSISD B register. */
1730 1.1 christos
1731 1.1 christos static struct type *
1732 1.1 christos aarch64_vnb_type (struct gdbarch *gdbarch)
1733 1.1 christos {
1734 1.1 christos struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
1735 1.1 christos
1736 1.1 christos if (tdep->vnb_type == NULL)
1737 1.1 christos {
1738 1.1 christos struct type *t;
1739 1.1 christos struct type *elem;
1740 1.1 christos
1741 1.1 christos t = arch_composite_type (gdbarch, "__gdb_builtin_type_vnb",
1742 1.1 christos TYPE_CODE_UNION);
1743 1.1 christos
1744 1.1 christos elem = builtin_type (gdbarch)->builtin_uint8;
1745 1.1 christos append_composite_type_field (t, "u", elem);
1746 1.1 christos
1747 1.1 christos elem = builtin_type (gdbarch)->builtin_int8;
1748 1.1 christos append_composite_type_field (t, "s", elem);
1749 1.1 christos
1750 1.1 christos tdep->vnb_type = t;
1751 1.1 christos }
1752 1.1 christos
1753 1.1 christos return tdep->vnb_type;
1754 1.1 christos }
1755 1.1 christos
1756 1.1 christos /* Implement the "dwarf2_reg_to_regnum" gdbarch method. */
1757 1.1 christos
1758 1.1 christos static int
1759 1.1 christos aarch64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
1760 1.1 christos {
1761 1.1 christos if (reg >= AARCH64_DWARF_X0 && reg <= AARCH64_DWARF_X0 + 30)
1762 1.1 christos return AARCH64_X0_REGNUM + reg - AARCH64_DWARF_X0;
1763 1.1 christos
1764 1.1 christos if (reg == AARCH64_DWARF_SP)
1765 1.1 christos return AARCH64_SP_REGNUM;
1766 1.1 christos
1767 1.1 christos if (reg >= AARCH64_DWARF_V0 && reg <= AARCH64_DWARF_V0 + 31)
1768 1.1 christos return AARCH64_V0_REGNUM + reg - AARCH64_DWARF_V0;
1769 1.1 christos
1770 1.1 christos return -1;
1771 1.1 christos }
1772 1.1 christos
1773 1.1 christos
1775 1.1 christos /* Implement the "print_insn" gdbarch method. */
1776 1.1 christos
1777 1.1 christos static int
1778 1.1 christos aarch64_gdb_print_insn (bfd_vma memaddr, disassemble_info *info)
1779 1.1 christos {
1780 1.1 christos info->symbols = NULL;
1781 1.1 christos return print_insn_aarch64 (memaddr, info);
1782 1.1 christos }
1783 1.1 christos
1784 1.1 christos /* AArch64 BRK software debug mode instruction.
1785 1.1 christos Note that AArch64 code is always little-endian.
1786 1.7 christos 1101.0100.0010.0000.0000.0000.0000.0000 = 0xd4200000. */
1787 1.1 christos constexpr gdb_byte aarch64_default_breakpoint[] = {0x00, 0x00, 0x20, 0xd4};
1788 1.7 christos
1789 1.1 christos typedef BP_MANIPULATION (aarch64_default_breakpoint) aarch64_breakpoint;
1790 1.1 christos
1791 1.1 christos /* Extract from an array REGS containing the (raw) register state a
1792 1.1 christos function return value of type TYPE, and copy that, in virtual
1793 1.1 christos format, into VALBUF. */
1794 1.1 christos
1795 1.1 christos static void
1796 1.1 christos aarch64_extract_return_value (struct type *type, struct regcache *regs,
1797 1.1 christos gdb_byte *valbuf)
1798 1.1 christos {
1799 1.1 christos struct gdbarch *gdbarch = get_regcache_arch (regs);
1800 1.1 christos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1801 1.1 christos
1802 1.1 christos if (TYPE_CODE (type) == TYPE_CODE_FLT)
1803 1.1 christos {
1804 1.1 christos bfd_byte buf[V_REGISTER_SIZE];
1805 1.1 christos int len = TYPE_LENGTH (type);
1806 1.1 christos
1807 1.1 christos regcache_cooked_read (regs, AARCH64_V0_REGNUM, buf);
1808 1.1 christos memcpy (valbuf, buf, len);
1809 1.1 christos }
1810 1.1 christos else if (TYPE_CODE (type) == TYPE_CODE_INT
1811 1.1 christos || TYPE_CODE (type) == TYPE_CODE_CHAR
1812 1.1 christos || TYPE_CODE (type) == TYPE_CODE_BOOL
1813 1.7 christos || TYPE_CODE (type) == TYPE_CODE_PTR
1814 1.1 christos || TYPE_IS_REFERENCE (type)
1815 1.1 christos || TYPE_CODE (type) == TYPE_CODE_ENUM)
1816 1.1 christos {
1817 1.1 christos /* If the the type is a plain integer, then the access is
1818 1.1 christos straight-forward. Otherwise we have to play around a bit
1819 1.1 christos more. */
1820 1.1 christos int len = TYPE_LENGTH (type);
1821 1.1 christos int regno = AARCH64_X0_REGNUM;
1822 1.1 christos ULONGEST tmp;
1823 1.1 christos
1824 1.1 christos while (len > 0)
1825 1.1 christos {
1826 1.1 christos /* By using store_unsigned_integer we avoid having to do
1827 1.1 christos anything special for small big-endian values. */
1828 1.1 christos regcache_cooked_read_unsigned (regs, regno++, &tmp);
1829 1.1 christos store_unsigned_integer (valbuf,
1830 1.1 christos (len > X_REGISTER_SIZE
1831 1.1 christos ? X_REGISTER_SIZE : len), byte_order, tmp);
1832 1.1 christos len -= X_REGISTER_SIZE;
1833 1.1 christos valbuf += X_REGISTER_SIZE;
1834 1.1 christos }
1835 1.1 christos }
1836 1.1 christos else if (TYPE_CODE (type) == TYPE_CODE_COMPLEX)
1837 1.1 christos {
1838 1.1 christos int regno = AARCH64_V0_REGNUM;
1839 1.1 christos bfd_byte buf[V_REGISTER_SIZE];
1840 1.1 christos struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
1841 1.1 christos int len = TYPE_LENGTH (target_type);
1842 1.1 christos
1843 1.1 christos regcache_cooked_read (regs, regno, buf);
1844 1.1 christos memcpy (valbuf, buf, len);
1845 1.1 christos valbuf += len;
1846 1.1 christos regcache_cooked_read (regs, regno + 1, buf);
1847 1.1 christos memcpy (valbuf, buf, len);
1848 1.1 christos valbuf += len;
1849 1.6 christos }
1850 1.1 christos else if (is_hfa_or_hva (type))
1851 1.1 christos {
1852 1.1 christos int elements = TYPE_NFIELDS (type);
1853 1.1 christos struct type *member_type = check_typedef (TYPE_FIELD_TYPE (type, 0));
1854 1.1 christos int len = TYPE_LENGTH (member_type);
1855 1.1 christos int i;
1856 1.1 christos
1857 1.1 christos for (i = 0; i < elements; i++)
1858 1.1 christos {
1859 1.6 christos int regno = AARCH64_V0_REGNUM + i;
1860 1.1 christos bfd_byte buf[V_REGISTER_SIZE];
1861 1.1 christos
1862 1.6 christos if (aarch64_debug)
1863 1.6 christos {
1864 1.6 christos debug_printf ("read HFA or HVA return value element %d from %s\n",
1865 1.6 christos i + 1,
1866 1.6 christos gdbarch_register_name (gdbarch, regno));
1867 1.1 christos }
1868 1.1 christos regcache_cooked_read (regs, regno, buf);
1869 1.1 christos
1870 1.1 christos memcpy (valbuf, buf, len);
1871 1.1 christos valbuf += len;
1872 1.1 christos }
1873 1.6 christos }
1874 1.6 christos else if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
1875 1.6 christos && (TYPE_LENGTH (type) == 16 || TYPE_LENGTH (type) == 8))
1876 1.6 christos {
1877 1.6 christos /* Short vector is returned in V register. */
1878 1.6 christos gdb_byte buf[V_REGISTER_SIZE];
1879 1.6 christos
1880 1.6 christos regcache_cooked_read (regs, AARCH64_V0_REGNUM, buf);
1881 1.6 christos memcpy (valbuf, buf, TYPE_LENGTH (type));
1882 1.1 christos }
1883 1.1 christos else
1884 1.1 christos {
1885 1.1 christos /* For a structure or union the behaviour is as if the value had
1886 1.1 christos been stored to word-aligned memory and then loaded into
1887 1.1 christos registers with 64-bit load instruction(s). */
1888 1.1 christos int len = TYPE_LENGTH (type);
1889 1.1 christos int regno = AARCH64_X0_REGNUM;
1890 1.1 christos bfd_byte buf[X_REGISTER_SIZE];
1891 1.1 christos
1892 1.1 christos while (len > 0)
1893 1.1 christos {
1894 1.1 christos regcache_cooked_read (regs, regno++, buf);
1895 1.1 christos memcpy (valbuf, buf, len > X_REGISTER_SIZE ? X_REGISTER_SIZE : len);
1896 1.1 christos len -= X_REGISTER_SIZE;
1897 1.1 christos valbuf += X_REGISTER_SIZE;
1898 1.1 christos }
1899 1.1 christos }
1900 1.1 christos }
1901 1.1 christos
1902 1.1 christos
1903 1.1 christos /* Will a function return an aggregate type in memory or in a
1904 1.1 christos register? Return 0 if an aggregate type can be returned in a
1905 1.1 christos register, 1 if it must be returned in memory. */
1906 1.1 christos
1907 1.1 christos static int
1908 1.1 christos aarch64_return_in_memory (struct gdbarch *gdbarch, struct type *type)
1909 1.6 christos {
1910 1.1 christos type = check_typedef (type);
1911 1.6 christos
1912 1.1 christos if (is_hfa_or_hva (type))
1913 1.6 christos {
1914 1.6 christos /* v0-v7 are used to return values and one register is allocated
1915 1.1 christos for one member. However, HFA or HVA has at most four members. */
1916 1.1 christos return 0;
1917 1.1 christos }
1918 1.1 christos
1919 1.1 christos if (TYPE_LENGTH (type) > 16)
1920 1.1 christos {
1921 1.1 christos /* PCS B.6 Aggregates larger than 16 bytes are passed by
1922 1.1 christos invisible reference. */
1923 1.1 christos
1924 1.1 christos return 1;
1925 1.1 christos }
1926 1.1 christos
1927 1.1 christos return 0;
1928 1.1 christos }
1929 1.1 christos
1930 1.1 christos /* Write into appropriate registers a function return value of type
1931 1.1 christos TYPE, given in virtual format. */
1932 1.1 christos
1933 1.1 christos static void
1934 1.1 christos aarch64_store_return_value (struct type *type, struct regcache *regs,
1935 1.1 christos const gdb_byte *valbuf)
1936 1.1 christos {
1937 1.1 christos struct gdbarch *gdbarch = get_regcache_arch (regs);
1938 1.1 christos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1939 1.1 christos
1940 1.1 christos if (TYPE_CODE (type) == TYPE_CODE_FLT)
1941 1.1 christos {
1942 1.1 christos bfd_byte buf[V_REGISTER_SIZE];
1943 1.1 christos int len = TYPE_LENGTH (type);
1944 1.1 christos
1945 1.1 christos memcpy (buf, valbuf, len > V_REGISTER_SIZE ? V_REGISTER_SIZE : len);
1946 1.1 christos regcache_cooked_write (regs, AARCH64_V0_REGNUM, buf);
1947 1.1 christos }
1948 1.1 christos else if (TYPE_CODE (type) == TYPE_CODE_INT
1949 1.1 christos || TYPE_CODE (type) == TYPE_CODE_CHAR
1950 1.1 christos || TYPE_CODE (type) == TYPE_CODE_BOOL
1951 1.7 christos || TYPE_CODE (type) == TYPE_CODE_PTR
1952 1.1 christos || TYPE_IS_REFERENCE (type)
1953 1.1 christos || TYPE_CODE (type) == TYPE_CODE_ENUM)
1954 1.1 christos {
1955 1.1 christos if (TYPE_LENGTH (type) <= X_REGISTER_SIZE)
1956 1.1 christos {
1957 1.1 christos /* Values of one word or less are zero/sign-extended and
1958 1.1 christos returned in r0. */
1959 1.1 christos bfd_byte tmpbuf[X_REGISTER_SIZE];
1960 1.1 christos LONGEST val = unpack_long (type, valbuf);
1961 1.1 christos
1962 1.1 christos store_signed_integer (tmpbuf, X_REGISTER_SIZE, byte_order, val);
1963 1.1 christos regcache_cooked_write (regs, AARCH64_X0_REGNUM, tmpbuf);
1964 1.1 christos }
1965 1.1 christos else
1966 1.1 christos {
1967 1.1 christos /* Integral values greater than one word are stored in
1968 1.1 christos consecutive registers starting with r0. This will always
1969 1.1 christos be a multiple of the regiser size. */
1970 1.1 christos int len = TYPE_LENGTH (type);
1971 1.1 christos int regno = AARCH64_X0_REGNUM;
1972 1.1 christos
1973 1.1 christos while (len > 0)
1974 1.1 christos {
1975 1.1 christos regcache_cooked_write (regs, regno++, valbuf);
1976 1.1 christos len -= X_REGISTER_SIZE;
1977 1.1 christos valbuf += X_REGISTER_SIZE;
1978 1.1 christos }
1979 1.1 christos }
1980 1.6 christos }
1981 1.1 christos else if (is_hfa_or_hva (type))
1982 1.1 christos {
1983 1.1 christos int elements = TYPE_NFIELDS (type);
1984 1.1 christos struct type *member_type = check_typedef (TYPE_FIELD_TYPE (type, 0));
1985 1.1 christos int len = TYPE_LENGTH (member_type);
1986 1.1 christos int i;
1987 1.1 christos
1988 1.1 christos for (i = 0; i < elements; i++)
1989 1.1 christos {
1990 1.1 christos int regno = AARCH64_V0_REGNUM + i;
1991 1.1 christos bfd_byte tmpbuf[MAX_REGISTER_SIZE];
1992 1.1 christos
1993 1.6 christos if (aarch64_debug)
1994 1.6 christos {
1995 1.6 christos debug_printf ("write HFA or HVA return value element %d to %s\n",
1996 1.6 christos i + 1,
1997 1.6 christos gdbarch_register_name (gdbarch, regno));
1998 1.1 christos }
1999 1.1 christos
2000 1.1 christos memcpy (tmpbuf, valbuf, len);
2001 1.1 christos regcache_cooked_write (regs, regno, tmpbuf);
2002 1.1 christos valbuf += len;
2003 1.1 christos }
2004 1.6 christos }
2005 1.6 christos else if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
2006 1.6 christos && (TYPE_LENGTH (type) == 8 || TYPE_LENGTH (type) == 16))
2007 1.6 christos {
2008 1.6 christos /* Short vector. */
2009 1.6 christos gdb_byte buf[V_REGISTER_SIZE];
2010 1.6 christos
2011 1.6 christos memcpy (buf, valbuf, TYPE_LENGTH (type));
2012 1.6 christos regcache_cooked_write (regs, AARCH64_V0_REGNUM, buf);
2013 1.1 christos }
2014 1.1 christos else
2015 1.1 christos {
2016 1.1 christos /* For a structure or union the behaviour is as if the value had
2017 1.1 christos been stored to word-aligned memory and then loaded into
2018 1.1 christos registers with 64-bit load instruction(s). */
2019 1.1 christos int len = TYPE_LENGTH (type);
2020 1.1 christos int regno = AARCH64_X0_REGNUM;
2021 1.1 christos bfd_byte tmpbuf[X_REGISTER_SIZE];
2022 1.1 christos
2023 1.1 christos while (len > 0)
2024 1.1 christos {
2025 1.1 christos memcpy (tmpbuf, valbuf,
2026 1.1 christos len > X_REGISTER_SIZE ? X_REGISTER_SIZE : len);
2027 1.1 christos regcache_cooked_write (regs, regno++, tmpbuf);
2028 1.1 christos len -= X_REGISTER_SIZE;
2029 1.1 christos valbuf += X_REGISTER_SIZE;
2030 1.1 christos }
2031 1.1 christos }
2032 1.1 christos }
2033 1.1 christos
2034 1.1 christos /* Implement the "return_value" gdbarch method. */
2035 1.1 christos
2036 1.1 christos static enum return_value_convention
2037 1.1 christos aarch64_return_value (struct gdbarch *gdbarch, struct value *func_value,
2038 1.1 christos struct type *valtype, struct regcache *regcache,
2039 1.1 christos gdb_byte *readbuf, const gdb_byte *writebuf)
2040 1.1 christos {
2041 1.1 christos
2042 1.1 christos if (TYPE_CODE (valtype) == TYPE_CODE_STRUCT
2043 1.1 christos || TYPE_CODE (valtype) == TYPE_CODE_UNION
2044 1.1 christos || TYPE_CODE (valtype) == TYPE_CODE_ARRAY)
2045 1.1 christos {
2046 1.1 christos if (aarch64_return_in_memory (gdbarch, valtype))
2047 1.1 christos {
2048 1.6 christos if (aarch64_debug)
2049 1.1 christos debug_printf ("return value in memory\n");
2050 1.1 christos return RETURN_VALUE_STRUCT_CONVENTION;
2051 1.1 christos }
2052 1.1 christos }
2053 1.1 christos
2054 1.1 christos if (writebuf)
2055 1.1 christos aarch64_store_return_value (valtype, regcache, writebuf);
2056 1.1 christos
2057 1.1 christos if (readbuf)
2058 1.1 christos aarch64_extract_return_value (valtype, regcache, readbuf);
2059 1.1 christos
2060 1.6 christos if (aarch64_debug)
2061 1.1 christos debug_printf ("return value in registers\n");
2062 1.1 christos
2063 1.1 christos return RETURN_VALUE_REGISTER_CONVENTION;
2064 1.1 christos }
2065 1.1 christos
2066 1.1 christos /* Implement the "get_longjmp_target" gdbarch method. */
2067 1.1 christos
2068 1.1 christos static int
2069 1.1 christos aarch64_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
2070 1.1 christos {
2071 1.1 christos CORE_ADDR jb_addr;
2072 1.1 christos gdb_byte buf[X_REGISTER_SIZE];
2073 1.1 christos struct gdbarch *gdbarch = get_frame_arch (frame);
2074 1.1 christos struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
2075 1.1 christos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
2076 1.1 christos
2077 1.1 christos jb_addr = get_frame_register_unsigned (frame, AARCH64_X0_REGNUM);
2078 1.1 christos
2079 1.1 christos if (target_read_memory (jb_addr + tdep->jb_pc * tdep->jb_elt_size, buf,
2080 1.1 christos X_REGISTER_SIZE))
2081 1.1 christos return 0;
2082 1.1 christos
2083 1.1 christos *pc = extract_unsigned_integer (buf, X_REGISTER_SIZE, byte_order);
2084 1.1 christos return 1;
2085 1.6 christos }
2086 1.6 christos
2087 1.6 christos /* Implement the "gen_return_address" gdbarch method. */
2088 1.6 christos
2089 1.6 christos static void
2090 1.6 christos aarch64_gen_return_address (struct gdbarch *gdbarch,
2091 1.6 christos struct agent_expr *ax, struct axs_value *value,
2092 1.6 christos CORE_ADDR scope)
2093 1.6 christos {
2094 1.6 christos value->type = register_type (gdbarch, AARCH64_LR_REGNUM);
2095 1.6 christos value->kind = axs_lvalue_register;
2096 1.6 christos value->u.reg = AARCH64_LR_REGNUM;
2097 1.1 christos }
2098 1.1 christos
2099 1.1 christos
2101 1.1 christos /* Return the pseudo register name corresponding to register regnum. */
2102 1.1 christos
2103 1.1 christos static const char *
2104 1.1 christos aarch64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
2105 1.1 christos {
2106 1.1 christos static const char *const q_name[] =
2107 1.1 christos {
2108 1.1 christos "q0", "q1", "q2", "q3",
2109 1.1 christos "q4", "q5", "q6", "q7",
2110 1.1 christos "q8", "q9", "q10", "q11",
2111 1.1 christos "q12", "q13", "q14", "q15",
2112 1.1 christos "q16", "q17", "q18", "q19",
2113 1.1 christos "q20", "q21", "q22", "q23",
2114 1.1 christos "q24", "q25", "q26", "q27",
2115 1.1 christos "q28", "q29", "q30", "q31",
2116 1.1 christos };
2117 1.1 christos
2118 1.1 christos static const char *const d_name[] =
2119 1.1 christos {
2120 1.1 christos "d0", "d1", "d2", "d3",
2121 1.1 christos "d4", "d5", "d6", "d7",
2122 1.1 christos "d8", "d9", "d10", "d11",
2123 1.1 christos "d12", "d13", "d14", "d15",
2124 1.1 christos "d16", "d17", "d18", "d19",
2125 1.1 christos "d20", "d21", "d22", "d23",
2126 1.1 christos "d24", "d25", "d26", "d27",
2127 1.1 christos "d28", "d29", "d30", "d31",
2128 1.1 christos };
2129 1.1 christos
2130 1.1 christos static const char *const s_name[] =
2131 1.1 christos {
2132 1.1 christos "s0", "s1", "s2", "s3",
2133 1.1 christos "s4", "s5", "s6", "s7",
2134 1.1 christos "s8", "s9", "s10", "s11",
2135 1.1 christos "s12", "s13", "s14", "s15",
2136 1.1 christos "s16", "s17", "s18", "s19",
2137 1.1 christos "s20", "s21", "s22", "s23",
2138 1.1 christos "s24", "s25", "s26", "s27",
2139 1.1 christos "s28", "s29", "s30", "s31",
2140 1.1 christos };
2141 1.1 christos
2142 1.1 christos static const char *const h_name[] =
2143 1.1 christos {
2144 1.1 christos "h0", "h1", "h2", "h3",
2145 1.1 christos "h4", "h5", "h6", "h7",
2146 1.1 christos "h8", "h9", "h10", "h11",
2147 1.1 christos "h12", "h13", "h14", "h15",
2148 1.1 christos "h16", "h17", "h18", "h19",
2149 1.1 christos "h20", "h21", "h22", "h23",
2150 1.1 christos "h24", "h25", "h26", "h27",
2151 1.1 christos "h28", "h29", "h30", "h31",
2152 1.1 christos };
2153 1.1 christos
2154 1.1 christos static const char *const b_name[] =
2155 1.1 christos {
2156 1.1 christos "b0", "b1", "b2", "b3",
2157 1.1 christos "b4", "b5", "b6", "b7",
2158 1.1 christos "b8", "b9", "b10", "b11",
2159 1.1 christos "b12", "b13", "b14", "b15",
2160 1.1 christos "b16", "b17", "b18", "b19",
2161 1.1 christos "b20", "b21", "b22", "b23",
2162 1.1 christos "b24", "b25", "b26", "b27",
2163 1.1 christos "b28", "b29", "b30", "b31",
2164 1.1 christos };
2165 1.1 christos
2166 1.1 christos regnum -= gdbarch_num_regs (gdbarch);
2167 1.1 christos
2168 1.1 christos if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
2169 1.1 christos return q_name[regnum - AARCH64_Q0_REGNUM];
2170 1.1 christos
2171 1.1 christos if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32)
2172 1.1 christos return d_name[regnum - AARCH64_D0_REGNUM];
2173 1.1 christos
2174 1.1 christos if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32)
2175 1.1 christos return s_name[regnum - AARCH64_S0_REGNUM];
2176 1.1 christos
2177 1.1 christos if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32)
2178 1.1 christos return h_name[regnum - AARCH64_H0_REGNUM];
2179 1.1 christos
2180 1.1 christos if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
2181 1.1 christos return b_name[regnum - AARCH64_B0_REGNUM];
2182 1.1 christos
2183 1.1 christos internal_error (__FILE__, __LINE__,
2184 1.1 christos _("aarch64_pseudo_register_name: bad register number %d"),
2185 1.1 christos regnum);
2186 1.1 christos }
2187 1.1 christos
2188 1.1 christos /* Implement the "pseudo_register_type" tdesc_arch_data method. */
2189 1.1 christos
2190 1.1 christos static struct type *
2191 1.1 christos aarch64_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
2192 1.1 christos {
2193 1.1 christos regnum -= gdbarch_num_regs (gdbarch);
2194 1.1 christos
2195 1.1 christos if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
2196 1.1 christos return aarch64_vnq_type (gdbarch);
2197 1.1 christos
2198 1.1 christos if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32)
2199 1.1 christos return aarch64_vnd_type (gdbarch);
2200 1.1 christos
2201 1.1 christos if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32)
2202 1.1 christos return aarch64_vns_type (gdbarch);
2203 1.1 christos
2204 1.1 christos if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32)
2205 1.1 christos return aarch64_vnh_type (gdbarch);
2206 1.1 christos
2207 1.1 christos if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
2208 1.1 christos return aarch64_vnb_type (gdbarch);
2209 1.1 christos
2210 1.1 christos internal_error (__FILE__, __LINE__,
2211 1.1 christos _("aarch64_pseudo_register_type: bad register number %d"),
2212 1.1 christos regnum);
2213 1.1 christos }
2214 1.1 christos
2215 1.1 christos /* Implement the "pseudo_register_reggroup_p" tdesc_arch_data method. */
2216 1.1 christos
2217 1.1 christos static int
2218 1.1 christos aarch64_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
2219 1.1 christos struct reggroup *group)
2220 1.1 christos {
2221 1.1 christos regnum -= gdbarch_num_regs (gdbarch);
2222 1.1 christos
2223 1.1 christos if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
2224 1.1 christos return group == all_reggroup || group == vector_reggroup;
2225 1.1 christos else if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32)
2226 1.1 christos return (group == all_reggroup || group == vector_reggroup
2227 1.1 christos || group == float_reggroup);
2228 1.1 christos else if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32)
2229 1.1 christos return (group == all_reggroup || group == vector_reggroup
2230 1.1 christos || group == float_reggroup);
2231 1.1 christos else if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32)
2232 1.1 christos return group == all_reggroup || group == vector_reggroup;
2233 1.1 christos else if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
2234 1.1 christos return group == all_reggroup || group == vector_reggroup;
2235 1.1 christos
2236 1.1 christos return group == all_reggroup;
2237 1.1 christos }
2238 1.1 christos
2239 1.1 christos /* Implement the "pseudo_register_read_value" gdbarch method. */
2240 1.1 christos
2241 1.1 christos static struct value *
2242 1.1 christos aarch64_pseudo_read_value (struct gdbarch *gdbarch,
2243 1.1 christos struct regcache *regcache,
2244 1.1 christos int regnum)
2245 1.1 christos {
2246 1.1 christos gdb_byte reg_buf[MAX_REGISTER_SIZE];
2247 1.1 christos struct value *result_value;
2248 1.1 christos gdb_byte *buf;
2249 1.1 christos
2250 1.1 christos result_value = allocate_value (register_type (gdbarch, regnum));
2251 1.1 christos VALUE_LVAL (result_value) = lval_register;
2252 1.1 christos VALUE_REGNUM (result_value) = regnum;
2253 1.1 christos buf = value_contents_raw (result_value);
2254 1.1 christos
2255 1.1 christos regnum -= gdbarch_num_regs (gdbarch);
2256 1.1 christos
2257 1.1 christos if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
2258 1.1 christos {
2259 1.1 christos enum register_status status;
2260 1.1 christos unsigned v_regnum;
2261 1.1 christos
2262 1.1 christos v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_Q0_REGNUM;
2263 1.1 christos status = regcache_raw_read (regcache, v_regnum, reg_buf);
2264 1.1 christos if (status != REG_VALID)
2265 1.1 christos mark_value_bytes_unavailable (result_value, 0,
2266 1.1 christos TYPE_LENGTH (value_type (result_value)));
2267 1.1 christos else
2268 1.1 christos memcpy (buf, reg_buf, Q_REGISTER_SIZE);
2269 1.1 christos return result_value;
2270 1.1 christos }
2271 1.1 christos
2272 1.1 christos if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32)
2273 1.1 christos {
2274 1.1 christos enum register_status status;
2275 1.1 christos unsigned v_regnum;
2276 1.1 christos
2277 1.1 christos v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_D0_REGNUM;
2278 1.1 christos status = regcache_raw_read (regcache, v_regnum, reg_buf);
2279 1.1 christos if (status != REG_VALID)
2280 1.1 christos mark_value_bytes_unavailable (result_value, 0,
2281 1.1 christos TYPE_LENGTH (value_type (result_value)));
2282 1.1 christos else
2283 1.1 christos memcpy (buf, reg_buf, D_REGISTER_SIZE);
2284 1.1 christos return result_value;
2285 1.1 christos }
2286 1.1 christos
2287 1.1 christos if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32)
2288 1.1 christos {
2289 1.1 christos enum register_status status;
2290 1.1 christos unsigned v_regnum;
2291 1.1 christos
2292 1.6 christos v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_S0_REGNUM;
2293 1.6 christos status = regcache_raw_read (regcache, v_regnum, reg_buf);
2294 1.6 christos if (status != REG_VALID)
2295 1.6 christos mark_value_bytes_unavailable (result_value, 0,
2296 1.6 christos TYPE_LENGTH (value_type (result_value)));
2297 1.1 christos else
2298 1.1 christos memcpy (buf, reg_buf, S_REGISTER_SIZE);
2299 1.1 christos return result_value;
2300 1.1 christos }
2301 1.1 christos
2302 1.1 christos if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32)
2303 1.1 christos {
2304 1.1 christos enum register_status status;
2305 1.1 christos unsigned v_regnum;
2306 1.1 christos
2307 1.1 christos v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_H0_REGNUM;
2308 1.1 christos status = regcache_raw_read (regcache, v_regnum, reg_buf);
2309 1.1 christos if (status != REG_VALID)
2310 1.1 christos mark_value_bytes_unavailable (result_value, 0,
2311 1.1 christos TYPE_LENGTH (value_type (result_value)));
2312 1.1 christos else
2313 1.1 christos memcpy (buf, reg_buf, H_REGISTER_SIZE);
2314 1.1 christos return result_value;
2315 1.1 christos }
2316 1.1 christos
2317 1.1 christos if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
2318 1.1 christos {
2319 1.1 christos enum register_status status;
2320 1.1 christos unsigned v_regnum;
2321 1.1 christos
2322 1.1 christos v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_B0_REGNUM;
2323 1.1 christos status = regcache_raw_read (regcache, v_regnum, reg_buf);
2324 1.1 christos if (status != REG_VALID)
2325 1.1 christos mark_value_bytes_unavailable (result_value, 0,
2326 1.1 christos TYPE_LENGTH (value_type (result_value)));
2327 1.1 christos else
2328 1.1 christos memcpy (buf, reg_buf, B_REGISTER_SIZE);
2329 1.1 christos return result_value;
2330 1.1 christos }
2331 1.1 christos
2332 1.1 christos gdb_assert_not_reached ("regnum out of bound");
2333 1.1 christos }
2334 1.1 christos
2335 1.1 christos /* Implement the "pseudo_register_write" gdbarch method. */
2336 1.1 christos
2337 1.1 christos static void
2338 1.1 christos aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
2339 1.1 christos int regnum, const gdb_byte *buf)
2340 1.1 christos {
2341 1.1 christos gdb_byte reg_buf[MAX_REGISTER_SIZE];
2342 1.1 christos
2343 1.1 christos /* Ensure the register buffer is zero, we want gdb writes of the
2344 1.1 christos various 'scalar' pseudo registers to behavior like architectural
2345 1.1 christos writes, register width bytes are written the remainder are set to
2346 1.1 christos zero. */
2347 1.1 christos memset (reg_buf, 0, sizeof (reg_buf));
2348 1.1 christos
2349 1.1 christos regnum -= gdbarch_num_regs (gdbarch);
2350 1.1 christos
2351 1.1 christos if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
2352 1.1 christos {
2353 1.1 christos /* pseudo Q registers */
2354 1.1 christos unsigned v_regnum;
2355 1.1 christos
2356 1.1 christos v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_Q0_REGNUM;
2357 1.1 christos memcpy (reg_buf, buf, Q_REGISTER_SIZE);
2358 1.1 christos regcache_raw_write (regcache, v_regnum, reg_buf);
2359 1.1 christos return;
2360 1.1 christos }
2361 1.1 christos
2362 1.1 christos if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32)
2363 1.1 christos {
2364 1.1 christos /* pseudo D registers */
2365 1.1 christos unsigned v_regnum;
2366 1.1 christos
2367 1.1 christos v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_D0_REGNUM;
2368 1.1 christos memcpy (reg_buf, buf, D_REGISTER_SIZE);
2369 1.1 christos regcache_raw_write (regcache, v_regnum, reg_buf);
2370 1.1 christos return;
2371 1.1 christos }
2372 1.1 christos
2373 1.1 christos if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32)
2374 1.1 christos {
2375 1.1 christos unsigned v_regnum;
2376 1.1 christos
2377 1.1 christos v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_S0_REGNUM;
2378 1.1 christos memcpy (reg_buf, buf, S_REGISTER_SIZE);
2379 1.1 christos regcache_raw_write (regcache, v_regnum, reg_buf);
2380 1.1 christos return;
2381 1.1 christos }
2382 1.1 christos
2383 1.1 christos if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32)
2384 1.1 christos {
2385 1.1 christos /* pseudo H registers */
2386 1.1 christos unsigned v_regnum;
2387 1.1 christos
2388 1.1 christos v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_H0_REGNUM;
2389 1.1 christos memcpy (reg_buf, buf, H_REGISTER_SIZE);
2390 1.1 christos regcache_raw_write (regcache, v_regnum, reg_buf);
2391 1.1 christos return;
2392 1.1 christos }
2393 1.1 christos
2394 1.1 christos if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
2395 1.1 christos {
2396 1.1 christos /* pseudo B registers */
2397 1.1 christos unsigned v_regnum;
2398 1.1 christos
2399 1.1 christos v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_B0_REGNUM;
2400 1.1 christos memcpy (reg_buf, buf, B_REGISTER_SIZE);
2401 1.1 christos regcache_raw_write (regcache, v_regnum, reg_buf);
2402 1.1 christos return;
2403 1.1 christos }
2404 1.1 christos
2405 1.1 christos gdb_assert_not_reached ("regnum out of bound");
2406 1.1 christos }
2407 1.1 christos
2408 1.1 christos /* Callback function for user_reg_add. */
2409 1.1 christos
2410 1.1 christos static struct value *
2411 1.6 christos value_of_aarch64_user_reg (struct frame_info *frame, const void *baton)
2412 1.1 christos {
2413 1.1 christos const int *reg_p = (const int *) baton;
2414 1.1 christos
2415 1.1 christos return value_of_register (*reg_p, frame);
2416 1.1 christos }
2417 1.3 christos
2418 1.3 christos
2420 1.7 christos /* Implement the "software_single_step" gdbarch method, needed to
2421 1.7 christos single step through atomic sequences on AArch64. */
2422 1.3 christos
2423 1.7 christos static VEC (CORE_ADDR) *
2424 1.3 christos aarch64_software_single_step (struct regcache *regcache)
2425 1.3 christos {
2426 1.3 christos struct gdbarch *gdbarch = get_regcache_arch (regcache);
2427 1.7 christos enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
2428 1.7 christos const int insn_size = 4;
2429 1.3 christos const int atomic_sequence_length = 16; /* Instruction sequence length. */
2430 1.3 christos CORE_ADDR pc = regcache_read_pc (regcache);
2431 1.3 christos CORE_ADDR breaks[2] = { (ULONGEST)-1, (ULONGEST)-1 };
2432 1.3 christos CORE_ADDR loc = pc;
2433 1.3 christos CORE_ADDR closing_insn = 0;
2434 1.3 christos uint32_t insn = read_memory_unsigned_integer (loc, insn_size,
2435 1.3 christos byte_order_for_code);
2436 1.3 christos int index;
2437 1.6 christos int insn_count;
2438 1.7 christos int bc_insn_count = 0; /* Conditional branch instruction count. */
2439 1.6 christos int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */
2440 1.6 christos aarch64_inst inst;
2441 1.7 christos VEC (CORE_ADDR) *next_pcs = NULL;
2442 1.3 christos
2443 1.3 christos if (aarch64_decode_insn (insn, &inst, 1) != 0)
2444 1.6 christos return NULL;
2445 1.7 christos
2446 1.3 christos /* Look for a Load Exclusive instruction which begins the sequence. */
2447 1.3 christos if (inst.opcode->iclass != ldstexcl || bit (insn, 22) == 0)
2448 1.3 christos return NULL;
2449 1.3 christos
2450 1.3 christos for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count)
2451 1.3 christos {
2452 1.3 christos loc += insn_size;
2453 1.6 christos insn = read_memory_unsigned_integer (loc, insn_size,
2454 1.7 christos byte_order_for_code);
2455 1.3 christos
2456 1.6 christos if (aarch64_decode_insn (insn, &inst, 1) != 0)
2457 1.3 christos return NULL;
2458 1.6 christos /* Check if the instruction is a conditional branch. */
2459 1.6 christos if (inst.opcode->iclass == condbranch)
2460 1.3 christos {
2461 1.7 christos gdb_assert (inst.operands[0].type == AARCH64_OPND_ADDR_PCREL19);
2462 1.3 christos
2463 1.3 christos if (bc_insn_count >= 1)
2464 1.6 christos return NULL;
2465 1.3 christos
2466 1.3 christos /* It is, so we'll try to set a breakpoint at the destination. */
2467 1.3 christos breaks[1] = loc + inst.operands[0].imm.value;
2468 1.3 christos
2469 1.3 christos bc_insn_count++;
2470 1.3 christos last_breakpoint++;
2471 1.6 christos }
2472 1.3 christos
2473 1.3 christos /* Look for the Store Exclusive which closes the atomic sequence. */
2474 1.3 christos if (inst.opcode->iclass == ldstexcl && bit (insn, 22) == 0)
2475 1.3 christos {
2476 1.3 christos closing_insn = loc;
2477 1.3 christos break;
2478 1.3 christos }
2479 1.3 christos }
2480 1.7 christos
2481 1.3 christos /* We didn't find a closing Store Exclusive instruction, fall back. */
2482 1.3 christos if (!closing_insn)
2483 1.3 christos return NULL;
2484 1.3 christos
2485 1.3 christos /* Insert breakpoint after the end of the atomic sequence. */
2486 1.3 christos breaks[0] = loc + insn_size;
2487 1.3 christos
2488 1.3 christos /* Check for duplicated breakpoints, and also check that the second
2489 1.3 christos breakpoint is not within the atomic sequence. */
2490 1.3 christos if (last_breakpoint
2491 1.3 christos && (breaks[1] == breaks[0]
2492 1.3 christos || (breaks[1] >= pc && breaks[1] <= closing_insn)))
2493 1.3 christos last_breakpoint = 0;
2494 1.3 christos
2495 1.7 christos /* Insert the breakpoint at the end of the sequence, and one at the
2496 1.3 christos destination of the conditional branch, if it exists. */
2497 1.7 christos for (index = 0; index <= last_breakpoint; index++)
2498 1.3 christos VEC_safe_push (CORE_ADDR, next_pcs, breaks[index]);
2499 1.3 christos
2500 1.6 christos return next_pcs;
2501 1.6 christos }
2502 1.6 christos
2503 1.6 christos struct displaced_step_closure
2504 1.6 christos {
2505 1.6 christos /* It is true when condition instruction, such as B.CON, TBZ, etc,
2506 1.6 christos is being displaced stepping. */
2507 1.6 christos int cond;
2508 1.6 christos
2509 1.6 christos /* PC adjustment offset after displaced stepping. */
2510 1.6 christos int32_t pc_adjust;
2511 1.6 christos };
2512 1.6 christos
2513 1.6 christos /* Data when visiting instructions for displaced stepping. */
2514 1.6 christos
2515 1.6 christos struct aarch64_displaced_step_data
2516 1.6 christos {
2517 1.6 christos struct aarch64_insn_data base;
2518 1.6 christos
2519 1.6 christos /* The address where the instruction will be executed at. */
2520 1.6 christos CORE_ADDR new_addr;
2521 1.6 christos /* Buffer of instructions to be copied to NEW_ADDR to execute. */
2522 1.6 christos uint32_t insn_buf[DISPLACED_MODIFIED_INSNS];
2523 1.6 christos /* Number of instructions in INSN_BUF. */
2524 1.6 christos unsigned insn_count;
2525 1.6 christos /* Registers when doing displaced stepping. */
2526 1.6 christos struct regcache *regs;
2527 1.6 christos
2528 1.6 christos struct displaced_step_closure *dsc;
2529 1.6 christos };
2530 1.6 christos
2531 1.6 christos /* Implementation of aarch64_insn_visitor method "b". */
2532 1.6 christos
2533 1.6 christos static void
2534 1.6 christos aarch64_displaced_step_b (const int is_bl, const int32_t offset,
2535 1.6 christos struct aarch64_insn_data *data)
2536 1.6 christos {
2537 1.6 christos struct aarch64_displaced_step_data *dsd
2538 1.6 christos = (struct aarch64_displaced_step_data *) data;
2539 1.6 christos int64_t new_offset = data->insn_addr - dsd->new_addr + offset;
2540 1.6 christos
2541 1.6 christos if (can_encode_int32 (new_offset, 28))
2542 1.6 christos {
2543 1.6 christos /* Emit B rather than BL, because executing BL on a new address
2544 1.6 christos will get the wrong address into LR. In order to avoid this,
2545 1.6 christos we emit B, and update LR if the instruction is BL. */
2546 1.6 christos emit_b (dsd->insn_buf, 0, new_offset);
2547 1.6 christos dsd->insn_count++;
2548 1.6 christos }
2549 1.6 christos else
2550 1.6 christos {
2551 1.6 christos /* Write NOP. */
2552 1.6 christos emit_nop (dsd->insn_buf);
2553 1.6 christos dsd->insn_count++;
2554 1.6 christos dsd->dsc->pc_adjust = offset;
2555 1.6 christos }
2556 1.6 christos
2557 1.6 christos if (is_bl)
2558 1.6 christos {
2559 1.6 christos /* Update LR. */
2560 1.6 christos regcache_cooked_write_unsigned (dsd->regs, AARCH64_LR_REGNUM,
2561 1.6 christos data->insn_addr + 4);
2562 1.6 christos }
2563 1.6 christos }
2564 1.6 christos
2565 1.6 christos /* Implementation of aarch64_insn_visitor method "b_cond". */
2566 1.6 christos
2567 1.6 christos static void
2568 1.6 christos aarch64_displaced_step_b_cond (const unsigned cond, const int32_t offset,
2569 1.6 christos struct aarch64_insn_data *data)
2570 1.6 christos {
2571 1.6 christos struct aarch64_displaced_step_data *dsd
2572 1.6 christos = (struct aarch64_displaced_step_data *) data;
2573 1.6 christos
2574 1.6 christos /* GDB has to fix up PC after displaced step this instruction
2575 1.6 christos differently according to the condition is true or false. Instead
2576 1.6 christos of checking COND against conditional flags, we can use
2577 1.6 christos the following instructions, and GDB can tell how to fix up PC
2578 1.6 christos according to the PC value.
2579 1.6 christos
2580 1.6 christos B.COND TAKEN ; If cond is true, then jump to TAKEN.
2581 1.6 christos INSN1 ;
2582 1.6 christos TAKEN:
2583 1.6 christos INSN2
2584 1.6 christos */
2585 1.6 christos
2586 1.6 christos emit_bcond (dsd->insn_buf, cond, 8);
2587 1.6 christos dsd->dsc->cond = 1;
2588 1.6 christos dsd->dsc->pc_adjust = offset;
2589 1.6 christos dsd->insn_count = 1;
2590 1.6 christos }
2591 1.6 christos
2592 1.6 christos /* Dynamically allocate a new register. If we know the register
2593 1.6 christos statically, we should make it a global as above instead of using this
2594 1.6 christos helper function. */
2595 1.6 christos
2596 1.6 christos static struct aarch64_register
2597 1.6 christos aarch64_register (unsigned num, int is64)
2598 1.6 christos {
2599 1.6 christos return (struct aarch64_register) { num, is64 };
2600 1.6 christos }
2601 1.6 christos
2602 1.6 christos /* Implementation of aarch64_insn_visitor method "cb". */
2603 1.6 christos
2604 1.6 christos static void
2605 1.6 christos aarch64_displaced_step_cb (const int32_t offset, const int is_cbnz,
2606 1.6 christos const unsigned rn, int is64,
2607 1.6 christos struct aarch64_insn_data *data)
2608 1.6 christos {
2609 1.6 christos struct aarch64_displaced_step_data *dsd
2610 1.6 christos = (struct aarch64_displaced_step_data *) data;
2611 1.6 christos
2612 1.6 christos /* The offset is out of range for a compare and branch
2613 1.6 christos instruction. We can use the following instructions instead:
2614 1.6 christos
2615 1.6 christos CBZ xn, TAKEN ; xn == 0, then jump to TAKEN.
2616 1.6 christos INSN1 ;
2617 1.6 christos TAKEN:
2618 1.6 christos INSN2
2619 1.6 christos */
2620 1.6 christos emit_cb (dsd->insn_buf, is_cbnz, aarch64_register (rn, is64), 8);
2621 1.6 christos dsd->insn_count = 1;
2622 1.6 christos dsd->dsc->cond = 1;
2623 1.6 christos dsd->dsc->pc_adjust = offset;
2624 1.6 christos }
2625 1.6 christos
2626 1.6 christos /* Implementation of aarch64_insn_visitor method "tb". */
2627 1.6 christos
2628 1.6 christos static void
2629 1.6 christos aarch64_displaced_step_tb (const int32_t offset, int is_tbnz,
2630 1.6 christos const unsigned rt, unsigned bit,
2631 1.6 christos struct aarch64_insn_data *data)
2632 1.6 christos {
2633 1.6 christos struct aarch64_displaced_step_data *dsd
2634 1.6 christos = (struct aarch64_displaced_step_data *) data;
2635 1.6 christos
2636 1.6 christos /* The offset is out of range for a test bit and branch
2637 1.6 christos instruction We can use the following instructions instead:
2638 1.6 christos
2639 1.6 christos TBZ xn, #bit, TAKEN ; xn[bit] == 0, then jump to TAKEN.
2640 1.6 christos INSN1 ;
2641 1.6 christos TAKEN:
2642 1.6 christos INSN2
2643 1.6 christos
2644 1.6 christos */
2645 1.6 christos emit_tb (dsd->insn_buf, is_tbnz, bit, aarch64_register (rt, 1), 8);
2646 1.6 christos dsd->insn_count = 1;
2647 1.6 christos dsd->dsc->cond = 1;
2648 1.6 christos dsd->dsc->pc_adjust = offset;
2649 1.6 christos }
2650 1.6 christos
2651 1.6 christos /* Implementation of aarch64_insn_visitor method "adr". */
2652 1.6 christos
2653 1.6 christos static void
2654 1.6 christos aarch64_displaced_step_adr (const int32_t offset, const unsigned rd,
2655 1.6 christos const int is_adrp, struct aarch64_insn_data *data)
2656 1.6 christos {
2657 1.6 christos struct aarch64_displaced_step_data *dsd
2658 1.6 christos = (struct aarch64_displaced_step_data *) data;
2659 1.6 christos /* We know exactly the address the ADR{P,} instruction will compute.
2660 1.6 christos We can just write it to the destination register. */
2661 1.6 christos CORE_ADDR address = data->insn_addr + offset;
2662 1.6 christos
2663 1.6 christos if (is_adrp)
2664 1.6 christos {
2665 1.6 christos /* Clear the lower 12 bits of the offset to get the 4K page. */
2666 1.6 christos regcache_cooked_write_unsigned (dsd->regs, AARCH64_X0_REGNUM + rd,
2667 1.6 christos address & ~0xfff);
2668 1.6 christos }
2669 1.6 christos else
2670 1.6 christos regcache_cooked_write_unsigned (dsd->regs, AARCH64_X0_REGNUM + rd,
2671 1.6 christos address);
2672 1.6 christos
2673 1.6 christos dsd->dsc->pc_adjust = 4;
2674 1.6 christos emit_nop (dsd->insn_buf);
2675 1.6 christos dsd->insn_count = 1;
2676 1.6 christos }
2677 1.6 christos
2678 1.6 christos /* Implementation of aarch64_insn_visitor method "ldr_literal". */
2679 1.6 christos
2680 1.6 christos static void
2681 1.6 christos aarch64_displaced_step_ldr_literal (const int32_t offset, const int is_sw,
2682 1.6 christos const unsigned rt, const int is64,
2683 1.6 christos struct aarch64_insn_data *data)
2684 1.6 christos {
2685 1.6 christos struct aarch64_displaced_step_data *dsd
2686 1.6 christos = (struct aarch64_displaced_step_data *) data;
2687 1.6 christos CORE_ADDR address = data->insn_addr + offset;
2688 1.6 christos struct aarch64_memory_operand zero = { MEMORY_OPERAND_OFFSET, 0 };
2689 1.6 christos
2690 1.6 christos regcache_cooked_write_unsigned (dsd->regs, AARCH64_X0_REGNUM + rt,
2691 1.6 christos address);
2692 1.6 christos
2693 1.6 christos if (is_sw)
2694 1.6 christos dsd->insn_count = emit_ldrsw (dsd->insn_buf, aarch64_register (rt, 1),
2695 1.6 christos aarch64_register (rt, 1), zero);
2696 1.6 christos else
2697 1.6 christos dsd->insn_count = emit_ldr (dsd->insn_buf, aarch64_register (rt, is64),
2698 1.6 christos aarch64_register (rt, 1), zero);
2699 1.6 christos
2700 1.6 christos dsd->dsc->pc_adjust = 4;
2701 1.6 christos }
2702 1.6 christos
2703 1.6 christos /* Implementation of aarch64_insn_visitor method "others". */
2704 1.6 christos
2705 1.6 christos static void
2706 1.6 christos aarch64_displaced_step_others (const uint32_t insn,
2707 1.6 christos struct aarch64_insn_data *data)
2708 1.6 christos {
2709 1.6 christos struct aarch64_displaced_step_data *dsd
2710 1.6 christos = (struct aarch64_displaced_step_data *) data;
2711 1.6 christos
2712 1.6 christos aarch64_emit_insn (dsd->insn_buf, insn);
2713 1.6 christos dsd->insn_count = 1;
2714 1.6 christos
2715 1.6 christos if ((insn & 0xfffffc1f) == 0xd65f0000)
2716 1.6 christos {
2717 1.6 christos /* RET */
2718 1.6 christos dsd->dsc->pc_adjust = 0;
2719 1.6 christos }
2720 1.6 christos else
2721 1.6 christos dsd->dsc->pc_adjust = 4;
2722 1.6 christos }
2723 1.6 christos
2724 1.6 christos static const struct aarch64_insn_visitor visitor =
2725 1.6 christos {
2726 1.6 christos aarch64_displaced_step_b,
2727 1.6 christos aarch64_displaced_step_b_cond,
2728 1.6 christos aarch64_displaced_step_cb,
2729 1.6 christos aarch64_displaced_step_tb,
2730 1.6 christos aarch64_displaced_step_adr,
2731 1.6 christos aarch64_displaced_step_ldr_literal,
2732 1.6 christos aarch64_displaced_step_others,
2733 1.6 christos };
2734 1.6 christos
2735 1.6 christos /* Implement the "displaced_step_copy_insn" gdbarch method. */
2736 1.6 christos
2737 1.6 christos struct displaced_step_closure *
2738 1.6 christos aarch64_displaced_step_copy_insn (struct gdbarch *gdbarch,
2739 1.6 christos CORE_ADDR from, CORE_ADDR to,
2740 1.6 christos struct regcache *regs)
2741 1.6 christos {
2742 1.6 christos struct displaced_step_closure *dsc = NULL;
2743 1.6 christos enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
2744 1.6 christos uint32_t insn = read_memory_unsigned_integer (from, 4, byte_order_for_code);
2745 1.6 christos struct aarch64_displaced_step_data dsd;
2746 1.6 christos aarch64_inst inst;
2747 1.6 christos
2748 1.6 christos if (aarch64_decode_insn (insn, &inst, 1) != 0)
2749 1.6 christos return NULL;
2750 1.6 christos
2751 1.6 christos /* Look for a Load Exclusive instruction which begins the sequence. */
2752 1.6 christos if (inst.opcode->iclass == ldstexcl && bit (insn, 22))
2753 1.6 christos {
2754 1.6 christos /* We can't displaced step atomic sequences. */
2755 1.6 christos return NULL;
2756 1.6 christos }
2757 1.6 christos
2758 1.6 christos dsc = XCNEW (struct displaced_step_closure);
2759 1.6 christos dsd.base.insn_addr = from;
2760 1.6 christos dsd.new_addr = to;
2761 1.6 christos dsd.regs = regs;
2762 1.6 christos dsd.dsc = dsc;
2763 1.6 christos dsd.insn_count = 0;
2764 1.6 christos aarch64_relocate_instruction (insn, &visitor,
2765 1.6 christos (struct aarch64_insn_data *) &dsd);
2766 1.6 christos gdb_assert (dsd.insn_count <= DISPLACED_MODIFIED_INSNS);
2767 1.6 christos
2768 1.6 christos if (dsd.insn_count != 0)
2769 1.6 christos {
2770 1.6 christos int i;
2771 1.6 christos
2772 1.6 christos /* Instruction can be relocated to scratch pad. Copy
2773 1.6 christos relocated instruction(s) there. */
2774 1.6 christos for (i = 0; i < dsd.insn_count; i++)
2775 1.6 christos {
2776 1.6 christos if (debug_displaced)
2777 1.6 christos {
2778 1.6 christos debug_printf ("displaced: writing insn ");
2779 1.6 christos debug_printf ("%.8x", dsd.insn_buf[i]);
2780 1.6 christos debug_printf (" at %s\n", paddress (gdbarch, to + i * 4));
2781 1.6 christos }
2782 1.6 christos write_memory_unsigned_integer (to + i * 4, 4, byte_order_for_code,
2783 1.6 christos (ULONGEST) dsd.insn_buf[i]);
2784 1.6 christos }
2785 1.6 christos }
2786 1.6 christos else
2787 1.6 christos {
2788 1.6 christos xfree (dsc);
2789 1.6 christos dsc = NULL;
2790 1.6 christos }
2791 1.6 christos
2792 1.6 christos return dsc;
2793 1.6 christos }
2794 1.6 christos
2795 1.6 christos /* Implement the "displaced_step_fixup" gdbarch method. */
2796 1.6 christos
2797 1.6 christos void
2798 1.6 christos aarch64_displaced_step_fixup (struct gdbarch *gdbarch,
2799 1.6 christos struct displaced_step_closure *dsc,
2800 1.6 christos CORE_ADDR from, CORE_ADDR to,
2801 1.6 christos struct regcache *regs)
2802 1.6 christos {
2803 1.6 christos if (dsc->cond)
2804 1.6 christos {
2805 1.6 christos ULONGEST pc;
2806 1.6 christos
2807 1.6 christos regcache_cooked_read_unsigned (regs, AARCH64_PC_REGNUM, &pc);
2808 1.6 christos if (pc - to == 8)
2809 1.6 christos {
2810 1.6 christos /* Condition is true. */
2811 1.6 christos }
2812 1.6 christos else if (pc - to == 4)
2813 1.6 christos {
2814 1.6 christos /* Condition is false. */
2815 1.6 christos dsc->pc_adjust = 4;
2816 1.6 christos }
2817 1.6 christos else
2818 1.6 christos gdb_assert_not_reached ("Unexpected PC value after displaced stepping");
2819 1.6 christos }
2820 1.6 christos
2821 1.6 christos if (dsc->pc_adjust != 0)
2822 1.6 christos {
2823 1.6 christos if (debug_displaced)
2824 1.6 christos {
2825 1.6 christos debug_printf ("displaced: fixup: set PC to %s:%d\n",
2826 1.6 christos paddress (gdbarch, from), dsc->pc_adjust);
2827 1.6 christos }
2828 1.6 christos regcache_cooked_write_unsigned (regs, AARCH64_PC_REGNUM,
2829 1.6 christos from + dsc->pc_adjust);
2830 1.6 christos }
2831 1.6 christos }
2832 1.6 christos
2833 1.6 christos /* Implement the "displaced_step_hw_singlestep" gdbarch method. */
2834 1.6 christos
2835 1.6 christos int
2836 1.6 christos aarch64_displaced_step_hw_singlestep (struct gdbarch *gdbarch,
2837 1.6 christos struct displaced_step_closure *closure)
2838 1.6 christos {
2839 1.1 christos return 1;
2840 1.1 christos }
2841 1.1 christos
2842 1.1 christos /* Initialize the current architecture based on INFO. If possible,
2843 1.1 christos re-use an architecture from ARCHES, which is a list of
2844 1.1 christos architectures already created during this debugging session.
2845 1.1 christos
2846 1.1 christos Called e.g. at program startup, when reading a core file, and when
2847 1.1 christos reading a binary file. */
2848 1.1 christos
2849 1.1 christos static struct gdbarch *
2850 1.1 christos aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
2851 1.1 christos {
2852 1.1 christos struct gdbarch_tdep *tdep;
2853 1.1 christos struct gdbarch *gdbarch;
2854 1.1 christos struct gdbarch_list *best_arch;
2855 1.1 christos struct tdesc_arch_data *tdesc_data = NULL;
2856 1.1 christos const struct target_desc *tdesc = info.target_desc;
2857 1.1 christos int i;
2858 1.1 christos int valid_p = 1;
2859 1.1 christos const struct tdesc_feature *feature;
2860 1.1 christos int num_regs = 0;
2861 1.1 christos int num_pseudo_regs = 0;
2862 1.1 christos
2863 1.1 christos /* Ensure we always have a target descriptor. */
2864 1.1 christos if (!tdesc_has_registers (tdesc))
2865 1.1 christos tdesc = tdesc_aarch64;
2866 1.1 christos
2867 1.1 christos gdb_assert (tdesc);
2868 1.1 christos
2869 1.1 christos feature = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.core");
2870 1.1 christos
2871 1.1 christos if (feature == NULL)
2872 1.1 christos return NULL;
2873 1.1 christos
2874 1.1 christos tdesc_data = tdesc_data_alloc ();
2875 1.1 christos
2876 1.1 christos /* Validate the descriptor provides the mandatory core R registers
2877 1.1 christos and allocate their numbers. */
2878 1.1 christos for (i = 0; i < ARRAY_SIZE (aarch64_r_register_names); i++)
2879 1.1 christos valid_p &=
2880 1.1 christos tdesc_numbered_register (feature, tdesc_data, AARCH64_X0_REGNUM + i,
2881 1.1 christos aarch64_r_register_names[i]);
2882 1.1 christos
2883 1.1 christos num_regs = AARCH64_X0_REGNUM + i;
2884 1.1 christos
2885 1.1 christos /* Look for the V registers. */
2886 1.1 christos feature = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.fpu");
2887 1.1 christos if (feature)
2888 1.1 christos {
2889 1.1 christos /* Validate the descriptor provides the mandatory V registers
2890 1.1 christos and allocate their numbers. */
2891 1.1 christos for (i = 0; i < ARRAY_SIZE (aarch64_v_register_names); i++)
2892 1.1 christos valid_p &=
2893 1.1 christos tdesc_numbered_register (feature, tdesc_data, AARCH64_V0_REGNUM + i,
2894 1.1 christos aarch64_v_register_names[i]);
2895 1.1 christos
2896 1.1 christos num_regs = AARCH64_V0_REGNUM + i;
2897 1.1 christos
2898 1.1 christos num_pseudo_regs += 32; /* add the Qn scalar register pseudos */
2899 1.1 christos num_pseudo_regs += 32; /* add the Dn scalar register pseudos */
2900 1.1 christos num_pseudo_regs += 32; /* add the Sn scalar register pseudos */
2901 1.1 christos num_pseudo_regs += 32; /* add the Hn scalar register pseudos */
2902 1.1 christos num_pseudo_regs += 32; /* add the Bn scalar register pseudos */
2903 1.1 christos }
2904 1.1 christos
2905 1.1 christos if (!valid_p)
2906 1.1 christos {
2907 1.1 christos tdesc_data_cleanup (tdesc_data);
2908 1.1 christos return NULL;
2909 1.1 christos }
2910 1.1 christos
2911 1.1 christos /* AArch64 code is always little-endian. */
2912 1.1 christos info.byte_order_for_code = BFD_ENDIAN_LITTLE;
2913 1.1 christos
2914 1.1 christos /* If there is already a candidate, use it. */
2915 1.1 christos for (best_arch = gdbarch_list_lookup_by_info (arches, &info);
2916 1.1 christos best_arch != NULL;
2917 1.1 christos best_arch = gdbarch_list_lookup_by_info (best_arch->next, &info))
2918 1.1 christos {
2919 1.1 christos /* Found a match. */
2920 1.1 christos break;
2921 1.1 christos }
2922 1.1 christos
2923 1.1 christos if (best_arch != NULL)
2924 1.1 christos {
2925 1.1 christos if (tdesc_data != NULL)
2926 1.1 christos tdesc_data_cleanup (tdesc_data);
2927 1.6 christos return best_arch->gdbarch;
2928 1.1 christos }
2929 1.1 christos
2930 1.1 christos tdep = XCNEW (struct gdbarch_tdep);
2931 1.1 christos gdbarch = gdbarch_alloc (&info, tdep);
2932 1.1 christos
2933 1.1 christos /* This should be low enough for everything. */
2934 1.1 christos tdep->lowest_pc = 0x20;
2935 1.1 christos tdep->jb_pc = -1; /* Longjump support not enabled by default. */
2936 1.1 christos tdep->jb_elt_size = 8;
2937 1.1 christos
2938 1.1 christos set_gdbarch_push_dummy_call (gdbarch, aarch64_push_dummy_call);
2939 1.1 christos set_gdbarch_frame_align (gdbarch, aarch64_frame_align);
2940 1.1 christos
2941 1.1 christos /* Frame handling. */
2942 1.1 christos set_gdbarch_dummy_id (gdbarch, aarch64_dummy_id);
2943 1.1 christos set_gdbarch_unwind_pc (gdbarch, aarch64_unwind_pc);
2944 1.1 christos set_gdbarch_unwind_sp (gdbarch, aarch64_unwind_sp);
2945 1.1 christos
2946 1.1 christos /* Advance PC across function entry code. */
2947 1.1 christos set_gdbarch_skip_prologue (gdbarch, aarch64_skip_prologue);
2948 1.1 christos
2949 1.1 christos /* The stack grows downward. */
2950 1.7 christos set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
2951 1.7 christos
2952 1.7 christos /* Breakpoint manipulation. */
2953 1.7 christos set_gdbarch_breakpoint_kind_from_pc (gdbarch,
2954 1.1 christos aarch64_breakpoint::kind_from_pc);
2955 1.3 christos set_gdbarch_sw_breakpoint_from_kind (gdbarch,
2956 1.1 christos aarch64_breakpoint::bp_from_kind);
2957 1.1 christos set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
2958 1.1 christos set_gdbarch_software_single_step (gdbarch, aarch64_software_single_step);
2959 1.1 christos
2960 1.1 christos /* Information about registers, etc. */
2961 1.1 christos set_gdbarch_sp_regnum (gdbarch, AARCH64_SP_REGNUM);
2962 1.1 christos set_gdbarch_pc_regnum (gdbarch, AARCH64_PC_REGNUM);
2963 1.1 christos set_gdbarch_num_regs (gdbarch, num_regs);
2964 1.1 christos
2965 1.1 christos set_gdbarch_num_pseudo_regs (gdbarch, num_pseudo_regs);
2966 1.1 christos set_gdbarch_pseudo_register_read_value (gdbarch, aarch64_pseudo_read_value);
2967 1.1 christos set_gdbarch_pseudo_register_write (gdbarch, aarch64_pseudo_write);
2968 1.1 christos set_tdesc_pseudo_register_name (gdbarch, aarch64_pseudo_register_name);
2969 1.1 christos set_tdesc_pseudo_register_type (gdbarch, aarch64_pseudo_register_type);
2970 1.1 christos set_tdesc_pseudo_register_reggroup_p (gdbarch,
2971 1.1 christos aarch64_pseudo_register_reggroup_p);
2972 1.1 christos
2973 1.1 christos /* ABI */
2974 1.1 christos set_gdbarch_short_bit (gdbarch, 16);
2975 1.1 christos set_gdbarch_int_bit (gdbarch, 32);
2976 1.1 christos set_gdbarch_float_bit (gdbarch, 32);
2977 1.1 christos set_gdbarch_double_bit (gdbarch, 64);
2978 1.1 christos set_gdbarch_long_double_bit (gdbarch, 128);
2979 1.1 christos set_gdbarch_long_bit (gdbarch, 64);
2980 1.7 christos set_gdbarch_long_long_bit (gdbarch, 64);
2981 1.1 christos set_gdbarch_ptr_bit (gdbarch, 64);
2982 1.1 christos set_gdbarch_char_signed (gdbarch, 0);
2983 1.1 christos set_gdbarch_wchar_signed (gdbarch, 0);
2984 1.1 christos set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
2985 1.1 christos set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
2986 1.1 christos set_gdbarch_long_double_format (gdbarch, floatformats_ia64_quad);
2987 1.1 christos
2988 1.1 christos /* Internal <-> external register number maps. */
2989 1.1 christos set_gdbarch_dwarf2_reg_to_regnum (gdbarch, aarch64_dwarf_reg_to_regnum);
2990 1.1 christos
2991 1.1 christos /* Returning results. */
2992 1.1 christos set_gdbarch_return_value (gdbarch, aarch64_return_value);
2993 1.1 christos
2994 1.1 christos /* Disassembly. */
2995 1.1 christos set_gdbarch_print_insn (gdbarch, aarch64_gdb_print_insn);
2996 1.1 christos
2997 1.1 christos /* Virtual tables. */
2998 1.1 christos set_gdbarch_vbit_in_delta (gdbarch, 1);
2999 1.1 christos
3000 1.1 christos /* Hook in the ABI-specific overrides, if they have been registered. */
3001 1.1 christos info.target_desc = tdesc;
3002 1.1 christos info.tdep_info = (void *) tdesc_data;
3003 1.1 christos gdbarch_init_osabi (info, gdbarch);
3004 1.1 christos
3005 1.1 christos dwarf2_frame_set_init_reg (gdbarch, aarch64_dwarf2_frame_init_reg);
3006 1.1 christos
3007 1.1 christos /* Add some default predicates. */
3008 1.1 christos frame_unwind_append_unwinder (gdbarch, &aarch64_stub_unwind);
3009 1.1 christos dwarf2_append_unwinders (gdbarch);
3010 1.1 christos frame_unwind_append_unwinder (gdbarch, &aarch64_prologue_unwind);
3011 1.1 christos
3012 1.1 christos frame_base_set_default (gdbarch, &aarch64_normal_base);
3013 1.1 christos
3014 1.1 christos /* Now we have tuned the configuration, set a few final things,
3015 1.1 christos based on what the OS ABI has told us. */
3016 1.1 christos
3017 1.6 christos if (tdep->jb_pc >= 0)
3018 1.6 christos set_gdbarch_get_longjmp_target (gdbarch, aarch64_get_longjmp_target);
3019 1.1 christos
3020 1.1 christos set_gdbarch_gen_return_address (gdbarch, aarch64_gen_return_address);
3021 1.1 christos
3022 1.1 christos tdesc_use_registers (gdbarch, tdesc, tdesc_data);
3023 1.1 christos
3024 1.1 christos /* Add standard register aliases. */
3025 1.1 christos for (i = 0; i < ARRAY_SIZE (aarch64_register_aliases); i++)
3026 1.1 christos user_reg_add (gdbarch, aarch64_register_aliases[i].name,
3027 1.1 christos value_of_aarch64_user_reg,
3028 1.1 christos &aarch64_register_aliases[i].regnum);
3029 1.1 christos
3030 1.1 christos return gdbarch;
3031 1.1 christos }
3032 1.1 christos
3033 1.1 christos static void
3034 1.1 christos aarch64_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
3035 1.1 christos {
3036 1.1 christos struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
3037 1.1 christos
3038 1.1 christos if (tdep == NULL)
3039 1.1 christos return;
3040 1.1 christos
3041 1.1 christos fprintf_unfiltered (file, _("aarch64_dump_tdep: Lowest pc = 0x%s"),
3042 1.7 christos paddress (gdbarch, tdep->lowest_pc));
3043 1.7 christos }
3044 1.7 christos
3045 1.7 christos #if GDB_SELF_TEST
3046 1.7 christos namespace selftests
3047 1.7 christos {
3048 1.7 christos static void aarch64_process_record_test (void);
3049 1.1 christos }
3050 1.1 christos #endif
3051 1.1 christos
3052 1.1 christos /* Suppress warning from -Wmissing-prototypes. */
3053 1.1 christos extern initialize_file_ftype _initialize_aarch64_tdep;
3054 1.1 christos
3055 1.1 christos void
3056 1.1 christos _initialize_aarch64_tdep (void)
3057 1.1 christos {
3058 1.1 christos gdbarch_register (bfd_arch_aarch64, aarch64_gdbarch_init,
3059 1.1 christos aarch64_dump_tdep);
3060 1.1 christos
3061 1.1 christos initialize_tdesc_aarch64 ();
3062 1.1 christos
3063 1.1 christos /* Debug this file's internals. */
3064 1.1 christos add_setshow_boolean_cmd ("aarch64", class_maintenance, &aarch64_debug, _("\
3065 1.1 christos Set AArch64 debugging."), _("\
3066 1.1 christos Show AArch64 debugging."), _("\
3067 1.1 christos When on, AArch64 specific debugging is enabled."),
3068 1.7 christos NULL,
3069 1.7 christos show_aarch64_debug,
3070 1.7 christos &setdebuglist, &showdebuglist);
3071 1.7 christos
3072 1.7 christos #if GDB_SELF_TEST
3073 1.1 christos register_self_test (selftests::aarch64_analyze_prologue_test);
3074 1.5 christos register_self_test (selftests::aarch64_process_record_test);
3075 1.5 christos #endif
3076 1.5 christos }
3077 1.5 christos
3078 1.5 christos /* AArch64 process record-replay related structures, defines etc. */
3079 1.5 christos
3080 1.5 christos #define REG_ALLOC(REGS, LENGTH, RECORD_BUF) \
3081 1.5 christos do \
3082 1.5 christos { \
3083 1.5 christos unsigned int reg_len = LENGTH; \
3084 1.5 christos if (reg_len) \
3085 1.5 christos { \
3086 1.5 christos REGS = XNEWVEC (uint32_t, reg_len); \
3087 1.5 christos memcpy(®S[0], &RECORD_BUF[0], sizeof(uint32_t)*LENGTH); \
3088 1.5 christos } \
3089 1.5 christos } \
3090 1.5 christos while (0)
3091 1.5 christos
3092 1.5 christos #define MEM_ALLOC(MEMS, LENGTH, RECORD_BUF) \
3093 1.5 christos do \
3094 1.5 christos { \
3095 1.5 christos unsigned int mem_len = LENGTH; \
3096 1.5 christos if (mem_len) \
3097 1.5 christos { \
3098 1.5 christos MEMS = XNEWVEC (struct aarch64_mem_r, mem_len); \
3099 1.5 christos memcpy(&MEMS->len, &RECORD_BUF[0], \
3100 1.5 christos sizeof(struct aarch64_mem_r) * LENGTH); \
3101 1.5 christos } \
3102 1.5 christos } \
3103 1.5 christos while (0)
3104 1.5 christos
3105 1.5 christos /* AArch64 record/replay structures and enumerations. */
3106 1.5 christos
3107 1.5 christos struct aarch64_mem_r
3108 1.5 christos {
3109 1.5 christos uint64_t len; /* Record length. */
3110 1.5 christos uint64_t addr; /* Memory address. */
3111 1.5 christos };
3112 1.5 christos
3113 1.5 christos enum aarch64_record_result
3114 1.5 christos {
3115 1.5 christos AARCH64_RECORD_SUCCESS,
3116 1.5 christos AARCH64_RECORD_UNSUPPORTED,
3117 1.5 christos AARCH64_RECORD_UNKNOWN
3118 1.5 christos };
3119 1.5 christos
3120 1.5 christos typedef struct insn_decode_record_t
3121 1.5 christos {
3122 1.5 christos struct gdbarch *gdbarch;
3123 1.5 christos struct regcache *regcache;
3124 1.5 christos CORE_ADDR this_addr; /* Address of insn to be recorded. */
3125 1.5 christos uint32_t aarch64_insn; /* Insn to be recorded. */
3126 1.5 christos uint32_t mem_rec_count; /* Count of memory records. */
3127 1.5 christos uint32_t reg_rec_count; /* Count of register records. */
3128 1.5 christos uint32_t *aarch64_regs; /* Registers to be recorded. */
3129 1.5 christos struct aarch64_mem_r *aarch64_mems; /* Memory locations to be recorded. */
3130 1.5 christos } insn_decode_record;
3131 1.5 christos
3132 1.5 christos /* Record handler for data processing - register instructions. */
3133 1.5 christos
3134 1.5 christos static unsigned int
3135 1.5 christos aarch64_record_data_proc_reg (insn_decode_record *aarch64_insn_r)
3136 1.5 christos {
3137 1.5 christos uint8_t reg_rd, insn_bits24_27, insn_bits21_23;
3138 1.5 christos uint32_t record_buf[4];
3139 1.5 christos
3140 1.5 christos reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4);
3141 1.5 christos insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
3142 1.5 christos insn_bits21_23 = bits (aarch64_insn_r->aarch64_insn, 21, 23);
3143 1.5 christos
3144 1.5 christos if (!bit (aarch64_insn_r->aarch64_insn, 28))
3145 1.5 christos {
3146 1.5 christos uint8_t setflags;
3147 1.5 christos
3148 1.5 christos /* Logical (shifted register). */
3149 1.5 christos if (insn_bits24_27 == 0x0a)
3150 1.5 christos setflags = (bits (aarch64_insn_r->aarch64_insn, 29, 30) == 0x03);
3151 1.5 christos /* Add/subtract. */
3152 1.5 christos else if (insn_bits24_27 == 0x0b)
3153 1.5 christos setflags = bit (aarch64_insn_r->aarch64_insn, 29);
3154 1.5 christos else
3155 1.5 christos return AARCH64_RECORD_UNKNOWN;
3156 1.5 christos
3157 1.5 christos record_buf[0] = reg_rd;
3158 1.5 christos aarch64_insn_r->reg_rec_count = 1;
3159 1.5 christos if (setflags)
3160 1.5 christos record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_CPSR_REGNUM;
3161 1.5 christos }
3162 1.5 christos else
3163 1.5 christos {
3164 1.5 christos if (insn_bits24_27 == 0x0b)
3165 1.5 christos {
3166 1.5 christos /* Data-processing (3 source). */
3167 1.5 christos record_buf[0] = reg_rd;
3168 1.5 christos aarch64_insn_r->reg_rec_count = 1;
3169 1.5 christos }
3170 1.5 christos else if (insn_bits24_27 == 0x0a)
3171 1.5 christos {
3172 1.5 christos if (insn_bits21_23 == 0x00)
3173 1.5 christos {
3174 1.5 christos /* Add/subtract (with carry). */
3175 1.5 christos record_buf[0] = reg_rd;
3176 1.5 christos aarch64_insn_r->reg_rec_count = 1;
3177 1.5 christos if (bit (aarch64_insn_r->aarch64_insn, 29))
3178 1.5 christos {
3179 1.5 christos record_buf[1] = AARCH64_CPSR_REGNUM;
3180 1.5 christos aarch64_insn_r->reg_rec_count = 2;
3181 1.5 christos }
3182 1.5 christos }
3183 1.5 christos else if (insn_bits21_23 == 0x02)
3184 1.5 christos {
3185 1.5 christos /* Conditional compare (register) and conditional compare
3186 1.5 christos (immediate) instructions. */
3187 1.5 christos record_buf[0] = AARCH64_CPSR_REGNUM;
3188 1.5 christos aarch64_insn_r->reg_rec_count = 1;
3189 1.5 christos }
3190 1.5 christos else if (insn_bits21_23 == 0x04 || insn_bits21_23 == 0x06)
3191 1.5 christos {
3192 1.5 christos /* CConditional select. */
3193 1.5 christos /* Data-processing (2 source). */
3194 1.5 christos /* Data-processing (1 source). */
3195 1.5 christos record_buf[0] = reg_rd;
3196 1.5 christos aarch64_insn_r->reg_rec_count = 1;
3197 1.5 christos }
3198 1.5 christos else
3199 1.5 christos return AARCH64_RECORD_UNKNOWN;
3200 1.5 christos }
3201 1.5 christos }
3202 1.5 christos
3203 1.5 christos REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
3204 1.5 christos record_buf);
3205 1.5 christos return AARCH64_RECORD_SUCCESS;
3206 1.5 christos }
3207 1.5 christos
3208 1.5 christos /* Record handler for data processing - immediate instructions. */
3209 1.5 christos
3210 1.6 christos static unsigned int
3211 1.5 christos aarch64_record_data_proc_imm (insn_decode_record *aarch64_insn_r)
3212 1.5 christos {
3213 1.5 christos uint8_t reg_rd, insn_bit23, insn_bits24_27, setflags;
3214 1.5 christos uint32_t record_buf[4];
3215 1.5 christos
3216 1.5 christos reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4);
3217 1.5 christos insn_bit23 = bit (aarch64_insn_r->aarch64_insn, 23);
3218 1.5 christos insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
3219 1.5 christos
3220 1.5 christos if (insn_bits24_27 == 0x00 /* PC rel addressing. */
3221 1.5 christos || insn_bits24_27 == 0x03 /* Bitfield and Extract. */
3222 1.5 christos || (insn_bits24_27 == 0x02 && insn_bit23)) /* Move wide (immediate). */
3223 1.5 christos {
3224 1.5 christos record_buf[0] = reg_rd;
3225 1.5 christos aarch64_insn_r->reg_rec_count = 1;
3226 1.5 christos }
3227 1.5 christos else if (insn_bits24_27 == 0x01)
3228 1.5 christos {
3229 1.5 christos /* Add/Subtract (immediate). */
3230 1.5 christos setflags = bit (aarch64_insn_r->aarch64_insn, 29);
3231 1.5 christos record_buf[0] = reg_rd;
3232 1.5 christos aarch64_insn_r->reg_rec_count = 1;
3233 1.5 christos if (setflags)
3234 1.5 christos record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_CPSR_REGNUM;
3235 1.5 christos }
3236 1.5 christos else if (insn_bits24_27 == 0x02 && !insn_bit23)
3237 1.5 christos {
3238 1.5 christos /* Logical (immediate). */
3239 1.5 christos setflags = bits (aarch64_insn_r->aarch64_insn, 29, 30) == 0x03;
3240 1.5 christos record_buf[0] = reg_rd;
3241 1.5 christos aarch64_insn_r->reg_rec_count = 1;
3242 1.5 christos if (setflags)
3243 1.5 christos record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_CPSR_REGNUM;
3244 1.5 christos }
3245 1.5 christos else
3246 1.5 christos return AARCH64_RECORD_UNKNOWN;
3247 1.5 christos
3248 1.5 christos REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
3249 1.5 christos record_buf);
3250 1.5 christos return AARCH64_RECORD_SUCCESS;
3251 1.5 christos }
3252 1.5 christos
3253 1.5 christos /* Record handler for branch, exception generation and system instructions. */
3254 1.5 christos
3255 1.5 christos static unsigned int
3256 1.5 christos aarch64_record_branch_except_sys (insn_decode_record *aarch64_insn_r)
3257 1.5 christos {
3258 1.5 christos struct gdbarch_tdep *tdep = gdbarch_tdep (aarch64_insn_r->gdbarch);
3259 1.5 christos uint8_t insn_bits24_27, insn_bits28_31, insn_bits22_23;
3260 1.5 christos uint32_t record_buf[4];
3261 1.5 christos
3262 1.5 christos insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
3263 1.5 christos insn_bits28_31 = bits (aarch64_insn_r->aarch64_insn, 28, 31);
3264 1.5 christos insn_bits22_23 = bits (aarch64_insn_r->aarch64_insn, 22, 23);
3265 1.5 christos
3266 1.5 christos if (insn_bits28_31 == 0x0d)
3267 1.5 christos {
3268 1.5 christos /* Exception generation instructions. */
3269 1.5 christos if (insn_bits24_27 == 0x04)
3270 1.5 christos {
3271 1.5 christos if (!bits (aarch64_insn_r->aarch64_insn, 2, 4)
3272 1.5 christos && !bits (aarch64_insn_r->aarch64_insn, 21, 23)
3273 1.5 christos && bits (aarch64_insn_r->aarch64_insn, 0, 1) == 0x01)
3274 1.5 christos {
3275 1.5 christos ULONGEST svc_number;
3276 1.5 christos
3277 1.5 christos regcache_raw_read_unsigned (aarch64_insn_r->regcache, 8,
3278 1.5 christos &svc_number);
3279 1.5 christos return tdep->aarch64_syscall_record (aarch64_insn_r->regcache,
3280 1.5 christos svc_number);
3281 1.5 christos }
3282 1.5 christos else
3283 1.5 christos return AARCH64_RECORD_UNSUPPORTED;
3284 1.5 christos }
3285 1.5 christos /* System instructions. */
3286 1.5 christos else if (insn_bits24_27 == 0x05 && insn_bits22_23 == 0x00)
3287 1.5 christos {
3288 1.5 christos uint32_t reg_rt, reg_crn;
3289 1.5 christos
3290 1.5 christos reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4);
3291 1.5 christos reg_crn = bits (aarch64_insn_r->aarch64_insn, 12, 15);
3292 1.5 christos
3293 1.5 christos /* Record rt in case of sysl and mrs instructions. */
3294 1.5 christos if (bit (aarch64_insn_r->aarch64_insn, 21))
3295 1.5 christos {
3296 1.5 christos record_buf[0] = reg_rt;
3297 1.5 christos aarch64_insn_r->reg_rec_count = 1;
3298 1.5 christos }
3299 1.5 christos /* Record cpsr for hint and msr(immediate) instructions. */
3300 1.5 christos else if (reg_crn == 0x02 || reg_crn == 0x04)
3301 1.5 christos {
3302 1.5 christos record_buf[0] = AARCH64_CPSR_REGNUM;
3303 1.5 christos aarch64_insn_r->reg_rec_count = 1;
3304 1.5 christos }
3305 1.5 christos }
3306 1.5 christos /* Unconditional branch (register). */
3307 1.5 christos else if((insn_bits24_27 & 0x0e) == 0x06)
3308 1.5 christos {
3309 1.5 christos record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_PC_REGNUM;
3310 1.5 christos if (bits (aarch64_insn_r->aarch64_insn, 21, 22) == 0x01)
3311 1.5 christos record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_LR_REGNUM;
3312 1.5 christos }
3313 1.5 christos else
3314 1.5 christos return AARCH64_RECORD_UNKNOWN;
3315 1.5 christos }
3316 1.5 christos /* Unconditional branch (immediate). */
3317 1.5 christos else if ((insn_bits28_31 & 0x07) == 0x01 && (insn_bits24_27 & 0x0c) == 0x04)
3318 1.5 christos {
3319 1.5 christos record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_PC_REGNUM;
3320 1.5 christos if (bit (aarch64_insn_r->aarch64_insn, 31))
3321 1.5 christos record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_LR_REGNUM;
3322 1.5 christos }
3323 1.5 christos else
3324 1.5 christos /* Compare & branch (immediate), Test & branch (immediate) and
3325 1.5 christos Conditional branch (immediate). */
3326 1.5 christos record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_PC_REGNUM;
3327 1.5 christos
3328 1.5 christos REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
3329 1.5 christos record_buf);
3330 1.5 christos return AARCH64_RECORD_SUCCESS;
3331 1.5 christos }
3332 1.5 christos
3333 1.5 christos /* Record handler for advanced SIMD load and store instructions. */
3334 1.5 christos
3335 1.5 christos static unsigned int
3336 1.5 christos aarch64_record_asimd_load_store (insn_decode_record *aarch64_insn_r)
3337 1.5 christos {
3338 1.5 christos CORE_ADDR address;
3339 1.5 christos uint64_t addr_offset = 0;
3340 1.5 christos uint32_t record_buf[24];
3341 1.5 christos uint64_t record_buf_mem[24];
3342 1.5 christos uint32_t reg_rn, reg_rt;
3343 1.5 christos uint32_t reg_index = 0, mem_index = 0;
3344 1.5 christos uint8_t opcode_bits, size_bits;
3345 1.5 christos
3346 1.5 christos reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4);
3347 1.5 christos reg_rn = bits (aarch64_insn_r->aarch64_insn, 5, 9);
3348 1.5 christos size_bits = bits (aarch64_insn_r->aarch64_insn, 10, 11);
3349 1.5 christos opcode_bits = bits (aarch64_insn_r->aarch64_insn, 12, 15);
3350 1.6 christos regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, &address);
3351 1.5 christos
3352 1.5 christos if (record_debug)
3353 1.5 christos debug_printf ("Process record: Advanced SIMD load/store\n");
3354 1.5 christos
3355 1.5 christos /* Load/store single structure. */
3356 1.5 christos if (bit (aarch64_insn_r->aarch64_insn, 24))
3357 1.5 christos {
3358 1.5 christos uint8_t sindex, scale, selem, esize, replicate = 0;
3359 1.5 christos scale = opcode_bits >> 2;
3360 1.5 christos selem = ((opcode_bits & 0x02) |
3361 1.5 christos bit (aarch64_insn_r->aarch64_insn, 21)) + 1;
3362 1.5 christos switch (scale)
3363 1.5 christos {
3364 1.5 christos case 1:
3365 1.5 christos if (size_bits & 0x01)
3366 1.5 christos return AARCH64_RECORD_UNKNOWN;
3367 1.5 christos break;
3368 1.5 christos case 2:
3369 1.5 christos if ((size_bits >> 1) & 0x01)
3370 1.5 christos return AARCH64_RECORD_UNKNOWN;
3371 1.5 christos if (size_bits & 0x01)
3372 1.5 christos {
3373 1.5 christos if (!((opcode_bits >> 1) & 0x01))
3374 1.5 christos scale = 3;
3375 1.5 christos else
3376 1.5 christos return AARCH64_RECORD_UNKNOWN;
3377 1.5 christos }
3378 1.5 christos break;
3379 1.5 christos case 3:
3380 1.5 christos if (bit (aarch64_insn_r->aarch64_insn, 22) && !(opcode_bits & 0x01))
3381 1.5 christos {
3382 1.5 christos scale = size_bits;
3383 1.5 christos replicate = 1;
3384 1.5 christos break;
3385 1.5 christos }
3386 1.5 christos else
3387 1.5 christos return AARCH64_RECORD_UNKNOWN;
3388 1.5 christos default:
3389 1.5 christos break;
3390 1.5 christos }
3391 1.5 christos esize = 8 << scale;
3392 1.5 christos if (replicate)
3393 1.5 christos for (sindex = 0; sindex < selem; sindex++)
3394 1.5 christos {
3395 1.5 christos record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
3396 1.5 christos reg_rt = (reg_rt + 1) % 32;
3397 1.5 christos }
3398 1.6 christos else
3399 1.6 christos {
3400 1.6 christos for (sindex = 0; sindex < selem; sindex++)
3401 1.6 christos {
3402 1.6 christos if (bit (aarch64_insn_r->aarch64_insn, 22))
3403 1.6 christos record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
3404 1.6 christos else
3405 1.6 christos {
3406 1.6 christos record_buf_mem[mem_index++] = esize / 8;
3407 1.6 christos record_buf_mem[mem_index++] = address + addr_offset;
3408 1.6 christos }
3409 1.5 christos addr_offset = addr_offset + (esize / 8);
3410 1.5 christos reg_rt = (reg_rt + 1) % 32;
3411 1.5 christos }
3412 1.5 christos }
3413 1.5 christos }
3414 1.5 christos /* Load/store multiple structure. */
3415 1.5 christos else
3416 1.5 christos {
3417 1.5 christos uint8_t selem, esize, rpt, elements;
3418 1.5 christos uint8_t eindex, rindex;
3419 1.5 christos
3420 1.5 christos esize = 8 << size_bits;
3421 1.5 christos if (bit (aarch64_insn_r->aarch64_insn, 30))
3422 1.5 christos elements = 128 / esize;
3423 1.5 christos else
3424 1.5 christos elements = 64 / esize;
3425 1.5 christos
3426 1.5 christos switch (opcode_bits)
3427 1.5 christos {
3428 1.5 christos /*LD/ST4 (4 Registers). */
3429 1.5 christos case 0:
3430 1.5 christos rpt = 1;
3431 1.5 christos selem = 4;
3432 1.5 christos break;
3433 1.5 christos /*LD/ST1 (4 Registers). */
3434 1.5 christos case 2:
3435 1.5 christos rpt = 4;
3436 1.5 christos selem = 1;
3437 1.5 christos break;
3438 1.5 christos /*LD/ST3 (3 Registers). */
3439 1.5 christos case 4:
3440 1.5 christos rpt = 1;
3441 1.5 christos selem = 3;
3442 1.5 christos break;
3443 1.5 christos /*LD/ST1 (3 Registers). */
3444 1.5 christos case 6:
3445 1.5 christos rpt = 3;
3446 1.5 christos selem = 1;
3447 1.5 christos break;
3448 1.5 christos /*LD/ST1 (1 Register). */
3449 1.5 christos case 7:
3450 1.5 christos rpt = 1;
3451 1.5 christos selem = 1;
3452 1.5 christos break;
3453 1.5 christos /*LD/ST2 (2 Registers). */
3454 1.5 christos case 8:
3455 1.5 christos rpt = 1;
3456 1.5 christos selem = 2;
3457 1.5 christos break;
3458 1.5 christos /*LD/ST1 (2 Registers). */
3459 1.5 christos case 10:
3460 1.5 christos rpt = 2;
3461 1.5 christos selem = 1;
3462 1.5 christos break;
3463 1.5 christos default:
3464 1.5 christos return AARCH64_RECORD_UNSUPPORTED;
3465 1.5 christos break;
3466 1.5 christos }
3467 1.5 christos for (rindex = 0; rindex < rpt; rindex++)
3468 1.5 christos for (eindex = 0; eindex < elements; eindex++)
3469 1.5 christos {
3470 1.5 christos uint8_t reg_tt, sindex;
3471 1.5 christos reg_tt = (reg_rt + rindex) % 32;
3472 1.5 christos for (sindex = 0; sindex < selem; sindex++)
3473 1.5 christos {
3474 1.5 christos if (bit (aarch64_insn_r->aarch64_insn, 22))
3475 1.5 christos record_buf[reg_index++] = reg_tt + AARCH64_V0_REGNUM;
3476 1.5 christos else
3477 1.5 christos {
3478 1.5 christos record_buf_mem[mem_index++] = esize / 8;
3479 1.5 christos record_buf_mem[mem_index++] = address + addr_offset;
3480 1.5 christos }
3481 1.5 christos addr_offset = addr_offset + (esize / 8);
3482 1.5 christos reg_tt = (reg_tt + 1) % 32;
3483 1.5 christos }
3484 1.5 christos }
3485 1.5 christos }
3486 1.5 christos
3487 1.5 christos if (bit (aarch64_insn_r->aarch64_insn, 23))
3488 1.5 christos record_buf[reg_index++] = reg_rn;
3489 1.5 christos
3490 1.5 christos aarch64_insn_r->reg_rec_count = reg_index;
3491 1.5 christos aarch64_insn_r->mem_rec_count = mem_index / 2;
3492 1.5 christos MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
3493 1.5 christos record_buf_mem);
3494 1.5 christos REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
3495 1.5 christos record_buf);
3496 1.5 christos return AARCH64_RECORD_SUCCESS;
3497 1.5 christos }
3498 1.5 christos
3499 1.5 christos /* Record handler for load and store instructions. */
3500 1.5 christos
3501 1.5 christos static unsigned int
3502 1.5 christos aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
3503 1.5 christos {
3504 1.5 christos uint8_t insn_bits24_27, insn_bits28_29, insn_bits10_11;
3505 1.5 christos uint8_t insn_bit23, insn_bit21;
3506 1.5 christos uint8_t opc, size_bits, ld_flag, vector_flag;
3507 1.5 christos uint32_t reg_rn, reg_rt, reg_rt2;
3508 1.5 christos uint64_t datasize, offset;
3509 1.5 christos uint32_t record_buf[8];
3510 1.5 christos uint64_t record_buf_mem[8];
3511 1.5 christos CORE_ADDR address;
3512 1.5 christos
3513 1.5 christos insn_bits10_11 = bits (aarch64_insn_r->aarch64_insn, 10, 11);
3514 1.5 christos insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
3515 1.5 christos insn_bits28_29 = bits (aarch64_insn_r->aarch64_insn, 28, 29);
3516 1.5 christos insn_bit21 = bit (aarch64_insn_r->aarch64_insn, 21);
3517 1.5 christos insn_bit23 = bit (aarch64_insn_r->aarch64_insn, 23);
3518 1.5 christos ld_flag = bit (aarch64_insn_r->aarch64_insn, 22);
3519 1.5 christos vector_flag = bit (aarch64_insn_r->aarch64_insn, 26);
3520 1.5 christos reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4);
3521 1.5 christos reg_rn = bits (aarch64_insn_r->aarch64_insn, 5, 9);
3522 1.5 christos reg_rt2 = bits (aarch64_insn_r->aarch64_insn, 10, 14);
3523 1.5 christos size_bits = bits (aarch64_insn_r->aarch64_insn, 30, 31);
3524 1.5 christos
3525 1.5 christos /* Load/store exclusive. */
3526 1.6 christos if (insn_bits24_27 == 0x08 && insn_bits28_29 == 0x00)
3527 1.5 christos {
3528 1.5 christos if (record_debug)
3529 1.5 christos debug_printf ("Process record: load/store exclusive\n");
3530 1.5 christos
3531 1.5 christos if (ld_flag)
3532 1.5 christos {
3533 1.5 christos record_buf[0] = reg_rt;
3534 1.5 christos aarch64_insn_r->reg_rec_count = 1;
3535 1.5 christos if (insn_bit21)
3536 1.5 christos {
3537 1.5 christos record_buf[1] = reg_rt2;
3538 1.5 christos aarch64_insn_r->reg_rec_count = 2;
3539 1.5 christos }
3540 1.5 christos }
3541 1.5 christos else
3542 1.5 christos {
3543 1.5 christos if (insn_bit21)
3544 1.5 christos datasize = (8 << size_bits) * 2;
3545 1.5 christos else
3546 1.5 christos datasize = (8 << size_bits);
3547 1.5 christos regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn,
3548 1.5 christos &address);
3549 1.5 christos record_buf_mem[0] = datasize / 8;
3550 1.5 christos record_buf_mem[1] = address;
3551 1.5 christos aarch64_insn_r->mem_rec_count = 1;
3552 1.5 christos if (!insn_bit23)
3553 1.5 christos {
3554 1.5 christos /* Save register rs. */
3555 1.5 christos record_buf[0] = bits (aarch64_insn_r->aarch64_insn, 16, 20);
3556 1.5 christos aarch64_insn_r->reg_rec_count = 1;
3557 1.5 christos }
3558 1.5 christos }
3559 1.5 christos }
3560 1.5 christos /* Load register (literal) instructions decoding. */
3561 1.6 christos else if ((insn_bits24_27 & 0x0b) == 0x08 && insn_bits28_29 == 0x01)
3562 1.5 christos {
3563 1.5 christos if (record_debug)
3564 1.5 christos debug_printf ("Process record: load register (literal)\n");
3565 1.5 christos if (vector_flag)
3566 1.5 christos record_buf[0] = reg_rt + AARCH64_V0_REGNUM;
3567 1.5 christos else
3568 1.5 christos record_buf[0] = reg_rt;
3569 1.5 christos aarch64_insn_r->reg_rec_count = 1;
3570 1.5 christos }
3571 1.5 christos /* All types of load/store pair instructions decoding. */
3572 1.6 christos else if ((insn_bits24_27 & 0x0a) == 0x08 && insn_bits28_29 == 0x02)
3573 1.5 christos {
3574 1.5 christos if (record_debug)
3575 1.5 christos debug_printf ("Process record: load/store pair\n");
3576 1.5 christos
3577 1.5 christos if (ld_flag)
3578 1.5 christos {
3579 1.5 christos if (vector_flag)
3580 1.5 christos {
3581 1.5 christos record_buf[0] = reg_rt + AARCH64_V0_REGNUM;
3582 1.5 christos record_buf[1] = reg_rt2 + AARCH64_V0_REGNUM;
3583 1.5 christos }
3584 1.5 christos else
3585 1.5 christos {
3586 1.5 christos record_buf[0] = reg_rt;
3587 1.5 christos record_buf[1] = reg_rt2;
3588 1.5 christos }
3589 1.5 christos aarch64_insn_r->reg_rec_count = 2;
3590 1.5 christos }
3591 1.5 christos else
3592 1.5 christos {
3593 1.5 christos uint16_t imm7_off;
3594 1.5 christos imm7_off = bits (aarch64_insn_r->aarch64_insn, 15, 21);
3595 1.5 christos if (!vector_flag)
3596 1.5 christos size_bits = size_bits >> 1;
3597 1.5 christos datasize = 8 << (2 + size_bits);
3598 1.5 christos offset = (imm7_off & 0x40) ? (~imm7_off & 0x007f) + 1 : imm7_off;
3599 1.5 christos offset = offset << (2 + size_bits);
3600 1.5 christos regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn,
3601 1.5 christos &address);
3602 1.5 christos if (!((insn_bits24_27 & 0x0b) == 0x08 && insn_bit23))
3603 1.5 christos {
3604 1.5 christos if (imm7_off & 0x40)
3605 1.5 christos address = address - offset;
3606 1.5 christos else
3607 1.5 christos address = address + offset;
3608 1.5 christos }
3609 1.5 christos
3610 1.5 christos record_buf_mem[0] = datasize / 8;
3611 1.5 christos record_buf_mem[1] = address;
3612 1.5 christos record_buf_mem[2] = datasize / 8;
3613 1.5 christos record_buf_mem[3] = address + (datasize / 8);
3614 1.5 christos aarch64_insn_r->mem_rec_count = 2;
3615 1.5 christos }
3616 1.5 christos if (bit (aarch64_insn_r->aarch64_insn, 23))
3617 1.5 christos record_buf[aarch64_insn_r->reg_rec_count++] = reg_rn;
3618 1.5 christos }
3619 1.5 christos /* Load/store register (unsigned immediate) instructions. */
3620 1.5 christos else if ((insn_bits24_27 & 0x0b) == 0x09 && insn_bits28_29 == 0x03)
3621 1.7 christos {
3622 1.7 christos opc = bits (aarch64_insn_r->aarch64_insn, 22, 23);
3623 1.7 christos if (!(opc >> 1))
3624 1.7 christos {
3625 1.7 christos if (opc & 0x01)
3626 1.7 christos ld_flag = 0x01;
3627 1.5 christos else
3628 1.7 christos ld_flag = 0x0;
3629 1.7 christos }
3630 1.7 christos else
3631 1.7 christos {
3632 1.7 christos if (size_bits == 0x3 && vector_flag == 0x0 && opc == 0x2)
3633 1.7 christos {
3634 1.7 christos /* PRFM (immediate) */
3635 1.7 christos return AARCH64_RECORD_SUCCESS;
3636 1.7 christos }
3637 1.7 christos else if (size_bits == 0x2 && vector_flag == 0x0 && opc == 0x2)
3638 1.7 christos {
3639 1.7 christos /* LDRSW (immediate) */
3640 1.7 christos ld_flag = 0x1;
3641 1.7 christos }
3642 1.7 christos else
3643 1.7 christos {
3644 1.7 christos if (opc & 0x01)
3645 1.7 christos ld_flag = 0x01;
3646 1.7 christos else
3647 1.5 christos ld_flag = 0x0;
3648 1.5 christos }
3649 1.5 christos }
3650 1.6 christos
3651 1.6 christos if (record_debug)
3652 1.6 christos {
3653 1.5 christos debug_printf ("Process record: load/store (unsigned immediate):"
3654 1.5 christos " size %x V %d opc %x\n", size_bits, vector_flag,
3655 1.5 christos opc);
3656 1.5 christos }
3657 1.5 christos
3658 1.5 christos if (!ld_flag)
3659 1.5 christos {
3660 1.5 christos offset = bits (aarch64_insn_r->aarch64_insn, 10, 21);
3661 1.5 christos datasize = 8 << size_bits;
3662 1.5 christos regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn,
3663 1.5 christos &address);
3664 1.5 christos offset = offset << size_bits;
3665 1.5 christos address = address + offset;
3666 1.5 christos
3667 1.5 christos record_buf_mem[0] = datasize >> 3;
3668 1.5 christos record_buf_mem[1] = address;
3669 1.5 christos aarch64_insn_r->mem_rec_count = 1;
3670 1.5 christos }
3671 1.5 christos else
3672 1.5 christos {
3673 1.5 christos if (vector_flag)
3674 1.5 christos record_buf[0] = reg_rt + AARCH64_V0_REGNUM;
3675 1.5 christos else
3676 1.5 christos record_buf[0] = reg_rt;
3677 1.5 christos aarch64_insn_r->reg_rec_count = 1;
3678 1.5 christos }
3679 1.5 christos }
3680 1.5 christos /* Load/store register (register offset) instructions. */
3681 1.5 christos else if ((insn_bits24_27 & 0x0b) == 0x08 && insn_bits28_29 == 0x03
3682 1.6 christos && insn_bits10_11 == 0x02 && insn_bit21)
3683 1.5 christos {
3684 1.5 christos if (record_debug)
3685 1.5 christos debug_printf ("Process record: load/store (register offset)\n");
3686 1.5 christos opc = bits (aarch64_insn_r->aarch64_insn, 22, 23);
3687 1.5 christos if (!(opc >> 1))
3688 1.5 christos if (opc & 0x01)
3689 1.5 christos ld_flag = 0x01;
3690 1.5 christos else
3691 1.5 christos ld_flag = 0x0;
3692 1.5 christos else
3693 1.5 christos if (size_bits != 0x03)
3694 1.5 christos ld_flag = 0x01;
3695 1.5 christos else
3696 1.5 christos return AARCH64_RECORD_UNKNOWN;
3697 1.6 christos
3698 1.6 christos if (!ld_flag)
3699 1.5 christos {
3700 1.5 christos ULONGEST reg_rm_val;
3701 1.5 christos
3702 1.5 christos regcache_raw_read_unsigned (aarch64_insn_r->regcache,
3703 1.5 christos bits (aarch64_insn_r->aarch64_insn, 16, 20), ®_rm_val);
3704 1.5 christos if (bit (aarch64_insn_r->aarch64_insn, 12))
3705 1.5 christos offset = reg_rm_val << size_bits;
3706 1.5 christos else
3707 1.5 christos offset = reg_rm_val;
3708 1.5 christos datasize = 8 << size_bits;
3709 1.5 christos regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn,
3710 1.5 christos &address);
3711 1.5 christos address = address + offset;
3712 1.5 christos record_buf_mem[0] = datasize >> 3;
3713 1.5 christos record_buf_mem[1] = address;
3714 1.5 christos aarch64_insn_r->mem_rec_count = 1;
3715 1.5 christos }
3716 1.5 christos else
3717 1.5 christos {
3718 1.5 christos if (vector_flag)
3719 1.5 christos record_buf[0] = reg_rt + AARCH64_V0_REGNUM;
3720 1.5 christos else
3721 1.5 christos record_buf[0] = reg_rt;
3722 1.5 christos aarch64_insn_r->reg_rec_count = 1;
3723 1.5 christos }
3724 1.5 christos }
3725 1.5 christos /* Load/store register (immediate and unprivileged) instructions. */
3726 1.5 christos else if ((insn_bits24_27 & 0x0b) == 0x08 && insn_bits28_29 == 0x03
3727 1.5 christos && !insn_bit21)
3728 1.6 christos {
3729 1.6 christos if (record_debug)
3730 1.5 christos {
3731 1.5 christos debug_printf ("Process record: load/store "
3732 1.5 christos "(immediate and unprivileged)\n");
3733 1.5 christos }
3734 1.5 christos opc = bits (aarch64_insn_r->aarch64_insn, 22, 23);
3735 1.5 christos if (!(opc >> 1))
3736 1.5 christos if (opc & 0x01)
3737 1.5 christos ld_flag = 0x01;
3738 1.5 christos else
3739 1.5 christos ld_flag = 0x0;
3740 1.5 christos else
3741 1.5 christos if (size_bits != 0x03)
3742 1.5 christos ld_flag = 0x01;
3743 1.5 christos else
3744 1.5 christos return AARCH64_RECORD_UNKNOWN;
3745 1.5 christos
3746 1.5 christos if (!ld_flag)
3747 1.5 christos {
3748 1.5 christos uint16_t imm9_off;
3749 1.5 christos imm9_off = bits (aarch64_insn_r->aarch64_insn, 12, 20);
3750 1.5 christos offset = (imm9_off & 0x0100) ? (((~imm9_off) & 0x01ff) + 1) : imm9_off;
3751 1.5 christos datasize = 8 << size_bits;
3752 1.5 christos regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn,
3753 1.5 christos &address);
3754 1.5 christos if (insn_bits10_11 != 0x01)
3755 1.5 christos {
3756 1.5 christos if (imm9_off & 0x0100)
3757 1.5 christos address = address - offset;
3758 1.5 christos else
3759 1.5 christos address = address + offset;
3760 1.5 christos }
3761 1.5 christos record_buf_mem[0] = datasize >> 3;
3762 1.5 christos record_buf_mem[1] = address;
3763 1.5 christos aarch64_insn_r->mem_rec_count = 1;
3764 1.5 christos }
3765 1.5 christos else
3766 1.5 christos {
3767 1.5 christos if (vector_flag)
3768 1.5 christos record_buf[0] = reg_rt + AARCH64_V0_REGNUM;
3769 1.5 christos else
3770 1.5 christos record_buf[0] = reg_rt;
3771 1.5 christos aarch64_insn_r->reg_rec_count = 1;
3772 1.5 christos }
3773 1.5 christos if (insn_bits10_11 == 0x01 || insn_bits10_11 == 0x03)
3774 1.5 christos record_buf[aarch64_insn_r->reg_rec_count++] = reg_rn;
3775 1.5 christos }
3776 1.5 christos /* Advanced SIMD load/store instructions. */
3777 1.5 christos else
3778 1.5 christos return aarch64_record_asimd_load_store (aarch64_insn_r);
3779 1.5 christos
3780 1.5 christos MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
3781 1.5 christos record_buf_mem);
3782 1.5 christos REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
3783 1.5 christos record_buf);
3784 1.5 christos return AARCH64_RECORD_SUCCESS;
3785 1.5 christos }
3786 1.5 christos
3787 1.5 christos /* Record handler for data processing SIMD and floating point instructions. */
3788 1.5 christos
3789 1.5 christos static unsigned int
3790 1.5 christos aarch64_record_data_proc_simd_fp (insn_decode_record *aarch64_insn_r)
3791 1.5 christos {
3792 1.5 christos uint8_t insn_bit21, opcode, rmode, reg_rd;
3793 1.5 christos uint8_t insn_bits24_27, insn_bits28_31, insn_bits10_11, insn_bits12_15;
3794 1.5 christos uint8_t insn_bits11_14;
3795 1.5 christos uint32_t record_buf[2];
3796 1.5 christos
3797 1.5 christos insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
3798 1.5 christos insn_bits28_31 = bits (aarch64_insn_r->aarch64_insn, 28, 31);
3799 1.5 christos insn_bits10_11 = bits (aarch64_insn_r->aarch64_insn, 10, 11);
3800 1.5 christos insn_bits12_15 = bits (aarch64_insn_r->aarch64_insn, 12, 15);
3801 1.5 christos insn_bits11_14 = bits (aarch64_insn_r->aarch64_insn, 11, 14);
3802 1.5 christos opcode = bits (aarch64_insn_r->aarch64_insn, 16, 18);
3803 1.5 christos rmode = bits (aarch64_insn_r->aarch64_insn, 19, 20);
3804 1.5 christos reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4);
3805 1.6 christos insn_bit21 = bit (aarch64_insn_r->aarch64_insn, 21);
3806 1.5 christos
3807 1.5 christos if (record_debug)
3808 1.5 christos debug_printf ("Process record: data processing SIMD/FP: ");
3809 1.5 christos
3810 1.5 christos if ((insn_bits28_31 & 0x05) == 0x01 && insn_bits24_27 == 0x0e)
3811 1.5 christos {
3812 1.5 christos /* Floating point - fixed point conversion instructions. */
3813 1.6 christos if (!insn_bit21)
3814 1.5 christos {
3815 1.5 christos if (record_debug)
3816 1.5 christos debug_printf ("FP - fixed point conversion");
3817 1.5 christos
3818 1.5 christos if ((opcode >> 1) == 0x0 && rmode == 0x03)
3819 1.5 christos record_buf[0] = reg_rd;
3820 1.5 christos else
3821 1.5 christos record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
3822 1.5 christos }
3823 1.5 christos /* Floating point - conditional compare instructions. */
3824 1.6 christos else if (insn_bits10_11 == 0x01)
3825 1.5 christos {
3826 1.5 christos if (record_debug)
3827 1.5 christos debug_printf ("FP - conditional compare");
3828 1.5 christos
3829 1.5 christos record_buf[0] = AARCH64_CPSR_REGNUM;
3830 1.5 christos }
3831 1.5 christos /* Floating point - data processing (2-source) and
3832 1.5 christos conditional select instructions. */
3833 1.6 christos else if (insn_bits10_11 == 0x02 || insn_bits10_11 == 0x03)
3834 1.5 christos {
3835 1.5 christos if (record_debug)
3836 1.5 christos debug_printf ("FP - DP (2-source)");
3837 1.5 christos
3838 1.5 christos record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
3839 1.5 christos }
3840 1.5 christos else if (insn_bits10_11 == 0x00)
3841 1.5 christos {
3842 1.5 christos /* Floating point - immediate instructions. */
3843 1.5 christos if ((insn_bits12_15 & 0x01) == 0x01
3844 1.6 christos || (insn_bits12_15 & 0x07) == 0x04)
3845 1.5 christos {
3846 1.5 christos if (record_debug)
3847 1.5 christos debug_printf ("FP - immediate");
3848 1.5 christos record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
3849 1.5 christos }
3850 1.5 christos /* Floating point - compare instructions. */
3851 1.6 christos else if ((insn_bits12_15 & 0x03) == 0x02)
3852 1.5 christos {
3853 1.5 christos if (record_debug)
3854 1.5 christos debug_printf ("FP - immediate");
3855 1.5 christos record_buf[0] = AARCH64_CPSR_REGNUM;
3856 1.5 christos }
3857 1.5 christos /* Floating point - integer conversions instructions. */
3858 1.5 christos else if (insn_bits12_15 == 0x00)
3859 1.5 christos {
3860 1.5 christos /* Convert float to integer instruction. */
3861 1.6 christos if (!(opcode >> 1) || ((opcode >> 1) == 0x02 && !rmode))
3862 1.5 christos {
3863 1.5 christos if (record_debug)
3864 1.5 christos debug_printf ("float to int conversion");
3865 1.5 christos
3866 1.5 christos record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
3867 1.5 christos }
3868 1.5 christos /* Convert integer to float instruction. */
3869 1.6 christos else if ((opcode >> 1) == 0x01 && !rmode)
3870 1.5 christos {
3871 1.5 christos if (record_debug)
3872 1.5 christos debug_printf ("int to float conversion");
3873 1.5 christos
3874 1.5 christos record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
3875 1.5 christos }
3876 1.5 christos /* Move float to integer instruction. */
3877 1.6 christos else if ((opcode >> 1) == 0x03)
3878 1.5 christos {
3879 1.5 christos if (record_debug)
3880 1.5 christos debug_printf ("move float to int");
3881 1.5 christos
3882 1.5 christos if (!(opcode & 0x01))
3883 1.5 christos record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
3884 1.5 christos else
3885 1.5 christos record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
3886 1.5 christos }
3887 1.5 christos else
3888 1.5 christos return AARCH64_RECORD_UNKNOWN;
3889 1.5 christos }
3890 1.5 christos else
3891 1.5 christos return AARCH64_RECORD_UNKNOWN;
3892 1.5 christos }
3893 1.5 christos else
3894 1.5 christos return AARCH64_RECORD_UNKNOWN;
3895 1.5 christos }
3896 1.6 christos else if ((insn_bits28_31 & 0x09) == 0x00 && insn_bits24_27 == 0x0e)
3897 1.5 christos {
3898 1.5 christos if (record_debug)
3899 1.5 christos debug_printf ("SIMD copy");
3900 1.5 christos
3901 1.5 christos /* Advanced SIMD copy instructions. */
3902 1.5 christos if (!bits (aarch64_insn_r->aarch64_insn, 21, 23)
3903 1.5 christos && !bit (aarch64_insn_r->aarch64_insn, 15)
3904 1.5 christos && bit (aarch64_insn_r->aarch64_insn, 10))
3905 1.5 christos {
3906 1.5 christos if (insn_bits11_14 == 0x05 || insn_bits11_14 == 0x07)
3907 1.5 christos record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
3908 1.5 christos else
3909 1.5 christos record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
3910 1.5 christos }
3911 1.5 christos else
3912 1.5 christos record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
3913 1.5 christos }
3914 1.5 christos /* All remaining floating point or advanced SIMD instructions. */
3915 1.6 christos else
3916 1.5 christos {
3917 1.5 christos if (record_debug)
3918 1.5 christos debug_printf ("all remain");
3919 1.5 christos
3920 1.5 christos record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
3921 1.6 christos }
3922 1.5 christos
3923 1.5 christos if (record_debug)
3924 1.5 christos debug_printf ("\n");
3925 1.5 christos
3926 1.5 christos aarch64_insn_r->reg_rec_count++;
3927 1.5 christos gdb_assert (aarch64_insn_r->reg_rec_count == 1);
3928 1.5 christos REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
3929 1.5 christos record_buf);
3930 1.5 christos return AARCH64_RECORD_SUCCESS;
3931 1.5 christos }
3932 1.5 christos
3933 1.5 christos /* Decodes insns type and invokes its record handler. */
3934 1.5 christos
3935 1.5 christos static unsigned int
3936 1.5 christos aarch64_record_decode_insn_handler (insn_decode_record *aarch64_insn_r)
3937 1.5 christos {
3938 1.5 christos uint32_t ins_bit25, ins_bit26, ins_bit27, ins_bit28;
3939 1.5 christos
3940 1.5 christos ins_bit25 = bit (aarch64_insn_r->aarch64_insn, 25);
3941 1.5 christos ins_bit26 = bit (aarch64_insn_r->aarch64_insn, 26);
3942 1.5 christos ins_bit27 = bit (aarch64_insn_r->aarch64_insn, 27);
3943 1.5 christos ins_bit28 = bit (aarch64_insn_r->aarch64_insn, 28);
3944 1.5 christos
3945 1.5 christos /* Data processing - immediate instructions. */
3946 1.5 christos if (!ins_bit26 && !ins_bit27 && ins_bit28)
3947 1.5 christos return aarch64_record_data_proc_imm (aarch64_insn_r);
3948 1.5 christos
3949 1.5 christos /* Branch, exception generation and system instructions. */
3950 1.5 christos if (ins_bit26 && !ins_bit27 && ins_bit28)
3951 1.5 christos return aarch64_record_branch_except_sys (aarch64_insn_r);
3952 1.5 christos
3953 1.5 christos /* Load and store instructions. */
3954 1.5 christos if (!ins_bit25 && ins_bit27)
3955 1.5 christos return aarch64_record_load_store (aarch64_insn_r);
3956 1.5 christos
3957 1.5 christos /* Data processing - register instructions. */
3958 1.5 christos if (ins_bit25 && !ins_bit26 && ins_bit27)
3959 1.5 christos return aarch64_record_data_proc_reg (aarch64_insn_r);
3960 1.5 christos
3961 1.5 christos /* Data processing - SIMD and floating point instructions. */
3962 1.5 christos if (ins_bit25 && ins_bit26 && ins_bit27)
3963 1.5 christos return aarch64_record_data_proc_simd_fp (aarch64_insn_r);
3964 1.5 christos
3965 1.5 christos return AARCH64_RECORD_UNSUPPORTED;
3966 1.5 christos }
3967 1.5 christos
3968 1.5 christos /* Cleans up local record registers and memory allocations. */
3969 1.5 christos
3970 1.5 christos static void
3971 1.5 christos deallocate_reg_mem (insn_decode_record *record)
3972 1.5 christos {
3973 1.5 christos xfree (record->aarch64_regs);
3974 1.7 christos xfree (record->aarch64_mems);
3975 1.7 christos }
3976 1.7 christos
3977 1.7 christos #if GDB_SELF_TEST
3978 1.7 christos namespace selftests {
3979 1.7 christos
3980 1.7 christos static void
3981 1.7 christos aarch64_process_record_test (void)
3982 1.7 christos {
3983 1.7 christos struct gdbarch_info info;
3984 1.7 christos uint32_t ret;
3985 1.7 christos
3986 1.7 christos gdbarch_info_init (&info);
3987 1.7 christos info.bfd_arch_info = bfd_scan_arch ("aarch64");
3988 1.7 christos
3989 1.7 christos struct gdbarch *gdbarch = gdbarch_find_by_info (info);
3990 1.7 christos SELF_CHECK (gdbarch != NULL);
3991 1.7 christos
3992 1.7 christos insn_decode_record aarch64_record;
3993 1.7 christos
3994 1.7 christos memset (&aarch64_record, 0, sizeof (insn_decode_record));
3995 1.7 christos aarch64_record.regcache = NULL;
3996 1.7 christos aarch64_record.this_addr = 0;
3997 1.7 christos aarch64_record.gdbarch = gdbarch;
3998 1.7 christos
3999 1.7 christos /* 20 00 80 f9 prfm pldl1keep, [x1] */
4000 1.7 christos aarch64_record.aarch64_insn = 0xf9800020;
4001 1.7 christos ret = aarch64_record_decode_insn_handler (&aarch64_record);
4002 1.7 christos SELF_CHECK (ret == AARCH64_RECORD_SUCCESS);
4003 1.7 christos SELF_CHECK (aarch64_record.reg_rec_count == 0);
4004 1.7 christos SELF_CHECK (aarch64_record.mem_rec_count == 0);
4005 1.7 christos
4006 1.7 christos deallocate_reg_mem (&aarch64_record);
4007 1.7 christos }
4008 1.7 christos
4009 1.5 christos } // namespace selftests
4010 1.5 christos #endif /* GDB_SELF_TEST */
4011 1.5 christos
4012 1.5 christos /* Parse the current instruction and record the values of the registers and
4013 1.5 christos memory that will be changed in current instruction to record_arch_list
4014 1.5 christos return -1 if something is wrong. */
4015 1.5 christos
4016 1.5 christos int
4017 1.5 christos aarch64_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
4018 1.5 christos CORE_ADDR insn_addr)
4019 1.5 christos {
4020 1.5 christos uint32_t rec_no = 0;
4021 1.5 christos uint8_t insn_size = 4;
4022 1.5 christos uint32_t ret = 0;
4023 1.5 christos gdb_byte buf[insn_size];
4024 1.5 christos insn_decode_record aarch64_record;
4025 1.5 christos
4026 1.5 christos memset (&buf[0], 0, insn_size);
4027 1.5 christos memset (&aarch64_record, 0, sizeof (insn_decode_record));
4028 1.5 christos target_read_memory (insn_addr, &buf[0], insn_size);
4029 1.5 christos aarch64_record.aarch64_insn
4030 1.5 christos = (uint32_t) extract_unsigned_integer (&buf[0],
4031 1.5 christos insn_size,
4032 1.5 christos gdbarch_byte_order (gdbarch));
4033 1.5 christos aarch64_record.regcache = regcache;
4034 1.5 christos aarch64_record.this_addr = insn_addr;
4035 1.5 christos aarch64_record.gdbarch = gdbarch;
4036 1.5 christos
4037 1.5 christos ret = aarch64_record_decode_insn_handler (&aarch64_record);
4038 1.5 christos if (ret == AARCH64_RECORD_UNSUPPORTED)
4039 1.5 christos {
4040 1.5 christos printf_unfiltered (_("Process record does not support instruction "
4041 1.5 christos "0x%0x at address %s.\n"),
4042 1.5 christos aarch64_record.aarch64_insn,
4043 1.5 christos paddress (gdbarch, insn_addr));
4044 1.5 christos ret = -1;
4045 1.5 christos }
4046 1.5 christos
4047 1.5 christos if (0 == ret)
4048 1.5 christos {
4049 1.5 christos /* Record registers. */
4050 1.5 christos record_full_arch_list_add_reg (aarch64_record.regcache,
4051 1.5 christos AARCH64_PC_REGNUM);
4052 1.5 christos /* Always record register CPSR. */
4053 1.5 christos record_full_arch_list_add_reg (aarch64_record.regcache,
4054 1.5 christos AARCH64_CPSR_REGNUM);
4055 1.5 christos if (aarch64_record.aarch64_regs)
4056 1.5 christos for (rec_no = 0; rec_no < aarch64_record.reg_rec_count; rec_no++)
4057 1.5 christos if (record_full_arch_list_add_reg (aarch64_record.regcache,
4058 1.5 christos aarch64_record.aarch64_regs[rec_no]))
4059 1.5 christos ret = -1;
4060 1.5 christos
4061 1.5 christos /* Record memories. */
4062 1.5 christos if (aarch64_record.aarch64_mems)
4063 1.5 christos for (rec_no = 0; rec_no < aarch64_record.mem_rec_count; rec_no++)
4064 1.5 christos if (record_full_arch_list_add_mem
4065 1.5 christos ((CORE_ADDR)aarch64_record.aarch64_mems[rec_no].addr,
4066 1.5 christos aarch64_record.aarch64_mems[rec_no].len))
4067 1.5 christos ret = -1;
4068 1.5 christos
4069 1.5 christos if (record_full_arch_list_add_end ())
4070 1.5 christos ret = -1;
4071 1.5 christos }
4072 1.5 christos
4073 deallocate_reg_mem (&aarch64_record);
4074 return ret;
4075 }
4076