/* SPU target-dependent code for GDB, the GNU debugger.
- Copyright (C) 2006-2015 Free Software Foundation, Inc.
+ Copyright (C) 2006-2017 Free Software Foundation, Inc.
Contributed by Ulrich Weigand <uweigand@de.ibm.com>.
Based on a port by Sid Manning <sid@us.ibm.com>.
#include "value.h"
#include "inferior.h"
#include "dis-asm.h"
+#include "disasm.h"
#include "objfiles.h"
#include "language.h"
#include "regcache.h"
static const char *
spu_register_name (struct gdbarch *gdbarch, int reg_nr)
{
- static char *register_names[] =
+ static const char *register_names[] =
{
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
{
struct value *value = default_value_from_register (gdbarch, type,
regnum, frame_id);
- int len = TYPE_LENGTH (type);
+ LONGEST len = TYPE_LENGTH (type);
if (regnum < SPU_NUM_GPRS && len < 16)
{
case TYPE_CODE_BOOL:
case TYPE_CODE_PTR:
case TYPE_CODE_REF:
+ case TYPE_CODE_RVALUE_REF:
return TYPE_LENGTH (type) <= 16;
default:
/* Breakpoints. */
+constexpr gdb_byte spu_break_insn[] = { 0x00, 0x00, 0x3f, 0xff };
-static const gdb_byte *
-spu_breakpoint_from_pc (struct gdbarch *gdbarch,
- CORE_ADDR * pcptr, int *lenptr)
-{
- static const gdb_byte breakpoint[] = { 0x00, 0x00, 0x3f, 0xff };
-
- *lenptr = sizeof breakpoint;
- return breakpoint;
-}
+typedef BP_MANIPULATION (spu_break_insn) spu_breakpoint;
static int
spu_memory_remove_breakpoint (struct gdbarch *gdbarch,
/* Software single-stepping support. */
-static int
-spu_software_single_step (struct frame_info *frame)
+static VEC (CORE_ADDR) *
+spu_software_single_step (struct regcache *regcache)
{
- struct gdbarch *gdbarch = get_frame_arch (frame);
- struct address_space *aspace = get_frame_address_space (frame);
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR pc, next_pc;
unsigned int insn;
int offset, reg;
gdb_byte buf[4];
ULONGEST lslr;
+ VEC (CORE_ADDR) *next_pcs = NULL;
- pc = get_frame_pc (frame);
+ pc = regcache_read_pc (regcache);
if (target_read_memory (pc, buf, 4))
- return 1;
+ throw_error (MEMORY_ERROR, _("Could not read instruction at %s."),
+ paddress (gdbarch, pc));
+
insn = extract_unsigned_integer (buf, 4, byte_order);
/* Get local store limit. */
- lslr = get_frame_register_unsigned (frame, SPU_LSLR_REGNUM);
+ lslr = regcache_raw_get_unsigned (regcache, SPU_LSLR_REGNUM);
if (!lslr)
lslr = (ULONGEST) -1;
else
next_pc = (SPUADDR_ADDR (pc) + 4) & lslr;
- insert_single_step_breakpoint (gdbarch,
- aspace, SPUADDR (SPUADDR_SPU (pc), next_pc));
+ VEC_safe_push (CORE_ADDR, next_pcs, SPUADDR (SPUADDR_SPU (pc), next_pc));
if (is_branch (insn, &offset, ®))
{
if (reg == SPU_PC_REGNUM)
target += SPUADDR_ADDR (pc);
else if (reg != -1)
- {
- int optim, unavail;
-
- if (get_frame_register_bytes (frame, reg, 0, 4, buf,
- &optim, &unavail))
- target += extract_unsigned_integer (buf, 4, byte_order) & -4;
- else
- {
- if (optim)
- throw_error (OPTIMIZED_OUT_ERROR,
- _("Could not determine address of "
- "single-step breakpoint."));
- if (unavail)
- throw_error (NOT_AVAILABLE_ERROR,
- _("Could not determine address of "
- "single-step breakpoint."));
- }
- }
+ target += regcache_raw_get_unsigned (regcache, reg) & -4;
target = target & lslr;
if (target != next_pc)
- insert_single_step_breakpoint (gdbarch, aspace,
- SPUADDR (SPUADDR_SPU (pc), target));
+ VEC_safe_push (CORE_ADDR, next_pcs, SPUADDR (SPUADDR_SPU (pc),
+ target));
}
- return 1;
+ return next_pcs;
}
/* Disassembler. */
-struct spu_dis_asm_data
+struct spu_dis_asm_info : disassemble_info
{
- struct gdbarch *gdbarch;
int id;
};
static void
spu_dis_asm_print_address (bfd_vma addr, struct disassemble_info *info)
{
- struct spu_dis_asm_data *data
- = (struct spu_dis_asm_data *) info->application_data;
- print_address (data->gdbarch, SPUADDR (data->id, addr),
+ struct spu_dis_asm_info *data = (struct spu_dis_asm_info *) info;
+ gdb_disassembler *di
+ = static_cast<gdb_disassembler *>(info->application_data);
+
+ print_address (di->arch (), SPUADDR (data->id, addr),
(struct ui_file *) info->stream);
}
/* The opcodes disassembler does 18-bit address arithmetic. Make
sure the SPU ID encoded in the high bits is added back when we
call print_address. */
- struct disassemble_info spu_info = *info;
- struct spu_dis_asm_data data;
- data.gdbarch = (struct gdbarch *) info->application_data;
- data.id = SPUADDR_SPU (memaddr);
+ struct spu_dis_asm_info spu_info;
- spu_info.application_data = &data;
+ memcpy (&spu_info, info, sizeof (*info));
+ spu_info.id = SPUADDR_SPU (memaddr);
spu_info.print_address_func = spu_dis_asm_print_address;
return print_insn_spu (memaddr, &spu_info);
}
struct bound_minimal_symbol minsym;
struct compunit_symtab *cust;
CORE_ADDR pc;
- struct event_location *location;
- struct cleanup *back_to;
/* Do this only if requested by "set spu stop-on-load on". */
if (!spu_stop_on_load_p)
/* Use a numerical address for the set_breakpoint command to avoid having
the breakpoint re-set incorrectly. */
- location = new_address_location (pc);
- back_to = make_cleanup_delete_event_location (location);
- create_breakpoint (get_objfile_arch (objfile), location,
+ event_location_up location = new_address_location (pc, NULL, 0);
+ create_breakpoint (get_objfile_arch (objfile), location.get (),
NULL /* cond_string */, -1 /* thread */,
NULL /* extra_string */,
0 /* parse_condition_and_thread */, 1 /* tempflag */,
AUTO_BOOLEAN_FALSE /* pending_break_support */,
&bkpt_breakpoint_ops /* ops */, 0 /* from_tty */,
1 /* enabled */, 0 /* internal */, 0);
- do_cleanups (back_to);
}
chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "SPUInfoEvent");
- if (ui_out_is_mi_like_p (current_uiout))
+ if (current_uiout->is_mi_like_p ())
{
- ui_out_field_fmt (current_uiout, "event_status",
- "0x%s", phex_nz (event_status, 4));
- ui_out_field_fmt (current_uiout, "event_mask",
- "0x%s", phex_nz (event_mask, 4));
+ current_uiout->field_fmt ("event_status",
+ "0x%s", phex_nz (event_status, 4));
+ current_uiout->field_fmt ("event_mask",
+ "0x%s", phex_nz (event_mask, 4));
}
else
{
chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "SPUInfoSignal");
- if (ui_out_is_mi_like_p (current_uiout))
+ if (current_uiout->is_mi_like_p ())
{
- ui_out_field_int (current_uiout, "signal1_pending", signal1_pending);
- ui_out_field_fmt (current_uiout, "signal1", "0x%s", phex_nz (signal1, 4));
- ui_out_field_int (current_uiout, "signal1_type", signal1_type);
- ui_out_field_int (current_uiout, "signal2_pending", signal2_pending);
- ui_out_field_fmt (current_uiout, "signal2", "0x%s", phex_nz (signal2, 4));
- ui_out_field_int (current_uiout, "signal2_type", signal2_type);
+ current_uiout->field_int ("signal1_pending", signal1_pending);
+ current_uiout->field_fmt ("signal1", "0x%s", phex_nz (signal1, 4));
+ current_uiout->field_int ("signal1_type", signal1_type);
+ current_uiout->field_int ("signal2_pending", signal2_pending);
+ current_uiout->field_fmt ("signal2", "0x%s", phex_nz (signal2, 4));
+ current_uiout->field_int ("signal2_type", signal2_type);
}
else
{
chain = make_cleanup_ui_out_table_begin_end (current_uiout, 1, nr, "mbox");
- ui_out_table_header (current_uiout, 32, ui_left, field, msg);
- ui_out_table_body (current_uiout);
+ current_uiout->table_header (32, ui_left, field, msg);
+ current_uiout->table_body ();
for (i = 0; i < nr; i++)
{
ULONGEST val;
val_chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "mbox");
val = extract_unsigned_integer (buf + 4*i, 4, byte_order);
- ui_out_field_fmt (current_uiout, field, "0x%s", phex (val, 4));
+ current_uiout->field_fmt (field, "0x%s", phex (val, 4));
do_cleanups (val_chain);
- if (!ui_out_is_mi_like_p (current_uiout))
+ if (!current_uiout->is_mi_like_p ())
printf_filtered ("\n");
}
static void
info_spu_dma_cmdlist (gdb_byte *buf, int nr, enum bfd_endian byte_order)
{
- static char *spu_mfc_opcode[256] =
+ static const char *spu_mfc_opcode[256] =
{
/* 00 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
chain = make_cleanup_ui_out_table_begin_end (current_uiout, 10, nr,
"dma_cmd");
- ui_out_table_header (current_uiout, 7, ui_left, "opcode", "Opcode");
- ui_out_table_header (current_uiout, 3, ui_left, "tag", "Tag");
- ui_out_table_header (current_uiout, 3, ui_left, "tid", "TId");
- ui_out_table_header (current_uiout, 3, ui_left, "rid", "RId");
- ui_out_table_header (current_uiout, 18, ui_left, "ea", "EA");
- ui_out_table_header (current_uiout, 7, ui_left, "lsa", "LSA");
- ui_out_table_header (current_uiout, 7, ui_left, "size", "Size");
- ui_out_table_header (current_uiout, 7, ui_left, "lstaddr", "LstAddr");
- ui_out_table_header (current_uiout, 7, ui_left, "lstsize", "LstSize");
- ui_out_table_header (current_uiout, 1, ui_left, "error_p", "E");
+ current_uiout->table_header (7, ui_left, "opcode", "Opcode");
+ current_uiout->table_header (3, ui_left, "tag", "Tag");
+ current_uiout->table_header (3, ui_left, "tid", "TId");
+ current_uiout->table_header (3, ui_left, "rid", "RId");
+ current_uiout->table_header (18, ui_left, "ea", "EA");
+ current_uiout->table_header (7, ui_left, "lsa", "LSA");
+ current_uiout->table_header (7, ui_left, "size", "Size");
+ current_uiout->table_header (7, ui_left, "lstaddr", "LstAddr");
+ current_uiout->table_header (7, ui_left, "lstsize", "LstSize");
+ current_uiout->table_header (1, ui_left, "error_p", "E");
- ui_out_table_body (current_uiout);
+ current_uiout->table_body ();
for (i = 0; i < nr; i++)
{
int mfc_cmd_opcode, mfc_cmd_tag, rclass_id, tclass_id;
int list_lsa, list_size, mfc_lsa, mfc_size;
ULONGEST mfc_ea;
- int list_valid_p, noop_valid_p, qw_valid_p, ea_valid_p, cmd_error_p;
+ int list_valid_p, qw_valid_p, ea_valid_p, cmd_error_p;
/* Decode contents of MFC Command Queue Context Save/Restore Registers.
See "Cell Broadband Engine Registers V1.3", section 3.3.2.1. */
mfc_lsa = spu_mfc_get_bitfield (mfc_cq_dw2, 0, 13);
mfc_size = spu_mfc_get_bitfield (mfc_cq_dw2, 14, 24);
- noop_valid_p = spu_mfc_get_bitfield (mfc_cq_dw2, 37, 37);
qw_valid_p = spu_mfc_get_bitfield (mfc_cq_dw2, 38, 38);
ea_valid_p = spu_mfc_get_bitfield (mfc_cq_dw2, 39, 39);
cmd_error_p = spu_mfc_get_bitfield (mfc_cq_dw2, 40, 40);
cmd_chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "cmd");
if (spu_mfc_opcode[mfc_cmd_opcode])
- ui_out_field_string (current_uiout, "opcode", spu_mfc_opcode[mfc_cmd_opcode]);
+ current_uiout->field_string ("opcode", spu_mfc_opcode[mfc_cmd_opcode]);
else
- ui_out_field_int (current_uiout, "opcode", mfc_cmd_opcode);
+ current_uiout->field_int ("opcode", mfc_cmd_opcode);
- ui_out_field_int (current_uiout, "tag", mfc_cmd_tag);
- ui_out_field_int (current_uiout, "tid", tclass_id);
- ui_out_field_int (current_uiout, "rid", rclass_id);
+ current_uiout->field_int ("tag", mfc_cmd_tag);
+ current_uiout->field_int ("tid", tclass_id);
+ current_uiout->field_int ("rid", rclass_id);
if (ea_valid_p)
- ui_out_field_fmt (current_uiout, "ea", "0x%s", phex (mfc_ea, 8));
+ current_uiout->field_fmt ("ea", "0x%s", phex (mfc_ea, 8));
else
- ui_out_field_skip (current_uiout, "ea");
+ current_uiout->field_skip ("ea");
- ui_out_field_fmt (current_uiout, "lsa", "0x%05x", mfc_lsa << 4);
+ current_uiout->field_fmt ("lsa", "0x%05x", mfc_lsa << 4);
if (qw_valid_p)
- ui_out_field_fmt (current_uiout, "size", "0x%05x", mfc_size << 4);
+ current_uiout->field_fmt ("size", "0x%05x", mfc_size << 4);
else
- ui_out_field_fmt (current_uiout, "size", "0x%05x", mfc_size);
+ current_uiout->field_fmt ("size", "0x%05x", mfc_size);
if (list_valid_p)
{
- ui_out_field_fmt (current_uiout, "lstaddr", "0x%05x", list_lsa << 3);
- ui_out_field_fmt (current_uiout, "lstsize", "0x%05x", list_size << 3);
+ current_uiout->field_fmt ("lstaddr", "0x%05x", list_lsa << 3);
+ current_uiout->field_fmt ("lstsize", "0x%05x", list_size << 3);
}
else
{
- ui_out_field_skip (current_uiout, "lstaddr");
- ui_out_field_skip (current_uiout, "lstsize");
+ current_uiout->field_skip ("lstaddr");
+ current_uiout->field_skip ("lstsize");
}
if (cmd_error_p)
- ui_out_field_string (current_uiout, "error_p", "*");
+ current_uiout->field_string ("error_p", "*");
else
- ui_out_field_skip (current_uiout, "error_p");
+ current_uiout->field_skip ("error_p");
do_cleanups (cmd_chain);
- if (!ui_out_is_mi_like_p (current_uiout))
+ if (!current_uiout->is_mi_like_p ())
printf_filtered ("\n");
}
chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "SPUInfoDMA");
- if (ui_out_is_mi_like_p (current_uiout))
+ if (current_uiout->is_mi_like_p ())
{
- ui_out_field_fmt (current_uiout, "dma_info_type", "0x%s",
- phex_nz (dma_info_type, 4));
- ui_out_field_fmt (current_uiout, "dma_info_mask", "0x%s",
- phex_nz (dma_info_mask, 4));
- ui_out_field_fmt (current_uiout, "dma_info_status", "0x%s",
- phex_nz (dma_info_status, 4));
- ui_out_field_fmt (current_uiout, "dma_info_stall_and_notify", "0x%s",
- phex_nz (dma_info_stall_and_notify, 4));
- ui_out_field_fmt (current_uiout, "dma_info_atomic_command_status", "0x%s",
- phex_nz (dma_info_atomic_command_status, 4));
+ current_uiout->field_fmt ("dma_info_type", "0x%s",
+ phex_nz (dma_info_type, 4));
+ current_uiout->field_fmt ("dma_info_mask", "0x%s",
+ phex_nz (dma_info_mask, 4));
+ current_uiout->field_fmt ("dma_info_status", "0x%s",
+ phex_nz (dma_info_status, 4));
+ current_uiout->field_fmt ("dma_info_stall_and_notify", "0x%s",
+ phex_nz (dma_info_stall_and_notify, 4));
+ current_uiout->field_fmt ("dma_info_atomic_command_status", "0x%s",
+ phex_nz (dma_info_atomic_command_status, 4));
}
else
{
chain = make_cleanup_ui_out_tuple_begin_end (current_uiout,
"SPUInfoProxyDMA");
- if (ui_out_is_mi_like_p (current_uiout))
+ if (current_uiout->is_mi_like_p ())
{
- ui_out_field_fmt (current_uiout, "proxydma_info_type", "0x%s",
- phex_nz (dma_info_type, 4));
- ui_out_field_fmt (current_uiout, "proxydma_info_mask", "0x%s",
- phex_nz (dma_info_mask, 4));
- ui_out_field_fmt (current_uiout, "proxydma_info_status", "0x%s",
- phex_nz (dma_info_status, 4));
+ current_uiout->field_fmt ("proxydma_info_type", "0x%s",
+ phex_nz (dma_info_type, 4));
+ current_uiout->field_fmt ("proxydma_info_mask", "0x%s",
+ phex_nz (dma_info_mask, 4));
+ current_uiout->field_fmt ("proxydma_info_status", "0x%s",
+ phex_nz (dma_info_status, 4));
}
else
{
/* Breakpoints. */
set_gdbarch_decr_pc_after_break (gdbarch, 4);
- set_gdbarch_breakpoint_from_pc (gdbarch, spu_breakpoint_from_pc);
+ set_gdbarch_breakpoint_kind_from_pc (gdbarch, spu_breakpoint::kind_from_pc);
+ set_gdbarch_sw_breakpoint_from_kind (gdbarch, spu_breakpoint::bp_from_kind);
set_gdbarch_memory_remove_breakpoint (gdbarch, spu_memory_remove_breakpoint);
set_gdbarch_software_single_step (gdbarch, spu_software_single_step);
set_gdbarch_get_longjmp_target (gdbarch, spu_get_longjmp_target);