1 /* Low level interface for debugging HPUX/DCE threads for GDB, the GNU debugger. 2 Copyright 1996 Free Software Foundation, Inc. 3 4 This file is part of GDB. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 19 20 /* This module implements a sort of half target that sits between the 21 machine-independent parts of GDB and the ptrace interface (infptrace.c) to 22 provide access to the HPUX user-mode thread implementation. 23 24 HPUX threads are true user-mode threads, which are invoked via the cma_* 25 and pthread_* (DCE and Posix respectivly) interfaces. These are mostly 26 implemented in user-space, with all thread context kept in various 27 structures that live in the user's heap. For the most part, the kernel has 28 no knowlege of these threads. 29 30 */ 31 32 #include "defs.h" 33 34 #define _CMA_NOWRAPPERS_ 35 36 #include <cma_tcb_defs.h> 37 #include <cma_deb_core.h> 38 #include "gdbthread.h" 39 #include "target.h" 40 #include "inferior.h" 41 #include <fcntl.h> 42 #include <unistd.h> 43 #include <sys/stat.h> 44 #include "gdbcore.h" 45 46 extern struct target_ops hpux_thread_ops; /* Forward declaration */ 47 48 extern int child_suppress_run; 49 extern struct target_ops child_ops; /* target vector for inftarg.c */ 50 51 struct string_map 52 { 53 int num; 54 char *str; 55 }; 56 57 static int hpux_thread_active = 0; 58 59 static int main_pid; /* Real process ID */ 60 61 static CORE_ADDR P_cma__g_known_threads; 62 static CORE_ADDR P_cma__g_current_thread; 63 64 static struct cleanup * save_inferior_pid PARAMS ((void)); 65 static void restore_inferior_pid PARAMS ((int pid)); 66 static void hpux_thread_resume PARAMS ((int pid, int step, 67 enum target_signal signo)); 68 69 /* 70 71 LOCAL FUNCTION 72 73 save_inferior_pid - Save inferior_pid on the cleanup list 74 restore_inferior_pid - Restore inferior_pid from the cleanup list 75 76 SYNOPSIS 77 78 struct cleanup *save_inferior_pid () 79 void restore_inferior_pid (int pid) 80 81 DESCRIPTION 82 83 These two functions act in unison to restore inferior_pid in 84 case of an error. 85 86 NOTES 87 88 inferior_pid is a global variable that needs to be changed by many of 89 these routines before calling functions in procfs.c. In order to 90 guarantee that inferior_pid gets restored (in case of errors), you 91 need to call save_inferior_pid before changing it. At the end of the 92 function, you should invoke do_cleanups to restore it. 93 94 */ 95 96 97 static struct cleanup * 98 save_inferior_pid () 99 { 100 return make_cleanup (restore_inferior_pid, inferior_pid); 101 } 102 103 static void 104 restore_inferior_pid (pid) 105 int pid; 106 { 107 inferior_pid = pid; 108 } 109 110 static int find_active_thread PARAMS ((void)); 111 112 static int cached_thread; 113 static int cached_active_thread; 114 static cma__t_int_tcb cached_tcb; 115 116 static int 117 find_active_thread () 118 { 119 static cma__t_int_tcb tcb; 120 CORE_ADDR tcb_ptr; 121 122 if (cached_active_thread != 0) 123 return cached_active_thread; 124 125 read_memory ((CORE_ADDR)P_cma__g_current_thread, 126 (char *)&tcb_ptr, 127 sizeof tcb_ptr); 128 129 read_memory (tcb_ptr, (char *)&tcb, sizeof tcb); 130 131 return (cma_thread_get_unique (&tcb.prolog.client_thread) << 16) | main_pid; 132 } 133 134 static cma__t_int_tcb * find_tcb PARAMS ((int thread)); 135 136 static cma__t_int_tcb * 137 find_tcb (thread) 138 int thread; 139 { 140 cma__t_known_object queue_header; 141 cma__t_queue *queue_ptr; 142 143 if (thread == cached_thread) 144 return &cached_tcb; 145 146 read_memory ((CORE_ADDR)P_cma__g_known_threads, 147 (char *)&queue_header, 148 sizeof queue_header); 149 150 for (queue_ptr = queue_header.queue.flink; 151 queue_ptr != (cma__t_queue *)P_cma__g_known_threads; 152 queue_ptr = cached_tcb.threads.flink) 153 { 154 cma__t_int_tcb *tcb_ptr; 155 156 tcb_ptr = cma__base (queue_ptr, threads, cma__t_int_tcb); 157 158 read_memory ((CORE_ADDR)tcb_ptr, (char *)&cached_tcb, sizeof cached_tcb); 159 160 if (cached_tcb.header.type == cma__c_obj_tcb) 161 if (cma_thread_get_unique (&cached_tcb.prolog.client_thread) == thread >> 16) 162 { 163 cached_thread = thread; 164 return &cached_tcb; 165 } 166 } 167 168 error ("Can't find TCB %d,%d", thread >> 16, thread & 0xffff); 169 return NULL; 170 } 171 172 /* Most target vector functions from here on actually just pass through to 173 inftarg.c, as they don't need to do anything specific for threads. */ 174 175 /* ARGSUSED */ 176 static void 177 hpux_thread_open (arg, from_tty) 178 char *arg; 179 int from_tty; 180 { 181 child_ops.to_open (arg, from_tty); 182 } 183 184 /* Attach to process PID, then initialize for debugging it 185 and wait for the trace-trap that results from attaching. */ 186 187 static void 188 hpux_thread_attach (args, from_tty) 189 char *args; 190 int from_tty; 191 { 192 child_ops.to_attach (args, from_tty); 193 194 /* XXX - might want to iterate over all the threads and register them. */ 195 } 196 197 /* Take a program previously attached to and detaches it. 198 The program resumes execution and will no longer stop 199 on signals, etc. We'd better not have left any breakpoints 200 in the program or it'll die when it hits one. For this 201 to work, it may be necessary for the process to have been 202 previously attached. It *might* work if the program was 203 started via the normal ptrace (PTRACE_TRACEME). */ 204 205 static void 206 hpux_thread_detach (args, from_tty) 207 char *args; 208 int from_tty; 209 { 210 child_ops.to_detach (args, from_tty); 211 } 212 213 /* Resume execution of process PID. If STEP is nozero, then 214 just single step it. If SIGNAL is nonzero, restart it with that 215 signal activated. We may have to convert pid from a thread-id to an LWP id 216 for procfs. */ 217 218 static void 219 hpux_thread_resume (pid, step, signo) 220 int pid; 221 int step; 222 enum target_signal signo; 223 { 224 struct cleanup *old_chain; 225 226 old_chain = save_inferior_pid (); 227 228 pid = inferior_pid = main_pid; 229 230 #if 0 231 if (pid != -1) 232 { 233 pid = thread_to_lwp (pid, -2); 234 if (pid == -2) /* Inactive thread */ 235 error ("This version of Solaris can't start inactive threads."); 236 } 237 #endif 238 239 child_ops.to_resume (pid, step, signo); 240 241 cached_thread = 0; 242 cached_active_thread = 0; 243 244 do_cleanups (old_chain); 245 } 246 247 /* Wait for any threads to stop. We may have to convert PID from a thread id 248 to a LWP id, and vice versa on the way out. */ 249 250 static int 251 hpux_thread_wait (pid, ourstatus) 252 int pid; 253 struct target_waitstatus *ourstatus; 254 { 255 int rtnval; 256 struct cleanup *old_chain; 257 258 old_chain = save_inferior_pid (); 259 260 inferior_pid = main_pid; 261 262 if (pid != -1) 263 pid = main_pid; 264 265 rtnval = child_ops.to_wait (pid, ourstatus); 266 267 rtnval = find_active_thread (); 268 269 do_cleanups (old_chain); 270 271 return rtnval; 272 } 273 274 static char regmap[NUM_REGS] = 275 { 276 -2, -1, -1, 0, 4, 8, 12, 16, 20, 24, /* flags, r1 -> r9 */ 277 28, 32, 36, 40, 44, 48, 52, 56, 60, -1, /* r10 -> r19 */ 278 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* r20 -> r29 */ 279 280 /* r30, r31, sar, pcoqh, pcsqh, pcoqt, pcsqt, eiem, iir, isr */ 281 -2, -1, -1, -2, -1, -1, -1, -1, -1, -1, 282 283 /* ior, ipsw, goto, sr4, sr0, sr1, sr2, sr3, sr5, sr6 */ 284 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 285 286 /* sr7, cr0, cr8, cr9, ccr, cr12, cr13, cr24, cr25, cr26 */ 287 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 288 289 -1, -1, -1, -1, /* mpsfu_high, mpsfu_low, mpsfu_ovflo, pad */ 290 144, -1, -1, -1, -1, -1, -1, -1, /* fpsr, fpe1 -> fpe7 */ 291 -1, -1, -1, -1, -1, -1, -1, -1, /* fr4 -> fr7 */ 292 -1, -1, -1, -1, -1, -1, -1, -1, /* fr8 -> fr11 */ 293 136, -1, 128, -1, 120, -1, 112, -1, /* fr12 -> fr15 */ 294 104, -1, 96, -1, 88, -1, 80, -1, /* fr16 -> fr19 */ 295 72, -1, 64, -1, -1, -1, -1, -1, /* fr20 -> fr23 */ 296 -1, -1, -1, -1, -1, -1, -1, -1, /* fr24 -> fr27 */ 297 -1, -1, -1, -1, -1, -1, -1, -1, /* fr28 -> fr31 */ 298 }; 299 300 static void 301 hpux_thread_fetch_registers (regno) 302 int regno; 303 { 304 cma__t_int_tcb tcb, *tcb_ptr; 305 struct cleanup *old_chain; 306 int i; 307 int first_regno, last_regno; 308 309 tcb_ptr = find_tcb (inferior_pid); 310 311 old_chain = save_inferior_pid (); 312 313 inferior_pid = main_pid; 314 315 if (tcb_ptr->state == cma__c_state_running) 316 { 317 child_ops.to_fetch_registers (regno); 318 319 do_cleanups (old_chain); 320 321 return; 322 } 323 324 if (regno == -1) 325 { 326 first_regno = 0; 327 last_regno = NUM_REGS - 1; 328 } 329 else 330 { 331 first_regno = regno; 332 last_regno = regno; 333 } 334 335 for (regno = first_regno; regno <= last_regno; regno++) 336 { 337 if (regmap[regno] == -1) 338 child_ops.to_fetch_registers (regno); 339 else 340 { 341 unsigned char buf[MAX_REGISTER_RAW_SIZE]; 342 CORE_ADDR sp; 343 344 sp = (CORE_ADDR)tcb_ptr->static_ctx.sp - 160; 345 346 if (regno == FLAGS_REGNUM) 347 /* Flags must be 0 to avoid bogus value for SS_INSYSCALL */ 348 memset (buf, '\000', REGISTER_RAW_SIZE (regno)); 349 else if (regno == SP_REGNUM) 350 store_address (buf, sizeof sp, sp); 351 else if (regno == PC_REGNUM) 352 read_memory (sp - 20, buf, REGISTER_RAW_SIZE (regno)); 353 else 354 read_memory (sp + regmap[regno], buf, REGISTER_RAW_SIZE (regno)); 355 356 supply_register (regno, buf); 357 } 358 } 359 360 do_cleanups (old_chain); 361 } 362 363 static void 364 hpux_thread_store_registers (regno) 365 int regno; 366 { 367 cma__t_int_tcb tcb, *tcb_ptr; 368 struct cleanup *old_chain; 369 int i; 370 int first_regno, last_regno; 371 372 tcb_ptr = find_tcb (inferior_pid); 373 374 old_chain = save_inferior_pid (); 375 376 inferior_pid = main_pid; 377 378 if (tcb_ptr->state == cma__c_state_running) 379 { 380 child_ops.to_store_registers (regno); 381 382 do_cleanups (old_chain); 383 384 return; 385 } 386 387 if (regno == -1) 388 { 389 first_regno = 0; 390 last_regno = NUM_REGS - 1; 391 } 392 else 393 { 394 first_regno = regno; 395 last_regno = regno; 396 } 397 398 for (regno = first_regno; regno <= last_regno; regno++) 399 { 400 if (regmap[regno] == -1) 401 child_ops.to_store_registers (regno); 402 else 403 { 404 unsigned char buf[MAX_REGISTER_RAW_SIZE]; 405 CORE_ADDR sp; 406 407 sp = (CORE_ADDR)tcb_ptr->static_ctx.sp - 160; 408 409 if (regno == FLAGS_REGNUM) 410 child_ops.to_store_registers (regno); /* Let lower layer handle this... */ 411 else if (regno == SP_REGNUM) 412 { 413 write_memory ((CORE_ADDR)&tcb_ptr->static_ctx.sp, 414 registers + REGISTER_BYTE (regno), 415 REGISTER_RAW_SIZE (regno)); 416 tcb_ptr->static_ctx.sp = (cma__t_hppa_regs *) 417 (extract_address (registers + REGISTER_BYTE (regno), REGISTER_RAW_SIZE (regno)) + 160); 418 } 419 else if (regno == PC_REGNUM) 420 write_memory (sp - 20, 421 registers + REGISTER_BYTE (regno), 422 REGISTER_RAW_SIZE (regno)); 423 else 424 write_memory (sp + regmap[regno], 425 registers + REGISTER_BYTE (regno), 426 REGISTER_RAW_SIZE (regno)); 427 } 428 } 429 430 do_cleanups (old_chain); 431 } 432 433 /* Get ready to modify the registers array. On machines which store 434 individual registers, this doesn't need to do anything. On machines 435 which store all the registers in one fell swoop, this makes sure 436 that registers contains all the registers from the program being 437 debugged. */ 438 439 static void 440 hpux_thread_prepare_to_store () 441 { 442 child_ops.to_prepare_to_store (); 443 } 444 445 static int 446 hpux_thread_xfer_memory (memaddr, myaddr, len, dowrite, target) 447 CORE_ADDR memaddr; 448 char *myaddr; 449 int len; 450 int dowrite; 451 struct target_ops *target; /* ignored */ 452 { 453 int retval; 454 struct cleanup *old_chain; 455 456 old_chain = save_inferior_pid (); 457 458 inferior_pid = main_pid; 459 460 retval = child_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, target); 461 462 do_cleanups (old_chain); 463 464 return retval; 465 } 466 467 /* Print status information about what we're accessing. */ 468 469 static void 470 hpux_thread_files_info (ignore) 471 struct target_ops *ignore; 472 { 473 child_ops.to_files_info (ignore); 474 } 475 476 static void 477 hpux_thread_kill_inferior () 478 { 479 child_ops.to_kill (); 480 } 481 482 static void 483 hpux_thread_notice_signals (pid) 484 int pid; 485 { 486 child_ops.to_notice_signals (pid); 487 } 488 489 /* Fork an inferior process, and start debugging it with /proc. */ 490 491 static void 492 hpux_thread_create_inferior (exec_file, allargs, env) 493 char *exec_file; 494 char *allargs; 495 char **env; 496 { 497 child_ops.to_create_inferior (exec_file, allargs, env); 498 499 if (hpux_thread_active) 500 { 501 main_pid = inferior_pid; 502 503 push_target (&hpux_thread_ops); 504 505 inferior_pid = find_active_thread (); 506 507 add_thread (inferior_pid); 508 } 509 } 510 511 /* This routine is called whenever a new symbol table is read in, or when all 512 symbol tables are removed. libthread_db can only be initialized when it 513 finds the right variables in libthread.so. Since it's a shared library, 514 those variables don't show up until the library gets mapped and the symbol 515 table is read in. */ 516 517 void 518 hpux_thread_new_objfile (objfile) 519 struct objfile *objfile; 520 { 521 struct minimal_symbol *ms; 522 523 if (!objfile) 524 { 525 hpux_thread_active = 0; 526 527 return; 528 } 529 530 ms = lookup_minimal_symbol ("cma__g_known_threads", NULL, objfile); 531 532 if (!ms) 533 return; 534 535 P_cma__g_known_threads = SYMBOL_VALUE_ADDRESS (ms); 536 537 ms = lookup_minimal_symbol ("cma__g_current_thread", NULL, objfile); 538 539 if (!ms) 540 return; 541 542 P_cma__g_current_thread = SYMBOL_VALUE_ADDRESS (ms); 543 544 hpux_thread_active = 1; 545 } 546 547 /* Clean up after the inferior dies. */ 548 549 static void 550 hpux_thread_mourn_inferior () 551 { 552 child_ops.to_mourn_inferior (); 553 } 554 555 /* Mark our target-struct as eligible for stray "run" and "attach" commands. */ 556 557 static int 558 hpux_thread_can_run () 559 { 560 return child_suppress_run; 561 } 562 563 static int 564 hpux_thread_alive (pid) 565 int pid; 566 { 567 return 1; 568 } 569 570 static void 571 hpux_thread_stop () 572 { 573 child_ops.to_stop (); 574 } 575 576 /* Convert a pid to printable form. */ 577 578 char * 579 hpux_pid_to_str (pid) 580 int pid; 581 { 582 static char buf[100]; 583 584 sprintf (buf, "Thread %d", pid >> 16); 585 586 return buf; 587 } 588 589 struct target_ops hpux_thread_ops = { 590 "hpux-threads", /* to_shortname */ 591 "HPUX threads and pthread.", /* to_longname */ 592 "HPUX threads and pthread support.", /* to_doc */ 593 hpux_thread_open, /* to_open */ 594 0, /* to_close */ 595 hpux_thread_attach, /* to_attach */ 596 hpux_thread_detach, /* to_detach */ 597 hpux_thread_resume, /* to_resume */ 598 hpux_thread_wait, /* to_wait */ 599 hpux_thread_fetch_registers, /* to_fetch_registers */ 600 hpux_thread_store_registers, /* to_store_registers */ 601 hpux_thread_prepare_to_store, /* to_prepare_to_store */ 602 hpux_thread_xfer_memory, /* to_xfer_memory */ 603 hpux_thread_files_info, /* to_files_info */ 604 memory_insert_breakpoint, /* to_insert_breakpoint */ 605 memory_remove_breakpoint, /* to_remove_breakpoint */ 606 terminal_init_inferior, /* to_terminal_init */ 607 terminal_inferior, /* to_terminal_inferior */ 608 terminal_ours_for_output, /* to_terminal_ours_for_output */ 609 terminal_ours, /* to_terminal_ours */ 610 child_terminal_info, /* to_terminal_info */ 611 hpux_thread_kill_inferior, /* to_kill */ 612 0, /* to_load */ 613 0, /* to_lookup_symbol */ 614 hpux_thread_create_inferior, /* to_create_inferior */ 615 hpux_thread_mourn_inferior, /* to_mourn_inferior */ 616 hpux_thread_can_run, /* to_can_run */ 617 hpux_thread_notice_signals, /* to_notice_signals */ 618 hpux_thread_alive, /* to_thread_alive */ 619 hpux_thread_stop, /* to_stop */ 620 process_stratum, /* to_stratum */ 621 0, /* to_next */ 622 1, /* to_has_all_memory */ 623 1, /* to_has_memory */ 624 1, /* to_has_stack */ 625 1, /* to_has_registers */ 626 1, /* to_has_execution */ 627 0, /* sections */ 628 0, /* sections_end */ 629 OPS_MAGIC /* to_magic */ 630 }; 631 632 void 633 _initialize_hpux_thread () 634 { 635 add_target (&hpux_thread_ops); 636 637 child_suppress_run = 1; 638 } 639