/* SPU target-dependent code for GDB, the GNU debugger.
- Copyright (C) 2006-2017 Free Software Foundation, Inc.
+ Copyright (C) 2006-2018 Free Software Foundation, Inc.
Contributed by Ulrich Weigand <uweigand@de.ibm.com>.
Based on a port by Sid Manning <sid@us.ibm.com>.
#include "language.h"
#include "regcache.h"
#include "reggroups.h"
-#include "floatformat.h"
#include "block.h"
-#include "observer.h"
+#include "observable.h"
#include "infcall.h"
#include "dwarf2.h"
#include "dwarf2-frame.h"
/* Pseudo registers for preferred slots - stack pointer. */
static enum register_status
-spu_pseudo_register_read_spu (struct regcache *regcache, const char *regname,
+spu_pseudo_register_read_spu (readable_regcache *regcache, const char *regname,
gdb_byte *buf)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
enum register_status status;
gdb_byte reg[32];
ULONGEST id;
ULONGEST ul;
- status = regcache_raw_read_unsigned (regcache, SPU_ID_REGNUM, &id);
+ status = regcache->raw_read (SPU_ID_REGNUM, &id);
if (status != REG_VALID)
return status;
xsnprintf (annex, sizeof annex, "%d/%s", (int) id, regname);
}
static enum register_status
-spu_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+spu_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
int regnum, gdb_byte *buf)
{
gdb_byte reg[16];
switch (regnum)
{
case SPU_SP_REGNUM:
- status = regcache_raw_read (regcache, SPU_RAW_SP_REGNUM, reg);
+ status = regcache->raw_read (SPU_RAW_SP_REGNUM, reg);
if (status != REG_VALID)
return status;
memcpy (buf, reg, 4);
return status;
case SPU_FPSCR_REGNUM:
- status = regcache_raw_read_unsigned (regcache, SPU_ID_REGNUM, &id);
+ status = regcache->raw_read (SPU_ID_REGNUM, &id);
if (status != REG_VALID)
return status;
xsnprintf (annex, sizeof annex, "%d/fpcr", (int) id);
spu_pseudo_register_write_spu (struct regcache *regcache, const char *regname,
const gdb_byte *buf)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
char reg[32];
char annex[32];
}
static CORE_ADDR
-spu_read_pc (struct regcache *regcache)
+spu_read_pc (readable_regcache *regcache)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
+ struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
ULONGEST pc;
- regcache_cooked_read_unsigned (regcache, SPU_PC_REGNUM, &pc);
+
+ regcache->cooked_read (SPU_PC_REGNUM, &pc);
/* Mask off interrupt enable bit. */
return SPUADDR (tdep->id, pc & -4);
}
struct spu2ppu_cache
{
struct frame_id frame_id;
- struct regcache *regcache;
+ readonly_detached_regcache *regcache;
};
static struct gdbarch *
spu2ppu_prev_arch (struct frame_info *this_frame, void **this_cache)
{
struct spu2ppu_cache *cache = (struct spu2ppu_cache *) *this_cache;
- return get_regcache_arch (cache->regcache);
+ return cache->regcache->arch ();
}
static void
void **this_cache, int regnum)
{
struct spu2ppu_cache *cache = (struct spu2ppu_cache *) *this_cache;
- struct gdbarch *gdbarch = get_regcache_arch (cache->regcache);
+ struct gdbarch *gdbarch = cache->regcache->arch ();
gdb_byte *buf;
buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));
- regcache_cooked_read (cache->regcache, regnum, buf);
+ cache->regcache->cooked_read (regnum, buf);
return frame_unwind_got_bytes (this_frame, regnum, buf);
}
if (fi)
{
- cache->regcache = frame_save_as_regcache (fi);
+ cache->regcache = frame_save_as_regcache (fi).release ();
*this_prologue_cache = cache;
return 1;
}
{
struct regcache *regcache;
regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
- cache->regcache = regcache_dup (regcache);
+ cache->regcache = new readonly_detached_regcache (*regcache);
*this_prologue_cache = cache;
return 1;
}
spu2ppu_dealloc_cache (struct frame_info *self, void *this_cache)
{
struct spu2ppu_cache *cache = (struct spu2ppu_cache *) this_cache;
- regcache_xfree (cache->regcache);
+ delete cache->regcache;
}
static const struct frame_unwind spu2ppu_unwind = {
/* Software single-stepping support. */
-static VEC (CORE_ADDR) *
+static std::vector<CORE_ADDR>
spu_software_single_step (struct regcache *regcache)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
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;
+ std::vector<CORE_ADDR> next_pcs;
pc = regcache_read_pc (regcache);
insn = extract_unsigned_integer (buf, 4, byte_order);
/* Get local store limit. */
- lslr = regcache_raw_get_unsigned (regcache, SPU_LSLR_REGNUM);
- if (!lslr)
+ if ((regcache_cooked_read_unsigned (regcache, SPU_LSLR_REGNUM, &lslr)
+ != REG_VALID) || !lslr)
lslr = (ULONGEST) -1;
/* Next sequential instruction is at PC + 4, except if the current
else
next_pc = (SPUADDR_ADDR (pc) + 4) & lslr;
- VEC_safe_push (CORE_ADDR, next_pcs, SPUADDR (SPUADDR_SPU (pc), next_pc));
+ next_pcs.push_back (SPUADDR (SPUADDR_SPU (pc), next_pc));
if (is_branch (insn, &offset, ®))
{
if (reg == SPU_PC_REGNUM)
target += SPUADDR_ADDR (pc);
else if (reg != -1)
- target += regcache_raw_get_unsigned (regcache, reg) & -4;
+ {
+ regcache_raw_read_part (regcache, reg, 0, 4, buf);
+ target += extract_unsigned_integer (buf, 4, byte_order) & -4;
+ }
target = target & lslr;
if (target != next_pc)
- VEC_safe_push (CORE_ADDR, next_pcs, SPUADDR (SPUADDR_SPU (pc),
- target));
+ next_pcs.push_back (SPUADDR (SPUADDR_SPU (pc), target));
}
return next_pcs;
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);
+ return default_print_insn (memaddr, &spu_info);
}
/* Now go and fiddle with all the LMAs. */
ALL_OBJFILE_OSECTIONS (objfile, osect)
{
- bfd *obfd = objfile->obfd;
asection *bsect = osect->the_bfd_section;
int ndx = osect - objfile->sections;
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)
struct symbol *sym;
struct symtab_and_line sal;
- sym = block_lookup_symbol (block, "main", VAR_DOMAIN);
+ sym = block_lookup_symbol (block, "main",
+ symbol_name_match_type::SEARCH_NAME,
+ VAR_DOMAIN);
if (sym)
{
fixup_symbol_section (sym, objfile);
/* Use a numerical address for the set_breakpoint command to avoid having
the breakpoint re-set incorrectly. */
- location = new_address_location (pc, NULL, 0);
- 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);
}
type = lookup_pointer_type (type);
addr = BMSYMBOL_VALUE_ADDRESS (msymbol);
- call_function_by_hand (value_from_pointer (type, addr), 0, NULL);
+ call_function_by_hand (value_from_pointer (type, addr), NULL, 0, NULL);
}
}
/* "info spu" commands. */
static void
-info_spu_event_command (char *args, int from_tty)
+info_spu_event_command (const char *args, int from_tty)
{
struct frame_info *frame = get_selected_frame (NULL);
ULONGEST event_status = 0;
ULONGEST event_mask = 0;
- struct cleanup *chain;
gdb_byte buf[100];
char annex[32];
LONGEST len;
buf[len] = '\0';
event_mask = strtoulst ((char *) buf, NULL, 16);
- chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "SPUInfoEvent");
+ ui_out_emit_tuple tuple_emitter (current_uiout, "SPUInfoEvent");
if (current_uiout->is_mi_like_p ())
{
printf_filtered (_("Event Status 0x%s\n"), phex (event_status, 4));
printf_filtered (_("Event Mask 0x%s\n"), phex (event_mask, 4));
}
-
- do_cleanups (chain);
}
static void
-info_spu_signal_command (char *args, int from_tty)
+info_spu_signal_command (const char *args, int from_tty)
{
struct frame_info *frame = get_selected_frame (NULL);
struct gdbarch *gdbarch = get_frame_arch (frame);
ULONGEST signal2 = 0;
ULONGEST signal2_type = 0;
int signal2_pending = 0;
- struct cleanup *chain;
char annex[32];
gdb_byte buf[100];
LONGEST len;
buf[len] = '\0';
signal2_type = strtoulst ((char *) buf, NULL, 16);
- chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "SPUInfoSignal");
+ ui_out_emit_tuple tuple_emitter (current_uiout, "SPUInfoSignal");
if (current_uiout->is_mi_like_p ())
{
else
printf_filtered (_("(Type Overwrite)\n"));
}
-
- do_cleanups (chain);
}
static void
info_spu_mailbox_list (gdb_byte *buf, int nr, enum bfd_endian byte_order,
const char *field, const char *msg)
{
- struct cleanup *chain;
int i;
if (nr <= 0)
return;
- chain = make_cleanup_ui_out_table_begin_end (current_uiout, 1, nr, "mbox");
+ ui_out_emit_table table_emitter (current_uiout, 1, nr, "mbox");
current_uiout->table_header (32, ui_left, field, msg);
current_uiout->table_body ();
for (i = 0; i < nr; i++)
{
- struct cleanup *val_chain;
- ULONGEST val;
- val_chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "mbox");
- val = extract_unsigned_integer (buf + 4*i, 4, byte_order);
- current_uiout->field_fmt (field, "0x%s", phex (val, 4));
- do_cleanups (val_chain);
+ {
+ ULONGEST val;
+ ui_out_emit_tuple tuple_emitter (current_uiout, "mbox");
+ val = extract_unsigned_integer (buf + 4*i, 4, byte_order);
+ current_uiout->field_fmt (field, "0x%s", phex (val, 4));
+ }
if (!current_uiout->is_mi_like_p ())
printf_filtered ("\n");
}
-
- do_cleanups (chain);
}
static void
-info_spu_mailbox_command (char *args, int from_tty)
+info_spu_mailbox_command (const char *args, int from_tty)
{
struct frame_info *frame = get_selected_frame (NULL);
struct gdbarch *gdbarch = get_frame_arch (frame);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct cleanup *chain;
char annex[32];
gdb_byte buf[1024];
LONGEST len;
id = get_frame_register_unsigned (frame, SPU_ID_REGNUM);
- chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "SPUInfoMailbox");
+ ui_out_emit_tuple tuple_emitter (current_uiout, "SPUInfoMailbox");
xsnprintf (annex, sizeof annex, "%d/mbox_info", id);
len = target_read (¤t_target, TARGET_OBJECT_SPU, annex,
info_spu_mailbox_list (buf, len / 4, byte_order,
"wbox", "SPU Inbound Mailbox");
-
- do_cleanups (chain);
}
static ULONGEST
int *seq = XALLOCAVEC (int, nr);
int done = 0;
- struct cleanup *chain;
int i, j;
nr = i;
- chain = make_cleanup_ui_out_table_begin_end (current_uiout, 10, nr,
- "dma_cmd");
+ ui_out_emit_table table_emitter (current_uiout, 10, nr, "dma_cmd");
current_uiout->table_header (7, ui_left, "opcode", "Opcode");
current_uiout->table_header (3, ui_left, "tag", "Tag");
for (i = 0; i < nr; i++)
{
- struct cleanup *cmd_chain;
ULONGEST mfc_cq_dw0;
ULONGEST mfc_cq_dw1;
ULONGEST mfc_cq_dw2;
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");
+ {
+ ui_out_emit_tuple tuple_emitter (current_uiout, "cmd");
- if (spu_mfc_opcode[mfc_cmd_opcode])
- current_uiout->field_string ("opcode", spu_mfc_opcode[mfc_cmd_opcode]);
- else
- current_uiout->field_int ("opcode", mfc_cmd_opcode);
+ if (spu_mfc_opcode[mfc_cmd_opcode])
+ current_uiout->field_string ("opcode", spu_mfc_opcode[mfc_cmd_opcode]);
+ else
+ current_uiout->field_int ("opcode", mfc_cmd_opcode);
- current_uiout->field_int ("tag", mfc_cmd_tag);
- current_uiout->field_int ("tid", tclass_id);
- current_uiout->field_int ("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)
- current_uiout->field_fmt ("ea", "0x%s", phex (mfc_ea, 8));
- else
- current_uiout->field_skip ("ea");
+ if (ea_valid_p)
+ current_uiout->field_fmt ("ea", "0x%s", phex (mfc_ea, 8));
+ else
+ current_uiout->field_skip ("ea");
- current_uiout->field_fmt ("lsa", "0x%05x", mfc_lsa << 4);
- if (qw_valid_p)
- current_uiout->field_fmt ("size", "0x%05x", mfc_size << 4);
- else
- current_uiout->field_fmt ("size", "0x%05x", mfc_size);
+ current_uiout->field_fmt ("lsa", "0x%05x", mfc_lsa << 4);
+ if (qw_valid_p)
+ current_uiout->field_fmt ("size", "0x%05x", mfc_size << 4);
+ else
+ current_uiout->field_fmt ("size", "0x%05x", mfc_size);
- if (list_valid_p)
- {
- current_uiout->field_fmt ("lstaddr", "0x%05x", list_lsa << 3);
- current_uiout->field_fmt ("lstsize", "0x%05x", list_size << 3);
- }
- else
- {
- current_uiout->field_skip ("lstaddr");
- current_uiout->field_skip ("lstsize");
- }
-
- if (cmd_error_p)
- current_uiout->field_string ("error_p", "*");
- else
- current_uiout->field_skip ("error_p");
+ if (list_valid_p)
+ {
+ current_uiout->field_fmt ("lstaddr", "0x%05x", list_lsa << 3);
+ current_uiout->field_fmt ("lstsize", "0x%05x", list_size << 3);
+ }
+ else
+ {
+ current_uiout->field_skip ("lstaddr");
+ current_uiout->field_skip ("lstsize");
+ }
- do_cleanups (cmd_chain);
+ if (cmd_error_p)
+ current_uiout->field_string ("error_p", "*");
+ else
+ current_uiout->field_skip ("error_p");
+ }
if (!current_uiout->is_mi_like_p ())
printf_filtered ("\n");
}
-
- do_cleanups (chain);
}
static void
-info_spu_dma_command (char *args, int from_tty)
+info_spu_dma_command (const char *args, int from_tty)
{
struct frame_info *frame = get_selected_frame (NULL);
struct gdbarch *gdbarch = get_frame_arch (frame);
ULONGEST dma_info_status;
ULONGEST dma_info_stall_and_notify;
ULONGEST dma_info_atomic_command_status;
- struct cleanup *chain;
char annex[32];
gdb_byte buf[1024];
LONGEST len;
dma_info_atomic_command_status
= extract_unsigned_integer (buf + 32, 8, byte_order);
- chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "SPUInfoDMA");
+ ui_out_emit_tuple tuple_emitter (current_uiout, "SPUInfoDMA");
if (current_uiout->is_mi_like_p ())
{
}
info_spu_dma_cmdlist (buf + 40, 16, byte_order);
- do_cleanups (chain);
}
static void
-info_spu_proxydma_command (char *args, int from_tty)
+info_spu_proxydma_command (const char *args, int from_tty)
{
struct frame_info *frame = get_selected_frame (NULL);
struct gdbarch *gdbarch = get_frame_arch (frame);
ULONGEST dma_info_type;
ULONGEST dma_info_mask;
ULONGEST dma_info_status;
- struct cleanup *chain;
char annex[32];
gdb_byte buf[1024];
LONGEST len;
dma_info_mask = extract_unsigned_integer (buf + 8, 8, byte_order);
dma_info_status = extract_unsigned_integer (buf + 16, 8, byte_order);
- chain = make_cleanup_ui_out_tuple_begin_end (current_uiout,
- "SPUInfoProxyDMA");
+ ui_out_emit_tuple tuple_emitter (current_uiout, "SPUInfoProxyDMA");
if (current_uiout->is_mi_like_p ())
{
}
info_spu_dma_cmdlist (buf + 24, 8, byte_order);
- do_cleanups (chain);
}
static void
-info_spu_command (char *args, int from_tty)
+info_spu_command (const char *args, int from_tty)
{
printf_unfiltered (_("\"info spu\" must be followed by "
"the name of an SPU facility.\n"));
/* Root of all "set spu "/"show spu " commands. */
static void
-show_spu_command (char *args, int from_tty)
+show_spu_command (const char *args, int from_tty)
{
help_list (showspucmdlist, "show spu ", all_commands, gdb_stdout);
}
static void
-set_spu_command (char *args, int from_tty)
+set_spu_command (const char *args, int from_tty)
{
help_list (setspucmdlist, "set spu ", all_commands, gdb_stdout);
}
int id = -1;
/* Which spufs ID was requested as address space? */
- if (info.tdep_info)
- id = *(int *)info.tdep_info;
+ if (info.id)
+ id = *info.id;
/* For objfile architectures of SPU solibs, decode the ID from the name.
This assumes the filename convention employed by solib-spu.c. */
else if (info.abfd)
set_gdbarch_address_class_name_to_type_flags
(gdbarch, spu_address_class_name_to_type_flags);
+ /* We need to support more than "addr_bit" significant address bits
+ in order to support SPUADDR_ADDR encoded values. */
+ set_gdbarch_significant_addr_bit (gdbarch, 64);
/* Inferior function calls. */
set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
return gdbarch;
}
-/* Provide a prototype to silence -Wmissing-prototypes. */
-extern initialize_file_ftype _initialize_spu_tdep;
-
void
_initialize_spu_tdep (void)
{
register_gdbarch_init (bfd_arch_spu, spu_gdbarch_init);
/* Add ourselves to objfile event chain. */
- observer_attach_new_objfile (spu_overlay_new_objfile);
+ gdb::observers::new_objfile.attach (spu_overlay_new_objfile);
spu_overlay_data = register_objfile_data ();
/* Install spu stop-on-load handler. */
- observer_attach_new_objfile (spu_catch_start);
+ gdb::observers::new_objfile.attach (spu_catch_start);
/* Add ourselves to normal_stop event chain. */
- observer_attach_normal_stop (spu_attach_normal_stop);
+ gdb::observers::normal_stop.attach (spu_attach_normal_stop);
/* Add root prefix command for all "set spu"/"show spu" commands. */
add_prefix_cmd ("spu", no_class, set_spu_command,