/* Target-dependent code for Renesas Super-H, for GDB.
- Copyright (C) 1993-2005, 2007-2012 Free Software Foundation, Inc.
+ Copyright (C) 1993-2016 Free Software Foundation, Inc.
This file is part of GDB.
#include "value.h"
#include "dis-asm.h"
#include "inferior.h"
-#include "gdb_string.h"
-#include "gdb_assert.h"
#include "arch-utils.h"
#include "floatformat.h"
#include "regcache.h"
#include "dwarf2.h"
/* registers numbers shared with the simulator. */
#include "gdb/sim-sh.h"
+#include <algorithm>
/* List of "set sh ..." and "show sh ..." commands. */
static struct cmd_list_element *setshcmdlist = NULL;
return register_names[reg_nr];
}
-static const unsigned char *
-sh_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr)
+/* Implement the breakpoint_kind_from_pc gdbarch method. */
+
+static int
+sh_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
- /* 0xc3c3 is trapa #c3, and it works in big and little endian modes. */
- static unsigned char breakpoint[] = { 0xc3, 0xc3 };
+ return 2;
+}
+
+/* Implement the sw_breakpoint_from_kind gdbarch method. */
+
+static const gdb_byte *
+sh_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
+{
+ *size = kind;
/* For remote stub targets, trapa #20 is used. */
if (strcmp (target_shortname, "remote") == 0)
static unsigned char little_remote_breakpoint[] = { 0x20, 0xc3 };
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
- {
- *lenptr = sizeof (big_remote_breakpoint);
- return big_remote_breakpoint;
- }
+ return big_remote_breakpoint;
else
- {
- *lenptr = sizeof (little_remote_breakpoint);
- return little_remote_breakpoint;
- }
+ return little_remote_breakpoint;
}
+ else
+ {
+ /* 0xc3c3 is trapa #c3, and it works in big and little endian
+ modes. */
+ static unsigned char breakpoint[] = { 0xc3, 0xc3 };
- *lenptr = sizeof (breakpoint);
- return breakpoint;
+ return breakpoint;
+ }
}
/* Prologue looks like
{
pc += 2;
/* Don't go any further than six more instructions. */
- limit_pc = min (limit_pc, pc + (2 * 6));
+ limit_pc = std::min (limit_pc, pc + (2 * 6));
cache->uses_fp = 1;
/* At this point, only allow argument register moves to other
{
post_prologue_pc = skip_prologue_using_sal (gdbarch, func_addr);
if (post_prologue_pc != 0)
- return max (pc, post_prologue_pc);
+ return std::max (pc, post_prologue_pc);
}
/* Can't determine prologue from the symbol table, need to examine
/* Do not allow limit_pc to be past the function end, if we know
where that end is... */
if (func_end_addr != 0)
- limit_pc = min (limit_pc, func_end_addr);
+ limit_pc = std::min (limit_pc, func_end_addr);
cache.sp_offset = -4;
post_prologue_pc = sh_analyze_prologue (gdbarch, pc, limit_pc, &cache, 0);
to R7. */
/* Helper function to justify value in register according to endianess. */
-static char *
+static const gdb_byte *
sh_justify_value_in_reg (struct gdbarch *gdbarch, struct value *val, int len)
{
- static char valbuf[4];
+ static gdb_byte valbuf[4];
memset (valbuf, 0, sizeof (valbuf));
if (len < 4)
{
/* value gets right-justified in the register or stack word. */
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
- memcpy (valbuf + (4 - len), (char *) value_contents (val), len);
+ memcpy (valbuf + (4 - len), value_contents (val), len);
else
- memcpy (valbuf, (char *) value_contents (val), len);
+ memcpy (valbuf, value_contents (val), len);
return valbuf;
}
- return (char *) value_contents (val);
+ return value_contents (val);
}
/* Helper function to eval number of bytes to allocate on stack. */
struct type *func_type = value_type (function);
struct type *type;
CORE_ADDR regval;
- char *val;
+ const gdb_byte *val;
int len, reg_size = 0;
int pass_on_stack = 0;
int treat_as_flt;
struct type *func_type = value_type (function);
struct type *type;
CORE_ADDR regval;
- char *val;
+ const gdb_byte *val;
int len, reg_size = 0;
int pass_on_stack = 0;
int last_reg_arg = INT_MAX;
TYPE, and copy that, in virtual format, into VALBUF. */
static void
sh_extract_return_value_nofpu (struct type *type, struct regcache *regcache,
- void *valbuf)
+ gdb_byte *valbuf)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int len = TYPE_LENGTH (type);
- int return_register = R0_REGNUM;
- int offset;
if (len <= 4)
{
{
int i, regnum = R0_REGNUM;
for (i = 0; i < len; i += 4)
- regcache_raw_read (regcache, regnum++, (char *) valbuf + i);
+ regcache_raw_read (regcache, regnum++, valbuf + i);
}
else
error (_("bad size for return value"));
static void
sh_extract_return_value_fpu (struct type *type, struct regcache *regcache,
- void *valbuf)
+ gdb_byte *valbuf)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
if (sh_treat_as_flt_p (type))
for (i = 0; i < len; i += 4)
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
regcache_raw_read (regcache, regnum++,
- (char *) valbuf + len - 4 - i);
+ valbuf + len - 4 - i);
else
- regcache_raw_read (regcache, regnum++, (char *) valbuf + i);
+ regcache_raw_read (regcache, regnum++, valbuf + i);
}
else
sh_extract_return_value_nofpu (type, regcache, valbuf);
the result is stored in r0, left-justified. */
static void
sh_store_return_value_nofpu (struct type *type, struct regcache *regcache,
- const void *valbuf)
+ const gdb_byte *valbuf)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
{
int i, regnum = R0_REGNUM;
for (i = 0; i < len; i += 4)
- regcache_raw_write (regcache, regnum++, (char *) valbuf + i);
+ regcache_raw_write (regcache, regnum++, valbuf + i);
}
}
static void
sh_store_return_value_fpu (struct type *type, struct regcache *regcache,
- const void *valbuf)
+ const gdb_byte *valbuf)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
if (sh_treat_as_flt_p (type))
for (i = 0; i < len; i += 4)
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
regcache_raw_write (regcache, regnum++,
- (char *) valbuf + len - 4 - i);
+ valbuf + len - 4 - i);
else
- regcache_raw_write (regcache, regnum++, (char *) valbuf + i);
+ regcache_raw_write (regcache, regnum++, valbuf + i);
}
else
sh_store_return_value_nofpu (type, regcache, valbuf);
static void
sh_register_convert_to_virtual (struct gdbarch *gdbarch, int regnum,
- struct type *type, char *from, char *to)
+ struct type *type, gdb_byte *from, gdb_byte *to)
{
if (gdbarch_byte_order (gdbarch) != BFD_ENDIAN_LITTLE)
{
static void
sh_register_convert_to_raw (struct gdbarch *gdbarch, struct type *type,
- int regnum, const void *from, void *to)
+ int regnum, const gdb_byte *from, gdb_byte *to)
{
if (gdbarch_byte_order (gdbarch) != BFD_ENDIAN_LITTLE)
{
int reg_nr, gdb_byte *buffer)
{
int base_regnum;
- char temp_buffer[MAX_REGISTER_SIZE];
+ gdb_byte temp_buffer[MAX_REGISTER_SIZE];
enum register_status status;
if (reg_nr == PSEUDO_BANK_REGNUM)
int reg_nr, const gdb_byte *buffer)
{
int base_regnum, portion;
- char temp_buffer[MAX_REGISTER_SIZE];
+ gdb_byte temp_buffer[MAX_REGISTER_SIZE];
if (reg_nr == PSEUDO_BANK_REGNUM)
{
/* Write the real regs for which this one is an alias. */
for (portion = 0; portion < 4; portion++)
regcache_raw_write (regcache, base_regnum + portion,
- ((char *) buffer
+ (buffer
+ register_size (gdbarch,
base_regnum) * portion));
}
int i;
if (*this_cache)
- return *this_cache;
+ return (struct sh_frame_cache *) *this_cache;
cache = sh_alloc_frame_cache ();
*this_cache = cache;
if (*this_cache == NULL)
*this_cache = sh_make_stub_cache (this_frame);
- cache = *this_cache;
+ cache = (struct sh_frame_cache *) *this_cache;
*this_id = frame_id_build (cache->saved_sp, get_frame_pc (this_frame));
}
CORE_ADDR addr_in_block;
addr_in_block = get_frame_address_in_block (this_frame);
- if (in_plt_section (addr_in_block, NULL))
+ if (in_plt_section (addr_in_block))
return 1;
return 0;
sh_stub_unwind_sniffer
};
-/* The epilogue is defined here as the area at the end of a function,
+/* Implement the stack_frame_destroyed_p gdbarch method.
+
+ The epilogue is defined here as the area at the end of a function,
either on the `ret' instruction itself or after an instruction which
destroys the function's stack frame. */
+
static int
-sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+sh_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR func_addr = 0, func_end = 0;
/* The following two regsets have the same contents, so it is tempting to
unify them, but they are distiguished by their address, so don't. */
-struct regset sh_corefile_gregset =
+const struct regset sh_corefile_gregset =
{
NULL,
sh_corefile_supply_regset,
sh_corefile_collect_regset
};
-static struct regset sh_corefile_fpregset =
+static const struct regset sh_corefile_fpregset =
{
NULL,
sh_corefile_supply_regset,
sh_corefile_collect_regset
};
-static const struct regset *
-sh_regset_from_core_section (struct gdbarch *gdbarch, const char *sect_name,
- size_t sect_size)
+static void
+sh_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- if (tdep->core_gregmap && strcmp (sect_name, ".reg") == 0)
- return &sh_corefile_gregset;
-
- if (tdep->core_fpregmap && strcmp (sect_name, ".reg2") == 0)
- return &sh_corefile_fpregset;
+ if (tdep->core_gregmap != NULL)
+ cb (".reg", tdep->sizeof_gregset, &sh_corefile_gregset, NULL, cb_data);
- return NULL;
+ if (tdep->core_fpregmap != NULL)
+ cb (".reg2", tdep->sizeof_fpregset, &sh_corefile_fpregset, NULL, cb_data);
}
/* This is the implementation of gdbarch method
/* None found, create a new architecture from the information
provided. */
- tdep = XZALLOC (struct gdbarch_tdep);
+ tdep = XCNEW (struct gdbarch_tdep);
gdbarch = gdbarch_alloc (&info, tdep);
set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
set_gdbarch_register_type (gdbarch, sh_default_register_type);
set_gdbarch_register_reggroup_p (gdbarch, sh_register_reggroup_p);
- set_gdbarch_breakpoint_from_pc (gdbarch, sh_breakpoint_from_pc);
+ set_gdbarch_breakpoint_kind_from_pc (gdbarch, sh_breakpoint_kind_from_pc);
+ set_gdbarch_sw_breakpoint_from_kind (gdbarch, sh_sw_breakpoint_from_kind);
set_gdbarch_print_insn (gdbarch, print_insn_sh);
set_gdbarch_register_sim_regno (gdbarch, legacy_register_sim_regno);
set_gdbarch_dummy_id (gdbarch, sh_dummy_id);
frame_base_set_default (gdbarch, &sh_frame_base);
- set_gdbarch_in_function_epilogue_p (gdbarch, sh_in_function_epilogue_p);
+ set_gdbarch_stack_frame_destroyed_p (gdbarch, sh_stack_frame_destroyed_p);
dwarf2_frame_set_init_reg (gdbarch, sh_dwarf2_frame_init_reg);
- set_gdbarch_regset_from_core_section (gdbarch, sh_regset_from_core_section);
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, sh_iterate_over_regset_sections);
switch (info.bfd_arch_info->mach)
{