Determine the kind of single step breakpoint
This patch adds a new gdbarch method breakpoint_kind_from_current_state for single step breakpoint, and uses it in breakpoint_kind. gdb: 2016-11-03 Yao Qi <yao.qi@linaro.org> * arch-utils.c (default_breakpoint_kind_from_current_state): New function. * arch-utils.h (default_breakpoint_kind_from_current_state): Declare. * arm-tdep.c (arm_breakpoint_kind_from_current_state): New function. (arm_gdbarch_init): Call set_gdbarch_breakpoint_kind_from_current_state. * breakpoint.c (breakpoint_kind): Call gdbarch_breakpoint_kind_from_current_state for single step breakpoint. Update comments. * gdbarch.sh (breakpoint_kind_from_current_state): New. * gdbarch.c, gdbarch.h: Regenerate.
This commit is contained in:
parent
22f13eb869
commit
833b7ab500
@ -1,3 +1,19 @@
|
|||||||
|
2016-11-03 Yao Qi <yao.qi@linaro.org>
|
||||||
|
|
||||||
|
* arch-utils.c (default_breakpoint_kind_from_current_state):
|
||||||
|
New function.
|
||||||
|
* arch-utils.h (default_breakpoint_kind_from_current_state):
|
||||||
|
Declare.
|
||||||
|
* arm-tdep.c (arm_breakpoint_kind_from_current_state): New
|
||||||
|
function.
|
||||||
|
(arm_gdbarch_init): Call
|
||||||
|
set_gdbarch_breakpoint_kind_from_current_state.
|
||||||
|
* breakpoint.c (breakpoint_kind): Call
|
||||||
|
gdbarch_breakpoint_kind_from_current_state for single step
|
||||||
|
breakpoint. Update comments.
|
||||||
|
* gdbarch.sh (breakpoint_kind_from_current_state): New.
|
||||||
|
* gdbarch.c, gdbarch.h: Regenerate.
|
||||||
|
|
||||||
2016-11-03 Yao Qi <yao.qi@linaro.org>
|
2016-11-03 Yao Qi <yao.qi@linaro.org>
|
||||||
|
|
||||||
* arch-utils.c (default_breakpoint_from_pc): New function.
|
* arch-utils.c (default_breakpoint_from_pc): New function.
|
||||||
|
@ -848,6 +848,14 @@ default_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
|
|||||||
|
|
||||||
return gdbarch_sw_breakpoint_from_kind (gdbarch, kind, lenptr);
|
return gdbarch_sw_breakpoint_from_kind (gdbarch, kind, lenptr);
|
||||||
}
|
}
|
||||||
|
int
|
||||||
|
default_breakpoint_kind_from_current_state (struct gdbarch *gdbarch,
|
||||||
|
struct regcache *regcache,
|
||||||
|
CORE_ADDR *pcptr)
|
||||||
|
{
|
||||||
|
return gdbarch_breakpoint_kind_from_pc (gdbarch, pcptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
default_gen_return_address (struct gdbarch *gdbarch,
|
default_gen_return_address (struct gdbarch *gdbarch,
|
||||||
|
@ -218,6 +218,10 @@ extern const gdb_byte *default_breakpoint_from_pc (struct gdbarch *gdbarch,
|
|||||||
CORE_ADDR *pcptr,
|
CORE_ADDR *pcptr,
|
||||||
int *lenptr);
|
int *lenptr);
|
||||||
|
|
||||||
|
extern int default_breakpoint_kind_from_current_state (struct gdbarch *gdbarch,
|
||||||
|
struct regcache *regcache,
|
||||||
|
CORE_ADDR *pcptr);
|
||||||
|
|
||||||
extern void default_gen_return_address (struct gdbarch *gdbarch,
|
extern void default_gen_return_address (struct gdbarch *gdbarch,
|
||||||
struct agent_expr *ax,
|
struct agent_expr *ax,
|
||||||
struct axs_value *value,
|
struct axs_value *value,
|
||||||
|
@ -7901,6 +7901,59 @@ arm_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Implement the breakpoint_kind_from_current_state gdbarch method. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
arm_breakpoint_kind_from_current_state (struct gdbarch *gdbarch,
|
||||||
|
struct regcache *regcache,
|
||||||
|
CORE_ADDR *pcptr)
|
||||||
|
{
|
||||||
|
gdb_byte buf[4];
|
||||||
|
|
||||||
|
/* Check the memory pointed by PC is readable. */
|
||||||
|
if (target_read_memory (regcache_read_pc (regcache), buf, 4) == 0)
|
||||||
|
{
|
||||||
|
struct arm_get_next_pcs next_pcs_ctx;
|
||||||
|
CORE_ADDR pc;
|
||||||
|
int i;
|
||||||
|
VEC (CORE_ADDR) *next_pcs = NULL;
|
||||||
|
struct cleanup *old_chain
|
||||||
|
= make_cleanup (VEC_cleanup (CORE_ADDR), &next_pcs);
|
||||||
|
|
||||||
|
arm_get_next_pcs_ctor (&next_pcs_ctx,
|
||||||
|
&arm_get_next_pcs_ops,
|
||||||
|
gdbarch_byte_order (gdbarch),
|
||||||
|
gdbarch_byte_order_for_code (gdbarch),
|
||||||
|
0,
|
||||||
|
regcache);
|
||||||
|
|
||||||
|
next_pcs = arm_get_next_pcs (&next_pcs_ctx);
|
||||||
|
|
||||||
|
/* If MEMADDR is the next instruction of current pc, do the
|
||||||
|
software single step computation, and get the thumb mode by
|
||||||
|
the destination address. */
|
||||||
|
for (i = 0; VEC_iterate (CORE_ADDR, next_pcs, i, pc); i++)
|
||||||
|
{
|
||||||
|
if (UNMAKE_THUMB_ADDR (pc) == *pcptr)
|
||||||
|
{
|
||||||
|
do_cleanups (old_chain);
|
||||||
|
|
||||||
|
if (IS_THUMB_ADDR (pc))
|
||||||
|
{
|
||||||
|
*pcptr = MAKE_THUMB_ADDR (*pcptr);
|
||||||
|
return arm_breakpoint_kind_from_pc (gdbarch, pcptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return ARM_BP_KIND_ARM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
do_cleanups (old_chain);
|
||||||
|
}
|
||||||
|
|
||||||
|
return arm_breakpoint_kind_from_pc (gdbarch, pcptr);
|
||||||
|
}
|
||||||
|
|
||||||
/* Extract from an array REGBUF containing the (raw) register state a
|
/* Extract from an array REGBUF containing the (raw) register state a
|
||||||
function return value of type TYPE, and copy that, in virtual
|
function return value of type TYPE, and copy that, in virtual
|
||||||
format, into VALBUF. */
|
format, into VALBUF. */
|
||||||
@ -9409,6 +9462,8 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||||||
|
|
||||||
/* Breakpoint manipulation. */
|
/* Breakpoint manipulation. */
|
||||||
SET_GDBARCH_BREAKPOINT_MANIPULATION (arm);
|
SET_GDBARCH_BREAKPOINT_MANIPULATION (arm);
|
||||||
|
set_gdbarch_breakpoint_kind_from_current_state (gdbarch,
|
||||||
|
arm_breakpoint_kind_from_current_state);
|
||||||
|
|
||||||
/* Information about registers, etc. */
|
/* Information about registers, etc. */
|
||||||
set_gdbarch_sp_regnum (gdbarch, ARM_SP_REGNUM);
|
set_gdbarch_sp_regnum (gdbarch, ARM_SP_REGNUM);
|
||||||
|
@ -2603,12 +2603,26 @@ build_target_command_list (struct bp_location *bl)
|
|||||||
bl->target_info.persist = 1;
|
bl->target_info.persist = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the kind of breakpoint on address *ADDR. */
|
/* Return the kind of breakpoint on address *ADDR. Get the kind
|
||||||
|
of breakpoint according to ADDR except single-step breakpoint.
|
||||||
|
Get the kind of single-step breakpoint according to the current
|
||||||
|
registers state. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
breakpoint_kind (struct bp_location *bl, CORE_ADDR *addr)
|
breakpoint_kind (struct bp_location *bl, CORE_ADDR *addr)
|
||||||
{
|
{
|
||||||
return gdbarch_breakpoint_kind_from_pc (bl->gdbarch, addr);
|
if (bl->owner->type == bp_single_step)
|
||||||
|
{
|
||||||
|
struct thread_info *thr = find_thread_global_id (bl->owner->thread);
|
||||||
|
struct regcache *regcache;
|
||||||
|
|
||||||
|
regcache = get_thread_regcache (thr->ptid);
|
||||||
|
|
||||||
|
return gdbarch_breakpoint_kind_from_current_state (bl->gdbarch,
|
||||||
|
regcache, addr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return gdbarch_breakpoint_kind_from_pc (bl->gdbarch, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Insert a low-level "breakpoint" of some type. BL is the breakpoint
|
/* Insert a low-level "breakpoint" of some type. BL is the breakpoint
|
||||||
|
@ -232,6 +232,7 @@ struct gdbarch
|
|||||||
gdbarch_breakpoint_from_pc_ftype *breakpoint_from_pc;
|
gdbarch_breakpoint_from_pc_ftype *breakpoint_from_pc;
|
||||||
gdbarch_breakpoint_kind_from_pc_ftype *breakpoint_kind_from_pc;
|
gdbarch_breakpoint_kind_from_pc_ftype *breakpoint_kind_from_pc;
|
||||||
gdbarch_sw_breakpoint_from_kind_ftype *sw_breakpoint_from_kind;
|
gdbarch_sw_breakpoint_from_kind_ftype *sw_breakpoint_from_kind;
|
||||||
|
gdbarch_breakpoint_kind_from_current_state_ftype *breakpoint_kind_from_current_state;
|
||||||
gdbarch_adjust_breakpoint_address_ftype *adjust_breakpoint_address;
|
gdbarch_adjust_breakpoint_address_ftype *adjust_breakpoint_address;
|
||||||
gdbarch_memory_insert_breakpoint_ftype *memory_insert_breakpoint;
|
gdbarch_memory_insert_breakpoint_ftype *memory_insert_breakpoint;
|
||||||
gdbarch_memory_remove_breakpoint_ftype *memory_remove_breakpoint;
|
gdbarch_memory_remove_breakpoint_ftype *memory_remove_breakpoint;
|
||||||
@ -406,6 +407,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
|
|||||||
gdbarch->return_in_first_hidden_param_p = default_return_in_first_hidden_param_p;
|
gdbarch->return_in_first_hidden_param_p = default_return_in_first_hidden_param_p;
|
||||||
gdbarch->breakpoint_from_pc = default_breakpoint_from_pc;
|
gdbarch->breakpoint_from_pc = default_breakpoint_from_pc;
|
||||||
gdbarch->sw_breakpoint_from_kind = NULL;
|
gdbarch->sw_breakpoint_from_kind = NULL;
|
||||||
|
gdbarch->breakpoint_kind_from_current_state = default_breakpoint_kind_from_current_state;
|
||||||
gdbarch->memory_insert_breakpoint = default_memory_insert_breakpoint;
|
gdbarch->memory_insert_breakpoint = default_memory_insert_breakpoint;
|
||||||
gdbarch->memory_remove_breakpoint = default_memory_remove_breakpoint;
|
gdbarch->memory_remove_breakpoint = default_memory_remove_breakpoint;
|
||||||
gdbarch->remote_register_number = default_remote_register_number;
|
gdbarch->remote_register_number = default_remote_register_number;
|
||||||
@ -587,6 +589,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
|
|||||||
if (gdbarch->breakpoint_kind_from_pc == 0)
|
if (gdbarch->breakpoint_kind_from_pc == 0)
|
||||||
fprintf_unfiltered (log, "\n\tbreakpoint_kind_from_pc");
|
fprintf_unfiltered (log, "\n\tbreakpoint_kind_from_pc");
|
||||||
/* Skip verify of sw_breakpoint_from_kind, invalid_p == 0 */
|
/* Skip verify of sw_breakpoint_from_kind, invalid_p == 0 */
|
||||||
|
/* Skip verify of breakpoint_kind_from_current_state, invalid_p == 0 */
|
||||||
/* Skip verify of adjust_breakpoint_address, has predicate. */
|
/* Skip verify of adjust_breakpoint_address, has predicate. */
|
||||||
/* Skip verify of memory_insert_breakpoint, invalid_p == 0 */
|
/* Skip verify of memory_insert_breakpoint, invalid_p == 0 */
|
||||||
/* Skip verify of memory_remove_breakpoint, invalid_p == 0 */
|
/* Skip verify of memory_remove_breakpoint, invalid_p == 0 */
|
||||||
@ -795,6 +798,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
|
|||||||
fprintf_unfiltered (file,
|
fprintf_unfiltered (file,
|
||||||
"gdbarch_dump: breakpoint_from_pc = <%s>\n",
|
"gdbarch_dump: breakpoint_from_pc = <%s>\n",
|
||||||
host_address_to_string (gdbarch->breakpoint_from_pc));
|
host_address_to_string (gdbarch->breakpoint_from_pc));
|
||||||
|
fprintf_unfiltered (file,
|
||||||
|
"gdbarch_dump: breakpoint_kind_from_current_state = <%s>\n",
|
||||||
|
host_address_to_string (gdbarch->breakpoint_kind_from_current_state));
|
||||||
fprintf_unfiltered (file,
|
fprintf_unfiltered (file,
|
||||||
"gdbarch_dump: breakpoint_kind_from_pc = <%s>\n",
|
"gdbarch_dump: breakpoint_kind_from_pc = <%s>\n",
|
||||||
host_address_to_string (gdbarch->breakpoint_kind_from_pc));
|
host_address_to_string (gdbarch->breakpoint_kind_from_pc));
|
||||||
@ -2822,6 +2828,23 @@ set_gdbarch_sw_breakpoint_from_kind (struct gdbarch *gdbarch,
|
|||||||
gdbarch->sw_breakpoint_from_kind = sw_breakpoint_from_kind;
|
gdbarch->sw_breakpoint_from_kind = sw_breakpoint_from_kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gdbarch_breakpoint_kind_from_current_state (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR *pcptr)
|
||||||
|
{
|
||||||
|
gdb_assert (gdbarch != NULL);
|
||||||
|
gdb_assert (gdbarch->breakpoint_kind_from_current_state != NULL);
|
||||||
|
if (gdbarch_debug >= 2)
|
||||||
|
fprintf_unfiltered (gdb_stdlog, "gdbarch_breakpoint_kind_from_current_state called\n");
|
||||||
|
return gdbarch->breakpoint_kind_from_current_state (gdbarch, regcache, pcptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_gdbarch_breakpoint_kind_from_current_state (struct gdbarch *gdbarch,
|
||||||
|
gdbarch_breakpoint_kind_from_current_state_ftype breakpoint_kind_from_current_state)
|
||||||
|
{
|
||||||
|
gdbarch->breakpoint_kind_from_current_state = breakpoint_kind_from_current_state;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
gdbarch_adjust_breakpoint_address_p (struct gdbarch *gdbarch)
|
gdbarch_adjust_breakpoint_address_p (struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
|
@ -564,6 +564,14 @@ typedef const gdb_byte * (gdbarch_sw_breakpoint_from_kind_ftype) (struct gdbarch
|
|||||||
extern const gdb_byte * gdbarch_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size);
|
extern const gdb_byte * gdbarch_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size);
|
||||||
extern void set_gdbarch_sw_breakpoint_from_kind (struct gdbarch *gdbarch, gdbarch_sw_breakpoint_from_kind_ftype *sw_breakpoint_from_kind);
|
extern void set_gdbarch_sw_breakpoint_from_kind (struct gdbarch *gdbarch, gdbarch_sw_breakpoint_from_kind_ftype *sw_breakpoint_from_kind);
|
||||||
|
|
||||||
|
/* Return the breakpoint kind for this target based on the current
|
||||||
|
processor state (e.g. the current instruction mode on ARM) and the
|
||||||
|
*PCPTR. In default, it is gdbarch->breakpoint_kind_from_pc. */
|
||||||
|
|
||||||
|
typedef int (gdbarch_breakpoint_kind_from_current_state_ftype) (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR *pcptr);
|
||||||
|
extern int gdbarch_breakpoint_kind_from_current_state (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR *pcptr);
|
||||||
|
extern void set_gdbarch_breakpoint_kind_from_current_state (struct gdbarch *gdbarch, gdbarch_breakpoint_kind_from_current_state_ftype *breakpoint_kind_from_current_state);
|
||||||
|
|
||||||
extern int gdbarch_adjust_breakpoint_address_p (struct gdbarch *gdbarch);
|
extern int gdbarch_adjust_breakpoint_address_p (struct gdbarch *gdbarch);
|
||||||
|
|
||||||
typedef CORE_ADDR (gdbarch_adjust_breakpoint_address_ftype) (struct gdbarch *gdbarch, CORE_ADDR bpaddr);
|
typedef CORE_ADDR (gdbarch_adjust_breakpoint_address_ftype) (struct gdbarch *gdbarch, CORE_ADDR bpaddr);
|
||||||
|
@ -569,6 +569,11 @@ m:int:breakpoint_kind_from_pc:CORE_ADDR *pcptr:pcptr::0:
|
|||||||
# SIZE is set to the software breakpoint's length in memory.
|
# SIZE is set to the software breakpoint's length in memory.
|
||||||
m:const gdb_byte *:sw_breakpoint_from_kind:int kind, int *size:kind, size::NULL::0
|
m:const gdb_byte *:sw_breakpoint_from_kind:int kind, int *size:kind, size::NULL::0
|
||||||
|
|
||||||
|
# Return the breakpoint kind for this target based on the current
|
||||||
|
# processor state (e.g. the current instruction mode on ARM) and the
|
||||||
|
# *PCPTR. In default, it is gdbarch->breakpoint_kind_from_pc.
|
||||||
|
m:int:breakpoint_kind_from_current_state:struct regcache *regcache, CORE_ADDR *pcptr:regcache, pcptr:0:default_breakpoint_kind_from_current_state::0
|
||||||
|
|
||||||
M:CORE_ADDR:adjust_breakpoint_address:CORE_ADDR bpaddr:bpaddr
|
M:CORE_ADDR:adjust_breakpoint_address:CORE_ADDR bpaddr:bpaddr
|
||||||
m:int:memory_insert_breakpoint:struct bp_target_info *bp_tgt:bp_tgt:0:default_memory_insert_breakpoint::0
|
m:int:memory_insert_breakpoint:struct bp_target_info *bp_tgt:bp_tgt:0:default_memory_insert_breakpoint::0
|
||||||
m:int:memory_remove_breakpoint:struct bp_target_info *bp_tgt:bp_tgt:0:default_memory_remove_breakpoint::0
|
m:int:memory_remove_breakpoint:struct bp_target_info *bp_tgt:bp_tgt:0:default_memory_remove_breakpoint::0
|
||||||
|
Loading…
Reference in New Issue
Block a user