+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