X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Frs6000-tdep.c;h=ce98dc2f88438eb76df8ec2d95986754b1716c12;hb=14aa4ee440f85a0e4d86b7adb50c93bbf0b7fc5b;hp=e875ad953663c2a8c2c05e0637740140d16c3b0d;hpb=6f072a103498fa9b7795782d9fdf1ae226f5565e;p=binutils-gdb.git diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index e875ad95366..ce98dc2f884 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-2019 Free Software Foundation, Inc. + Copyright (C) 1986-2021 Free Software Foundation, Inc. This file is part of GDB. @@ -37,7 +37,7 @@ #include "sim-regno.h" #include "gdb/sim-ppc.h" #include "reggroups.h" -#include "dwarf2-frame.h" +#include "dwarf2/frame.h" #include "target-descriptions.h" #include "user-regs.h" #include "record-full.h" @@ -153,6 +153,23 @@ static const char *const powerpc_vector_strings[] = static enum powerpc_vector_abi powerpc_vector_abi_global = POWERPC_VEC_AUTO; static const char *powerpc_vector_abi_string = "auto"; +/* PowerPC-related per-inferior data. */ + +static inferior_key ppc_inferior_data_key; + +/* Get the per-inferior PowerPC data for INF. */ + +ppc_inferior_data * +get_ppc_per_inferior (inferior *inf) +{ + ppc_inferior_data *per_inf = ppc_inferior_data_key.get (inf); + + if (per_inf == nullptr) + per_inf = ppc_inferior_data_key.emplace (inf); + + return per_inf; +} + /* To be used by skip_prologue. */ struct rs6000_framedata @@ -184,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 @@ -196,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 @@ -208,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)) @@ -240,10 +257,10 @@ 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); + && tdep->ppc_fpscr_regnum >= 0); } /* Return non-zero if the architecture described by GDBARCH has @@ -251,10 +268,10 @@ 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); + && tdep->ppc_vrsave_regnum >= 0); } /* Check that TABLE[GDB_REGNO] is not already initialized, and then @@ -280,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; @@ -302,8 +319,8 @@ init_sim_regno_table (struct gdbarch *arch) if (tdep->ppc_fp0_regnum >= 0) for (i = 0; i < ppc_num_fprs; i++) set_sim_regno (sim_regno, - tdep->ppc_fp0_regnum + i, - sim_ppc_f0_regnum + i); + tdep->ppc_fp0_regnum + i, + sim_ppc_f0_regnum + i); if (tdep->ppc_fpscr_regnum >= 0) set_sim_regno (sim_regno, tdep->ppc_fpscr_regnum, sim_ppc_fpscr_regnum); @@ -325,15 +342,15 @@ init_sim_regno_table (struct gdbarch *arch) if (tdep->ppc_vr0_regnum >= 0) { for (i = 0; i < ppc_num_vrs; i++) - set_sim_regno (sim_regno, - tdep->ppc_vr0_regnum + i, - sim_ppc_vr0_regnum + i); + set_sim_regno (sim_regno, + tdep->ppc_vr0_regnum + i, + sim_ppc_vr0_regnum + i); /* FIXME: jimb/2004-07-15: when we have tdep->ppc_vscr_regnum, - we can treat this more like the other cases. */ + we can treat this more like the other cases. */ set_sim_regno (sim_regno, - tdep->ppc_vr0_regnum + ppc_num_vrs, - sim_ppc_vscr_regnum); + tdep->ppc_vr0_regnum + ppc_num_vrs, + sim_ppc_vscr_regnum); } /* vsave is a special-purpose register, so the code below handles it. */ @@ -341,8 +358,8 @@ init_sim_regno_table (struct gdbarch *arch) if (tdep->ppc_ev0_upper_regnum >= 0) for (i = 0; i < ppc_num_gprs; i++) set_sim_regno (sim_regno, - tdep->ppc_ev0_upper_regnum + i, - sim_ppc_rh0_regnum + i); + tdep->ppc_ev0_upper_regnum + i, + sim_ppc_rh0_regnum + i); if (tdep->ppc_acc_regnum >= 0) set_sim_regno (sim_regno, tdep->ppc_acc_regnum, sim_ppc_acc_regnum); /* spefscr is a special-purpose register, so the code below handles it. */ @@ -374,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) @@ -445,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) @@ -482,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) { @@ -505,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; @@ -555,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) { @@ -595,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; @@ -646,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) { @@ -686,8 +701,8 @@ insn_changes_sp_or_jumps (unsigned long insn) /* Changes the stack pointer. */ /* NOTE: There are many ways to change the value of a given register. - The ways below are those used when the register is R1, the SP, - in a funtion's epilogue. */ + The ways below are those used when the register is R1, the SP, + in a funtion's epilogue. */ if (opcode == 31 && subcode == 444 && a == 1) return 1; /* mr R1,Rn */ @@ -715,23 +730,23 @@ insn_changes_sp_or_jumps (unsigned long insn) 1) scan forward from the point of execution: a) If you find an instruction that modifies the stack pointer - or transfers control (except a return), execution is not in - an epilogue, return. + or transfers control (except a return), execution is not in + an epilogue, return. b) Stop scanning if you find a return instruction or reach the - end of the function or reach the hard limit for the size of - an epilogue. + end of the function or reach the hard limit for the size of + an epilogue. 2) scan backward from the point of execution: - a) If you find an instruction that modifies the stack pointer, - execution *is* in an epilogue, return. - b) Stop scanning if you reach an instruction that transfers - control or the beginning of the function or reach the hard - limit for the size of an epilogue. */ + a) If you find an instruction that modifies the stack pointer, + execution *is* in an epilogue, return. + b) Stop scanning if you reach an instruction that transfers + control or the beginning of the function or reach the hard + limit for the size of an epilogue. */ 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; @@ -752,11 +767,12 @@ rs6000_in_function_epilogue_frame_p (struct frame_info *curfrm, for (scan_pc = pc; scan_pc < epilogue_end; scan_pc += PPC_INSN_SIZE) { - if (!safe_frame_unwind_memory (curfrm, scan_pc, insn_buf, PPC_INSN_SIZE)) - return 0; + if (!safe_frame_unwind_memory (curfrm, scan_pc, + {insn_buf, PPC_INSN_SIZE})) + return 0; insn = extract_unsigned_integer (insn_buf, PPC_INSN_SIZE, byte_order); if (insn == 0x4e800020) - break; + break; /* Assume a bctr is a tail call unless it points strictly within this function. */ if (insn == 0x4e800420) @@ -769,7 +785,7 @@ rs6000_in_function_epilogue_frame_p (struct frame_info *curfrm, break; } if (insn_changes_sp_or_jumps (insn)) - return 0; + return 0; } /* Scan backward until adjustment to stack pointer (R1). */ @@ -778,11 +794,12 @@ rs6000_in_function_epilogue_frame_p (struct frame_info *curfrm, scan_pc >= epilogue_start; scan_pc -= PPC_INSN_SIZE) { - if (!safe_frame_unwind_memory (curfrm, scan_pc, insn_buf, PPC_INSN_SIZE)) - return 0; + if (!safe_frame_unwind_memory (curfrm, scan_pc, + {insn_buf, PPC_INSN_SIZE})) + return 0; insn = extract_unsigned_integer (insn_buf, PPC_INSN_SIZE, byte_order); if (insn_changes_sp_or_jumps (insn)) - return 1; + return 1; } return 0; @@ -807,14 +824,14 @@ 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; /* Instruction masks for displaced stepping. */ -#define BRANCH_MASK 0xfc000000 +#define OP_MASK 0xfc000000 #define BP_MASK 0xFC0007FE #define B_INSN 0x48000000 #define BC_INSN 0x40000000 @@ -836,6 +853,17 @@ typedef BP_MANIPULATION_ENDIAN (little_breakpoint, big_breakpoint) #define STHCX_INSTRUCTION 0x7c0005ad #define STQCX_INSTRUCTION 0x7c00016d +/* Instruction masks for single-stepping of addpcis/lnia. */ +#define ADDPCIS_INSN 0x4c000004 +#define ADDPCIS_INSN_MASK 0xfc00003e +#define ADDPCIS_TARGET_REGISTER 0x03F00000 +#define ADDPCIS_INSN_REGSHIFT 21 + +#define PNOP_MASK 0xfff3ffff +#define PNOP_INSN 0x07000000 +#define R_MASK 0x00100000 +#define R_ZERO 0x00000000 + /* Check if insn is one of the Load And Reserve instructions used for atomic sequences. */ #define IS_LOAD_AND_RESERVE_INSN(insn) ((insn & LOAD_AND_RESERVE_MASK) == LWARX_INSTRUCTION \ @@ -851,79 +879,124 @@ typedef BP_MANIPULATION_ENDIAN (little_breakpoint, big_breakpoint) || (insn & STORE_CONDITIONAL_MASK) == STHCX_INSTRUCTION \ || (insn & STORE_CONDITIONAL_MASK) == STQCX_INSTRUCTION) -typedef buf_displaced_step_closure ppc_displaced_step_closure; +typedef buf_displaced_step_copy_insn_closure + ppc_displaced_step_copy_insn_closure; /* We can't displaced step atomic sequences. */ -static struct displaced_step_closure * +static displaced_step_copy_insn_closure_up ppc_displaced_step_copy_insn (struct gdbarch *gdbarch, CORE_ADDR from, CORE_ADDR to, struct regcache *regs) { size_t len = gdbarch_max_insn_length (gdbarch); - std::unique_ptr closure - (new ppc_displaced_step_closure (len)); + std::unique_ptr closure + (new ppc_displaced_step_copy_insn_closure (len)); gdb_byte *buf = closure->buf.data (); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int insn; - read_memory (from, buf, len); + len = target_read (current_inferior()->top_target(), TARGET_OBJECT_MEMORY, NULL, + buf, from, len); + if ((ssize_t) len < PPC_INSN_SIZE) + memory_error (TARGET_XFER_E_IO, from); insn = extract_signed_integer (buf, PPC_INSN_SIZE, byte_order); + /* Check for PNOP and for prefixed instructions with R=0. Those + instructions are safe to displace. Prefixed instructions with R=1 + will read/write data to/from locations relative to the current PC. + We would not be able to fixup after an instruction has written data + into a displaced location, so decline to displace those instructions. */ + if ((insn & OP_MASK) == 1 << 26) + { + if (((insn & PNOP_MASK) != PNOP_INSN) + && ((insn & R_MASK) != R_ZERO)) + { + displaced_debug_printf ("Not displacing prefixed instruction %08x at %s", + insn, paddress (gdbarch, from)); + return NULL; + } + } + else + /* Non-prefixed instructions.. */ + { + /* Set the instruction length to 4 to match the actual instruction + length. */ + len = 4; + } + /* Assume all atomic sequences start with a Load and Reserve instruction. */ if (IS_LOAD_AND_RESERVE_INSN (insn)) { - if (debug_displaced) - { - fprintf_unfiltered (gdb_stdlog, - "displaced: can't displaced step " - "atomic sequence at %s\n", + displaced_debug_printf ("can't displaced step atomic sequence at %s", paddress (gdbarch, from)); - } return NULL; } write_memory (to, buf, len); - if (debug_displaced) - { - fprintf_unfiltered (gdb_stdlog, "displaced: copy %s->%s: ", - paddress (gdbarch, from), paddress (gdbarch, to)); - displaced_step_dump_bytes (gdb_stdlog, buf, len); - } + displaced_debug_printf ("copy %s->%s: %s", + paddress (gdbarch, from), paddress (gdbarch, to), + displaced_step_dump_bytes (buf, len).c_str ()); - return closure.release (); + /* This is a work around for a problem with g++ 4.8. */ + return displaced_step_copy_insn_closure_up (closure.release ()); } /* Fix up the state of registers and memory after having single-stepped a displaced instruction. */ static void ppc_displaced_step_fixup (struct gdbarch *gdbarch, - struct displaced_step_closure *closure_, + struct displaced_step_copy_insn_closure *closure_, CORE_ADDR from, CORE_ADDR to, struct regcache *regs) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* Our closure is a copy of the instruction. */ - ppc_displaced_step_closure *closure = (ppc_displaced_step_closure *) closure_; + ppc_displaced_step_copy_insn_closure *closure + = (ppc_displaced_step_copy_insn_closure *) closure_; ULONGEST insn = extract_unsigned_integer (closure->buf.data (), PPC_INSN_SIZE, byte_order); - ULONGEST opcode = 0; + ULONGEST opcode; /* Offset for non PC-relative instructions. */ - LONGEST offset = PPC_INSN_SIZE; - - opcode = insn & BRANCH_MASK; - - if (debug_displaced) - fprintf_unfiltered (gdb_stdlog, - "displaced: (ppc) fixup (%s, %s)\n", - paddress (gdbarch, from), paddress (gdbarch, to)); + LONGEST offset; + opcode = insn & OP_MASK; + /* Set offset to 8 if this is an 8-byte (prefixed) instruction. */ + if ((opcode) == 1 << 26) + offset = 2 * PPC_INSN_SIZE; + else + offset = PPC_INSN_SIZE; + + displaced_debug_printf ("(ppc) fixup (%s, %s)", + paddress (gdbarch, from), paddress (gdbarch, to)); + + /* Handle the addpcis/lnia instruction. */ + if ((insn & ADDPCIS_INSN_MASK) == ADDPCIS_INSN) + { + LONGEST displaced_offset; + ULONGEST current_val; + /* Measure the displacement. */ + displaced_offset = from - to; + /* Identify the target register that was updated by the instruction. */ + int regnum = (insn & ADDPCIS_TARGET_REGISTER) >> ADDPCIS_INSN_REGSHIFT; + /* Read and update the target value. */ + regcache_cooked_read_unsigned (regs, regnum , ¤t_val); + displaced_debug_printf ("addpcis target regnum %d was %s now %s", + regnum, paddress (gdbarch, current_val), + paddress (gdbarch, current_val + + displaced_offset)); + regcache_cooked_write_unsigned (regs, regnum, + current_val + displaced_offset); + /* point the PC back at the non-displaced instruction. */ + regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch), + from + offset); + } /* Handle PC-relative branch instructions. */ - if (opcode == B_INSN || opcode == BC_INSN || opcode == BXL_INSN) + else if (opcode == B_INSN || opcode == BC_INSN || opcode == BXL_INSN) { ULONGEST current_pc; @@ -941,13 +1014,11 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch, if (!(insn & 0x2)) { /* PC-relative addressing is being used in the branch. */ - if (debug_displaced) - fprintf_unfiltered - (gdb_stdlog, - "displaced: (ppc) branch instruction: %s\n" - "displaced: (ppc) adjusted PC from %s to %s\n", - paddress (gdbarch, insn), paddress (gdbarch, current_pc), - paddress (gdbarch, from + offset)); + displaced_debug_printf ("(ppc) branch instruction: %s", + paddress (gdbarch, insn)); + displaced_debug_printf ("(ppc) adjusted PC from %s to %s", + paddress (gdbarch, current_pc), + paddress (gdbarch, from + offset)); regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch), @@ -971,13 +1042,12 @@ 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); - if (debug_displaced) - fprintf_unfiltered (gdb_stdlog, - "displaced: (ppc) adjusted LR to %s\n", - paddress (gdbarch, from + PPC_INSN_SIZE)); + displaced_debug_printf ("(ppc) adjusted LR to %s", + paddress (gdbarch, from + PPC_INSN_SIZE)); } } @@ -986,18 +1056,67 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch, else if ((insn & BP_MASK) == BP_INSN) regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch), from); else - /* Handle any other instructions that do not fit in the categories above. */ - regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch), - from + offset); + { + /* Handle any other instructions that do not fit in the categories + above. */ + regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch), + from + offset); + } +} + +/* Implementation of gdbarch_displaced_step_prepare. */ + +static displaced_step_prepare_status +ppc_displaced_step_prepare (gdbarch *arch, thread_info *thread, + CORE_ADDR &displaced_pc) +{ + ppc_inferior_data *per_inferior = get_ppc_per_inferior (thread->inf); + + if (!per_inferior->disp_step_buf.has_value ()) + { + /* Figure out where the displaced step buffer is. */ + CORE_ADDR disp_step_buf_addr + = displaced_step_at_entry_point (thread->inf->gdbarch); + + per_inferior->disp_step_buf.emplace (disp_step_buf_addr); + } + + return per_inferior->disp_step_buf->prepare (thread, displaced_pc); +} + +/* Implementation of gdbarch_displaced_step_finish. */ + +static displaced_step_finish_status +ppc_displaced_step_finish (gdbarch *arch, thread_info *thread, + gdb_signal sig) +{ + ppc_inferior_data *per_inferior = get_ppc_per_inferior (thread->inf); + + gdb_assert (per_inferior->disp_step_buf.has_value ()); + + return per_inferior->disp_step_buf->finish (arch, thread, sig); +} + +/* Implementation of gdbarch_displaced_step_restore_all_in_ptid. */ + +static void +ppc_displaced_step_restore_all_in_ptid (inferior *parent_inf, ptid_t ptid) +{ + ppc_inferior_data *per_inferior = ppc_inferior_data_key.get (parent_inf); + + if (per_inferior == nullptr + || !per_inferior->disp_step_buf.has_value ()) + return; + + per_inferior->disp_step_buf->restore_in_ptid (ptid); } /* Always use hardware single-stepping to execute the displaced instruction. */ -static int -ppc_displaced_step_hw_singlestep (struct gdbarch *gdbarch, - struct displaced_step_closure *closure) +static bool +ppc_displaced_step_hw_singlestep (struct gdbarch *gdbarch) { - return 1; + return true; } /* Checks for an atomic sequence of instructions beginning with a @@ -1028,20 +1147,23 @@ ppc_deal_with_atomic_sequence (struct regcache *regcache) instructions. */ for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count) { - loc += PPC_INSN_SIZE; + if ((insn & OP_MASK) == 1 << 26) + loc += 2 * PPC_INSN_SIZE; + else + loc += PPC_INSN_SIZE; insn = read_memory_integer (loc, PPC_INSN_SIZE, byte_order); /* Assume that there is at most one conditional branch in the atomic - sequence. If a conditional branch is found, put a breakpoint in - its destination address. */ - if ((insn & BRANCH_MASK) == BC_INSN) - { - int immediate = ((insn & 0xfffc) ^ 0x8000) - 0x8000; - int absolute = insn & 2; - - if (bc_insn_count >= 1) - return {}; /* More than one conditional branch found, fallback - to the standard single-step code. */ + sequence. If a conditional branch is found, put a breakpoint in + its destination address. */ + if ((insn & OP_MASK) == BC_INSN) + { + int immediate = ((insn & 0xfffc) ^ 0x8000) - 0x8000; + int absolute = insn & 2; + + if (bc_insn_count >= 1) + return {}; /* More than one conditional branch found, fallback + to the standard single-step code. */ if (absolute) breaks[1] = immediate; @@ -1050,10 +1172,10 @@ ppc_deal_with_atomic_sequence (struct regcache *regcache) bc_insn_count++; last_breakpoint++; - } + } if (IS_STORE_CONDITIONAL_INSN (insn)) - break; + break; } /* Assume that the atomic sequence ends with a Store Conditional @@ -1111,12 +1233,12 @@ store_param_on_stack_p (unsigned long op, int framep, int *r0_contains_arg) const int ry_regno = GET_SRC_REG (op); if (rx_regno == 0 && ry_regno >= 3 && ry_regno <= 10) - { - *r0_contains_arg = 1; - return 1; - } + { + *r0_contains_arg = 1; + return 1; + } else - return 0; + return 0; } /* Save a General Purpose Register on stack. */ @@ -1129,7 +1251,7 @@ store_param_on_stack_p (unsigned long op, int framep, int *r0_contains_arg) return (rx_regno >= 3 && rx_regno <= 10); } - + /* Save a General Purpose Register on stack via the Frame Pointer. */ if (framep && @@ -1138,11 +1260,11 @@ store_param_on_stack_p (unsigned long op, int framep, int *r0_contains_arg) (op & 0xfc1f0000) == 0xd81f0000)) /* stfd Rx,NUM(r31) */ { /* Rx: Usually, only r3 - r10 are used for parameter passing. - However, the compiler sometimes uses r0 to hold an argument. */ + However, the compiler sometimes uses r0 to hold an argument. */ const int rx_regno = GET_SRC_REG (op); return ((rx_regno >= 3 && rx_regno <= 10) - || (rx_regno == 0 && *r0_contains_arg)); + || (rx_regno == 0 && *r0_contains_arg)); } if ((op & 0xfc1f0000) == 0xfc010000) /* frsp, fp?,NUM(r1) */ @@ -1234,7 +1356,7 @@ store_insn_p (unsigned long op, unsigned long rs, this masking operation is equal to BL_INSTRUCTION, then the opcode in question is a ``bl'' instruction. - BL_DISPLACMENT_MASK is anded with the opcode in order to extract + BL_DISPLACEMENT_MASK is anded with the opcode in order to extract the branch displacement. */ #define BL_MASK 0xfc000001 @@ -1268,150 +1390,150 @@ rs6000_skip_stack_check (struct gdbarch *gdbarch, const CORE_ADDR start_pc) unsigned long op = rs6000_fetch_instruction (gdbarch, pc); /* First possible sequence: A small number of probes. - stw 0, -(1) - [repeat this instruction any (small) number of times]. */ + stw 0, -(1) + [repeat this instruction any (small) number of times]. */ if ((op & 0xffff0000) == 0x90010000) { while ((op & 0xffff0000) == 0x90010000) - { - pc = pc + 4; - op = rs6000_fetch_instruction (gdbarch, pc); - } + { + pc = pc + 4; + op = rs6000_fetch_instruction (gdbarch, pc); + } return pc; } /* Second sequence: A probing loop. - addi 12,1,- - lis 0,- - [possibly ori 0,0,] - add 0,12,0 - cmpw 0,12,0 - beq 0, - addi 12,12,- - stw 0,0(12) - b - [possibly one last probe: stw 0,(12)]. */ + addi 12,1,- + lis 0,- + [possibly ori 0,0,] + add 0,12,0 + cmpw 0,12,0 + beq 0, + addi 12,12,- + stw 0,0(12) + b + [possibly one last probe: stw 0,(12)]. */ while (1) { /* addi 12,1,- */ if ((op & 0xffff0000) != 0x39810000) - break; + break; /* lis 0,- */ pc = pc + 4; op = rs6000_fetch_instruction (gdbarch, pc); if ((op & 0xffff0000) != 0x3c000000) - break; + break; pc = pc + 4; op = rs6000_fetch_instruction (gdbarch, pc); /* [possibly ori 0,0,] */ if ((op & 0xffff0000) == 0x60000000) - { - pc = pc + 4; - op = rs6000_fetch_instruction (gdbarch, pc); - } + { + pc = pc + 4; + op = rs6000_fetch_instruction (gdbarch, pc); + } /* add 0,12,0 */ if (op != 0x7c0c0214) - break; + break; /* cmpw 0,12,0 */ pc = pc + 4; op = rs6000_fetch_instruction (gdbarch, pc); if (op != 0x7c0c0000) - break; + break; /* beq 0, */ pc = pc + 4; op = rs6000_fetch_instruction (gdbarch, pc); if ((op & 0xff9f0001) != 0x41820000) - break; + break; /* addi 12,12,- */ pc = pc + 4; op = rs6000_fetch_instruction (gdbarch, pc); if ((op & 0xffff0000) != 0x398c0000) - break; + break; /* stw 0,0(12) */ pc = pc + 4; op = rs6000_fetch_instruction (gdbarch, pc); if (op != 0x900c0000) - break; + break; /* b */ pc = pc + 4; op = rs6000_fetch_instruction (gdbarch, pc); if ((op & 0xfc000001) != 0x48000000) - break; + break; /* [possibly one last probe: stw 0,(12)]. */ pc = pc + 4; op = rs6000_fetch_instruction (gdbarch, pc); if ((op & 0xffff0000) == 0x900c0000) - { - pc = pc + 4; - op = rs6000_fetch_instruction (gdbarch, pc); - } + { + pc = pc + 4; + op = rs6000_fetch_instruction (gdbarch, pc); + } /* We found a valid stack-check sequence, return the new PC. */ return pc; } - /* Third sequence: No probe; instead, a comparizon between the stack size + /* Third sequence: No probe; instead, a comparison between the stack size limit (saved in a run-time global variable) and the current stack pointer: - addi 0,1,- - lis 12,__gnat_stack_limit@ha - lwz 12,__gnat_stack_limit@l(12) - twllt 0,12 + addi 0,1,- + lis 12,__gnat_stack_limit@ha + lwz 12,__gnat_stack_limit@l(12) + twllt 0,12 or, with a small variant in the case of a bigger stack frame: - addis 0,1, - addic 0,0,- - lis 12,__gnat_stack_limit@ha - lwz 12,__gnat_stack_limit@l(12) - twllt 0,12 + addis 0,1, + addic 0,0,- + lis 12,__gnat_stack_limit@ha + lwz 12,__gnat_stack_limit@l(12) + twllt 0,12 */ while (1) { /* addi 0,1,- */ if ((op & 0xffff0000) != 0x38010000) - { - /* small stack frame variant not recognized; try the - big stack frame variant: */ + { + /* small stack frame variant not recognized; try the + big stack frame variant: */ - /* addis 0,1, */ - if ((op & 0xffff0000) != 0x3c010000) - break; + /* addis 0,1, */ + if ((op & 0xffff0000) != 0x3c010000) + break; - /* addic 0,0,- */ - pc = pc + 4; - op = rs6000_fetch_instruction (gdbarch, pc); - if ((op & 0xffff0000) != 0x30000000) - break; - } + /* addic 0,0,- */ + pc = pc + 4; + op = rs6000_fetch_instruction (gdbarch, pc); + if ((op & 0xffff0000) != 0x30000000) + break; + } /* lis 12, */ pc = pc + 4; op = rs6000_fetch_instruction (gdbarch, pc); if ((op & 0xffff0000) != 0x3d800000) - break; + break; /* lwz 12,(12) */ pc = pc + 4; op = rs6000_fetch_instruction (gdbarch, pc); if ((op & 0xffff0000) != 0x818c0000) - break; + break; /* twllt 0,12 */ pc = pc + 4; op = rs6000_fetch_instruction (gdbarch, pc); if ((op & 0xfffffffe) != 0x7c406008) - break; + break; /* We found a valid stack-check sequence, return the new PC. */ return pc; @@ -1468,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)); @@ -1488,7 +1610,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, for (;; pc += 4) { /* Sometimes it isn't clear if an instruction is a prologue - instruction or not. When we encounter one of these ambiguous + instruction or not. When we encounter one of these ambiguous cases, we'll set prev_insn_was_prologue_insn to 0 (false). Otherwise, we'll assume that it really is a prologue instruction. */ if (prev_insn_was_prologue_insn) @@ -1526,15 +1648,15 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, ones. */ if (lr_reg == -1) lr_reg = (op & 0x03e00000) >> 21; - if (lr_reg == 0) - r0_contains_arg = 0; + if (lr_reg == 0) + r0_contains_arg = 0; continue; } else if ((op & 0xfc1fffff) == 0x7c000026) { /* mfcr Rx */ cr_reg = (op & 0x03e00000) >> 21; - if (cr_reg == 0) - r0_contains_arg = 0; + if (cr_reg == 0) + r0_contains_arg = 0; continue; } @@ -1583,7 +1705,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, continue; } else if (op == 0x60000000) - { + { /* nop */ /* Allow nops in the prologue, but do not consider them to be part of the prologue unless followed by other prologue @@ -1596,7 +1718,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, { /* addis 0,0,NUM, used for >= 32k frames */ fdata->offset = (op & 0x0000ffff) << 16; fdata->frameless = 0; - r0_contains_arg = 0; + r0_contains_arg = 0; continue; } @@ -1604,7 +1726,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, { /* ori 0,0,NUM, 2nd half of >= 32k frames */ fdata->offset |= (op & 0x0000ffff); fdata->frameless = 0; - r0_contains_arg = 0; + r0_contains_arg = 0; continue; } @@ -1683,7 +1805,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, /* If the return address has already been saved, we can skip calls to blrl (for PIC). */ - if (lr_reg != -1 && bl_to_blrl_insn_p (pc, op, byte_order)) + if (lr_reg != -1 && bl_to_blrl_insn_p (pc, op, byte_order)) { fdata->used_bl = 1; continue; @@ -1741,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,... */ @@ -1758,12 +1880,12 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, continue; /* move parameters from argument registers to local variable - registers */ - } + registers */ + } else if ((op & 0xfc0007fe) == 0x7c000378 && /* mr(.) Rx,Ry */ - (((op >> 21) & 31) >= 3) && /* R3 >= Ry >= R10 */ - (((op >> 21) & 31) <= 10) && - ((long) ((op >> 16) & 31) + (((op >> 21) & 31) >= 3) && /* R3 >= Ry >= R10 */ + (((op >> 21) & 31) <= 10) && + ((long) ((op >> 16) & 31) >= fdata->saved_gpr)) /* Rx: local var reg */ { continue; @@ -1772,7 +1894,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, } /* Move parameters from argument registers to temporary register. */ else if (store_param_on_stack_p (op, framep, &r0_contains_arg)) - { + { continue; /* Set up frame pointer */ @@ -1817,28 +1939,28 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, mtspr SPR256 Rn == 011111 nnnnn 0000001000 01110100110 */ else if ((op & 0xfc1fffff) == 0x7c0042a6) /* mfvrsave Rn */ { - vrsave_reg = GET_SRC_REG (op); + vrsave_reg = GET_SRC_REG (op); continue; } else if ((op & 0xfc1fffff) == 0x7c0043a6) /* mtvrsave Rn */ - { - continue; - } + { + continue; + } /* Store the register where vrsave was saved to onto the stack: - rS is the register where vrsave was stored in a previous + rS is the register where vrsave was stored in a previous instruction. */ /* 100100 sssss 00001 dddddddd dddddddd */ else if ((op & 0xfc1f0000) == 0x90010000) /* stw rS, d(r1) */ - { - if (vrsave_reg == GET_SRC_REG (op)) + { + if (vrsave_reg == GET_SRC_REG (op)) { fdata->vrsave_offset = SIGNED_SHORT (op) + offset; vrsave_reg = -1; } - continue; - } + continue; + } /* Compute the new value of vrsave, by modifying the register - where vrsave was saved to. */ + where vrsave was saved to. */ else if (((op & 0xfc000000) == 0x64000000) /* oris Ra, Rs, UIMM */ || ((op & 0xfc000000) == 0x60000000))/* ori Ra, Rs, UIMM */ { @@ -1850,22 +1972,22 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, /* 001110 00000 00000 iiii iiii iiii iiii */ /* 001110 01110 00000 iiii iiii iiii iiii */ else if ((op & 0xffff0000) == 0x38000000 /* li r0, SIMM */ - || (op & 0xffff0000) == 0x39c00000) /* li r14, SIMM */ + || (op & 0xffff0000) == 0x39c00000) /* li r14, SIMM */ { - if ((op & 0xffff0000) == 0x38000000) - r0_contains_arg = 0; + if ((op & 0xffff0000) == 0x38000000) + r0_contains_arg = 0; li_found_pc = pc; vr_saved_offset = SIGNED_SHORT (op); - /* This insn by itself is not part of the prologue, unless - if part of the pair of insns mentioned above. So do not - record this insn as part of the prologue yet. */ - prev_insn_was_prologue_insn = 0; + /* This insn by itself is not part of the prologue, unless + if part of the pair of insns mentioned above. So do not + record this insn as part of the prologue yet. */ + prev_insn_was_prologue_insn = 0; } /* Store vector register S at (r31+r0) aligned to 16 bytes. */ /* 011111 sssss 11111 00000 00111001110 */ else if ((op & 0xfc1fffff) == 0x7c1f01ce) /* stvx Vs, R31, R0 */ - { + { if (pc == (li_found_pc + 4)) { vr_reg = GET_SRC_REG (op); @@ -1886,16 +2008,16 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, /* Start BookE related instructions. */ /* Store gen register S at (r31+uimm). - Any register less than r13 is volatile, so we don't care. */ + Any register less than r13 is volatile, so we don't care. */ /* 000100 sssss 11111 iiiii 01100100001 */ else if (arch_info->mach == bfd_mach_ppc_e500 && (op & 0xfc1f07ff) == 0x101f0321) /* evstdd Rs,uimm(R31) */ { - if ((op & 0x03e00000) >= 0x01a00000) /* Rs >= r13 */ + if ((op & 0x03e00000) >= 0x01a00000) /* Rs >= r13 */ { - unsigned int imm; + unsigned int imm; ev_reg = GET_SRC_REG (op); - imm = (op >> 11) & 0x1f; + imm = (op >> 11) & 0x1f; ev_offset = imm * 8; /* If this is the first vector reg to be saved, or if it has a lower number than others previously seen, @@ -1906,40 +2028,40 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, fdata->ev_offset = ev_offset + offset; } } - continue; - } + continue; + } /* Store gen register rS at (r1+rB). */ /* 000100 sssss 00001 bbbbb 01100100000 */ else if (arch_info->mach == bfd_mach_ppc_e500 && (op & 0xffe007ff) == 0x13e00320) /* evstddx RS,R1,Rb */ { - if (pc == (li_found_pc + 4)) - { - ev_reg = GET_SRC_REG (op); + if (pc == (li_found_pc + 4)) + { + ev_reg = GET_SRC_REG (op); /* If this is the first vector reg to be saved, or if - it has a lower number than others previously seen, - reupdate the frame info. */ - /* We know the contents of rB from the previous instruction. */ + it has a lower number than others previously seen, + reupdate the frame info. */ + /* We know the contents of rB from the previous instruction. */ if (fdata->saved_ev == -1 || fdata->saved_ev > ev_reg) { - fdata->saved_ev = ev_reg; - fdata->ev_offset = vr_saved_offset + offset; + fdata->saved_ev = ev_reg; + fdata->ev_offset = vr_saved_offset + offset; } vr_saved_offset = -1; ev_reg = -1; li_found_pc = 0; - } - continue; - } + } + continue; + } /* Store gen register r31 at (rA+uimm). */ /* 000100 11111 aaaaa iiiii 01100100001 */ else if (arch_info->mach == bfd_mach_ppc_e500 && (op & 0xffe007ff) == 0x13e00321) /* evstdd R31,Ra,UIMM */ - { - /* Wwe know that the source register is 31 already, but - it can't hurt to compute it. */ + { + /* Wwe know that the source register is 31 already, but + it can't hurt to compute it. */ ev_reg = GET_SRC_REG (op); - ev_offset = ((op >> 11) & 0x1f) * 8; + ev_offset = ((op >> 11) & 0x1f) * 8; /* If this is the first vector reg to be saved, or if it has a lower number than others previously seen, reupdate the frame info. */ @@ -1950,23 +2072,23 @@ 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. */ + Store param on stack when offset from SP bigger than 4 bytes. */ /* 000100 sssss 11111 00000 01100100000 */ else if (arch_info->mach == bfd_mach_ppc_e500 && (op & 0xfc1fffff) == 0x101f0320) /* evstddx Rs,R31,R0 */ { - if (pc == (li_found_pc + 4)) - { - if ((op & 0x03e00000) >= 0x01a00000) + if (pc == (li_found_pc + 4)) + { + if ((op & 0x03e00000) >= 0x01a00000) { ev_reg = GET_SRC_REG (op); /* If this is the first vector reg to be saved, or if it has a lower number than others previously seen, reupdate the frame info. */ - /* We know the contents of r0 from the previous - instruction. */ + /* We know the contents of r0 from the previous + instruction. */ if (fdata->saved_ev == -1 || fdata->saved_ev > ev_reg) { fdata->saved_ev = ev_reg; @@ -1977,7 +2099,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, vr_saved_offset = -1; li_found_pc = 0; continue; - } + } } /* End BookE related instructions. */ @@ -2006,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. */ @@ -2116,12 +2244,12 @@ rs6000_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) struct bound_minimal_symbol s = lookup_minimal_symbol_by_pc (call_dest); /* We check for ___eabi (three leading underscores) in addition - to __eabi in case the GCC option "-fleading-underscore" was + to __eabi in case the GCC option "-fleading-underscore" was used to compile the program. */ if (s.minsym != NULL - && MSYMBOL_LINKAGE_NAME (s.minsym) != NULL - && (strcmp (MSYMBOL_LINKAGE_NAME (s.minsym), "__eabi") == 0 - || strcmp (MSYMBOL_LINKAGE_NAME (s.minsym), "___eabi") == 0)) + && s.minsym->linkage_name () != NULL + && (strcmp (s.minsym->linkage_name (), "__eabi") == 0 + || strcmp (s.minsym->linkage_name (), "___eabi") == 0)) pc += 4; } return pc; @@ -2182,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; @@ -2205,7 +2333,7 @@ rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) msymbol = lookup_minimal_symbol_by_pc (pc); if (msymbol.minsym && rs6000_in_solib_return_trampoline (gdbarch, pc, - MSYMBOL_LINKAGE_NAME (msymbol.minsym))) + msymbol.minsym->linkage_name ())) { /* Double-check that the third instruction from PC is relative "b". */ op = read_memory_integer (pc + 8, 4, byte_order); @@ -2240,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) { @@ -2272,8 +2400,8 @@ rs6000_builtin_type_vec64 (struct gdbarch *gdbarch) append_composite_type_field (t, "v8_int8", init_vector_type (bt->builtin_int8, 8)); - TYPE_VECTOR (t) = 1; - TYPE_NAME (t) = "ppc_builtin_type_vec64"; + t->set_is_vector (true); + t->set_name ("ppc_builtin_type_vec64"); tdep->ppc_builtin_type_vec64 = t; } @@ -2285,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) { @@ -2294,6 +2422,7 @@ rs6000_builtin_type_vec128 (struct gdbarch *gdbarch) /* The type we're building is this type = union __ppc_builtin_type_vec128 { + float128_t float128; uint128_t uint128; double v2_double[2]; float v4_float[4]; @@ -2303,10 +2432,15 @@ rs6000_builtin_type_vec128 (struct gdbarch *gdbarch) } */ + /* PPC specific type for IEEE 128-bit float field */ + struct type *t_float128 + = arch_float_type (gdbarch, 128, "float128_t", floatformats_ia64_quad); + struct type *t; t = arch_composite_type (gdbarch, "__ppc_builtin_type_vec128", TYPE_CODE_UNION); + append_composite_type_field (t, "float128", t_float128); append_composite_type_field (t, "uint128", bt->builtin_uint128); append_composite_type_field (t, "v2_double", init_vector_type (bt->builtin_double, 2)); @@ -2319,8 +2453,8 @@ rs6000_builtin_type_vec128 (struct gdbarch *gdbarch) append_composite_type_field (t, "v16_int8", init_vector_type (bt->builtin_int8, 16)); - TYPE_VECTOR (t) = 1; - TYPE_NAME (t) = "ppc_builtin_type_vec128"; + t->set_is_vector (true); + t->set_name ("ppc_builtin_type_vec128"); tdep->ppc_builtin_type_vec128 = t; } @@ -2333,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 @@ -2471,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)) @@ -2510,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; @@ -2525,31 +2659,33 @@ 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 && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs - && TYPE_CODE (type) == TYPE_CODE_FLT + && type->code () == TYPE_CODE_FLT && TYPE_LENGTH (type) != TYPE_LENGTH (builtin_type (gdbarch)->builtin_double)); } static int rs6000_register_to_value (struct frame_info *frame, - int regnum, - struct type *type, - gdb_byte *to, + int regnum, + struct type *type, + gdb_byte *to, int *optimizedp, int *unavailablep) { struct gdbarch *gdbarch = get_frame_arch (frame); gdb_byte from[PPC_MAX_REGISTER_SIZE]; - gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT); + gdb_assert (type->code () == TYPE_CODE_FLT); if (!get_frame_register_bytes (frame, regnum, 0, - register_size (gdbarch, regnum), - from, optimizedp, unavailablep)) + gdb::make_array_view (from, + register_size (gdbarch, + regnum)), + optimizedp, unavailablep)) return 0; target_float_convert (from, builtin_type (gdbarch)->builtin_double, @@ -2560,14 +2696,14 @@ rs6000_register_to_value (struct frame_info *frame, static void rs6000_value_to_register (struct frame_info *frame, - int regnum, - struct type *type, - const gdb_byte *from) + int regnum, + struct type *type, + const gdb_byte *from) { struct gdbarch *gdbarch = get_frame_arch (frame); gdb_byte to[PPC_MAX_REGISTER_SIZE]; - gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT); + gdb_assert (type->code () == TYPE_CODE_FLT); target_float_convert (from, type, to, builtin_type (gdbarch)->builtin_double); @@ -2608,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; @@ -2649,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; @@ -2690,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; @@ -2730,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)) @@ -2767,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 @@ -2782,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 @@ -2794,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; @@ -2842,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)) @@ -2884,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)) @@ -2913,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; @@ -2949,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); @@ -2980,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); @@ -3011,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)) @@ -3038,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 @@ -3052,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)) @@ -3090,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)) @@ -3113,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; @@ -3153,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; @@ -3164,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; @@ -3181,23 +3317,23 @@ rs6000_stab_reg_to_regnum (struct gdbarch *gdbarch, int num) switch (num) { case 64: - return tdep->ppc_mq_regnum; + return tdep->ppc_mq_regnum; case 65: - return tdep->ppc_lr_regnum; + return tdep->ppc_lr_regnum; case 66: - return tdep->ppc_ctr_regnum; + return tdep->ppc_ctr_regnum; case 76: - return tdep->ppc_xer_regnum; + return tdep->ppc_xer_regnum; case 109: - return tdep->ppc_vrsave_regnum; + return tdep->ppc_vrsave_regnum; case 110: - return tdep->ppc_vrsave_regnum - 1; /* vscr */ + return tdep->ppc_vrsave_regnum - 1; /* vscr */ case 111: - return tdep->ppc_acc_regnum; + return tdep->ppc_acc_regnum; case 112: - return tdep->ppc_spefscr_regnum; + return tdep->ppc_spefscr_regnum; default: - return num; + return num; } } @@ -3206,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; @@ -3225,24 +3361,25 @@ rs6000_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int num) case 64: return tdep->ppc_cr_regnum; case 67: - return tdep->ppc_vrsave_regnum - 1; /* vscr */ + return tdep->ppc_vrsave_regnum - 1; /* vscr */ case 99: - return tdep->ppc_acc_regnum; + return tdep->ppc_acc_regnum; case 100: - return tdep->ppc_mq_regnum; + return tdep->ppc_mq_regnum; case 101: - return tdep->ppc_xer_regnum; + return tdep->ppc_xer_regnum; case 108: - return tdep->ppc_lr_regnum; + return tdep->ppc_lr_regnum; case 109: - return tdep->ppc_ctr_regnum; + return tdep->ppc_ctr_regnum; case 356: - return tdep->ppc_vrsave_regnum; + return tdep->ppc_vrsave_regnum; case 612: - return tdep->ppc_spefscr_regnum; - default: - return num; + return tdep->ppc_spefscr_regnum; } + + /* Unknown DWARF register number. */ + return -1; } /* Translate a .eh_frame register to DWARF register, or adjust a @@ -3314,7 +3451,7 @@ rs6000_adjust_frame_regnum (struct gdbarch *gdbarch, int num, int eh_frame_p) /* Information about a particular processor variant. */ -struct variant +struct ppc_variant { /* Name of this variant. */ const char *name; @@ -3332,7 +3469,7 @@ struct variant struct target_desc **tdesc; }; -static struct variant variants[] = +static struct ppc_variant variants[] = { {"powerpc", "PowerPC user-level", bfd_arch_powerpc, bfd_mach_ppc, &tdesc_powerpc_altivec32}, @@ -3391,10 +3528,10 @@ static struct variant variants[] = /* Return the variant corresponding to architecture ARCH and machine number MACH. If no such variant exists, return null. */ -static const struct variant * +static const struct ppc_variant * find_variant_by_arch (enum bfd_architecture arch, unsigned long mach) { - const struct variant *v; + const struct ppc_variant *v; for (v = variants; v->name; v++) if (arch == v->arch && mach == v->mach) @@ -3404,26 +3541,12 @@ find_variant_by_arch (enum bfd_architecture arch, unsigned long mach) } -static CORE_ADDR -rs6000_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) -{ - return frame_unwind_register_unsigned (next_frame, - gdbarch_pc_regnum (gdbarch)); -} - -static struct frame_id -rs6000_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame) -{ - return frame_id_build (get_frame_register_unsigned - (this_frame, gdbarch_sp_regnum (gdbarch)), - get_frame_pc (this_frame)); -} struct rs6000_frame_cache { CORE_ADDR base; CORE_ADDR initial_sp; - struct trad_frame_saved_reg *saved_regs; + trad_frame_saved_reg *saved_regs; /* Set BASE_P to true if this frame cache is properly initialized. Otherwise set to false because some registers or memory cannot @@ -3438,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; @@ -3451,7 +3574,7 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) cache->pc = 0; cache->saved_regs = trad_frame_alloc_saved_regs (this_frame); - TRY + try { func = get_frame_func (this_frame); cache->pc = func; @@ -3468,13 +3591,12 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) cache->base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch)); } - CATCH (ex, RETURN_MASK_ERROR) + catch (const gdb_exception_error &ex) { if (ex.error != NOT_AVAILABLE_ERROR) - throw_exception (ex); + throw; return (struct rs6000_frame_cache *) (*this_cache); } - END_CATCH /* If the function appears to be frameless, check a couple of likely indicators that we have simply failed to find the frame setup. @@ -3514,11 +3636,10 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) if (safe_read_memory_unsigned_integer (cache->base, wordsize, byte_order, &backchain)) - cache->base = (CORE_ADDR) backchain; + cache->base = (CORE_ADDR) backchain; } - trad_frame_set_value (cache->saved_regs, - gdbarch_sp_regnum (gdbarch), cache->base); + cache->saved_regs[gdbarch_sp_regnum (gdbarch)].set_value (cache->base); /* if != -1, fdata.saved_fpr is the smallest number of saved_fpr. All fpr's from saved_fpr to fp31 are saved. */ @@ -3529,15 +3650,15 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) CORE_ADDR fpr_addr = cache->base + fdata.fpr_offset; /* If skip_prologue says floating-point registers were saved, - but the current architecture has no floating-point registers, - then that's strange. But we have no indices to even record - the addresses under, so we just ignore it. */ + but the current architecture has no floating-point registers, + then that's strange. But we have no indices to even record + the addresses under, so we just ignore it. */ if (ppc_floating_point_unit_p (gdbarch)) - for (i = fdata.saved_fpr; i < ppc_num_fprs; i++) - { - cache->saved_regs[tdep->ppc_fp0_regnum + i].addr = fpr_addr; - fpr_addr += 8; - } + for (i = fdata.saved_fpr; i < ppc_num_fprs; i++) + { + cache->saved_regs[tdep->ppc_fp0_regnum + i].set_addr (fpr_addr); + fpr_addr += 8; + } } /* if != -1, fdata.saved_gpr is the smallest number of saved_gpr. @@ -3551,7 +3672,7 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) for (i = fdata.saved_gpr; i < ppc_num_gprs; i++) { if (fdata.gpr_mask & (1U << i)) - cache->saved_regs[tdep->ppc_gp0_regnum + i].addr = gpr_addr; + cache->saved_regs[tdep->ppc_gp0_regnum + i].set_addr (gpr_addr); gpr_addr += wordsize; } } @@ -3566,7 +3687,7 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) CORE_ADDR vr_addr = cache->base + fdata.vr_offset; for (i = fdata.saved_vr; i < 32; i++) { - cache->saved_regs[tdep->ppc_vr0_regnum + i].addr = vr_addr; + cache->saved_regs[tdep->ppc_vr0_regnum + i].set_addr (vr_addr); vr_addr += register_size (gdbarch, tdep->ppc_vr0_regnum); } } @@ -3584,8 +3705,9 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) for (i = fdata.saved_ev; i < ppc_num_gprs; i++) { - cache->saved_regs[tdep->ppc_ev0_regnum + i].addr = ev_addr; - cache->saved_regs[tdep->ppc_gp0_regnum + i].addr = ev_addr + off; + cache->saved_regs[tdep->ppc_ev0_regnum + i].set_addr (ev_addr); + cache->saved_regs[tdep->ppc_gp0_regnum + i].set_addr (ev_addr + + off); ev_addr += register_size (gdbarch, tdep->ppc_ev0_regnum); } } @@ -3594,16 +3716,16 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) /* If != 0, fdata.cr_offset is the offset from the frame that holds the CR. */ if (fdata.cr_offset != 0) - cache->saved_regs[tdep->ppc_cr_regnum].addr - = cache->base + fdata.cr_offset; + cache->saved_regs[tdep->ppc_cr_regnum].set_addr (cache->base + + fdata.cr_offset); /* If != 0, fdata.lr_offset is the offset from the frame that holds the LR. */ if (fdata.lr_offset != 0) - cache->saved_regs[tdep->ppc_lr_regnum].addr - = cache->base + fdata.lr_offset; + cache->saved_regs[tdep->ppc_lr_regnum].set_addr (cache->base + + fdata.lr_offset); else if (fdata.lr_register != -1) - cache->saved_regs[tdep->ppc_lr_regnum].realreg = fdata.lr_register; + cache->saved_regs[tdep->ppc_lr_regnum].set_realreg (fdata.lr_register); /* The PC is found in the link register. */ cache->saved_regs[gdbarch_pc_regnum (gdbarch)] = cache->saved_regs[tdep->ppc_lr_regnum]; @@ -3611,8 +3733,8 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) /* If != 0, fdata.vrsave_offset is the offset from the frame that holds the VRSAVE. */ if (fdata.vrsave_offset != 0) - cache->saved_regs[tdep->ppc_vrsave_regnum].addr - = cache->base + fdata.vrsave_offset; + cache->saved_regs[tdep->ppc_vrsave_regnum].set_addr (cache->base + + fdata.vrsave_offset); if (fdata.alloca_reg < 0) /* If no alloca register used, then fi->frame is the value of the @@ -3658,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, @@ -3674,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; @@ -3683,7 +3806,7 @@ rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache) (*this_cache) = cache; cache->saved_regs = trad_frame_alloc_saved_regs (this_frame); - TRY + try { /* At this point the stack looks as if we just entered the function, and the return address is stored in LR. */ @@ -3695,15 +3818,13 @@ rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache) cache->base = sp; cache->initial_sp = sp; - trad_frame_set_value (cache->saved_regs, - gdbarch_pc_regnum (gdbarch), lr); + cache->saved_regs[gdbarch_pc_regnum (gdbarch)].set_value (lr); } - CATCH (ex, RETURN_MASK_ERROR) + catch (const gdb_exception_error &ex) { if (ex.error != NOT_AVAILABLE_ERROR) - throw_exception (ex); + throw; } - END_CATCH return cache; } @@ -3759,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, @@ -3796,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. */ @@ -3882,7 +4004,7 @@ bfd_uses_spe_extensions (bfd *abfd) if (!sect) return 0; - size = bfd_get_section_size (sect); + size = bfd_section_size (sect); contents = (gdb_byte *) xmalloc (size); if (!bfd_get_section_contents (abfd, sect, contents, 0, size)) { @@ -4008,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; @@ -4037,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); @@ -4410,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) @@ -4462,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; @@ -4868,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 */ @@ -5030,7 +5152,8 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, return 0; case 1014: /* Data Cache Block set to Zero */ - if (target_auxv_search (current_top_target (), AT_DCACHEBSIZE, &at_dcsz) <= 0 + if (target_auxv_search (current_inferior ()->top_target (), + AT_DCACHEBSIZE, &at_dcsz) <= 0 || at_dcsz == 0) at_dcsz = 128; /* Assume 128-byte cache line size (POWER8) */ @@ -5058,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) @@ -5152,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) @@ -5446,7 +5569,7 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache, { case 0: /* VSX Scalar Extract Exponent Double-Precision */ case 1: /* VSX Scalar Extract Significand Double-Precision */ - record_full_arch_list_add_reg (regcache, + record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + PPC_RT (insn)); return 0; case 16: /* VSX Scalar Convert Half-Precision format to @@ -5514,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; @@ -5573,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; @@ -5703,7 +5826,7 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache, case 583: switch (PPC_FIELD (insn, 11, 5)) - { + { case 1: /* Move From FPSCR & Clear Enables */ case 20: /* Move From FPSCR Control & set DRN */ case 21: /* Move From FPSCR Control & set DRN Immediate */ @@ -5719,7 +5842,7 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache, tdep->ppc_fp0_regnum + PPC_FRT (insn)); return 0; - } + } break; case 8: /* Floating Copy Sign */ @@ -5832,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; @@ -6033,7 +6156,7 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache, case 57: switch (insn & 0x3) - { + { case 0: /* Load Floating-Point Double Pair */ tmp = tdep->ppc_fp0_regnum + (PPC_RT (insn) & ~1); record_full_arch_list_add_reg (regcache, tmp); @@ -6124,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. @@ -6135,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; @@ -6153,20 +6338,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) int have_htm_tar = 0; int tdesc_wordsize = -1; const struct target_desc *tdesc = info.target_desc; - struct tdesc_arch_data *tdesc_data = NULL; + tdesc_arch_data_up tdesc_data; int num_pseudoregs = 0; int cur_reg; - /* INFO may refer to a binary that is not of the PowerPC architecture, - e.g. when debugging a stand-alone SPE executable on a Cell/B.E. system. - In this case, we must not attempt to infer properties of the (PowerPC - side) of the target system from properties of that executable. Trust - the target description instead. */ - if (info.abfd - && bfd_get_arch (info.abfd) != bfd_arch_powerpc - && bfd_get_arch (info.abfd) != bfd_arch_rs6000) - info.abfd = NULL; - from_xcoff_exec = info.abfd && info.abfd->format == bfd_object && bfd_get_flavour (info.abfd) == bfd_target_xcoff_flavour; @@ -6224,7 +6399,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) layout, if we do not already have one. */ if (! tdesc_has_registers (tdesc)) { - const struct variant *v; + const struct ppc_variant *v; /* Choose variant. */ v = find_variant_by_arch (arch, mach); @@ -6260,31 +6435,29 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) valid_p = 1; for (i = 0; i < ppc_num_gprs; i++) - valid_p &= tdesc_numbered_register (feature, tdesc_data, i, gprs[i]); - valid_p &= tdesc_numbered_register (feature, tdesc_data, PPC_PC_REGNUM, - "pc"); - valid_p &= tdesc_numbered_register (feature, tdesc_data, PPC_LR_REGNUM, - "lr"); - valid_p &= tdesc_numbered_register (feature, tdesc_data, PPC_XER_REGNUM, - "xer"); + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), + i, gprs[i]); + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), + PPC_PC_REGNUM, "pc"); + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), + PPC_LR_REGNUM, "lr"); + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), + PPC_XER_REGNUM, "xer"); /* Allow alternate names for these registers, to accomodate GDB's historic naming. */ - valid_p &= tdesc_numbered_register_choices (feature, tdesc_data, + valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (), PPC_MSR_REGNUM, msr_names); - valid_p &= tdesc_numbered_register_choices (feature, tdesc_data, + valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (), PPC_CR_REGNUM, cr_names); - valid_p &= tdesc_numbered_register_choices (feature, tdesc_data, + valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (), PPC_CTR_REGNUM, ctr_names); if (!valid_p) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } + return NULL; - have_mq = tdesc_numbered_register (feature, tdesc_data, PPC_MQ_REGNUM, - "mq"); + have_mq = tdesc_numbered_register (feature, tdesc_data.get (), + PPC_MQ_REGNUM, "mq"); tdesc_wordsize = tdesc_register_bitsize (feature, "pc") / 8; if (wordsize == -1) @@ -6302,16 +6475,13 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) }; valid_p = 1; for (i = 0; i < ppc_num_fprs; i++) - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_F0_REGNUM + i, fprs[i]); - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_FPSCR_REGNUM, "fpscr"); if (!valid_p) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } + return NULL; have_fpu = 1; /* The fpscr register was expanded in isa 2.05 to 64 bits @@ -6336,19 +6506,16 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) valid_p = 1; for (i = 0; i < ppc_num_gprs; i++) - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_VR0_REGNUM + i, vector_regs[i]); - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_VSCR_REGNUM, "vscr"); - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_VRSAVE_REGNUM, "vrsave"); if (have_spe || !valid_p) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } + return NULL; have_altivec = 1; } else @@ -6372,15 +6539,12 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) valid_p = 1; for (i = 0; i < ppc_num_vshrs; i++) - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_VSR0_UPPER_REGNUM + i, vsx_regs[i]); if (!valid_p || !have_fpu || !have_altivec) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } + return NULL; have_vsx = 1; } @@ -6417,19 +6581,16 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) valid_p = 1; for (i = 0; i < ppc_num_gprs; i++) - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_SPE_UPPER_GP0_REGNUM + i, upper_spe[i]); - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_SPE_ACC_REGNUM, "acc"); - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_SPE_FSCR_REGNUM, "spefscr"); if (have_mq || have_fpu || !valid_p) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } + return NULL; have_spe = 1; } else @@ -6441,14 +6602,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) if (feature != NULL) { valid_p = 1; - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_PPR_REGNUM, "ppr"); if (!valid_p) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } + return NULL; have_ppr = 1; } else @@ -6460,14 +6618,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) if (feature != NULL) { valid_p = 1; - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_DSCR_REGNUM, "dscr"); if (!valid_p) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } + return NULL; have_dscr = 1; } else @@ -6479,14 +6634,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) if (feature != NULL) { valid_p = 1; - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_TAR_REGNUM, "tar"); if (!valid_p) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } + return NULL; have_tar = 1; } else @@ -6503,14 +6655,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) valid_p = 1; for (i = 0; i < ARRAY_SIZE (ebb_regs); i++) - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_BESCR_REGNUM + i, ebb_regs[i]); if (!valid_p) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } + return NULL; have_ebb = 1; } else @@ -6524,27 +6673,24 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { valid_p = 1; - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_MMCR0_REGNUM, "mmcr0"); - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_MMCR2_REGNUM, "mmcr2"); - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_SIAR_REGNUM, "siar"); - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_SDAR_REGNUM, "sdar"); - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_SIER_REGNUM, "sier"); if (!valid_p) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } + return NULL; have_pmu = 1; } else @@ -6561,14 +6707,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) valid_p = 1; for (i = 0; i < ARRAY_SIZE (tm_spr_regs); i++) - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_TFHAR_REGNUM + i, tm_spr_regs[i]); if (!valid_p) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } + return NULL; have_htm_spr = 1; } @@ -6590,14 +6733,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) valid_p = 1; for (i = 0; i < ARRAY_SIZE (cgprs); i++) - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_CR0_REGNUM + i, cgprs[i]); if (!valid_p) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } + return NULL; have_htm_core = 1; } @@ -6619,15 +6759,12 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) }; for (i = 0; i < ARRAY_SIZE (cfprs); i++) - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_CF0_REGNUM + i, cfprs[i]); if (!valid_p) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } + return NULL; have_htm_fpu = 1; } else @@ -6649,15 +6786,12 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) }; for (i = 0; i < ARRAY_SIZE (cvmx); i++) - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), PPC_CVR0_REGNUM + i, cvmx[i]); if (!valid_p) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } + return NULL; have_htm_altivec = 1; } else @@ -6679,16 +6813,13 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) }; for (i = 0; i < ARRAY_SIZE (cvsx); i++) - valid_p &= tdesc_numbered_register (feature, tdesc_data, + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), (PPC_CVSR0_UPPER_REGNUM + i), cvsx[i]); if (!valid_p || !have_htm_fpu || !have_htm_altivec) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } + return NULL; have_htm_vsx = 1; } else @@ -6698,14 +6829,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) "org.gnu.gdb.power.htm.ppr"); if (feature != NULL) { - valid_p = tdesc_numbered_register (feature, tdesc_data, + valid_p = tdesc_numbered_register (feature, tdesc_data.get (), PPC_CPPR_REGNUM, "cppr"); if (!valid_p) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } + return NULL; have_htm_ppr = 1; } else @@ -6715,14 +6843,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) "org.gnu.gdb.power.htm.dscr"); if (feature != NULL) { - valid_p = tdesc_numbered_register (feature, tdesc_data, + valid_p = tdesc_numbered_register (feature, tdesc_data.get (), PPC_CDSCR_REGNUM, "cdscr"); if (!valid_p) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } + return NULL; have_htm_dscr = 1; } else @@ -6732,14 +6857,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) "org.gnu.gdb.power.htm.tar"); if (feature != NULL) { - valid_p = tdesc_numbered_register (feature, tdesc_data, + valid_p = tdesc_numbered_register (feature, tdesc_data.get (), PPC_CTAR_REGNUM, "ctar"); if (!valid_p) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } + return NULL; have_htm_tar = 1; } else @@ -6758,10 +6880,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) supplies a 64-bit description while debugging a 32-bit binary. */ if (tdesc_wordsize != -1 && tdesc_wordsize != wordsize) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } + return NULL; #ifdef HAVE_ELF if (from_elf_exec) @@ -6841,9 +6960,9 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) if (elf_abi == POWERPC_ELF_AUTO) { if (wordsize == 8 && info.byte_order == BFD_ENDIAN_LITTLE) - elf_abi = POWERPC_ELF_V2; + elf_abi = POWERPC_ELF_V2; else - elf_abi = POWERPC_ELF_V1; + elf_abi = POWERPC_ELF_V1; } if (soft_float_flag == AUTO_BOOLEAN_TRUE) @@ -6885,9 +7004,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) arches = gdbarch_list_lookup_by_info (arches->next, &info)) { /* 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); + meaningful, because 64-bit CPUs can run in 32-bit mode. So, perform + separate word size check. */ + 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) @@ -6897,11 +7017,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) if (tdep && tdep->vector_abi != vector_abi) continue; if (tdep && tdep->wordsize == wordsize) - { - if (tdesc_data != NULL) - tdesc_data_cleanup (tdesc_data); - return arches->gdbarch; - } + return arches->gdbarch; } /* None found, create a new architecture from INFO, whose bfd_arch_info @@ -6912,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; @@ -7056,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. */ @@ -7088,14 +7206,16 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_displaced_step_hw_singlestep (gdbarch, ppc_displaced_step_hw_singlestep); set_gdbarch_displaced_step_fixup (gdbarch, ppc_displaced_step_fixup); - set_gdbarch_displaced_step_location (gdbarch, - displaced_step_at_entry_point); + set_gdbarch_displaced_step_prepare (gdbarch, ppc_displaced_step_prepare); + set_gdbarch_displaced_step_finish (gdbarch, ppc_displaced_step_finish); + set_gdbarch_displaced_step_restore_all_in_ptid + (gdbarch, ppc_displaced_step_restore_all_in_ptid); - set_gdbarch_max_insn_length (gdbarch, PPC_INSN_SIZE); + set_gdbarch_max_insn_length (gdbarch, 2 * PPC_INSN_SIZE); /* Hook in ABI-specific overrides, if they have been registered. */ info.target_desc = tdesc; - info.tdesc_data = tdesc_data; + info.tdesc_data = tdesc_data.get (); gdbarch_init_osabi (info, gdbarch); switch (info.osabi) @@ -7103,26 +7223,22 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) case GDB_OSABI_LINUX: case GDB_OSABI_NETBSD: case GDB_OSABI_UNKNOWN: - set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc); frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind); frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind); - set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id); frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer); break; default: set_gdbarch_believe_pcc_promotion (gdbarch, 1); - set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc); frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind); frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind); - set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id); frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer); } set_tdesc_pseudo_register_type (gdbarch, rs6000_pseudo_register_type); set_tdesc_pseudo_register_reggroup_p (gdbarch, rs6000_pseudo_register_reggroup_p); - tdesc_use_registers (gdbarch, tdesc, tdesc_data); + tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data)); /* Override the normal target description method to make the SPE upper halves anonymous. */ @@ -7193,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; @@ -7201,22 +7317,6 @@ rs6000_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) /* FIXME: Dump gdbarch_tdep. */ } -/* PowerPC-specific commands. */ - -static void -set_powerpc_command (const char *args, int from_tty) -{ - printf_unfiltered (_("\ -\"set powerpc\" must be followed by an appropriate subcommand.\n")); - help_list (setpowerpccmdlist, "set powerpc ", all_commands, gdb_stdout); -} - -static void -show_powerpc_command (const char *args, int from_tty) -{ - cmd_show_list (showpowerpccmdlist, from_tty, ""); -} - static void powerpc_set_soft_float (const char *args, int from_tty, struct cmd_list_element *c) @@ -7224,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")); } @@ -7233,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; @@ -7251,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")); } @@ -7335,10 +7433,19 @@ 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 (); void -_initialize_rs6000_tdep (void) +_initialize_rs6000_tdep () { gdbarch_register (bfd_arch_rs6000, rs6000_gdbarch_init, rs6000_dump_tdep); gdbarch_register (bfd_arch_powerpc, rs6000_gdbarch_init, rs6000_dump_tdep); @@ -7366,13 +7473,11 @@ _initialize_rs6000_tdep (void) /* Add root prefix command for all "set powerpc"/"show powerpc" commands. */ - add_prefix_cmd ("powerpc", no_class, set_powerpc_command, - _("Various PowerPC-specific commands."), - &setpowerpccmdlist, "set powerpc ", 0, &setlist); - - add_prefix_cmd ("powerpc", no_class, show_powerpc_command, - _("Various PowerPC-specific commands."), - &showpowerpccmdlist, "show powerpc ", 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,