summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/amd64-linux-tdep.c2
-rw-r--r--gdb/arm-linux-tdep.c2
-rw-r--r--gdb/i386-linux-tdep.c2
-rw-r--r--gdb/linux-tdep.c26
-rw-r--r--gdb/linux-tdep.h5
-rw-r--r--gdb/ppc-linux-tdep.c52
-rw-r--r--gdb/s390-linux-tdep.c3
-rw-r--r--gdb/testsuite/gdb.base/step-over-no-symbols.exp87
8 files changed, 125 insertions, 54 deletions
diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
index b126366cafb..2a8de82e6f0 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 2b5aed7b0d8..f58da846e65 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 4a0ce600c35..061ad3a74c1 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 0b11e58ca1c..7a917f4b175 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 78fc36b5962..ff45286cd9a 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 3afbff215e8..3849ca665c9 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 cafa57b4d54..b83a264ee86 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 00000000000..0880d6649a6
--- /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
+ }
+}