* ada-lang.c (static_unwrap_type): Add forward declaration.
[platform/upstream/binutils.git] / gdb / inf-ttrace.c
1 /* Low-level child interface to ttrace.
2
3    Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
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.
11
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.
16
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/>.  */
19
20 #include "defs.h"
21
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
25
26 #include "command.h"
27 #include "gdbcore.h"
28 #include "gdbthread.h"
29 #include "inferior.h"
30 #include "target.h"
31
32 #include "gdb_assert.h"
33 #include "gdb_string.h"
34 #include <sys/mman.h>
35 #include <sys/ttrace.h>
36
37 #include "inf-child.h"
38 #include "inf-ttrace.h"
39
40 /* HACK: Save the ttrace ops returned by inf_ttrace_target.  */
41 static struct target_ops *ttrace_ops_hack;
42 \f
43
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.  */
52
53 /* Number of active lwps.  */
54 static int inf_ttrace_num_lwps;
55 \f
56
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.  */
62
63 struct inf_ttrace_page
64 {
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;
70 };
71
72 struct inf_ttrace_page_dict
73 {
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;
78
79 struct inf_ttrace_private_thread_info
80 {
81   int dying;
82 };
83
84 /* Number of lwps that are currently in a system call.  */
85 static int inf_ttrace_num_lwps_in_syscall;
86
87 /* Flag to indicate whether we should re-enable page protections after
88    the next wait.  */
89 static int inf_ttrace_reenable_page_protections;
90
91 /* Enable system call events for process PID.  */
92
93 static void
94 inf_ttrace_enable_syscall_events (pid_t pid)
95 {
96   ttevent_t tte;
97   ttstate_t tts;
98
99   gdb_assert (inf_ttrace_num_lwps_in_syscall == 0);
100
101   if (ttrace (TT_PROC_GET_EVENT_MASK, pid, 0,
102               (uintptr_t)&tte, sizeof tte, 0) == -1)
103     perror_with_name (("ttrace"));
104
105   tte.tte_events |= (TTEVT_SYSCALL_ENTRY | TTEVT_SYSCALL_RETURN);
106
107   if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0,
108               (uintptr_t)&tte, sizeof tte, 0) == -1)
109     perror_with_name (("ttrace"));
110
111   if (ttrace (TT_PROC_GET_FIRST_LWP_STATE, pid, 0,
112               (uintptr_t)&tts, sizeof tts, 0) == -1)
113     perror_with_name (("ttrace"));
114
115   if (tts.tts_flags & TTS_INSYSCALL)
116     inf_ttrace_num_lwps_in_syscall++;
117
118   /* FIXME: Handle multiple threads.  */
119 }
120
121 /* Disable system call events for process PID.  */
122
123 static void
124 inf_ttrace_disable_syscall_events (pid_t pid)
125 {
126   ttevent_t tte;
127
128   gdb_assert (inf_ttrace_page_dict.count == 0);
129
130   if (ttrace (TT_PROC_GET_EVENT_MASK, pid, 0,
131               (uintptr_t)&tte, sizeof tte, 0) == -1)
132     perror_with_name (("ttrace"));
133
134   tte.tte_events &= ~(TTEVT_SYSCALL_ENTRY | TTEVT_SYSCALL_RETURN);
135
136   if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0,
137               (uintptr_t)&tte, sizeof tte, 0) == -1)
138     perror_with_name (("ttrace"));
139
140   inf_ttrace_num_lwps_in_syscall = 0;
141 }
142
143 /* Get information about the page at address ADDR for process PID from
144    the dictionary.  */
145
146 static struct inf_ttrace_page *
147 inf_ttrace_get_page (pid_t pid, CORE_ADDR addr)
148 {
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;
153
154   bucket = (addr / pagesize) % num_buckets;
155   page = &inf_ttrace_page_dict.buckets[bucket];
156   while (page)
157     {
158       if (page->addr == addr)
159         break;
160
161       page = page->next;
162     }
163
164   return page;
165 }
166
167 /* Add the page at address ADDR for process PID to the dictionary.  */
168
169 static struct inf_ttrace_page *
170 inf_ttrace_add_page (pid_t pid, CORE_ADDR addr)
171 {
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;
177
178   bucket = (addr / pagesize) % num_buckets;
179   page = &inf_ttrace_page_dict.buckets[bucket];
180   while (page)
181     {
182       if (page->addr == addr)
183         break;
184
185       prev = page;
186       page = page->next;
187     }
188   
189   if (!page)
190     {
191       int prot;
192
193       if (ttrace (TT_PROC_GET_MPROTECT, pid, 0,
194                   addr, 0, (uintptr_t)&prot) == -1)
195         perror_with_name (("ttrace"));
196       
197       page = XMALLOC (struct inf_ttrace_page);
198       page->addr = addr;
199       page->prot = prot;
200       page->refcount = 0;
201       page->next = NULL;
202
203       page->prev = prev;
204       prev->next = page;
205
206       inf_ttrace_page_dict.count++;
207       if (inf_ttrace_page_dict.count == 1)
208         inf_ttrace_enable_syscall_events (pid);
209
210       if (inf_ttrace_num_lwps_in_syscall == 0)
211         {
212           if (ttrace (TT_PROC_SET_MPROTECT, pid, 0,
213                       addr, pagesize, prot & ~PROT_WRITE) == -1)
214             perror_with_name (("ttrace"));
215         }
216     }
217
218   return page;
219 }
220
221 /* Insert the page at address ADDR of process PID to the dictionary.  */
222
223 static void
224 inf_ttrace_insert_page (pid_t pid, CORE_ADDR addr)
225 {
226   struct inf_ttrace_page *page;
227
228   page = inf_ttrace_get_page (pid, addr);
229   if (!page)
230     page = inf_ttrace_add_page (pid, addr);
231
232   page->refcount++;
233 }
234
235 /* Remove the page at address ADDR of process PID from the dictionary.  */
236
237 static void
238 inf_ttrace_remove_page (pid_t pid, CORE_ADDR addr)
239 {
240   const int pagesize = inf_ttrace_page_dict.pagesize;
241   struct inf_ttrace_page *page;
242
243   page = inf_ttrace_get_page (pid, addr);
244   page->refcount--;
245
246   gdb_assert (page->refcount >= 0);
247
248   if (page->refcount == 0)
249     {
250       if (inf_ttrace_num_lwps_in_syscall == 0)
251         {
252           if (ttrace (TT_PROC_SET_MPROTECT, pid, 0,
253                       addr, pagesize, page->prot) == -1)
254             perror_with_name (("ttrace"));
255         }
256
257       inf_ttrace_page_dict.count--;
258       if (inf_ttrace_page_dict.count == 0)
259         inf_ttrace_disable_syscall_events (pid);
260
261       page->prev->next = page->next;
262       if (page->next)
263         page->next->prev = page->prev;
264
265       xfree (page);
266     }
267 }
268
269 /* Mask the bits in PROT from the page protections that are currently
270    in the dictionary for process PID.  */
271
272 static void
273 inf_ttrace_mask_page_protections (pid_t pid, int prot)
274 {
275   const int num_buckets = ARRAY_SIZE (inf_ttrace_page_dict.buckets);
276   const int pagesize = inf_ttrace_page_dict.pagesize;
277   int bucket;
278
279   for (bucket = 0; bucket < num_buckets; bucket++)
280     {
281       struct inf_ttrace_page *page;
282
283       page = inf_ttrace_page_dict.buckets[bucket].next;
284       while (page)
285         {
286           if (ttrace (TT_PROC_SET_MPROTECT, pid, 0,
287                       page->addr, pagesize, page->prot & ~prot) == -1)
288             perror_with_name (("ttrace"));
289
290           page = page->next;
291         }
292     }
293 }
294
295 /* Write-protect the pages in the dictionary for process PID.  */
296
297 static void
298 inf_ttrace_enable_page_protections (pid_t pid)
299 {
300   inf_ttrace_mask_page_protections (pid, PROT_WRITE);
301 }
302
303 /* Restore the protection of the pages in the dictionary for process
304    PID.  */
305
306 static void
307 inf_ttrace_disable_page_protections (pid_t pid)
308 {
309   inf_ttrace_mask_page_protections (pid, 0);
310 }
311
312 /* Insert a "hardware" watchpoint for LEN bytes at address ADDR of
313    type TYPE.  */
314
315 static int
316 inf_ttrace_insert_watchpoint (CORE_ADDR addr, int len, int type)
317 {
318   const int pagesize = inf_ttrace_page_dict.pagesize;
319   pid_t pid = ptid_get_pid (inferior_ptid);
320   CORE_ADDR page_addr;
321   int num_pages;
322   int page;
323
324   gdb_assert (type == hw_write);
325
326   page_addr = (addr / pagesize) * pagesize;
327   num_pages = (len + pagesize - 1) / pagesize;
328
329   for (page = 0; page < num_pages; page++, page_addr += pagesize)
330     inf_ttrace_insert_page (pid, page_addr);
331
332   return 1;
333 }
334
335 /* Remove a "hardware" watchpoint for LEN bytes at address ADDR of
336    type TYPE.  */
337
338 static int
339 inf_ttrace_remove_watchpoint (CORE_ADDR addr, int len, int type)
340 {
341   const int pagesize = inf_ttrace_page_dict.pagesize;
342   pid_t pid = ptid_get_pid (inferior_ptid);
343   CORE_ADDR page_addr;
344   int num_pages;
345   int page;
346
347   gdb_assert (type == hw_write);
348
349   page_addr = (addr / pagesize) * pagesize;
350   num_pages = (len + pagesize - 1) / pagesize;
351
352   for (page = 0; page < num_pages; page++, page_addr += pagesize)
353     inf_ttrace_remove_page (pid, page_addr);
354
355   return 1;
356 }
357
358 static int
359 inf_ttrace_can_use_hw_breakpoint (int type, int len, int ot)
360 {
361   return (type == bp_hardware_watchpoint);
362 }
363
364 static int
365 inf_ttrace_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
366 {
367   return 1;
368 }
369
370 /* Return non-zero if the current inferior was (potentially) stopped
371    by hitting a "hardware" watchpoint.  */
372
373 static int
374 inf_ttrace_stopped_by_watchpoint (void)
375 {
376   pid_t pid = ptid_get_pid (inferior_ptid);
377   lwpid_t lwpid = ptid_get_lwp (inferior_ptid);
378   ttstate_t tts;
379
380   if (inf_ttrace_page_dict.count > 0)
381     {
382       if (ttrace (TT_LWP_GET_STATE, pid, lwpid,
383                   (uintptr_t)&tts, sizeof tts, 0) == -1)
384         perror_with_name (("ttrace"));
385
386       if (tts.tts_event == TTEVT_SIGNAL
387           && tts.tts_u.tts_signal.tts_signo == SIGBUS)
388         {
389           const int pagesize = inf_ttrace_page_dict.pagesize;
390           void *addr = tts.tts_u.tts_signal.tts_siginfo.si_addr;
391           CORE_ADDR page_addr = ((uintptr_t)addr / pagesize) * pagesize;
392
393           if (inf_ttrace_get_page (pid, page_addr))
394             return 1;
395         }
396     }
397
398   return 0;
399 }
400 \f
401
402 /* When tracking a vfork(2), we cannot detach from the parent until
403    after the child has called exec(3) or has exited.  If we are still
404    attached to the parent, this variable will be set to the process ID
405    of the parent.  Otherwise it will be set to zero.  */
406 static pid_t inf_ttrace_vfork_ppid = -1;
407
408 static int
409 inf_ttrace_follow_fork (struct target_ops *ops, int follow_child)
410 {
411   pid_t pid, fpid;
412   lwpid_t lwpid, flwpid;
413   ttstate_t tts;
414
415   /* FIXME: kettenis/20050720: This stuff should really be passed as
416      an argument by our caller.  */
417   {
418     ptid_t ptid;
419     struct target_waitstatus status;
420
421     get_last_target_status (&ptid, &status);
422     gdb_assert (status.kind == TARGET_WAITKIND_FORKED
423                 || status.kind == TARGET_WAITKIND_VFORKED);
424
425     pid = ptid_get_pid (ptid);
426     lwpid = ptid_get_lwp (ptid);
427   }
428
429   /* Get all important details that core GDB doesn't (and shouldn't)
430      know about.  */
431   if (ttrace (TT_LWP_GET_STATE, pid, lwpid,
432               (uintptr_t)&tts, sizeof tts, 0) == -1)
433     perror_with_name (("ttrace"));
434
435   gdb_assert (tts.tts_event == TTEVT_FORK || tts.tts_event == TTEVT_VFORK);
436
437   if (tts.tts_u.tts_fork.tts_isparent)
438     {
439       pid = tts.tts_pid;
440       lwpid = tts.tts_lwpid;
441       fpid = tts.tts_u.tts_fork.tts_fpid;
442       flwpid = tts.tts_u.tts_fork.tts_flwpid;
443     }
444   else
445     {
446       pid = tts.tts_u.tts_fork.tts_fpid;
447       lwpid = tts.tts_u.tts_fork.tts_flwpid;
448       fpid = tts.tts_pid;
449       flwpid = tts.tts_lwpid;
450     }
451
452   if (follow_child)
453     {
454       inferior_ptid = ptid_build (fpid, flwpid, 0);
455       detach_breakpoints (pid);
456
457       target_terminal_ours ();
458       fprintf_unfiltered (gdb_stdlog, _("\
459 Attaching after fork to child process %ld.\n"), (long)fpid);
460     }
461   else
462     {
463       inferior_ptid = ptid_build (pid, lwpid, 0);
464       detach_breakpoints (fpid);
465
466       target_terminal_ours ();
467       fprintf_unfiltered (gdb_stdlog, _("\
468 Detaching after fork from child process %ld.\n"), (long)fpid);
469     }
470
471   if (tts.tts_event == TTEVT_VFORK)
472     {
473       gdb_assert (!tts.tts_u.tts_fork.tts_isparent);
474
475       if (follow_child)
476         {
477           /* We can't detach from the parent yet.  */
478           inf_ttrace_vfork_ppid = pid;
479
480           reattach_breakpoints (fpid);
481         }
482       else
483         {
484           if (ttrace (TT_PROC_DETACH, fpid, 0, 0, 0, 0) == -1)
485             perror_with_name (("ttrace"));
486
487           /* Wait till we get the TTEVT_VFORK event in the parent.
488              This indicates that the child has called exec(3) or has
489              exited and that the parent is ready to be traced again.  */
490           if (ttrace_wait (pid, lwpid, TTRACE_WAITOK, &tts, sizeof tts) == -1)
491             perror_with_name (("ttrace_wait"));
492           gdb_assert (tts.tts_event == TTEVT_VFORK);
493           gdb_assert (tts.tts_u.tts_fork.tts_isparent);
494
495           reattach_breakpoints (pid);
496         }
497     }
498   else
499     {
500       gdb_assert (tts.tts_u.tts_fork.tts_isparent);
501
502       if (follow_child)
503         {
504           if (ttrace (TT_PROC_DETACH, pid, 0, 0, 0, 0) == -1)
505             perror_with_name (("ttrace"));
506         }
507       else
508         {
509           if (ttrace (TT_PROC_DETACH, fpid, 0, 0, 0, 0) == -1)
510             perror_with_name (("ttrace"));
511         }
512     }
513
514   if (follow_child)
515     {
516       /* The child will start out single-threaded.  */
517       inf_ttrace_num_lwps = 0;
518       inf_ttrace_num_lwps_in_syscall = 0;
519
520       /* Reset breakpoints in the child as appropriate.  */
521       follow_inferior_reset_breakpoints ();
522     }
523
524   return 0;
525 }
526 \f
527
528 /* File descriptors for pipes used as semaphores during initial
529    startup of an inferior.  */
530 static int inf_ttrace_pfd1[2];
531 static int inf_ttrace_pfd2[2];
532
533 static void
534 do_cleanup_pfds (void *dummy)
535 {
536   close (inf_ttrace_pfd1[0]);
537   close (inf_ttrace_pfd1[1]);
538   close (inf_ttrace_pfd2[0]);
539   close (inf_ttrace_pfd2[1]);
540 }
541
542 static void
543 inf_ttrace_prepare (void)
544 {
545   if (pipe (inf_ttrace_pfd1) == -1)
546     perror_with_name (("pipe"));
547
548   if (pipe (inf_ttrace_pfd2) == -1)
549     {
550       close (inf_ttrace_pfd1[0]);
551       close (inf_ttrace_pfd2[0]);
552       perror_with_name (("pipe"));
553     }
554 }
555
556 /* Prepare to be traced.  */
557
558 static void
559 inf_ttrace_me (void)
560 {
561   struct cleanup *old_chain = make_cleanup (do_cleanup_pfds, 0);
562   char c;
563
564   /* "Trace me, Dr. Memory!"  */
565   if (ttrace (TT_PROC_SETTRC, 0, 0, 0, TT_VERSION, 0) == -1)
566     perror_with_name (("ttrace"));
567
568   /* Tell our parent that we are ready to be traced.  */
569   if (write (inf_ttrace_pfd1[1], &c, sizeof c) != sizeof c)
570     perror_with_name (("write"));
571
572   /* Wait until our parent has set the initial event mask.  */
573   if (read (inf_ttrace_pfd2[0], &c, sizeof c) != sizeof c)
574     perror_with_name (("read"));
575
576   do_cleanups (old_chain);
577 }
578
579 /* Start tracing PID.  */
580
581 static void
582 inf_ttrace_him (int pid)
583 {
584   struct cleanup *old_chain = make_cleanup (do_cleanup_pfds, 0);
585   ttevent_t tte;
586   char c;
587
588   /* Wait until our child is ready to be traced.  */
589   if (read (inf_ttrace_pfd1[0], &c, sizeof c) != sizeof c)
590     perror_with_name (("read"));
591
592   /* Set the initial event mask.  */
593   memset (&tte, 0, sizeof (tte));
594   tte.tte_events |= TTEVT_EXEC | TTEVT_EXIT | TTEVT_FORK | TTEVT_VFORK;
595   tte.tte_events |= TTEVT_LWP_CREATE | TTEVT_LWP_EXIT | TTEVT_LWP_TERMINATE;
596 #ifdef TTEVT_BPT_SSTEP
597   tte.tte_events |= TTEVT_BPT_SSTEP;
598 #endif
599   tte.tte_opts |= TTEO_PROC_INHERIT;
600   if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0,
601               (uintptr_t)&tte, sizeof tte, 0) == -1)
602     perror_with_name (("ttrace"));
603
604   /* Tell our child that we have set the initial event mask.  */
605   if (write (inf_ttrace_pfd2[1], &c, sizeof c) != sizeof c)
606     perror_with_name (("write"));
607
608   do_cleanups (old_chain);
609
610   push_target (ttrace_ops_hack);
611
612   /* On some targets, there must be some explicit synchronization
613      between the parent and child processes after the debugger forks,
614      and before the child execs the debuggee program.  This call
615      basically gives permission for the child to exec.  */
616
617   target_acknowledge_created_inferior (pid);
618
619   /* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h, and will
620      be 1 or 2 depending on whether we're starting without or with a
621      shell.  */
622   startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
623
624   /* On some targets, there must be some explicit actions taken after
625      the inferior has been started up.  */
626   target_post_startup_inferior (pid_to_ptid (pid));
627 }
628
629 static void
630 inf_ttrace_create_inferior (char *exec_file, char *allargs, char **env,
631                             int from_tty)
632 {
633   gdb_assert (inf_ttrace_num_lwps == 0);
634   gdb_assert (inf_ttrace_num_lwps_in_syscall == 0);
635   gdb_assert (inf_ttrace_page_dict.count == 0);
636   gdb_assert (inf_ttrace_reenable_page_protections == 0);
637   gdb_assert (inf_ttrace_vfork_ppid == -1);
638
639   fork_inferior (exec_file, allargs, env, inf_ttrace_me, inf_ttrace_him,
640                  inf_ttrace_prepare, NULL);
641 }
642
643 static void
644 inf_ttrace_mourn_inferior (void)
645 {
646   const int num_buckets = ARRAY_SIZE (inf_ttrace_page_dict.buckets);
647   int bucket;
648
649   inf_ttrace_num_lwps = 0;
650   inf_ttrace_num_lwps_in_syscall = 0;
651
652   for (bucket = 0; bucket < num_buckets; bucket++)
653     {
654       struct inf_ttrace_page *page;
655       struct inf_ttrace_page *next;
656
657       page = inf_ttrace_page_dict.buckets[bucket].next;
658       while (page)
659         {
660           next = page->next;
661           xfree (page);
662           page = next;
663         }
664     }
665   inf_ttrace_page_dict.count = 0;
666
667   unpush_target (ttrace_ops_hack);
668   generic_mourn_inferior ();
669 }
670
671 static void
672 inf_ttrace_attach (char *args, int from_tty)
673 {
674   char *exec_file;
675   pid_t pid;
676   char *dummy;
677   ttevent_t tte;
678
679   if (!args)
680     error_no_arg (_("process-id to attach"));
681
682   dummy = args;
683   pid = strtol (args, &dummy, 0);
684   if (pid == 0 && args == dummy)
685     error (_("Illegal process-id: %s."), args);
686
687   if (pid == getpid ())         /* Trying to masturbate?  */
688     error (_("I refuse to debug myself!"));
689
690   if (from_tty)
691     {
692       exec_file = get_exec_file (0);
693
694       if (exec_file)
695         printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file,
696                            target_pid_to_str (pid_to_ptid (pid)));
697       else
698         printf_unfiltered (_("Attaching to %s\n"),
699                            target_pid_to_str (pid_to_ptid (pid)));
700
701       gdb_flush (gdb_stdout);
702     }
703
704   gdb_assert (inf_ttrace_num_lwps == 0);
705   gdb_assert (inf_ttrace_num_lwps_in_syscall == 0);
706   gdb_assert (inf_ttrace_vfork_ppid == -1);
707
708   if (ttrace (TT_PROC_ATTACH, pid, 0, TT_KILL_ON_EXIT, TT_VERSION, 0) == -1)
709     perror_with_name (("ttrace"));
710   attach_flag = 1;
711
712   /* Set the initial event mask.  */
713   memset (&tte, 0, sizeof (tte));
714   tte.tte_events |= TTEVT_EXEC | TTEVT_EXIT | TTEVT_FORK | TTEVT_VFORK;
715   tte.tte_events |= TTEVT_LWP_CREATE | TTEVT_LWP_EXIT | TTEVT_LWP_TERMINATE;
716 #ifdef TTEVT_BPT_SSTEP
717   tte.tte_events |= TTEVT_BPT_SSTEP;
718 #endif
719   tte.tte_opts |= TTEO_PROC_INHERIT;
720   if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0,
721               (uintptr_t)&tte, sizeof tte, 0) == -1)
722     perror_with_name (("ttrace"));
723
724   inferior_ptid = pid_to_ptid (pid);
725   push_target (ttrace_ops_hack);
726 }
727
728 static void
729 inf_ttrace_detach (char *args, int from_tty)
730 {
731   pid_t pid = ptid_get_pid (inferior_ptid);
732   int sig = 0;
733
734   if (from_tty)
735     {
736       char *exec_file = get_exec_file (0);
737       if (exec_file == 0)
738         exec_file = "";
739       printf_unfiltered (_("Detaching from program: %s, %s\n"), exec_file,
740                          target_pid_to_str (pid_to_ptid (pid)));
741       gdb_flush (gdb_stdout);
742     }
743   if (args)
744     sig = atoi (args);
745
746   /* ??? The HP-UX 11.0 ttrace(2) manual page doesn't mention that we
747      can pass a signal number here.  Does this really work?  */
748   if (ttrace (TT_PROC_DETACH, pid, 0, 0, sig, 0) == -1)
749     perror_with_name (("ttrace"));
750
751   if (inf_ttrace_vfork_ppid != -1)
752     {
753       if (ttrace (TT_PROC_DETACH, inf_ttrace_vfork_ppid, 0, 0, 0, 0) == -1)
754         perror_with_name (("ttrace"));
755       inf_ttrace_vfork_ppid = -1;
756     }
757
758   inf_ttrace_num_lwps = 0;
759   inf_ttrace_num_lwps_in_syscall = 0;
760
761   unpush_target (ttrace_ops_hack);
762   inferior_ptid = null_ptid;
763 }
764
765 static void
766 inf_ttrace_kill (void)
767 {
768   pid_t pid = ptid_get_pid (inferior_ptid);
769
770   if (pid == 0)
771     return;
772
773   if (ttrace (TT_PROC_EXIT, pid, 0, 0, 0, 0) == -1)
774     perror_with_name (("ttrace"));
775   /* ??? Is it necessary to call ttrace_wait() here?  */
776
777   if (inf_ttrace_vfork_ppid != -1)
778     {
779       if (ttrace (TT_PROC_DETACH, inf_ttrace_vfork_ppid, 0, 0, 0, 0) == -1)
780         perror_with_name (("ttrace"));
781       inf_ttrace_vfork_ppid = -1;
782     }
783
784   target_mourn_inferior ();
785 }
786
787 static int
788 inf_ttrace_resume_callback (struct thread_info *info, void *arg)
789 {
790   if (!ptid_equal (info->ptid, inferior_ptid))
791     {
792       pid_t pid = ptid_get_pid (info->ptid);
793       lwpid_t lwpid = ptid_get_lwp (info->ptid);
794
795       if (ttrace (TT_LWP_CONTINUE, pid, lwpid, TT_NOPC, 0, 0) == -1)
796         perror_with_name (("ttrace"));
797     }
798
799   return 0;
800 }
801
802 static int
803 inf_ttrace_delete_dying_threads_callback (struct thread_info *info, void *arg)
804 {
805   if (((struct inf_ttrace_private_thread_info *)info->private)->dying == 1)
806     delete_thread (info->ptid);
807   return 0;
808 }
809
810 static void
811 inf_ttrace_resume (ptid_t ptid, int step, enum target_signal signal)
812 {
813   pid_t pid = ptid_get_pid (ptid);
814   lwpid_t lwpid = ptid_get_lwp (ptid);
815   ttreq_t request = step ? TT_LWP_SINGLE : TT_LWP_CONTINUE;
816   int sig = target_signal_to_host (signal);
817
818   if (pid == -1)
819     {
820       pid = ptid_get_pid (inferior_ptid);
821       lwpid = ptid_get_lwp (inferior_ptid);
822     }
823
824   if (ttrace (request, pid, lwpid, TT_NOPC, sig, 0) == -1)
825     perror_with_name (("ttrace"));
826
827   if (ptid_equal (ptid, minus_one_ptid) && inf_ttrace_num_lwps > 0)
828     {
829       /* Let all the other threads run too.  */
830       iterate_over_threads (inf_ttrace_resume_callback, NULL);
831       iterate_over_threads (inf_ttrace_delete_dying_threads_callback, NULL);
832     }
833 }
834
835 static ptid_t
836 inf_ttrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
837 {
838   pid_t pid = ptid_get_pid (ptid);
839   lwpid_t lwpid = ptid_get_lwp (ptid);
840   ttstate_t tts;
841   struct thread_info *ti;
842
843   /* Until proven otherwise.  */
844   ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
845
846   if (pid == -1)
847     pid = lwpid = 0;
848
849   gdb_assert (pid != 0 || lwpid == 0);
850
851   do
852     {
853       set_sigint_trap ();
854       set_sigio_trap ();
855
856       if (ttrace_wait (pid, lwpid, TTRACE_WAITOK, &tts, sizeof tts) == -1)
857         perror_with_name (("ttrace_wait"));
858
859       if (tts.tts_event == TTEVT_VFORK && tts.tts_u.tts_fork.tts_isparent)
860         {
861           if (inf_ttrace_vfork_ppid != -1)
862             {
863               gdb_assert (inf_ttrace_vfork_ppid == tts.tts_pid);
864
865               if (ttrace (TT_PROC_DETACH, tts.tts_pid, 0, 0, 0, 0) == -1)
866                 perror_with_name (("ttrace"));
867               inf_ttrace_vfork_ppid = -1;
868             }
869
870           tts.tts_event = TTEVT_NONE;
871         }
872
873       clear_sigio_trap ();
874       clear_sigint_trap ();
875     }
876   while (tts.tts_event == TTEVT_NONE);
877
878   /* Now that we've waited, we can re-enable the page protections.  */
879   if (inf_ttrace_reenable_page_protections)
880     {
881       gdb_assert (inf_ttrace_num_lwps_in_syscall == 0);
882       inf_ttrace_enable_page_protections (tts.tts_pid);
883       inf_ttrace_reenable_page_protections = 0;
884     }
885
886   ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0);
887
888   switch (tts.tts_event)
889     {
890 #ifdef TTEVT_BPT_SSTEP
891     case TTEVT_BPT_SSTEP:
892       /* Make it look like a breakpoint.  */
893       ourstatus->kind = TARGET_WAITKIND_STOPPED;
894       ourstatus->value.sig = TARGET_SIGNAL_TRAP;
895       break;
896 #endif
897
898     case TTEVT_EXEC:
899       /* FIXME: kettenis/20051029: GDB doesn't really know how to deal
900          with TARGET_WAITKIND_EXECD events yet.  So we make it look
901          like a SIGTRAP instead.  */
902 #if 0
903       ourstatus->kind = TARGET_WAITKIND_EXECD;
904       ourstatus->value.execd_pathname =
905         xmalloc (tts.tts_u.tts_exec.tts_pathlen + 1);
906       if (ttrace (TT_PROC_GET_PATHNAME, tts.tts_pid, 0,
907                   (uintptr_t)ourstatus->value.execd_pathname,
908                   tts.tts_u.tts_exec.tts_pathlen, 0) == -1)
909         perror_with_name (("ttrace"));
910       ourstatus->value.execd_pathname[tts.tts_u.tts_exec.tts_pathlen] = 0;
911 #else
912       ourstatus->kind = TARGET_WAITKIND_STOPPED;
913       ourstatus->value.sig = TARGET_SIGNAL_TRAP;
914 #endif
915       break;
916
917     case TTEVT_EXIT:
918       store_waitstatus (ourstatus, tts.tts_u.tts_exit.tts_exitcode);
919       inf_ttrace_num_lwps = 0;
920       break;
921
922     case TTEVT_FORK:
923       ourstatus->kind = TARGET_WAITKIND_FORKED;
924       ourstatus->value.related_pid = tts.tts_u.tts_fork.tts_fpid;
925
926       /* Make sure the other end of the fork is stopped too.  */
927       if (ttrace_wait (tts.tts_u.tts_fork.tts_fpid,
928                        tts.tts_u.tts_fork.tts_flwpid,
929                        TTRACE_WAITOK, &tts, sizeof tts) == -1)
930         perror_with_name (("ttrace_wait"));
931
932       gdb_assert (tts.tts_event == TTEVT_FORK);
933       if (tts.tts_u.tts_fork.tts_isparent)
934         {
935           ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0);
936           ourstatus->value.related_pid = tts.tts_u.tts_fork.tts_fpid;
937         }
938       break;
939
940     case TTEVT_VFORK:
941       gdb_assert (!tts.tts_u.tts_fork.tts_isparent);
942
943       ourstatus->kind = TARGET_WAITKIND_VFORKED;
944       ourstatus->value.related_pid = tts.tts_u.tts_fork.tts_fpid;
945
946       /* HACK: To avoid touching the parent during the vfork, switch
947          away from it.  */
948       inferior_ptid = ptid;
949       break;
950
951     case TTEVT_LWP_CREATE:
952       lwpid = tts.tts_u.tts_thread.tts_target_lwpid;
953       ptid = ptid_build (tts.tts_pid, lwpid, 0);
954       if (inf_ttrace_num_lwps == 0)
955         {
956           /* Now that we're going to be multi-threaded, add the
957              original thread to the list first.  */
958           ti = add_thread (ptid_build (tts.tts_pid, tts.tts_lwpid, 0));
959           ti->private =
960             xmalloc (sizeof (struct inf_ttrace_private_thread_info));
961           memset (ti->private, 0,
962                   sizeof (struct inf_ttrace_private_thread_info));
963           inf_ttrace_num_lwps++;
964         }
965       printf_filtered (_("[New %s]\n"), target_pid_to_str (ptid));
966       ti = add_thread (ptid);
967       ti->private =
968         xmalloc (sizeof (struct inf_ttrace_private_thread_info));
969       memset (ti->private, 0,
970               sizeof (struct inf_ttrace_private_thread_info));
971       inf_ttrace_num_lwps++;
972       ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0);
973       break;
974
975     case TTEVT_LWP_EXIT:
976       printf_filtered(_("[%s exited]\n"), target_pid_to_str (ptid));
977       ti = find_thread_pid (ptid);
978       gdb_assert (ti != NULL);
979       ((struct inf_ttrace_private_thread_info *)ti->private)->dying = 1;
980       inf_ttrace_num_lwps--;
981       ttrace (TT_LWP_CONTINUE, ptid_get_pid (ptid),
982               ptid_get_lwp (ptid), TT_NOPC, 0, 0);
983       /* If we don't return -1 here, core GDB will re-add the thread.  */
984       ptid = minus_one_ptid;
985       break;
986
987     case TTEVT_LWP_TERMINATE:
988       lwpid = tts.tts_u.tts_thread.tts_target_lwpid;
989       ptid = ptid_build (tts.tts_pid, lwpid, 0);
990       printf_filtered(_("[%s has been terminated]\n"), target_pid_to_str (ptid));
991       ti = find_thread_pid (ptid);
992       gdb_assert (ti != NULL);
993       ((struct inf_ttrace_private_thread_info *)ti->private)->dying = 1;
994       inf_ttrace_num_lwps--;
995       ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0);
996       break;
997
998     case TTEVT_SIGNAL:
999       ourstatus->kind = TARGET_WAITKIND_STOPPED;
1000       ourstatus->value.sig =
1001         target_signal_from_host (tts.tts_u.tts_signal.tts_signo);
1002       break;
1003
1004     case TTEVT_SYSCALL_ENTRY:
1005       gdb_assert (inf_ttrace_reenable_page_protections == 0);
1006       inf_ttrace_num_lwps_in_syscall++;
1007       if (inf_ttrace_num_lwps_in_syscall == 1)
1008         {
1009           /* A thread has just entered a system call.  Disable any
1010              page protections as the kernel can't deal with them.  */
1011           inf_ttrace_disable_page_protections (tts.tts_pid);
1012         }
1013       ourstatus->kind = TARGET_WAITKIND_SYSCALL_ENTRY;
1014       ourstatus->value.syscall_id = tts.tts_scno;
1015       break;
1016
1017     case TTEVT_SYSCALL_RETURN:
1018       if (inf_ttrace_num_lwps_in_syscall > 0)
1019         {
1020           /* If the last thread has just left the system call, this
1021              would be a logical place to re-enable the page
1022              protections, but that doesn't work.  We can't re-enable
1023              them until we've done another wait.  */
1024           inf_ttrace_reenable_page_protections = 
1025             (inf_ttrace_num_lwps_in_syscall == 1);
1026           inf_ttrace_num_lwps_in_syscall--;
1027         }
1028       ourstatus->kind = TARGET_WAITKIND_SYSCALL_RETURN;
1029       ourstatus->value.syscall_id = tts.tts_scno;
1030       break;
1031
1032     default:
1033       gdb_assert (!"Unexpected ttrace event");
1034       break;
1035     }
1036
1037   /* Make sure all threads within the process are stopped.  */
1038   if (ttrace (TT_PROC_STOP, tts.tts_pid, 0, 0, 0, 0) == -1)
1039     perror_with_name (("ttrace"));
1040
1041   /* HACK: Twiddle INFERIOR_PTID such that the initial thread of a
1042      process isn't recognized as a new thread.  */
1043   if (ptid_get_lwp (inferior_ptid) == 0)
1044     inferior_ptid = ptid;
1045
1046   return ptid;
1047 }
1048
1049 /* Transfer LEN bytes from ADDR in the inferior's memory into READBUF,
1050    and transfer LEN bytes from WRITEBUF into the inferior's memory at
1051    ADDR.  Either READBUF or WRITEBUF may be null, in which case the
1052    corresponding transfer doesn't happen.  Return the number of bytes
1053    actually transferred (which may be zero if an error occurs).  */
1054
1055 static LONGEST
1056 inf_ttrace_xfer_memory (CORE_ADDR addr, ULONGEST len,
1057                         void *readbuf, const void *writebuf)
1058 {
1059   pid_t pid = ptid_get_pid (inferior_ptid);
1060
1061   /* HP-UX treats text space and data space differently.  GDB however,
1062      doesn't really know the difference.  Therefore we try both.  Try
1063      text space before data space though because when we're writing
1064      into text space the instruction cache might need to be flushed.  */
1065
1066   if (readbuf
1067       && ttrace (TT_PROC_RDTEXT, pid, 0, addr, len, (uintptr_t)readbuf) == -1
1068       && ttrace (TT_PROC_RDDATA, pid, 0, addr, len, (uintptr_t)readbuf) == -1)
1069     return 0;
1070
1071   if (writebuf
1072       && ttrace (TT_PROC_WRTEXT, pid, 0, addr, len, (uintptr_t)writebuf) == -1
1073       && ttrace (TT_PROC_WRDATA, pid, 0, addr, len, (uintptr_t)writebuf) == -1)
1074     return 0;
1075
1076   return len;
1077 }
1078
1079 static LONGEST
1080 inf_ttrace_xfer_partial (struct target_ops *ops, enum target_object object,
1081                          const char *annex, gdb_byte *readbuf,
1082                          const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
1083 {
1084   switch (object)
1085     {
1086     case TARGET_OBJECT_MEMORY:
1087       return inf_ttrace_xfer_memory (offset, len, readbuf, writebuf);
1088
1089     case TARGET_OBJECT_UNWIND_TABLE:
1090       return -1;
1091
1092     case TARGET_OBJECT_AUXV:
1093       return -1;
1094
1095     case TARGET_OBJECT_WCOOKIE:
1096       return -1;
1097
1098     default:
1099       return -1;
1100     }
1101 }
1102
1103 /* Print status information about what we're accessing.  */
1104
1105 static void
1106 inf_ttrace_files_info (struct target_ops *ignore)
1107 {
1108   printf_filtered (_("\tUsing the running image of %s %s.\n"),
1109                    attach_flag ? "attached" : "child",
1110                    target_pid_to_str (inferior_ptid));
1111 }
1112
1113 static int
1114 inf_ttrace_thread_alive (ptid_t ptid)
1115 {
1116   struct thread_info *ti;
1117   ti = find_thread_pid (ptid);
1118   return !(((struct inf_ttrace_private_thread_info *)ti->private)->dying);
1119 }
1120
1121 static char *
1122 inf_ttrace_pid_to_str (ptid_t ptid)
1123 {
1124   if (inf_ttrace_num_lwps > 0)
1125     {
1126       pid_t pid = ptid_get_pid (ptid);
1127       lwpid_t lwpid = ptid_get_lwp (ptid);
1128       static char buf[128];
1129
1130       xsnprintf (buf, sizeof buf, "process %ld, lwp %ld",
1131                  (long)pid, (long)lwpid);
1132       return buf;
1133     }
1134
1135   return normal_pid_to_str (ptid);
1136 }
1137 \f
1138
1139 struct target_ops *
1140 inf_ttrace_target (void)
1141 {
1142   struct target_ops *t = inf_child_target ();
1143
1144   t->to_attach = inf_ttrace_attach;
1145   t->to_detach = inf_ttrace_detach;
1146   t->to_resume = inf_ttrace_resume;
1147   t->to_wait = inf_ttrace_wait;
1148   t->to_files_info = inf_ttrace_files_info;
1149   t->to_can_use_hw_breakpoint = inf_ttrace_can_use_hw_breakpoint;
1150   t->to_insert_watchpoint = inf_ttrace_insert_watchpoint;
1151   t->to_remove_watchpoint = inf_ttrace_remove_watchpoint;
1152   t->to_stopped_by_watchpoint = inf_ttrace_stopped_by_watchpoint;
1153   t->to_region_ok_for_hw_watchpoint =
1154     inf_ttrace_region_ok_for_hw_watchpoint;
1155   t->to_kill = inf_ttrace_kill;
1156   t->to_create_inferior = inf_ttrace_create_inferior;
1157   t->to_follow_fork = inf_ttrace_follow_fork;
1158   t->to_mourn_inferior = inf_ttrace_mourn_inferior;
1159   t->to_thread_alive = inf_ttrace_thread_alive;
1160   t->to_pid_to_str = inf_ttrace_pid_to_str;
1161   t->to_xfer_partial = inf_ttrace_xfer_partial;
1162
1163   ttrace_ops_hack = t;
1164   return t;
1165 }
1166 #endif
1167 \f
1168
1169 /* Prevent warning from -Wmissing-prototypes.  */
1170 void _initialize_hppa_hpux_nat (void);
1171
1172 void
1173 _initialize_inf_ttrace (void)
1174 {
1175 #ifdef HAVE_TTRACE
1176   inf_ttrace_page_dict.pagesize = getpagesize();
1177 #endif
1178 }