* gdbarch.sh (displaced_step_hw_singlestep): New callback.

* gdbarch.c, gdbarch.h: Regenerate.
	* arch-utils.c (default_displaced_step_hw_singlestep): New function.
	* arch-utils.h (default_displaced_step_hw_singlestep): Add prototype.

	* ppc-linux-tdep.c (ppc_displaced_step_hw_singlestep): New function.
	(rs6000_gdbarch_init): Install it.

	* infrun.c (displaced_step_fixup): Use new callback to determine
	whether to "step" or "continue" displaced copy.
	(resume): Likewise.  Do not call maybe_software_singlestep
	for displaced stepping.
	(maybe_software_singlestep): Do not handle displaced stepping.
This commit is contained in:
Ulrich Weigand 2009-09-29 00:53:04 +00:00
parent 69368a60a4
commit 99e4058030
8 changed files with 103 additions and 16 deletions

View File

@ -1,3 +1,19 @@
2009-09-28 Ulrich Weigand <uweigand@de.ibm.com>
* gdbarch.sh (displaced_step_hw_singlestep): New callback.
* gdbarch.c, gdbarch.h: Regenerate.
* arch-utils.c (default_displaced_step_hw_singlestep): New function.
* arch-utils.h (default_displaced_step_hw_singlestep): Add prototype.
* ppc-linux-tdep.c (ppc_displaced_step_hw_singlestep): New function.
(rs6000_gdbarch_init): Install it.
* infrun.c (displaced_step_fixup): Use new callback to determine
whether to "step" or "continue" displaced copy.
(resume): Likewise. Do not call maybe_software_singlestep
for displaced stepping.
(maybe_software_singlestep): Do not handle displaced stepping.
2009-09-28 Ulrich Weigand <uweigand@de.ibm.com>
* eval.c (evaluate_subexp_standard) [OP_OBJC_MSGCALL]: Support

View File

@ -67,6 +67,12 @@ simple_displaced_step_free_closure (struct gdbarch *gdbarch,
xfree (closure);
}
int
default_displaced_step_hw_singlestep (struct gdbarch *gdbarch,
struct displaced_step_closure *closure)
{
return !gdbarch_software_single_step_p (gdbarch);
}
CORE_ADDR
displaced_step_at_entry_point (struct gdbarch *gdbarch)

View File

@ -49,6 +49,11 @@ extern void
simple_displaced_step_free_closure (struct gdbarch *gdbarch,
struct displaced_step_closure *closure);
/* Default implementation of gdbarch_displaced_hw_singlestep. */
extern int
default_displaced_step_hw_singlestep (struct gdbarch *gdbarch,
struct displaced_step_closure *closure);
/* Possible value for gdbarch_displaced_step_location:
Place displaced instructions at the program's entry point,
leaving space for inferior function call return breakpoints. */

View File

