/* SPU target-dependent code for GDB, the GNU debugger.
- Copyright (C) 2006-2017 Free Software Foundation, Inc.
+ Copyright (C) 2006-2019 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);
memset (reg, 0, sizeof reg);
- target_read (¤t_target, TARGET_OBJECT_SPU, annex,
+ target_read (current_top_target (), TARGET_OBJECT_SPU, annex,
reg, 0, sizeof reg);
ul = strtoulst ((char *) reg, NULL, 16);
}
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);
- target_read (¤t_target, TARGET_OBJECT_SPU, annex, buf, 0, 16);
+ target_read (current_top_target (), TARGET_OBJECT_SPU, annex, buf, 0, 16);
return status;
case SPU_SRR0_REGNUM:
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];
xsnprintf (annex, sizeof annex, "%d/%s", (int) id, regname);
xsnprintf (reg, sizeof reg, "0x%s",
phex_nz (extract_unsigned_integer (buf, 4, byte_order), 4));
- target_write (¤t_target, TARGET_OBJECT_SPU, annex,
+ target_write (current_top_target (), TARGET_OBJECT_SPU, annex,
(gdb_byte *) reg, 0, strlen (reg));
}
switch (regnum)
{
case SPU_SP_REGNUM:
- regcache_raw_read (regcache, SPU_RAW_SP_REGNUM, reg);
+ regcache->raw_read (SPU_RAW_SP_REGNUM, reg);
memcpy (reg, buf, 4);
- regcache_raw_write (regcache, SPU_RAW_SP_REGNUM, reg);
+ regcache->raw_write (SPU_RAW_SP_REGNUM, reg);
break;
case SPU_FPSCR_REGNUM:
regcache_raw_read_unsigned (regcache, SPU_ID_REGNUM, &id);
xsnprintf (annex, sizeof annex, "%d/fpcr", (int) id);
- target_write (¤t_target, TARGET_OBJECT_SPU, annex, buf, 0, 16);
+ target_write (current_top_target (), TARGET_OBJECT_SPU, annex, buf, 0, 16);
break;
case SPU_SRR0_REGNUM:
}
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);
}
{
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;
}
if (spu_scalar_value_p (type))
{
int preferred_slot = len < 4 ? 4 - len : 0;
- regcache_cooked_write_part (regcache, regnum, preferred_slot, len, in);
+ regcache->cooked_write_part (regnum, preferred_slot, len, in);
}
else
{
while (len >= 16)
{
- regcache_cooked_write (regcache, regnum++, in);
+ regcache->cooked_write (regnum++, in);
in += 16;
len -= 16;
}
if (len > 0)
- regcache_cooked_write_part (regcache, regnum, 0, len, in);
+ regcache->cooked_write_part (regnum, 0, len, in);
}
}
if (spu_scalar_value_p (type))
{
int preferred_slot = len < 4 ? 4 - len : 0;
- regcache_cooked_read_part (regcache, regnum, preferred_slot, len, out);
+ regcache->cooked_read_part (regnum, preferred_slot, len, out);
}
else
{
while (len >= 16)
{
- regcache_cooked_read (regcache, regnum++, out);
+ regcache->cooked_read (regnum++, out);
out += 16;
len -= 16;
}
if (len > 0)
- regcache_cooked_read_part (regcache, regnum, 0, len, out);
+ regcache->cooked_read_part (regnum, 0, len, out);
}
}
spu_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
struct regcache *regcache, CORE_ADDR bp_addr,
int nargs, struct value **args, CORE_ADDR sp,
- int struct_return, CORE_ADDR struct_addr)
+ function_call_return_method return_method,
+ CORE_ADDR struct_addr)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR sp_delta;
/* Set the return address. */
memset (buf, 0, sizeof buf);
store_unsigned_integer (buf, 4, byte_order, SPUADDR_ADDR (bp_addr));
- regcache_cooked_write (regcache, SPU_LR_REGNUM, buf);
+ regcache->cooked_write (SPU_LR_REGNUM, buf);
/* If STRUCT_RETURN is true, then the struct return address (in
STRUCT_ADDR) will consume the first argument-passing register.
Both adjust the register count and store that value. */
- if (struct_return)
+ if (return_method == return_method_struct)
{
memset (buf, 0, sizeof buf);
store_unsigned_integer (buf, 4, byte_order, SPUADDR_ADDR (struct_addr));
- regcache_cooked_write (regcache, regnum++, buf);
+ regcache->cooked_write (regnum++, buf);
}
/* Fill in argument registers. */
sp -= 32;
/* Store stack back chain. */
- regcache_cooked_read (regcache, SPU_RAW_SP_REGNUM, buf);
+ regcache->cooked_read (SPU_RAW_SP_REGNUM, buf);
target_write_memory (sp, buf, 16);
/* Finally, update all slots of the SP register. */
CORE_ADDR sp_slot = extract_unsigned_integer (buf + 4*i, 4, byte_order);
store_unsigned_integer (buf + 4*i, 4, byte_order, sp_slot + sp_delta);
}
- regcache_cooked_write (regcache, SPU_RAW_SP_REGNUM, buf);
+ regcache->cooked_write (SPU_RAW_SP_REGNUM, buf);
return sp;
}
{
case RETURN_VALUE_REGISTER_CONVENTION:
if (opencl_vector && TYPE_LENGTH (type) == 2)
- regcache_cooked_write_part (regcache, SPU_ARG1_REGNUM, 2, 2, in);
+ regcache->cooked_write_part (SPU_ARG1_REGNUM, 2, 2, in);
else
spu_value_to_regcache (regcache, SPU_ARG1_REGNUM, type, in);
break;
{
case RETURN_VALUE_REGISTER_CONVENTION:
if (opencl_vector && TYPE_LENGTH (type) == 2)
- regcache_cooked_read_part (regcache, SPU_ARG1_REGNUM, 2, 2, out);
+ regcache->cooked_read_part (SPU_ARG1_REGNUM, 2, 2, out);
else
spu_regcache_to_value (regcache, SPU_ARG1_REGNUM, type, out);
break;
-- this is not the correct behaviour.
The workaround is to check whether the PID we are asked to remove this
- breakpoint from (i.e. ptid_get_pid (inferior_ptid)) is different from the
+ breakpoint from (i.e. inferior_ptid.pid ()) is different from the
PID of the current inferior (i.e. current_inferior ()->pid). This is only
true in the context of detach_breakpoints. If so, we simply do nothing.
[ Note that for the fork child process, it does not matter if breakpoints
remain inserted, because those SPU contexts are not runnable anyway --
the Linux kernel allows only the original process to invoke spu_run. */
- if (ptid_get_pid (inferior_ptid) != current_inferior ()->pid)
+ if (inferior_ptid.pid () != current_inferior ()->pid)
return 0;
return default_memory_remove_breakpoint (gdbarch, bp_tgt);
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;
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
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 (reg, 0, 4, buf);
+ target += extract_unsigned_integer (buf, 4, byte_order) & -4;
+ }
target = target & lslr;
if (target != next_pc)
{
CORE_ADDR vma = extract_unsigned_integer (ovly_table + 16*i + 0,
4, byte_order);
- CORE_ADDR size = extract_unsigned_integer (ovly_table + 16*i + 4,
- 4, byte_order);
+ /* Note that this skips the "size" entry, which is at offset
+ 4. */
CORE_ADDR pos = extract_unsigned_integer (ovly_table + 16*i + 8,
4, byte_order);
CORE_ADDR buf = extract_unsigned_integer (ovly_table + 16*i + 12,
/* All sections. */
else
{
- struct objfile *objfile;
-
- ALL_OBJSECTIONS (objfile, osect)
- if (section_is_overlay (osect))
- spu_overlay_update_osect (osect);
+ for (objfile *objfile : current_program_space->objfiles ())
+ ALL_OBJFILE_OSECTIONS (objfile, osect)
+ if (section_is_overlay (osect))
+ spu_overlay_update_osect (osect);
}
}
/* 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;
if (cust != NULL)
{
const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (cust);
- struct block *block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ const struct block *block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
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);
{
struct gdbarch *gdbarch = get_frame_arch (frame);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- struct objfile *obj;
if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
return NULL;
- ALL_OBJFILES (obj)
+ for (objfile *obj : current_program_space->objfiles ())
{
if (obj->sections != obj->sections_end
&& SPUADDR_SPU (obj_section_addr (obj->sections)) == tdep->id)
type = lookup_pointer_type (type);
addr = BMSYMBOL_VALUE_ADDRESS (msymbol);
- call_function_by_hand (value_from_pointer (type, addr), NULL, 0, NULL);
+ call_function_by_hand (value_from_pointer (type, addr), 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;
id = get_frame_register_unsigned (frame, SPU_ID_REGNUM);
xsnprintf (annex, sizeof annex, "%d/event_status", id);
- len = target_read (¤t_target, TARGET_OBJECT_SPU, annex,
+ len = target_read (current_top_target (), TARGET_OBJECT_SPU, annex,
buf, 0, (sizeof (buf) - 1));
if (len <= 0)
error (_("Could not read event_status."));
event_status = strtoulst ((char *) buf, NULL, 16);
xsnprintf (annex, sizeof annex, "%d/event_mask", id);
- len = target_read (¤t_target, TARGET_OBJECT_SPU, annex,
+ len = target_read (current_top_target (), TARGET_OBJECT_SPU, annex,
buf, 0, (sizeof (buf) - 1));
if (len <= 0)
error (_("Could not read event_mask."));
ui_out_emit_tuple tuple_emitter (current_uiout, "SPUInfoEvent");
- if (current_uiout->is_mi_like_p ())
- {
- 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
- {
- printf_filtered (_("Event Status 0x%s\n"), phex (event_status, 4));
- printf_filtered (_("Event Mask 0x%s\n"), phex (event_mask, 4));
- }
+ current_uiout->text (_("Event Status "));
+ current_uiout->field_fmt ("event_status", "0x%s", phex (event_status, 4));
+ current_uiout->text ("\n");
+ current_uiout->text (_("Event Mask "));
+ current_uiout->field_fmt ("event_mask", "0x%s", phex (event_mask, 4));
+ current_uiout->text ("\n");
}
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);
id = get_frame_register_unsigned (frame, SPU_ID_REGNUM);
xsnprintf (annex, sizeof annex, "%d/signal1", id);
- len = target_read (¤t_target, TARGET_OBJECT_SPU, annex, buf, 0, 4);
+ len = target_read (current_top_target (), TARGET_OBJECT_SPU,
+ annex, buf, 0, 4);
if (len < 0)
error (_("Could not read signal1."));
else if (len == 4)
}
xsnprintf (annex, sizeof annex, "%d/signal1_type", id);
- len = target_read (¤t_target, TARGET_OBJECT_SPU, annex,
+ len = target_read (current_top_target (), TARGET_OBJECT_SPU, annex,
buf, 0, (sizeof (buf) - 1));
if (len <= 0)
error (_("Could not read signal1_type."));
signal1_type = strtoulst ((char *) buf, NULL, 16);
xsnprintf (annex, sizeof annex, "%d/signal2", id);
- len = target_read (¤t_target, TARGET_OBJECT_SPU, annex, buf, 0, 4);
+ len = target_read (current_top_target (), TARGET_OBJECT_SPU,
+ annex, buf, 0, 4);
if (len < 0)
error (_("Could not read signal2."));
else if (len == 4)
}
xsnprintf (annex, sizeof annex, "%d/signal2_type", id);
- len = target_read (¤t_target, TARGET_OBJECT_SPU, annex,
+ len = target_read (current_top_target (), TARGET_OBJECT_SPU, annex,
buf, 0, (sizeof (buf) - 1));
if (len <= 0)
error (_("Could not read signal2_type."));
current_uiout->field_fmt (field, "0x%s", phex (val, 4));
}
- if (!current_uiout->is_mi_like_p ())
- printf_filtered ("\n");
+ current_uiout->text ("\n");
}
}
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);
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,
+ len = target_read (current_top_target (), TARGET_OBJECT_SPU, annex,
buf, 0, sizeof buf);
if (len < 0)
error (_("Could not read mbox_info."));
"mbox", "SPU Outbound Mailbox");
xsnprintf (annex, sizeof annex, "%d/ibox_info", id);
- len = target_read (¤t_target, TARGET_OBJECT_SPU, annex,
+ len = target_read (current_top_target (), TARGET_OBJECT_SPU, annex,
buf, 0, sizeof buf);
if (len < 0)
error (_("Could not read ibox_info."));
"ibox", "SPU Outbound Interrupt Mailbox");
xsnprintf (annex, sizeof annex, "%d/wbox_info", id);
- len = target_read (¤t_target, TARGET_OBJECT_SPU, annex,
+ len = target_read (current_top_target (), TARGET_OBJECT_SPU, annex,
buf, 0, sizeof buf);
if (len < 0)
error (_("Could not read wbox_info."));
current_uiout->field_skip ("error_p");
}
- if (!current_uiout->is_mi_like_p ())
- printf_filtered ("\n");
+ current_uiout->text ("\n");
}
}
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);
id = get_frame_register_unsigned (frame, SPU_ID_REGNUM);
xsnprintf (annex, sizeof annex, "%d/dma_info", id);
- len = target_read (¤t_target, TARGET_OBJECT_SPU, annex,
+ len = target_read (current_top_target (), TARGET_OBJECT_SPU, annex,
buf, 0, 40 + 16 * 32);
if (len <= 0)
error (_("Could not read dma_info."));
}
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);
id = get_frame_register_unsigned (frame, SPU_ID_REGNUM);
xsnprintf (annex, sizeof annex, "%d/proxydma_info", id);
- len = target_read (¤t_target, TARGET_OBJECT_SPU, annex,
+ len = target_read (current_top_target (), TARGET_OBJECT_SPU, annex,
buf, 0, 24 + 8 * 32);
if (len <= 0)
error (_("Could not read proxydma_info."));
}
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);
}
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);
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,