diff options
Diffstat (limited to 'gdb/gdbserver/linux-arm-low.c')
-rw-r--r-- | gdb/gdbserver/linux-arm-low.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c index 2958fdf..07e2792 100644 --- a/gdb/gdbserver/linux-arm-low.c +++ b/gdb/gdbserver/linux-arm-low.c @@ -45,9 +45,49 @@ arm_cannot_fetch_register (int regno) return (regno >= arm_num_regs); } +static CORE_ADDR +arm_get_pc () +{ + unsigned long pc; + collect_register_by_name ("pc", &pc); + return pc; +} + +static void +arm_set_pc (CORE_ADDR pc) +{ + unsigned long newpc = pc; + supply_register_by_name ("pc", &newpc); +} + +/* Correct in either endianness. We do not support Thumb yet. */ +static const unsigned long arm_breakpoint = 0xef9f0001; +#define arm_breakpoint_len 4 + +static int +arm_breakpoint_at (CORE_ADDR where) +{ + unsigned long insn; + + (*the_target->read_memory) (where, (char *) &insn, 4); + if (insn == arm_breakpoint) + return 1; + + /* If necessary, recognize more trap instructions here. GDB only uses the + one. */ + return 0; +} + struct linux_target_ops the_low_target = { arm_num_regs, arm_regmap, arm_cannot_fetch_register, arm_cannot_store_register, + arm_get_pc, + arm_set_pc, + (const char *) &arm_breakpoint, + arm_breakpoint_len, + NULL, + 0, + arm_breakpoint_at, }; |