/* Target-dependent code for the Fujitsu FR-V, for GDB, the GNU Debugger.
- Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008
+ Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "gdb_string.h"
#include "elf/frv.h"
#include "osabi.h"
#include "infcall.h"
+#include "solib.h"
#include "frv-tdep.h"
extern void _initialize_frv_tdep (void);
-static gdbarch_init_ftype frv_gdbarch_init;
-
-static gdbarch_register_name_ftype frv_register_name;
-static gdbarch_breakpoint_from_pc_ftype frv_breakpoint_from_pc;
-static gdbarch_adjust_breakpoint_address_ftype frv_gdbarch_adjust_breakpoint_address;
-static gdbarch_skip_prologue_ftype frv_skip_prologue;
-
-
struct frv_unwind_cache /* was struct frame_extra_info */
{
/* The previous frame's inner-most stack address. Used as this
char **register_names;
};
-#define CURRENT_VARIANT (gdbarch_tdep (current_gdbarch))
-
/* Return the FR-V ABI associated with GDBARCH. */
enum frv_abi
frv_abi (struct gdbarch *gdbarch)
return -1;
else
{
+ struct regcache *regcache = get_current_regcache ();
+
if (interp_addr != NULL)
{
ULONGEST val;
- regcache_cooked_read_unsigned (current_regcache,
+ regcache_cooked_read_unsigned (regcache,
fdpic_loadmap_interp_regnum, &val);
*interp_addr = val;
}
if (exec_addr != NULL)
{
ULONGEST val;
- regcache_cooked_read_unsigned (current_regcache,
+ regcache_cooked_read_unsigned (regcache,
fdpic_loadmap_exec_regnum, &val);
*exec_addr = val;
}
}
static const char *
-frv_register_name (int reg)
+frv_register_name (struct gdbarch *gdbarch, int reg)
{
if (reg < 0)
return "?toosmall?";
if (reg >= frv_num_regs + frv_num_pseudo_regs)
return "?toolarge?";
- return CURRENT_VARIANT->register_names[reg];
+ return gdbarch_tdep (gdbarch)->register_names[reg];
}
}
static int
-frv_register_sim_regno (int reg)
+frv_register_sim_regno (struct gdbarch *gdbarch, int reg)
{
static const int spr_map[] =
{
H_SPR_FNER1, /* fner1_regnum */
};
- gdb_assert (reg >= 0 && reg < NUM_REGS);
+ gdb_assert (reg >= 0 && reg < gdbarch_num_regs (gdbarch));
if (first_gpr_regnum <= reg && reg <= last_gpr_regnum)
return reg - first_gpr_regnum + SIM_FRV_GR0_REGNUM;
}
static const unsigned char *
-frv_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenp)
+frv_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenp)
{
static unsigned char breakpoint[] = {0xc0, 0x70, 0x00, 0x01};
*lenp = sizeof (breakpoint);
constraint that a break instruction must not appear as any but the
first instruction in the bundle. */
static CORE_ADDR
-frv_gdbarch_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
+frv_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
{
int count = max_instrs_per_bundle;
CORE_ADDR addr = bpaddr - frv_instr_size;
char instr[frv_instr_size];
int status;
- status = deprecated_read_memory_nobpt (addr, instr, sizeof instr);
+ status = target_read_memory (addr, instr, sizeof instr);
if (status != 0)
break;
because instructions may save relative to the SP, but we need
their addresses relative to the FP. */
if (fp_set)
- frame_unwind_unsigned_register (next_frame, fp_regnum, &this_base);
+ this_base = frame_unwind_register_unsigned (next_frame, fp_regnum);
else
- frame_unwind_unsigned_register (next_frame, sp_regnum, &this_base);
+ this_base = frame_unwind_register_unsigned (next_frame, sp_regnum);
for (i = 0; i < 64; i++)
if (gr_saved[i])
static CORE_ADDR
-frv_skip_prologue (CORE_ADDR pc)
+frv_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
CORE_ADDR func_addr, func_end, new_pc;
info->saved_regs = trad_frame_alloc_saved_regs (next_frame);
/* Prologue analysis does the rest... */
- frv_analyze_prologue (frame_func_unwind (next_frame), next_frame, info);
+ frv_analyze_prologue (frame_func_unwind (next_frame, NORMAL_FRAME),
+ next_frame, info);
return info;
}
internal_error (__FILE__, __LINE__, _("Illegal return value length: %d"), len);
}
-static CORE_ADDR
-frv_extract_struct_value_address (struct regcache *regcache)
-{
- ULONGEST addr;
- regcache_cooked_read_unsigned (regcache, struct_return_regnum, &addr);
- return addr;
-}
-
-static void
-frv_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
-{
- write_register (struct_return_regnum, addr);
-}
-
static CORE_ADDR
frv_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
{
_("Don't know how to return a %d-byte value."), len);
}
+enum return_value_convention
+frv_return_value (struct gdbarch *gdbarch, struct type *func_type,
+ struct type *valtype, struct regcache *regcache,
+ gdb_byte *readbuf, const gdb_byte *writebuf)
+{
+ int struct_return = TYPE_CODE (valtype) == TYPE_CODE_STRUCT
+ || TYPE_CODE (valtype) == TYPE_CODE_UNION
+ || TYPE_CODE (valtype) == TYPE_CODE_ARRAY;
+
+ if (writebuf != NULL)
+ {
+ gdb_assert (!struct_return);
+ frv_store_return_value (valtype, regcache, writebuf);
+ }
+
+ if (readbuf != NULL)
+ {
+ gdb_assert (!struct_return);
+ frv_extract_return_value (valtype, regcache, readbuf);
+ }
+
+ if (struct_return)
+ return RETURN_VALUE_STRUCT_CONVENTION;
+ else
+ return RETURN_VALUE_REGISTER_CONVENTION;
+}
+
/* Hardware watchpoint / breakpoint support for the FR500
and FR400. */
int
-frv_check_watch_resources (int type, int cnt, int ot)
+frv_check_watch_resources (struct gdbarch *gdbarch, int type, int cnt, int ot)
{
- struct gdbarch_tdep *var = CURRENT_VARIANT;
+ struct gdbarch_tdep *var = gdbarch_tdep (gdbarch);
/* Watchpoints not supported on simulator. */
if (strcmp (target_shortname, "sim") == 0)
int
frv_stopped_data_address (CORE_ADDR *addr_p)
{
+ struct frame_info *frame = get_current_frame ();
CORE_ADDR brr, dbar0, dbar1, dbar2, dbar3;
- brr = read_register (brr_regnum);
- dbar0 = read_register (dbar0_regnum);
- dbar1 = read_register (dbar1_regnum);
- dbar2 = read_register (dbar2_regnum);
- dbar3 = read_register (dbar3_regnum);
+ brr = get_frame_register_unsigned (frame, brr_regnum);
+ dbar0 = get_frame_register_unsigned (frame, dbar0_regnum);
+ dbar1 = get_frame_register_unsigned (frame, dbar1_regnum);
+ dbar2 = get_frame_register_unsigned (frame, dbar2_regnum);
+ dbar3 = get_frame_register_unsigned (frame, dbar3_regnum);
if (brr & (1<<11))
*addr_p = dbar0;
struct frame_id id;
/* The FUNC is easy. */
- func = frame_func_unwind (next_frame);
+ func = frame_func_unwind (next_frame, NORMAL_FRAME);
/* Check if the stack is empty. */
msym_stack = lookup_minimal_symbol ("_stack", NULL, NULL);
set_gdbarch_skip_prologue (gdbarch, frv_skip_prologue);
set_gdbarch_breakpoint_from_pc (gdbarch, frv_breakpoint_from_pc);
- set_gdbarch_adjust_breakpoint_address (gdbarch, frv_gdbarch_adjust_breakpoint_address);
-
- set_gdbarch_deprecated_use_struct_convention (gdbarch, always_use_struct_convention);
- set_gdbarch_extract_return_value (gdbarch, frv_extract_return_value);
+ set_gdbarch_adjust_breakpoint_address
+ (gdbarch, frv_adjust_breakpoint_address);
- set_gdbarch_deprecated_store_struct_return (gdbarch, frv_store_struct_return);
- set_gdbarch_store_return_value (gdbarch, frv_store_return_value);
- set_gdbarch_deprecated_extract_struct_value_address (gdbarch, frv_extract_struct_value_address);
+ set_gdbarch_return_value (gdbarch, frv_return_value);
/* Frame stuff. */
set_gdbarch_unwind_pc (gdbarch, frv_unwind_pc);
/* Settings that should be unnecessary. */
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
-
- set_gdbarch_remote_translate_xfer_address
- (gdbarch, generic_remote_translate_xfer_address);
-
/* Hardware watchpoint / breakpoint support. */
switch (info.bfd_arch_info->mach)
{
set_gdbarch_convert_from_func_ptr_addr (gdbarch,
frv_convert_from_func_ptr_addr);
+ set_solib_ops (gdbarch, &frv_so_ops);
+
/* Hook in ABI-specific overrides, if they have been registered. */
gdbarch_init_osabi (info, gdbarch);