diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
index b126366..2a8de82 100644
--- a/gdb/amd64-linux-tdep.c
+++ b/gdb/amd64-linux-tdep.c
@@ -1833,7 +1833,7 @@ amd64_linux_init_abi_common(struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_displaced_step_free_closure (gdbarch,
                                            simple_displaced_step_free_closure);
   set_gdbarch_displaced_step_location (gdbarch,
-                                       displaced_step_at_entry_point);
+                                       linux_displaced_step_location);
 
   set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type);
 
diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c
index 2b5aed7..f58da84 100644
--- a/gdb/arm-linux-tdep.c
+++ b/gdb/arm-linux-tdep.c
@@ -1448,7 +1448,7 @@ arm_linux_init_abi (struct gdbarch_info info,
   set_gdbarch_displaced_step_fixup (gdbarch, arm_displaced_step_fixup);
   set_gdbarch_displaced_step_free_closure (gdbarch,
 					   simple_displaced_step_free_closure);
-  set_gdbarch_displaced_step_location (gdbarch, displaced_step_at_entry_point);
+  set_gdbarch_displaced_step_location (gdbarch, linux_displaced_step_location);
 
   /* Reversible debugging, process record.  */
   set_gdbarch_process_record (gdbarch, arm_process_record);
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index 4a0ce60..061ad3a 100644
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -990,7 +990,7 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_displaced_step_free_closure (gdbarch,
                                            simple_displaced_step_free_closure);
   set_gdbarch_displaced_step_location (gdbarch,
-                                       displaced_step_at_entry_point);
+                                       linux_displaced_step_location);
 
   /* Functions for 'catch syscall'.  */
   set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_I386);
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 0b11e58..7a917f4 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -2348,6 +2348,32 @@ linux_infcall_mmap (CORE_ADDR size, unsigned prot)
   return retval;
 }
 
+/* See linux-tdep.h.  */
+
+CORE_ADDR
+linux_displaced_step_location (struct gdbarch *gdbarch)
+{
+  CORE_ADDR addr;
+  int bp_len;
+
+  /* Determine entry point from target auxiliary vector.  */
+  if (target_auxv_search (&current_target, AT_ENTRY, &addr) <= 0)
+    error (_("Cannot find AT_ENTRY auxiliary vector entry."));
+
+  /* Make certain that the address points at real code, and not a
+     function descriptor.  */
+  addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
+					     &current_target);
+
+  /* Inferior calls also use the entry point as a breakpoint location.
+     We don't want displaced stepping to interfere with those
+     breakpoints, so leave space.  */
+  gdbarch_breakpoint_from_pc (gdbarch, &addr, &bp_len);
+  addr += bp_len * 2;
+
+  return addr;
+}
+
 /* Display whether the gcore command is using the
    /proc/PID/coredump_filter file.  */
 
diff --git a/gdb/linux-tdep.h b/gdb/linux-tdep.h
index 78fc36b..ff45286 100644
--- a/gdb/linux-tdep.h
+++ b/gdb/linux-tdep.h
@@ -37,6 +37,11 @@ extern enum gdb_signal linux_gdb_signal_from_target (struct gdbarch *gdbarch,
 extern int linux_gdb_signal_to_target (struct gdbarch *gdbarch,
 				       enum gdb_signal signal);
 
+/* Default GNU/Linux implementation of `displaced_step_location', as
+   defined in gdbarch.h.  Determines the entry point from AT_ENTRY in
+   the target auxiliary vector.  */
+extern CORE_ADDR linux_displaced_step_location (struct gdbarch *gdbarch);
+
 extern void linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch);
 
 extern int linux_is_uclinux (void);
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index 3afbff2..3849ca6 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -703,47 +703,6 @@ static struct tramp_frame ppc64_linux_sighandler_tramp_frame = {
   ppc64_linux_sighandler_cache_init
 };
 
