Fix breakpoint size when stepping over a permanent breakpoint in GDBServer.

When manually stepping over a permanent breakpoint on ARM we need to fetch the
right breakpoint size based on the current instruction set used.

Since this is not encoded in the stop_pc, the instruction mode needs to be
fetched from the CPSR register.

This is done by introducing a new target operation called :
breakpoint_kind_from_current_state.

For other targets that do not need this, breakpoint_kind_from_pc is used.

No regressions, tested on ubuntu 14.04 ARMv7 and x86.
With gdbserver-{native,extended} / { -marm -mthumb }

gdb/gdbserver/ChangeLog:

	* linux-arm-low.c (arm_is_thumb_mode): New function.
	(arm_breakpoint_at): Use arm_is_thumb_mode.
	(arm_breakpoint_kind_from_current_state): New function.
	(struct linux_target_ops) <breakpoint_kind_from_current_state>:
	Initialize.
	* linux-low.c (linux_wait_1): Call breakpoint_kind_from_current_state.
	(linux_breakpoint_kind_from_current_state): New function.
	(struct target_ops <breakpoint_kind_from_current_state>: Initialize.
	* linux-low.h (struct linux_target_ops)
	<breakpoint_kind_from_current_state>: New field.
	* target.h (struct target_ops): Likewise.
	(target_breakpoint_kind_from_current_state): New macro.
This commit is contained in:
Antoine Tremblay
2015-11-30 15:08:04 -05:00
parent fddedbe665
commit 769ef81fec
5 changed files with 83 additions and 2 deletions

View File

@@ -457,6 +457,12 @@ struct target_ops
/* Return the thread's name, or NULL if the target is unable to determine it.
The returned value must not be freed by the caller. */
const char *(*thread_name) (ptid_t thread);
/* Return the breakpoint kind for this target based on the current
processor state (e.g. the current instruction mode on ARM) and the
PC. The PCPTR is adjusted to the real memory location in case a flag
(e.g., the Thumb bit on ARM) is present in the PC. */
int (*breakpoint_kind_from_current_state) (CORE_ADDR *pcptr);
};
extern struct target_ops *the_target;
@@ -644,6 +650,11 @@ int kill_inferior (int);
? (*the_target->breakpoint_kind_from_pc) (pcptr) \
: default_breakpoint_kind_from_pc (pcptr))
#define target_breakpoint_kind_from_current_state(pcptr) \
(the_target->breakpoint_kind_from_current_state \
? (*the_target->breakpoint_kind_from_current_state) (pcptr) \
: target_breakpoint_kind_from_pc (pcptr))
/* Start non-stop mode, returns 0 on success, -1 on failure. */
int start_non_stop (int nonstop);