+2014-11-12 Pedro Alves <palves@redhat.com>
+
+ * arch-utils.c (default_skip_permanent_breakpoint): New function.
+ * arch-utils.h (default_skip_permanent_breakpoint): New
+ declaration.
+ * gdbarch.sh (skip_permanent_breakpoint): Now an 'f' function.
+ Install default_skip_permanent_breakpoint as default method.
+ * i386-tdep.c (i386_skip_permanent_breakpoint): Delete function.
+ (i386_gdbarch_init): Don't install it.
+ * infrun.c (resume): Assume there's always a
+ gdbarch_skip_permanent_breakpoint implementation.
+ * gdbarch.h, gdbarch.c: Regenerate.
+
2014-11-11 Daniel Colascione <dancol@dancol.org>
Warn about cross-PID-namespace debugging.
return 0;
}
-/* */
+void
+default_skip_permanent_breakpoint (struct regcache *regcache)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ CORE_ADDR current_pc = regcache_read_pc (regcache);
+ const gdb_byte *bp_insn;
+ int bp_len;
+
+ bp_insn = gdbarch_breakpoint_from_pc (gdbarch, ¤t_pc, &bp_len);
+ current_pc += bp_len;
+ regcache_write_pc (regcache, current_pc);
+}
/* -Wmissing-prototypes */
extern initialize_file_ftype _initialize_gdbarch_utils;
/* Do-nothing version of vsyscall_range. Returns false. */
extern int default_vsyscall_range (struct gdbarch *gdbarch, struct mem_range *range);
+
+/* Default way to advance the PC to the next instruction in order to
+ skip a permanent breakpoint. Increments the PC by the size of a
+ software breakpoint instruction, as determined with
+ gdbarch_breakpoint_from_pc. This matches how the breakpoints
+ module determines whether a breakpoint is permanent. */
+extern void default_skip_permanent_breakpoint (struct regcache *regcache);
+
#endif
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->skip_permanent_breakpoint = default_skip_permanent_breakpoint;
gdbarch->displaced_step_hw_singlestep = default_displaced_step_hw_singlestep;
gdbarch->displaced_step_fixup = NULL;
gdbarch->displaced_step_free_closure = NULL;
/* Skip verify of gcore_bfd_target, has predicate. */
/* 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 skip_permanent_breakpoint, invalid_p == 0 */
/* 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 */
fprintf_unfiltered (file,
"gdbarch_dump: skip_main_prologue = <%s>\n",
host_address_to_string (gdbarch->skip_main_prologue));
- fprintf_unfiltered (file,
- "gdbarch_dump: gdbarch_skip_permanent_breakpoint_p() = %d\n",
- gdbarch_skip_permanent_breakpoint_p (gdbarch));
fprintf_unfiltered (file,
"gdbarch_dump: skip_permanent_breakpoint = <%s>\n",
host_address_to_string (gdbarch->skip_permanent_breakpoint));
gdbarch->vbit_in_delta = vbit_in_delta;
}
-int
-gdbarch_skip_permanent_breakpoint_p (struct gdbarch *gdbarch)
-{
- gdb_assert (gdbarch != NULL);
- return gdbarch->skip_permanent_breakpoint != NULL;
-}
-
void
gdbarch_skip_permanent_breakpoint (struct gdbarch *gdbarch, struct regcache *regcache)
{
/* Advance PC to next instruction in order to skip a permanent breakpoint. */
-extern int gdbarch_skip_permanent_breakpoint_p (struct gdbarch *gdbarch);
-
typedef void (gdbarch_skip_permanent_breakpoint_ftype) (struct regcache *regcache);
extern void gdbarch_skip_permanent_breakpoint (struct gdbarch *gdbarch, struct regcache *regcache);
extern void set_gdbarch_skip_permanent_breakpoint (struct gdbarch *gdbarch, gdbarch_skip_permanent_breakpoint_ftype *skip_permanent_breakpoint);
v:int:vbit_in_delta:::0:0::0
# Advance PC to next instruction in order to skip a permanent breakpoint.
-F:void:skip_permanent_breakpoint:struct regcache *regcache:regcache
+f:void:skip_permanent_breakpoint:struct regcache *regcache:regcache:default_skip_permanent_breakpoint:default_skip_permanent_breakpoint::0
# The maximum length of an instruction on this architecture in bytes.
V:ULONGEST:max_insn_length:::0:0
return read_memory_unsigned_integer (sp + (4 * (argi + 1)), 4, byte_order);
}
-static void
-i386_skip_permanent_breakpoint (struct regcache *regcache)
-{
- CORE_ADDR current_pc = regcache_read_pc (regcache);
-
- /* On i386, breakpoint is exactly 1 byte long, so we just
- adjust the PC in the regcache. */
- current_pc += 1;
- regcache_write_pc (regcache, current_pc);
-}
-
-
#define PREFIX_REPZ 0x01
#define PREFIX_REPNZ 0x02
#define PREFIX_LOCK 0x04
set_gdbarch_iterate_over_regset_sections
(gdbarch, i386_iterate_over_regset_sections);
- set_gdbarch_skip_permanent_breakpoint (gdbarch,
- i386_skip_permanent_breakpoint);
-
set_gdbarch_fast_tracepoint_valid_at (gdbarch,
i386_fast_tracepoint_valid_at);
breakpoints can't be removed. So we have to test for it here. */
if (breakpoint_here_p (aspace, pc) == permanent_breakpoint_here)
{
- if (gdbarch_skip_permanent_breakpoint_p (gdbarch))
- gdbarch_skip_permanent_breakpoint (gdbarch, regcache);
- else
- error (_("\
-The program is stopped at a permanent breakpoint, but GDB does not know\n\
-how to step past a permanent breakpoint on this architecture. Try using\n\
-a command like `return' or `jump' to continue execution."));
+ gdbarch_skip_permanent_breakpoint (gdbarch, regcache);
}
/* If we have a breakpoint to step over, make sure to do a single