* 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:
parent
69368a60a4
commit
99e4058030
@ -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>
|
2009-09-28 Ulrich Weigand <uweigand@de.ibm.com>
|
||||||
|
|
||||||
* eval.c (evaluate_subexp_standard) [OP_OBJC_MSGCALL]: Support
|
* eval.c (evaluate_subexp_standard) [OP_OBJC_MSGCALL]: Support
|
||||||
|
@ -67,6 +67,12 @@ simple_displaced_step_free_closure (struct gdbarch *gdbarch,
|
|||||||
xfree (closure);
|
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
|
CORE_ADDR
|
||||||
displaced_step_at_entry_point (struct gdbarch *gdbarch)
|
displaced_step_at_entry_point (struct gdbarch *gdbarch)
|
||||||
|
@ -49,6 +49,11 @@ extern void
|
|||||||
simple_displaced_step_free_closure (struct gdbarch *gdbarch,
|
simple_displaced_step_free_closure (struct gdbarch *gdbarch,
|
||||||
struct displaced_step_closure *closure);
|
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:
|
/* Possible value for gdbarch_displaced_step_location:
|
||||||
Place displaced instructions at the program's entry point,
|
Place displaced instructions at the program's entry point,
|
||||||
leaving space for inferior function call return breakpoints. */
|
leaving space for inferior function call return breakpoints. */
|
||||||
|
@ -232,6 +232,7 @@ struct gdbarch
|
|||||||
gdbarch_skip_permanent_breakpoint_ftype *skip_permanent_breakpoint;
|
gdbarch_skip_permanent_breakpoint_ftype *skip_permanent_breakpoint;
|
||||||
ULONGEST max_insn_length;
|
ULONGEST max_insn_length;
|
||||||
gdbarch_displaced_step_copy_insn_ftype *displaced_step_copy_insn;
|
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_fixup_ftype *displaced_step_fixup;
|
||||||
gdbarch_displaced_step_free_closure_ftype *displaced_step_free_closure;
|
gdbarch_displaced_step_free_closure_ftype *displaced_step_free_closure;
|
||||||
gdbarch_displaced_step_location_ftype *displaced_step_location;
|
gdbarch_displaced_step_location_ftype *displaced_step_location;
|
||||||
@ -371,6 +372,7 @@ struct gdbarch startup_gdbarch =
|
|||||||
0, /* skip_permanent_breakpoint */
|
0, /* skip_permanent_breakpoint */
|
||||||
0, /* max_insn_length */
|
0, /* max_insn_length */
|
||||||
0, /* displaced_step_copy_insn */
|
0, /* displaced_step_copy_insn */
|
||||||
|
default_displaced_step_hw_singlestep, /* displaced_step_hw_singlestep */
|
||||||
0, /* displaced_step_fixup */
|
0, /* displaced_step_fixup */
|
||||||
NULL, /* displaced_step_free_closure */
|
NULL, /* displaced_step_free_closure */
|
||||||
NULL, /* displaced_step_location */
|
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->elf_make_msymbol_special = default_elf_make_msymbol_special;
|
||||||
gdbarch->coff_make_msymbol_special = default_coff_make_msymbol_special;
|
gdbarch->coff_make_msymbol_special = default_coff_make_msymbol_special;
|
||||||
gdbarch->register_reggroup_p = default_register_reggroup_p;
|
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_fixup = NULL;
|
||||||
gdbarch->displaced_step_free_closure = NULL;
|
gdbarch->displaced_step_free_closure = NULL;
|
||||||
gdbarch->displaced_step_location = 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 skip_permanent_breakpoint, has predicate */
|
||||||
/* Skip verify of max_insn_length, has predicate */
|
/* Skip verify of max_insn_length, has predicate */
|
||||||
/* Skip verify of displaced_step_copy_insn, 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 */
|
/* Skip verify of displaced_step_fixup, has predicate */
|
||||||
if ((! gdbarch->displaced_step_free_closure) != (! gdbarch->displaced_step_copy_insn))
|
if ((! gdbarch->displaced_step_free_closure) != (! gdbarch->displaced_step_copy_insn))
|
||||||
fprintf_unfiltered (log, "\n\tdisplaced_step_free_closure");
|
fprintf_unfiltered (log, "\n\tdisplaced_step_free_closure");
|
||||||
@ -790,6 +794,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
|
|||||||
fprintf_unfiltered (file,
|
fprintf_unfiltered (file,
|
||||||
"gdbarch_dump: displaced_step_free_closure = <%s>\n",
|
"gdbarch_dump: displaced_step_free_closure = <%s>\n",
|
||||||
host_address_to_string (gdbarch->displaced_step_free_closure));
|
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,
|
fprintf_unfiltered (file,
|
||||||
"gdbarch_dump: displaced_step_location = <%s>\n",
|
"gdbarch_dump: displaced_step_location = <%s>\n",
|
||||||
host_address_to_string (gdbarch->displaced_step_location));
|
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;
|
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
|
int
|
||||||
gdbarch_displaced_step_fixup_p (struct gdbarch *gdbarch)
|
gdbarch_displaced_step_fixup_p (struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
|
@ -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 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);
|
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
|
/* Fix up the state resulting from successfully single-stepping a
|
||||||
displaced instruction, to give the result we would have gotten from
|
displaced instruction, to give the result we would have gotten from
|
||||||
stepping the instruction in its original location.
|
stepping the instruction in its original location.
|
||||||
|
@ -654,6 +654,17 @@ V:ULONGEST:max_insn_length:::0:0
|
|||||||
# here.
|
# here.
|
||||||
M:struct displaced_step_closure *:displaced_step_copy_insn:CORE_ADDR from, CORE_ADDR to, struct regcache *regs:from, to, regs
|
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
|
# Fix up the state resulting from successfully single-stepping a
|
||||||
# displaced instruction, to give the result we would have gotten from
|
# displaced instruction, to give the result we would have gotten from
|
||||||
# stepping the instruction in its original location.
|
# stepping the instruction in its original location.
|
||||||
|
32
gdb/infrun.c
32
gdb/infrun.c
@ -1002,10 +1002,11 @@ displaced_step_fixup (ptid_t event_ptid, enum target_signal signal)
|
|||||||
displaced_step_dump_bytes (gdb_stdlog, buf, sizeof (buf));
|
displaced_step_dump_bytes (gdb_stdlog, buf, sizeof (buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gdbarch_software_single_step_p (gdbarch))
|
if (gdbarch_displaced_step_hw_singlestep
|
||||||
target_resume (ptid, 0, TARGET_SIGNAL_0);
|
(gdbarch, displaced_step_closure))
|
||||||
else
|
|
||||||
target_resume (ptid, 1, TARGET_SIGNAL_0);
|
target_resume (ptid, 1, TARGET_SIGNAL_0);
|
||||||
|
else
|
||||||
|
target_resume (ptid, 0, TARGET_SIGNAL_0);
|
||||||
|
|
||||||
/* Done, we're stepping a thread. */
|
/* Done, we're stepping a thread. */
|
||||||
break;
|
break;
|
||||||
@ -1114,19 +1115,15 @@ maybe_software_singlestep (struct gdbarch *gdbarch, CORE_ADDR pc)
|
|||||||
{
|
{
|
||||||
int hw_step = 1;
|
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;
|
||||||
hw_step = 0;
|
/* Do not pull these breakpoints until after a `wait' in
|
||||||
else if (gdbarch_software_single_step (gdbarch, get_current_frame ()))
|
`wait_for_inferior' */
|
||||||
{
|
singlestep_breakpoints_inserted_p = 1;
|
||||||
hw_step = 0;
|
singlestep_ptid = inferior_ptid;
|
||||||
/* Do not pull these breakpoints until after a `wait' in
|
singlestep_pc = pc;
|
||||||
`wait_for_inferior' */
|
|
||||||
singlestep_breakpoints_inserted_p = 1;
|
|
||||||
singlestep_ptid = inferior_ptid;
|
|
||||||
singlestep_pc = pc;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return hw_step;
|
return hw_step;
|
||||||
}
|
}
|
||||||
@ -1208,10 +1205,13 @@ a command like `return' or `jump' to continue execution."));
|
|||||||
discard_cleanups (old_cleanups);
|
discard_cleanups (old_cleanups);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
step = gdbarch_displaced_step_hw_singlestep
|
||||||
|
(gdbarch, displaced_step_closure);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do we need to do it the hard way, w/temp breakpoints? */
|
/* Do we need to do it the hard way, w/temp breakpoints? */
|
||||||
if (step)
|
else if (step)
|
||||||
step = maybe_software_singlestep (gdbarch, pc);
|
step = maybe_software_singlestep (gdbarch, pc);
|
||||||
|
|
||||||
if (should_resume)
|
if (should_resume)
|
||||||
|
@ -1058,6 +1058,15 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch,
|
|||||||
from + offset);
|
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. */
|
/* Instruction masks used during single-stepping of atomic sequences. */
|
||||||
#define LWARX_MASK 0xfc0007fe
|
#define LWARX_MASK 0xfc0007fe
|
||||||
#define LWARX_INSTRUCTION 0x7c000028
|
#define LWARX_INSTRUCTION 0x7c000028
|
||||||
@ -3898,6 +3907,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||||||
/* Setup displaced stepping. */
|
/* Setup displaced stepping. */
|
||||||
set_gdbarch_displaced_step_copy_insn (gdbarch,
|
set_gdbarch_displaced_step_copy_insn (gdbarch,
|
||||||
simple_displaced_step_copy_insn);
|
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_fixup (gdbarch, ppc_displaced_step_fixup);
|
||||||
set_gdbarch_displaced_step_free_closure (gdbarch,
|
set_gdbarch_displaced_step_free_closure (gdbarch,
|
||||||
simple_displaced_step_free_closure);
|
simple_displaced_step_free_closure);
|
||||||
|
Loading…
Reference in New Issue
Block a user