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