diff --git a/gdb-6.3-threaded-watchpoints-20041213.patch b/gdb-6.3-threaded-watchpoints-20041213.patch index d9b1788..74abf64 100644 --- a/gdb-6.3-threaded-watchpoints-20041213.patch +++ b/gdb-6.3-threaded-watchpoints-20041213.patch @@ -27,12 +27,14 @@ * s390-nat.c: Ditto. * Makefile.in: Add observer.h and linux-nat.h to ia64-linux-nat.o and s390-nat.o. + * gdbarch.sh (single_step_through_delay): New directive. + * gdbarch.h: Regenerated. + * gdbarch.c: Ditto. * doc/observer.texi: Add two new observers for linux_new_thread and sigtrap. ---- gdb-6.3/gdb/doc/observer.texi.fix Mon Dec 13 15:01:35 2004 ---- gdb-6.3/gdb/doc/observer.texi.fix Wed Dec 15 14:36:48 2004 -+++ gdb-6.3/gdb/doc/observer.texi Wed Dec 15 14:38:18 2004 +--- gdb-6.3/gdb/doc/observer.texi.fix Fri Jan 7 16:59:57 2005 ++++ gdb-6.3/gdb/doc/observer.texi Fri Jan 7 17:04:07 2005 @@ -95,3 +95,14 @@ inferior, and before any information on The specified shared library has been discovered to be unloaded. @end deftypefun @@ -48,305 +50,8 @@ +@end deftypefun + + ---- gdb-6.3/gdb/linux-nat.c.fix Wed Dec 15 14:49:33 2004 -+++ gdb-6.3/gdb/linux-nat.c Wed Dec 15 15:58:50 2004 -@@ -34,6 +34,7 @@ - #include "gdbthread.h" - #include "gdbcmd.h" - #include "regcache.h" -+#include "observer.h" - #include /* for MAXPATHLEN */ - #include /* for elf_gregset etc. */ - #include "elf-bfd.h" /* for elfcore_write_* */ -@@ -69,7 +70,7 @@ - #define PTRACE_EVENT_VFORK 2 - #define PTRACE_EVENT_CLONE 3 - #define PTRACE_EVENT_EXEC 4 --#define PTRACE_EVENT_VFORKDONE 5 -+#define PTRACE_EVENT_VFORK_DONE 5 - #define PTRACE_EVENT_EXIT 6 - - #endif /* PTRACE_EVENT_FORK */ -@@ -147,21 +148,50 @@ linux_tracefork_child (void) - ptrace (PTRACE_TRACEME, 0, 0, 0); - kill (getpid (), SIGSTOP); - fork (); -- exit (0); -+ _exit (0); - } - --/* Determine if PTRACE_O_TRACEFORK can be used to follow fork events. We -+/* Wrapper function for waitpid which handles EINTR. */ -+ -+static int -+my_waitpid (int pid, int *status, int flags) -+{ -+ int ret; -+ do -+ { -+ ret = waitpid (pid, status, flags); -+ } -+ while (ret == -1 && errno == EINTR); -+ -+ return ret; -+} -+ -+/* Determine if PTRACE_O_TRACEFORK can be used to follow fork events. -+ -+ First, we try to enable fork tracing on ORIGINAL_PID. If this fails, -+ we know that the feature is not available. This may change the tracing -+ options for ORIGINAL_PID, but we'll be setting them shortly anyway. -+ -+ However, if it succeeds, we don't know for sure that the feature is -+ available; old versions of PTRACE_SETOPTIONS ignored unknown options. We - create a child process, attach to it, use PTRACE_SETOPTIONS to enable -- fork tracing, and let it fork. If the process exits, we assume that -- we can't use TRACEFORK; if we get the fork notification, and we can -- extract the new child's PID, then we assume that we can. */ -+ fork tracing, and let it fork. If the process exits, we assume that we -+ can't use TRACEFORK; if we get the fork notification, and we can extract -+ the new child's PID, then we assume that we can. */ - - static void --linux_test_for_tracefork (void) -+linux_test_for_tracefork (int original_pid) - { - int child_pid, ret, status; - long second_pid; - -+ linux_supports_tracefork_flag = 0; -+ linux_supports_tracevforkdone_flag = 0; -+ -+ ret = ptrace (PTRACE_SETOPTIONS, original_pid, 0, PTRACE_O_TRACEFORK); -+ if (ret != 0) -+ return; -+ - child_pid = fork (); - if (child_pid == -1) - perror_with_name ("linux_test_for_tracefork: fork"); -@@ -169,7 +199,7 @@ linux_test_for_tracefork (void) - if (child_pid == 0) - linux_tracefork_child (); - -- ret = waitpid (child_pid, &status, 0); -+ ret = my_waitpid (child_pid, &status, 0); - if (ret == -1) - perror_with_name ("linux_test_for_tracefork: waitpid"); - else if (ret != child_pid) -@@ -177,13 +207,23 @@ linux_test_for_tracefork (void) - if (! WIFSTOPPED (status)) - error ("linux_test_for_tracefork: waitpid: unexpected status %d.", status); - -- linux_supports_tracefork_flag = 0; -- - ret = ptrace (PTRACE_SETOPTIONS, child_pid, 0, PTRACE_O_TRACEFORK); - if (ret != 0) - { -- ptrace (PTRACE_KILL, child_pid, 0, 0); -- waitpid (child_pid, &status, 0); -+ ret = ptrace (PTRACE_KILL, child_pid, 0, 0); -+ if (ret != 0) -+ { -+ warning ("linux_test_for_tracefork: failed to kill child"); -+ return; -+ } -+ -+ ret = my_waitpid (child_pid, &status, 0); -+ if (ret != child_pid) -+ warning ("linux_test_for_tracefork: failed to wait for killed child"); -+ else if (!WIFSIGNALED (status)) -+ warning ("linux_test_for_tracefork: unexpected wait status 0x%x from " -+ "killed child", status); -+ - return; - } - -@@ -192,8 +232,12 @@ linux_test_for_tracefork (void) - PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORKDONE); - linux_supports_tracevforkdone_flag = (ret == 0); - -- ptrace (PTRACE_CONT, child_pid, 0, 0); -- ret = waitpid (child_pid, &status, 0); -+ ret = ptrace (PTRACE_CONT, child_pid, 0, 0); -+ if (ret != 0) -+ warning ("linux_test_for_tracefork: failed to resume child"); -+ -+ ret = my_waitpid (child_pid, &status, 0); -+ - if (ret == child_pid && WIFSTOPPED (status) - && status >> 16 == PTRACE_EVENT_FORK) - { -@@ -204,34 +248,38 @@ linux_test_for_tracefork (void) - int second_status; - - linux_supports_tracefork_flag = 1; -- waitpid (second_pid, &second_status, 0); -- ptrace (PTRACE_DETACH, second_pid, 0, 0); -+ my_waitpid (second_pid, &second_status, 0); -+ ret = ptrace (PTRACE_KILL, second_pid, 0, 0); -+ if (ret != 0) -+ warning ("linux_test_for_tracefork: failed to kill second child"); - } - } -+ else -+ warning ("linux_test_for_tracefork: unexpected result from waitpid " -+ "(%d, status 0x%x)", ret, status); - -- if (WIFSTOPPED (status)) -- { -- ptrace (PTRACE_DETACH, child_pid, 0, 0); -- waitpid (child_pid, &status, 0); -- } -+ ret = ptrace (PTRACE_KILL, child_pid, 0, 0); -+ if (ret != 0) -+ warning ("linux_test_for_tracefork: failed to kill child"); -+ my_waitpid (child_pid, &status, 0); - } - - /* Return non-zero iff we have tracefork functionality available. - This function also sets linux_supports_tracefork_flag. */ - - static int --linux_supports_tracefork (void) -+linux_supports_tracefork (int pid) - { - if (linux_supports_tracefork_flag == -1) -- linux_test_for_tracefork (); -+ linux_test_for_tracefork (pid); - return linux_supports_tracefork_flag; - } - - static int --linux_supports_tracevforkdone (void) -+linux_supports_tracevforkdone (int pid) - { - if (linux_supports_tracefork_flag == -1) -- linux_test_for_tracefork (); -+ linux_test_for_tracefork (pid); - return linux_supports_tracevforkdone_flag; - } - -@@ -242,12 +290,12 @@ linux_enable_event_reporting (ptid_t pti - int pid = ptid_get_pid (ptid); - int options; - -- if (! linux_supports_tracefork ()) -+ if (! linux_supports_tracefork (pid)) - return; - - options = PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACEEXEC - | PTRACE_O_TRACECLONE; -- if (linux_supports_tracevforkdone ()) -+ if (linux_supports_tracevforkdone (pid)) - options |= PTRACE_O_TRACEVFORKDONE; - - /* Do not enable PTRACE_O_TRACEEXIT until GDB is more prepared to support -@@ -308,13 +356,14 @@ child_follow_fork (int follow_child) - - if (has_vforked) - { -- if (linux_supports_tracevforkdone ()) -+ gdb_assert (linux_supports_tracefork_flag >= 0); -+ if (linux_supports_tracevforkdone (0)) - { - int status; - - ptrace (PTRACE_CONT, parent_pid, 0, 0); - waitpid (parent_pid, &status, __WALL); -- if ((status >> 16) != PTRACE_EVENT_VFORKDONE) -+ if ((status >> 16) != PTRACE_EVENT_VFORK_DONE) - warning ("Unexpected waitpid result %06x when waiting for " - "vfork-done", status); - } -@@ -476,7 +525,7 @@ linux_handle_extended_wait (int pid, int - int - child_insert_fork_catchpoint (int pid) - { -- if (! linux_supports_tracefork ()) -+ if (! linux_supports_tracefork (pid)) - error ("Your system does not support fork catchpoints."); - - return 0; -@@ -485,7 +534,7 @@ child_insert_fork_catchpoint (int pid) - int - child_insert_vfork_catchpoint (int pid) - { -- if (!linux_supports_tracefork ()) -+ if (!linux_supports_tracefork (pid)) - error ("Your system does not support vfork catchpoints."); - - return 0; -@@ -494,7 +543,7 @@ child_insert_vfork_catchpoint (int pid) - int - child_insert_exec_catchpoint (int pid) - { -- if (!linux_supports_tracefork ()) -+ if (!linux_supports_tracefork (pid)) - error ("Your system does not support exec catchpoints."); - - return 0; -@@ -716,6 +765,9 @@ delete_lwp (ptid_t ptid) - else - lwp_list = lp->next; - -+ if (lp->saved_trap_data) -+ xfree (lp->saved_trap_data); -+ - xfree (lp); - } - -@@ -1285,6 +1337,13 @@ stop_wait_callback (struct lwp_info *lp, - user will delete or disable the breakpoint, but the - thread will have already tripped on it. */ - -+ /* Notify any observers that we have a SIGTRAP. -+ This is needed on platforms that must save more state -+ than just the trap. For example, ia64 linux uses -+ siginfo to determine if a watchpoint has occurred and -+ this information gets trashed by a SIGSTOP. */ -+ observer_notify_sigtrap (lp); -+ - /* Now resume this LWP and get the SIGSTOP event. */ - errno = 0; - ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0); -@@ -1960,6 +2019,14 @@ retry: - } - } - -+ /* For platforms such as ia64, a hardware watchpoint is -+ determined by looking at special information available -+ at the time time of the trap (siginfo). This information -+ is not preserved if we choose to take an event on another -+ thread and later come back to this event, thus we must -+ notify an observer so the information can be stored. */ -+ observer_notify_sigtrap (lp); -+ - /* Handle GNU/Linux's extended waitstatus for trace events. */ - if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP && status >> 16 != 0) - { ---- gdb-6.3/gdb/linux-nat.h.fix Wed Dec 15 14:49:22 2004 -+++ gdb-6.3/gdb/linux-nat.h Wed Dec 15 14:46:57 2004 -@@ -61,6 +61,18 @@ struct lwp_info - - /* Next LWP in list. */ - struct lwp_info *next; -+ -+ /* Optional saved trap state for when a trap gets pushed back -+ due to multiple events occurring at the same time. */ -+ void *saved_trap_data; -+}; -+ -+/* Watchpoint description. */ -+struct linux_watchpoint -+{ -+ CORE_ADDR addr; -+ int len; -+ int type; - }; - - /* Read/write to target memory via the Linux kernel's "proc file ---- gdb-6.3/gdb/infrun.c.fix Wed Dec 15 14:49:16 2004 -+++ gdb-6.3/gdb/infrun.c Wed Dec 15 14:46:50 2004 +--- gdb-6.3/gdb/infrun.c.fix Fri Jan 7 16:55:54 2005 ++++ gdb-6.3/gdb/infrun.c Fri Jan 7 17:04:37 2005 @@ -106,6 +106,8 @@ static ptid_t previous_inferior_ptid; static int may_follow_exec = MAY_FOLLOW_EXEC; @@ -1029,15 +734,6 @@ if (ecs->infwait_state == infwait_normal_state) { overlay_cache_invalid = 1; -@@ -3014,7 +3118,7 @@ normal_stop (void) - LOCATION: Print only location - SRC_AND_LOC: Print location and source line */ - if (do_frame_printing) -- print_stack_frame (get_selected_frame (), 0, source_flag); -+ print_stack_frame (get_selected_frame (NULL), 0, source_flag); - - /* Display the auto-display expressions. */ - do_displays (); @@ -3790,6 +3894,10 @@ Pass and Stop may be combined.", NULL)); This allows you to set a list of commands to be run each time execution\n\ of the program stops.", &cmdlist); @@ -1049,8 +745,26 @@ numsigs = (int) TARGET_SIGNAL_LAST; signal_stop = (unsigned char *) xmalloc (sizeof (signal_stop[0]) * numsigs); signal_print = (unsigned char *) ---- gdb-6.3/gdb/breakpoint.c.fix Wed Dec 15 14:48:52 2004 -+++ gdb-6.3/gdb/breakpoint.c Wed Dec 15 14:46:26 2004 +--- gdb-6.3/gdb/gdbarch.h.fix Fri Jan 7 17:08:19 2005 ++++ gdb-6.3/gdb/gdbarch.h Fri Jan 7 17:09:12 2005 +@@ -1218,6 +1218,15 @@ extern void set_gdbarch_software_single_ + #define SOFTWARE_SINGLE_STEP(sig, insert_breakpoints_p) (gdbarch_software_single_step (current_gdbarch, sig, insert_breakpoints_p)) + #endif + ++/* Return non-zero if the processor is executing a delay slot and a ++ * further single-step is needed before the instruction finishes. */ ++ ++extern int gdbarch_single_step_through_delay_p (struct gdbarch *gdbarch); ++ ++typedef int (gdbarch_single_step_through_delay_ftype) (struct gdbarch *gdbarch, struct frame_info *frame); ++extern int gdbarch_single_step_through_delay (struct gdbarch *gdbarch, struct frame_info *frame); ++extern void set_gdbarch_single_step_through_delay (struct gdbarch *gdbarch, gdbarch_single_step_through_delay_ftype *single_step_through_delay); ++ + /* FIXME: cagney/2003-08-28: Need to find a better way of selecting the + disassembler. Perhaps objdump can handle it? */ + +--- gdb-6.3/gdb/breakpoint.c.fix Fri Jan 7 16:58:12 2005 ++++ gdb-6.3/gdb/breakpoint.c Fri Jan 7 17:04:07 2005 @@ -86,11 +86,6 @@ static void watch_command (char *, int); static int can_use_hardware_watchpoint (struct value *); @@ -1619,8 +1333,78 @@ static void hbreak_command (char *arg, int from_tty) { ---- gdb-6.3/gdb/breakpoint.h.fix Wed Dec 15 14:49:02 2004 -+++ gdb-6.3/gdb/breakpoint.h Wed Dec 15 14:46:40 2004 +--- gdb-6.3/gdb/gdbarch.c.fix Fri Jan 7 17:09:18 2005 ++++ gdb-6.3/gdb/gdbarch.c Fri Jan 7 17:36:36 2005 +@@ -211,6 +211,7 @@ struct gdbarch + gdbarch_addr_bits_remove_ftype *addr_bits_remove; + gdbarch_smash_text_address_ftype *smash_text_address; + gdbarch_software_single_step_ftype *software_single_step; ++ gdbarch_single_step_through_delay_ftype *single_step_through_delay; + gdbarch_print_insn_ftype *print_insn; + gdbarch_skip_trampoline_code_ftype *skip_trampoline_code; + gdbarch_skip_solib_resolver_ftype *skip_solib_resolver; +@@ -337,6 +338,7 @@ struct gdbarch startup_gdbarch = + 0, /* addr_bits_remove */ + 0, /* smash_text_address */ + 0, /* software_single_step */ ++ 0, /* single_step_through_delay */ + 0, /* print_insn */ + 0, /* skip_trampoline_code */ + generic_skip_solib_resolver, /* skip_solib_resolver */ +@@ -591,6 +593,7 @@ verify_gdbarch (struct gdbarch *current_ + /* Skip verify of addr_bits_remove, invalid_p == 0 */ + /* Skip verify of smash_text_address, invalid_p == 0 */ + /* Skip verify of software_single_step, has predicate */ ++ /* Skip verify of single_step_through_delay, has predicate */ + if (current_gdbarch->print_insn == 0) + fprintf_unfiltered (log, "\n\tprint_insn"); + /* Skip verify of skip_trampoline_code, invalid_p == 0 */ +@@ -1516,6 +1519,12 @@ gdbarch_dump (struct gdbarch *current_gd + fprintf_unfiltered (file, + "gdbarch_dump: short_bit = %s\n", + paddr_d (current_gdbarch->short_bit)); ++ fprintf_unfiltered (file, ++ "gdbarch_dump: gdbarch_single_step_through_delay_p() = %d\n", ++ gdbarch_single_step_through_delay_p (current_gdbarch)); ++ fprintf_unfiltered (file, ++ "gdbarch_dump: single_step_through_delay = <0x%lx>\n", ++ (long) current_gdbarch->single_step_through_delay); + #ifdef SKIP_PROLOGUE + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", +@@ -3346,6 +3355,30 @@ set_gdbarch_software_single_step (struct + } + + int ++gdbarch_single_step_through_delay_p (struct gdbarch *gdbarch) ++{ ++ gdb_assert (gdbarch != NULL); ++ return gdbarch->single_step_through_delay != NULL; ++} ++ ++int ++gdbarch_single_step_through_delay (struct gdbarch *gdbarch, struct frame_info *frame) ++{ ++ gdb_assert (gdbarch != NULL); ++ gdb_assert (gdbarch->single_step_through_delay != NULL); ++ if (gdbarch_debug >= 2) ++ fprintf_unfiltered (gdb_stdlog, "gdbarch_single_step_through_delay called\n"); ++ return gdbarch->single_step_through_delay (gdbarch, frame); ++} ++ ++void ++set_gdbarch_single_step_through_delay (struct gdbarch *gdbarch, ++ gdbarch_single_step_through_delay_ftype single_step_through_delay) ++{ ++ gdbarch->single_step_through_delay = single_step_through_delay; ++} ++ ++int + gdbarch_print_insn (struct gdbarch *gdbarch, bfd_vma vma, struct disassemble_info *info) + { + gdb_assert (gdbarch != NULL); +--- gdb-6.3/gdb/breakpoint.h.fix Fri Jan 7 16:58:19 2005 ++++ gdb-6.3/gdb/breakpoint.h Fri Jan 7 17:04:07 2005 @@ -397,6 +397,11 @@ struct breakpoint /* Is breakpoint pending on shlib loads? */ @@ -1648,8 +1432,465 @@ extern int remove_breakpoints (void); /* This function can be used to physically insert eventpoints from the ---- gdb-6.3/gdb/ia64-linux-nat.c.fix Wed Dec 15 14:48:34 2004 -+++ gdb-6.3/gdb/ia64-linux-nat.c Wed Dec 15 14:46:14 2004 +--- gdb-6.3/gdb/linux-nat.c.fix Fri Jan 7 16:58:27 2005 ++++ gdb-6.3/gdb/linux-nat.c Fri Jan 7 17:04:07 2005 +@@ -34,6 +34,7 @@ + #include "gdbthread.h" + #include "gdbcmd.h" + #include "regcache.h" ++#include "observer.h" + #include /* for MAXPATHLEN */ + #include /* for elf_gregset etc. */ + #include "elf-bfd.h" /* for elfcore_write_* */ +@@ -69,7 +70,7 @@ + #define PTRACE_EVENT_VFORK 2 + #define PTRACE_EVENT_CLONE 3 + #define PTRACE_EVENT_EXEC 4 +-#define PTRACE_EVENT_VFORKDONE 5 ++#define PTRACE_EVENT_VFORK_DONE 5 + #define PTRACE_EVENT_EXIT 6 + + #endif /* PTRACE_EVENT_FORK */ +@@ -147,21 +148,50 @@ linux_tracefork_child (void) + ptrace (PTRACE_TRACEME, 0, 0, 0); + kill (getpid (), SIGSTOP); + fork (); +- exit (0); ++ _exit (0); + } + +-/* Determine if PTRACE_O_TRACEFORK can be used to follow fork events. We ++/* Wrapper function for waitpid which handles EINTR. */ ++ ++static int ++my_waitpid (int pid, int *status, int flags) ++{ ++ int ret; ++ do ++ { ++ ret = waitpid (pid, status, flags); ++ } ++ while (ret == -1 && errno == EINTR); ++ ++ return ret; ++} ++ ++/* Determine if PTRACE_O_TRACEFORK can be used to follow fork events. ++ ++ First, we try to enable fork tracing on ORIGINAL_PID. If this fails, ++ we know that the feature is not available. This may change the tracing ++ options for ORIGINAL_PID, but we'll be setting them shortly anyway. ++ ++ However, if it succeeds, we don't know for sure that the feature is ++ available; old versions of PTRACE_SETOPTIONS ignored unknown options. We + create a child process, attach to it, use PTRACE_SETOPTIONS to enable +- fork tracing, and let it fork. If the process exits, we assume that +- we can't use TRACEFORK; if we get the fork notification, and we can +- extract the new child's PID, then we assume that we can. */ ++ fork tracing, and let it fork. If the process exits, we assume that we ++ can't use TRACEFORK; if we get the fork notification, and we can extract ++ the new child's PID, then we assume that we can. */ + + static void +-linux_test_for_tracefork (void) ++linux_test_for_tracefork (int original_pid) + { + int child_pid, ret, status; + long second_pid; + ++ linux_supports_tracefork_flag = 0; ++ linux_supports_tracevforkdone_flag = 0; ++ ++ ret = ptrace (PTRACE_SETOPTIONS, original_pid, 0, PTRACE_O_TRACEFORK); ++ if (ret != 0) ++ return; ++ + child_pid = fork (); + if (child_pid == -1) + perror_with_name ("linux_test_for_tracefork: fork"); +@@ -169,7 +199,7 @@ linux_test_for_tracefork (void) + if (child_pid == 0) + linux_tracefork_child (); + +- ret = waitpid (child_pid, &status, 0); ++ ret = my_waitpid (child_pid, &status, 0); + if (ret == -1) + perror_with_name ("linux_test_for_tracefork: waitpid"); + else if (ret != child_pid) +@@ -177,13 +207,23 @@ linux_test_for_tracefork (void) + if (! WIFSTOPPED (status)) + error ("linux_test_for_tracefork: waitpid: unexpected status %d.", status); + +- linux_supports_tracefork_flag = 0; +- + ret = ptrace (PTRACE_SETOPTIONS, child_pid, 0, PTRACE_O_TRACEFORK); + if (ret != 0) + { +- ptrace (PTRACE_KILL, child_pid, 0, 0); +- waitpid (child_pid, &status, 0); ++ ret = ptrace (PTRACE_KILL, child_pid, 0, 0); ++ if (ret != 0) ++ { ++ warning ("linux_test_for_tracefork: failed to kill child"); ++ return; ++ } ++ ++ ret = my_waitpid (child_pid, &status, 0); ++ if (ret != child_pid) ++ warning ("linux_test_for_tracefork: failed to wait for killed child"); ++ else if (!WIFSIGNALED (status)) ++ warning ("linux_test_for_tracefork: unexpected wait status 0x%x from " ++ "killed child", status); ++ + return; + } + +@@ -192,8 +232,12 @@ linux_test_for_tracefork (void) + PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORKDONE); + linux_supports_tracevforkdone_flag = (ret == 0); + +- ptrace (PTRACE_CONT, child_pid, 0, 0); +- ret = waitpid (child_pid, &status, 0); ++ ret = ptrace (PTRACE_CONT, child_pid, 0, 0); ++ if (ret != 0) ++ warning ("linux_test_for_tracefork: failed to resume child"); ++ ++ ret = my_waitpid (child_pid, &status, 0); ++ + if (ret == child_pid && WIFSTOPPED (status) + && status >> 16 == PTRACE_EVENT_FORK) + { +@@ -204,34 +248,38 @@ linux_test_for_tracefork (void) + int second_status; + + linux_supports_tracefork_flag = 1; +- waitpid (second_pid, &second_status, 0); +- ptrace (PTRACE_DETACH, second_pid, 0, 0); ++ my_waitpid (second_pid, &second_status, 0); ++ ret = ptrace (PTRACE_KILL, second_pid, 0, 0); ++ if (ret != 0) ++ warning ("linux_test_for_tracefork: failed to kill second child"); + } + } ++ else ++ warning ("linux_test_for_tracefork: unexpected result from waitpid " ++ "(%d, status 0x%x)", ret, status); + +- if (WIFSTOPPED (status)) +- { +- ptrace (PTRACE_DETACH, child_pid, 0, 0); +- waitpid (child_pid, &status, 0); +- } ++ ret = ptrace (PTRACE_KILL, child_pid, 0, 0); ++ if (ret != 0) ++ warning ("linux_test_for_tracefork: failed to kill child"); ++ my_waitpid (child_pid, &status, 0); + } + + /* Return non-zero iff we have tracefork functionality available. + This function also sets linux_supports_tracefork_flag. */ + + static int +-linux_supports_tracefork (void) ++linux_supports_tracefork (int pid) + { + if (linux_supports_tracefork_flag == -1) +- linux_test_for_tracefork (); ++ linux_test_for_tracefork (pid); + return linux_supports_tracefork_flag; + } + + static int +-linux_supports_tracevforkdone (void) ++linux_supports_tracevforkdone (int pid) + { + if (linux_supports_tracefork_flag == -1) +- linux_test_for_tracefork (); ++ linux_test_for_tracefork (pid); + return linux_supports_tracevforkdone_flag; + } + +@@ -242,12 +290,12 @@ linux_enable_event_reporting (ptid_t pti + int pid = ptid_get_pid (ptid); + int options; + +- if (! linux_supports_tracefork ()) ++ if (! linux_supports_tracefork (pid)) + return; + + options = PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACEEXEC + | PTRACE_O_TRACECLONE; +- if (linux_supports_tracevforkdone ()) ++ if (linux_supports_tracevforkdone (pid)) + options |= PTRACE_O_TRACEVFORKDONE; + + /* Do not enable PTRACE_O_TRACEEXIT until GDB is more prepared to support +@@ -308,13 +356,14 @@ child_follow_fork (int follow_child) + + if (has_vforked) + { +- if (linux_supports_tracevforkdone ()) ++ gdb_assert (linux_supports_tracefork_flag >= 0); ++ if (linux_supports_tracevforkdone (0)) + { + int status; + + ptrace (PTRACE_CONT, parent_pid, 0, 0); + waitpid (parent_pid, &status, __WALL); +- if ((status >> 16) != PTRACE_EVENT_VFORKDONE) ++ if ((status >> 16) != PTRACE_EVENT_VFORK_DONE) + warning ("Unexpected waitpid result %06x when waiting for " + "vfork-done", status); + } +@@ -476,7 +525,7 @@ linux_handle_extended_wait (int pid, int + int + child_insert_fork_catchpoint (int pid) + { +- if (! linux_supports_tracefork ()) ++ if (! linux_supports_tracefork (pid)) + error ("Your system does not support fork catchpoints."); + + return 0; +@@ -485,7 +534,7 @@ child_insert_fork_catchpoint (int pid) + int + child_insert_vfork_catchpoint (int pid) + { +- if (!linux_supports_tracefork ()) ++ if (!linux_supports_tracefork (pid)) + error ("Your system does not support vfork catchpoints."); + + return 0; +@@ -494,7 +543,7 @@ child_insert_vfork_catchpoint (int pid) + int + child_insert_exec_catchpoint (int pid) + { +- if (!linux_supports_tracefork ()) ++ if (!linux_supports_tracefork (pid)) + error ("Your system does not support exec catchpoints."); + + return 0; +@@ -716,6 +765,9 @@ delete_lwp (ptid_t ptid) + else + lwp_list = lp->next; + ++ if (lp->saved_trap_data) ++ xfree (lp->saved_trap_data); ++ + xfree (lp); + } + +@@ -1285,6 +1337,13 @@ stop_wait_callback (struct lwp_info *lp, + user will delete or disable the breakpoint, but the + thread will have already tripped on it. */ + ++ /* Notify any observers that we have a SIGTRAP. ++ This is needed on platforms that must save more state ++ than just the trap. For example, ia64 linux uses ++ siginfo to determine if a watchpoint has occurred and ++ this information gets trashed by a SIGSTOP. */ ++ observer_notify_sigtrap (lp); ++ + /* Now resume this LWP and get the SIGSTOP event. */ + errno = 0; + ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0); +@@ -1960,6 +2019,14 @@ retry: + } + } + ++ /* For platforms such as ia64, a hardware watchpoint is ++ determined by looking at special information available ++ at the time time of the trap (siginfo). This information ++ is not preserved if we choose to take an event on another ++ thread and later come back to this event, thus we must ++ notify an observer so the information can be stored. */ ++ observer_notify_sigtrap (lp); ++ + /* Handle GNU/Linux's extended waitstatus for trace events. */ + if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP && status >> 16 != 0) + { +--- gdb-6.3/gdb/linux-nat.h.fix Fri Jan 7 16:58:33 2005 ++++ gdb-6.3/gdb/linux-nat.h Fri Jan 7 17:04:07 2005 +@@ -61,6 +61,18 @@ struct lwp_info + + /* Next LWP in list. */ + struct lwp_info *next; ++ ++ /* Optional saved trap state for when a trap gets pushed back ++ due to multiple events occurring at the same time. */ ++ void *saved_trap_data; ++}; ++ ++/* Watchpoint description. */ ++struct linux_watchpoint ++{ ++ CORE_ADDR addr; ++ int len; ++ int type; + }; + + /* Read/write to target memory via the Linux kernel's "proc file +--- gdb-6.3/gdb/Makefile.in.fix Fri Jan 7 16:58:42 2005 ++++ gdb-6.3/gdb/Makefile.in Fri Jan 7 17:04:07 2005 +@@ -2055,7 +2055,8 @@ ia64-aix-nat.o: ia64-aix-nat.c $(defs_h) + $(objfiles_h) $(gdb_stat_h) + ia64-aix-tdep.o: ia64-aix-tdep.c $(defs_h) + ia64-linux-nat.o: ia64-linux-nat.c $(defs_h) $(gdb_string_h) $(inferior_h) \ +- $(target_h) $(gdbcore_h) $(regcache_h) $(gdb_wait_h) $(gregset_h) ++ $(target_h) $(gdbcore_h) $(regcache_h) $(gdb_wait_h) $(gregset_h) \ ++ $(observer_h) $(linux_nat_h) + ia64-linux-tdep.o: ia64-linux-tdep.c $(defs_h) $(ia64_tdep_h) \ + $(arch_utils_h) $(gdbcore_h) $(regcache_h) + ia64-tdep.o: ia64-tdep.c $(defs_h) $(inferior_h) $(gdbcore_h) \ +@@ -2437,7 +2438,7 @@ rs6000-tdep.o: rs6000-tdep.c $(defs_h) $ + $(ppc_tdep_h) $(gdb_assert_h) $(dis_asm_h) $(trad_frame_h) \ + $(frame_unwind_h) $(frame_base_h) + s390-nat.o: s390-nat.c $(defs_h) $(tm_h) $(regcache_h) $(inferior_h) \ +- $(s390_tdep_h) ++ $(s390_tdep_h) $(observer_h) $(linux_nat_h) + s390-tdep.o: s390-tdep.c $(defs_h) $(arch_utils_h) $(frame_h) $(inferior_h) \ + $(symtab_h) $(target_h) $(gdbcore_h) $(gdbcmd_h) $(objfiles_h) \ + $(tm_h) $(__bfd_bfd_h) $(floatformat_h) $(regcache_h) \ +--- gdb-6.3/gdb/thread-db.c.fix Fri Jan 7 16:58:49 2005 ++++ gdb-6.3/gdb/thread-db.c Fri Jan 7 17:04:07 2005 +@@ -34,6 +34,7 @@ + #include "target.h" + #include "regcache.h" + #include "solib-svr4.h" ++#include "observer.h" + + #ifdef HAVE_GNU_LIBC_VERSION_H + #include +@@ -143,7 +144,6 @@ static void detach_thread (ptid_t ptid, + #define is_thread(ptid) (GET_THREAD (ptid) != 0) + + #define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0) +-#define BUILD_THREAD(tid, pid) ptid_build (pid, 0, tid) + + + /* Use "struct private_thread_info" to cache thread state. This is +@@ -267,7 +267,7 @@ thread_get_info_callback (const td_thrha + thread_db_err_str (err)); + + /* Fill the cache. */ +- thread_ptid = BUILD_THREAD (ti.ti_tid, GET_PID (inferior_ptid)); ++ thread_ptid = ptid_build (GET_PID (inferior_ptid), ti.ti_lid, ti.ti_tid); + thread_info = find_thread_pid (thread_ptid); + + /* In the case of a zombie thread, don't continue. We don't want to +@@ -385,22 +385,14 @@ thread_from_lwp (ptid_t ptid) + + gdb_assert (thread_info && thread_info->private->ti_valid); + +- return BUILD_THREAD (thread_info->private->ti.ti_tid, GET_PID (ptid)); ++ return ptid_build (GET_PID (ptid), GET_LWP (ptid), ++ thread_info->private->ti.ti_tid); + } + + static ptid_t + lwp_from_thread (ptid_t ptid) + { +- struct thread_info *thread_info; +- ptid_t thread_ptid; +- +- if (!is_thread (ptid)) +- return ptid; +- +- thread_info = find_thread_pid (ptid); +- thread_db_get_info (thread_info); +- +- return BUILD_LWP (thread_info->private->ti.ti_lid, GET_PID (ptid)); ++ return BUILD_LWP (GET_LWP (ptid), GET_PID (ptid)); + } + + +@@ -722,6 +714,7 @@ attach_thread (ptid_t ptid, const td_thr + { + struct thread_info *tp; + td_err_e err; ++ ptid_t new_ptid; + + /* If we're being called after a TD_CREATE event, we may already + know about this thread. There are two ways this can happen. We +@@ -757,11 +750,18 @@ attach_thread (ptid_t ptid, const td_thr + if (ti_p->ti_state == TD_THR_UNKNOWN || ti_p->ti_state == TD_THR_ZOMBIE) + return; /* A zombie thread -- do not attach. */ + ++ new_ptid = BUILD_LWP (ti_p->ti_lid, GET_PID (ptid)); ++ + /* Under GNU/Linux, we have to attach to each and every thread. */ + #ifdef ATTACH_LWP +- ATTACH_LWP (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid)), 0); ++ ATTACH_LWP (new_ptid, 0); + #endif + ++ /* Notify any observers of a new linux thread. This ++ would include any linux platforms that have to insert hardware ++ watchpoints on every thread. */ ++ observer_notify_linux_new_thread (new_ptid); ++ + /* Enable thread event reporting for this thread. */ + err = td_thr_event_enable_p (th_p, 1); + if (err != TD_OK) +@@ -903,7 +903,7 @@ check_event (ptid_t ptid) + if (err != TD_OK) + error ("Cannot get thread info: %s", thread_db_err_str (err)); + +- ptid = BUILD_THREAD (ti.ti_tid, GET_PID (ptid)); ++ ptid = ptid_build (GET_PID (ptid), ti.ti_lid, ti.ti_tid); + + switch (msg.event) + { +@@ -950,7 +950,8 @@ thread_db_wait (ptid_t ptid, struct targ + return pid_to_ptid (-1); + + if (ourstatus->kind == TARGET_WAITKIND_STOPPED +- && ourstatus->value.sig == TARGET_SIGNAL_TRAP) ++ && (ourstatus->value.sig == TARGET_SIGNAL_TRAP ++ || ourstatus->value.sig == TARGET_SIGNAL_ILL)) + /* Check for a thread event. */ + check_event (ptid); + +@@ -1175,7 +1176,7 @@ find_new_threads_callback (const td_thrh + if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE) + return 0; /* A zombie -- ignore. */ + +- ptid = BUILD_THREAD (ti.ti_tid, GET_PID (inferior_ptid)); ++ ptid = ptid_build (GET_PID (inferior_ptid), ti.ti_lid, ti.ti_tid); + + if (!in_thread_list (ptid)) + attach_thread (ptid, th_p, &ti, 1); +--- gdb-6.3/gdb/i386-linux-nat.c.fix Fri Jan 7 16:59:02 2005 ++++ gdb-6.3/gdb/i386-linux-nat.c Fri Jan 7 17:04:07 2005 +@@ -617,10 +617,9 @@ i386_linux_dr_get (int regnum) + int tid; + unsigned long value; + +- /* FIXME: kettenis/2001-01-29: It's not clear what we should do with +- multi-threaded processes here. For now, pretend there is just +- one thread. */ +- tid = PIDGET (inferior_ptid); ++ tid = TIDGET (inferior_ptid); ++ if (tid == 0) ++ tid = PIDGET (inferior_ptid); + + /* FIXME: kettenis/2001-03-27: Calling perror_with_name if the + ptrace call fails breaks debugging remote targets. The correct +@@ -645,10 +644,9 @@ i386_linux_dr_set (int regnum, unsigned + { + int tid; + +- /* FIXME: kettenis/2001-01-29: It's not clear what we should do with +- multi-threaded processes here. For now, pretend there is just +- one thread. */ +- tid = PIDGET (inferior_ptid); ++ tid = TIDGET (inferior_ptid); ++ if (tid == 0) ++ tid = PIDGET (inferior_ptid); + + errno = 0; + ptrace (PTRACE_POKEUSER, tid, +--- gdb-6.3/gdb/ia64-linux-nat.c.fix Fri Jan 7 16:59:11 2005 ++++ gdb-6.3/gdb/ia64-linux-nat.c Fri Jan 7 17:04:07 2005 @@ -39,6 +39,8 @@ #include @@ -1835,8 +2076,38 @@ + observer_attach_sigtrap (ia64_linux_save_sigtrap_info); +} + ---- gdb-6.3/gdb/s390-nat.c.fix Wed Dec 15 14:48:43 2004 -+++ gdb-6.3/gdb/s390-nat.c Wed Dec 15 14:46:18 2004 +--- gdb-6.3/gdb/amd64-linux-nat.c.fix Fri Jan 7 16:59:21 2005 ++++ gdb-6.3/gdb/amd64-linux-nat.c Fri Jan 7 17:04:07 2005 +@@ -233,10 +233,9 @@ amd64_linux_dr_get (int regnum) + int tid; + unsigned long value; + +- /* FIXME: kettenis/2001-01-29: It's not clear what we should do with +- multi-threaded processes here. For now, pretend there is just +- one thread. */ +- tid = PIDGET (inferior_ptid); ++ tid = TIDGET (inferior_ptid); ++ if (tid == 0) ++ tid = PIDGET (inferior_ptid); + + /* FIXME: kettenis/2001-03-27: Calling perror_with_name if the + ptrace call fails breaks debugging remote targets. The correct +@@ -261,10 +260,9 @@ amd64_linux_dr_set (int regnum, unsigned + { + int tid; + +- /* FIXME: kettenis/2001-01-29: It's not clear what we should do with +- multi-threaded processes here. For now, pretend there is just +- one thread. */ +- tid = PIDGET (inferior_ptid); ++ tid = TIDGET (inferior_ptid); ++ if (tid == 0) ++ tid = PIDGET (inferior_ptid); + + errno = 0; + ptrace (PT_WRITE_U, tid, offsetof (struct user, u_debugreg[regnum]), value); +--- gdb-6.3/gdb/s390-nat.c.fix Fri Jan 7 16:59:28 2005 ++++ gdb-6.3/gdb/s390-nat.c Fri Jan 7 17:04:07 2005 @@ -27,6 +27,8 @@ #include "inferior.h" @@ -1978,193 +2249,15 @@ +{ + observer_attach_linux_new_thread (s390_linux_new_thread); +} ---- gdb-6.3/gdb/i386-linux-nat.c.fix Wed Dec 15 14:49:08 2004 -+++ gdb-6.3/gdb/i386-linux-nat.c Wed Dec 15 14:46:46 2004 -@@ -617,10 +617,9 @@ i386_linux_dr_get (int regnum) - int tid; - unsigned long value; - -- /* FIXME: kettenis/2001-01-29: It's not clear what we should do with -- multi-threaded processes here. For now, pretend there is just -- one thread. */ -- tid = PIDGET (inferior_ptid); -+ tid = TIDGET (inferior_ptid); -+ if (tid == 0) -+ tid = PIDGET (inferior_ptid); - - /* FIXME: kettenis/2001-03-27: Calling perror_with_name if the - ptrace call fails breaks debugging remote targets. The correct -@@ -645,10 +644,9 @@ i386_linux_dr_set (int regnum, unsigned - { - int tid; - -- /* FIXME: kettenis/2001-01-29: It's not clear what we should do with -- multi-threaded processes here. For now, pretend there is just -- one thread. */ -- tid = PIDGET (inferior_ptid); -+ tid = TIDGET (inferior_ptid); -+ if (tid == 0) -+ tid = PIDGET (inferior_ptid); - - errno = 0; - ptrace (PTRACE_POKEUSER, tid, ---- gdb-6.3/gdb/amd64-linux-nat.c.fix Wed Dec 15 14:48:59 2004 -+++ gdb-6.3/gdb/amd64-linux-nat.c Wed Dec 15 14:46:33 2004 -@@ -233,10 +233,9 @@ amd64_linux_dr_get (int regnum) - int tid; - unsigned long value; - -- /* FIXME: kettenis/2001-01-29: It's not clear what we should do with -- multi-threaded processes here. For now, pretend there is just -- one thread. */ -- tid = PIDGET (inferior_ptid); -+ tid = TIDGET (inferior_ptid); -+ if (tid == 0) -+ tid = PIDGET (inferior_ptid); - - /* FIXME: kettenis/2001-03-27: Calling perror_with_name if the - ptrace call fails breaks debugging remote targets. The correct -@@ -261,10 +260,9 @@ amd64_linux_dr_set (int regnum, unsigned - { - int tid; - -- /* FIXME: kettenis/2001-01-29: It's not clear what we should do with -- multi-threaded processes here. For now, pretend there is just -- one thread. */ -- tid = PIDGET (inferior_ptid); -+ tid = TIDGET (inferior_ptid); -+ if (tid == 0) -+ tid = PIDGET (inferior_ptid); - - errno = 0; - ptrace (PT_WRITE_U, tid, offsetof (struct user, u_debugreg[regnum]), value); ---- gdb-6.3/gdb/thread-db.c.fix Wed Dec 15 14:49:28 2004 -+++ gdb-6.3/gdb/thread-db.c Wed Dec 15 14:47:02 2004 -@@ -34,6 +34,7 @@ - #include "target.h" - #include "regcache.h" - #include "solib-svr4.h" -+#include "observer.h" - - #ifdef HAVE_GNU_LIBC_VERSION_H - #include -@@ -143,7 +144,6 @@ static void detach_thread (ptid_t ptid, - #define is_thread(ptid) (GET_THREAD (ptid) != 0) - - #define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0) --#define BUILD_THREAD(tid, pid) ptid_build (pid, 0, tid) - - - /* Use "struct private_thread_info" to cache thread state. This is -@@ -267,7 +267,7 @@ thread_get_info_callback (const td_thrha - thread_db_err_str (err)); - - /* Fill the cache. */ -- thread_ptid = BUILD_THREAD (ti.ti_tid, GET_PID (inferior_ptid)); -+ thread_ptid = ptid_build (GET_PID (inferior_ptid), ti.ti_lid, ti.ti_tid); - thread_info = find_thread_pid (thread_ptid); - - /* In the case of a zombie thread, don't continue. We don't want to -@@ -385,22 +385,14 @@ thread_from_lwp (ptid_t ptid) - - gdb_assert (thread_info && thread_info->private->ti_valid); - -- return BUILD_THREAD (thread_info->private->ti.ti_tid, GET_PID (ptid)); -+ return ptid_build (GET_PID (ptid), GET_LWP (ptid), -+ thread_info->private->ti.ti_tid); - } - - static ptid_t - lwp_from_thread (ptid_t ptid) - { -- struct thread_info *thread_info; -- ptid_t thread_ptid; -- -- if (!is_thread (ptid)) -- return ptid; -- -- thread_info = find_thread_pid (ptid); -- thread_db_get_info (thread_info); -- -- return BUILD_LWP (thread_info->private->ti.ti_lid, GET_PID (ptid)); -+ return BUILD_LWP (GET_LWP (ptid), GET_PID (ptid)); - } - - -@@ -722,6 +714,7 @@ attach_thread (ptid_t ptid, const td_thr - { - struct thread_info *tp; - td_err_e err; -+ ptid_t new_ptid; - - /* If we're being called after a TD_CREATE event, we may already - know about this thread. There are two ways this can happen. We -@@ -757,11 +750,18 @@ attach_thread (ptid_t ptid, const td_thr - if (ti_p->ti_state == TD_THR_UNKNOWN || ti_p->ti_state == TD_THR_ZOMBIE) - return; /* A zombie thread -- do not attach. */ - -+ new_ptid = BUILD_LWP (ti_p->ti_lid, GET_PID (ptid)); -+ - /* Under GNU/Linux, we have to attach to each and every thread. */ - #ifdef ATTACH_LWP -- ATTACH_LWP (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid)), 0); -+ ATTACH_LWP (new_ptid, 0); - #endif - -+ /* Notify any observers of a new linux thread. This -+ would include any linux platforms that have to insert hardware -+ watchpoints on every thread. */ -+ observer_notify_linux_new_thread (new_ptid); -+ - /* Enable thread event reporting for this thread. */ - err = td_thr_event_enable_p (th_p, 1); - if (err != TD_OK) -@@ -903,7 +903,7 @@ check_event (ptid_t ptid) - if (err != TD_OK) - error ("Cannot get thread info: %s", thread_db_err_str (err)); - -- ptid = BUILD_THREAD (ti.ti_tid, GET_PID (ptid)); -+ ptid = ptid_build (GET_PID (ptid), ti.ti_lid, ti.ti_tid); - - switch (msg.event) - { -@@ -950,7 +950,8 @@ thread_db_wait (ptid_t ptid, struct targ - return pid_to_ptid (-1); - - if (ourstatus->kind == TARGET_WAITKIND_STOPPED -- && ourstatus->value.sig == TARGET_SIGNAL_TRAP) -+ && (ourstatus->value.sig == TARGET_SIGNAL_TRAP -+ || ourstatus->value.sig == TARGET_SIGNAL_ILL)) - /* Check for a thread event. */ - check_event (ptid); - -@@ -1175,7 +1176,7 @@ find_new_threads_callback (const td_thrh - if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE) - return 0; /* A zombie -- ignore. */ - -- ptid = BUILD_THREAD (ti.ti_tid, GET_PID (inferior_ptid)); -+ ptid = ptid_build (GET_PID (inferior_ptid), ti.ti_lid, ti.ti_tid); - - if (!in_thread_list (ptid)) - attach_thread (ptid, th_p, &ti, 1); ---- gdb-6.3/gdb/Makefile.in.fix Wed Dec 15 14:48:48 2004 -+++ gdb-6.3/gdb/Makefile.in Wed Dec 15 14:46:22 2004 -@@ -2055,7 +2055,8 @@ ia64-aix-nat.o: ia64-aix-nat.c $(defs_h) - $(objfiles_h) $(gdb_stat_h) - ia64-aix-tdep.o: ia64-aix-tdep.c $(defs_h) - ia64-linux-nat.o: ia64-linux-nat.c $(defs_h) $(gdb_string_h) $(inferior_h) \ -- $(target_h) $(gdbcore_h) $(regcache_h) $(gdb_wait_h) $(gregset_h) -+ $(target_h) $(gdbcore_h) $(regcache_h) $(gdb_wait_h) $(gregset_h) \ -+ $(observer_h) $(linux_nat_h) - ia64-linux-tdep.o: ia64-linux-tdep.c $(defs_h) $(ia64_tdep_h) \ - $(arch_utils_h) $(gdbcore_h) $(regcache_h) - ia64-tdep.o: ia64-tdep.c $(defs_h) $(inferior_h) $(gdbcore_h) \ -@@ -2437,7 +2438,7 @@ rs6000-tdep.o: rs6000-tdep.c $(defs_h) $ - $(ppc_tdep_h) $(gdb_assert_h) $(dis_asm_h) $(trad_frame_h) \ - $(frame_unwind_h) $(frame_base_h) - s390-nat.o: s390-nat.c $(defs_h) $(tm_h) $(regcache_h) $(inferior_h) \ -- $(s390_tdep_h) -+ $(s390_tdep_h) $(observer_h) $(linux_nat_h) - s390-tdep.o: s390-tdep.c $(defs_h) $(arch_utils_h) $(frame_h) $(inferior_h) \ - $(symtab_h) $(target_h) $(gdbcore_h) $(gdbcmd_h) $(objfiles_h) \ - $(tm_h) $(__bfd_bfd_h) $(floatformat_h) $(regcache_h) \ +--- gdb-6.3/gdb/gdbarch.sh.fix Fri Jan 7 17:30:46 2005 ++++ gdb-6.3/gdb/gdbarch.sh Fri Jan 7 17:32:28 2005 +@@ -611,6 +611,9 @@ f:=:CORE_ADDR:smash_text_address:CORE_AD + # FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the target can + # single step. If not, then implement single step using breakpoints. + F:=:void:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p ++# Return non-zero if the processor is executing a delay slot and a ++# further single-step is needed before the instruction finishes. ++M::int:single_step_through_delay:struct frame_info *frame:frame + # FIXME: cagney/2003-08-28: Need to find a better way of selecting the + # disassembler. Perhaps objdump can handle it? + f:TARGET_PRINT_INSN:int:print_insn:bfd_vma vma, struct disassemble_info *info:vma, info::0: