struct score_frame_cache
{
CORE_ADDR base;
+ CORE_ADDR fp;
struct trad_frame_saved_reg *saved_regs;
};
fci_ext = frame_obstack_zalloc (sizeof (extra_info_t));
if ((sec = find_pc_section (pc)) == NULL)
{
- error ("Can't find section in file:%s, line:%d!", __FILE__, __LINE__);
+ error ("Error: Can't find section in file:%s, line:%d!",
+ __FILE__, __LINE__);
return;
}
int low = 0, mid, high = priv->size / 32;
char *ptr;
do
-
{
CORE_ADDR pdr_pc;
mid = (low + high) / 2;
}
#endif
-static struct type *
-score_register_type (struct gdbarch *gdbarch, int regnum)
+#if 0
+/* Open these functions if build with simulator. */
+
+int
+score_target_can_use_watch (int type, int cnt, int othertype)
{
- gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
- return builtin_type_uint32;
+ if (strcmp (current_target.to_shortname, "sim") == 0)
+ {
+ return soc_gh_can_use_watch (type, cnt);
+ }
+ else
+ {
+ return (*current_target.to_can_use_hw_breakpoint) (type, cnt, othertype);
+ }
+}
+
+int
+score_stopped_by_watch (void)
+{
+ if (strcmp (current_target.to_shortname, "sim") == 0)
+ {
+ return soc_gh_stopped_by_watch ();
+ }
+ else
+ {
+ return (*current_target.to_stopped_by_watchpoint) ();
+ }
}
-static LONGEST
-score_read_unsigned_register (int regnum)
+int
+score_target_insert_watchpoint (CORE_ADDR addr, int len, int type)
{
- LONGEST val;
- regcache_cooked_read_unsigned (current_regcache, regnum, &val);
- return val;
+ if (strcmp (current_target.to_shortname, "sim") == 0)
+ {
+ return soc_gh_add_watch (addr, len, type);
+ }
+ else
+ {
+ return (*current_target.to_insert_watchpoint) (addr, len, type);
+ }
}
-static CORE_ADDR
-score_read_sp (void)
+int
+score_target_remove_watchpoint (CORE_ADDR addr, int len, int type)
+{
+ if (strcmp (current_target.to_shortname, "sim") == 0)
+ {
+ return soc_gh_del_watch (addr, len, type);
+ }
+ else
+ {
+ return (*current_target.to_remove_watchpoint) (addr, len, type);
+ }
+}
+
+int
+score_target_insert_hw_breakpoint (struct bp_target_info * bp_tgt)
+{
+ if (strcmp (current_target.to_shortname, "sim") == 0)
+ {
+ return soc_gh_add_hardbp (bp_tgt->placed_address);
+ }
+ else
+ {
+ return (*current_target.to_insert_hw_breakpoint) (bp_tgt);
+ }
+}
+
+int
+score_target_remove_hw_breakpoint (struct bp_target_info * bp_tgt)
+{
+ if (strcmp (current_target.to_shortname, "sim") == 0)
+ {
+ return soc_gh_del_hardbp (bp_tgt->placed_address);
+ }
+ else
+ {
+ return (*current_target.to_remove_hw_breakpoint) (bp_tgt);
+ }
+}
+#endif
+
+static struct type *
+score_register_type (struct gdbarch *gdbarch, int regnum)
{
- return score_read_unsigned_register (SCORE_SP_REGNUM);
+ gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
+ return builtin_type_uint32;
}
static CORE_ADDR
return frame_unwind_register_unsigned (next_frame, SCORE_PC_REGNUM);
}
+static CORE_ADDR
+score_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+ return frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
+}
+
static const char *
score_register_name (int regnum)
{
static int
score_print_insn (bfd_vma memaddr, struct disassemble_info *info)
{
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
return print_insn_big_score (memaddr, info);
else
return print_insn_little_score (memaddr, info);
if ((ret = target_read_memory (*pcptr & ~0x3, buf, SCORE_INSTLEN)) != 0)
{
- memory_error (ret, *pcptr);
+ error ("Error: target_read_memory in file:%s, line:%d!",
+ __FILE__, __LINE__);
}
raw = extract_unsigned_integer (buf, SCORE_INSTLEN);
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
{
if (!(raw & 0x80008000))
{
reg_offset = 0;
break;
default:
- internal_error (__FILE__, __LINE__, _("score_xfer_register error!"));
+ error ("Error: score_xfer_register in file:%s, line:%d!",
+ __FILE__, __LINE__);
}
if (readbuf != NULL)
int xfer = SCORE_REGSIZE;
if (offset + xfer > TYPE_LENGTH (type))
xfer = TYPE_LENGTH (type) - offset;
- score_xfer_register (regcache, regnum, xfer, TARGET_BYTE_ORDER,
+ score_xfer_register (regcache, regnum, xfer,
+ gdbarch_byte_order (current_gdbarch),
readbuf, writebuf, offset);
}
return RETURN_VALUE_REGISTER_CONVENTION;
}
static struct frame_id
-score_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+score_unwind_dummy_id (struct gdbarch *gdbarch,
+ struct frame_info *next_frame)
{
return frame_id_build (
frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM),
{
enum type_code typecode = TYPE_CODE (type);
- if (typecode == TYPE_CODE_INT && TYPE_LENGTH (type) == 8)
- return 1;
- if (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8)
+ if ((typecode == TYPE_CODE_INT && TYPE_LENGTH (type) == 8)
+ || (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8))
return 1;
else if (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
{
argreg = SCORE_BEGIN_ARG_REGNUM;
- /* Step 3, Check if struct return then save the struct address to r4 and
- increase the stack_offset by 4. */
+ /* Step 3, Check if struct return then save the struct address to
+ r4 and increase the stack_offset by 4. */
if (struct_return)
{
regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
}
/* Step 4, Load arguments:
- If arg length is too long (> 4 bytes),
- then split the arg and save every parts. */
+ If arg length is too long (> 4 bytes), then split the arg and
+ save every parts. */
for (argnum = 0; argnum < nargs; argnum++)
{
struct value *arg = args[argnum];
arglen = TYPE_LENGTH (arg_type);
odd_sized_struct_p = (arglen > SCORE_REGSIZE
- && arglen % SCORE_REGSIZE != 0);
+ && arglen % SCORE_REGSIZE != 0);
/* If a arg should be aligned to 8 bytes (long long or double),
the value should be put to even register numbers. */
Where X is a hole. */
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG
&& (typecode == TYPE_CODE_STRUCT
|| typecode == TYPE_CODE_UNION)
&& argreg > SCORE_LAST_ARG_REGNUM
ULONGEST regval = extract_unsigned_integer (val, partial_len);
/* The last part of a arg should shift left when
- TARGET_BYTE_ORDER is BFD_ENDIAN_BIG. */
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+ gdbarch_byte_order is BFD_ENDIAN_BIG. */
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG
&& arg_last_part_p == 1
&& (typecode == TYPE_CODE_STRUCT
|| typecode == TYPE_CODE_UNION))
return sp;
}
+static char *
+score_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size)
+{
+ int ret;
+ char *memblock = NULL;
+
+ if (size < 0)
+ {
+ error ("Error: malloc size < 0 in file:%s, line:%d!",
+ __FILE__, __LINE__);
+ return NULL;
+ }
+ else if (size == 0)
+ return NULL;
+
+ memblock = (char *) xmalloc (size);
+ memset (memblock, 0, size);
+ ret = target_read_memory (addr & ~0x3, memblock, size);
+ if (ret)
+ {
+ error ("Error: target_read_memory in file:%s, line:%d!",
+ __FILE__, __LINE__);
+ return NULL;
+ }
+ return memblock;
+}
+
+static void
+score_free_memblock (char *memblock)
+{
+ xfree (memblock);
+}
+
+static void
+score_adjust_memblock_ptr (char **memblock, CORE_ADDR prev_pc,
+ CORE_ADDR cur_pc)
+{
+ if (prev_pc == -1)
+ {
+ /* First time call this function, do nothing. */
+ }
+ else if (cur_pc - prev_pc == 2 && (cur_pc & 0x3) == 0)
+ {
+ /* First 16-bit instruction, then 32-bit instruction. */
+ *memblock += SCORE_INSTLEN;
+ }
+ else if (cur_pc - prev_pc == 4)
+ {
+ /* Is 32-bit instruction, increase MEMBLOCK by 4. */
+ *memblock += SCORE_INSTLEN;
+ }
+}
+
static inst_t *
-score_fetch_instruction (CORE_ADDR addr)
+score_fetch_inst (CORE_ADDR addr, char *memblock)
{
static inst_t inst = { 0, 0 };
- char buf[SCORE_INSTLEN];
+ char buf[SCORE_INSTLEN] = { 0 };
int big;
- int ret = target_read_memory (addr & ~0x3, buf, SCORE_INSTLEN);
- unsigned int raw;
+ int ret;
- if (ret)
+ if (target_has_execution && memblock != NULL)
{
- memory_error (ret, addr);
- return 0;
+ /* Fetch instruction from local MEMBLOCK. */
+ memcpy (buf, memblock, SCORE_INSTLEN);
}
+ else
+ {
+ /* Fetch instruction from target. */
+ ret = target_read_memory (addr & ~0x3, buf, SCORE_INSTLEN);
+ if (ret)
+ {
+ error ("Error: target_read_memory in file:%s, line:%d!",
+ __FILE__, __LINE__);
+ return 0;
+ }
+ }
+
inst.raw = extract_unsigned_integer (buf, SCORE_INSTLEN);
inst.is15 = !(inst.raw & 0x80008000);
inst.v = RM_PBITS (inst.raw);
- big = (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG);
-
+ big = (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG);
if (inst.is15)
{
if (big ^ ((addr & 0x2) == 2))
int iscan = 32, stack_sub = 0;
while (iscan-- > 0)
{
- inst_t *inst = score_fetch_instruction (cpc);
+ inst_t *inst = score_fetch_inst (cpc, NULL);
if (!inst)
break;
if (!inst->is15 && !stack_sub
static int
score_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
{
- inst_t *inst = score_fetch_instruction (cur_pc);
+ inst_t *inst = score_fetch_inst (cur_pc, NULL);
if (inst->v == 0x23)
return 1; /* mv! r0, r2 */
struct score_frame_cache *this_cache)
{
CORE_ADDR sp;
+ CORE_ADDR fp;
CORE_ADDR cur_pc = startaddr;
int sp_offset = 0;
int fp_offset_p = 0;
int inst_len = 0;
+ char *memblock = NULL;
+ char *memblock_ptr = NULL;
+ CORE_ADDR prev_pc = -1;
+
+ /* Allocate MEMBLOCK if PC - STARTADDR > 0. */
+ memblock_ptr = memblock =
+ score_malloc_and_get_memblock (startaddr, pc - startaddr);
+
sp = frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
+ fp = frame_unwind_register_unsigned (next_frame, SCORE_FP_REGNUM);
- for (; cur_pc < pc; cur_pc += inst_len)
+ for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len)
{
- inst_t *inst = score_fetch_instruction (cur_pc);
+ inst_t *inst = NULL;
+ if (memblock != NULL)
+ {
+ /* Reading memory block from target succefully and got all
+ the instructions(from STARTADDR to PC) needed. */
+ score_adjust_memblock_ptr (&memblock, prev_pc, cur_pc);
+ inst = score_fetch_inst (cur_pc, memblock);
+ }
+ else
+ {
+ /* Otherwise, we fetch 4 bytes from target, and GDB also
+ work correctly. */
+ inst = score_fetch_inst (cur_pc, NULL);
+ }
+
if (inst->is15 == 1)
{
inst_len = SCORE16_INSTLEN;
{
unsigned int save_v = inst->v;
inst_t *inst2 =
- score_fetch_instruction (cur_pc + SCORE_INSTLEN);
+ score_fetch_inst (cur_pc + SCORE_INSTLEN, NULL);
if (inst2->v == 0x23)
- /* mv! r0, r2 */
- sp_offset -= G_FLD (save_v, 16, 1);
+ {
+ /* mv! r0, r2 */
+ sp_offset -= G_FLD (save_v, 16, 1);
+ }
}
}
}
sp + sp_offset - fp_offset;
}
- /* Save SP. */
- this_cache->base =
- frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM) + sp_offset;
+ /* Save SP and FP. */
+ this_cache->base = sp + sp_offset;
+ this_cache->fp = fp;
+
+ /* Don't forget to free MEMBLOCK if we allocated it. */
+ if (memblock_ptr != NULL)
+ score_free_memblock (memblock_ptr);
}
static struct score_frame_cache *
struct score_frame_cache *info = score_make_prologue_cache (next_frame,
this_cache);
(*this_id) = frame_id_build (info->base,
- frame_func_unwind (next_frame, NORMAL_FRAME));
+ frame_func_unwind (next_frame, NORMAL_FRAME));
}
static void
{
struct score_frame_cache *info =
score_make_prologue_cache (next_frame, this_cache);
- return info->base;
+ return info->fp;
}
static const struct frame_base score_prologue_frame_base =
set_gdbarch_register_type (gdbarch, score_register_type);
set_gdbarch_frame_align (gdbarch, score_frame_align);
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- set_gdbarch_read_sp (gdbarch, score_read_sp);
set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
+ set_gdbarch_unwind_sp (gdbarch, score_unwind_sp);
set_gdbarch_print_insn (gdbarch, score_print_insn);
set_gdbarch_skip_prologue (gdbarch, score_skip_prologue);
set_gdbarch_in_function_epilogue_p (gdbarch, score_in_function_epilogue_p);
- set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
+
+ /* Watchpoint hooks. */
+ set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
+
+ /* Dummy frame hooks. */
set_gdbarch_return_value (gdbarch, score_return_value);
+ set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
set_gdbarch_unwind_dummy_id (gdbarch, score_unwind_dummy_id);
set_gdbarch_push_dummy_call (gdbarch, score_push_dummy_call);
+ /* Normal frame hooks. */
frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
frame_unwind_append_sniffer (gdbarch, score_prologue_sniffer);