gdb/aarch64-tdep.c - gdb
Global variables defined
Data types defined
Functions defined
Macros defined
Source code
- #include "defs.h"
- #include "frame.h"
- #include "inferior.h"
- #include "gdbcmd.h"
- #include "gdbcore.h"
- #include "dis-asm.h"
- #include "regcache.h"
- #include "reggroups.h"
- #include "doublest.h"
- #include "value.h"
- #include "arch-utils.h"
- #include "osabi.h"
- #include "frame-unwind.h"
- #include "frame-base.h"
- #include "trad-frame.h"
- #include "objfiles.h"
- #include "dwarf2-frame.h"
- #include "gdbtypes.h"
- #include "prologue-value.h"
- #include "target-descriptions.h"
- #include "user-regs.h"
- #include "language.h"
- #include "infcall.h"
- #include "aarch64-tdep.h"
- #include "elf-bfd.h"
- #include "elf/aarch64.h"
- #include "vec.h"
- #include "features/aarch64.c"
- #define AARCH64_Q0_REGNUM 0
- #define AARCH64_D0_REGNUM (AARCH64_Q0_REGNUM + 32)
- #define AARCH64_S0_REGNUM (AARCH64_D0_REGNUM + 32)
- #define AARCH64_H0_REGNUM (AARCH64_S0_REGNUM + 32)
- #define AARCH64_B0_REGNUM (AARCH64_H0_REGNUM + 32)
- static const struct
- {
- const char *const name;
- int regnum;
- } aarch64_register_aliases[] =
- {
-
- {"fp", AARCH64_FP_REGNUM},
- {"lr", AARCH64_LR_REGNUM},
- {"sp", AARCH64_SP_REGNUM},
-
- {"w0", AARCH64_X0_REGNUM + 0},
- {"w1", AARCH64_X0_REGNUM + 1},
- {"w2", AARCH64_X0_REGNUM + 2},
- {"w3", AARCH64_X0_REGNUM + 3},
- {"w4", AARCH64_X0_REGNUM + 4},
- {"w5", AARCH64_X0_REGNUM + 5},
- {"w6", AARCH64_X0_REGNUM + 6},
- {"w7", AARCH64_X0_REGNUM + 7},
- {"w8", AARCH64_X0_REGNUM + 8},
- {"w9", AARCH64_X0_REGNUM + 9},
- {"w10", AARCH64_X0_REGNUM + 10},
- {"w11", AARCH64_X0_REGNUM + 11},
- {"w12", AARCH64_X0_REGNUM + 12},
- {"w13", AARCH64_X0_REGNUM + 13},
- {"w14", AARCH64_X0_REGNUM + 14},
- {"w15", AARCH64_X0_REGNUM + 15},
- {"w16", AARCH64_X0_REGNUM + 16},
- {"w17", AARCH64_X0_REGNUM + 17},
- {"w18", AARCH64_X0_REGNUM + 18},
- {"w19", AARCH64_X0_REGNUM + 19},
- {"w20", AARCH64_X0_REGNUM + 20},
- {"w21", AARCH64_X0_REGNUM + 21},
- {"w22", AARCH64_X0_REGNUM + 22},
- {"w23", AARCH64_X0_REGNUM + 23},
- {"w24", AARCH64_X0_REGNUM + 24},
- {"w25", AARCH64_X0_REGNUM + 25},
- {"w26", AARCH64_X0_REGNUM + 26},
- {"w27", AARCH64_X0_REGNUM + 27},
- {"w28", AARCH64_X0_REGNUM + 28},
- {"w29", AARCH64_X0_REGNUM + 29},
- {"w30", AARCH64_X0_REGNUM + 30},
-
- {"ip0", AARCH64_X0_REGNUM + 16},
- {"ip1", AARCH64_X0_REGNUM + 17}
- };
- static const char *const aarch64_r_register_names[] =
- {
-
- "x0", "x1", "x2", "x3",
- "x4", "x5", "x6", "x7",
- "x8", "x9", "x10", "x11",
- "x12", "x13", "x14", "x15",
- "x16", "x17", "x18", "x19",
- "x20", "x21", "x22", "x23",
- "x24", "x25", "x26", "x27",
- "x28", "x29", "x30", "sp",
- "pc", "cpsr"
- };
- static const char *const aarch64_v_register_names[] =
- {
-
- "v0", "v1", "v2", "v3",
- "v4", "v5", "v6", "v7",
- "v8", "v9", "v10", "v11",
- "v12", "v13", "v14", "v15",
- "v16", "v17", "v18", "v19",
- "v20", "v21", "v22", "v23",
- "v24", "v25", "v26", "v27",
- "v28", "v29", "v30", "v31",
- "fpsr",
- "fpcr"
- };
- struct aarch64_prologue_cache
- {
-
- CORE_ADDR prev_sp;
-
- int framesize;
-
- int framereg;
-
- struct trad_frame_saved_reg *saved_regs;
- };
- static int aarch64_debug;
- static void
- show_aarch64_debug (struct ui_file *file, int from_tty,
- struct cmd_list_element *c, const char *value)
- {
- fprintf_filtered (file, _("AArch64 debugging is %s.\n"), value);
- }
- static int32_t
- extract_signed_bitfield (uint32_t insn, unsigned width, unsigned offset)
- {
- unsigned shift_l = sizeof (int32_t) * 8 - (offset + width);
- unsigned shift_r = sizeof (int32_t) * 8 - width;
- return ((int32_t) insn << shift_l) >> shift_r;
- }
- static int
- decode_masked_match (uint32_t insn, uint32_t mask, uint32_t pattern)
- {
- return (insn & mask) == pattern;
- }
- static int
- decode_add_sub_imm (CORE_ADDR addr, uint32_t insn, unsigned *rd, unsigned *rn,
- int32_t *imm)
- {
- if ((insn & 0x9f000000) == 0x91000000)
- {
- unsigned shift;
- unsigned op_is_sub;
- *rd = (insn >> 0) & 0x1f;
- *rn = (insn >> 5) & 0x1f;
- *imm = (insn >> 10) & 0xfff;
- shift = (insn >> 22) & 0x3;
- op_is_sub = (insn >> 30) & 0x1;
- switch (shift)
- {
- case 0:
- break;
- case 1:
- *imm <<= 12;
- break;
- default:
-
- return 0;
- }
- if (op_is_sub)
- *imm = -*imm;
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog,
- "decode: 0x%s 0x%x add x%u, x%u, #%d\n",
- core_addr_to_string_nz (addr), insn, *rd, *rn,
- *imm);
- return 1;
- }
- return 0;
- }
- static int
- decode_adrp (CORE_ADDR addr, uint32_t insn, unsigned *rd)
- {
- if (decode_masked_match (insn, 0x9f000000, 0x90000000))
- {
- *rd = (insn >> 0) & 0x1f;
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog,
- "decode: 0x%s 0x%x adrp x%u, #?\n",
- core_addr_to_string_nz (addr), insn, *rd);
- return 1;
- }
- return 0;
- }
- static int
- decode_b (CORE_ADDR addr, uint32_t insn, unsigned *link, int32_t *offset)
- {
-
-
- if (decode_masked_match (insn, 0x7c000000, 0x14000000))
- {
- *link = insn >> 31;
- *offset = extract_signed_bitfield (insn, 26, 0) << 2;
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog,
- "decode: 0x%s 0x%x %s 0x%s\n",
- core_addr_to_string_nz (addr), insn,
- *link ? "bl" : "b",
- core_addr_to_string_nz (addr + *offset));
- return 1;
- }
- return 0;
- }
- static int
- decode_bcond (CORE_ADDR addr, uint32_t insn, unsigned *cond, int32_t *offset)
- {
- if (decode_masked_match (insn, 0xfe000000, 0x54000000))
- {
- *cond = (insn >> 0) & 0xf;
- *offset = extract_signed_bitfield (insn, 19, 5) << 2;
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog,
- "decode: 0x%s 0x%x b<%u> 0x%s\n",
- core_addr_to_string_nz (addr), insn, *cond,
- core_addr_to_string_nz (addr + *offset));
- return 1;
- }
- return 0;
- }
- static int
- decode_br (CORE_ADDR addr, uint32_t insn, unsigned *link, unsigned *rn)
- {
-
-
-
- if (decode_masked_match (insn, 0xffdffc1f, 0xd61f0000))
- {
- *link = (insn >> 21) & 1;
- *rn = (insn >> 5) & 0x1f;
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog,
- "decode: 0x%s 0x%x %s 0x%x\n",
- core_addr_to_string_nz (addr), insn,
- *link ? "blr" : "br", *rn);
- return 1;
- }
- return 0;
- }
- static int
- decode_cb (CORE_ADDR addr,
- uint32_t insn, int *is64, unsigned *op, unsigned *rn,
- int32_t *offset)
- {
- if (decode_masked_match (insn, 0x7e000000, 0x34000000))
- {
-
-
- *rn = (insn >> 0) & 0x1f;
- *is64 = (insn >> 31) & 0x1;
- *op = (insn >> 24) & 0x1;
- *offset = extract_signed_bitfield (insn, 19, 5) << 2;
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog,
- "decode: 0x%s 0x%x %s 0x%s\n",
- core_addr_to_string_nz (addr), insn,
- *op ? "cbnz" : "cbz",
- core_addr_to_string_nz (addr + *offset));
- return 1;
- }
- return 0;
- }
- static int
- decode_eret (CORE_ADDR addr, uint32_t insn)
- {
-
- if (insn == 0xd69f03e0)
- {
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog, "decode: 0x%s 0x%x eret\n",
- core_addr_to_string_nz (addr), insn);
- return 1;
- }
- return 0;
- }
- static int
- decode_movz (CORE_ADDR addr, uint32_t insn, unsigned *rd)
- {
- if (decode_masked_match (insn, 0xff800000, 0x52800000))
- {
- *rd = (insn >> 0) & 0x1f;
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog,
- "decode: 0x%s 0x%x movz x%u, #?\n",
- core_addr_to_string_nz (addr), insn, *rd);
- return 1;
- }
- return 0;
- }
- static int
- decode_orr_shifted_register_x (CORE_ADDR addr,
- uint32_t insn, unsigned *rd, unsigned *rn,
- unsigned *rm, int32_t *imm)
- {
- if (decode_masked_match (insn, 0xff200000, 0xaa000000))
- {
- *rd = (insn >> 0) & 0x1f;
- *rn = (insn >> 5) & 0x1f;
- *rm = (insn >> 16) & 0x1f;
- *imm = (insn >> 10) & 0x3f;
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog,
- "decode: 0x%s 0x%x orr x%u, x%u, x%u, #%u\n",
- core_addr_to_string_nz (addr), insn, *rd,
- *rn, *rm, *imm);
- return 1;
- }
- return 0;
- }
- static int
- decode_ret (CORE_ADDR addr, uint32_t insn, unsigned *rn)
- {
- if (decode_masked_match (insn, 0xfffffc1f, 0xd65f0000))
- {
- *rn = (insn >> 5) & 0x1f;
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog,
- "decode: 0x%s 0x%x ret x%u\n",
- core_addr_to_string_nz (addr), insn, *rn);
- return 1;
- }
- return 0;
- }
- static int
- decode_stp_offset (CORE_ADDR addr,
- uint32_t insn,
- unsigned *rt1, unsigned *rt2, unsigned *rn, int32_t *imm)
- {
- if (decode_masked_match (insn, 0xffc00000, 0xa9000000))
- {
- *rt1 = (insn >> 0) & 0x1f;
- *rn = (insn >> 5) & 0x1f;
- *rt2 = (insn >> 10) & 0x1f;
- *imm = extract_signed_bitfield (insn, 7, 15);
- *imm <<= 3;
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog,
- "decode: 0x%s 0x%x stp x%u, x%u, [x%u + #%d]\n",
- core_addr_to_string_nz (addr), insn,
- *rt1, *rt2, *rn, *imm);
- return 1;
- }
- return 0;
- }
- static int
- decode_stp_offset_wb (CORE_ADDR addr,
- uint32_t insn,
- unsigned *rt1, unsigned *rt2, unsigned *rn,
- int32_t *imm)
- {
- if (decode_masked_match (insn, 0xffc00000, 0xa9800000))
- {
- *rt1 = (insn >> 0) & 0x1f;
- *rn = (insn >> 5) & 0x1f;
- *rt2 = (insn >> 10) & 0x1f;
- *imm = extract_signed_bitfield (insn, 7, 15);
- *imm <<= 3;
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog,
- "decode: 0x%s 0x%x stp x%u, x%u, [x%u + #%d]!\n",
- core_addr_to_string_nz (addr), insn,
- *rt1, *rt2, *rn, *imm);
- return 1;
- }
- return 0;
- }
- static int
- decode_stur (CORE_ADDR addr, uint32_t insn, int *is64, unsigned *rt,
- unsigned *rn, int32_t *imm)
- {
- if (decode_masked_match (insn, 0xbfe00c00, 0xb8000000))
- {
- *is64 = (insn >> 30) & 1;
- *rt = (insn >> 0) & 0x1f;
- *rn = (insn >> 5) & 0x1f;
- *imm = extract_signed_bitfield (insn, 9, 12);
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog,
- "decode: 0x%s 0x%x stur %c%u, [x%u + #%d]\n",
- core_addr_to_string_nz (addr), insn,
- *is64 ? 'x' : 'w', *rt, *rn, *imm);
- return 1;
- }
- return 0;
- }
- static int
- decode_tb (CORE_ADDR addr,
- uint32_t insn, unsigned *op, unsigned *bit, unsigned *rt,
- int32_t *imm)
- {
- if (decode_masked_match (insn, 0x7e000000, 0x36000000))
- {
-
-
- *rt = (insn >> 0) & 0x1f;
- *op = insn & (1 << 24);
- *bit = ((insn >> (31 - 4)) & 0x20) | ((insn >> 19) & 0x1f);
- *imm = extract_signed_bitfield (insn, 14, 5) << 2;
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog,
- "decode: 0x%s 0x%x %s x%u, #%u, 0x%s\n",
- core_addr_to_string_nz (addr), insn,
- *op ? "tbnz" : "tbz", *rt, *bit,
- core_addr_to_string_nz (addr + *imm));
- return 1;
- }
- return 0;
- }
- static CORE_ADDR
- aarch64_analyze_prologue (struct gdbarch *gdbarch,
- CORE_ADDR start, CORE_ADDR limit,
- struct aarch64_prologue_cache *cache)
- {
- enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
- int i;
- pv_t regs[AARCH64_X_REGISTER_COUNT];
- struct pv_area *stack;
- struct cleanup *back_to;
- for (i = 0; i < AARCH64_X_REGISTER_COUNT; i++)
- regs[i] = pv_register (i, 0);
- stack = make_pv_area (AARCH64_SP_REGNUM, gdbarch_addr_bit (gdbarch));
- back_to = make_cleanup_free_pv_area (stack);
- for (; start < limit; start += 4)
- {
- uint32_t insn;
- unsigned rd;
- unsigned rn;
- unsigned rm;
- unsigned rt;
- unsigned rt1;
- unsigned rt2;
- int op_is_sub;
- int32_t imm;
- unsigned cond;
- int is64;
- unsigned is_link;
- unsigned op;
- unsigned bit;
- int32_t offset;
- insn = read_memory_unsigned_integer (start, 4, byte_order_for_code);
- if (decode_add_sub_imm (start, insn, &rd, &rn, &imm))
- regs[rd] = pv_add_constant (regs[rn], imm);
- else if (decode_adrp (start, insn, &rd))
- regs[rd] = pv_unknown ();
- else if (decode_b (start, insn, &is_link, &offset))
- {
-
- break;
- }
- else if (decode_bcond (start, insn, &cond, &offset))
- {
-
- break;
- }
- else if (decode_br (start, insn, &is_link, &rn))
- {
-
- break;
- }
- else if (decode_cb (start, insn, &is64, &op, &rn, &offset))
- {
-
- break;
- }
- else if (decode_eret (start, insn))
- {
-
- break;
- }
- else if (decode_movz (start, insn, &rd))
- regs[rd] = pv_unknown ();
- else
- if (decode_orr_shifted_register_x (start, insn, &rd, &rn, &rm, &imm))
- {
- if (imm == 0 && rn == 31)
- regs[rd] = regs[rm];
- else
- {
- if (aarch64_debug)
- fprintf_unfiltered
- (gdb_stdlog,
- "aarch64: prologue analysis gave up addr=0x%s "
- "opcode=0x%x (orr x register)\n",
- core_addr_to_string_nz (start),
- insn);
- break;
- }
- }
- else if (decode_ret (start, insn, &rn))
- {
-
- break;
- }
- else if (decode_stur (start, insn, &is64, &rt, &rn, &offset))
- {
- pv_area_store (stack, pv_add_constant (regs[rn], offset),
- is64 ? 8 : 4, regs[rt]);
- }
- else if (decode_stp_offset (start, insn, &rt1, &rt2, &rn, &imm))
- {
-
- if (pv_area_store_would_trash (stack,
- pv_add_constant (regs[rn], imm)))
- break;
- if (pv_area_store_would_trash (stack,
- pv_add_constant (regs[rn], imm + 8)))
- break;
- pv_area_store (stack, pv_add_constant (regs[rn], imm), 8,
- regs[rt1]);
- pv_area_store (stack, pv_add_constant (regs[rn], imm + 8), 8,
- regs[rt2]);
- }
- else if (decode_stp_offset_wb (start, insn, &rt1, &rt2, &rn, &imm))
- {
-
- if (pv_area_store_would_trash (stack,
- pv_add_constant (regs[rn], imm)))
- break;
- if (pv_area_store_would_trash (stack,
- pv_add_constant (regs[rn], imm + 8)))
- break;
- pv_area_store (stack, pv_add_constant (regs[rn], imm), 8,
- regs[rt1]);
- pv_area_store (stack, pv_add_constant (regs[rn], imm + 8), 8,
- regs[rt2]);
- regs[rn] = pv_add_constant (regs[rn], imm);
- }
- else if (decode_tb (start, insn, &op, &bit, &rn, &offset))
- {
-
- break;
- }
- else
- {
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog,
- "aarch64: prologue analysis gave up addr=0x%s"
- " opcode=0x%x\n",
- core_addr_to_string_nz (start), insn);
- break;
- }
- }
- if (cache == NULL)
- {
- do_cleanups (back_to);
- return start;
- }
- if (pv_is_register (regs[AARCH64_FP_REGNUM], AARCH64_SP_REGNUM))
- {
-
- cache->framereg = AARCH64_FP_REGNUM;
- cache->framesize = -regs[AARCH64_FP_REGNUM].k;
- }
- else if (pv_is_register (regs[AARCH64_SP_REGNUM], AARCH64_SP_REGNUM))
- {
-
- cache->framesize = -regs[AARCH64_SP_REGNUM].k;
- cache->framereg = AARCH64_SP_REGNUM;
- }
- else
- {
-
- cache->framereg = -1;
- cache->framesize = 0;
- }
- for (i = 0; i < AARCH64_X_REGISTER_COUNT; i++)
- {
- CORE_ADDR offset;
- if (pv_area_find_reg (stack, gdbarch, i, &offset))
- cache->saved_regs[i].addr = offset;
- }
- do_cleanups (back_to);
- return start;
- }
- static CORE_ADDR
- aarch64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
- {
- unsigned long inst;
- CORE_ADDR skip_pc;
- CORE_ADDR func_addr, limit_pc;
- struct symtab_and_line sal;
-
- if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
- {
- CORE_ADDR post_prologue_pc
- = skip_prologue_using_sal (gdbarch, func_addr);
- if (post_prologue_pc != 0)
- return max (pc, post_prologue_pc);
- }
-
-
- limit_pc = skip_prologue_using_sal (gdbarch, pc);
- if (limit_pc == 0)
- limit_pc = pc + 128;
-
- return aarch64_analyze_prologue (gdbarch, pc, limit_pc, NULL);
- }
- static void
- aarch64_scan_prologue (struct frame_info *this_frame,
- struct aarch64_prologue_cache *cache)
- {
- CORE_ADDR block_addr = get_frame_address_in_block (this_frame);
- CORE_ADDR prologue_start;
- CORE_ADDR prologue_end;
- CORE_ADDR prev_pc = get_frame_pc (this_frame);
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
-
- cache->framereg = -1;
- cache->framesize = 0;
- if (find_pc_partial_function (block_addr, NULL, &prologue_start,
- &prologue_end))
- {
- struct symtab_and_line sal = find_pc_line (prologue_start, 0);
- if (sal.line == 0)
- {
-
- prologue_end = prev_pc;
- }
- else if (sal.end < prologue_end)
- {
-
- prologue_end = sal.end;
- }
- prologue_end = min (prologue_end, prev_pc);
- aarch64_analyze_prologue (gdbarch, prologue_start, prologue_end, cache);
- }
- else
- {
- CORE_ADDR frame_loc;
- LONGEST saved_fp;
- LONGEST saved_lr;
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- frame_loc = get_frame_register_unsigned (this_frame, AARCH64_FP_REGNUM);
- if (frame_loc == 0)
- return;
- cache->framereg = AARCH64_FP_REGNUM;
- cache->framesize = 16;
- cache->saved_regs[29].addr = 0;
- cache->saved_regs[30].addr = 8;
- }
- }
- static struct aarch64_prologue_cache *
- aarch64_make_prologue_cache (struct frame_info *this_frame)
- {
- struct aarch64_prologue_cache *cache;
- CORE_ADDR unwound_fp;
- int reg;
- cache = FRAME_OBSTACK_ZALLOC (struct aarch64_prologue_cache);
- cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
- aarch64_scan_prologue (this_frame, cache);
- if (cache->framereg == -1)
- return cache;
- unwound_fp = get_frame_register_unsigned (this_frame, cache->framereg);
- if (unwound_fp == 0)
- return cache;
- cache->prev_sp = unwound_fp + cache->framesize;
-
- for (reg = 0; reg < gdbarch_num_regs (get_frame_arch (this_frame)); reg++)
- if (trad_frame_addr_p (cache->saved_regs, reg))
- cache->saved_regs[reg].addr += cache->prev_sp;
- return cache;
- }
- static void
- aarch64_prologue_this_id (struct frame_info *this_frame,
- void **this_cache, struct frame_id *this_id)
- {
- struct aarch64_prologue_cache *cache;
- struct frame_id id;
- CORE_ADDR pc, func;
- if (*this_cache == NULL)
- *this_cache = aarch64_make_prologue_cache (this_frame);
- cache = *this_cache;
-
- pc = get_frame_pc (this_frame);
- if (pc <= gdbarch_tdep (get_frame_arch (this_frame))->lowest_pc)
- return;
-
- if (cache->prev_sp == 0)
- return;
- func = get_frame_func (this_frame);
- id = frame_id_build (cache->prev_sp, func);
- *this_id = id;
- }
- static struct value *
- aarch64_prologue_prev_register (struct frame_info *this_frame,
- void **this_cache, int prev_regnum)
- {
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- struct aarch64_prologue_cache *cache;
- if (*this_cache == NULL)
- *this_cache = aarch64_make_prologue_cache (this_frame);
- cache = *this_cache;
-
- if (prev_regnum == AARCH64_PC_REGNUM)
- {
- CORE_ADDR lr;
- lr = frame_unwind_register_unsigned (this_frame, AARCH64_LR_REGNUM);
- return frame_unwind_got_constant (this_frame, prev_regnum, lr);
- }
-
-
- if (prev_regnum == AARCH64_SP_REGNUM)
- return frame_unwind_got_constant (this_frame, prev_regnum,
- cache->prev_sp);
- return trad_frame_get_prev_register (this_frame, cache->saved_regs,
- prev_regnum);
- }
- struct frame_unwind aarch64_prologue_unwind =
- {
- NORMAL_FRAME,
- default_frame_unwind_stop_reason,
- aarch64_prologue_this_id,
- aarch64_prologue_prev_register,
- NULL,
- default_frame_sniffer
- };
- static struct aarch64_prologue_cache *
- aarch64_make_stub_cache (struct frame_info *this_frame)
- {
- int reg;
- struct aarch64_prologue_cache *cache;
- CORE_ADDR unwound_fp;
- cache = FRAME_OBSTACK_ZALLOC (struct aarch64_prologue_cache);
- cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
- cache->prev_sp
- = get_frame_register_unsigned (this_frame, AARCH64_SP_REGNUM);
- return cache;
- }
- static void
- aarch64_stub_this_id (struct frame_info *this_frame,
- void **this_cache, struct frame_id *this_id)
- {
- struct aarch64_prologue_cache *cache;
- if (*this_cache == NULL)
- *this_cache = aarch64_make_stub_cache (this_frame);
- cache = *this_cache;
- *this_id = frame_id_build (cache->prev_sp, get_frame_pc (this_frame));
- }
- static int
- aarch64_stub_unwind_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
- void **this_prologue_cache)
- {
- CORE_ADDR addr_in_block;
- gdb_byte dummy[4];
- addr_in_block = get_frame_address_in_block (this_frame);
- if (in_plt_section (addr_in_block)
-
- || target_read_memory (get_frame_pc (this_frame), dummy, 4) != 0)
- return 1;
- return 0;
- }
- struct frame_unwind aarch64_stub_unwind =
- {
- NORMAL_FRAME,
- default_frame_unwind_stop_reason,
- aarch64_stub_this_id,
- aarch64_prologue_prev_register,
- NULL,
- aarch64_stub_unwind_sniffer
- };
- static CORE_ADDR
- aarch64_normal_frame_base (struct frame_info *this_frame, void **this_cache)
- {
- struct aarch64_prologue_cache *cache;
- if (*this_cache == NULL)
- *this_cache = aarch64_make_prologue_cache (this_frame);
- cache = *this_cache;
- return cache->prev_sp - cache->framesize;
- }
- struct frame_base aarch64_normal_base =
- {
- &aarch64_prologue_unwind,
- aarch64_normal_frame_base,
- aarch64_normal_frame_base,
- aarch64_normal_frame_base
- };
- static struct frame_id
- aarch64_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
- {
- return frame_id_build (get_frame_register_unsigned (this_frame,
- AARCH64_SP_REGNUM),
- get_frame_pc (this_frame));
- }
- static CORE_ADDR
- aarch64_unwind_pc (struct gdbarch *gdbarch, struct frame_info *this_frame)
- {
- CORE_ADDR pc
- = frame_unwind_register_unsigned (this_frame, AARCH64_PC_REGNUM);
- return pc;
- }
- static CORE_ADDR
- aarch64_unwind_sp (struct gdbarch *gdbarch, struct frame_info *this_frame)
- {
- return frame_unwind_register_unsigned (this_frame, AARCH64_SP_REGNUM);
- }
- static struct value *
- aarch64_dwarf2_prev_register (struct frame_info *this_frame,
- void **this_cache, int regnum)
- {
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- CORE_ADDR lr;
- switch (regnum)
- {
- case AARCH64_PC_REGNUM:
- lr = frame_unwind_register_unsigned (this_frame, AARCH64_LR_REGNUM);
- return frame_unwind_got_constant (this_frame, regnum, lr);
- default:
- internal_error (__FILE__, __LINE__,
- _("Unexpected register %d"), regnum);
- }
- }
- static void
- aarch64_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
- struct dwarf2_frame_state_reg *reg,
- struct frame_info *this_frame)
- {
- switch (regnum)
- {
- case AARCH64_PC_REGNUM:
- reg->how = DWARF2_FRAME_REG_FN;
- reg->loc.fn = aarch64_dwarf2_prev_register;
- break;
- case AARCH64_SP_REGNUM:
- reg->how = DWARF2_FRAME_REG_CFA;
- break;
- }
- }
- typedef struct
- {
-
- const void *data;
-
- int len;
- } stack_item_t;
- DEF_VEC_O (stack_item_t);
- static int
- aarch64_type_align (struct type *t)
- {
- int n;
- int align;
- int falign;
- t = check_typedef (t);
- switch (TYPE_CODE (t))
- {
- default:
-
- internal_error (__FILE__, __LINE__, _("unknown type alignment"));
- return 4;
- case TYPE_CODE_PTR:
- case TYPE_CODE_ENUM:
- case TYPE_CODE_INT:
- case TYPE_CODE_FLT:
- case TYPE_CODE_SET:
- case TYPE_CODE_RANGE:
- case TYPE_CODE_BITSTRING:
- case TYPE_CODE_REF:
- case TYPE_CODE_CHAR:
- case TYPE_CODE_BOOL:
- return TYPE_LENGTH (t);
- case TYPE_CODE_ARRAY:
- case TYPE_CODE_COMPLEX:
- return aarch64_type_align (TYPE_TARGET_TYPE (t));
- case TYPE_CODE_STRUCT:
- case TYPE_CODE_UNION:
- align = 1;
- for (n = 0; n < TYPE_NFIELDS (t); n++)
- {
- falign = aarch64_type_align (TYPE_FIELD_TYPE (t, n));
- if (falign > align)
- align = falign;
- }
- return align;
- }
- }
- static int
- is_hfa (struct type *ty)
- {
- switch (TYPE_CODE (ty))
- {
- case TYPE_CODE_ARRAY:
- {
- struct type *target_ty = TYPE_TARGET_TYPE (ty);
- if (TYPE_CODE (target_ty) == TYPE_CODE_FLT && TYPE_LENGTH (ty) <= 4)
- return 1;
- break;
- }
- case TYPE_CODE_UNION:
- case TYPE_CODE_STRUCT:
- {
- if (TYPE_NFIELDS (ty) > 0 && TYPE_NFIELDS (ty) <= 4)
- {
- struct type *member0_type;
- member0_type = check_typedef (TYPE_FIELD_TYPE (ty, 0));
- if (TYPE_CODE (member0_type) == TYPE_CODE_FLT)
- {
- int i;
- for (i = 0; i < TYPE_NFIELDS (ty); i++)
- {
- struct type *member1_type;
- member1_type = check_typedef (TYPE_FIELD_TYPE (ty, i));
- if (TYPE_CODE (member0_type) != TYPE_CODE (member1_type)
- || (TYPE_LENGTH (member0_type)
- != TYPE_LENGTH (member1_type)))
- return 0;
- }
- return 1;
- }
- }
- return 0;
- }
- default:
- break;
- }
- return 0;
- }
- struct aarch64_call_info
- {
-
- unsigned argnum;
-
- unsigned ngrn;
-
- unsigned nsrn;
-
- unsigned nsaa;
-
- VEC(stack_item_t) *si;
- };
- static void
- pass_in_x (struct gdbarch *gdbarch, struct regcache *regcache,
- struct aarch64_call_info *info, struct type *type,
- const bfd_byte *buf)
- {
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- int len = TYPE_LENGTH (type);
- enum type_code typecode = TYPE_CODE (type);
- int regnum = AARCH64_X0_REGNUM + info->ngrn;
- info->argnum++;
- while (len > 0)
- {
- int partial_len = len < X_REGISTER_SIZE ? len : X_REGISTER_SIZE;
- CORE_ADDR regval = extract_unsigned_integer (buf, partial_len,
- byte_order);
-
- if (byte_order == BFD_ENDIAN_BIG
- && partial_len < X_REGISTER_SIZE
- && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
- regval <<= ((X_REGISTER_SIZE - partial_len) * TARGET_CHAR_BIT);
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog, "arg %d in %s = 0x%s\n",
- info->argnum,
- gdbarch_register_name (gdbarch, regnum),
- phex (regval, X_REGISTER_SIZE));
- regcache_cooked_write_unsigned (regcache, regnum, regval);
- len -= partial_len;
- buf += partial_len;
- regnum++;
- }
- }
- static int
- pass_in_v (struct gdbarch *gdbarch,
- struct regcache *regcache,
- struct aarch64_call_info *info,
- const bfd_byte *buf)
- {
- if (info->nsrn < 8)
- {
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- int regnum = AARCH64_V0_REGNUM + info->nsrn;
- info->argnum++;
- info->nsrn++;
- regcache_cooked_write (regcache, regnum, buf);
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog, "arg %d in %s\n",
- info->argnum,
- gdbarch_register_name (gdbarch, regnum));
- return 1;
- }
- info->nsrn = 8;
- return 0;
- }
- static void
- pass_on_stack (struct aarch64_call_info *info, struct type *type,
- const bfd_byte *buf)
- {
- int len = TYPE_LENGTH (type);
- int align;
- stack_item_t item;
- info->argnum++;
- align = aarch64_type_align (type);
-
- align = align_up (align, 8);
-
- if (align > 16)
- align = 16;
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog, "arg %d len=%d @ sp + %d\n",
- info->argnum, len, info->nsaa);
- item.len = len;
- item.data = buf;
- VEC_safe_push (stack_item_t, info->si, &item);
- info->nsaa += len;
- if (info->nsaa & (align - 1))
- {
-
- int pad = align - (info->nsaa & (align - 1));
- item.len = pad;
- item.data = buf;
- VEC_safe_push (stack_item_t, info->si, &item);
- info->nsaa += pad;
- }
- }
- static void
- pass_in_x_or_stack (struct gdbarch *gdbarch, struct regcache *regcache,
- struct aarch64_call_info *info, struct type *type,
- const bfd_byte *buf)
- {
- int len = TYPE_LENGTH (type);
- int nregs = (len + X_REGISTER_SIZE - 1) / X_REGISTER_SIZE;
-
- if (info->ngrn + nregs <= 8)
- {
- pass_in_x (gdbarch, regcache, info, type, buf);
- info->ngrn += nregs;
- }
- else
- {
- info->ngrn = 8;
- pass_on_stack (info, type, buf);
- }
- }
- static void
- pass_in_v_or_stack (struct gdbarch *gdbarch,
- struct regcache *regcache,
- struct aarch64_call_info *info,
- struct type *type,
- const bfd_byte *buf)
- {
- if (!pass_in_v (gdbarch, regcache, info, buf))
- pass_on_stack (info, type, buf);
- }
- static CORE_ADDR
- aarch64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
- struct regcache *regcache, CORE_ADDR bp_addr,
- int nargs,
- struct value **args, CORE_ADDR sp, int struct_return,
- CORE_ADDR struct_addr)
- {
- int nstack = 0;
- int argnum;
- int x_argreg;
- int v_argreg;
- struct aarch64_call_info info;
- struct type *func_type;
- struct type *return_type;
- int lang_struct_return;
- memset (&info, 0, sizeof (info));
-
- func_type = check_typedef (value_type (function));
-
- if (TYPE_CODE (func_type) == TYPE_CODE_PTR)
- func_type = TYPE_TARGET_TYPE (func_type);
- gdb_assert (TYPE_CODE (func_type) == TYPE_CODE_FUNC
- || TYPE_CODE (func_type) == TYPE_CODE_METHOD);
-
- return_type = TYPE_TARGET_TYPE (func_type);
- lang_struct_return = language_pass_by_reference (return_type);
-
- regcache_cooked_write_unsigned (regcache, AARCH64_LR_REGNUM, bp_addr);
-
- if (lang_struct_return)
- {
- args++;
- nargs--;
- }
-
- if (struct_return || lang_struct_return)
- {
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog, "struct return in %s = 0x%s\n",
- gdbarch_register_name
- (gdbarch,
- AARCH64_STRUCT_RETURN_REGNUM),
- paddress (gdbarch, struct_addr));
- regcache_cooked_write_unsigned (regcache, AARCH64_STRUCT_RETURN_REGNUM,
- struct_addr);
- }
- for (argnum = 0; argnum < nargs; argnum++)
- {
- struct value *arg = args[argnum];
- struct type *arg_type;
- int len;
- arg_type = check_typedef (value_type (arg));
- len = TYPE_LENGTH (arg_type);
- switch (TYPE_CODE (arg_type))
- {
- case TYPE_CODE_INT:
- case TYPE_CODE_BOOL:
- case TYPE_CODE_CHAR:
- case TYPE_CODE_RANGE:
- case TYPE_CODE_ENUM:
- if (len < 4)
- {
-
- if (TYPE_UNSIGNED (arg_type))
- arg_type = builtin_type (gdbarch)->builtin_uint32;
- else
- arg_type = builtin_type (gdbarch)->builtin_int32;
- arg = value_cast (arg_type, arg);
- }
- pass_in_x_or_stack (gdbarch, regcache, &info, arg_type,
- value_contents (arg));
- break;
- case TYPE_CODE_COMPLEX:
- if (info.nsrn <= 6)
- {
- const bfd_byte *buf = value_contents (arg);
- struct type *target_type =
- check_typedef (TYPE_TARGET_TYPE (arg_type));
- pass_in_v (gdbarch, regcache, &info, buf);
- pass_in_v (gdbarch, regcache, &info,
- buf + TYPE_LENGTH (target_type));
- }
- else
- {
- info.nsrn = 8;
- pass_on_stack (&info, arg_type, value_contents (arg));
- }
- break;
- case TYPE_CODE_FLT:
- pass_in_v_or_stack (gdbarch, regcache, &info, arg_type,
- value_contents (arg));
- break;
- case TYPE_CODE_STRUCT:
- case TYPE_CODE_ARRAY:
- case TYPE_CODE_UNION:
- if (is_hfa (arg_type))
- {
- int elements = TYPE_NFIELDS (arg_type);
-
- if (info.nsrn + elements < 8)
- {
- int i;
- for (i = 0; i < elements; i++)
- {
-
- struct value *field =
- value_primitive_field (arg, 0, i, arg_type);
- struct type *field_type =
- check_typedef (value_type (field));
- pass_in_v_or_stack (gdbarch, regcache, &info, field_type,
- value_contents_writeable (field));
- }
- }
- else
- {
- info.nsrn = 8;
- pass_on_stack (&info, arg_type, value_contents (arg));
- }
- }
- else if (len > 16)
- {
-
-
- sp = align_down (sp - len, 16);
-
- write_memory (sp, value_contents (arg), len);
-
- arg_type = lookup_pointer_type (arg_type);
- arg = value_from_pointer (arg_type, sp);
- pass_in_x_or_stack (gdbarch, regcache, &info, arg_type,
- value_contents (arg));
- }
- else
-
- pass_in_x_or_stack (gdbarch, regcache, &info, arg_type,
- value_contents (arg));
- break;
- default:
- pass_in_x_or_stack (gdbarch, regcache, &info, arg_type,
- value_contents (arg));
- break;
- }
- }
-
- if (info.nsaa & 15)
- sp -= 16 - (info.nsaa & 15);
- while (!VEC_empty (stack_item_t, info.si))
- {
- stack_item_t *si = VEC_last (stack_item_t, info.si);
- sp -= si->len;
- write_memory (sp, si->data, si->len);
- VEC_pop (stack_item_t, info.si);
- }
- VEC_free (stack_item_t, info.si);
-
- regcache_cooked_write_unsigned (regcache, AARCH64_SP_REGNUM, sp);
- return sp;
- }
- static CORE_ADDR
- aarch64_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
- {
-
- return sp & ~(CORE_ADDR) 15;
- }
- static struct type *
- aarch64_vnq_type (struct gdbarch *gdbarch)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- if (tdep->vnq_type == NULL)
- {
- struct type *t;
- struct type *elem;
- t = arch_composite_type (gdbarch, "__gdb_builtin_type_vnq",
- TYPE_CODE_UNION);
- elem = builtin_type (gdbarch)->builtin_uint128;
- append_composite_type_field (t, "u", elem);
- elem = builtin_type (gdbarch)->builtin_int128;
- append_composite_type_field (t, "s", elem);
- tdep->vnq_type = t;
- }
- return tdep->vnq_type;
- }
- static struct type *
- aarch64_vnd_type (struct gdbarch *gdbarch)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- if (tdep->vnd_type == NULL)
- {
- struct type *t;
- struct type *elem;
- t = arch_composite_type (gdbarch, "__gdb_builtin_type_vnd",
- TYPE_CODE_UNION);
- elem = builtin_type (gdbarch)->builtin_double;
- append_composite_type_field (t, "f", elem);
- elem = builtin_type (gdbarch)->builtin_uint64;
- append_composite_type_field (t, "u", elem);
- elem = builtin_type (gdbarch)->builtin_int64;
- append_composite_type_field (t, "s", elem);
- tdep->vnd_type = t;
- }
- return tdep->vnd_type;
- }
- static struct type *
- aarch64_vns_type (struct gdbarch *gdbarch)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- if (tdep->vns_type == NULL)
- {
- struct type *t;
- struct type *elem;
- t = arch_composite_type (gdbarch, "__gdb_builtin_type_vns",
- TYPE_CODE_UNION);
- elem = builtin_type (gdbarch)->builtin_float;
- append_composite_type_field (t, "f", elem);
- elem = builtin_type (gdbarch)->builtin_uint32;
- append_composite_type_field (t, "u", elem);
- elem = builtin_type (gdbarch)->builtin_int32;
- append_composite_type_field (t, "s", elem);
- tdep->vns_type = t;
- }
- return tdep->vns_type;
- }
- static struct type *
- aarch64_vnh_type (struct gdbarch *gdbarch)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- if (tdep->vnh_type == NULL)
- {
- struct type *t;
- struct type *elem;
- t = arch_composite_type (gdbarch, "__gdb_builtin_type_vnh",
- TYPE_CODE_UNION);
- elem = builtin_type (gdbarch)->builtin_uint16;
- append_composite_type_field (t, "u", elem);
- elem = builtin_type (gdbarch)->builtin_int16;
- append_composite_type_field (t, "s", elem);
- tdep->vnh_type = t;
- }
- return tdep->vnh_type;
- }
- static struct type *
- aarch64_vnb_type (struct gdbarch *gdbarch)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- if (tdep->vnb_type == NULL)
- {
- struct type *t;
- struct type *elem;
- t = arch_composite_type (gdbarch, "__gdb_builtin_type_vnb",
- TYPE_CODE_UNION);
- elem = builtin_type (gdbarch)->builtin_uint8;
- append_composite_type_field (t, "u", elem);
- elem = builtin_type (gdbarch)->builtin_int8;
- append_composite_type_field (t, "s", elem);
- tdep->vnb_type = t;
- }
- return tdep->vnb_type;
- }
- static int
- aarch64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
- {
- if (reg >= AARCH64_DWARF_X0 && reg <= AARCH64_DWARF_X0 + 30)
- return AARCH64_X0_REGNUM + reg - AARCH64_DWARF_X0;
- if (reg == AARCH64_DWARF_SP)
- return AARCH64_SP_REGNUM;
- if (reg >= AARCH64_DWARF_V0 && reg <= AARCH64_DWARF_V0 + 31)
- return AARCH64_V0_REGNUM + reg - AARCH64_DWARF_V0;
- return -1;
- }
- static int
- aarch64_gdb_print_insn (bfd_vma memaddr, disassemble_info *info)
- {
- info->symbols = NULL;
- return print_insn_aarch64 (memaddr, info);
- }
- static const gdb_byte aarch64_default_breakpoint[] = {0x00, 0x00, 0x20, 0xd4};
- static const gdb_byte *
- aarch64_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
- int *lenptr)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- *lenptr = sizeof (aarch64_default_breakpoint);
- return aarch64_default_breakpoint;
- }
- static void
- aarch64_extract_return_value (struct type *type, struct regcache *regs,
- gdb_byte *valbuf)
- {
- struct gdbarch *gdbarch = get_regcache_arch (regs);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- if (TYPE_CODE (type) == TYPE_CODE_FLT)
- {
- bfd_byte buf[V_REGISTER_SIZE];
- int len = TYPE_LENGTH (type);
- regcache_cooked_read (regs, AARCH64_V0_REGNUM, buf);
- memcpy (valbuf, buf, len);
- }
- else if (TYPE_CODE (type) == TYPE_CODE_INT
- || TYPE_CODE (type) == TYPE_CODE_CHAR
- || TYPE_CODE (type) == TYPE_CODE_BOOL
- || TYPE_CODE (type) == TYPE_CODE_PTR
- || TYPE_CODE (type) == TYPE_CODE_REF
- || TYPE_CODE (type) == TYPE_CODE_ENUM)
- {
-
- int len = TYPE_LENGTH (type);
- int regno = AARCH64_X0_REGNUM;
- ULONGEST tmp;
- while (len > 0)
- {
-
- regcache_cooked_read_unsigned (regs, regno++, &tmp);
- store_unsigned_integer (valbuf,
- (len > X_REGISTER_SIZE
- ? X_REGISTER_SIZE : len), byte_order, tmp);
- len -= X_REGISTER_SIZE;
- valbuf += X_REGISTER_SIZE;
- }
- }
- else if (TYPE_CODE (type) == TYPE_CODE_COMPLEX)
- {
- int regno = AARCH64_V0_REGNUM;
- bfd_byte buf[V_REGISTER_SIZE];
- struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
- int len = TYPE_LENGTH (target_type);
- regcache_cooked_read (regs, regno, buf);
- memcpy (valbuf, buf, len);
- valbuf += len;
- regcache_cooked_read (regs, regno + 1, buf);
- memcpy (valbuf, buf, len);
- valbuf += len;
- }
- else if (is_hfa (type))
- {
- int elements = TYPE_NFIELDS (type);
- struct type *member_type = check_typedef (TYPE_FIELD_TYPE (type, 0));
- int len = TYPE_LENGTH (member_type);
- int i;
- for (i = 0; i < elements; i++)
- {
- int regno = AARCH64_V0_REGNUM + i;
- bfd_byte buf[X_REGISTER_SIZE];
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog,
- "read HFA return value element %d from %s\n",
- i + 1,
- gdbarch_register_name (gdbarch, regno));
- regcache_cooked_read (regs, regno, buf);
- memcpy (valbuf, buf, len);
- valbuf += len;
- }
- }
- else
- {
-
- int len = TYPE_LENGTH (type);
- int regno = AARCH64_X0_REGNUM;
- bfd_byte buf[X_REGISTER_SIZE];
- while (len > 0)
- {
- regcache_cooked_read (regs, regno++, buf);
- memcpy (valbuf, buf, len > X_REGISTER_SIZE ? X_REGISTER_SIZE : len);
- len -= X_REGISTER_SIZE;
- valbuf += X_REGISTER_SIZE;
- }
- }
- }
- static int
- aarch64_return_in_memory (struct gdbarch *gdbarch, struct type *type)
- {
- int nRc;
- enum type_code code;
- CHECK_TYPEDEF (type);
-
- if (is_hfa (type))
- {
-
- return 0;
- }
- if (TYPE_LENGTH (type) > 16)
- {
-
- return 1;
- }
- return 0;
- }
- static void
- aarch64_store_return_value (struct type *type, struct regcache *regs,
- const gdb_byte *valbuf)
- {
- struct gdbarch *gdbarch = get_regcache_arch (regs);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- if (TYPE_CODE (type) == TYPE_CODE_FLT)
- {
- bfd_byte buf[V_REGISTER_SIZE];
- int len = TYPE_LENGTH (type);
- memcpy (buf, valbuf, len > V_REGISTER_SIZE ? V_REGISTER_SIZE : len);
- regcache_cooked_write (regs, AARCH64_V0_REGNUM, buf);
- }
- else if (TYPE_CODE (type) == TYPE_CODE_INT
- || TYPE_CODE (type) == TYPE_CODE_CHAR
- || TYPE_CODE (type) == TYPE_CODE_BOOL
- || TYPE_CODE (type) == TYPE_CODE_PTR
- || TYPE_CODE (type) == TYPE_CODE_REF
- || TYPE_CODE (type) == TYPE_CODE_ENUM)
- {
- if (TYPE_LENGTH (type) <= X_REGISTER_SIZE)
- {
-
- bfd_byte tmpbuf[X_REGISTER_SIZE];
- LONGEST val = unpack_long (type, valbuf);
- store_signed_integer (tmpbuf, X_REGISTER_SIZE, byte_order, val);
- regcache_cooked_write (regs, AARCH64_X0_REGNUM, tmpbuf);
- }
- else
- {
-
- int len = TYPE_LENGTH (type);
- int regno = AARCH64_X0_REGNUM;
- while (len > 0)
- {
- regcache_cooked_write (regs, regno++, valbuf);
- len -= X_REGISTER_SIZE;
- valbuf += X_REGISTER_SIZE;
- }
- }
- }
- else if (is_hfa (type))
- {
- int elements = TYPE_NFIELDS (type);
- struct type *member_type = check_typedef (TYPE_FIELD_TYPE (type, 0));
- int len = TYPE_LENGTH (member_type);
- int i;
- for (i = 0; i < elements; i++)
- {
- int regno = AARCH64_V0_REGNUM + i;
- bfd_byte tmpbuf[MAX_REGISTER_SIZE];
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog,
- "write HFA return value element %d to %s\n",
- i + 1,
- gdbarch_register_name (gdbarch, regno));
- memcpy (tmpbuf, valbuf, len);
- regcache_cooked_write (regs, regno, tmpbuf);
- valbuf += len;
- }
- }
- else
- {
-
- int len = TYPE_LENGTH (type);
- int regno = AARCH64_X0_REGNUM;
- bfd_byte tmpbuf[X_REGISTER_SIZE];
- while (len > 0)
- {
- memcpy (tmpbuf, valbuf,
- len > X_REGISTER_SIZE ? X_REGISTER_SIZE : len);
- regcache_cooked_write (regs, regno++, tmpbuf);
- len -= X_REGISTER_SIZE;
- valbuf += X_REGISTER_SIZE;
- }
- }
- }
- static enum return_value_convention
- aarch64_return_value (struct gdbarch *gdbarch, struct value *func_value,
- struct type *valtype, struct regcache *regcache,
- gdb_byte *readbuf, const gdb_byte *writebuf)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- if (TYPE_CODE (valtype) == TYPE_CODE_STRUCT
- || TYPE_CODE (valtype) == TYPE_CODE_UNION
- || TYPE_CODE (valtype) == TYPE_CODE_ARRAY)
- {
- if (aarch64_return_in_memory (gdbarch, valtype))
- {
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog, "return value in memory\n");
- return RETURN_VALUE_STRUCT_CONVENTION;
- }
- }
- if (writebuf)
- aarch64_store_return_value (valtype, regcache, writebuf);
- if (readbuf)
- aarch64_extract_return_value (valtype, regcache, readbuf);
- if (aarch64_debug)
- fprintf_unfiltered (gdb_stdlog, "return value in registers\n");
- return RETURN_VALUE_REGISTER_CONVENTION;
- }
- static int
- aarch64_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
- {
- CORE_ADDR jb_addr;
- gdb_byte buf[X_REGISTER_SIZE];
- struct gdbarch *gdbarch = get_frame_arch (frame);
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- jb_addr = get_frame_register_unsigned (frame, AARCH64_X0_REGNUM);
- if (target_read_memory (jb_addr + tdep->jb_pc * tdep->jb_elt_size, buf,
- X_REGISTER_SIZE))
- return 0;
- *pc = extract_unsigned_integer (buf, X_REGISTER_SIZE, byte_order);
- return 1;
- }
- static const char *
- aarch64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
- {
- static const char *const q_name[] =
- {
- "q0", "q1", "q2", "q3",
- "q4", "q5", "q6", "q7",
- "q8", "q9", "q10", "q11",
- "q12", "q13", "q14", "q15",
- "q16", "q17", "q18", "q19",
- "q20", "q21", "q22", "q23",
- "q24", "q25", "q26", "q27",
- "q28", "q29", "q30", "q31",
- };
- static const char *const d_name[] =
- {
- "d0", "d1", "d2", "d3",
- "d4", "d5", "d6", "d7",
- "d8", "d9", "d10", "d11",
- "d12", "d13", "d14", "d15",
- "d16", "d17", "d18", "d19",
- "d20", "d21", "d22", "d23",
- "d24", "d25", "d26", "d27",
- "d28", "d29", "d30", "d31",
- };
- static const char *const s_name[] =
- {
- "s0", "s1", "s2", "s3",
- "s4", "s5", "s6", "s7",
- "s8", "s9", "s10", "s11",
- "s12", "s13", "s14", "s15",
- "s16", "s17", "s18", "s19",
- "s20", "s21", "s22", "s23",
- "s24", "s25", "s26", "s27",
- "s28", "s29", "s30", "s31",
- };
- static const char *const h_name[] =
- {
- "h0", "h1", "h2", "h3",
- "h4", "h5", "h6", "h7",
- "h8", "h9", "h10", "h11",
- "h12", "h13", "h14", "h15",
- "h16", "h17", "h18", "h19",
- "h20", "h21", "h22", "h23",
- "h24", "h25", "h26", "h27",
- "h28", "h29", "h30", "h31",
- };
- static const char *const b_name[] =
- {
- "b0", "b1", "b2", "b3",
- "b4", "b5", "b6", "b7",
- "b8", "b9", "b10", "b11",
- "b12", "b13", "b14", "b15",
- "b16", "b17", "b18", "b19",
- "b20", "b21", "b22", "b23",
- "b24", "b25", "b26", "b27",
- "b28", "b29", "b30", "b31",
- };
- regnum -= gdbarch_num_regs (gdbarch);
- if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
- return q_name[regnum - AARCH64_Q0_REGNUM];
- if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32)
- return d_name[regnum - AARCH64_D0_REGNUM];
- if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32)
- return s_name[regnum - AARCH64_S0_REGNUM];
- if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32)
- return h_name[regnum - AARCH64_H0_REGNUM];
- if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
- return b_name[regnum - AARCH64_B0_REGNUM];
- internal_error (__FILE__, __LINE__,
- _("aarch64_pseudo_register_name: bad register number %d"),
- regnum);
- }
- static struct type *
- aarch64_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
- {
- regnum -= gdbarch_num_regs (gdbarch);
- if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
- return aarch64_vnq_type (gdbarch);
- if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32)
- return aarch64_vnd_type (gdbarch);
- if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32)
- return aarch64_vns_type (gdbarch);
- if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32)
- return aarch64_vnh_type (gdbarch);
- if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
- return aarch64_vnb_type (gdbarch);
- internal_error (__FILE__, __LINE__,
- _("aarch64_pseudo_register_type: bad register number %d"),
- regnum);
- }
- static int
- aarch64_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
- struct reggroup *group)
- {
- regnum -= gdbarch_num_regs (gdbarch);
- if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
- return group == all_reggroup || group == vector_reggroup;
- else if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32)
- return (group == all_reggroup || group == vector_reggroup
- || group == float_reggroup);
- else if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32)
- return (group == all_reggroup || group == vector_reggroup
- || group == float_reggroup);
- else if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32)
- return group == all_reggroup || group == vector_reggroup;
- else if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
- return group == all_reggroup || group == vector_reggroup;
- return group == all_reggroup;
- }
- static struct value *
- aarch64_pseudo_read_value (struct gdbarch *gdbarch,
- struct regcache *regcache,
- int regnum)
- {
- gdb_byte reg_buf[MAX_REGISTER_SIZE];
- struct value *result_value;
- gdb_byte *buf;
- result_value = allocate_value (register_type (gdbarch, regnum));
- VALUE_LVAL (result_value) = lval_register;
- VALUE_REGNUM (result_value) = regnum;
- buf = value_contents_raw (result_value);
- regnum -= gdbarch_num_regs (gdbarch);
- if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
- {
- enum register_status status;
- unsigned v_regnum;
- v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_Q0_REGNUM;
- status = regcache_raw_read (regcache, v_regnum, reg_buf);
- if (status != REG_VALID)
- mark_value_bytes_unavailable (result_value, 0,
- TYPE_LENGTH (value_type (result_value)));
- else
- memcpy (buf, reg_buf, Q_REGISTER_SIZE);
- return result_value;
- }
- if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32)
- {
- enum register_status status;
- unsigned v_regnum;
- v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_D0_REGNUM;
- status = regcache_raw_read (regcache, v_regnum, reg_buf);
- if (status != REG_VALID)
- mark_value_bytes_unavailable (result_value, 0,
- TYPE_LENGTH (value_type (result_value)));
- else
- memcpy (buf, reg_buf, D_REGISTER_SIZE);
- return result_value;
- }
- if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32)
- {
- enum register_status status;
- unsigned v_regnum;
- v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_S0_REGNUM;
- status = regcache_raw_read (regcache, v_regnum, reg_buf);
- memcpy (buf, reg_buf, S_REGISTER_SIZE);
- return result_value;
- }
- if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32)
- {
- enum register_status status;
- unsigned v_regnum;
- v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_H0_REGNUM;
- status = regcache_raw_read (regcache, v_regnum, reg_buf);
- if (status != REG_VALID)
- mark_value_bytes_unavailable (result_value, 0,
- TYPE_LENGTH (value_type (result_value)));
- else
- memcpy (buf, reg_buf, H_REGISTER_SIZE);
- return result_value;
- }
- if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
- {
- enum register_status status;
- unsigned v_regnum;
- v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_B0_REGNUM;
- status = regcache_raw_read (regcache, v_regnum, reg_buf);
- if (status != REG_VALID)
- mark_value_bytes_unavailable (result_value, 0,
- TYPE_LENGTH (value_type (result_value)));
- else
- memcpy (buf, reg_buf, B_REGISTER_SIZE);
- return result_value;
- }
- gdb_assert_not_reached ("regnum out of bound");
- }
- static void
- aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
- int regnum, const gdb_byte *buf)
- {
- gdb_byte reg_buf[MAX_REGISTER_SIZE];
-
- memset (reg_buf, 0, sizeof (reg_buf));
- regnum -= gdbarch_num_regs (gdbarch);
- if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
- {
-
- unsigned v_regnum;
- v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_Q0_REGNUM;
- memcpy (reg_buf, buf, Q_REGISTER_SIZE);
- regcache_raw_write (regcache, v_regnum, reg_buf);
- return;
- }
- if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32)
- {
-
- unsigned v_regnum;
- v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_D0_REGNUM;
- memcpy (reg_buf, buf, D_REGISTER_SIZE);
- regcache_raw_write (regcache, v_regnum, reg_buf);
- return;
- }
- if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32)
- {
- unsigned v_regnum;
- v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_S0_REGNUM;
- memcpy (reg_buf, buf, S_REGISTER_SIZE);
- regcache_raw_write (regcache, v_regnum, reg_buf);
- return;
- }
- if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32)
- {
-
- unsigned v_regnum;
- v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_H0_REGNUM;
- memcpy (reg_buf, buf, H_REGISTER_SIZE);
- regcache_raw_write (regcache, v_regnum, reg_buf);
- return;
- }
- if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
- {
-
- unsigned v_regnum;
- v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_B0_REGNUM;
- memcpy (reg_buf, buf, B_REGISTER_SIZE);
- regcache_raw_write (regcache, v_regnum, reg_buf);
- return;
- }
- gdb_assert_not_reached ("regnum out of bound");
- }
- static struct value *
- value_of_aarch64_user_reg (struct frame_info *frame, const void *baton)
- {
- const int *reg_p = baton;
- return value_of_register (*reg_p, frame);
- }
- static int
- aarch64_software_single_step (struct frame_info *frame)
- {
- struct gdbarch *gdbarch = get_frame_arch (frame);
- struct address_space *aspace = get_frame_address_space (frame);
- enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
- const int insn_size = 4;
- const int atomic_sequence_length = 16;
- CORE_ADDR pc = get_frame_pc (frame);
- CORE_ADDR breaks[2] = { -1, -1 };
- CORE_ADDR loc = pc;
- CORE_ADDR closing_insn = 0;
- uint32_t insn = read_memory_unsigned_integer (loc, insn_size,
- byte_order_for_code);
- int index;
- int insn_count;
- int bc_insn_count = 0;
- int last_breakpoint = 0;
-
- if (!decode_masked_match (insn, 0x3fc00000, 0x08400000))
- return 0;
- for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count)
- {
- int32_t offset;
- unsigned cond;
- loc += insn_size;
- insn = read_memory_unsigned_integer (loc, insn_size,
- byte_order_for_code);
-
- if (decode_bcond (loc, insn, &cond, &offset))
- {
- if (bc_insn_count >= 1)
- return 0;
-
- breaks[1] = loc + offset;
- bc_insn_count++;
- last_breakpoint++;
- }
-
- if (decode_masked_match (insn, 0x3fc00000, 0x08000000))
- {
- closing_insn = loc;
- break;
- }
- }
-
- if (!closing_insn)
- return 0;
-
- breaks[0] = loc + insn_size;
-
- if (last_breakpoint
- && (breaks[1] == breaks[0]
- || (breaks[1] >= pc && breaks[1] <= closing_insn)))
- last_breakpoint = 0;
-
- for (index = 0; index <= last_breakpoint; index++)
- insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);
- return 1;
- }
- static struct gdbarch *
- aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
- {
- struct gdbarch_tdep *tdep;
- struct gdbarch *gdbarch;
- struct gdbarch_list *best_arch;
- struct tdesc_arch_data *tdesc_data = NULL;
- const struct target_desc *tdesc = info.target_desc;
- int i;
- int have_fpa_registers = 1;
- int valid_p = 1;
- const struct tdesc_feature *feature;
- int num_regs = 0;
- int num_pseudo_regs = 0;
-
- if (!tdesc_has_registers (tdesc))
- tdesc = tdesc_aarch64;
- gdb_assert (tdesc);
- feature = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.core");
- if (feature == NULL)
- return NULL;
- tdesc_data = tdesc_data_alloc ();
-
- for (i = 0; i < ARRAY_SIZE (aarch64_r_register_names); i++)
- valid_p &=
- tdesc_numbered_register (feature, tdesc_data, AARCH64_X0_REGNUM + i,
- aarch64_r_register_names[i]);
- num_regs = AARCH64_X0_REGNUM + i;
-
- feature = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.fpu");
- if (feature)
- {
-
- for (i = 0; i < ARRAY_SIZE (aarch64_v_register_names); i++)
- valid_p &=
- tdesc_numbered_register (feature, tdesc_data, AARCH64_V0_REGNUM + i,
- aarch64_v_register_names[i]);
- num_regs = AARCH64_V0_REGNUM + i;
- num_pseudo_regs += 32;
- num_pseudo_regs += 32;
- num_pseudo_regs += 32;
- num_pseudo_regs += 32;
- num_pseudo_regs += 32;
- }
- if (!valid_p)
- {
- tdesc_data_cleanup (tdesc_data);
- return NULL;
- }
-
- info.byte_order_for_code = BFD_ENDIAN_LITTLE;
-
- for (best_arch = gdbarch_list_lookup_by_info (arches, &info);
- best_arch != NULL;
- best_arch = gdbarch_list_lookup_by_info (best_arch->next, &info))
- {
-
- break;
- }
- if (best_arch != NULL)
- {
- if (tdesc_data != NULL)
- tdesc_data_cleanup (tdesc_data);
- return best_arch->gdbarch;
- }
- tdep = xcalloc (1, sizeof (struct gdbarch_tdep));
- gdbarch = gdbarch_alloc (&info, tdep);
-
- tdep->lowest_pc = 0x20;
- tdep->jb_pc = -1;
- tdep->jb_elt_size = 8;
- set_gdbarch_push_dummy_call (gdbarch, aarch64_push_dummy_call);
- set_gdbarch_frame_align (gdbarch, aarch64_frame_align);
-
- set_gdbarch_dummy_id (gdbarch, aarch64_dummy_id);
- set_gdbarch_unwind_pc (gdbarch, aarch64_unwind_pc);
- set_gdbarch_unwind_sp (gdbarch, aarch64_unwind_sp);
-
- set_gdbarch_skip_prologue (gdbarch, aarch64_skip_prologue);
-
- set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
-
- set_gdbarch_breakpoint_from_pc (gdbarch, aarch64_breakpoint_from_pc);
- set_gdbarch_cannot_step_breakpoint (gdbarch, 1);
- set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
- set_gdbarch_software_single_step (gdbarch, aarch64_software_single_step);
-
- set_gdbarch_sp_regnum (gdbarch, AARCH64_SP_REGNUM);
- set_gdbarch_pc_regnum (gdbarch, AARCH64_PC_REGNUM);
- set_gdbarch_num_regs (gdbarch, num_regs);
- set_gdbarch_num_pseudo_regs (gdbarch, num_pseudo_regs);
- set_gdbarch_pseudo_register_read_value (gdbarch, aarch64_pseudo_read_value);
- set_gdbarch_pseudo_register_write (gdbarch, aarch64_pseudo_write);
- set_tdesc_pseudo_register_name (gdbarch, aarch64_pseudo_register_name);
- set_tdesc_pseudo_register_type (gdbarch, aarch64_pseudo_register_type);
- set_tdesc_pseudo_register_reggroup_p (gdbarch,
- aarch64_pseudo_register_reggroup_p);
-
- set_gdbarch_short_bit (gdbarch, 16);
- set_gdbarch_int_bit (gdbarch, 32);
- set_gdbarch_float_bit (gdbarch, 32);
- set_gdbarch_double_bit (gdbarch, 64);
- set_gdbarch_long_double_bit (gdbarch, 128);
- set_gdbarch_long_bit (gdbarch, 64);
- set_gdbarch_long_long_bit (gdbarch, 64);
- set_gdbarch_ptr_bit (gdbarch, 64);
- set_gdbarch_char_signed (gdbarch, 0);
- set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
- set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
- set_gdbarch_long_double_format (gdbarch, floatformats_ia64_quad);
-
- set_gdbarch_dwarf2_reg_to_regnum (gdbarch, aarch64_dwarf_reg_to_regnum);
-
- set_gdbarch_return_value (gdbarch, aarch64_return_value);
-
- set_gdbarch_print_insn (gdbarch, aarch64_gdb_print_insn);
-
- set_gdbarch_vbit_in_delta (gdbarch, 1);
-
- info.target_desc = tdesc;
- info.tdep_info = (void *) tdesc_data;
- gdbarch_init_osabi (info, gdbarch);
- dwarf2_frame_set_init_reg (gdbarch, aarch64_dwarf2_frame_init_reg);
-
- frame_unwind_append_unwinder (gdbarch, &aarch64_stub_unwind);
- dwarf2_append_unwinders (gdbarch);
- frame_unwind_append_unwinder (gdbarch, &aarch64_prologue_unwind);
- frame_base_set_default (gdbarch, &aarch64_normal_base);
-
- if (tdep->jb_pc >= 0)
- set_gdbarch_get_longjmp_target (gdbarch, aarch64_get_longjmp_target);
- tdesc_use_registers (gdbarch, tdesc, tdesc_data);
-
- for (i = 0; i < ARRAY_SIZE (aarch64_register_aliases); i++)
- user_reg_add (gdbarch, aarch64_register_aliases[i].name,
- value_of_aarch64_user_reg,
- &aarch64_register_aliases[i].regnum);
- return gdbarch;
- }
- static void
- aarch64_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- if (tdep == NULL)
- return;
- fprintf_unfiltered (file, _("aarch64_dump_tdep: Lowest pc = 0x%s"),
- paddress (gdbarch, tdep->lowest_pc));
- }
- extern initialize_file_ftype _initialize_aarch64_tdep;
- void
- _initialize_aarch64_tdep (void)
- {
- gdbarch_register (bfd_arch_aarch64, aarch64_gdbarch_init,
- aarch64_dump_tdep);
- initialize_tdesc_aarch64 ();
-
- add_setshow_boolean_cmd ("aarch64", class_maintenance, &aarch64_debug, _("\
- Set AArch64 debugging."), _("\
- Show AArch64 debugging."), _("\
- When on, AArch64 specific debugging is enabled."),
- NULL,
- show_aarch64_debug,
- &setdebuglist, &showdebuglist);
- }