/* Control debugging information emitted in this file. */
-static int nios2_debug = 0;
+static bool nios2_debug = false;
/* The following structures are used in the cache for prologue
analysis; see the reg_value and reg_saved tables in
struct nios2_unwind_cache, respectively. */
-/* struct reg_value is used to record that a register has the same value
- as reg at the given offset from the start of a function. */
+/* struct reg_value is used to record that a register has reg's initial
+ value at the start of a function plus the given constant offset.
+ If reg == 0, then the value is just the offset.
+ If reg < 0, then the value is unknown. */
struct reg_value
{
int reg;
- unsigned int offset;
+ int offset;
};
/* struct reg_saved is used to record that a register value has been saved at
return RETURN_VALUE_REGISTER_CONVENTION;
}
-/* Implement the dummy_id gdbarch method. */
-
-static struct frame_id
-nios2_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
- return frame_id_build
- (get_frame_register_unsigned (this_frame, NIOS2_SP_REGNUM),
- get_frame_pc (this_frame));
-}
-
/* Implement the push_dummy_call gdbarch method. */
static CORE_ADDR
return extract_typed_address (buf, builtin_type (gdbarch)->builtin_func_ptr);
}
-/* Implement the unwind_sp gdbarch method. */
-
-static CORE_ADDR
-nios2_unwind_sp (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
- return frame_unwind_register_unsigned (this_frame, NIOS2_SP_REGNUM);
-}
-
/* Use prologue analysis to fill in the register cache
*THIS_PROLOGUE_CACHE for THIS_FRAME. This function initializes
*THIS_PROLOGUE_CACHE first. */
}
}
- else if (nios2_match_jmpi (insn, op, mach, &uimm)
- || nios2_match_calli (insn, op, mach, &uimm))
+ else if (nios2_match_jmpi (insn, op, mach, &uimm))
pc = (pc & 0xf0000000) | uimm;
+ else if (nios2_match_calli (insn, op, mach, &uimm))
+ {
+ CORE_ADDR callto = (pc & 0xf0000000) | uimm;
+ if (tdep->is_kernel_helper != NULL
+ && tdep->is_kernel_helper (callto))
+ /* Step over call to kernel helper, which we cannot debug
+ from user space. */
+ pc += op->size;
+ else
+ pc = callto;
+ }
- else if (nios2_match_jmpr (insn, op, mach, &ra)
- || nios2_match_callr (insn, op, mach, &ra))
+ else if (nios2_match_jmpr (insn, op, mach, &ra))
pc = regcache_raw_get_unsigned (regcache, ra);
+ else if (nios2_match_callr (insn, op, mach, &ra))
+ {
+ CORE_ADDR callto = regcache_raw_get_unsigned (regcache, ra);
+ if (tdep->is_kernel_helper != NULL
+ && tdep->is_kernel_helper (callto))
+ /* Step over call to kernel helper. */
+ pc += op->size;
+ else
+ pc = callto;
+ }
else if (nios2_match_ldwm (insn, op, mach, &uimm, &ra, &imm, &wb, &id, &ret)
&& ret)
static ULONGEST
nios2_type_align (struct gdbarch *gdbarch, struct type *type)
{
- type = check_typedef (type);
- return std::min<ULONGEST> (4, TYPE_LENGTH (type));
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_FUNC:
+ case TYPE_CODE_FLAGS:
+ case TYPE_CODE_INT:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_FLT:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_REF:
+ case TYPE_CODE_RVALUE_REF:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_DECFLOAT:
+ case TYPE_CODE_METHODPTR:
+ case TYPE_CODE_MEMBERPTR:
+ type = check_typedef (type);
+ return std::min<ULONGEST> (4, TYPE_LENGTH (type));
+ default:
+ return 0;
+ }
}
/* Implement the gcc_target_options gdbarch method. */
-static char *
+static std::string
nios2_gcc_target_options (struct gdbarch *gdbarch)
{
/* GCC doesn't know "-m32". */
- return NULL;
+ return {};
}
/* Initialize the Nios II gdbarch. */
set_gdbarch_breakpoint_kind_from_pc (gdbarch, nios2_breakpoint_kind_from_pc);
set_gdbarch_sw_breakpoint_from_kind (gdbarch, nios2_sw_breakpoint_from_kind);
- set_gdbarch_dummy_id (gdbarch, nios2_dummy_id);
set_gdbarch_unwind_pc (gdbarch, nios2_unwind_pc);
- set_gdbarch_unwind_sp (gdbarch, nios2_unwind_sp);
/* The dwarf2 unwinder will normally produce the best results if
the debug information is available, so register it first. */