mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-27 22:10:32 +00:00
* arm-linux-tdep.c (arm_linux_software_single_step): New.
(arm_linux_init_abi): Use it. * arm-tdep.c (arm_get_next_pc): Make global. Handle all-ones condition correctly. * arm-tdep.h (arm_get_next_pc): Declare. * Makefile.in (arm-linux-tdep.o): Update.
This commit is contained in:
parent
7c52e0e865
commit
daddc3c15f
@ -1,3 +1,12 @@
|
||||
2007-09-27 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* arm-linux-tdep.c (arm_linux_software_single_step): New.
|
||||
(arm_linux_init_abi): Use it.
|
||||
* arm-tdep.c (arm_get_next_pc): Make global. Handle all-ones
|
||||
condition correctly.
|
||||
* arm-tdep.h (arm_get_next_pc): Declare.
|
||||
* Makefile.in (arm-linux-tdep.o): Update.
|
||||
|
||||
2007-09-26 Vladimir Prus <vladimir@codesourcery.com>
|
||||
|
||||
* varobj.c (install_new_value): Don't
|
||||
|
@ -1805,7 +1805,7 @@ arm-linux-nat.o: arm-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \
|
||||
arm-linux-tdep.o: arm-linux-tdep.c $(defs_h) $(target_h) $(value_h) \
|
||||
$(gdbtypes_h) $(floatformat_h) $(gdbcore_h) $(frame_h) $(regcache_h) \
|
||||
$(doublest_h) $(solib_svr4_h) $(osabi_h) $(arm_tdep_h) \
|
||||
$(regset_h) $(arm_linux_tdep_h) \
|
||||
$(regset_h) $(arm_linux_tdep_h) $(breakpoint_h) \
|
||||
$(glibc_tdep_h) $(trad_frame_h) $(tramp_frame_h) $(gdb_string_h)
|
||||
armnbsd-nat.o: armnbsd-nat.c $(defs_h) $(gdbcore_h) $(inferior_h) \
|
||||
$(regcache_h) $(target_h) $(gdb_string_h) $(arm_tdep_h) $(inf_ptrace_h)
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "regset.h"
|
||||
#include "trad-frame.h"
|
||||
#include "tramp-frame.h"
|
||||
#include "breakpoint.h"
|
||||
|
||||
#include "arm-tdep.h"
|
||||
#include "arm-linux-tdep.h"
|
||||
@ -568,6 +569,26 @@ arm_linux_regset_from_core_section (struct gdbarch *gdbarch,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Insert a single step breakpoint at the next executed instruction. */
|
||||
|
||||
int
|
||||
arm_linux_software_single_step (struct frame_info *frame)
|
||||
{
|
||||
CORE_ADDR next_pc = arm_get_next_pc (frame, get_frame_pc (frame));
|
||||
|
||||
/* The Linux kernel offers some user-mode helpers in a high page. We can
|
||||
not read this page (as of 2.6.23), and even if we could then we couldn't
|
||||
set breakpoints in it, and even if we could then the atomic operations
|
||||
would fail when interrupted. They are all called as functions and return
|
||||
to the address in LR, so step to there instead. */
|
||||
if (next_pc > 0xffff0000)
|
||||
next_pc = get_frame_register_unsigned (frame, ARM_LR_REGNUM);
|
||||
|
||||
insert_single_step_breakpoint (next_pc);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
arm_linux_init_abi (struct gdbarch_info info,
|
||||
struct gdbarch *gdbarch)
|
||||
@ -604,7 +625,7 @@ arm_linux_init_abi (struct gdbarch_info info,
|
||||
(gdbarch, svr4_ilp32_fetch_link_map_offsets);
|
||||
|
||||
/* Single stepping. */
|
||||
set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
|
||||
set_gdbarch_software_single_step (gdbarch, arm_linux_software_single_step);
|
||||
|
||||
/* Shared library handling. */
|
||||
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
|
||||
|
@ -1664,7 +1664,7 @@ thumb_get_next_pc (struct frame_info *frame, CORE_ADDR pc)
|
||||
return nextpc;
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
CORE_ADDR
|
||||
arm_get_next_pc (struct frame_info *frame, CORE_ADDR pc)
|
||||
{
|
||||
unsigned long pc_val;
|
||||
@ -1680,7 +1680,30 @@ arm_get_next_pc (struct frame_info *frame, CORE_ADDR pc)
|
||||
status = get_frame_register_unsigned (frame, ARM_PS_REGNUM);
|
||||
nextpc = (CORE_ADDR) (pc_val + 4); /* Default case */
|
||||
|
||||
if (condition_true (bits (this_instr, 28, 31), status))
|
||||
if (bits (this_instr, 28, 31) == INST_NV)
|
||||
switch (bits (this_instr, 24, 27))
|
||||
{
|
||||
case 0xa:
|
||||
case 0xb:
|
||||
{
|
||||
/* Branch with Link and change to Thumb. */
|
||||
nextpc = BranchDest (pc, this_instr);
|
||||
nextpc |= bit (this_instr, 24) << 1;
|
||||
|
||||
nextpc = gdbarch_addr_bits_remove (current_gdbarch, nextpc);
|
||||
if (nextpc == pc)
|
||||
error (_("Infinite loop detected"));
|
||||
break;
|
||||
}
|
||||
case 0xc:
|
||||
case 0xd:
|
||||
case 0xe:
|
||||
/* Coprocessor register transfer. */
|
||||
if (bits (this_instr, 12, 15) == 15)
|
||||
error (_("Invalid update to pc in instruction"));
|
||||
break;
|
||||
}
|
||||
else if (condition_true (bits (this_instr, 28, 31), status))
|
||||
{
|
||||
switch (bits (this_instr, 24, 27))
|
||||
{
|
||||
@ -1886,10 +1909,6 @@ arm_get_next_pc (struct frame_info *frame, CORE_ADDR pc)
|
||||
{
|
||||
nextpc = BranchDest (pc, this_instr);
|
||||
|
||||
/* BLX */
|
||||
if (bits (this_instr, 28, 31) == INST_NV)
|
||||
nextpc |= bit (this_instr, 24) << 1;
|
||||
|
||||
nextpc = gdbarch_addr_bits_remove (current_gdbarch, nextpc);
|
||||
if (nextpc == pc)
|
||||
error (_("Infinite loop detected"));
|
||||
|
@ -181,6 +181,7 @@ struct gdbarch_tdep
|
||||
#endif
|
||||
|
||||
CORE_ADDR arm_skip_stub (struct frame_info *, CORE_ADDR);
|
||||
CORE_ADDR arm_get_next_pc (struct frame_info *, CORE_ADDR);
|
||||
int arm_software_single_step (struct frame_info *);
|
||||
|
||||
/* Functions exported from armbsd-tdep.h. */
|
||||
|
Loading…
Reference in New Issue
Block a user