X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Frs6000-tdep.c;h=ee3f051dda69a568ce528d3db310d6db15a79a6c;hb=dd1ae8eaa369ac5c7df7e55c929b42ac8ac44526;hp=d45a15c16ca1be6854ea9b829ead0be0bb6e9f6c;hpb=01add95bed9afd5e7815439c3967db976be53f80;p=binutils-gdb.git diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index d45a15c16ca..ee3f051dda6 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -1,6 +1,6 @@ /* Target-dependent code for GDB, the GNU debugger. - Copyright (C) 1986-2021 Free Software Foundation, Inc. + Copyright (C) 1986-2022 Free Software Foundation, Inc. This file is part of GDB. @@ -155,19 +155,11 @@ static const char *powerpc_vector_abi_string = "auto"; /* PowerPC-related per-inferior data. */ -struct ppc_inferior_data -{ - /* This is an optional in case we add more fields to ppc_inferior_data, we - don't want it instantiated as soon as we get the ppc_inferior_data for an - inferior. */ - gdb::optional disp_step_buf; -}; - static inferior_key ppc_inferior_data_key; /* Get the per-inferior PowerPC data for INF. */ -static ppc_inferior_data * +ppc_inferior_data * get_ppc_per_inferior (inferior *inf) { ppc_inferior_data *per_inf = ppc_inferior_data_key.get (inf); @@ -209,7 +201,7 @@ struct rs6000_framedata int vsx_register_p (struct gdbarch *gdbarch, int regno) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); if (tdep->ppc_vsr0_regnum < 0) return 0; else @@ -221,7 +213,7 @@ vsx_register_p (struct gdbarch *gdbarch, int regno) int altivec_register_p (struct gdbarch *gdbarch, int regno) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); if (tdep->ppc_vr0_regnum < 0 || tdep->ppc_vrsave_regnum < 0) return 0; else @@ -233,7 +225,7 @@ altivec_register_p (struct gdbarch *gdbarch, int regno) int spe_register_p (struct gdbarch *gdbarch, int regno) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); /* Is it a reference to EV0 -- EV31, and do we have those? */ if (IS_SPE_PSEUDOREG (tdep, regno)) @@ -265,7 +257,7 @@ spe_register_p (struct gdbarch *gdbarch, int regno) int ppc_floating_point_unit_p (struct gdbarch *gdbarch) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); return (tdep->ppc_fp0_regnum >= 0 && tdep->ppc_fpscr_regnum >= 0); @@ -276,7 +268,7 @@ ppc_floating_point_unit_p (struct gdbarch *gdbarch) int ppc_altivec_support_p (struct gdbarch *gdbarch) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); return (tdep->ppc_vr0_regnum >= 0 && tdep->ppc_vrsave_regnum >= 0); @@ -305,7 +297,7 @@ set_sim_regno (int *table, int gdb_regno, int sim_regno) static void init_sim_regno_table (struct gdbarch *arch) { - struct gdbarch_tdep *tdep = gdbarch_tdep (arch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (arch); int total_regs = gdbarch_num_regs (arch); int *sim_regno = GDBARCH_OBSTACK_CALLOC (arch, total_regs, int); int i; @@ -399,7 +391,7 @@ init_sim_regno_table (struct gdbarch *arch) static int rs6000_register_sim_regno (struct gdbarch *gdbarch, int reg) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); int sim_regno; if (tdep->sim_regno == NULL) @@ -470,7 +462,7 @@ ppc_collect_reg (const struct regcache *regcache, int regnum, static int ppc_greg_offset (struct gdbarch *gdbarch, - struct gdbarch_tdep *tdep, + ppc_gdbarch_tdep *tdep, const struct ppc_reg_offsets *offsets, int regnum, int *regsize) @@ -507,7 +499,7 @@ ppc_greg_offset (struct gdbarch *gdbarch, } static int -ppc_fpreg_offset (struct gdbarch_tdep *tdep, +ppc_fpreg_offset (ppc_gdbarch_tdep *tdep, const struct ppc_reg_offsets *offsets, int regnum) { @@ -530,7 +522,7 @@ ppc_supply_gregset (const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs, size_t len) { struct gdbarch *gdbarch = regcache->arch (); - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); const struct ppc_reg_offsets *offsets = (const struct ppc_reg_offsets *) regset->regmap; size_t offset; @@ -580,14 +572,13 @@ ppc_supply_fpregset (const struct regset *regset, struct regcache *regcache, int regnum, const void *fpregs, size_t len) { struct gdbarch *gdbarch = regcache->arch (); - struct gdbarch_tdep *tdep; const struct ppc_reg_offsets *offsets; size_t offset; if (!ppc_floating_point_unit_p (gdbarch)) return; - tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); offsets = (const struct ppc_reg_offsets *) regset->regmap; if (regnum == -1) { @@ -620,7 +611,7 @@ ppc_collect_gregset (const struct regset *regset, int regnum, void *gregs, size_t len) { struct gdbarch *gdbarch = regcache->arch (); - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); const struct ppc_reg_offsets *offsets = (const struct ppc_reg_offsets *) regset->regmap; size_t offset; @@ -671,14 +662,13 @@ ppc_collect_fpregset (const struct regset *regset, int regnum, void *fpregs, size_t len) { struct gdbarch *gdbarch = regcache->arch (); - struct gdbarch_tdep *tdep; const struct ppc_reg_offsets *offsets; size_t offset; if (!ppc_floating_point_unit_p (gdbarch)) return; - tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); offsets = (const struct ppc_reg_offsets *) regset->regmap; if (regnum == -1) { @@ -756,7 +746,7 @@ static int rs6000_in_function_epilogue_frame_p (struct frame_info *curfrm, struct gdbarch *gdbarch, CORE_ADDR pc) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); bfd_byte insn_buf[PPC_INSN_SIZE]; CORE_ADDR scan_pc, func_start, func_end, epilogue_start, epilogue_end; @@ -834,8 +824,8 @@ rs6000_fetch_pointer_argument (struct frame_info *frame, int argi, /* Sequence of bytes for breakpoint instruction. */ -constexpr gdb_byte big_breakpoint[] = { 0x7d, 0x82, 0x10, 0x08 }; -constexpr gdb_byte little_breakpoint[] = { 0x08, 0x10, 0x82, 0x7d }; +constexpr gdb_byte big_breakpoint[] = { 0x7f, 0xe0, 0x00, 0x08 }; +constexpr gdb_byte little_breakpoint[] = { 0x08, 0x00, 0xe0, 0x7f }; typedef BP_MANIPULATION_ENDIAN (little_breakpoint, big_breakpoint) rs6000_breakpoint; @@ -1052,8 +1042,9 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch, if (insn & 0x1) { /* Link register needs to be set to the next instruction's PC. */ + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); regcache_cooked_write_unsigned (regs, - gdbarch_tdep (gdbarch)->ppc_lr_regnum, + tdep->ppc_lr_regnum, from + PPC_INSN_SIZE); displaced_debug_printf ("(ppc) adjusted LR to %s", paddress (gdbarch, from + PPC_INSN_SIZE)); @@ -1599,7 +1590,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, int num_skip_non_prologue_insns = 0; int r0_contains_arg = 0; const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch); - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); memset (fdata, 0, sizeof (struct rs6000_framedata)); @@ -1872,12 +1863,12 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, continue; } else if ((op & 0xffff0000) == 0x38210000) - { /* addi r1,r1,SIMM */ - fdata->frameless = 0; - fdata->offset += SIGNED_SHORT (op); - offset = fdata->offset; - continue; - } + { /* addi r1,r1,SIMM */ + fdata->frameless = 0; + fdata->offset += SIGNED_SHORT (op); + offset = fdata->offset; + continue; + } /* Load up minimal toc pointer. Do not treat an epilogue restore of r31 as a minimal TOC load. */ else if (((op >> 22) == 0x20f || /* l r31,... or l r30,... */ @@ -1890,7 +1881,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, /* move parameters from argument registers to local variable registers */ - } + } else if ((op & 0xfc0007fe) == 0x7c000378 && /* mr(.) Rx,Ry */ (((op >> 21) & 31) >= 3) && /* R3 >= Ry >= R10 */ (((op >> 21) & 31) <= 10) && @@ -2081,7 +2072,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, } continue; - } + } /* Store gen register S at (r31+r0). Store param on stack when offset from SP bigger than 4 bytes. */ /* 000100 sssss 11111 00000 01100100000 */ @@ -2137,6 +2128,12 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, /* Never skip branches. */ break; + /* Test based on opcode and mask values of + powerpc_opcodes[svc..svcla] in opcodes/ppc-opc.c. */ + if ((op & 0xffff0000) == 0x44000000) + /* Never skip system calls. */ + break; + if (num_skip_non_prologue_insns++ > max_skip_non_prologue_insns) /* Do not scan too many insns, scanning insns is expensive with remote targets. */ @@ -2313,7 +2310,7 @@ static CORE_ADDR rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) { struct gdbarch *gdbarch = get_frame_arch (frame); - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); unsigned int ii, op; int rel; @@ -2371,7 +2368,7 @@ rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) static struct type * rs6000_builtin_type_vec64 (struct gdbarch *gdbarch) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); if (!tdep->ppc_builtin_type_vec64) { @@ -2416,7 +2413,7 @@ rs6000_builtin_type_vec64 (struct gdbarch *gdbarch) static struct type * rs6000_builtin_type_vec128 (struct gdbarch *gdbarch) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); if (!tdep->ppc_builtin_type_vec128) { @@ -2470,7 +2467,7 @@ rs6000_builtin_type_vec128 (struct gdbarch *gdbarch) static const char * rs6000_register_name (struct gdbarch *gdbarch, int regno) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); /* The upper half "registers" have names in the XML description, but we present only the low GPRs and the full 64-bit registers @@ -2608,7 +2605,7 @@ rs6000_register_name (struct gdbarch *gdbarch, int regno) static struct type * rs6000_pseudo_register_type (struct gdbarch *gdbarch, int regnum) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); /* These are the e500 pseudo-registers. */ if (IS_SPE_PSEUDOREG (tdep, regnum)) @@ -2647,7 +2644,7 @@ static int rs6000_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum, struct reggroup *group) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); if (IS_V_ALIAS_PSEUDOREG (tdep, regnum)) return 0; @@ -2662,7 +2659,7 @@ static int rs6000_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); return (tdep->ppc_fp0_regnum >= 0 && regnum >= tdep->ppc_fp0_regnum @@ -2747,7 +2744,7 @@ e500_move_ev_register (move_ev_register_func move, struct regcache *regcache, int ev_reg, void *buffer) { struct gdbarch *arch = regcache->arch (); - struct gdbarch_tdep *tdep = gdbarch_tdep (arch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (arch); int reg_index; gdb_byte *byte_buffer = (gdb_byte *) buffer; enum register_status status; @@ -2788,7 +2785,7 @@ e500_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache, int ev_reg, gdb_byte *buffer) { struct gdbarch *arch = regcache->arch (); - struct gdbarch_tdep *tdep = gdbarch_tdep (arch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); int reg_index; enum register_status status; @@ -2829,7 +2826,7 @@ static enum register_status dfp_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache, int reg_nr, gdb_byte *buffer) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); int reg_index, fp0; enum register_status status; @@ -2869,7 +2866,7 @@ static void dfp_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, int reg_nr, const gdb_byte *buffer) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); int reg_index, fp0; if (IS_DFP_PSEUDOREG (tdep, reg_nr)) @@ -2906,7 +2903,7 @@ v_alias_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache, int reg_nr, gdb_byte *buffer) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); gdb_assert (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr)); return regcache->raw_read (tdep->ppc_vr0_regnum @@ -2921,7 +2918,7 @@ v_alias_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, int reg_nr, const gdb_byte *buffer) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); gdb_assert (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr)); regcache->raw_write (tdep->ppc_vr0_regnum @@ -2933,7 +2930,7 @@ static enum register_status vsx_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache, int reg_nr, gdb_byte *buffer) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); int reg_index, vr0, fp0, vsr0_upper; enum register_status status; @@ -2981,7 +2978,7 @@ static void vsx_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, int reg_nr, const gdb_byte *buffer) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); int reg_index, vr0, fp0, vsr0_upper; if (IS_VSX_PSEUDOREG (tdep, reg_nr)) @@ -3023,7 +3020,7 @@ static enum register_status efp_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache, int reg_nr, gdb_byte *buffer) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); int reg_index, vr0; if (IS_EFP_PSEUDOREG (tdep, reg_nr)) @@ -3052,7 +3049,7 @@ static void efp_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, int reg_nr, const gdb_byte *buffer) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); int reg_index, vr0; int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8; @@ -3088,7 +3085,7 @@ rs6000_pseudo_register_read (struct gdbarch *gdbarch, int reg_nr, gdb_byte *buffer) { struct gdbarch *regcache_arch = regcache->arch (); - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); gdb_assert (regcache_arch == gdbarch); @@ -3119,7 +3116,7 @@ rs6000_pseudo_register_write (struct gdbarch *gdbarch, int reg_nr, const gdb_byte *buffer) { struct gdbarch *regcache_arch = regcache->arch (); - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); gdb_assert (regcache_arch == gdbarch); @@ -3150,7 +3147,7 @@ static void dfp_ax_pseudo_register_collect (struct gdbarch *gdbarch, struct agent_expr *ax, int reg_nr) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); int reg_index, fp0; if (IS_DFP_PSEUDOREG (tdep, reg_nr)) @@ -3177,7 +3174,7 @@ static void v_alias_pseudo_register_collect (struct gdbarch *gdbarch, struct agent_expr *ax, int reg_nr) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); gdb_assert (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr)); ax_reg_mask (ax, tdep->ppc_vr0_regnum @@ -3191,7 +3188,7 @@ static void vsx_ax_pseudo_register_collect (struct gdbarch *gdbarch, struct agent_expr *ax, int reg_nr) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); int reg_index, vr0, fp0, vsr0_upper; if (IS_VSX_PSEUDOREG (tdep, reg_nr)) @@ -3229,7 +3226,7 @@ static void efp_ax_pseudo_register_collect (struct gdbarch *gdbarch, struct agent_expr *ax, int reg_nr) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); int reg_index, vr0; if (IS_EFP_PSEUDOREG (tdep, reg_nr)) @@ -3252,7 +3249,7 @@ static int rs6000_ax_pseudo_register_collect (struct gdbarch *gdbarch, struct agent_expr *ax, int reg_nr) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); if (IS_SPE_PSEUDOREG (tdep, reg_nr)) { int reg_index = reg_nr - tdep->ppc_ev0_regnum; @@ -3292,7 +3289,7 @@ rs6000_gen_return_address (struct gdbarch *gdbarch, struct agent_expr *ax, struct axs_value *value, CORE_ADDR scope) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); value->type = register_type (gdbarch, tdep->ppc_lr_regnum); value->kind = axs_lvalue_register; value->u.reg = tdep->ppc_lr_regnum; @@ -3303,7 +3300,7 @@ rs6000_gen_return_address (struct gdbarch *gdbarch, static int rs6000_stab_reg_to_regnum (struct gdbarch *gdbarch, int num) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); if (0 <= num && num <= 31) return tdep->ppc_gp0_regnum + num; @@ -3345,7 +3342,7 @@ rs6000_stab_reg_to_regnum (struct gdbarch *gdbarch, int num) static int rs6000_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int num) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); if (0 <= num && num <= 31) return tdep->ppc_gp0_regnum + num; @@ -3564,7 +3561,7 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) { struct rs6000_frame_cache *cache; struct gdbarch *gdbarch = get_frame_arch (this_frame); - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct rs6000_framedata fdata; int wordsize = tdep->wordsize; @@ -3783,6 +3780,7 @@ rs6000_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind rs6000_frame_unwind = { + "rs6000 prologue", NORMAL_FRAME, default_frame_unwind_stop_reason, rs6000_frame_this_id, @@ -3799,7 +3797,7 @@ rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache) { struct rs6000_frame_cache *cache; struct gdbarch *gdbarch = get_frame_arch (this_frame); - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); if (*this_cache) return (struct rs6000_frame_cache *) *this_cache; @@ -3882,6 +3880,7 @@ rs6000_epilogue_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind rs6000_epilogue_frame_unwind = { + "rs6000 epilogue", NORMAL_FRAME, default_frame_unwind_stop_reason, rs6000_epilogue_frame_this_id, rs6000_epilogue_frame_prev_register, @@ -3919,7 +3918,7 @@ ppc_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum, struct dwarf2_frame_state_reg *reg, struct frame_info *this_frame) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); /* PPC32 and PPC64 ABI's are the same regarding volatile and non-volatile registers. We will use the same code for both. */ @@ -4131,7 +4130,7 @@ bfd_uses_spe_extensions (bfd *abfd) Otherwise, it's just a VR register. Record them accordingly. */ static int -ppc_record_vsr (struct regcache *regcache, struct gdbarch_tdep *tdep, int vsr) +ppc_record_vsr (struct regcache *regcache, ppc_gdbarch_tdep *tdep, int vsr) { if (vsr < 0 || vsr >= 64) return -1; @@ -4160,7 +4159,7 @@ static int ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR addr, uint32_t insn) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); int ext = PPC_FIELD (insn, 21, 11); int vra = PPC_FIELD (insn, 11, 5); @@ -4533,7 +4532,7 @@ static int ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR addr, uint32_t insn) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); int ext = PPC_EXTOP (insn); switch (ext & 0x01f) @@ -4585,7 +4584,7 @@ static int ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR addr, uint32_t insn) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); int ext = PPC_EXTOP (insn); int tmp, nr, nb, i; CORE_ADDR at_dcsz, ea = 0; @@ -4991,20 +4990,20 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, switch (ext) { case 167: /* Store Vector Element Halfword Indexed */ - addr = addr & ~0x1ULL; + ea = ea & ~0x1ULL; break; case 199: /* Store Vector Element Word Indexed */ - addr = addr & ~0x3ULL; + ea = ea & ~0x3ULL; break; case 231: /* Store Vector Indexed */ case 487: /* Store Vector Indexed LRU */ - addr = addr & ~0xfULL; + ea = ea & ~0xfULL; break; } - record_full_arch_list_add_mem (addr, size); + record_full_arch_list_add_mem (ea, size); return 0; case 397: /* Store VSX Vector with Length */ @@ -5182,7 +5181,7 @@ static int ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR addr, uint32_t insn) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); int ext = PPC_EXTOP (insn); switch (ext & 0x1f) @@ -5276,7 +5275,7 @@ static int ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR addr, uint32_t insn) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); int ext = PPC_EXTOP (insn); switch (ext >> 2) @@ -5638,7 +5637,7 @@ static int ppc_process_record_op61 (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR addr, uint32_t insn) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); ULONGEST ea = 0; int size; @@ -5697,7 +5696,7 @@ static int ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR addr, uint32_t insn) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); int ext = PPC_EXTOP (insn); int tmp; @@ -5956,7 +5955,7 @@ int ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR addr) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); uint32_t insn; int op6, tmp, i; @@ -5987,7 +5986,7 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache, } else { - printf_unfiltered (_("no syscall record support\n")); + fprintf_unfiltered (gdb_stderr, _("no syscall record support\n")); return -1; } break; @@ -6248,6 +6247,69 @@ UNKNOWN_OP: return 0; } +/* Used for matching tw, twi, td and tdi instructions for POWER. */ + +static constexpr uint32_t TX_INSN_MASK = 0xFC0007FF; +static constexpr uint32_t TW_INSN = 0x7C000008; +static constexpr uint32_t TD_INSN = 0x7C000088; + +static constexpr uint32_t TXI_INSN_MASK = 0xFC000000; +static constexpr uint32_t TWI_INSN = 0x0C000000; +static constexpr uint32_t TDI_INSN = 0x08000000; + +static inline bool +is_tw_insn (uint32_t insn) +{ + return (insn & TX_INSN_MASK) == TW_INSN; +} + +static inline bool +is_twi_insn (uint32_t insn) +{ + return (insn & TXI_INSN_MASK) == TWI_INSN; +} + +static inline bool +is_td_insn (uint32_t insn) +{ + return (insn & TX_INSN_MASK) == TD_INSN; +} + +static inline bool +is_tdi_insn (uint32_t insn) +{ + return (insn & TXI_INSN_MASK) == TDI_INSN; +} + +/* Implementation of gdbarch_program_breakpoint_here_p for POWER. */ + +static bool +rs6000_program_breakpoint_here_p (gdbarch *gdbarch, CORE_ADDR address) +{ + gdb_byte target_mem[PPC_INSN_SIZE]; + + /* Enable the automatic memory restoration from breakpoints while + we read the memory. Otherwise we may find temporary breakpoints, ones + inserted by GDB, and flag them as permanent breakpoints. */ + scoped_restore restore_memory + = make_scoped_restore_show_memory_breakpoints (0); + + if (target_read_memory (address, target_mem, PPC_INSN_SIZE) == 0) + { + uint32_t insn = (uint32_t) extract_unsigned_integer + (target_mem, PPC_INSN_SIZE, gdbarch_byte_order_for_code (gdbarch)); + + /* Check if INSN is a TW, TWI, TD or TDI instruction. There + are multiple choices of such instructions with different registers + and / or immediate values but they all cause a break. */ + if (is_tw_insn (insn) || is_twi_insn (insn) || is_td_insn (insn) + || is_tdi_insn (insn)) + return true; + } + + return false; +} + /* Initialize the current architecture based on INFO. If possible, re-use an architecture from ARCHES, which is a list of architectures already created during this debugging session. @@ -6259,7 +6321,6 @@ static struct gdbarch * rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { struct gdbarch *gdbarch; - struct gdbarch_tdep *tdep; int wordsize, from_xcoff_exec, from_elf_exec; enum bfd_architecture arch; unsigned long mach; @@ -6945,7 +7006,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Word size in the various PowerPC bfd_arch_info structs isn't meaningful, because 64-bit CPUs can run in 32-bit mode. So, perform separate word size check. */ - tdep = gdbarch_tdep (arches->gdbarch); + ppc_gdbarch_tdep *tdep + = (ppc_gdbarch_tdep *) gdbarch_tdep (arches->gdbarch); if (tdep && tdep->elf_abi != elf_abi) continue; if (tdep && tdep->soft_float != soft_float) @@ -6966,7 +7028,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) - "set arch" trust blindly - GDB startup useless but harmless */ - tdep = XCNEW (struct gdbarch_tdep); + ppc_gdbarch_tdep *tdep = new ppc_gdbarch_tdep; tdep->wordsize = wordsize; tdep->elf_abi = elf_abi; tdep->soft_float = soft_float; @@ -7110,6 +7172,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) rs6000_breakpoint::kind_from_pc); set_gdbarch_sw_breakpoint_from_kind (gdbarch, rs6000_breakpoint::bp_from_kind); + set_gdbarch_program_breakpoint_here_p (gdbarch, + rs6000_program_breakpoint_here_p); /* The value of symbols of type N_SO and N_FUN maybe null when it shouldn't be. */ @@ -7245,7 +7309,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) static void rs6000_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch); if (tdep == NULL) return; @@ -7260,7 +7324,6 @@ powerpc_set_soft_float (const char *args, int from_tty, struct gdbarch_info info; /* Update the architecture. */ - gdbarch_info_init (&info); if (!gdbarch_update_p (info)) internal_error (__FILE__, __LINE__, _("could not update architecture")); } @@ -7269,7 +7332,6 @@ static void powerpc_set_vector_abi (const char *args, int from_tty, struct cmd_list_element *c) { - struct gdbarch_info info; int vector_abi; for (vector_abi = POWERPC_VEC_AUTO; @@ -7287,7 +7349,7 @@ powerpc_set_vector_abi (const char *args, int from_tty, powerpc_vector_abi_string); /* Update the architecture. */ - gdbarch_info_init (&info); + gdbarch_info info; if (!gdbarch_update_p (info)) internal_error (__FILE__, __LINE__, _("could not update architecture")); } @@ -7371,6 +7433,14 @@ ppc_insn_ds_field (unsigned int insn) return ((((CORE_ADDR) insn & 0xfffc) ^ 0x8000) - 0x8000); } +CORE_ADDR +ppc_insn_prefix_dform (unsigned int insn1, unsigned int insn2) +{ + /* result is 34-bits */ + return (CORE_ADDR) ((((insn1 & 0x3ffff) ^ 0x20000) - 0x20000) << 16) + | (CORE_ADDR)(insn2 & 0xffff); +} + /* Initialization code. */ void _initialize_rs6000_tdep (); @@ -7403,13 +7473,11 @@ _initialize_rs6000_tdep () /* Add root prefix command for all "set powerpc"/"show powerpc" commands. */ - add_basic_prefix_cmd ("powerpc", no_class, - _("Various PowerPC-specific commands."), - &setpowerpccmdlist, 0, &setlist); - - add_show_prefix_cmd ("powerpc", no_class, - _("Various PowerPC-specific commands."), - &showpowerpccmdlist, 0, &showlist); + add_setshow_prefix_cmd ("powerpc", no_class, + _("Various PowerPC-specific commands."), + _("Various PowerPC-specific commands."), + &setpowerpccmdlist, &showpowerpccmdlist, + &setlist, &showlist); /* Add a command to allow the user to force the ABI. */ add_setshow_auto_boolean_cmd ("soft-float", class_support,