diff --git a/gdb/infrun.c b/gdb/infrun.c
index 466bc4a..48da790 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -1581,7 +1581,7 @@ show_can_use_displaced_stepping (struct ui_file *file, int from_tty,
    over breakpoints.  */
 
 static int
-use_displaced_stepping (struct gdbarch *gdbarch)
+can_use_displaced_stepping_p (struct gdbarch *gdbarch)
 {
   return (((can_use_displaced_stepping == AUTO_BOOLEAN_AUTO && non_stop)
 	   || can_use_displaced_stepping == AUTO_BOOLEAN_TRUE)
@@ -1589,6 +1589,24 @@ use_displaced_stepping (struct gdbarch *gdbarch)
 	  && find_record_target () == NULL);
 }
 
+/* Return non-zero if displaced stepping should be used to step
+   over a breakpoint in the current thread.  */
+
+static int
+use_displaced_stepping_now_p (struct gdbarch *gdbarch,
+			      enum gdb_signal sig)
+{
+  CORE_ADDR retval;
+
+  /* We can't use displaced stepping when we have a signal to deliver;
+     the comments for displaced_step_prepare explain why.  The
+     comments in the handle_inferior event for dealing with 'random
+     signals' explain what we do instead.  */
+  return  (sig == GDB_SIGNAL_0
+	   && can_use_displaced_stepping_p (gdbarch)
+	   && entry_point_address_query (&retval));
+}
+
 /* Clean out any stray displaced stepping state.  */
 static void
 displaced_step_clear (struct displaced_step_inferior_state *displaced)
@@ -2140,6 +2158,10 @@ resume (enum gdb_signal sig)
 	fprintf_unfiltered (gdb_stdlog,
 			    "infrun: resume : clear step\n");
       step = 0;
+
+      /* Likewise, make sure we don't use displaced stepping, which
+	 would poke the scratch buffer in the child.  */
+      tp->control.trap_expected = 0;
     }
 
   if (debug_infrun)
@@ -2235,20 +2257,8 @@ resume (enum gdb_signal sig)
     tp->control.may_range_step = 0;
 
   /* If enabled, step over breakpoints by executing a copy of the
-     instruction at a different address.
-
-     We can't use displaced stepping when we have a signal to deliver;
-     the comments for displaced_step_prepare explain why.  The
-     comments in the handle_inferior event for dealing with 'random
-     signals' explain what we do instead.
-
-     We can't use displaced stepping when we are waiting for vfork_done
-     event, displaced stepping breaks the vfork child similarly as single
-     step software breakpoint.  */
-  if (use_displaced_stepping (gdbarch)
-      && tp->control.trap_expected
-      && sig == GDB_SIGNAL_0
-      && !current_inferior ()->waiting_for_vfork_done)
+     instruction at a different address.  */
+  if (tp->control.trap_expected && use_displaced_stepping_now_p (gdbarch, sig))
     {
       struct displaced_step_inferior_state *displaced;
 
@@ -2391,8 +2401,8 @@ resume (enum gdb_signal sig)
     }
 
   if (debug_displaced
-      && use_displaced_stepping (gdbarch)
-      && tp->control.trap_expected)
+      && tp->control.trap_expected
+      && use_displaced_stepping_now_p (gdbarch, sig))
     {
       struct regcache *resume_regcache = get_thread_regcache (tp->ptid);
       struct gdbarch *resume_gdbarch = get_regcache_arch (resume_regcache);
@@ -2707,7 +2717,9 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
      displaced stepping to do so, insert all breakpoints (watchpoints,
      etc.) but the one we're stepping over, step one instruction, and
      then re-insert the breakpoint when that step is finished.  */
-  if (tp->stepping_over_breakpoint && !use_displaced_stepping (gdbarch))
+  if (tp->stepping_over_breakpoint
+      && !use_displaced_stepping_now_p (gdbarch,
+					tp->suspend.stop_signal))
     {
       struct regcache *regcache = get_current_regcache ();
 
@@ -6255,6 +6267,7 @@ keep_going (struct execution_control_state *ecs)
       struct regcache *regcache = get_current_regcache ();
       int remove_bp;
       int remove_wps;
+      enum gdb_signal signo;
 
       /* Either the trap was not expected, but we are continuing
 	 anyway (if we got a signal, the user asked it be passed to
@@ -6280,7 +6293,25 @@ keep_going (struct execution_control_state *ecs)
       remove_wps = (ecs->event_thread->stepping_over_watchpoint
 		    && !target_have_steppable_watchpoint);
 
-      if (remove_bp && !use_displaced_stepping (get_regcache_arch (regcache)))
+      /* Do not deliver GDB_SIGNAL_TRAP (except when the user
+	 explicitly specifies that such a signal should be delivered
+	 to the target program).  Typically, that would occur when a
+	 user is debugging a target monitor on a simulator: the target
+	 monitor sets a breakpoint; the simulator encounters this
+	 breakpoint and halts the simulation handing control to GDB;
+	 GDB, noting that the stop address doesn't map to any known
+	 breakpoint, returns control back to the simulator; the
+	 simulator then delivers the hardware equivalent of a
+	 GDB_SIGNAL_TRAP to the program being debugged.	 */
+      if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
+	  && !signal_program[ecs->event_thread->suspend.stop_signal])
+	ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
+
+      signo = ecs->event_thread->suspend.stop_signal;
+
+      if (remove_bp
+	  && !use_displaced_stepping_now_p (get_regcache_arch (regcache),
+					    signo))
 	{
 	  set_step_over_info (get_regcache_aspace (regcache),
 			      regcache_read_pc (regcache), remove_wps);
@@ -6306,20 +6337,6 @@ keep_going (struct execution_control_state *ecs)
 
       ecs->event_thread->control.trap_expected = (remove_bp || remove_wps);
 
-      /* Do not deliver GDB_SIGNAL_TRAP (except when the user
-	 explicitly specifies that such a signal should be delivered
-	 to the target program).  Typically, that would occur when a
-	 user is debugging a target monitor on a simulator: the target
-	 monitor sets a breakpoint; the simulator encounters this
-	 breakpoint and halts the simulation handing control to GDB;
-	 GDB, noting that the stop address doesn't map to any known
-	 breakpoint, returns control back to the simulator; the
-	 simulator then delivers the hardware equivalent of a
-	 GDB_SIGNAL_TRAP to the program being debugged.	 */
-      if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
-	  && !signal_program[ecs->event_thread->suspend.stop_signal])
-	ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
-
       discard_cleanups (old_cleanups);
       resume (ecs->event_thread->suspend.stop_signal);
     }
