diff options
author | Pedro Alves <palves@redhat.com> | 2008-05-02 16:49:54 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2008-05-02 16:49:54 +0000 |
commit | 237fc4c9cdd1a1df1e53a8321dfd7b147da722fd (patch) | |
tree | a58beb3878b7f1e95d6d4bb0f5dc84025fa8c9b7 /gdb/gdbarch.c | |
parent | 0428b8f567d7966cd47efe0cc99eb8b5072c625e (diff) | |
download | gdb-237fc4c9cdd1a1df1e53a8321dfd7b147da722fd.zip gdb-237fc4c9cdd1a1df1e53a8321dfd7b147da722fd.tar.gz gdb-237fc4c9cdd1a1df1e53a8321dfd7b147da722fd.tar.bz2 |
Implement displaced stepping.
gdb/
* gdbarch.sh (max_insn_length): New 'variable'.
(displaced_step_copy, displaced_step_fixup)
(displaced_step_free_closure, displaced_step_location): New
functions.
(struct displaced_step_closure): Add forward declaration.
* gdbarch.c, gdbarch.h: Regenerated.
* arch-utils.c: #include "objfiles.h".
(simple_displaced_step_copy_insn)
(simple_displaced_step_free_closure)
(displaced_step_at_entry_point): New functions.
* arch-utils.h (simple_displaced_step_copy_insn)
(simple_displaced_step_free_closure)
(displaced_step_at_entry_point): New prototypes.
* i386-tdep.c (I386_MAX_INSN_LEN): Rename to...
(I386_MAX_MATCHED_INSN_LEN): ... this.
(i386_absolute_jmp_p, i386_absolute_call_p)
(i386_ret_p, i386_call_p, i386_breakpoint_p, i386_syscall_p)
(i386_displaced_step_fixup): New functions.
(struct i386_insn, i386_match_insn): Update.
(i386_gdbarch_init): Set gdbarch_max_insn_length.
* i386-tdep.h (I386_MAX_INSN_LEN): New.
(i386_displaced_step_fixup): New prototype.
* i386-linux-tdep.c (i386_linux_init_abi): Include "arch-utils.h".
Register gdbarch_displaced_step_copy,
gdbarch_displaced_step_fixup, gdbarch_displaced_step_free_closure,
and gdbarch_displaced_step_location functions.
* infrun.c (debug_displaced): New variable.
(show_debug_displaced): New function.
(struct displaced_step_request): New struct.
(displaced_step_request_queue, displaced_step_ptid)
(displaced_step_gdbarch, displaced_step_closure)
(displaced_step_original, displaced_step_copy)
(displaced_step_saved_copy, can_use_displaced_stepping): New
variables.
(show_can_use_displaced_stepping, use_displaced_stepping)
(displaced_step_clear, cleanup_displaced_step_closure)
(displaced_step_dump_bytes, displaced_step_prepare)
(displaced_step_clear_cleanup, write_memory_ptid)
(displaced_step_fixup): New functions.
(resume): Call displaced_step_prepare.
(proceed): Call read_pc once, and remember the value. If using
displaced stepping, don't remove breakpoints.
(handle_inferior_event): Call displaced_step_fixup. Add some
debugging output. When we try to step over a breakpoint, but get
a signal to deliver to the thread instead, ensure the step-resume
breakpoint is actually inserted. If a thread hop is needed, and
displaced stepping is enabled, don't remove breakpoints.
(init_wait_for_inferior): Call displaced_step_clear.
(_initialize_infrun): Add "set debug displaced" command. Add
"maint set can-use-displaced-stepping" command. Clear
displaced_step_ptid.
* inferior.h (debug_displaced): Declare variable.
(displaced_step_dump_bytes): Declare function.
* Makefile.in (arch-utils.o, i386-linux-tdep.o): Update
dependencies.
gdb/testsuite/
* gdb.asm/asmsrc1.s: Add scratch space.
gdb/doc/
* gdb.texinfo (Debugging Output): Document "set/show debug
displaced".
(Maintenance Commands): Document "maint set/show
can-use-displaced-stepping".
Diffstat (limited to 'gdb/gdbarch.c')
-rw-r--r-- | gdb/gdbarch.c | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index dd13de1..0449aaa 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -226,6 +226,11 @@ struct gdbarch int vtable_function_descriptors; int vbit_in_delta; 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_fixup_ftype *displaced_step_fixup; + gdbarch_displaced_step_free_closure_ftype *displaced_step_free_closure; + gdbarch_displaced_step_location_ftype *displaced_step_location; gdbarch_overlay_update_ftype *overlay_update; gdbarch_core_read_description_ftype *core_read_description; gdbarch_static_transform_name_ftype *static_transform_name; @@ -350,6 +355,11 @@ struct gdbarch startup_gdbarch = 0, /* vtable_function_descriptors */ 0, /* vbit_in_delta */ 0, /* skip_permanent_breakpoint */ + 0, /* max_insn_length */ + 0, /* displaced_step_copy_insn */ + 0, /* displaced_step_fixup */ + NULL, /* displaced_step_free_closure */ + NULL, /* displaced_step_location */ 0, /* overlay_update */ 0, /* core_read_description */ 0, /* static_transform_name */ @@ -435,6 +445,9 @@ gdbarch_alloc (const struct gdbarch_info *info, gdbarch->coff_make_msymbol_special = default_coff_make_msymbol_special; gdbarch->name_of_malloc = "malloc"; gdbarch->register_reggroup_p = default_register_reggroup_p; + gdbarch->displaced_step_fixup = NULL; + gdbarch->displaced_step_free_closure = NULL; + gdbarch->displaced_step_location = NULL; gdbarch->target_signal_from_host = default_target_signal_from_host; gdbarch->target_signal_to_host = default_target_signal_to_host; /* gdbarch_alloc() */ @@ -592,6 +605,13 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of vtable_function_descriptors, invalid_p == 0 */ /* Skip verify of vbit_in_delta, invalid_p == 0 */ /* 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_fixup, has predicate */ + if ((! gdbarch->displaced_step_free_closure) != (! gdbarch->displaced_step_copy_insn)) + fprintf_unfiltered (log, "\n\tdisplaced_step_free_closure"); + if ((! gdbarch->displaced_step_location) != (! gdbarch->displaced_step_copy_insn)) + fprintf_unfiltered (log, "\n\tdisplaced_step_location"); /* Skip verify of overlay_update, has predicate */ /* Skip verify of core_read_description, has predicate */ /* Skip verify of static_transform_name, has predicate */ @@ -717,6 +737,24 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: deprecated_function_start_offset = 0x%s\n", paddr_nz (gdbarch->deprecated_function_start_offset)); fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_displaced_step_copy_insn_p() = %d\n", + gdbarch_displaced_step_copy_insn_p (gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: displaced_step_copy_insn = <0x%lx>\n", + (long) gdbarch->displaced_step_copy_insn); + fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_displaced_step_fixup_p() = %d\n", + gdbarch_displaced_step_fixup_p (gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: displaced_step_fixup = <0x%lx>\n", + (long) gdbarch->displaced_step_fixup); + fprintf_unfiltered (file, + "gdbarch_dump: displaced_step_free_closure = <0x%lx>\n", + (long) gdbarch->displaced_step_free_closure); + fprintf_unfiltered (file, + "gdbarch_dump: displaced_step_location = <0x%lx>\n", + (long) gdbarch->displaced_step_location); + fprintf_unfiltered (file, "gdbarch_dump: double_bit = %s\n", paddr_d (gdbarch->double_bit)); fprintf_unfiltered (file, @@ -819,6 +857,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: long_long_bit = %s\n", paddr_d (gdbarch->long_long_bit)); fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_max_insn_length_p() = %d\n", + gdbarch_max_insn_length_p (gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: max_insn_length = %s\n", + paddr_d (gdbarch->max_insn_length)); + fprintf_unfiltered (file, "gdbarch_dump: memory_insert_breakpoint = <0x%lx>\n", (long) gdbarch->memory_insert_breakpoint); fprintf_unfiltered (file, @@ -2907,6 +2951,114 @@ set_gdbarch_skip_permanent_breakpoint (struct gdbarch *gdbarch, } int +gdbarch_max_insn_length_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->max_insn_length != 0; +} + +ULONGEST +gdbarch_max_insn_length (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + /* Check variable changed from pre-default. */ + gdb_assert (gdbarch->max_insn_length != 0); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_max_insn_length called\n"); + return gdbarch->max_insn_length; +} + +void +set_gdbarch_max_insn_length (struct gdbarch *gdbarch, + ULONGEST max_insn_length) +{ + gdbarch->max_insn_length = max_insn_length; +} + +int +gdbarch_displaced_step_copy_insn_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->displaced_step_copy_insn != NULL; +} + +struct displaced_step_closure * +gdbarch_displaced_step_copy_insn (struct gdbarch *gdbarch, CORE_ADDR from, CORE_ADDR to, struct regcache *regs) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->displaced_step_copy_insn != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_displaced_step_copy_insn called\n"); + return gdbarch->displaced_step_copy_insn (gdbarch, from, to, regs); +} + +void +set_gdbarch_displaced_step_copy_insn (struct gdbarch *gdbarch, + gdbarch_displaced_step_copy_insn_ftype displaced_step_copy_insn) +{ + gdbarch->displaced_step_copy_insn = displaced_step_copy_insn; +} + +int +gdbarch_displaced_step_fixup_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->displaced_step_fixup != NULL; +} + +void +gdbarch_displaced_step_fixup (struct gdbarch *gdbarch, struct displaced_step_closure *closure, CORE_ADDR from, CORE_ADDR to, struct regcache *regs) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->displaced_step_fixup != NULL); + /* Do not check predicate: gdbarch->displaced_step_fixup != NULL, allow call. */ + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_displaced_step_fixup called\n"); + gdbarch->displaced_step_fixup (gdbarch, closure, from, to, regs); +} + +void +set_gdbarch_displaced_step_fixup (struct gdbarch *gdbarch, + gdbarch_displaced_step_fixup_ftype displaced_step_fixup) +{ + gdbarch->displaced_step_fixup = displaced_step_fixup; +} + +void +gdbarch_displaced_step_free_closure (struct gdbarch *gdbarch, struct displaced_step_closure *closure) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->displaced_step_free_closure != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_displaced_step_free_closure called\n"); + gdbarch->displaced_step_free_closure (gdbarch, closure); +} + +void +set_gdbarch_displaced_step_free_closure (struct gdbarch *gdbarch, + gdbarch_displaced_step_free_closure_ftype displaced_step_free_closure) +{ + gdbarch->displaced_step_free_closure = displaced_step_free_closure; +} + +CORE_ADDR +gdbarch_displaced_step_location (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->displaced_step_location != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_displaced_step_location called\n"); + return gdbarch->displaced_step_location (gdbarch); +} + +void +set_gdbarch_displaced_step_location (struct gdbarch *gdbarch, + gdbarch_displaced_step_location_ftype displaced_step_location) +{ + gdbarch->displaced_step_location = displaced_step_location; +} + +int gdbarch_overlay_update_p (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); |