-
-/* Address to use for displaced stepping.  When debugging a stand-alone
-   SPU executable, entry_point_address () will point to an SPU local-store
-   address and is thus not usable as displaced stepping location.  We use
-   the auxiliary vector to determine the PowerPC-side entry point address
-   instead.  */
-
-static CORE_ADDR ppc_linux_entry_point_addr = 0;
-
-static void
-ppc_linux_inferior_created (struct target_ops *target, int from_tty)
-{
-  ppc_linux_entry_point_addr = 0;
-}
-
-static CORE_ADDR
-ppc_linux_displaced_step_location (struct gdbarch *gdbarch)
-{
-  if (ppc_linux_entry_point_addr == 0)
-    {
-      CORE_ADDR addr;
-
-      /* Determine entry point from target auxiliary vector.  */
-      if (target_auxv_search (&current_target, AT_ENTRY, &addr) <= 0)
-	error (_("Cannot find AT_ENTRY auxiliary vector entry."));
-
-      /* Make certain that the address points at real code, and not a
-	 function descriptor.  */
-      addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
-						 &current_target);
-
-      /* Inferior calls also use the entry point as a breakpoint location.
-	 We don't want displaced stepping to interfere with those
-	 breakpoints, so leave space.  */
-      ppc_linux_entry_point_addr = addr + 2 * PPC_INSN_SIZE;
-    }
-
-  return ppc_linux_entry_point_addr;
-}
-
-
 /* Return 1 if PPC_ORIG_R3_REGNUM and PPC_TRAP_REGNUM are usable.  */
 int
 ppc_linux_trap_reg_p (struct gdbarch *gdbarch)
@@ -1837,13 +1796,11 @@ ppc_linux_init_abi (struct gdbarch_info info,
 
       /* Cell/B.E. cross-architecture unwinder support.  */
       frame_unwind_prepend_unwinder (gdbarch, &ppu2spu_unwind);
-
-      /* The default displaced_step_at_entry_point doesn't work for
-	 SPU stand-alone executables.  */
-      set_gdbarch_displaced_step_location (gdbarch,
-					   ppc_linux_displaced_step_location);
     }
 
+  set_gdbarch_displaced_step_location (gdbarch,
+				       linux_displaced_step_location);
+
   set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type);
 
   /* Support reverse debugging.  */
@@ -1870,9 +1827,6 @@ _initialize_ppc_linux_tdep (void)
   gdbarch_register_osabi (bfd_arch_rs6000, bfd_mach_rs6k, GDB_OSABI_LINUX,
                          ppc_linux_init_abi);
 
-  /* Attach to inferior_created observer.  */
-  observer_attach_inferior_created (ppc_linux_inferior_created);
-
   /* Attach to observers to track __spe_current_active_context.  */
   observer_attach_inferior_created (ppc_linux_spe_context_inferior_created);
   observer_attach_solib_loaded (ppc_linux_spe_context_solib_loaded);
diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index cafa57b..b83a264 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -3295,8 +3295,7 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_displaced_step_fixup (gdbarch, s390_displaced_step_fixup);
   set_gdbarch_displaced_step_free_closure (gdbarch,
 					   simple_displaced_step_free_closure);
-  set_gdbarch_displaced_step_location (gdbarch,
-				       displaced_step_at_entry_point);
+  set_gdbarch_displaced_step_location (gdbarch, linux_displaced_step_location);
   set_gdbarch_max_insn_length (gdbarch, S390_MAX_INSTR_SIZE);
 
   /* Note that GNU/Linux is the only OS supported on this
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..0880d66
--- /dev/null
+++ b/gdb/testsuite/gdb.base/step-over-no-symbols.exp
@@ -0,0 +1,87 @@
+# 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 { [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" } {
+    if { $displaced != "off" && ![support_displaced_stepping] } {
+	continue
+    }
+
+    with_test_prefix "displaced=$displaced" {
+	test_step_over $displaced
+    }
+}
