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