2013-03-12 Sebastian Huber <sebastian.huber@embedded-brains.de>
[binutils-gdb.git] / gdb / inf-ttrace.c
blob642e520faf41f2cd96fedcf4462fa768f2d6f45f
1 /* Low-level child interface to ttrace.
3 Copyright (C) 2004-2013 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 3 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, see <http://www.gnu.org/licenses/>. */
20 #include "defs.h"
22 /* The ttrace(2) system call didn't exist before HP-UX 10.30. Don't
23 try to compile this code unless we have it. */
24 #ifdef HAVE_TTRACE
26 #include "command.h"
27 #include "gdbcore.h"
28 #include "gdbthread.h"
29 #include "inferior.h"
30 #include "terminal.h"
31 #include "target.h"
33 #include "gdb_assert.h"
34 #include "gdb_string.h"
35 #include <sys/mman.h>
36 #include <sys/ttrace.h>
37 #include <signal.h>
39 #include "inf-child.h"
40 #include "inf-ttrace.h"
44 /* HP-UX uses a threading model where each user-space thread
45 corresponds to a kernel thread. These kernel threads are called
46 lwps. The ttrace(2) interface gives us almost full control over
47 the threads, which makes it very easy to support them in GDB. We
48 identify the threads by process ID and lwp ID. The ttrace(2) also
49 provides us with a thread's user ID (in the `tts_user_tid' member
50 of `ttstate_t') but we don't use that (yet) as it isn't necessary
51 to uniquely label the thread. */
53 /* Number of active lwps. */
54 static int inf_ttrace_num_lwps;
57 /* On HP-UX versions that have the ttrace(2) system call, we can
58 implement "hardware" watchpoints by fiddling with the protection of
59 pages in the address space that contain the variable being watched.
60 In order to implement this, we keep a dictionary of pages for which
61 we have changed the protection. */
63 struct inf_ttrace_page
65 CORE_ADDR addr; /* Page address. */
66 int prot; /* Protection. */
67 int refcount; /* Reference count. */
68 struct inf_ttrace_page *next;
69 struct inf_ttrace_page *prev;
72 struct inf_ttrace_page_dict
74 struct inf_ttrace_page buckets[128];
75 int pagesize; /* Page size. */
76 int count; /* Number of pages in this dictionary. */
77 } inf_ttrace_page_dict;
79 struct inf_ttrace_private_thread_info
81 int dying;
84 /* Number of lwps that are currently in a system call. */
85 static int inf_ttrace_num_lwps_in_syscall;
87 /* Flag to indicate whether we should re-enable page protections after
88 the next wait. */
89 static int inf_ttrace_reenable_page_protections;
91 /* Enable system call events for process PID. */
93 static void
94 inf_ttrace_enable_syscall_events (pid_t pid)
96 ttevent_t tte;
97 ttstate_t tts;
99 gdb_assert (inf_ttrace_num_lwps_in_syscall == 0);
101 if (ttrace (TT_PROC_GET_EVENT_MASK, pid, 0,
102 (uintptr_t)&tte, sizeof tte, 0) == -1)
103 perror_with_name (("ttrace"));
105 tte.tte_events |= (TTEVT_SYSCALL_ENTRY | TTEVT_SYSCALL_RETURN);
107 if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0,
108 (uintptr_t)&tte, sizeof tte, 0) == -1)
109 perror_with_name (("ttrace"));
111 if (ttrace (TT_PROC_GET_FIRST_LWP_STATE, pid, 0,
112 (uintptr_t)&tts, sizeof tts, 0) == -1)
113 perror_with_name (("ttrace"));
115 if (tts.tts_flags & TTS_INSYSCALL)
116 inf_ttrace_num_lwps_in_syscall++;
118 /* FIXME: Handle multiple threads. */
121 /* Disable system call events for process PID. */
123 static void
124 inf_ttrace_disable_syscall_events (pid_t pid)
126 ttevent_t tte;
128 gdb_assert (inf_ttrace_page_dict.count == 0);
130 if (ttrace (TT_PROC_GET_EVENT_MASK, pid, 0,
131 (uintptr_t)&tte, sizeof tte, 0) == -1)
132 perror_with_name (("ttrace"));
134 tte.tte_events &= ~(TTEVT_SYSCALL_ENTRY | TTEVT_SYSCALL_RETURN);
136 if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0,
137 (uintptr_t)&tte, sizeof tte, 0) == -1)
138 perror_with_name (("ttrace"));
140 inf_ttrace_num_lwps_in_syscall = 0;
143 /* Get information about the page at address ADDR for process PID from
144 the dictionary. */
146 static struct inf_ttrace_page *
147 inf_ttrace_get_page (pid_t pid, CORE_ADDR addr)
149 const int num_buckets = ARRAY_SIZE (inf_ttrace_page_dict.buckets);
150 const int pagesize = inf_ttrace_page_dict.pagesize;
151 int bucket;
152 struct inf_ttrace_page *page;
154 bucket = (addr / pagesize) % num_buckets;
155 page = &inf_ttrace_page_dict.buckets[bucket];
156 while (page)
158 if (page->addr == addr)
159 break;
161 page = page->next;
164 return page;
167 /* Add the page at address ADDR for process PID to the dictionary. */
169 static struct inf_ttrace_page *
170 inf_ttrace_add_page (pid_t pid, CORE_ADDR addr)
172 const int num_buckets = ARRAY_SIZE (inf_ttrace_page_dict.buckets);
173 const int pagesize = inf_ttrace_page_dict.pagesize;
174 int bucket;
175 struct inf_ttrace_page *page;
176 struct inf_ttrace_page *prev = NULL;
178 bucket = (addr / pagesize) % num_buckets;
179 page = &inf_ttrace_page_dict.buckets[bucket];
180 while (page)
182 if (page->addr == addr)
183 break;
185 prev = page;
186 page = page->next;
189 if (!page)
191 int prot;
193 if (ttrace (TT_PROC_GET_MPROTECT, pid, 0,
194 addr, 0, (uintptr_t)&prot) == -1)
195 perror_with_name (("ttrace"));
197 page = XMALLOC (struct inf_ttrace_page);
198 page->addr = addr;
199 page->prot = prot;
200 page->refcount = 0;
201 page->next = NULL;
203 page->prev = prev;
204 prev->next = page;
206 inf_ttrace_page_dict.count++;
207 if (inf_ttrace_page_dict.count == 1)
208 inf_ttrace_enable_syscall_events (pid);
210 if (inf_ttrace_num_lwps_in_syscall == 0)
212 if (ttrace (TT_PROC_SET_MPROTECT, pid, 0,
213 addr, pagesize, prot & ~PROT_WRITE) == -1)
214 perror_with_name (("ttrace"));
218 return page;
221 /* Insert the page at address ADDR of process PID to the dictionary. */
223 static void
224 inf_ttrace_insert_page (pid_t pid, CORE_ADDR addr)
226 struct inf_ttrace_page *page;
228 page = inf_ttrace_get_page (pid, addr);
229 if (!page)
230 page = inf_ttrace_add_page (pid, addr);
232 page->refcount++;
235 /* Remove the page at address ADDR of process PID from the dictionary. */
237 static void
238 inf_ttrace_remove_page (pid_t pid, CORE_ADDR addr)
240 const int pagesize = inf_ttrace_page_dict.pagesize;
241 struct inf_ttrace_page *page;
243 page = inf_ttrace_get_page (pid, addr);
244 page->refcount--;
246 gdb_assert (page->refcount >= 0);
248 if (page->refcount == 0)
250 if (inf_ttrace_num_lwps_in_syscall == 0)
252 if (ttrace (TT_PROC_SET_MPROTECT, pid, 0,
253 addr, pagesize, page->prot) == -1)
254 perror_with_name (("ttrace"));
257 inf_ttrace_page_dict.count--;
258 if (inf_ttrace_page_dict.count == 0)
259 inf_ttrace_disable_syscall_events (pid);
261 page->prev->next = page->next;
262 if (page->next)
263 page->next->prev = page->prev;
265 xfree (page);
269 /* Mask the bits in PROT from the page protections that are currently
270 in the dictionary for process PID. */
272 static void
273 inf_ttrace_mask_page_protections (pid_t pid, int prot)
275 const int num_buckets = ARRAY_SIZE (inf_ttrace_page_dict.buckets);
276 const int pagesize = inf_ttrace_page_dict.pagesize;
277 int bucket;
279 for (bucket = 0; bucket < num_buckets; bucket++)
281 struct inf_ttrace_page *page;
283 page = inf_ttrace_page_dict.buckets[bucket].next;
284 while (page)
286 if (ttrace (TT_PROC_SET_MPROTECT, pid, 0,
287 page->addr, pagesize, page->prot & ~prot) == -1)
288 perror_with_name (("ttrace"));
290 page = page->next;
295 /* Write-protect the pages in the dictionary for process PID. */
297 static void
298 inf_ttrace_enable_page_protections (pid_t pid)
300 inf_ttrace_mask_page_protections (pid, PROT_WRITE);
303 /* Restore the protection of the pages in the dictionary for process
304 PID. */
306 static void
307 inf_ttrace_disable_page_protections (pid_t pid)
309 inf_ttrace_mask_page_protections (pid, 0);
312 /* Insert a "hardware" watchpoint for LEN bytes at address ADDR of
313 type TYPE. */
315 static int
316 inf_ttrace_insert_watchpoint (CORE_ADDR addr, int len, int type,
317 struct expression *cond)
319 const int pagesize = inf_ttrace_page_dict.pagesize;
320 pid_t pid = ptid_get_pid (inferior_ptid);
321 CORE_ADDR page_addr;
322 int num_pages;
323 int page;
325 gdb_assert (type == hw_write);
327 page_addr = (addr / pagesize) * pagesize;
328 num_pages = (len + pagesize - 1) / pagesize;
330 for (page = 0; page < num_pages; page++, page_addr += pagesize)
331 inf_ttrace_insert_page (pid, page_addr);
333 return 1;
336 /* Remove a "hardware" watchpoint for LEN bytes at address ADDR of
337 type TYPE. */
339 static int
340 inf_ttrace_remove_watchpoint (CORE_ADDR addr, int len, int type,
341 struct expression *cond)
343 const int pagesize = inf_ttrace_page_dict.pagesize;
344 pid_t pid = ptid_get_pid (inferior_ptid);
345 CORE_ADDR page_addr;
346 int num_pages;
347 int page;
349 gdb_assert (type == hw_write);
351 page_addr = (addr / pagesize) * pagesize;
352 num_pages = (len + pagesize - 1) / pagesize;
354 for (page = 0; page < num_pages; page++, page_addr += pagesize)
355 inf_ttrace_remove_page (pid, page_addr);
357 return 1;
360 static int
361 inf_ttrace_can_use_hw_breakpoint (int type, int len, int ot)
363 return (type == bp_hardware_watchpoint);
366 static int
367 inf_ttrace_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
369 return 1;
372 /* Return non-zero if the current inferior was (potentially) stopped
373 by hitting a "hardware" watchpoint. */
375 static int
376 inf_ttrace_stopped_by_watchpoint (void)
378 pid_t pid = ptid_get_pid (inferior_ptid);
379 lwpid_t lwpid = ptid_get_lwp (inferior_ptid);
380 ttstate_t tts;
382 if (inf_ttrace_page_dict.count > 0)
384 if (ttrace (TT_LWP_GET_STATE, pid, lwpid,
385 (uintptr_t)&tts, sizeof tts, 0) == -1)
386 perror_with_name (("ttrace"));
388 if (tts.tts_event == TTEVT_SIGNAL
389 && tts.tts_u.tts_signal.tts_signo == SIGBUS)
391 const int pagesize = inf_ttrace_page_dict.pagesize;
392 void *addr = tts.tts_u.tts_signal.tts_siginfo.si_addr;
393 CORE_ADDR page_addr = ((uintptr_t)addr / pagesize) * pagesize;
395 if (inf_ttrace_get_page (pid, page_addr))
396 return 1;
400 return 0;
404 /* When tracking a vfork(2), we cannot detach from the parent until
405 after the child has called exec(3) or has exited. If we are still
406 attached to the parent, this variable will be set to the process ID
407 of the parent. Otherwise it will be set to zero. */
408 static pid_t inf_ttrace_vfork_ppid = -1;
410 static int
411 inf_ttrace_follow_fork (struct target_ops *ops, int follow_child)
413 pid_t pid, fpid;
414 lwpid_t lwpid, flwpid;
415 ttstate_t tts;
416 struct thread_info *tp = inferior_thread ();
418 gdb_assert (tp->pending_follow.kind == TARGET_WAITKIND_FORKED
419 || tp->pending_follow.kind == TARGET_WAITKIND_VFORKED);
421 pid = ptid_get_pid (inferior_ptid);
422 lwpid = ptid_get_lwp (inferior_ptid);
424 /* Get all important details that core GDB doesn't (and shouldn't)
425 know about. */
426 if (ttrace (TT_LWP_GET_STATE, pid, lwpid,
427 (uintptr_t)&tts, sizeof tts, 0) == -1)
428 perror_with_name (("ttrace"));
430 gdb_assert (tts.tts_event == TTEVT_FORK || tts.tts_event == TTEVT_VFORK);
432 if (tts.tts_u.tts_fork.tts_isparent)
434 pid = tts.tts_pid;
435 lwpid = tts.tts_lwpid;
436 fpid = tts.tts_u.tts_fork.tts_fpid;
437 flwpid = tts.tts_u.tts_fork.tts_flwpid;
439 else
441 pid = tts.tts_u.tts_fork.tts_fpid;
442 lwpid = tts.tts_u.tts_fork.tts_flwpid;
443 fpid = tts.tts_pid;
444 flwpid = tts.tts_lwpid;
447 if (follow_child)
449 struct inferior *inf;
450 struct inferior *parent_inf;
452 parent_inf = find_inferior_pid (pid);
454 inferior_ptid = ptid_build (fpid, flwpid, 0);
455 inf = add_inferior (fpid);
456 inf->attach_flag = parent_inf->attach_flag;
457 inf->pspace = parent_inf->pspace;
458 inf->aspace = parent_inf->aspace;
459 copy_terminal_info (inf, parent_inf);
460 detach_breakpoints (ptid_build (pid, lwpid, 0));
462 target_terminal_ours ();
463 fprintf_unfiltered (gdb_stdlog,
464 _("Attaching after fork to child process %ld.\n"),
465 (long)fpid);
467 else
469 inferior_ptid = ptid_build (pid, lwpid, 0);
470 /* Detach any remaining breakpoints in the child. In the case
471 of fork events, we do not need to do this, because breakpoints
472 should have already been removed earlier. */
473 if (tts.tts_event == TTEVT_VFORK)
474 detach_breakpoints (ptid_build (fpid, flwpid, 0));
476 target_terminal_ours ();
477 fprintf_unfiltered (gdb_stdlog,
478 _("Detaching after fork from child process %ld.\n"),
479 (long)fpid);
482 if (tts.tts_event == TTEVT_VFORK)
484 gdb_assert (!tts.tts_u.tts_fork.tts_isparent);
486 if (follow_child)
488 /* We can't detach from the parent yet. */
489 inf_ttrace_vfork_ppid = pid;
491 reattach_breakpoints (fpid);
493 else
495 if (ttrace (TT_PROC_DETACH, fpid, 0, 0, 0, 0) == -1)
496 perror_with_name (("ttrace"));
498 /* Wait till we get the TTEVT_VFORK event in the parent.
499 This indicates that the child has called exec(3) or has
500 exited and that the parent is ready to be traced again. */
501 if (ttrace_wait (pid, lwpid, TTRACE_WAITOK, &tts, sizeof tts) == -1)
502 perror_with_name (("ttrace_wait"));
503 gdb_assert (tts.tts_event == TTEVT_VFORK);
504 gdb_assert (tts.tts_u.tts_fork.tts_isparent);
506 reattach_breakpoints (pid);
509 else
511 gdb_assert (tts.tts_u.tts_fork.tts_isparent);
513 if (follow_child)
515 if (ttrace (TT_PROC_DETACH, pid, 0, 0, 0, 0) == -1)
516 perror_with_name (("ttrace"));
518 else
520 if (ttrace (TT_PROC_DETACH, fpid, 0, 0, 0, 0) == -1)
521 perror_with_name (("ttrace"));
525 if (follow_child)
527 struct thread_info *ti;
529 /* The child will start out single-threaded. */
530 inf_ttrace_num_lwps = 1;
531 inf_ttrace_num_lwps_in_syscall = 0;
533 /* Delete parent. */
534 delete_thread_silent (ptid_build (pid, lwpid, 0));
535 detach_inferior (pid);
537 /* Add child thread. inferior_ptid was already set above. */
538 ti = add_thread_silent (inferior_ptid);
539 ti->private =
540 xmalloc (sizeof (struct inf_ttrace_private_thread_info));
541 memset (ti->private, 0,
542 sizeof (struct inf_ttrace_private_thread_info));
545 return 0;
549 /* File descriptors for pipes used as semaphores during initial
550 startup of an inferior. */
551 static int inf_ttrace_pfd1[2];
552 static int inf_ttrace_pfd2[2];
554 static void
555 do_cleanup_pfds (void *dummy)
557 close (inf_ttrace_pfd1[0]);
558 close (inf_ttrace_pfd1[1]);
559 close (inf_ttrace_pfd2[0]);
560 close (inf_ttrace_pfd2[1]);
563 static void
564 inf_ttrace_prepare (void)
566 if (pipe (inf_ttrace_pfd1) == -1)
567 perror_with_name (("pipe"));
569 if (pipe (inf_ttrace_pfd2) == -1)
571 close (inf_ttrace_pfd1[0]);
572 close (inf_ttrace_pfd2[0]);
573 perror_with_name (("pipe"));
577 /* Prepare to be traced. */
579 static void
580 inf_ttrace_me (void)
582 struct cleanup *old_chain = make_cleanup (do_cleanup_pfds, 0);
583 char c;
585 /* "Trace me, Dr. Memory!" */
586 if (ttrace (TT_PROC_SETTRC, 0, 0, 0, TT_VERSION, 0) == -1)
587 perror_with_name (("ttrace"));
589 /* Tell our parent that we are ready to be traced. */
590 if (write (inf_ttrace_pfd1[1], &c, sizeof c) != sizeof c)
591 perror_with_name (("write"));
593 /* Wait until our parent has set the initial event mask. */
594 if (read (inf_ttrace_pfd2[0], &c, sizeof c) != sizeof c)
595 perror_with_name (("read"));
597 do_cleanups (old_chain);
600 /* Start tracing PID. */
602 static void
603 inf_ttrace_him (struct target_ops *ops, int pid)
605 struct cleanup *old_chain = make_cleanup (do_cleanup_pfds, 0);
606 ttevent_t tte;
607 char c;
609 /* Wait until our child is ready to be traced. */
610 if (read (inf_ttrace_pfd1[0], &c, sizeof c) != sizeof c)
611 perror_with_name (("read"));
613 /* Set the initial event mask. */
614 memset (&tte, 0, sizeof (tte));
615 tte.tte_events |= TTEVT_EXEC | TTEVT_EXIT | TTEVT_FORK | TTEVT_VFORK;
616 tte.tte_events |= TTEVT_LWP_CREATE | TTEVT_LWP_EXIT | TTEVT_LWP_TERMINATE;
617 #ifdef TTEVT_BPT_SSTEP
618 tte.tte_events |= TTEVT_BPT_SSTEP;
619 #endif
620 tte.tte_opts |= TTEO_PROC_INHERIT;
621 if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0,
622 (uintptr_t)&tte, sizeof tte, 0) == -1)
623 perror_with_name (("ttrace"));
625 /* Tell our child that we have set the initial event mask. */
626 if (write (inf_ttrace_pfd2[1], &c, sizeof c) != sizeof c)
627 perror_with_name (("write"));
629 do_cleanups (old_chain);
631 push_target (ops);
633 /* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h, and will
634 be 1 or 2 depending on whether we're starting without or with a
635 shell. */
636 startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
638 /* On some targets, there must be some explicit actions taken after
639 the inferior has been started up. */
640 target_post_startup_inferior (pid_to_ptid (pid));
643 static void
644 inf_ttrace_create_inferior (struct target_ops *ops, char *exec_file,
645 char *allargs, char **env, int from_tty)
647 int pid;
649 gdb_assert (inf_ttrace_num_lwps == 0);
650 gdb_assert (inf_ttrace_num_lwps_in_syscall == 0);
651 gdb_assert (inf_ttrace_page_dict.count == 0);
652 gdb_assert (inf_ttrace_reenable_page_protections == 0);
653 gdb_assert (inf_ttrace_vfork_ppid == -1);
655 pid = fork_inferior (exec_file, allargs, env, inf_ttrace_me, NULL,
656 inf_ttrace_prepare, NULL, NULL);
658 inf_ttrace_him (ops, pid);
661 static void
662 inf_ttrace_mourn_inferior (struct target_ops *ops)
664 const int num_buckets = ARRAY_SIZE (inf_ttrace_page_dict.buckets);
665 int bucket;
667 inf_ttrace_num_lwps = 0;
668 inf_ttrace_num_lwps_in_syscall = 0;
670 for (bucket = 0; bucket < num_buckets; bucket++)
672 struct inf_ttrace_page *page;
673 struct inf_ttrace_page *next;
675 page = inf_ttrace_page_dict.buckets[bucket].next;
676 while (page)
678 next = page->next;
679 xfree (page);
680 page = next;
683 inf_ttrace_page_dict.count = 0;
685 unpush_target (ops);
686 generic_mourn_inferior ();
689 /* Assuming we just attached the debugger to a new inferior, create
690 a new thread_info structure for each thread, and add it to our
691 list of threads. */
693 static void
694 inf_ttrace_create_threads_after_attach (int pid)
696 int status;
697 ptid_t ptid;
698 ttstate_t tts;
699 struct thread_info *ti;
701 status = ttrace (TT_PROC_GET_FIRST_LWP_STATE, pid, 0,
702 (uintptr_t) &tts, sizeof (ttstate_t), 0);
703 if (status < 0)
704 perror_with_name (_("TT_PROC_GET_FIRST_LWP_STATE ttrace call failed"));
705 gdb_assert (tts.tts_pid == pid);
707 /* Add the stopped thread. */
708 ptid = ptid_build (pid, tts.tts_lwpid, 0);
709 ti = add_thread (ptid);
710 ti->private = xzalloc (sizeof (struct inf_ttrace_private_thread_info));
711 inf_ttrace_num_lwps++;
713 /* We use the "first stopped thread" as the currently active thread. */
714 inferior_ptid = ptid;
716 /* Iterative over all the remaining threads. */
718 for (;;)
720 ptid_t ptid;
722 status = ttrace (TT_PROC_GET_NEXT_LWP_STATE, pid, 0,
723 (uintptr_t) &tts, sizeof (ttstate_t), 0);
724 if (status < 0)
725 perror_with_name (_("TT_PROC_GET_NEXT_LWP_STATE ttrace call failed"));
726 if (status == 0)
727 break; /* End of list. */
729 ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0);
730 ti = add_thread (ptid);
731 ti->private = xzalloc (sizeof (struct inf_ttrace_private_thread_info));
732 inf_ttrace_num_lwps++;
736 static void
737 inf_ttrace_attach (struct target_ops *ops, char *args, int from_tty)
739 char *exec_file;
740 pid_t pid;
741 ttevent_t tte;
742 struct inferior *inf;
744 pid = parse_pid_to_attach (args);
746 if (pid == getpid ()) /* Trying to masturbate? */
747 error (_("I refuse to debug myself!"));
749 if (from_tty)
751 exec_file = get_exec_file (0);
753 if (exec_file)
754 printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file,
755 target_pid_to_str (pid_to_ptid (pid)));
756 else
757 printf_unfiltered (_("Attaching to %s\n"),
758 target_pid_to_str (pid_to_ptid (pid)));
760 gdb_flush (gdb_stdout);
763 gdb_assert (inf_ttrace_num_lwps == 0);
764 gdb_assert (inf_ttrace_num_lwps_in_syscall == 0);
765 gdb_assert (inf_ttrace_vfork_ppid == -1);
767 if (ttrace (TT_PROC_ATTACH, pid, 0, TT_KILL_ON_EXIT, TT_VERSION, 0) == -1)
768 perror_with_name (("ttrace"));
770 inf = current_inferior ();
771 inferior_appeared (inf, pid);
772 inf->attach_flag = 1;
774 /* Set the initial event mask. */
775 memset (&tte, 0, sizeof (tte));
776 tte.tte_events |= TTEVT_EXEC | TTEVT_EXIT | TTEVT_FORK | TTEVT_VFORK;
777 tte.tte_events |= TTEVT_LWP_CREATE | TTEVT_LWP_EXIT | TTEVT_LWP_TERMINATE;
778 #ifdef TTEVT_BPT_SSTEP
779 tte.tte_events |= TTEVT_BPT_SSTEP;
780 #endif
781 tte.tte_opts |= TTEO_PROC_INHERIT;
782 if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0,
783 (uintptr_t)&tte, sizeof tte, 0) == -1)
784 perror_with_name (("ttrace"));
786 push_target (ops);
788 inf_ttrace_create_threads_after_attach (pid);
791 static void
792 inf_ttrace_detach (struct target_ops *ops, char *args, int from_tty)
794 pid_t pid = ptid_get_pid (inferior_ptid);
795 int sig = 0;
797 if (from_tty)
799 char *exec_file = get_exec_file (0);
800 if (exec_file == 0)
801 exec_file = "";
802 printf_unfiltered (_("Detaching from program: %s, %s\n"), exec_file,
803 target_pid_to_str (pid_to_ptid (pid)));
804 gdb_flush (gdb_stdout);
806 if (args)
807 sig = atoi (args);
809 /* ??? The HP-UX 11.0 ttrace(2) manual page doesn't mention that we
810 can pass a signal number here. Does this really work? */
811 if (ttrace (TT_PROC_DETACH, pid, 0, 0, sig, 0) == -1)
812 perror_with_name (("ttrace"));
814 if (inf_ttrace_vfork_ppid != -1)
816 if (ttrace (TT_PROC_DETACH, inf_ttrace_vfork_ppid, 0, 0, 0, 0) == -1)
817 perror_with_name (("ttrace"));
818 inf_ttrace_vfork_ppid = -1;
821 inf_ttrace_num_lwps = 0;
822 inf_ttrace_num_lwps_in_syscall = 0;
824 inferior_ptid = null_ptid;
825 detach_inferior (pid);
827 unpush_target (ops);
830 static void
831 inf_ttrace_kill (struct target_ops *ops)
833 pid_t pid = ptid_get_pid (inferior_ptid);
835 if (pid == 0)
836 return;
838 if (ttrace (TT_PROC_EXIT, pid, 0, 0, 0, 0) == -1)
839 perror_with_name (("ttrace"));
840 /* ??? Is it necessary to call ttrace_wait() here? */
842 if (inf_ttrace_vfork_ppid != -1)
844 if (ttrace (TT_PROC_DETACH, inf_ttrace_vfork_ppid, 0, 0, 0, 0) == -1)
845 perror_with_name (("ttrace"));
846 inf_ttrace_vfork_ppid = -1;
849 target_mourn_inferior ();
852 /* Check is a dying thread is dead by now, and delete it from GDBs
853 thread list if so. */
854 static int
855 inf_ttrace_delete_dead_threads_callback (struct thread_info *info, void *arg)
857 lwpid_t lwpid;
858 struct inf_ttrace_private_thread_info *p;
860 if (is_exited (info->ptid))
861 return 0;
863 lwpid = ptid_get_lwp (info->ptid);
864 p = (struct inf_ttrace_private_thread_info *) info->private;
866 /* Check if an lwp that was dying is still there or not. */
867 if (p->dying && (kill (lwpid, 0) == -1))
868 /* It's gone now. */
869 delete_thread (info->ptid);
871 return 0;
874 /* Resume the lwp pointed to by INFO, with REQUEST, and pass it signal
875 SIG. */
877 static void
878 inf_ttrace_resume_lwp (struct thread_info *info, ttreq_t request, int sig)
880 pid_t pid = ptid_get_pid (info->ptid);
881 lwpid_t lwpid = ptid_get_lwp (info->ptid);
883 if (ttrace (request, pid, lwpid, TT_NOPC, sig, 0) == -1)
885 struct inf_ttrace_private_thread_info *p
886 = (struct inf_ttrace_private_thread_info *) info->private;
887 if (p->dying && errno == EPROTO)
888 /* This is expected, it means the dying lwp is really gone
889 by now. If ttrace had an event to inform the debugger
890 the lwp is really gone, this wouldn't be needed. */
891 delete_thread (info->ptid);
892 else
893 /* This was really unexpected. */
894 perror_with_name (("ttrace"));
898 /* Callback for iterate_over_threads. */
900 static int
901 inf_ttrace_resume_callback (struct thread_info *info, void *arg)
903 if (!ptid_equal (info->ptid, inferior_ptid) && !is_exited (info->ptid))
904 inf_ttrace_resume_lwp (info, TT_LWP_CONTINUE, 0);
906 return 0;
909 static void
910 inf_ttrace_resume (struct target_ops *ops,
911 ptid_t ptid, int step, enum gdb_signal signal)
913 int resume_all;
914 ttreq_t request = step ? TT_LWP_SINGLE : TT_LWP_CONTINUE;
915 int sig = gdb_signal_to_host (signal);
916 struct thread_info *info;
918 /* A specific PTID means `step only this process id'. */
919 resume_all = (ptid_equal (ptid, minus_one_ptid));
921 /* If resuming all threads, it's the current thread that should be
922 handled specially. */
923 if (resume_all)
924 ptid = inferior_ptid;
926 info = find_thread_ptid (ptid);
927 inf_ttrace_resume_lwp (info, request, sig);
929 if (resume_all)
930 /* Let all the other threads run too. */
931 iterate_over_threads (inf_ttrace_resume_callback, NULL);
934 static ptid_t
935 inf_ttrace_wait (struct target_ops *ops,
936 ptid_t ptid, struct target_waitstatus *ourstatus, int options)
938 pid_t pid = ptid_get_pid (ptid);
939 lwpid_t lwpid = ptid_get_lwp (ptid);
940 ttstate_t tts;
941 struct thread_info *ti;
942 ptid_t related_ptid;
944 /* Until proven otherwise. */
945 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
947 if (pid == -1)
948 pid = lwpid = 0;
950 gdb_assert (pid != 0 || lwpid == 0);
954 set_sigint_trap ();
956 if (ttrace_wait (pid, lwpid, TTRACE_WAITOK, &tts, sizeof tts) == -1)
957 perror_with_name (("ttrace_wait"));
959 if (tts.tts_event == TTEVT_VFORK && tts.tts_u.tts_fork.tts_isparent)
961 if (inf_ttrace_vfork_ppid != -1)
963 gdb_assert (inf_ttrace_vfork_ppid == tts.tts_pid);
965 if (ttrace (TT_PROC_DETACH, tts.tts_pid, 0, 0, 0, 0) == -1)
966 perror_with_name (("ttrace"));
967 inf_ttrace_vfork_ppid = -1;
970 tts.tts_event = TTEVT_NONE;
973 clear_sigint_trap ();
975 while (tts.tts_event == TTEVT_NONE);
977 /* Now that we've waited, we can re-enable the page protections. */
978 if (inf_ttrace_reenable_page_protections)
980 gdb_assert (inf_ttrace_num_lwps_in_syscall == 0);
981 inf_ttrace_enable_page_protections (tts.tts_pid);
982 inf_ttrace_reenable_page_protections = 0;
985 ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0);
987 if (inf_ttrace_num_lwps == 0)
989 struct thread_info *ti;
991 inf_ttrace_num_lwps = 1;
993 /* This is the earliest we hear about the lwp member of
994 INFERIOR_PTID, after an attach or fork_inferior. */
995 gdb_assert (ptid_get_lwp (inferior_ptid) == 0);
997 /* We haven't set the private member on the main thread yet. Do
998 it now. */
999 ti = find_thread_ptid (inferior_ptid);
1000 gdb_assert (ti != NULL && ti->private == NULL);
1001 ti->private =
1002 xmalloc (sizeof (struct inf_ttrace_private_thread_info));
1003 memset (ti->private, 0,
1004 sizeof (struct inf_ttrace_private_thread_info));
1006 /* Notify the core that this ptid changed. This changes
1007 inferior_ptid as well. */
1008 thread_change_ptid (inferior_ptid, ptid);
1011 switch (tts.tts_event)
1013 #ifdef TTEVT_BPT_SSTEP
1014 case TTEVT_BPT_SSTEP:
1015 /* Make it look like a breakpoint. */
1016 ourstatus->kind = TARGET_WAITKIND_STOPPED;
1017 ourstatus->value.sig = GDB_SIGNAL_TRAP;
1018 break;
1019 #endif
1021 case TTEVT_EXEC:
1022 ourstatus->kind = TARGET_WAITKIND_EXECD;
1023 ourstatus->value.execd_pathname =
1024 xmalloc (tts.tts_u.tts_exec.tts_pathlen + 1);
1025 if (ttrace (TT_PROC_GET_PATHNAME, tts.tts_pid, 0,
1026 (uintptr_t)ourstatus->value.execd_pathname,
1027 tts.tts_u.tts_exec.tts_pathlen, 0) == -1)
1028 perror_with_name (("ttrace"));
1029 ourstatus->value.execd_pathname[tts.tts_u.tts_exec.tts_pathlen] = 0;
1031 /* At this point, all inserted breakpoints are gone. Doing this
1032 as soon as we detect an exec prevents the badness of deleting
1033 a breakpoint writing the current "shadow contents" to lift
1034 the bp. That shadow is NOT valid after an exec. */
1035 mark_breakpoints_out ();
1036 break;
1038 case TTEVT_EXIT:
1039 store_waitstatus (ourstatus, tts.tts_u.tts_exit.tts_exitcode);
1040 inf_ttrace_num_lwps = 0;
1041 break;
1043 case TTEVT_FORK:
1044 related_ptid = ptid_build (tts.tts_u.tts_fork.tts_fpid,
1045 tts.tts_u.tts_fork.tts_flwpid, 0);
1047 ourstatus->kind = TARGET_WAITKIND_FORKED;
1048 ourstatus->value.related_pid = related_ptid;
1050 /* Make sure the other end of the fork is stopped too. */
1051 if (ttrace_wait (tts.tts_u.tts_fork.tts_fpid,
1052 tts.tts_u.tts_fork.tts_flwpid,
1053 TTRACE_WAITOK, &tts, sizeof tts) == -1)
1054 perror_with_name (("ttrace_wait"));
1056 gdb_assert (tts.tts_event == TTEVT_FORK);
1057 if (tts.tts_u.tts_fork.tts_isparent)
1059 related_ptid = ptid_build (tts.tts_u.tts_fork.tts_fpid,
1060 tts.tts_u.tts_fork.tts_flwpid, 0);
1061 ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0);
1062 ourstatus->value.related_pid = related_ptid;
1064 break;
1066 case TTEVT_VFORK:
1067 gdb_assert (!tts.tts_u.tts_fork.tts_isparent);
1069 related_ptid = ptid_build (tts.tts_u.tts_fork.tts_fpid,
1070 tts.tts_u.tts_fork.tts_flwpid, 0);
1072 ourstatus->kind = TARGET_WAITKIND_VFORKED;
1073 ourstatus->value.related_pid = related_ptid;
1075 /* HACK: To avoid touching the parent during the vfork, switch
1076 away from it. */
1077 inferior_ptid = ptid;
1078 break;
1080 case TTEVT_LWP_CREATE:
1081 lwpid = tts.tts_u.tts_thread.tts_target_lwpid;
1082 ptid = ptid_build (tts.tts_pid, lwpid, 0);
1083 ti = add_thread (ptid);
1084 ti->private =
1085 xmalloc (sizeof (struct inf_ttrace_private_thread_info));
1086 memset (ti->private, 0,
1087 sizeof (struct inf_ttrace_private_thread_info));
1088 inf_ttrace_num_lwps++;
1089 ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0);
1090 /* Let the lwp_create-caller thread continue. */
1091 ttrace (TT_LWP_CONTINUE, ptid_get_pid (ptid),
1092 ptid_get_lwp (ptid), TT_NOPC, 0, 0);
1093 /* Return without stopping the whole process. */
1094 ourstatus->kind = TARGET_WAITKIND_IGNORE;
1095 return ptid;
1097 case TTEVT_LWP_EXIT:
1098 if (print_thread_events)
1099 printf_unfiltered (_("[%s exited]\n"), target_pid_to_str (ptid));
1100 ti = find_thread_ptid (ptid);
1101 gdb_assert (ti != NULL);
1102 ((struct inf_ttrace_private_thread_info *)ti->private)->dying = 1;
1103 inf_ttrace_num_lwps--;
1104 /* Let the thread really exit. */
1105 ttrace (TT_LWP_CONTINUE, ptid_get_pid (ptid),
1106 ptid_get_lwp (ptid), TT_NOPC, 0, 0);
1107 /* Return without stopping the whole process. */
1108 ourstatus->kind = TARGET_WAITKIND_IGNORE;
1109 return ptid;
1111 case TTEVT_LWP_TERMINATE:
1112 lwpid = tts.tts_u.tts_thread.tts_target_lwpid;
1113 ptid = ptid_build (tts.tts_pid, lwpid, 0);
1114 if (print_thread_events)
1115 printf_unfiltered(_("[%s has been terminated]\n"),
1116 target_pid_to_str (ptid));
1117 ti = find_thread_ptid (ptid);
1118 gdb_assert (ti != NULL);
1119 ((struct inf_ttrace_private_thread_info *)ti->private)->dying = 1;
1120 inf_ttrace_num_lwps--;
1122 /* Resume the lwp_terminate-caller thread. */
1123 ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0);
1124 ttrace (TT_LWP_CONTINUE, ptid_get_pid (ptid),
1125 ptid_get_lwp (ptid), TT_NOPC, 0, 0);
1126 /* Return without stopping the whole process. */
1127 ourstatus->kind = TARGET_WAITKIND_IGNORE;
1128 return ptid;
1130 case TTEVT_SIGNAL:
1131 ourstatus->kind = TARGET_WAITKIND_STOPPED;
1132 ourstatus->value.sig =
1133 gdb_signal_from_host (tts.tts_u.tts_signal.tts_signo);
1134 break;
1136 case TTEVT_SYSCALL_ENTRY:
1137 gdb_assert (inf_ttrace_reenable_page_protections == 0);
1138 inf_ttrace_num_lwps_in_syscall++;
1139 if (inf_ttrace_num_lwps_in_syscall == 1)
1141 /* A thread has just entered a system call. Disable any
1142 page protections as the kernel can't deal with them. */
1143 inf_ttrace_disable_page_protections (tts.tts_pid);
1145 ourstatus->kind = TARGET_WAITKIND_SYSCALL_ENTRY;
1146 ourstatus->value.syscall_number = tts.tts_scno;
1147 break;
1149 case TTEVT_SYSCALL_RETURN:
1150 if (inf_ttrace_num_lwps_in_syscall > 0)
1152 /* If the last thread has just left the system call, this
1153 would be a logical place to re-enable the page
1154 protections, but that doesn't work. We can't re-enable
1155 them until we've done another wait. */
1156 inf_ttrace_reenable_page_protections =
1157 (inf_ttrace_num_lwps_in_syscall == 1);
1158 inf_ttrace_num_lwps_in_syscall--;
1160 ourstatus->kind = TARGET_WAITKIND_SYSCALL_RETURN;
1161 ourstatus->value.syscall_number = tts.tts_scno;
1162 break;
1164 default:
1165 gdb_assert (!"Unexpected ttrace event");
1166 break;
1169 /* Make sure all threads within the process are stopped. */
1170 if (ttrace (TT_PROC_STOP, tts.tts_pid, 0, 0, 0, 0) == -1)
1171 perror_with_name (("ttrace"));
1173 /* Now that the whole process is stopped, check if any dying thread
1174 is really dead by now. If a dying thread is still alive, it will
1175 be stopped too, and will still show up in `info threads', tagged
1176 with "(Exiting)". We could make `info threads' prune dead
1177 threads instead via inf_ttrace_thread_alive, but doing this here
1178 has the advantage that a frontend is notificed sooner of thread
1179 exits. Note that a dying lwp is still alive, it still has to be
1180 resumed, like any other lwp. */
1181 iterate_over_threads (inf_ttrace_delete_dead_threads_callback, NULL);
1183 return ptid;
1186 /* Transfer LEN bytes from ADDR in the inferior's memory into READBUF,
1187 and transfer LEN bytes from WRITEBUF into the inferior's memory at
1188 ADDR. Either READBUF or WRITEBUF may be null, in which case the
1189 corresponding transfer doesn't happen. Return the number of bytes
1190 actually transferred (which may be zero if an error occurs). */
1192 static LONGEST
1193 inf_ttrace_xfer_memory (CORE_ADDR addr, ULONGEST len,
1194 void *readbuf, const void *writebuf)
1196 pid_t pid = ptid_get_pid (inferior_ptid);
1198 /* HP-UX treats text space and data space differently. GDB however,
1199 doesn't really know the difference. Therefore we try both. Try
1200 text space before data space though because when we're writing
1201 into text space the instruction cache might need to be flushed. */
1203 if (readbuf
1204 && ttrace (TT_PROC_RDTEXT, pid, 0, addr, len, (uintptr_t)readbuf) == -1
1205 && ttrace (TT_PROC_RDDATA, pid, 0, addr, len, (uintptr_t)readbuf) == -1)
1206 return 0;
1208 if (writebuf
1209 && ttrace (TT_PROC_WRTEXT, pid, 0, addr, len, (uintptr_t)writebuf) == -1
1210 && ttrace (TT_PROC_WRDATA, pid, 0, addr, len, (uintptr_t)writebuf) == -1)
1211 return 0;
1213 return len;
1216 static LONGEST
1217 inf_ttrace_xfer_partial (struct target_ops *ops, enum target_object object,
1218 const char *annex, gdb_byte *readbuf,
1219 const gdb_byte *writebuf,
1220 ULONGEST offset, LONGEST len)
1222 switch (object)
1224 case TARGET_OBJECT_MEMORY:
1225 return inf_ttrace_xfer_memory (offset, len, readbuf, writebuf);
1227 case TARGET_OBJECT_UNWIND_TABLE:
1228 return -1;
1230 case TARGET_OBJECT_AUXV:
1231 return -1;
1233 case TARGET_OBJECT_WCOOKIE:
1234 return -1;
1236 default:
1237 return -1;
1241 /* Print status information about what we're accessing. */
1243 static void
1244 inf_ttrace_files_info (struct target_ops *ignore)
1246 struct inferior *inf = current_inferior ();
1247 printf_filtered (_("\tUsing the running image of %s %s.\n"),
1248 inf->attach_flag ? "attached" : "child",
1249 target_pid_to_str (inferior_ptid));
1252 static int
1253 inf_ttrace_thread_alive (struct target_ops *ops, ptid_t ptid)
1255 return 1;
1258 /* Return a string describing the state of the thread specified by
1259 INFO. */
1261 static char *
1262 inf_ttrace_extra_thread_info (struct thread_info *info)
1264 struct inf_ttrace_private_thread_info* private =
1265 (struct inf_ttrace_private_thread_info *) info->private;
1267 if (private != NULL && private->dying)
1268 return "Exiting";
1270 return NULL;
1273 static char *
1274 inf_ttrace_pid_to_str (struct target_ops *ops, ptid_t ptid)
1276 pid_t pid = ptid_get_pid (ptid);
1277 lwpid_t lwpid = ptid_get_lwp (ptid);
1278 static char buf[128];
1280 if (lwpid == 0)
1281 xsnprintf (buf, sizeof buf, "process %ld",
1282 (long) pid);
1283 else
1284 xsnprintf (buf, sizeof buf, "process %ld, lwp %ld",
1285 (long) pid, (long) lwpid);
1286 return buf;
1290 /* Implement the get_ada_task_ptid target_ops method. */
1292 static ptid_t
1293 inf_ttrace_get_ada_task_ptid (long lwp, long thread)
1295 return ptid_build (ptid_get_pid (inferior_ptid), lwp, 0);
1299 struct target_ops *
1300 inf_ttrace_target (void)
1302 struct target_ops *t = inf_child_target ();
1304 t->to_attach = inf_ttrace_attach;
1305 t->to_detach = inf_ttrace_detach;
1306 t->to_resume = inf_ttrace_resume;
1307 t->to_wait = inf_ttrace_wait;
1308 t->to_files_info = inf_ttrace_files_info;
1309 t->to_can_use_hw_breakpoint = inf_ttrace_can_use_hw_breakpoint;
1310 t->to_insert_watchpoint = inf_ttrace_insert_watchpoint;
1311 t->to_remove_watchpoint = inf_ttrace_remove_watchpoint;
1312 t->to_stopped_by_watchpoint = inf_ttrace_stopped_by_watchpoint;
1313 t->to_region_ok_for_hw_watchpoint =
1314 inf_ttrace_region_ok_for_hw_watchpoint;
1315 t->to_kill = inf_ttrace_kill;
1316 t->to_create_inferior = inf_ttrace_create_inferior;
1317 t->to_follow_fork = inf_ttrace_follow_fork;
1318 t->to_mourn_inferior = inf_ttrace_mourn_inferior;
1319 t->to_thread_alive = inf_ttrace_thread_alive;
1320 t->to_extra_thread_info = inf_ttrace_extra_thread_info;
1321 t->to_pid_to_str = inf_ttrace_pid_to_str;
1322 t->to_xfer_partial = inf_ttrace_xfer_partial;
1323 t->to_get_ada_task_ptid = inf_ttrace_get_ada_task_ptid;
1325 return t;
1327 #endif
1330 /* Prevent warning from -Wmissing-prototypes. */
1331 void _initialize_inf_ttrace (void);
1333 void
1334 _initialize_inf_ttrace (void)
1336 #ifdef HAVE_TTRACE
1337 inf_ttrace_page_dict.pagesize = getpagesize();
1338 #endif