]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/inf-ttrace.c
C++ keyword cleanliness, mostly auto-generated
[thirdparty/binutils-gdb.git] / gdb / inf-ttrace.c
1 /* Low-level child interface to ttrace.
2
3 Copyright (C) 2004-2015 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 "terminal.h"
31 #include "target.h"
32 #include <sys/mman.h>
33 #include <sys/ttrace.h>
34 #include <signal.h>
35
36 #include "inf-child.h"
37 #include "inf-ttrace.h"
38 #include "common/filestuff.h"
39
40 \f
41
42 /* HP-UX uses a threading model where each user-space thread
43 corresponds to a kernel thread. These kernel threads are called
44 lwps. The ttrace(2) interface gives us almost full control over
45 the threads, which makes it very easy to support them in GDB. We
46 identify the threads by process ID and lwp ID. The ttrace(2) also
47 provides us with a thread's user ID (in the `tts_user_tid' member
48 of `ttstate_t') but we don't use that (yet) as it isn't necessary
49 to uniquely label the thread. */
50
51 /* Number of active lwps. */
52 static int inf_ttrace_num_lwps;
53 \f
54
55 /* On HP-UX versions that have the ttrace(2) system call, we can
56 implement "hardware" watchpoints by fiddling with the protection of
57 pages in the address space that contain the variable being watched.
58 In order to implement this, we keep a dictionary of pages for which
59 we have changed the protection. */
60
61 struct inf_ttrace_page
62 {
63 CORE_ADDR addr; /* Page address. */
64 int prot; /* Protection. */
65 int refcount; /* Reference count. */
66 struct inf_ttrace_page *next;
67 struct inf_ttrace_page *prev;
68 };
69
70 struct inf_ttrace_page_dict
71 {
72 struct inf_ttrace_page buckets[128];
73 int pagesize; /* Page size. */
74 int count; /* Number of pages in this dictionary. */
75 } inf_ttrace_page_dict;
76
77 struct inf_ttrace_private_thread_info
78 {
79 int dying;
80 };
81
82 /* Number of lwps that are currently in a system call. */
83 static int inf_ttrace_num_lwps_in_syscall;
84
85 /* Flag to indicate whether we should re-enable page protections after
86 the next wait. */
87 static int inf_ttrace_reenable_page_protections;
88
89 /* Enable system call events for process PID. */
90
91 static void
92 inf_ttrace_enable_syscall_events (pid_t pid)
93 {
94 ttevent_t tte;
95 ttstate_t tts;
96
97 gdb_assert (inf_ttrace_num_lwps_in_syscall == 0);
98
99 if (ttrace (TT_PROC_GET_EVENT_MASK, pid, 0,
100 (uintptr_t)&tte, sizeof tte, 0) == -1)
101 perror_with_name (("ttrace"));
102
103 tte.tte_events |= (TTEVT_SYSCALL_ENTRY | TTEVT_SYSCALL_RETURN);
104
105 if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0,
106 (uintptr_t)&tte, sizeof tte, 0) == -1)
107 perror_with_name (("ttrace"));
108
109 if (ttrace (TT_PROC_GET_FIRST_LWP_STATE, pid, 0,
110 (uintptr_t)&tts, sizeof tts, 0) == -1)
111 perror_with_name (("ttrace"));
112
113 if (tts.tts_flags & TTS_INSYSCALL)
114 inf_ttrace_num_lwps_in_syscall++;
115
116 /* FIXME: Handle multiple threads. */
117 }
118
119 /* Disable system call events for process PID. */
120
121 static void
122 inf_ttrace_disable_syscall_events (pid_t pid)
123 {
124 ttevent_t tte;
125
126 gdb_assert (inf_ttrace_page_dict.count == 0);
127
128 if (ttrace (TT_PROC_GET_EVENT_MASK, pid, 0,
129 (uintptr_t)&tte, sizeof tte, 0) == -1)
130 perror_with_name (("ttrace"));
131
132 tte.tte_events &= ~(TTEVT_SYSCALL_ENTRY | TTEVT_SYSCALL_RETURN);
133
134 if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0,
135 (uintptr_t)&tte, sizeof tte, 0) == -1)
136 perror_with_name (("ttrace"));
137
138 inf_ttrace_num_lwps_in_syscall = 0;
139 }
140
141 /* Get information about the page at address ADDR for process PID from
142 the dictionary. */
143
144 static struct inf_ttrace_page *
145 inf_ttrace_get_page (pid_t pid, CORE_ADDR addr)
146 {
147 const int num_buckets = ARRAY_SIZE (inf_ttrace_page_dict.buckets);
148 const int pagesize = inf_ttrace_page_dict.pagesize;
149 int bucket;
150 struct inf_ttrace_page *page;
151
152 bucket = (addr / pagesize) % num_buckets;
153 page = &inf_ttrace_page_dict.buckets[bucket];
154 while (page)
155 {
156 if (page->addr == addr)
157 break;
158
159 page = page->next;
160 }
161
162 return page;
163 }
164
165 /* Add the page at address ADDR for process PID to the dictionary. */
166
167 static struct inf_ttrace_page *
168 inf_ttrace_add_page (pid_t pid, CORE_ADDR addr)
169 {
170 const int num_buckets = ARRAY_SIZE (inf_ttrace_page_dict.buckets);
171 const int pagesize = inf_ttrace_page_dict.pagesize;
172 int bucket;
173 struct inf_ttrace_page *page;
174 struct inf_ttrace_page *prev = NULL;
175
176 bucket = (addr / pagesize) % num_buckets;
177 page = &inf_ttrace_page_dict.buckets[bucket];
178 while (page)
179 {
180 if (page->addr == addr)
181 break;
182
183 prev = page;
184 page = page->next;
185 }
186
187 if (!page)
188 {
189 int prot;
190
191 if (ttrace (TT_PROC_GET_MPROTECT, pid, 0,
192 addr, 0, (uintptr_t)&prot) == -1)
193 perror_with_name (("ttrace"));
194
195 page = XNEW (struct inf_ttrace_page);
196 page->addr = addr;
197 page->prot = prot;
198 page->refcount = 0;
199 page->next = NULL;
200
201 page->prev = prev;
202 prev->next = page;
203
204 inf_ttrace_page_dict.count++;
205 if (inf_ttrace_page_dict.count == 1)
206 inf_ttrace_enable_syscall_events (pid);
207
208 if (inf_ttrace_num_lwps_in_syscall == 0)
209 {
210 if (ttrace (TT_PROC_SET_MPROTECT, pid, 0,
211 addr, pagesize, prot & ~PROT_WRITE) == -1)
212 perror_with_name (("ttrace"));
213 }
214 }
215
216 return page;
217 }
218
219 /* Insert the page at address ADDR of process PID to the dictionary. */
220
221 static void
222 inf_ttrace_insert_page (pid_t pid, CORE_ADDR addr)
223 {
224 struct inf_ttrace_page *page;
225
226 page = inf_ttrace_get_page (pid, addr);
227 if (!page)
228 page = inf_ttrace_add_page (pid, addr);
229
230 page->refcount++;
231 }
232
233 /* Remove the page at address ADDR of process PID from the dictionary. */
234
235 static void
236 inf_ttrace_remove_page (pid_t pid, CORE_ADDR addr)
237 {
238 const int pagesize = inf_ttrace_page_dict.pagesize;
239 struct inf_ttrace_page *page;
240
241 page = inf_ttrace_get_page (pid, addr);
242 page->refcount--;
243
244 gdb_assert (page->refcount >= 0);
245
246 if (page->refcount == 0)
247 {
248 if (inf_ttrace_num_lwps_in_syscall == 0)
249 {
250 if (ttrace (TT_PROC_SET_MPROTECT, pid, 0,
251 addr, pagesize, page->prot) == -1)
252 perror_with_name (("ttrace"));
253 }
254
255 inf_ttrace_page_dict.count--;
256 if (inf_ttrace_page_dict.count == 0)
257 inf_ttrace_disable_syscall_events (pid);
258
259 page->prev->next = page->next;
260 if (page->next)
261 page->next->prev = page->prev;
262
263 xfree (page);
264 }
265 }
266
267 /* Mask the bits in PROT from the page protections that are currently
268 in the dictionary for process PID. */
269
270 static void
271 inf_ttrace_mask_page_protections (pid_t pid, int prot)
272 {
273 const int num_buckets = ARRAY_SIZE (inf_ttrace_page_dict.buckets);
274 const int pagesize = inf_ttrace_page_dict.pagesize;
275 int bucket;
276
277 for (bucket = 0; bucket < num_buckets; bucket++)
278 {
279 struct inf_ttrace_page *page;
280
281 page = inf_ttrace_page_dict.buckets[bucket].next;
282 while (page)
283 {
284 if (ttrace (TT_PROC_SET_MPROTECT, pid, 0,
285 page->addr, pagesize, page->prot & ~prot) == -1)
286 perror_with_name (("ttrace"));
287
288 page = page->next;
289 }
290 }
291 }
292
293 /* Write-protect the pages in the dictionary for process PID. */
294
295 static void
296 inf_ttrace_enable_page_protections (pid_t pid)
297 {
298 inf_ttrace_mask_page_protections (pid, PROT_WRITE);
299 }
300
301 /* Restore the protection of the pages in the dictionary for process
302 PID. */
303
304 static void
305 inf_ttrace_disable_page_protections (pid_t pid)
306 {
307 inf_ttrace_mask_page_protections (pid, 0);
308 }
309
310 /* Insert a "hardware" watchpoint for LEN bytes at address ADDR of
311 type TYPE. */
312
313 static int
314 inf_ttrace_insert_watchpoint (struct target_ops *self,
315 CORE_ADDR addr, int len, int type,
316 struct expression *cond)
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 (struct target_ops *self,
340 CORE_ADDR addr, int len, int type,
341 struct expression *cond)
342 {
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;
348
349 gdb_assert (type == hw_write);
350
351 page_addr = (addr / pagesize) * pagesize;
352 num_pages = (len + pagesize - 1) / pagesize;
353
354 for (page = 0; page < num_pages; page++, page_addr += pagesize)
355 inf_ttrace_remove_page (pid, page_addr);
356
357 return 1;
358 }
359
360 static int
361 inf_ttrace_can_use_hw_breakpoint (struct target_ops *self,
362 int type, int len, int ot)
363 {
364 return (type == bp_hardware_watchpoint);
365 }
366
367 static int
368 inf_ttrace_region_ok_for_hw_watchpoint (struct target_ops *self,
369 CORE_ADDR addr, int len)
370 {
371 return 1;
372 }
373
374 /* Return non-zero if the current inferior was (potentially) stopped
375 by hitting a "hardware" watchpoint. */
376
377 static int
378 inf_ttrace_stopped_by_watchpoint (struct target_ops *ops)
379 {
380 pid_t pid = ptid_get_pid (inferior_ptid);
381 lwpid_t lwpid = ptid_get_lwp (inferior_ptid);
382 ttstate_t tts;
383
384 if (inf_ttrace_page_dict.count > 0)
385 {
386 if (ttrace (TT_LWP_GET_STATE, pid, lwpid,
387 (uintptr_t)&tts, sizeof tts, 0) == -1)
388 perror_with_name (("ttrace"));
389
390 if (tts.tts_event == TTEVT_SIGNAL
391 && tts.tts_u.tts_signal.tts_signo == SIGBUS)
392 {
393 const int pagesize = inf_ttrace_page_dict.pagesize;
394 void *addr = tts.tts_u.tts_signal.tts_siginfo.si_addr;
395 CORE_ADDR page_addr = ((uintptr_t)addr / pagesize) * pagesize;
396
397 if (inf_ttrace_get_page (pid, page_addr))
398 return 1;
399 }
400 }
401
402 return 0;
403 }
404 \f
405
406 /* Target hook for follow_fork. On entry and at return inferior_ptid
407 is the ptid of the followed inferior. */
408
409 static int
410 inf_ttrace_follow_fork (struct target_ops *ops, int follow_child,
411 int detach_fork)
412 {
413 struct thread_info *tp = inferior_thread ();
414
415 gdb_assert (tp->pending_follow.kind == TARGET_WAITKIND_FORKED
416 || tp->pending_follow.kind == TARGET_WAITKIND_VFORKED);
417
418 if (follow_child)
419 {
420 struct thread_info *ti;
421
422 /* The child will start out single-threaded. */
423 inf_ttrace_num_lwps = 1;
424 inf_ttrace_num_lwps_in_syscall = 0;
425
426 ti = inferior_thread ();
427 ti->priv =
428 xmalloc (sizeof (struct inf_ttrace_private_thread_info));
429 memset (ti->priv, 0,
430 sizeof (struct inf_ttrace_private_thread_info));
431 }
432 else
433 {
434 pid_t child_pid;
435
436 /* Following parent. Detach child now. */
437 child_pid = ptid_get_pid (tp->pending_follow.value.related_pid);
438 if (ttrace (TT_PROC_DETACH, child_pid, 0, 0, 0, 0) == -1)
439 perror_with_name (("ttrace"));
440 }
441
442 return 0;
443 }
444 \f
445
446 /* File descriptors for pipes used as semaphores during initial
447 startup of an inferior. */
448 static int inf_ttrace_pfd1[2];
449 static int inf_ttrace_pfd2[2];
450
451 static void
452 do_cleanup_pfds (void *dummy)
453 {
454 close (inf_ttrace_pfd1[0]);
455 close (inf_ttrace_pfd1[1]);
456 close (inf_ttrace_pfd2[0]);
457 close (inf_ttrace_pfd2[1]);
458
459 unmark_fd_no_cloexec (inf_ttrace_pfd1[0]);
460 unmark_fd_no_cloexec (inf_ttrace_pfd1[1]);
461 unmark_fd_no_cloexec (inf_ttrace_pfd2[0]);
462 unmark_fd_no_cloexec (inf_ttrace_pfd2[1]);
463 }
464
465 static void
466 inf_ttrace_prepare (void)
467 {
468 if (pipe (inf_ttrace_pfd1) == -1)
469 perror_with_name (("pipe"));
470
471 if (pipe (inf_ttrace_pfd2) == -1)
472 {
473 close (inf_ttrace_pfd1[0]);
474 close (inf_ttrace_pfd2[0]);
475 perror_with_name (("pipe"));
476 }
477
478 mark_fd_no_cloexec (inf_ttrace_pfd1[0]);
479 mark_fd_no_cloexec (inf_ttrace_pfd1[1]);
480 mark_fd_no_cloexec (inf_ttrace_pfd2[0]);
481 mark_fd_no_cloexec (inf_ttrace_pfd2[1]);
482 }
483
484 /* Prepare to be traced. */
485
486 static void
487 inf_ttrace_me (void)
488 {
489 struct cleanup *old_chain = make_cleanup (do_cleanup_pfds, 0);
490 char c;
491
492 /* "Trace me, Dr. Memory!" */
493 if (ttrace (TT_PROC_SETTRC, 0, 0, 0, TT_VERSION, 0) == -1)
494 perror_with_name (("ttrace"));
495
496 /* Tell our parent that we are ready to be traced. */
497 if (write (inf_ttrace_pfd1[1], &c, sizeof c) != sizeof c)
498 perror_with_name (("write"));
499
500 /* Wait until our parent has set the initial event mask. */
501 if (read (inf_ttrace_pfd2[0], &c, sizeof c) != sizeof c)
502 perror_with_name (("read"));
503
504 do_cleanups (old_chain);
505 }
506
507 /* Start tracing PID. */
508
509 static void
510 inf_ttrace_him (struct target_ops *ops, int pid)
511 {
512 struct cleanup *old_chain = make_cleanup (do_cleanup_pfds, 0);
513 ttevent_t tte;
514 char c;
515
516 /* Wait until our child is ready to be traced. */
517 if (read (inf_ttrace_pfd1[0], &c, sizeof c) != sizeof c)
518 perror_with_name (("read"));
519
520 /* Set the initial event mask. */
521 memset (&tte, 0, sizeof (tte));
522 tte.tte_events |= TTEVT_EXEC | TTEVT_EXIT | TTEVT_FORK | TTEVT_VFORK;
523 tte.tte_events |= TTEVT_LWP_CREATE | TTEVT_LWP_EXIT | TTEVT_LWP_TERMINATE;
524 #ifdef TTEVT_BPT_SSTEP
525 tte.tte_events |= TTEVT_BPT_SSTEP;
526 #endif
527 tte.tte_opts |= TTEO_PROC_INHERIT;
528 if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0,
529 (uintptr_t)&tte, sizeof tte, 0) == -1)
530 perror_with_name (("ttrace"));
531
532 /* Tell our child that we have set the initial event mask. */
533 if (write (inf_ttrace_pfd2[1], &c, sizeof c) != sizeof c)
534 perror_with_name (("write"));
535
536 do_cleanups (old_chain);
537
538 if (!target_is_pushed (ops))
539 push_target (ops);
540
541 startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
542
543 /* On some targets, there must be some explicit actions taken after
544 the inferior has been started up. */
545 target_post_startup_inferior (pid_to_ptid (pid));
546 }
547
548 static void
549 inf_ttrace_create_inferior (struct target_ops *ops, char *exec_file,
550 char *allargs, char **env, int from_tty)
551 {
552 int pid;
553
554 gdb_assert (inf_ttrace_num_lwps == 0);
555 gdb_assert (inf_ttrace_num_lwps_in_syscall == 0);
556 gdb_assert (inf_ttrace_page_dict.count == 0);
557 gdb_assert (inf_ttrace_reenable_page_protections == 0);
558
559 pid = fork_inferior (exec_file, allargs, env, inf_ttrace_me, NULL,
560 inf_ttrace_prepare, NULL, NULL);
561
562 inf_ttrace_him (ops, pid);
563 }
564
565 static void
566 inf_ttrace_mourn_inferior (struct target_ops *ops)
567 {
568 const int num_buckets = ARRAY_SIZE (inf_ttrace_page_dict.buckets);
569 int bucket;
570
571 inf_ttrace_num_lwps = 0;
572 inf_ttrace_num_lwps_in_syscall = 0;
573
574 for (bucket = 0; bucket < num_buckets; bucket++)
575 {
576 struct inf_ttrace_page *page;
577 struct inf_ttrace_page *next;
578
579 page = inf_ttrace_page_dict.buckets[bucket].next;
580 while (page)
581 {
582 next = page->next;
583 xfree (page);
584 page = next;
585 }
586 }
587 inf_ttrace_page_dict.count = 0;
588
589 inf_child_mourn_inferior (ops);
590 }
591
592 /* Assuming we just attached the debugger to a new inferior, create
593 a new thread_info structure for each thread, and add it to our
594 list of threads. */
595
596 static void
597 inf_ttrace_create_threads_after_attach (int pid)
598 {
599 int status;
600 ptid_t ptid;
601 ttstate_t tts;
602 struct thread_info *ti;
603
604 status = ttrace (TT_PROC_GET_FIRST_LWP_STATE, pid, 0,
605 (uintptr_t) &tts, sizeof (ttstate_t), 0);
606 if (status < 0)
607 perror_with_name (_("TT_PROC_GET_FIRST_LWP_STATE ttrace call failed"));
608 gdb_assert (tts.tts_pid == pid);
609
610 /* Add the stopped thread. */
611 ptid = ptid_build (pid, tts.tts_lwpid, 0);
612 ti = add_thread (ptid);
613 ti->priv = xzalloc (sizeof (struct inf_ttrace_private_thread_info));
614 inf_ttrace_num_lwps++;
615
616 /* We use the "first stopped thread" as the currently active thread. */
617 inferior_ptid = ptid;
618
619 /* Iterative over all the remaining threads. */
620
621 for (;;)
622 {
623 ptid_t ptid;
624
625 status = ttrace (TT_PROC_GET_NEXT_LWP_STATE, pid, 0,
626 (uintptr_t) &tts, sizeof (ttstate_t), 0);
627 if (status < 0)
628 perror_with_name (_("TT_PROC_GET_NEXT_LWP_STATE ttrace call failed"));
629 if (status == 0)
630 break; /* End of list. */
631
632 ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0);
633 ti = add_thread (ptid);
634 ti->priv = xzalloc (sizeof (struct inf_ttrace_private_thread_info));
635 inf_ttrace_num_lwps++;
636 }
637 }
638
639 static void
640 inf_ttrace_attach (struct target_ops *ops, const char *args, int from_tty)
641 {
642 char *exec_file;
643 pid_t pid;
644 ttevent_t tte;
645 struct inferior *inf;
646
647 pid = parse_pid_to_attach (args);
648
649 if (pid == getpid ()) /* Trying to masturbate? */
650 error (_("I refuse to debug myself!"));
651
652 if (from_tty)
653 {
654 exec_file = get_exec_file (0);
655
656 if (exec_file)
657 printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file,
658 target_pid_to_str (pid_to_ptid (pid)));
659 else
660 printf_unfiltered (_("Attaching to %s\n"),
661 target_pid_to_str (pid_to_ptid (pid)));
662
663 gdb_flush (gdb_stdout);
664 }
665
666 gdb_assert (inf_ttrace_num_lwps == 0);
667 gdb_assert (inf_ttrace_num_lwps_in_syscall == 0);
668
669 if (ttrace (TT_PROC_ATTACH, pid, 0, TT_KILL_ON_EXIT, TT_VERSION, 0) == -1)
670 perror_with_name (("ttrace"));
671
672 inf = current_inferior ();
673 inferior_appeared (inf, pid);
674 inf->attach_flag = 1;
675
676 /* Set the initial event mask. */
677 memset (&tte, 0, sizeof (tte));
678 tte.tte_events |= TTEVT_EXEC | TTEVT_EXIT | TTEVT_FORK | TTEVT_VFORK;
679 tte.tte_events |= TTEVT_LWP_CREATE | TTEVT_LWP_EXIT | TTEVT_LWP_TERMINATE;
680 #ifdef TTEVT_BPT_SSTEP
681 tte.tte_events |= TTEVT_BPT_SSTEP;
682 #endif
683 tte.tte_opts |= TTEO_PROC_INHERIT;
684 if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0,
685 (uintptr_t)&tte, sizeof tte, 0) == -1)
686 perror_with_name (("ttrace"));
687
688 if (!target_is_pushed (ops))
689 push_target (ops);
690
691 inf_ttrace_create_threads_after_attach (pid);
692 }
693
694 static void
695 inf_ttrace_detach (struct target_ops *ops, const char *args, int from_tty)
696 {
697 pid_t pid = ptid_get_pid (inferior_ptid);
698 int sig = 0;
699
700 if (from_tty)
701 {
702 char *exec_file = get_exec_file (0);
703 if (exec_file == 0)
704 exec_file = "";
705 printf_unfiltered (_("Detaching from program: %s, %s\n"), exec_file,
706 target_pid_to_str (pid_to_ptid (pid)));
707 gdb_flush (gdb_stdout);
708 }
709 if (args)
710 sig = atoi (args);
711
712 /* ??? The HP-UX 11.0 ttrace(2) manual page doesn't mention that we
713 can pass a signal number here. Does this really work? */
714 if (ttrace (TT_PROC_DETACH, pid, 0, 0, sig, 0) == -1)
715 perror_with_name (("ttrace"));
716
717 inf_ttrace_num_lwps = 0;
718 inf_ttrace_num_lwps_in_syscall = 0;
719
720 inferior_ptid = null_ptid;
721 detach_inferior (pid);
722
723 inf_child_maybe_unpush_target (ops);
724 }
725
726 static void
727 inf_ttrace_kill (struct target_ops *ops)
728 {
729 pid_t pid = ptid_get_pid (inferior_ptid);
730
731 if (pid == 0)
732 return;
733
734 if (ttrace (TT_PROC_EXIT, pid, 0, 0, 0, 0) == -1)
735 perror_with_name (("ttrace"));
736 /* ??? Is it necessary to call ttrace_wait() here? */
737
738 target_mourn_inferior ();
739 }
740
741 /* Check is a dying thread is dead by now, and delete it from GDBs
742 thread list if so. */
743 static int
744 inf_ttrace_delete_dead_threads_callback (struct thread_info *info, void *arg)
745 {
746 lwpid_t lwpid;
747 struct inf_ttrace_private_thread_info *p;
748
749 if (is_exited (info->ptid))
750 return 0;
751
752 lwpid = ptid_get_lwp (info->ptid);
753 p = (struct inf_ttrace_private_thread_info *) info->priv;
754
755 /* Check if an lwp that was dying is still there or not. */
756 if (p->dying && (kill (lwpid, 0) == -1))
757 /* It's gone now. */
758 delete_thread (info->ptid);
759
760 return 0;
761 }
762
763 /* Resume the lwp pointed to by INFO, with REQUEST, and pass it signal
764 SIG. */
765
766 static void
767 inf_ttrace_resume_lwp (struct thread_info *info, ttreq_t request, int sig)
768 {
769 pid_t pid = ptid_get_pid (info->ptid);
770 lwpid_t lwpid = ptid_get_lwp (info->ptid);
771
772 if (ttrace (request, pid, lwpid, TT_NOPC, sig, 0) == -1)
773 {
774 struct inf_ttrace_private_thread_info *p
775 = (struct inf_ttrace_private_thread_info *) info->priv;
776 if (p->dying && errno == EPROTO)
777 /* This is expected, it means the dying lwp is really gone
778 by now. If ttrace had an event to inform the debugger
779 the lwp is really gone, this wouldn't be needed. */
780 delete_thread (info->ptid);
781 else
782 /* This was really unexpected. */
783 perror_with_name (("ttrace"));
784 }
785 }
786
787 /* Callback for iterate_over_threads. */
788
789 static int
790 inf_ttrace_resume_callback (struct thread_info *info, void *arg)
791 {
792 if (!ptid_equal (info->ptid, inferior_ptid) && !is_exited (info->ptid))
793 inf_ttrace_resume_lwp (info, TT_LWP_CONTINUE, 0);
794
795 return 0;
796 }
797
798 static void
799 inf_ttrace_resume (struct target_ops *ops,
800 ptid_t ptid, int step, enum gdb_signal signal)
801 {
802 int resume_all;
803 ttreq_t request = step ? TT_LWP_SINGLE : TT_LWP_CONTINUE;
804 int sig = gdb_signal_to_host (signal);
805 struct thread_info *info;
806
807 /* A specific PTID means `step only this process id'. */
808 resume_all = (ptid_equal (ptid, minus_one_ptid));
809
810 /* If resuming all threads, it's the current thread that should be
811 handled specially. */
812 if (resume_all)
813 ptid = inferior_ptid;
814
815 info = find_thread_ptid (ptid);
816 inf_ttrace_resume_lwp (info, request, sig);
817
818 if (resume_all)
819 /* Let all the other threads run too. */
820 iterate_over_threads (inf_ttrace_resume_callback, NULL);
821 }
822
823 static ptid_t
824 inf_ttrace_wait (struct target_ops *ops,
825 ptid_t ptid, struct target_waitstatus *ourstatus, int options)
826 {
827 pid_t pid = ptid_get_pid (ptid);
828 lwpid_t lwpid = ptid_get_lwp (ptid);
829 ttstate_t tts;
830 struct thread_info *ti;
831 ptid_t related_ptid;
832
833 /* Until proven otherwise. */
834 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
835
836 if (pid == -1)
837 pid = lwpid = 0;
838
839 gdb_assert (pid != 0 || lwpid == 0);
840
841 do
842 {
843 set_sigint_trap ();
844
845 if (ttrace_wait (pid, lwpid, TTRACE_WAITOK, &tts, sizeof tts) == -1)
846 perror_with_name (("ttrace_wait"));
847
848 clear_sigint_trap ();
849 }
850 while (tts.tts_event == TTEVT_NONE);
851
852 /* Now that we've waited, we can re-enable the page protections. */
853 if (inf_ttrace_reenable_page_protections)
854 {
855 gdb_assert (inf_ttrace_num_lwps_in_syscall == 0);
856 inf_ttrace_enable_page_protections (tts.tts_pid);
857 inf_ttrace_reenable_page_protections = 0;
858 }
859
860 ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0);
861
862 if (inf_ttrace_num_lwps == 0)
863 {
864 struct thread_info *ti;
865
866 inf_ttrace_num_lwps = 1;
867
868 /* This is the earliest we hear about the lwp member of
869 INFERIOR_PTID, after an attach or fork_inferior. */
870 gdb_assert (ptid_get_lwp (inferior_ptid) == 0);
871
872 /* We haven't set the private member on the main thread yet. Do
873 it now. */
874 ti = find_thread_ptid (inferior_ptid);
875 gdb_assert (ti != NULL && ti->priv == NULL);
876 ti->priv =
877 xmalloc (sizeof (struct inf_ttrace_private_thread_info));
878 memset (ti->priv, 0,
879 sizeof (struct inf_ttrace_private_thread_info));
880
881 /* Notify the core that this ptid changed. This changes
882 inferior_ptid as well. */
883 thread_change_ptid (inferior_ptid, ptid);
884 }
885
886 switch (tts.tts_event)
887 {
888 #ifdef TTEVT_BPT_SSTEP
889 case TTEVT_BPT_SSTEP:
890 /* Make it look like a breakpoint. */
891 ourstatus->kind = TARGET_WAITKIND_STOPPED;
892 ourstatus->value.sig = GDB_SIGNAL_TRAP;
893 break;
894 #endif
895
896 case TTEVT_EXEC:
897 ourstatus->kind = TARGET_WAITKIND_EXECD;
898 ourstatus->value.execd_pathname =
899 xmalloc (tts.tts_u.tts_exec.tts_pathlen + 1);
900 if (ttrace (TT_PROC_GET_PATHNAME, tts.tts_pid, 0,
901 (uintptr_t)ourstatus->value.execd_pathname,
902 tts.tts_u.tts_exec.tts_pathlen, 0) == -1)
903 perror_with_name (("ttrace"));
904 ourstatus->value.execd_pathname[tts.tts_u.tts_exec.tts_pathlen] = 0;
905
906 /* At this point, all inserted breakpoints are gone. Doing this
907 as soon as we detect an exec prevents the badness of deleting
908 a breakpoint writing the current "shadow contents" to lift
909 the bp. That shadow is NOT valid after an exec. */
910 mark_breakpoints_out ();
911 break;
912
913 case TTEVT_EXIT:
914 store_waitstatus (ourstatus, tts.tts_u.tts_exit.tts_exitcode);
915 inf_ttrace_num_lwps = 0;
916 break;
917
918 case TTEVT_FORK:
919 related_ptid = ptid_build (tts.tts_u.tts_fork.tts_fpid,
920 tts.tts_u.tts_fork.tts_flwpid, 0);
921
922 ourstatus->kind = TARGET_WAITKIND_FORKED;
923 ourstatus->value.related_pid = related_ptid;
924
925 /* Make sure the other end of the fork is stopped too. */
926 if (ttrace_wait (tts.tts_u.tts_fork.tts_fpid,
927 tts.tts_u.tts_fork.tts_flwpid,
928 TTRACE_WAITOK, &tts, sizeof tts) == -1)
929 perror_with_name (("ttrace_wait"));
930
931 gdb_assert (tts.tts_event == TTEVT_FORK);
932 if (tts.tts_u.tts_fork.tts_isparent)
933 {
934 related_ptid = ptid_build (tts.tts_u.tts_fork.tts_fpid,
935 tts.tts_u.tts_fork.tts_flwpid, 0);
936 ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0);
937 ourstatus->value.related_pid = related_ptid;
938 }
939 break;
940
941 case TTEVT_VFORK:
942 if (tts.tts_u.tts_fork.tts_isparent)
943 ourstatus->kind = TARGET_WAITKIND_VFORK_DONE;
944 else
945 {
946 related_ptid = ptid_build (tts.tts_u.tts_fork.tts_fpid,
947 tts.tts_u.tts_fork.tts_flwpid, 0);
948
949 ourstatus->kind = TARGET_WAITKIND_VFORKED;
950 ourstatus->value.related_pid = related_ptid;
951 }
952 break;
953
954 case TTEVT_LWP_CREATE:
955 lwpid = tts.tts_u.tts_thread.tts_target_lwpid;
956 ptid = ptid_build (tts.tts_pid, lwpid, 0);
957 ti = add_thread (ptid);
958 ti->priv =
959 xmalloc (sizeof (struct inf_ttrace_private_thread_info));
960 memset (ti->priv, 0,
961 sizeof (struct inf_ttrace_private_thread_info));
962 inf_ttrace_num_lwps++;
963 ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0);
964 /* Let the lwp_create-caller thread continue. */
965 ttrace (TT_LWP_CONTINUE, ptid_get_pid (ptid),
966 ptid_get_lwp (ptid), TT_NOPC, 0, 0);
967 /* Return without stopping the whole process. */
968 ourstatus->kind = TARGET_WAITKIND_IGNORE;
969 return ptid;
970
971 case TTEVT_LWP_EXIT:
972 if (print_thread_events)
973 printf_unfiltered (_("[%s exited]\n"), target_pid_to_str (ptid));
974 ti = find_thread_ptid (ptid);
975 gdb_assert (ti != NULL);
976 ((struct inf_ttrace_private_thread_info *)ti->priv)->dying = 1;
977 inf_ttrace_num_lwps--;
978 /* Let the thread really exit. */
979 ttrace (TT_LWP_CONTINUE, ptid_get_pid (ptid),
980 ptid_get_lwp (ptid), TT_NOPC, 0, 0);
981 /* Return without stopping the whole process. */
982 ourstatus->kind = TARGET_WAITKIND_IGNORE;
983 return ptid;
984
985 case TTEVT_LWP_TERMINATE:
986 lwpid = tts.tts_u.tts_thread.tts_target_lwpid;
987 ptid = ptid_build (tts.tts_pid, lwpid, 0);
988 if (print_thread_events)
989 printf_unfiltered(_("[%s has been terminated]\n"),
990 target_pid_to_str (ptid));
991 ti = find_thread_ptid (ptid);
992 gdb_assert (ti != NULL);
993 ((struct inf_ttrace_private_thread_info *)ti->priv)->dying = 1;
994 inf_ttrace_num_lwps--;
995
996 /* Resume the lwp_terminate-caller thread. */
997 ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0);
998 ttrace (TT_LWP_CONTINUE, ptid_get_pid (ptid),
999 ptid_get_lwp (ptid), TT_NOPC, 0, 0);
1000 /* Return without stopping the whole process. */
1001 ourstatus->kind = TARGET_WAITKIND_IGNORE;
1002 return ptid;
1003
1004 case TTEVT_SIGNAL:
1005 ourstatus->kind = TARGET_WAITKIND_STOPPED;
1006 ourstatus->value.sig =
1007 gdb_signal_from_host (tts.tts_u.tts_signal.tts_signo);
1008 break;
1009
1010 case TTEVT_SYSCALL_ENTRY:
1011 gdb_assert (inf_ttrace_reenable_page_protections == 0);
1012 inf_ttrace_num_lwps_in_syscall++;
1013 if (inf_ttrace_num_lwps_in_syscall == 1)
1014 {
1015 /* A thread has just entered a system call. Disable any
1016 page protections as the kernel can't deal with them. */
1017 inf_ttrace_disable_page_protections (tts.tts_pid);
1018 }
1019 ourstatus->kind = TARGET_WAITKIND_SYSCALL_ENTRY;
1020 ourstatus->value.syscall_number = tts.tts_scno;
1021 break;
1022
1023 case TTEVT_SYSCALL_RETURN:
1024 if (inf_ttrace_num_lwps_in_syscall > 0)
1025 {
1026 /* If the last thread has just left the system call, this
1027 would be a logical place to re-enable the page
1028 protections, but that doesn't work. We can't re-enable
1029 them until we've done another wait. */
1030 inf_ttrace_reenable_page_protections =
1031 (inf_ttrace_num_lwps_in_syscall == 1);
1032 inf_ttrace_num_lwps_in_syscall--;
1033 }
1034 ourstatus->kind = TARGET_WAITKIND_SYSCALL_RETURN;
1035 ourstatus->value.syscall_number = tts.tts_scno;
1036 break;
1037
1038 default:
1039 gdb_assert (!"Unexpected ttrace event");
1040 break;
1041 }
1042
1043 /* Make sure all threads within the process are stopped. */
1044 if (ttrace (TT_PROC_STOP, tts.tts_pid, 0, 0, 0, 0) == -1)
1045 perror_with_name (("ttrace"));
1046
1047 /* Now that the whole process is stopped, check if any dying thread
1048 is really dead by now. If a dying thread is still alive, it will
1049 be stopped too, and will still show up in `info threads', tagged
1050 with "(Exiting)". We could make `info threads' prune dead
1051 threads instead via inf_ttrace_thread_alive, but doing this here
1052 has the advantage that a frontend is notificed sooner of thread
1053 exits. Note that a dying lwp is still alive, it still has to be
1054 resumed, like any other lwp. */
1055 iterate_over_threads (inf_ttrace_delete_dead_threads_callback, NULL);
1056
1057 return ptid;
1058 }
1059
1060 /* Transfer LEN bytes from ADDR in the inferior's memory into READBUF,
1061 and transfer LEN bytes from WRITEBUF into the inferior's memory at
1062 ADDR. Either READBUF or WRITEBUF may be null, in which case the
1063 corresponding transfer doesn't happen. Return the number of bytes
1064 actually transferred (which may be zero if an error occurs). */
1065
1066 static LONGEST
1067 inf_ttrace_xfer_memory (CORE_ADDR addr, ULONGEST len,
1068 void *readbuf, const void *writebuf)
1069 {
1070 pid_t pid = ptid_get_pid (inferior_ptid);
1071
1072 /* HP-UX treats text space and data space differently. GDB however,
1073 doesn't really know the difference. Therefore we try both. Try
1074 text space before data space though because when we're writing
1075 into text space the instruction cache might need to be flushed. */
1076
1077 if (readbuf
1078 && ttrace (TT_PROC_RDTEXT, pid, 0, addr, len, (uintptr_t)readbuf) == -1
1079 && ttrace (TT_PROC_RDDATA, pid, 0, addr, len, (uintptr_t)readbuf) == -1)
1080 return 0;
1081
1082 if (writebuf
1083 && ttrace (TT_PROC_WRTEXT, pid, 0, addr, len, (uintptr_t)writebuf) == -1
1084 && ttrace (TT_PROC_WRDATA, pid, 0, addr, len, (uintptr_t)writebuf) == -1)
1085 return 0;
1086
1087 return len;
1088 }
1089
1090 static enum target_xfer_status
1091 inf_ttrace_xfer_partial (struct target_ops *ops, enum target_object object,
1092 const char *annex, gdb_byte *readbuf,
1093 const gdb_byte *writebuf,
1094 ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
1095 {
1096 switch (object)
1097 {
1098 case TARGET_OBJECT_MEMORY:
1099 {
1100 LONGEST val = inf_ttrace_xfer_memory (offset, len, readbuf, writebuf);
1101
1102 if (val == 0)
1103 return TARGET_XFER_EOF;
1104 else
1105 {
1106 *xfered_len = (ULONGEST) val;
1107 return TARGET_XFER_OK;
1108 }
1109 }
1110
1111 case TARGET_OBJECT_UNWIND_TABLE:
1112 return TARGET_XFER_E_IO;
1113
1114 case TARGET_OBJECT_AUXV:
1115 return TARGET_XFER_E_IO;
1116
1117 case TARGET_OBJECT_WCOOKIE:
1118 return TARGET_XFER_E_IO;
1119
1120 default:
1121 return TARGET_XFER_E_IO;
1122 }
1123 }
1124
1125 /* Print status information about what we're accessing. */
1126
1127 static void
1128 inf_ttrace_files_info (struct target_ops *ignore)
1129 {
1130 struct inferior *inf = current_inferior ();
1131 printf_filtered (_("\tUsing the running image of %s %s.\n"),
1132 inf->attach_flag ? "attached" : "child",
1133 target_pid_to_str (inferior_ptid));
1134 }
1135
1136 static int
1137 inf_ttrace_thread_alive (struct target_ops *ops, ptid_t ptid)
1138 {
1139 return 1;
1140 }
1141
1142 /* Return a string describing the state of the thread specified by
1143 INFO. */
1144
1145 static char *
1146 inf_ttrace_extra_thread_info (struct target_ops *self,
1147 struct thread_info *info)
1148 {
1149 struct inf_ttrace_private_thread_info* priv =
1150 (struct inf_ttrace_private_thread_info *) info->priv;
1151
1152 if (priv != NULL && priv->dying)
1153 return "Exiting";
1154
1155 return NULL;
1156 }
1157
1158 static char *
1159 inf_ttrace_pid_to_str (struct target_ops *ops, ptid_t ptid)
1160 {
1161 pid_t pid = ptid_get_pid (ptid);
1162 lwpid_t lwpid = ptid_get_lwp (ptid);
1163 static char buf[128];
1164
1165 if (lwpid == 0)
1166 xsnprintf (buf, sizeof buf, "process %ld",
1167 (long) pid);
1168 else
1169 xsnprintf (buf, sizeof buf, "process %ld, lwp %ld",
1170 (long) pid, (long) lwpid);
1171 return buf;
1172 }
1173 \f
1174
1175 /* Implement the get_ada_task_ptid target_ops method. */
1176
1177 static ptid_t
1178 inf_ttrace_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
1179 {
1180 return ptid_build (ptid_get_pid (inferior_ptid), lwp, 0);
1181 }
1182
1183 \f
1184 struct target_ops *
1185 inf_ttrace_target (void)
1186 {
1187 struct target_ops *t = inf_child_target ();
1188
1189 t->to_attach = inf_ttrace_attach;
1190 t->to_detach = inf_ttrace_detach;
1191 t->to_resume = inf_ttrace_resume;
1192 t->to_wait = inf_ttrace_wait;
1193 t->to_files_info = inf_ttrace_files_info;
1194 t->to_can_use_hw_breakpoint = inf_ttrace_can_use_hw_breakpoint;
1195 t->to_insert_watchpoint = inf_ttrace_insert_watchpoint;
1196 t->to_remove_watchpoint = inf_ttrace_remove_watchpoint;
1197 t->to_stopped_by_watchpoint = inf_ttrace_stopped_by_watchpoint;
1198 t->to_region_ok_for_hw_watchpoint =
1199 inf_ttrace_region_ok_for_hw_watchpoint;
1200 t->to_kill = inf_ttrace_kill;
1201 t->to_create_inferior = inf_ttrace_create_inferior;
1202 t->to_follow_fork = inf_ttrace_follow_fork;
1203 t->to_mourn_inferior = inf_ttrace_mourn_inferior;
1204 t->to_thread_alive = inf_ttrace_thread_alive;
1205 t->to_extra_thread_info = inf_ttrace_extra_thread_info;
1206 t->to_pid_to_str = inf_ttrace_pid_to_str;
1207 t->to_xfer_partial = inf_ttrace_xfer_partial;
1208 t->to_get_ada_task_ptid = inf_ttrace_get_ada_task_ptid;
1209
1210 return t;
1211 }
1212 #endif
1213 \f
1214
1215 /* Prevent warning from -Wmissing-prototypes. */
1216 void _initialize_inf_ttrace (void);
1217
1218 void
1219 _initialize_inf_ttrace (void)
1220 {
1221 #ifdef HAVE_TTRACE
1222 inf_ttrace_page_dict.pagesize = getpagesize();
1223 #endif
1224 }