/* Target-dependent code for GDB, the GNU debugger.
- Copyright (C) 1986-2020 Free Software Foundation, Inc.
+ Copyright (C) 1986-2021 Free Software Foundation, Inc.
This file is part of GDB.
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. */
+
+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<displaced_step_buffers> disp_step_buf;
+};
+
+static inferior_key<ppc_inferior_data> ppc_inferior_data_key;
+
+/* Get the per-inferior PowerPC data for INF. */
+
+static 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
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))
+ 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)
scan_pc >= epilogue_start;
scan_pc -= PPC_INSN_SIZE)
{
- if (!safe_frame_unwind_memory (curfrm, scan_pc, insn_buf, PPC_INSN_SIZE))
+ 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))
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 bool
/* 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];
}
*/
+ /* 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));
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,
{
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
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. */
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;
+ cache->saved_regs[tdep->ppc_fp0_regnum + i].set_addr (fpr_addr);
fpr_addr += 8;
}
}
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;
}
}
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);
}
}
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);
}
}
/* 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];
/* 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
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 (const gdb_exception_error &ex)
{
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) */
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);