/* Target-dependent code for GDB, the GNU debugger.
- Copyright (C) 1986-2015 Free Software Foundation, Inc.
+ Copyright (C) 1986-2016 Free Software Foundation, Inc.
This file is part of GDB.
#include "frame-unwind.h"
#include "frame-base.h"
+#include "ax.h"
+#include "ax-gdb.h"
+
#include "features/rs6000/powerpc-32.c"
#include "features/rs6000/powerpc-altivec32.c"
#include "features/rs6000/powerpc-vsx32.c"
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. */
-#ifdef WITH_SIM
+#ifdef WITH_PPC_SIM
/* Now handle all special-purpose registers. Verify that they
haven't mistakenly been assigned numbers by any of the above
code. */
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- const struct ppc_reg_offsets *offsets = regset->regmap;
+ const struct ppc_reg_offsets *offsets
+ = (const struct ppc_reg_offsets *) regset->regmap;
size_t offset;
int regsize;
for (i = tdep->ppc_gp0_regnum, offset = offsets->r0_offset;
i < tdep->ppc_gp0_regnum + ppc_num_gprs;
i++, offset += gpr_size)
- ppc_supply_reg (regcache, i, gregs, offset, gpr_size);
+ ppc_supply_reg (regcache, i, (const gdb_byte *) gregs, offset,
+ gpr_size);
ppc_supply_reg (regcache, gdbarch_pc_regnum (gdbarch),
- gregs, offsets->pc_offset, gpr_size);
+ (const gdb_byte *) gregs, offsets->pc_offset, gpr_size);
ppc_supply_reg (regcache, tdep->ppc_ps_regnum,
- gregs, offsets->ps_offset, gpr_size);
+ (const gdb_byte *) gregs, offsets->ps_offset, gpr_size);
ppc_supply_reg (regcache, tdep->ppc_lr_regnum,
- gregs, offsets->lr_offset, gpr_size);
+ (const gdb_byte *) gregs, offsets->lr_offset, gpr_size);
ppc_supply_reg (regcache, tdep->ppc_ctr_regnum,
- gregs, offsets->ctr_offset, gpr_size);
+ (const gdb_byte *) gregs, offsets->ctr_offset, gpr_size);
ppc_supply_reg (regcache, tdep->ppc_cr_regnum,
- gregs, offsets->cr_offset, offsets->xr_size);
+ (const gdb_byte *) gregs, offsets->cr_offset,
+ offsets->xr_size);
ppc_supply_reg (regcache, tdep->ppc_xer_regnum,
- gregs, offsets->xer_offset, offsets->xr_size);
+ (const gdb_byte *) gregs, offsets->xer_offset,
+ offsets->xr_size);
ppc_supply_reg (regcache, tdep->ppc_mq_regnum,
- gregs, offsets->mq_offset, offsets->xr_size);
+ (const gdb_byte *) gregs, offsets->mq_offset,
+ offsets->xr_size);
return;
}
offset = ppc_greg_offset (gdbarch, tdep, offsets, regnum, ®size);
- ppc_supply_reg (regcache, regnum, gregs, offset, regsize);
+ ppc_supply_reg (regcache, regnum, (const gdb_byte *) gregs, offset, regsize);
}
/* Supply register REGNUM in the floating-point register set REGSET
return;
tdep = gdbarch_tdep (gdbarch);
- offsets = regset->regmap;
+ offsets = (const struct ppc_reg_offsets *) regset->regmap;
if (regnum == -1)
{
int i;
for (i = tdep->ppc_fp0_regnum, offset = offsets->f0_offset;
i < tdep->ppc_fp0_regnum + ppc_num_fprs;
i++, offset += 8)
- ppc_supply_reg (regcache, i, fpregs, offset, 8);
+ ppc_supply_reg (regcache, i, (const gdb_byte *) fpregs, offset, 8);
ppc_supply_reg (regcache, tdep->ppc_fpscr_regnum,
- fpregs, offsets->fpscr_offset, offsets->fpscr_size);
+ (const gdb_byte *) fpregs, offsets->fpscr_offset,
+ offsets->fpscr_size);
return;
}
offset = ppc_fpreg_offset (tdep, offsets, regnum);
- ppc_supply_reg (regcache, regnum, fpregs, offset,
+ ppc_supply_reg (regcache, regnum, (const gdb_byte *) fpregs, offset,
regnum == tdep->ppc_fpscr_regnum ? offsets->fpscr_size : 8);
}
for (i = tdep->ppc_vsr0_upper_regnum;
i < tdep->ppc_vsr0_upper_regnum + 32;
i++)
- ppc_supply_reg (regcache, i, vsxregs, 0, 8);
+ ppc_supply_reg (regcache, i, (const gdb_byte *) vsxregs, 0, 8);
return;
}
else
- ppc_supply_reg (regcache, regnum, vsxregs, 0, 8);
+ ppc_supply_reg (regcache, regnum, (const gdb_byte *) vsxregs, 0, 8);
}
/* Supply register REGNUM in the Altivec register set REGSET
return;
tdep = gdbarch_tdep (gdbarch);
- offsets = regset->regmap;
+ offsets = (const struct ppc_reg_offsets *) regset->regmap;
if (regnum == -1)
{
int i;
for (i = tdep->ppc_vr0_regnum, offset = offsets->vr0_offset;
i < tdep->ppc_vr0_regnum + ppc_num_vrs;
i++, offset += 16)
- ppc_supply_reg (regcache, i, vrregs, offset, 16);
+ ppc_supply_reg (regcache, i, (const gdb_byte *) vrregs, offset, 16);
ppc_supply_reg (regcache, (tdep->ppc_vrsave_regnum - 1),
- vrregs, offsets->vscr_offset, 4);
+ (const gdb_byte *) vrregs, offsets->vscr_offset, 4);
ppc_supply_reg (regcache, tdep->ppc_vrsave_regnum,
- vrregs, offsets->vrsave_offset, 4);
+ (const gdb_byte *) vrregs, offsets->vrsave_offset, 4);
return;
}
offset = ppc_vrreg_offset (tdep, offsets, regnum);
if (regnum != tdep->ppc_vrsave_regnum
&& regnum != tdep->ppc_vrsave_regnum - 1)
- ppc_supply_reg (regcache, regnum, vrregs, offset, 16);
+ ppc_supply_reg (regcache, regnum, (const gdb_byte *) vrregs, offset, 16);
else
ppc_supply_reg (regcache, regnum,
- vrregs, offset, 4);
+ (const gdb_byte *) vrregs, offset, 4);
}
/* Collect register REGNUM in the general-purpose register set
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- const struct ppc_reg_offsets *offsets = regset->regmap;
+ const struct ppc_reg_offsets *offsets
+ = (const struct ppc_reg_offsets *) regset->regmap;
size_t offset;
int regsize;
for (i = tdep->ppc_gp0_regnum, offset = offsets->r0_offset;
i < tdep->ppc_gp0_regnum + ppc_num_gprs;
i++, offset += gpr_size)
- ppc_collect_reg (regcache, i, gregs, offset, gpr_size);
+ ppc_collect_reg (regcache, i, (gdb_byte *) gregs, offset, gpr_size);
ppc_collect_reg (regcache, gdbarch_pc_regnum (gdbarch),
- gregs, offsets->pc_offset, gpr_size);
+ (gdb_byte *) gregs, offsets->pc_offset, gpr_size);
ppc_collect_reg (regcache, tdep->ppc_ps_regnum,
- gregs, offsets->ps_offset, gpr_size);
+ (gdb_byte *) gregs, offsets->ps_offset, gpr_size);
ppc_collect_reg (regcache, tdep->ppc_lr_regnum,
- gregs, offsets->lr_offset, gpr_size);
+ (gdb_byte *) gregs, offsets->lr_offset, gpr_size);
ppc_collect_reg (regcache, tdep->ppc_ctr_regnum,
- gregs, offsets->ctr_offset, gpr_size);
+ (gdb_byte *) gregs, offsets->ctr_offset, gpr_size);
ppc_collect_reg (regcache, tdep->ppc_cr_regnum,
- gregs, offsets->cr_offset, offsets->xr_size);
+ (gdb_byte *) gregs, offsets->cr_offset,
+ offsets->xr_size);
ppc_collect_reg (regcache, tdep->ppc_xer_regnum,
- gregs, offsets->xer_offset, offsets->xr_size);
+ (gdb_byte *) gregs, offsets->xer_offset,
+ offsets->xr_size);
ppc_collect_reg (regcache, tdep->ppc_mq_regnum,
- gregs, offsets->mq_offset, offsets->xr_size);
+ (gdb_byte *) gregs, offsets->mq_offset,
+ offsets->xr_size);
return;
}
offset = ppc_greg_offset (gdbarch, tdep, offsets, regnum, ®size);
- ppc_collect_reg (regcache, regnum, gregs, offset, regsize);
+ ppc_collect_reg (regcache, regnum, (gdb_byte *) gregs, offset, regsize);
}
/* Collect register REGNUM in the floating-point register set
return;
tdep = gdbarch_tdep (gdbarch);
- offsets = regset->regmap;
+ offsets = (const struct ppc_reg_offsets *) regset->regmap;
if (regnum == -1)
{
int i;
for (i = tdep->ppc_fp0_regnum, offset = offsets->f0_offset;
i < tdep->ppc_fp0_regnum + ppc_num_fprs;
i++, offset += 8)
- ppc_collect_reg (regcache, i, fpregs, offset, 8);
+ ppc_collect_reg (regcache, i, (gdb_byte *) fpregs, offset, 8);
ppc_collect_reg (regcache, tdep->ppc_fpscr_regnum,
- fpregs, offsets->fpscr_offset, offsets->fpscr_size);
+ (gdb_byte *) fpregs, offsets->fpscr_offset,
+ offsets->fpscr_size);
return;
}
offset = ppc_fpreg_offset (tdep, offsets, regnum);
- ppc_collect_reg (regcache, regnum, fpregs, offset,
+ ppc_collect_reg (regcache, regnum, (gdb_byte *) fpregs, offset,
regnum == tdep->ppc_fpscr_regnum ? offsets->fpscr_size : 8);
}
for (i = tdep->ppc_vsr0_upper_regnum;
i < tdep->ppc_vsr0_upper_regnum + 32;
i++)
- ppc_collect_reg (regcache, i, vsxregs, 0, 8);
+ ppc_collect_reg (regcache, i, (gdb_byte *) vsxregs, 0, 8);
return;
}
else
- ppc_collect_reg (regcache, regnum, vsxregs, 0, 8);
+ ppc_collect_reg (regcache, regnum, (gdb_byte *) vsxregs, 0, 8);
}
return;
tdep = gdbarch_tdep (gdbarch);
- offsets = regset->regmap;
+ offsets = (const struct ppc_reg_offsets *) regset->regmap;
if (regnum == -1)
{
int i;
for (i = tdep->ppc_vr0_regnum, offset = offsets->vr0_offset;
i < tdep->ppc_vr0_regnum + ppc_num_vrs;
i++, offset += 16)
- ppc_collect_reg (regcache, i, vrregs, offset, 16);
+ ppc_collect_reg (regcache, i, (gdb_byte *) vrregs, offset, 16);
ppc_collect_reg (regcache, (tdep->ppc_vrsave_regnum - 1),
- vrregs, offsets->vscr_offset, 4);
+ (gdb_byte *) vrregs, offsets->vscr_offset, 4);
ppc_collect_reg (regcache, tdep->ppc_vrsave_regnum,
- vrregs, offsets->vrsave_offset, 4);
+ (gdb_byte *) vrregs, offsets->vrsave_offset, 4);
return;
}
offset = ppc_vrreg_offset (tdep, offsets, regnum);
if (regnum != tdep->ppc_vrsave_regnum
&& regnum != tdep->ppc_vrsave_regnum - 1)
- ppc_collect_reg (regcache, regnum, vrregs, offset, 16);
+ ppc_collect_reg (regcache, regnum, (gdb_byte *) vrregs, offset, 16);
else
ppc_collect_reg (regcache, regnum,
- vrregs, offset, 4);
+ (gdb_byte *) vrregs, offset, 4);
}
\f
struct gdbarch *arch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
int reg_index;
- gdb_byte *byte_buffer = buffer;
+ gdb_byte *byte_buffer = (gdb_byte *) buffer;
enum register_status status;
gdb_assert (IS_SPE_PSEUDOREG (tdep, ev_reg));
static enum register_status
do_regcache_raw_read (struct regcache *regcache, int regnum, void *buffer)
{
- return regcache_raw_read (regcache, regnum, buffer);
+ return regcache_raw_read (regcache, regnum, (gdb_byte *) buffer);
}
static enum register_status
do_regcache_raw_write (struct regcache *regcache, int regnum, void *buffer)
{
- regcache_raw_write (regcache, regnum, buffer);
+ regcache_raw_write (regcache, regnum, (const gdb_byte *) buffer);
return REG_VALID;
}
gdbarch_register_name (gdbarch, reg_nr), reg_nr);
}
+static int
+rs6000_ax_pseudo_register_collect (struct gdbarch *gdbarch,
+ struct agent_expr *ax, int reg_nr)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ if (IS_SPE_PSEUDOREG (tdep, reg_nr))
+ {
+ int reg_index = reg_nr - tdep->ppc_ev0_regnum;
+ ax_reg_mask (ax, tdep->ppc_gp0_regnum + reg_index);
+ ax_reg_mask (ax, tdep->ppc_ev0_upper_regnum + reg_index);
+ }
+ else if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+ {
+ int reg_index = reg_nr - tdep->ppc_dl0_regnum;
+ ax_reg_mask (ax, tdep->ppc_fp0_regnum + 2 * reg_index);
+ ax_reg_mask (ax, tdep->ppc_fp0_regnum + 2 * reg_index + 1);
+ }
+ else if (IS_VSX_PSEUDOREG (tdep, reg_nr))
+ {
+ int reg_index = reg_nr - tdep->ppc_vsr0_regnum;
+ if (reg_index > 31)
+ {
+ ax_reg_mask (ax, tdep->ppc_vr0_regnum + reg_index - 32);
+ }
+ else
+ {
+ ax_reg_mask (ax, tdep->ppc_fp0_regnum + reg_index);
+ ax_reg_mask (ax, tdep->ppc_vsr0_upper_regnum + reg_index);
+ }
+ }
+ else if (IS_EFP_PSEUDOREG (tdep, reg_nr))
+ {
+ int reg_index = reg_nr - tdep->ppc_efpr0_regnum;
+ ax_reg_mask (ax, tdep->ppc_vr0_regnum + reg_index);
+ }
+ else
+ internal_error (__FILE__, __LINE__,
+ _("rs6000_pseudo_register_collect: "
+ "called on unexpected register '%s' (%d)"),
+ gdbarch_register_name (gdbarch, reg_nr), reg_nr);
+ return 0;
+}
+
+
+static void
+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);
+ value->type = register_type (gdbarch, tdep->ppc_lr_regnum);
+ value->kind = axs_lvalue_register;
+ value->u.reg = tdep->ppc_lr_regnum;
+}
+
+
/* Convert a DBX STABS register number to a GDB register number. */
static int
rs6000_stab_reg_to_regnum (struct gdbarch *gdbarch, int num)
{"rs2", "IBM POWER RS2", bfd_arch_rs6000,
bfd_mach_rs6k_rs2, &tdesc_rs6000},
- {0, 0, 0, 0, 0}
+ {0, 0, (enum bfd_architecture) 0, 0, 0}
};
/* Return the variant corresponding to architecture ARCH and machine number
CORE_ADDR base;
CORE_ADDR initial_sp;
struct 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
+ collected. */
+ int base_p;
+ /* Cache PC for building unavailable frame. */
+ CORE_ADDR pc;
};
static struct rs6000_frame_cache *
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct rs6000_framedata fdata;
int wordsize = tdep->wordsize;
- CORE_ADDR func, pc;
+ CORE_ADDR func = 0, pc = 0;
if ((*this_cache) != NULL)
- return (*this_cache);
+ return (struct rs6000_frame_cache *) (*this_cache);
cache = FRAME_OBSTACK_ZALLOC (struct rs6000_frame_cache);
(*this_cache) = cache;
+ cache->pc = 0;
cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
- func = get_frame_func (this_frame);
- pc = get_frame_pc (this_frame);
- skip_prologue (gdbarch, func, pc, &fdata);
-
- /* Figure out the parent's stack pointer. */
-
- /* NOTE: cagney/2002-04-14: The ->frame points to the inner-most
- address of the current frame. Things might be easier if the
- ->frame pointed to the outer-most address of the frame. In
- the mean time, the address of the prev frame is used as the
- base address of this frame. */
- cache->base = get_frame_register_unsigned
- (this_frame, gdbarch_sp_regnum (gdbarch));
+ TRY
+ {
+ func = get_frame_func (this_frame);
+ cache->pc = func;
+ pc = get_frame_pc (this_frame);
+ skip_prologue (gdbarch, func, pc, &fdata);
+
+ /* Figure out the parent's stack pointer. */
+
+ /* NOTE: cagney/2002-04-14: The ->frame points to the inner-most
+ address of the current frame. Things might be easier if the
+ ->frame pointed to the outer-most address of the frame. In
+ the mean time, the address of the prev frame is used as the
+ base address of this frame. */
+ cache->base = get_frame_register_unsigned
+ (this_frame, gdbarch_sp_regnum (gdbarch));
+ }
+ CATCH (ex, RETURN_MASK_ERROR)
+ {
+ if (ex.error != NOT_AVAILABLE_ERROR)
+ throw_exception (ex);
+ 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.
if (!fdata.frameless)
{
/* Frameless really means stackless. */
- LONGEST backchain;
+ ULONGEST backchain;
- if (safe_read_memory_integer (cache->base, wordsize,
- byte_order, &backchain))
+ if (safe_read_memory_unsigned_integer (cache->base, wordsize,
+ byte_order, &backchain))
cache->base = (CORE_ADDR) backchain;
}
cache->initial_sp
= get_frame_register_unsigned (this_frame, fdata.alloca_reg);
+ cache->base_p = 1;
return cache;
}
{
struct rs6000_frame_cache *info = rs6000_frame_cache (this_frame,
this_cache);
+
+ if (!info->base_p)
+ {
+ (*this_id) = frame_id_build_unavailable_stack (info->pc);
+ return;
+ }
+
/* This marks the outermost frame. */
if (info->base == 0)
return;
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
if (*this_cache)
- return *this_cache;
+ return (struct rs6000_frame_cache *) *this_cache;
cache = FRAME_OBSTACK_ZALLOC (struct rs6000_frame_cache);
(*this_cache) = cache;
set_gdbarch_pseudo_register_read (gdbarch, rs6000_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch,
rs6000_pseudo_register_write);
+ set_gdbarch_ax_pseudo_register_collect (gdbarch,
+ rs6000_ax_pseudo_register_collect);
}
+ set_gdbarch_gen_return_address (gdbarch, rs6000_gen_return_address);
+
set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
/* Select instruction printer. */
/* Hook in ABI-specific overrides, if they have been registered. */
info.target_desc = tdesc;
- info.tdep_info = (void *) tdesc_data;
+ info.tdep_info = tdesc_data;
gdbarch_init_osabi (info, gdbarch);
switch (info.osabi)