diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 777dfa57132..cedf0c5a684 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,25 @@ +2015-04-10 Pedro Alves + + PR gdb/13858 + * amd64-linux-tdep.c (amd64_linux_init_abi_common): Install + linux_displaced_step_location as gdbarch_displaced_step_location + hook. + * arm-linux-tdep.c (arm_linux_init_abi): Likewise. + * i386-linux-tdep.c (i386_linux_init_abi): Likewise. + * linux-tdep.c (linux_displaced_step_location): New function, + based on ppc_linux_displaced_step_location. + * linux-tdep.h (linux_displaced_step_location): New declaration. + * ppc-linux-tdep.c (ppc_linux_entry_point_addr): Delete. + (ppc_linux_inferior_created, ppc_linux_displaced_step_location): + Delete. + (ppc_linux_init_abi): Install linux_displaced_step_location as + gdbarch_displaced_step_location hook, even without Cell/B.E.. + (_initialize_ppc_linux_tdep): Don't install + ppc_linux_inferior_created as inferior_created observer. + * s390-linux-tdep.c (s390_gdbarch_init): Install + linux_displaced_step_location as gdbarch_displaced_step_location + hook. + 2015-04-09 Gary Benson * common/common-remote-fileio.h: Rename to... 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..9d75b667e85 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -2348,6 +2348,37 @@ 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. This avoids + the need for symbols. Also, 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. The auxiliary vector gets us the PowerPC-side entry + point address instead. */ + if (target_auxv_search (¤t_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, + ¤t_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 (¤t_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, - ¤t_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/ChangeLog b/gdb/testsuite/ChangeLog index 73785d62392..39f2f690ba1 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-04-10 Pedro Alves + + PR gdb/13858 + * gdb.base/step-over-no-symbols.exp: New file. + 2015-04-09 Andy Wingo * gdb.guile/scm-frame.exp: Add frame-read-register tests, modelled 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..43f33395a44 --- /dev/null +++ b/gdb/testsuite/gdb.base/step-over-no-symbols.exp @@ -0,0 +1,92 @@ +# 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 . + +# Test that GDB can step past a breakpoint even if GDB doesn't have +# symbols for the main binary. PR gdb/13858. + +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. If GDB can't find where to +# put the scratch pad, 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 "file" "$msg" { + -re "Are you sure you want to change the file.*y or n. $" { + send_gdb "y\n" + exp_continue + } + -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 + } +}