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