diff --git a/gdb/testsuite/gdb.base/step-over-no-symbols.exp b/gdb/testsuite/gdb.base/step-over-no-symbols.exp
new file mode 100644
index 0000000..d7bfd64
--- /dev/null
+++ b/gdb/testsuite/gdb.base/step-over-no-symbols.exp
@@ -0,0 +1,88 @@
+# Copyright (C) 2015 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Test that GDB can step past a breakpoint even if GDB doesn't have
+# symbols for the main binary.
+
+standard_testfile start.c
+
+if { ![support_displaced_stepping] } {
+    unsupported "displaced stepping"
+    return -1
+}
+
+if { [build_executable "failed to build" ${testfile} $srcfile] } {
+    return -1
+}
+
+# Get the current PC.  MSG is used as test message.
+
+proc get_pc { msg } {
+    global hex gdb_prompt
+
+    set addr ""
+    gdb_test_multiple "p /x \$pc" "$msg" {
+	-re " = ($hex).*$gdb_prompt $" {
+	    set addr $expect_out(1,string)
+	    pass "$msg"
+	}
+    }
+
+    return $addr
+}
+
+# Test stepping past a breakpoint with no symbols.  DISPLACED is one
+# of the "set displaced-stepping" options.  GDB should be able to fall
+# back to stepping past the breakpoint using an in-line step-over.
+
+proc test_step_over {displaced} {
+    global hex
+    global binfile
+
+    clean_restart $binfile
+
+    if ![runto_main] {
+	fail "couldn't run to main"
+	untested "stepping over breakpoint with displaced=$displaced"
+	return -1
+    }
+
+    delete_breakpoints
+
+    set msg "purging symbols"
+    gdb_test_multiple "symbol-file" "$msg" {
+	-re "Discard symbol table.*y or n. $" {
+	    gdb_test "y" "No symbol file now." "$msg"
+	}
+    }
+
+    set before_addr [get_pc "get before PC"]
+
+    gdb_test "break *\$pc" "Breakpoint .* at $hex"
+
+    gdb_test_no_output "set displaced-stepping $displaced"
+
+    gdb_test "stepi" "$hex in \?\? .*"
+
+    set after_addr [get_pc "get after PC"]
+
+    gdb_assert {$before_addr != $after_addr} "advanced"
+}
+
+foreach displaced { "off" "on" "auto" } {
+    with_test_prefix "displaced=$displaced" {
+	test_step_over $displaced
+    }
+}
