1 /* Low-level child interface to ttrace.
3 Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
24 /* The ttrace(2) system call didn't exist before HP-UX 10.30. Don't
25 try to compile this code unless we have it. */
30 #include "gdbthread.h"
34 #include "gdb_assert.h"
35 #include "gdb_string.h"
37 #include <sys/ttrace.h>
39 #include "inf-child.h"
40 #include "inf-ttrace.h"
42 /* HACK: Save the ttrace ops returned by inf_ttrace_target. */
43 static struct target_ops *ttrace_ops_hack;
46 /* HP-UX uses a threading model where each user-space thread
47 corresponds to a kernel thread. These kernel threads are called
48 lwps. The ttrace(2) interface gives us almost full control over
49 the threads, which makes it very easy to support them in GDB. We
50 identify the threads by process ID and lwp ID. The ttrace(2) also
51 provides us with a thread's user ID (in the `tts_user_tid' member
52 of `ttstate_t') but we don't use that (yet) as it isn't necessary
53 to uniquely label the thread. */
55 /* Number of active lwps. */
56 static int inf_ttrace_num_lwps;
59 /* On HP-UX versions that have the ttrace(2) system call, we can
60 implement "hardware" watchpoints by fiddling with the protection of
61 pages in the address space that contain the variable being watched.
62 In order to implement this, we keep a dictionary of pages for which
63 we have changed the protection. */
65 struct inf_ttrace_page
67 CORE_ADDR addr; /* Page address. */
68 int prot; /* Protection. */
69 int refcount; /* Reference count. */
70 struct inf_ttrace_page *next;
71 struct inf_ttrace_page *prev;
74 struct inf_ttrace_page_dict
76 struct inf_ttrace_page buckets[128];
77 int pagesize; /* Page size. */
78 int count; /* Number of pages in this dictionary. */
79 } inf_ttrace_page_dict;
81 /* Number of lwps that are currently in a system call. */
82 static int inf_ttrace_num_lwps_in_syscall;
84 /* Flag to indicate whether we should re-enable page protections after
86 static int inf_ttrace_reenable_page_protections;
88 /* Enable system call events for process PID. */
91 inf_ttrace_enable_syscall_events (pid_t pid)
96 gdb_assert (inf_ttrace_num_lwps_in_syscall == 0);
98 if (ttrace (TT_PROC_GET_EVENT_MASK, pid, 0,
99 (uintptr_t)&tte, sizeof tte, 0) == -1)
100 perror_with_name (("ttrace"));
102 tte.tte_events |= (TTEVT_SYSCALL_ENTRY | TTEVT_SYSCALL_RETURN);
104 if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0,
105 (uintptr_t)&tte, sizeof tte, 0) == -1)
106 perror_with_name (("ttrace"));
108 if (ttrace (TT_PROC_GET_FIRST_LWP_STATE, pid, 0,
109 (uintptr_t)&tts, sizeof tts, 0) == -1)
110 perror_with_name (("ttrace"));
112 if (tts.tts_flags & TTS_INSYSCALL)
113 inf_ttrace_num_lwps_in_syscall++;
115 /* FIXME: Handle multiple threads. */
118 /* Disable system call events for process PID. */
121 inf_ttrace_disable_syscall_events (pid_t pid)
125 gdb_assert (inf_ttrace_page_dict.count == 0);
127 if (ttrace (TT_PROC_GET_EVENT_MASK, pid, 0,
128 (uintptr_t)&tte, sizeof tte, 0) == -1)
129 perror_with_name (("ttrace"));
131 tte.tte_events &= ~(TTEVT_SYSCALL_ENTRY | TTEVT_SYSCALL_RETURN);
133 if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0,
134 (uintptr_t)&tte, sizeof tte, 0) == -1)
135 perror_with_name (("ttrace"));
137 inf_ttrace_num_lwps_in_syscall = 0;
140 /* Get information about the page at address ADDR for process PID from
143 static struct inf_ttrace_page *
144 inf_ttrace_get_page (pid_t pid, CORE_ADDR addr)
146 const int num_buckets = ARRAY_SIZE (inf_ttrace_page_dict.buckets);
147 const int pagesize = inf_ttrace_page_dict.pagesize;
149 struct inf_ttrace_page *page;
151 bucket = (addr / pagesize) % num_buckets;
152 page = &inf_ttrace_page_dict.buckets[bucket];
155 if (page->addr == addr)
164 /* Add the page at address ADDR for process PID to the dictionary. */
166 static struct inf_ttrace_page *
167 inf_ttrace_add_page (pid_t pid, CORE_ADDR addr)
169 const int num_buckets = ARRAY_SIZE (inf_ttrace_page_dict.buckets);
170 const int pagesize = inf_ttrace_page_dict.pagesize;
172 struct inf_ttrace_page *page;
173 struct inf_ttrace_page *prev = NULL;
175 bucket = (addr / pagesize) % num_buckets;
176 page = &inf_ttrace_page_dict.buckets[bucket];
179 if (page->addr == addr)
190 if (ttrace (TT_PROC_GET_MPROTECT, pid, 0,
191 addr, 0, (uintptr_t)&prot) == -1)
192 perror_with_name (("ttrace"));
194 page = XMALLOC (struct inf_ttrace_page);
203 inf_ttrace_page_dict.count++;
204 if (inf_ttrace_page_dict.count == 1)
205 inf_ttrace_enable_syscall_events (pid);
207 if (inf_ttrace_num_lwps_in_syscall == 0)
209 if (ttrace (TT_PROC_SET_MPROTECT, pid, 0,
210 addr, pagesize, prot & ~PROT_WRITE) == -1)
211 perror_with_name (("ttrace"));
218 /* Insert the page at address ADDR of process PID to the dictionary. */
221 inf_ttrace_insert_page (pid_t pid, CORE_ADDR addr)
223 struct inf_ttrace_page *page;
225 page = inf_ttrace_get_page (pid, addr);
227 page = inf_ttrace_add_page (pid, addr);
232 /* Remove the page at address ADDR of process PID from the dictionary. */
235 inf_ttrace_remove_page (pid_t pid, CORE_ADDR addr)
237 const int pagesize = inf_ttrace_page_dict.pagesize;
238 struct inf_ttrace_page *page;
240 page = inf_ttrace_get_page (pid, addr);
243 gdb_assert (page->refcount >= 0);
245 if (page->refcount == 0)
247 if (inf_ttrace_num_lwps_in_syscall == 0)
249 if (ttrace (TT_PROC_SET_MPROTECT, pid, 0,
250 addr, pagesize, page->prot) == -1)
251 perror_with_name (("ttrace"));
254 inf_ttrace_page_dict.count--;
255 if (inf_ttrace_page_dict.count == 0)
256 inf_ttrace_disable_syscall_events (pid);
258 page->prev->next = page->next;
260 page->next->prev = page->prev;
266 /* Mask the bits in PROT from the page protections that are currently
267 in the dictionary for process PID. */
270 inf_ttrace_mask_page_protections (pid_t pid, int prot)
272 const int num_buckets = ARRAY_SIZE (inf_ttrace_page_dict.buckets);
273 const int pagesize = inf_ttrace_page_dict.pagesize;
276 for (bucket = 0; bucket < num_buckets; bucket++)
278 struct inf_ttrace_page *page;
280 page = inf_ttrace_page_dict.buckets[bucket].next;
283 if (ttrace (TT_PROC_SET_MPROTECT, pid, 0,
284 page->addr, pagesize, page->prot & ~prot) == -1)
285 perror_with_name (("ttrace"));
292 /* Write-protect the pages in the dictionary for process PID. */
295 inf_ttrace_enable_page_protections (pid_t pid)
297 inf_ttrace_mask_page_protections (pid, PROT_WRITE);
300 /* Restore the protection of the pages in the dictionary for process
304 inf_ttrace_disable_page_protections (pid_t pid)
306 inf_ttrace_mask_page_protections (pid, 0);
309 /* Insert a "hardware" watchpoint for LEN bytes at address ADDR of
313 inf_ttrace_insert_watchpoint (CORE_ADDR addr, int len, int type)
315 const int pagesize = inf_ttrace_page_dict.pagesize;
316 pid_t pid = ptid_get_pid (inferior_ptid);
321 gdb_assert (type == hw_write);
323 page_addr = (addr / pagesize) * pagesize;
324 num_pages = (len + pagesize - 1) / pagesize;
326 for (page = 0; page < num_pages; page++, page_addr += pagesize)
327 inf_ttrace_insert_page (pid, page_addr);
332 /* Remove a "hardware" watchpoint for LEN bytes at address ADDR of
336 inf_ttrace_remove_watchpoint (CORE_ADDR addr, int len, int type)
338 const int pagesize = inf_ttrace_page_dict.pagesize;
339 pid_t pid = ptid_get_pid (inferior_ptid);
344 gdb_assert (type == hw_write);
346 page_addr = (addr / pagesize) * pagesize;
347 num_pages = (len + pagesize - 1) / pagesize;
349 for (page = 0; page < num_pages; page++, page_addr += pagesize)
350 inf_ttrace_remove_page (pid, page_addr);
356 inf_ttrace_can_use_hw_breakpoint (int type, int len, int ot)
358 return (type == bp_hardware_watchpoint);
362 inf_ttrace_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
367 /* Return non-zero if the current inferior was (potentially) stopped
368 by hitting a "hardware" watchpoint. */
371 inf_ttrace_stopped_by_watchpoint (void)
373 pid_t pid = ptid_get_pid (inferior_ptid);
374 lwpid_t lwpid = ptid_get_lwp (inferior_ptid);
377 if (inf_ttrace_page_dict.count > 0)
379 if (ttrace (TT_LWP_GET_STATE, pid, lwpid,
380 (uintptr_t)&tts, sizeof tts, 0) == -1)
381 perror_with_name (("ttrace"));
383 if (tts.tts_event == TTEVT_SIGNAL
384 && tts.tts_u.tts_signal.tts_signo == SIGBUS)
386 const int pagesize = inf_ttrace_page_dict.pagesize;
387 void *addr = tts.tts_u.tts_signal.tts_siginfo.si_addr;
388 CORE_ADDR page_addr = ((uintptr_t)addr / pagesize) * pagesize;
390 if (inf_ttrace_get_page (pid, page_addr))
399 /* When tracking a vfork(2), we cannot detach from the parent until
400 after the child has called exec(3) or has exited. If we are still
401 attached to the parent, this variable will be set to the process ID
402 of the parent. Otherwise it will be set to zero. */
403 static pid_t inf_ttrace_vfork_ppid = -1;
406 inf_ttrace_follow_fork (struct target_ops *ops, int follow_child)
409 lwpid_t lwpid, flwpid;
412 /* FIXME: kettenis/20050720: This stuff should really be passed as
413 an argument by our caller. */
416 struct target_waitstatus status;
418 get_last_target_status (&ptid, &status);
419 gdb_assert (status.kind == TARGET_WAITKIND_FORKED
420 || status.kind == TARGET_WAITKIND_VFORKED);
422 pid = ptid_get_pid (ptid);
423 lwpid = ptid_get_lwp (ptid);
426 /* Get all important details that core GDB doesn't (and shouldn't)
428 if (ttrace (TT_LWP_GET_STATE, pid, lwpid,
429 (uintptr_t)&tts, sizeof tts, 0) == -1)
430 perror_with_name (("ttrace"));
432 gdb_assert (tts.tts_event == TTEVT_FORK || tts.tts_event == TTEVT_VFORK);
434 if (tts.tts_u.tts_fork.tts_isparent)
437 lwpid = tts.tts_lwpid;
438 fpid = tts.tts_u.tts_fork.tts_fpid;
439 flwpid = tts.tts_u.tts_fork.tts_flwpid;
443 pid = tts.tts_u.tts_fork.tts_fpid;
444 lwpid = tts.tts_u.tts_fork.tts_flwpid;
446 flwpid = tts.tts_lwpid;
451 inferior_ptid = ptid_build (fpid, flwpid, 0);
452 detach_breakpoints (pid);
454 target_terminal_ours ();
455 fprintf_unfiltered (gdb_stdlog, _("\
456 Attaching after fork to child process %ld.\n"), (long)fpid);
460 inferior_ptid = ptid_build (pid, lwpid, 0);
461 detach_breakpoints (fpid);
463 target_terminal_ours ();
464 fprintf_unfiltered (gdb_stdlog, _("\
465 Detaching after fork from child process %ld.\n"), (long)fpid);
468 if (tts.tts_event == TTEVT_VFORK)
470 gdb_assert (!tts.tts_u.tts_fork.tts_isparent);
474 /* We can't detach from the parent yet. */
475 inf_ttrace_vfork_ppid = pid;
477 reattach_breakpoints (fpid);
481 if (ttrace (TT_PROC_DETACH, fpid, 0, 0, 0, 0) == -1)
482 perror_with_name (("ttrace"));
484 /* Wait till we get the TTEVT_VFORK event in the parent.
485 This indicates that the child has called exec(3) or has
486 exited and that the parent is ready to be traced again. */
487 if (ttrace_wait (pid, lwpid, TTRACE_WAITOK, &tts, sizeof tts) == -1)
488 perror_with_name (("ttrace_wait"));
489 gdb_assert (tts.tts_event == TTEVT_VFORK);
490 gdb_assert (tts.tts_u.tts_fork.tts_isparent);
492 reattach_breakpoints (pid);
497 gdb_assert (tts.tts_u.tts_fork.tts_isparent);
501 if (ttrace (TT_PROC_DETACH, pid, 0, 0, 0, 0) == -1)
502 perror_with_name (("ttrace"));
506 if (ttrace (TT_PROC_DETACH, fpid, 0, 0, 0, 0) == -1)
507 perror_with_name (("ttrace"));
513 /* The child will start out single-threaded. */
514 inf_ttrace_num_lwps = 0;
515 inf_ttrace_num_lwps_in_syscall = 0;
517 /* Reset breakpoints in the child as appropriate. */
518 follow_inferior_reset_breakpoints ();
525 /* File descriptors for pipes used as semaphores during initial
526 startup of an inferior. */
527 static int inf_ttrace_pfd1[2];
528 static int inf_ttrace_pfd2[2];
531 do_cleanup_pfds (void *dummy)
533 close (inf_ttrace_pfd1[0]);
534 close (inf_ttrace_pfd1[1]);
535 close (inf_ttrace_pfd2[0]);
536 close (inf_ttrace_pfd2[1]);
540 inf_ttrace_prepare (void)
542 if (pipe (inf_ttrace_pfd1) == -1)
543 perror_with_name (("pipe"));
545 if (pipe (inf_ttrace_pfd2) == -1)
547 close (inf_ttrace_pfd1[0]);
548 close (inf_ttrace_pfd2[0]);
549 perror_with_name (("pipe"));
553 /* Prepare to be traced. */
558 struct cleanup *old_chain = make_cleanup (do_cleanup_pfds, 0);
561 /* "Trace me, Dr. Memory!" */
562 if (ttrace (TT_PROC_SETTRC, 0, 0, 0, TT_VERSION, 0) == -1)
563 perror_with_name (("ttrace"));
565 /* Tell our parent that we are ready to be traced. */
566 if (write (inf_ttrace_pfd1[1], &c, sizeof c) != sizeof c)
567 perror_with_name (("write"));
569 /* Wait until our parent has set the initial event mask. */
570 if (read (inf_ttrace_pfd2[0], &c, sizeof c) != sizeof c)
571 perror_with_name (("read"));
573 do_cleanups (old_chain);
576 /* Start tracing PID. */
579 inf_ttrace_him (int pid)
581 struct cleanup *old_chain = make_cleanup (do_cleanup_pfds, 0);
585 /* Wait until our child is ready to be traced. */
586 if (read (inf_ttrace_pfd1[0], &c, sizeof c) != sizeof c)
587 perror_with_name (("read"));
589 /* Set the initial event mask. */
590 memset (&tte, 0, sizeof (tte));
591 tte.tte_events |= TTEVT_EXEC | TTEVT_EXIT | TTEVT_FORK | TTEVT_VFORK;
592 tte.tte_events |= TTEVT_LWP_CREATE | TTEVT_LWP_EXIT | TTEVT_LWP_TERMINATE;
593 #ifdef TTEVT_BPT_SSTEP
594 tte.tte_events |= TTEVT_BPT_SSTEP;
596 tte.tte_opts |= TTEO_PROC_INHERIT;
597 if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0,
598 (uintptr_t)&tte, sizeof tte, 0) == -1)
599 perror_with_name (("ttrace"));
601 /* Tell our child that we have set the initial event mask. */
602 if (write (inf_ttrace_pfd2[1], &c, sizeof c) != sizeof c)
603 perror_with_name (("write"));
605 do_cleanups (old_chain);
607 push_target (ttrace_ops_hack);
609 /* On some targets, there must be some explicit synchronization
610 between the parent and child processes after the debugger forks,
611 and before the child execs the debuggee program. This call
612 basically gives permission for the child to exec. */
614 target_acknowledge_created_inferior (pid);
616 /* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h, and will
617 be 1 or 2 depending on whether we're starting without or with a
619 startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
621 /* On some targets, there must be some explicit actions taken after
622 the inferior has been started up. */
623 target_post_startup_inferior (pid_to_ptid (pid));
627 inf_ttrace_create_inferior (char *exec_file, char *allargs, char **env,
630 gdb_assert (inf_ttrace_num_lwps == 0);
631 gdb_assert (inf_ttrace_num_lwps_in_syscall == 0);
632 gdb_assert (inf_ttrace_page_dict.count == 0);
633 gdb_assert (inf_ttrace_reenable_page_protections == 0);
634 gdb_assert (inf_ttrace_vfork_ppid == -1);
636 fork_inferior (exec_file, allargs, env, inf_ttrace_me, inf_ttrace_him,
637 inf_ttrace_prepare, NULL);
641 inf_ttrace_mourn_inferior (void)
643 const int num_buckets = ARRAY_SIZE (inf_ttrace_page_dict.buckets);
646 inf_ttrace_num_lwps = 0;
647 inf_ttrace_num_lwps_in_syscall = 0;
649 for (bucket = 0; bucket < num_buckets; bucket++)
651 struct inf_ttrace_page *page;
652 struct inf_ttrace_page *next;
654 page = inf_ttrace_page_dict.buckets[bucket].next;
662 inf_ttrace_page_dict.count = 0;
664 unpush_target (ttrace_ops_hack);
665 generic_mourn_inferior ();
669 inf_ttrace_attach (char *args, int from_tty)
677 error_no_arg (_("process-id to attach"));
680 pid = strtol (args, &dummy, 0);
681 if (pid == 0 && args == dummy)
682 error (_("Illegal process-id: %s."), args);
684 if (pid == getpid ()) /* Trying to masturbate? */
685 error (_("I refuse to debug myself!"));
689 exec_file = get_exec_file (0);
692 printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file,
693 target_pid_to_str (pid_to_ptid (pid)));
695 printf_unfiltered (_("Attaching to %s\n"),
696 target_pid_to_str (pid_to_ptid (pid)));
698 gdb_flush (gdb_stdout);
701 gdb_assert (inf_ttrace_num_lwps == 0);
702 gdb_assert (inf_ttrace_num_lwps_in_syscall == 0);
703 gdb_assert (inf_ttrace_vfork_ppid == -1);
705 if (ttrace (TT_PROC_ATTACH, pid, 0, TT_KILL_ON_EXIT, TT_VERSION, 0) == -1)
706 perror_with_name (("ttrace"));
709 /* Set the initial event mask. */
710 memset (&tte, 0, sizeof (tte));
711 tte.tte_events |= TTEVT_EXEC | TTEVT_EXIT | TTEVT_FORK | TTEVT_VFORK;
712 tte.tte_events |= TTEVT_LWP_CREATE | TTEVT_LWP_EXIT | TTEVT_LWP_TERMINATE;
713 #ifdef TTEVT_BPT_SSTEP
714 tte.tte_events |= TTEVT_BPT_SSTEP;
716 tte.tte_opts |= TTEO_PROC_INHERIT;
717 if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0,
718 (uintptr_t)&tte, sizeof tte, 0) == -1)
719 perror_with_name (("ttrace"));
721 inferior_ptid = pid_to_ptid (pid);
722 push_target (ttrace_ops_hack);
726 inf_ttrace_detach (char *args, int from_tty)
728 pid_t pid = ptid_get_pid (inferior_ptid);
733 char *exec_file = get_exec_file (0);
736 printf_unfiltered (_("Detaching from program: %s, %s\n"), exec_file,
737 target_pid_to_str (pid_to_ptid (pid)));
738 gdb_flush (gdb_stdout);
743 /* ??? The HP-UX 11.0 ttrace(2) manual page doesn't mention that we
744 can pass a signal number here. Does this really work? */
745 if (ttrace (TT_PROC_DETACH, pid, 0, 0, sig, 0) == -1)
746 perror_with_name (("ttrace"));
748 if (inf_ttrace_vfork_ppid != -1)
750 if (ttrace (TT_PROC_DETACH, inf_ttrace_vfork_ppid, 0, 0, 0, 0) == -1)
751 perror_with_name (("ttrace"));
752 inf_ttrace_vfork_ppid = -1;
755 inf_ttrace_num_lwps = 0;
756 inf_ttrace_num_lwps_in_syscall = 0;
758 unpush_target (ttrace_ops_hack);
759 inferior_ptid = null_ptid;
763 inf_ttrace_kill (void)
765 pid_t pid = ptid_get_pid (inferior_ptid);
770 if (ttrace (TT_PROC_EXIT, pid, 0, 0, 0, 0) == -1)
771 perror_with_name (("ttrace"));
772 /* ??? Is it necessary to call ttrace_wait() here? */
774 if (inf_ttrace_vfork_ppid != -1)
776 if (ttrace (TT_PROC_DETACH, inf_ttrace_vfork_ppid, 0, 0, 0, 0) == -1)
777 perror_with_name (("ttrace"));
778 inf_ttrace_vfork_ppid = -1;
781 target_mourn_inferior ();
785 inf_ttrace_resume_callback (struct thread_info *info, void *arg)
787 if (!ptid_equal (info->ptid, inferior_ptid))
789 pid_t pid = ptid_get_pid (info->ptid);
790 lwpid_t lwpid = ptid_get_lwp (info->ptid);
792 if (ttrace (TT_LWP_CONTINUE, pid, lwpid, TT_NOPC, 0, 0) == -1)
793 perror_with_name (("ttrace"));
800 inf_ttrace_resume (ptid_t ptid, int step, enum target_signal signal)
802 pid_t pid = ptid_get_pid (ptid);
803 lwpid_t lwpid = ptid_get_lwp (ptid);
804 ttreq_t request = step ? TT_LWP_SINGLE : TT_LWP_CONTINUE;
805 int sig = target_signal_to_host (signal);
809 pid = ptid_get_pid (inferior_ptid);
810 lwpid = ptid_get_lwp (inferior_ptid);
813 if (ttrace (request, pid, lwpid, TT_NOPC, sig, 0) == -1)
814 perror_with_name (("ttrace"));
816 if (ptid_equal (ptid, minus_one_ptid) && inf_ttrace_num_lwps > 0)
818 /* Let all the other threads run too. */
819 iterate_over_threads (inf_ttrace_resume_callback, NULL);
824 inf_ttrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
826 pid_t pid = ptid_get_pid (ptid);
827 lwpid_t lwpid = ptid_get_lwp (ptid);
830 /* Until proven otherwise. */
831 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
836 gdb_assert (pid != 0 || lwpid == 0);
843 if (ttrace_wait (pid, lwpid, TTRACE_WAITOK, &tts, sizeof tts) == -1)
844 perror_with_name (("ttrace_wait"));
846 if (tts.tts_event == TTEVT_VFORK && tts.tts_u.tts_fork.tts_isparent)
848 if (inf_ttrace_vfork_ppid != -1)
850 gdb_assert (inf_ttrace_vfork_ppid == tts.tts_pid);
852 if (ttrace (TT_PROC_DETACH, tts.tts_pid, 0, 0, 0, 0) == -1)
853 perror_with_name (("ttrace"));
854 inf_ttrace_vfork_ppid = -1;
857 tts.tts_event = TTEVT_NONE;
861 clear_sigint_trap ();
863 while (tts.tts_event == TTEVT_NONE);
865 /* Now that we've waited, we can re-enable the page protections. */
866 if (inf_ttrace_reenable_page_protections)
868 gdb_assert (inf_ttrace_num_lwps_in_syscall == 0);
869 inf_ttrace_enable_page_protections (tts.tts_pid);
870 inf_ttrace_reenable_page_protections = 0;
873 ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0);
875 switch (tts.tts_event)
877 #ifdef TTEVT_BPT_SSTEP
878 case TTEVT_BPT_SSTEP:
879 /* Make it look like a breakpoint. */
880 ourstatus->kind = TARGET_WAITKIND_STOPPED;
881 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
886 /* FIXME: kettenis/20051029: GDB doesn't really know how to deal
887 with TARGET_WAITKIND_EXECD events yet. So we make it look
888 like a SIGTRAP instead. */
890 ourstatus->kind = TARGET_WAITKIND_EXECD;
891 ourstatus->value.execd_pathname =
892 xmalloc (tts.tts_u.tts_exec.tts_pathlen + 1);
893 if (ttrace (TT_PROC_GET_PATHNAME, tts.tts_pid, 0,
894 (uintptr_t)ourstatus->value.execd_pathname,
895 tts.tts_u.tts_exec.tts_pathlen, 0) == -1)
896 perror_with_name (("ttrace"));
897 ourstatus->value.execd_pathname[tts.tts_u.tts_exec.tts_pathlen] = 0;
899 ourstatus->kind = TARGET_WAITKIND_STOPPED;
900 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
905 store_waitstatus (ourstatus, tts.tts_u.tts_exit.tts_exitcode);
906 inf_ttrace_num_lwps = 0;
910 ourstatus->kind = TARGET_WAITKIND_FORKED;
911 ourstatus->value.related_pid = tts.tts_u.tts_fork.tts_fpid;
913 /* Make sure the other end of the fork is stopped too. */
914 if (ttrace_wait (tts.tts_u.tts_fork.tts_fpid,
915 tts.tts_u.tts_fork.tts_flwpid,
916 TTRACE_WAITOK, &tts, sizeof tts) == -1)
917 perror_with_name (("ttrace_wait"));
919 gdb_assert (tts.tts_event == TTEVT_FORK);
920 if (tts.tts_u.tts_fork.tts_isparent)
922 ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0);
923 ourstatus->value.related_pid = tts.tts_u.tts_fork.tts_fpid;
928 gdb_assert (!tts.tts_u.tts_fork.tts_isparent);
930 ourstatus->kind = TARGET_WAITKIND_VFORKED;
931 ourstatus->value.related_pid = tts.tts_u.tts_fork.tts_fpid;
933 /* HACK: To avoid touching the parent during the vfork, switch
935 inferior_ptid = ptid;
938 case TTEVT_LWP_CREATE:
939 lwpid = tts.tts_u.tts_thread.tts_target_lwpid;
940 ptid = ptid_build (tts.tts_pid, lwpid, 0);
941 if (inf_ttrace_num_lwps == 0)
943 /* Now that we're going to be multi-threaded, add the
944 original thread to the list first. */
945 add_thread (ptid_build (tts.tts_pid, tts.tts_lwpid, 0));
946 inf_ttrace_num_lwps++;
948 printf_filtered (_("[New %s]\n"), target_pid_to_str (ptid));
950 inf_ttrace_num_lwps++;
951 ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0);
955 printf_filtered(_("[%s exited]\n"), target_pid_to_str (ptid));
956 delete_thread (ptid);
957 inf_ttrace_num_lwps--;
958 /* If we don't return -1 here, core GDB will re-add the thread. */
959 ptid = minus_one_ptid;
962 case TTEVT_LWP_TERMINATE:
963 lwpid = tts.tts_u.tts_thread.tts_target_lwpid;
964 ptid = ptid_build (tts.tts_pid, lwpid, 0);
965 printf_filtered(_("[%s has been terminated]\n"), target_pid_to_str (ptid));
966 delete_thread (ptid);
967 inf_ttrace_num_lwps--;
968 ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0);
972 ourstatus->kind = TARGET_WAITKIND_STOPPED;
973 ourstatus->value.sig =
974 target_signal_from_host (tts.tts_u.tts_signal.tts_signo);
977 case TTEVT_SYSCALL_ENTRY:
978 gdb_assert (inf_ttrace_reenable_page_protections == 0);
979 inf_ttrace_num_lwps_in_syscall++;
980 if (inf_ttrace_num_lwps_in_syscall == 1)
982 /* A thread has just entered a system call. Disable any
983 page protections as the kernel can't deal with them. */
984 inf_ttrace_disable_page_protections (tts.tts_pid);
986 ourstatus->kind = TARGET_WAITKIND_SYSCALL_ENTRY;
987 ourstatus->value.syscall_id = tts.tts_scno;
990 case TTEVT_SYSCALL_RETURN:
991 if (inf_ttrace_num_lwps_in_syscall > 0)
993 /* If the last thread has just left the system call, this
994 would be a logical place to re-enable the page
995 protections, but that doesn't work. We can't re-enable
996 them until we've done another wait. */
997 inf_ttrace_reenable_page_protections =
998 (inf_ttrace_num_lwps_in_syscall == 1);
999 inf_ttrace_num_lwps_in_syscall--;
1001 ourstatus->kind = TARGET_WAITKIND_SYSCALL_RETURN;
1002 ourstatus->value.syscall_id = tts.tts_scno;
1006 gdb_assert (!"Unexpected ttrace event");
1010 /* Make sure all threads within the process are stopped. */
1011 if (ttrace (TT_PROC_STOP, tts.tts_pid, 0, 0, 0, 0) == -1)
1012 perror_with_name (("ttrace"));
1014 /* HACK: Twiddle INFERIOR_PTID such that the initial thread of a
1015 process isn't recognized as a new thread. */
1016 if (ptid_get_lwp (inferior_ptid) == 0)
1017 inferior_ptid = ptid;
1022 /* Transfer LEN bytes from ADDR in the inferior's memory into READBUF,
1023 and transfer LEN bytes from WRITEBUF into the inferior's memory at
1024 ADDR. Either READBUF or WRITEBUF may be null, in which case the
1025 corresponding transfer doesn't happen. Return the number of bytes
1026 actually transferred (which may be zero if an error occurs). */
1029 inf_ttrace_xfer_memory (CORE_ADDR addr, ULONGEST len,
1030 void *readbuf, const void *writebuf)
1032 pid_t pid = ptid_get_pid (inferior_ptid);
1034 /* HP-UX treats text space and data space differently. GDB however,
1035 doesn't really know the difference. Therefore we try both. Try
1036 text space before data space though because when we're writing
1037 into text space the instruction cache might need to be flushed. */
1040 && ttrace (TT_PROC_RDTEXT, pid, 0, addr, len, (uintptr_t)readbuf) == -1
1041 && ttrace (TT_PROC_RDDATA, pid, 0, addr, len, (uintptr_t)readbuf) == -1)
1045 && ttrace (TT_PROC_WRTEXT, pid, 0, addr, len, (uintptr_t)writebuf) == -1
1046 && ttrace (TT_PROC_WRDATA, pid, 0, addr, len, (uintptr_t)writebuf) == -1)
1053 inf_ttrace_xfer_partial (struct target_ops *ops, enum target_object object,
1054 const char *annex, gdb_byte *readbuf,
1055 const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
1059 case TARGET_OBJECT_MEMORY:
1060 return inf_ttrace_xfer_memory (offset, len, readbuf, writebuf);
1062 case TARGET_OBJECT_UNWIND_TABLE:
1065 case TARGET_OBJECT_AUXV:
1068 case TARGET_OBJECT_WCOOKIE:
1076 /* Print status information about what we're accessing. */
1079 inf_ttrace_files_info (struct target_ops *ignore)
1081 printf_filtered (_("\tUsing the running image of %s %s.\n"),
1082 attach_flag ? "attached" : "child",
1083 target_pid_to_str (inferior_ptid));
1087 inf_ttrace_thread_alive (ptid_t ptid)
1093 inf_ttrace_pid_to_str (ptid_t ptid)
1095 if (inf_ttrace_num_lwps > 0)
1097 pid_t pid = ptid_get_pid (ptid);
1098 lwpid_t lwpid = ptid_get_lwp (ptid);
1099 static char buf[128];
1101 xsnprintf (buf, sizeof buf, "process %ld, lwp %ld",
1102 (long)pid, (long)lwpid);
1106 return normal_pid_to_str (ptid);
1111 inf_ttrace_target (void)
1113 struct target_ops *t = inf_child_target ();
1115 t->to_attach = inf_ttrace_attach;
1116 t->to_detach = inf_ttrace_detach;
1117 t->to_resume = inf_ttrace_resume;
1118 t->to_wait = inf_ttrace_wait;
1119 t->to_files_info = inf_ttrace_files_info;
1120 t->to_can_use_hw_breakpoint = inf_ttrace_can_use_hw_breakpoint;
1121 t->to_insert_watchpoint = inf_ttrace_insert_watchpoint;
1122 t->to_remove_watchpoint = inf_ttrace_remove_watchpoint;
1123 t->to_stopped_by_watchpoint = inf_ttrace_stopped_by_watchpoint;
1124 t->to_region_ok_for_hw_watchpoint =
1125 inf_ttrace_region_ok_for_hw_watchpoint;
1126 t->to_kill = inf_ttrace_kill;
1127 t->to_create_inferior = inf_ttrace_create_inferior;
1128 t->to_follow_fork = inf_ttrace_follow_fork;
1129 t->to_mourn_inferior = inf_ttrace_mourn_inferior;
1130 t->to_thread_alive = inf_ttrace_thread_alive;
1131 t->to_pid_to_str = inf_ttrace_pid_to_str;
1132 t->to_xfer_partial = inf_ttrace_xfer_partial;
1134 ttrace_ops_hack = t;
1140 /* Prevent warning from -Wmissing-prototypes. */
1141 void _initialize_hppa_hpux_nat (void);
1144 _initialize_inf_ttrace (void)
1147 inf_ttrace_page_dict.pagesize = getpagesize();