@ -232,6 +232,7 @@ struct gdbarch
gdbarch_skip_permanent_breakpoint_ftype *skip_permanent_breakpoint;
ULONGEST max_insn_length;
gdbarch_displaced_step_copy_insn_ftype *displaced_step_copy_insn;
gdbarch_displaced_step_hw_singlestep_ftype *displaced_step_hw_singlestep;
gdbarch_displaced_step_fixup_ftype *displaced_step_fixup;
gdbarch_displaced_step_free_closure_ftype *displaced_step_free_closure;
gdbarch_displaced_step_location_ftype *displaced_step_location;
@ -371,6 +372,7 @@ struct gdbarch startup_gdbarch =
0, /* skip_permanent_breakpoint */
0, /* max_insn_length */
0, /* displaced_step_copy_insn */
default_displaced_step_hw_singlestep, /* displaced_step_hw_singlestep */
0, /* displaced_step_fixup */
NULL, /* displaced_step_free_closure */
NULL, /* displaced_step_location */
@ -464,6 +466,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
gdbarch->elf_make_msymbol_special = default_elf_make_msymbol_special;
gdbarch->coff_make_msymbol_special = default_coff_make_msymbol_special;
gdbarch->register_reggroup_p = default_register_reggroup_p;
gdbarch->displaced_step_hw_singlestep = default_displaced_step_hw_singlestep;
gdbarch->displaced_step_fixup = NULL;
gdbarch->displaced_step_free_closure = NULL;
gdbarch->displaced_step_location = NULL;
@ -627,6 +630,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of skip_permanent_breakpoint, has predicate */
/* Skip verify of max_insn_length, has predicate */
/* Skip verify of displaced_step_copy_insn, has predicate */
/* Skip verify of displaced_step_hw_singlestep, invalid_p == 0 */
/* Skip verify of displaced_step_fixup, has predicate */
if ((! gdbarch->displaced_step_free_closure) != (! gdbarch->displaced_step_copy_insn))
fprintf_unfiltered (log, "\n\tdisplaced_step_free_closure");
@ -790,6 +794,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
fprintf_unfiltered (file,
"gdbarch_dump: displaced_step_free_closure = <%s>\n",
host_address_to_string (gdbarch->displaced_step_free_closure));
fprintf_unfiltered (file,
"gdbarch_dump: displaced_step_hw_singlestep = <%s>\n",
host_address_to_string (gdbarch->displaced_step_hw_singlestep));
fprintf_unfiltered (file,
"gdbarch_dump: displaced_step_location = <%s>\n",
host_address_to_string (gdbarch->displaced_step_location));
@ -3144,6 +3151,23 @@ set_gdbarch_displaced_step_copy_insn (struct gdbarch *gdbarch,
gdbarch->displaced_step_copy_insn = displaced_step_copy_insn;
}
int
gdbarch_displaced_step_hw_singlestep (struct gdbarch *gdbarch, struct displaced_step_closure *closure)
{
gdb_assert (gdbarch != NULL);
gdb_assert (gdbarch->displaced_step_hw_singlestep != NULL);
if (gdbarch_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "gdbarch_displaced_step_hw_singlestep called\n");
return gdbarch->displaced_step_hw_singlestep (gdbarch, closure);
}
void
set_gdbarch_displaced_step_hw_singlestep (struct gdbarch *gdbarch,
gdbarch_displaced_step_hw_singlestep_ftype displaced_step_hw_singlestep)
{
gdbarch->displaced_step_hw_singlestep = displaced_step_hw_singlestep;
}
int
gdbarch_displaced_step_fixup_p (struct gdbarch *gdbarch)
{

View File

@ -734,6 +734,20 @@ typedef struct displaced_step_closure * (gdbarch_displaced_step_copy_insn_ftype)
extern struct displaced_step_closure * gdbarch_displaced_step_copy_insn (struct gdbarch *gdbarch, CORE_ADDR from, CORE_ADDR to, struct regcache *regs);
extern void set_gdbarch_displaced_step_copy_insn (struct gdbarch *gdbarch, gdbarch_displaced_step_copy_insn_ftype *displaced_step_copy_insn);
/* Return true if GDB should use hardware single-stepping to execute
the displaced instruction identified by CLOSURE. If false,
GDB will simply restart execution at the displaced instruction
location, and it is up to the target to ensure GDB will receive
control again (e.g. by placing a software breakpoint instruction
into the displaced instruction buffer).
The default implementation returns false on all targets that
provide a gdbarch_software_single_step routine, and true otherwise. */
typedef int (gdbarch_displaced_step_hw_singlestep_ftype) (struct gdbarch *gdbarch, struct displaced_step_closure *closure);
extern int gdbarch_displaced_step_hw_singlestep (struct gdbarch *gdbarch, struct displaced_step_closure *closure);
extern void set_gdbarch_displaced_step_hw_singlestep (struct gdbarch *gdbarch, gdbarch_displaced_step_hw_singlestep_ftype *displaced_step_hw_singlestep);
/* Fix up the state resulting from successfully single-stepping a
displaced instruction, to give the result we would have gotten from
stepping the instruction in its original location.

View File

@ -654,6 +654,17 @@ V:ULONGEST:max_insn_length:::0:0
# here.
M:struct displaced_step_closure *:displaced_step_copy_insn:CORE_ADDR from, CORE_ADDR to, struct regcache *regs:from, to, regs
# Return true if GDB should use hardware single-stepping to execute
# the displaced instruction identified by CLOSURE. If false,
# GDB will simply restart execution at the displaced instruction
# location, and it is up to the target to ensure GDB will receive
# control again (e.g. by placing a software breakpoint instruction
# into the displaced instruction buffer).
#
# The default implementation returns false on all targets that
# provide a gdbarch_software_single_step routine, and true otherwise.
m:int:displaced_step_hw_singlestep:struct displaced_step_closure *closure:closure::default_displaced_step_hw_singlestep::0
# Fix up the state resulting from successfully single-stepping a
# displaced instruction, to give the result we would have gotten from
# stepping the instruction in its original location.

View File

@ -1002,10 +1002,11 @@ displaced_step_fixup (ptid_t event_ptid, enum target_signal signal)
displaced_step_dump_bytes (gdb_stdlog, buf, sizeof (buf));
}
if (gdbarch_software_single_step_p (gdbarch))
target_resume (ptid, 0, TARGET_SIGNAL_0);
else
if (gdbarch_displaced_step_hw_singlestep
(gdbarch, displaced_step_closure))
target_resume (ptid, 1, TARGET_SIGNAL_0);
else
target_resume (ptid, 0, TARGET_SIGNAL_0);
/* Done, we're stepping a thread. */
break;
@ -1114,19 +1115,15 @@ maybe_software_singlestep (struct gdbarch *gdbarch, CORE_ADDR pc)
{
int hw_step = 1;
if (gdbarch_software_single_step_p (gdbarch))
if (gdbarch_software_single_step_p (gdbarch)
&& gdbarch_software_single_step (gdbarch, get_current_frame ()))
{
if (use_displaced_stepping (gdbarch))
hw_step = 0;
else if (gdbarch_software_single_step (gdbarch, get_current_frame ()))
{
hw_step = 0;
/* Do not pull these breakpoints until after a `wait' in
`wait_for_inferior' */
singlestep_breakpoints_inserted_p = 1;
singlestep_ptid = inferior_ptid;
singlestep_pc = pc;
}
hw_step = 0;
/* Do not pull these breakpoints until after a `wait' in
`wait_for_inferior' */
singlestep_breakpoints_inserted_p = 1;
singlestep_ptid = inferior_ptid;
singlestep_pc = pc;
}
return hw_step;
}
@ -1208,10 +1205,13 @@ a command like `return' or `jump' to continue execution."));
discard_cleanups (old_cleanups);
return;
}
step = gdbarch_displaced_step_hw_singlestep
(gdbarch, displaced_step_closure);
}
/* Do we need to do it the hard way, w/temp breakpoints? */
if (step)
else if (step)
step = maybe_software_singlestep (gdbarch, pc);
if (should_resume)

View File

@ -1058,6 +1058,15 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch,
from + offset);
}
/* Always use hardware single-stepping to execute the
displaced instruction. */
static int
ppc_displaced_step_hw_singlestep (struct gdbarch *gdbarch,
struct displaced_step_closure *closure)
{
return 1;
}
/* Instruction masks used during single-stepping of atomic sequences. */
#define LWARX_MASK 0xfc0007fe
#define LWARX_INSTRUCTION 0x7c000028
@ -3898,6 +3907,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
/* Setup displaced stepping. */
set_gdbarch_displaced_step_copy_insn (gdbarch,
simple_displaced_step_copy_insn);
set_gdbarch_displaced_step_hw_singlestep (gdbarch,
ppc_displaced_step_hw_singlestep);
set_gdbarch_displaced_step_fixup (gdbarch, ppc_displaced_step_fixup);
set_gdbarch_displaced_step_free_closure (gdbarch,
simple_displaced_step_free_closure);