1 /* Low level interface for debugging Solaris 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 /proc interface (procfs.c) to 22 provide access to the Solaris user-mode thread implementation. 23 24 Solaris threads are true user-mode threads, which are invoked via the thr_* 25 and pthread_* (native 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. These should not be confused with 28 lightweight processes (LWPs), which are implemented by the kernel, and 29 scheduled without explicit intervention by the process. 30 31 Just to confuse things a little, Solaris threads (both native and Posix) are 32 actually implemented using LWPs. In general, there are going to be more 33 threads than LWPs. There is no fixed correspondence between a thread and an 34 LWP. When a thread wants to run, it gets scheduled onto the first available 35 LWP and can therefore migrate from one LWP to another as time goes on. A 36 sleeping thread may not be associated with an LWP at all! 37 38 To make it possible to mess with threads, Sun provides a library called 39 libthread_db.so.1 (not to be confused with libthread_db.so.0, which doesn't 40 have a published interface). This interface has an upper part, which it 41 provides, and a lower part which I provide. The upper part consists of the 42 td_* routines, which allow me to find all the threads, query their state, 43 etc... The lower part consists of all of the ps_*, which are used by the 44 td_* routines to read/write memory, manipulate LWPs, lookup symbols, etc... 45 The ps_* routines actually do most of their work by calling functions in 46 procfs.c. */ 47 48 #include "defs.h" 49 50 /* Undefine gregset_t and fpregset_t to avoid conflict with defs in xm file. */ 51 52 #ifdef gregset_t 53 #undef gregset_t 54 #endif 55 56 #ifdef fpregset_t 57 #undef fpregset_t 58 #endif 59 60 #include <thread.h> 61 #include <proc_service.h> 62 #include <thread_db.h> 63 #include "gdbthread.h" 64 #include "target.h" 65 #include "inferior.h" 66 #include <fcntl.h> 67 #include <unistd.h> 68 #include <sys/stat.h> 69 #include <dlfcn.h> 70 71 extern struct target_ops sol_thread_ops; /* Forward declaration */ 72 73 extern int procfs_suppress_run; 74 extern struct target_ops procfs_ops; /* target vector for procfs.c */ 75 76 /* Note that these prototypes differ slightly from those used in procfs.c 77 for of two reasons. One, we can't use gregset_t, as that's got a whole 78 different meaning under Solaris (also, see above). Two, we can't use the 79 pointer form here as these are actually arrays of ints (for Sparc's at 80 least), and are automatically coerced into pointers to ints when used as 81 parameters. That makes it impossible to avoid a compiler warning when 82 passing pr{g fp}regset_t's from a parameter to an argument of one of 83 these functions. */ 84 85 extern void supply_gregset PARAMS ((const prgregset_t)); 86 extern void fill_gregset PARAMS ((prgregset_t, int)); 87 extern void supply_fpregset PARAMS ((const prfpregset_t)); 88 extern void fill_fpregset PARAMS ((prfpregset_t, int)); 89 90 /* This struct is defined by us, but mainly used for the proc_service interface. 91 We don't have much use for it, except as a handy place to get a real pid 92 for memory accesses. */ 93 94 struct ps_prochandle 95 { 96 pid_t pid; 97 }; 98 99 struct string_map 100 { 101 int num; 102 char *str; 103 }; 104 105 static struct ps_prochandle main_ph; 106 static td_thragent_t *main_ta; 107 static int sol_thread_active = 0; 108 109 static struct cleanup * save_inferior_pid PARAMS ((void)); 110 static void restore_inferior_pid PARAMS ((int pid)); 111 static char *td_err_string PARAMS ((td_err_e errcode)); 112 static char *td_state_string PARAMS ((td_thr_state_e statecode)); 113 static int thread_to_lwp PARAMS ((int thread_id, int default_lwp)); 114 static void sol_thread_resume PARAMS ((int pid, int step, 115 enum target_signal signo)); 116 static int lwp_to_thread PARAMS ((int lwp)); 117 118 #define THREAD_FLAG 0x80000000 119 #define is_thread(ARG) (((ARG) & THREAD_FLAG) != 0) 120 #define is_lwp(ARG) (((ARG) & THREAD_FLAG) == 0) 121 #define GET_LWP(LWP_ID) (TIDGET(LWP_ID)) 122 #define GET_THREAD(THREAD_ID) (((THREAD_ID) >> 16) & 0x7fff) 123 #define BUILD_LWP(LWP_ID, PID) ((LWP_ID) << 16 | (PID)) 124 #define BUILD_THREAD(THREAD_ID, PID) (THREAD_FLAG | BUILD_LWP (THREAD_ID, PID)) 125 126 /* Pointers to routines from lithread_db resolved by dlopen() */ 127 128 static void 129 (*p_td_log) (const int on_off); 130 static td_err_e 131 (*p_td_ta_new) (const struct ps_prochandle *ph_p, td_thragent_t **ta_pp); 132 static td_err_e 133 (*p_td_ta_delete) (td_thragent_t *ta_p); 134 static td_err_e 135 (*p_td_init) (void); 136 static td_err_e 137 (*p_td_ta_get_ph) (const td_thragent_t *ta_p, struct ps_prochandle **ph_pp); 138 static td_err_e 139 (*p_td_ta_get_nthreads) (const td_thragent_t *ta_p, int *nthread_p); 140 static td_err_e 141 (*p_td_ta_tsd_iter) (const td_thragent_t *ta_p, td_key_iter_f *cb, void *cbdata_p); 142 static td_err_e 143 (*p_td_ta_thr_iter) (const td_thragent_t *ta_p, td_thr_iter_f *cb, void *cbdata_p, td_thr_state_e state, 144 int ti_pri, sigset_t *ti_sigmask_p, unsigned ti_user_flags); 145 static td_err_e 146 (*p_td_thr_validate) (const td_thrhandle_t *th_p); 147 static td_err_e 148 (*p_td_thr_tsd) (const td_thrhandle_t *th_p, const thread_key_t key, void **data_pp); 149 static td_err_e 150 (*p_td_thr_get_info) (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p); 151 static td_err_e 152 (*p_td_thr_getfpregs) (const td_thrhandle_t *th_p, prfpregset_t *fpregset); 153 static td_err_e 154 (*p_td_thr_getxregsize) (const td_thrhandle_t *th_p, int *xregsize); 155 static td_err_e 156 (*p_td_thr_getxregs) (const td_thrhandle_t *th_p, const caddr_t xregset); 157 static td_err_e 158 (*p_td_thr_sigsetmask) (const td_thrhandle_t *th_p, const sigset_t ti_sigmask); 159 static td_err_e 160 (*p_td_thr_setprio) (const td_thrhandle_t *th_p, const int ti_pri); 161 static td_err_e 162 (*p_td_thr_setsigpending) (const td_thrhandle_t *th_p, const uchar_t ti_pending_flag, const sigset_t ti_pending); 163 static td_err_e 164 (*p_td_thr_setfpregs) (const td_thrhandle_t *th_p, const prfpregset_t *fpregset); 165 static td_err_e 166 (*p_td_thr_setxregs) (const td_thrhandle_t *th_p, const caddr_t xregset); 167 static td_err_e 168 (*p_td_ta_map_id2thr) (const td_thragent_t *ta_p, thread_t tid, td_thrhandle_t *th_p); 169 static td_err_e 170 (*p_td_ta_map_lwp2thr) (const td_thragent_t *ta_p, lwpid_t lwpid, td_thrhandle_t *th_p); 171 static td_err_e 172 (*p_td_thr_getgregs) (const td_thrhandle_t *th_p, prgregset_t regset); 173 static td_err_e 174 (*p_td_thr_setgregs) (const td_thrhandle_t *th_p, const prgregset_t regset); 175 176 /* 177 178 LOCAL FUNCTION 179 180 td_err_string - Convert a thread_db error code to a string 181 182 SYNOPSIS 183 184 char * td_err_string (errcode) 185 186 DESCRIPTION 187 188 Return the thread_db error string associated with errcode. If errcode 189 is unknown, then return a message. 190 191 */ 192 193 static char * 194 td_err_string (errcode) 195 td_err_e errcode; 196 { 197 static struct string_map 198 td_err_table[] = { 199 {TD_OK, "generic \"call succeeded\""}, 200 {TD_ERR, "generic error."}, 201 {TD_NOTHR, "no thread can be found to satisfy query"}, 202 {TD_NOSV, "no synch. variable can be found to satisfy query"}, 203 {TD_NOLWP, "no lwp can be found to satisfy query"}, 204 {TD_BADPH, "invalid process handle"}, 205 {TD_BADTH, "invalid thread handle"}, 206 {TD_BADSH, "invalid synchronization handle"}, 207 {TD_BADTA, "invalid thread agent"}, 208 {TD_BADKEY, "invalid key"}, 209 {TD_NOMSG, "td_thr_event_getmsg() called when there was no message"}, 210 {TD_NOFPREGS, "FPU register set not available for given thread"}, 211 {TD_NOLIBTHREAD, "application not linked with libthread"}, 212 {TD_NOEVENT, "requested event is not supported"}, 213 {TD_NOCAPAB, "capability not available"}, 214 {TD_DBERR, "Debugger service failed"}, 215 {TD_NOAPLIC, "Operation not applicable to"}, 216 {TD_NOTSD, "No thread specific data for this thread"}, 217 {TD_MALLOC, "Malloc failed"}, 218 {TD_PARTIALREG, "Only part of register set was writen/read"}, 219 {TD_NOXREGS, "X register set not available for given thread"} 220 }; 221 const int td_err_size = sizeof td_err_table / sizeof (struct string_map); 222 int i; 223 static char buf[50]; 224 225 for (i = 0; i < td_err_size; i++) 226 if (td_err_table[i].num == errcode) 227 return td_err_table[i].str; 228 229 sprintf (buf, "Unknown thread_db error code: %d", errcode); 230 231 return buf; 232 } 233 234 /* 235 236 LOCAL FUNCTION 237 238 td_state_string - Convert a thread_db state code to a string 239 240 SYNOPSIS 241 242 char * td_state_string (statecode) 243 244 DESCRIPTION 245 246 Return the thread_db state string associated with statecode. If 247 statecode is unknown, then return a message. 248 249 */ 250 251 static char * 252 td_state_string (statecode) 253 td_thr_state_e statecode; 254 { 255 static struct string_map 256 td_thr_state_table[] = { 257 {TD_THR_ANY_STATE, "any state"}, 258 {TD_THR_UNKNOWN, "unknown"}, 259 {TD_THR_STOPPED, "stopped"}, 260 {TD_THR_RUN, "run"}, 261 {TD_THR_ACTIVE, "active"}, 262 {TD_THR_ZOMBIE, "zombie"}, 263 {TD_THR_SLEEP, "sleep"}, 264 {TD_THR_STOPPED_ASLEEP, "stopped asleep"} 265 }; 266 const int td_thr_state_table_size = sizeof td_thr_state_table / sizeof (struct string_map); 267 int i; 268 static char buf[50]; 269 270 for (i = 0; i < td_thr_state_table_size; i++) 271 if (td_thr_state_table[i].num == statecode) 272 return td_thr_state_table[i].str; 273 274 sprintf (buf, "Unknown thread_db state code: %d", statecode); 275 276 return buf; 277 } 278 279 /* 280 281 LOCAL FUNCTION 282 283 thread_to_lwp - Convert a Posix or Solaris thread id to a LWP id. 284 285 SYNOPSIS 286 287 int thread_to_lwp (thread_id, default_lwp) 288 289 DESCRIPTION 290 291 This function converts a Posix or Solaris thread id to a lightweight 292 process id. If thread_id is non-existent, that's an error. If it's 293 an inactive thread, then we return default_lwp. 294 295 NOTES 296 297 This function probably shouldn't call error()... 298 299 */ 300 301 static int 302 thread_to_lwp (thread_id, default_lwp) 303 int thread_id; 304 int default_lwp; 305 { 306 td_thrinfo_t ti; 307 td_thrhandle_t th; 308 td_err_e val; 309 int pid; 310 int lwp; 311 312 if (is_lwp (thread_id)) 313 return thread_id; /* It's already an LWP id */ 314 315 /* It's a thread. Convert to lwp */ 316 317 pid = PIDGET (thread_id); 318 thread_id = GET_THREAD(thread_id); 319 320 val = p_td_ta_map_id2thr (main_ta, thread_id, &th); 321 if (val != TD_OK) 322 error ("thread_to_lwp: td_ta_map_id2thr %s", td_err_string (val)); 323 324 val = p_td_thr_get_info (&th, &ti); 325 326 if (val != TD_OK) 327 error ("thread_to_lwp: td_thr_get_info: %s", td_err_string (val)); 328 329 if (ti.ti_state != TD_THR_ACTIVE) 330 { 331 if (default_lwp != -1) 332 return default_lwp; 333 error ("thread_to_lwp: thread state not active: %s", 334 td_state_string (ti.ti_state)); 335 } 336 337 lwp = BUILD_LWP (ti.ti_lid, pid); 338 339 return lwp; 340 } 341 342 /* 343 344 LOCAL FUNCTION 345 346 lwp_to_thread - Convert a LWP id to a Posix or Solaris thread id. 347 348 SYNOPSIS 349 350 int lwp_to_thread (lwp_id) 351 352 DESCRIPTION 353 354 This function converts a lightweight process id to a Posix or Solaris 355 thread id. If thread_id is non-existent, that's an error. 356 357 NOTES 358 359 This function probably shouldn't call error()... 360 361 */ 362 363 static int 364 lwp_to_thread (lwp) 365 int lwp; 366 { 367 td_thrinfo_t ti; 368 td_thrhandle_t th; 369 td_err_e val; 370 int pid; 371 int thread_id; 372 373 if (is_thread (lwp)) 374 return lwp; /* It's already a thread id */ 375 376 /* It's an lwp. Convert it to a thread id. */ 377 378 pid = PIDGET (lwp); 379 lwp = GET_LWP (lwp); 380 381 val = p_td_ta_map_lwp2thr (main_ta, lwp, &th); 382 if (val != TD_OK) 383 error ("lwp_to_thread: td_thr_get_info: %s.", td_err_string (val)); 384 385 val = p_td_thr_get_info (&th, &ti); 386 387 if (val != TD_OK) 388 error ("lwp_to_thread: td_thr_get_info: %s.", td_err_string (val)); 389 390 thread_id = BUILD_THREAD (ti.ti_tid, pid); 391 392 return thread_id; 393 } 394 395 /* 396 397 LOCAL FUNCTION 398 399 save_inferior_pid - Save inferior_pid on the cleanup list 400 restore_inferior_pid - Restore inferior_pid from the cleanup list 401 402 SYNOPSIS 403 404 struct cleanup *save_inferior_pid () 405 void restore_inferior_pid (int pid) 406 407 DESCRIPTION 408 409 These two functions act in unison to restore inferior_pid in 410 case of an error. 411 412 NOTES 413 414 inferior_pid is a global variable that needs to be changed by many of 415 these routines before calling functions in procfs.c. In order to 416 guarantee that inferior_pid gets restored (in case of errors), you 417 need to call save_inferior_pid before changing it. At the end of the 418 function, you should invoke do_cleanups to restore it. 419 420 */ 421 422 423 static struct cleanup * 424 save_inferior_pid () 425 { 426 return make_cleanup (restore_inferior_pid, inferior_pid); 427 } 428 429 static void 430 restore_inferior_pid (pid) 431 int pid; 432 { 433 inferior_pid = pid; 434 } 435 436 437 /* Most target vector functions from here on actually just pass through to 438 procfs.c, as they don't need to do anything specific for threads. */ 439 440 441 /* ARGSUSED */ 442 static void 443 sol_thread_open (arg, from_tty) 444 char *arg; 445 int from_tty; 446 { 447 procfs_ops.to_open (arg, from_tty); 448 } 449 450 /* Attach to process PID, then initialize for debugging it 451 and wait for the trace-trap that results from attaching. */ 452 453 static void 454 sol_thread_attach (args, from_tty) 455 char *args; 456 int from_tty; 457 { 458 procfs_ops.to_attach (args, from_tty); 459 460 /* XXX - might want to iterate over all the threads and register them. */ 461 } 462 463 /* Take a program previously attached to and detaches it. 464 The program resumes execution and will no longer stop 465 on signals, etc. We'd better not have left any breakpoints 466 in the program or it'll die when it hits one. For this 467 to work, it may be necessary for the process to have been 468 previously attached. It *might* work if the program was 469 started via the normal ptrace (PTRACE_TRACEME). */ 470 471 static void 472 sol_thread_detach (args, from_tty) 473 char *args; 474 int from_tty; 475 { 476 procfs_ops.to_detach (args, from_tty); 477 } 478 479 /* Resume execution of process PID. If STEP is nozero, then 480 just single step it. If SIGNAL is nonzero, restart it with that 481 signal activated. We may have to convert pid from a thread-id to an LWP id 482 for procfs. */ 483 484 static void 485 sol_thread_resume (pid, step, signo) 486 int pid; 487 int step; 488 enum target_signal signo; 489 { 490 struct cleanup *old_chain; 491 492 old_chain = save_inferior_pid (); 493 494 inferior_pid = thread_to_lwp (inferior_pid, main_ph.pid); 495 496 if (pid != -1) 497 { 498 pid = thread_to_lwp (pid, -2); 499 if (pid == -2) /* Inactive thread */ 500 error ("This version of Solaris can't start inactive threads."); 501 } 502 503 procfs_ops.to_resume (pid, step, signo); 504 505 do_cleanups (old_chain); 506 } 507 508 /* Wait for any threads to stop. We may have to convert PID from a thread id 509 to a LWP id, and vice versa on the way out. */ 510 511 static int 512 sol_thread_wait (pid, ourstatus) 513 int pid; 514 struct target_waitstatus *ourstatus; 515 { 516 int rtnval; 517 int save_pid; 518 struct cleanup *old_chain; 519 520 save_pid = inferior_pid; 521 old_chain = save_inferior_pid (); 522 523 inferior_pid = thread_to_lwp (inferior_pid, main_ph.pid); 524 525 if (pid != -1) 526 pid = thread_to_lwp (pid, -1); 527 528 rtnval = procfs_ops.to_wait (pid, ourstatus); 529 530 if (rtnval != save_pid 531 && !in_thread_list (rtnval)) 532 { 533 fprintf_unfiltered (gdb_stderr, "[New %s]\n", 534 target_pid_to_str (rtnval)); 535 add_thread (rtnval); 536 } 537 538 /* During process initialization, we may get here without the thread package 539 being initialized, since that can only happen after we've found the shared 540 libs. */ 541 542 /* Map the LWP of interest back to the appropriate thread ID */ 543 544 rtnval = lwp_to_thread (rtnval); 545 546 do_cleanups (old_chain); 547 548 return rtnval; 549 } 550 551 static void 552 sol_thread_fetch_registers (regno) 553 int regno; 554 { 555 thread_t thread; 556 td_thrhandle_t thandle; 557 td_err_e val; 558 prgregset_t gregset; 559 prfpregset_t fpregset; 560 #if 0 561 int xregsize; 562 caddr_t xregset; 563 #endif 564 565 /* Convert inferior_pid into a td_thrhandle_t */ 566 567 thread = GET_THREAD (inferior_pid); 568 569 if (thread == 0) 570 error ("sol_thread_fetch_registers: thread == 0"); 571 572 val = p_td_ta_map_id2thr (main_ta, thread, &thandle); 573 if (val != TD_OK) 574 error ("sol_thread_fetch_registers: td_ta_map_id2thr: %s", 575 td_err_string (val)); 576 577 /* Get the integer regs */ 578 579 val = p_td_thr_getgregs (&thandle, gregset); 580 if (val != TD_OK 581 && val != TD_PARTIALREG) 582 error ("sol_thread_fetch_registers: td_thr_getgregs %s", 583 td_err_string (val)); 584 585 /* For the sparc, TD_PARTIALREG means that only i0->i7, l0->l7, pc and sp 586 are saved (by a thread context switch). */ 587 588 /* And, now the fp regs */ 589 590 val = p_td_thr_getfpregs (&thandle, &fpregset); 591 if (val != TD_OK 592 && val != TD_NOFPREGS) 593 error ("sol_thread_fetch_registers: td_thr_getfpregs %s", 594 td_err_string (val)); 595 596 /* Note that we must call supply_{g fp}regset *after* calling the td routines 597 because the td routines call ps_lget* which affect the values stored in the 598 registers array. */ 599 600 supply_gregset (gregset); 601 supply_fpregset (fpregset); 602 603 #if 0 604 /* thread_db doesn't seem to handle this right */ 605 val = td_thr_getxregsize (&thandle, &xregsize); 606 if (val != TD_OK && val != TD_NOXREGS) 607 error ("sol_thread_fetch_registers: td_thr_getxregsize %s", 608 td_err_string (val)); 609 610 if (val == TD_OK) 611 { 612 xregset = alloca (xregsize); 613 val = td_thr_getxregs (&thandle, xregset); 614 if (val != TD_OK) 615 error ("sol_thread_fetch_registers: td_thr_getxregs %s", 616 td_err_string (val)); 617 } 618 #endif 619 } 620 621 static void 622 sol_thread_store_registers (regno) 623 int regno; 624 { 625 thread_t thread; 626 td_thrhandle_t thandle; 627 td_err_e val; 628 prgregset_t regset; 629 prfpregset_t fpregset; 630 #if 0 631 int xregsize; 632 caddr_t xregset; 633 #endif 634 635 /* Convert inferior_pid into a td_thrhandle_t */ 636 637 thread = GET_THREAD (inferior_pid); 638 639 val = p_td_ta_map_id2thr (main_ta, thread, &thandle); 640 if (val != TD_OK) 641 error ("sol_thread_store_registers: td_ta_map_id2thr %s", 642 td_err_string (val)); 643 644 if (regno != -1) 645 { /* Not writing all the regs */ 646 val = p_td_thr_getgregs (&thandle, regset); 647 if (val != TD_OK) 648 error ("sol_thread_store_registers: td_thr_getgregs %s", 649 td_err_string (val)); 650 val = p_td_thr_getfpregs (&thandle, &fpregset); 651 if (val != TD_OK) 652 error ("sol_thread_store_registers: td_thr_getfpregs %s", 653 td_err_string (val)); 654 655 #if 0 656 /* thread_db doesn't seem to handle this right */ 657 val = td_thr_getxregsize (&thandle, &xregsize); 658 if (val != TD_OK && val != TD_NOXREGS) 659 error ("sol_thread_store_registers: td_thr_getxregsize %s", 660 td_err_string (val)); 661 662 if (val == TD_OK) 663 { 664 xregset = alloca (xregsize); 665 val = td_thr_getxregs (&thandle, xregset); 666 if (val != TD_OK) 667 error ("sol_thread_store_registers: td_thr_getxregs %s", 668 td_err_string (val)); 669 } 670 #endif 671 } 672 673 fill_gregset (regset, regno); 674 fill_fpregset (fpregset, regno); 675 676 val = p_td_thr_setgregs (&thandle, regset); 677 if (val != TD_OK) 678 error ("sol_thread_store_registers: td_thr_setgregs %s", 679 td_err_string (val)); 680 val = p_td_thr_setfpregs (&thandle, &fpregset); 681 if (val != TD_OK) 682 error ("sol_thread_store_registers: td_thr_setfpregs %s", 683 td_err_string (val)); 684 685 #if 0 686 /* thread_db doesn't seem to handle this right */ 687 val = td_thr_getxregsize (&thandle, &xregsize); 688 if (val != TD_OK && val != TD_NOXREGS) 689 error ("sol_thread_store_registers: td_thr_getxregsize %s", 690 td_err_string (val)); 691 692 /* Should probably do something about writing the xregs here, but what are 693 they? */ 694 #endif 695 } 696 697 /* Get ready to modify the registers array. On machines which store 698 individual registers, this doesn't need to do anything. On machines 699 which store all the registers in one fell swoop, this makes sure 700 that registers contains all the registers from the program being 701 debugged. */ 702 703 static void 704 sol_thread_prepare_to_store () 705 { 706 procfs_ops.to_prepare_to_store (); 707 } 708 709 static int 710 sol_thread_xfer_memory (memaddr, myaddr, len, dowrite, target) 711 CORE_ADDR memaddr; 712 char *myaddr; 713 int len; 714 int dowrite; 715 struct target_ops *target; /* ignored */ 716 { 717 int retval; 718 struct cleanup *old_chain; 719 720 old_chain = save_inferior_pid (); 721 722 if (is_thread (inferior_pid)) 723 inferior_pid = main_ph.pid; /* It's a thread. Convert to lwp */ 724 725 retval = procfs_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, target); 726 727 do_cleanups (old_chain); 728 729 return retval; 730 } 731 732 /* Print status information about what we're accessing. */ 733 734 static void 735 sol_thread_files_info (ignore) 736 struct target_ops *ignore; 737 { 738 procfs_ops.to_files_info (ignore); 739 } 740 741 static void 742 sol_thread_kill_inferior () 743 { 744 procfs_ops.to_kill (); 745 } 746 747 static void 748 sol_thread_notice_signals (pid) 749 int pid; 750 { 751 procfs_ops.to_notice_signals (pid); 752 } 753 754 void target_new_objfile PARAMS ((struct objfile *objfile)); 755 756 /* Fork an inferior process, and start debugging it with /proc. */ 757 758 static void 759 sol_thread_create_inferior (exec_file, allargs, env) 760 char *exec_file; 761 char *allargs; 762 char **env; 763 { 764 procfs_ops.to_create_inferior (exec_file, allargs, env); 765 766 if (sol_thread_active) 767 { 768 main_ph.pid = inferior_pid; /* Save for xfer_memory */ 769 770 push_target (&sol_thread_ops); 771 772 inferior_pid = lwp_to_thread (inferior_pid); 773 774 add_thread (inferior_pid); 775 } 776 } 777 778 /* This routine is called whenever a new symbol table is read in, or when all 779 symbol tables are removed. libthread_db can only be initialized when it 780 finds the right variables in libthread.so. Since it's a shared library, 781 those variables don't show up until the library gets mapped and the symbol 782 table is read in. */ 783 784 void 785 sol_thread_new_objfile (objfile) 786 struct objfile *objfile; 787 { 788 td_err_e val; 789 790 if (!objfile) 791 { 792 sol_thread_active = 0; 793 794 return; 795 } 796 797 /* Now, initialize the thread debugging library. This needs to be done after 798 the shared libraries are located because it needs information from the 799 user's thread library. */ 800 801 val = p_td_init (); 802 if (val != TD_OK) 803 error ("target_new_objfile: td_init: %s", td_err_string (val)); 804 805 val = p_td_ta_new (&main_ph, &main_ta); 806 if (val == TD_NOLIBTHREAD) 807 return; 808 else if (val != TD_OK) 809 error ("target_new_objfile: td_ta_new: %s", td_err_string (val)); 810 811 sol_thread_active = 1; 812 } 813 814 /* Clean up after the inferior dies. */ 815 816 static void 817 sol_thread_mourn_inferior () 818 { 819 procfs_ops.to_mourn_inferior (); 820 } 821 822 /* Mark our target-struct as eligible for stray "run" and "attach" commands. */ 823 824 static int 825 sol_thread_can_run () 826 { 827 return procfs_suppress_run; 828 } 829 830 static int 831 sol_thread_alive (pid) 832 int pid; 833 { 834 return 1; 835 } 836 837 static void 838 sol_thread_stop () 839 { 840 procfs_ops.to_stop (); 841 } 842 843 /* These routines implement the lower half of the thread_db interface. Ie: the 844 ps_* routines. */ 845 846 /* The next four routines are called by thread_db to tell us to stop and stop 847 a particular process or lwp. Since GDB ensures that these are all stopped 848 by the time we call anything in thread_db, these routines need to do 849 nothing. */ 850 851 ps_err_e 852 ps_pstop (const struct ps_prochandle *ph) 853 { 854 return PS_OK; 855 } 856 857 ps_err_e 858 ps_pcontinue (const struct ps_prochandle *ph) 859 { 860 return PS_OK; 861 } 862 863 ps_err_e 864 ps_lstop (const struct ps_prochandle *ph, lwpid_t lwpid) 865 { 866 return PS_OK; 867 } 868 869 ps_err_e 870 ps_lcontinue (const struct ps_prochandle *ph, lwpid_t lwpid) 871 { 872 return PS_OK; 873 } 874 875 ps_err_e 876 ps_pglobal_lookup (const struct ps_prochandle *ph, const char *ld_object_name, 877 const char *ld_symbol_name, paddr_t *ld_symbol_addr) 878 { 879 struct minimal_symbol *ms; 880 881 ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL); 882 883 if (!ms) 884 return PS_NOSYM; 885 886 *ld_symbol_addr = SYMBOL_VALUE_ADDRESS (ms); 887 888 return PS_OK; 889 } 890 891 /* Common routine for reading and writing memory. */ 892 893 static ps_err_e 894 rw_common (int dowrite, const struct ps_prochandle *ph, paddr_t addr, 895 char *buf, int size) 896 { 897 struct cleanup *old_chain; 898 899 old_chain = save_inferior_pid (); 900 901 if (is_thread (inferior_pid)) 902 inferior_pid = main_ph.pid; /* It's a thread. Convert to lwp */ 903 904 while (size > 0) 905 { 906 int cc; 907 908 cc = procfs_ops.to_xfer_memory (addr, buf, size, dowrite, &procfs_ops); 909 910 if (cc < 0) 911 { 912 if (dowrite == 0) 913 print_sys_errmsg ("ps_pdread (): read", errno); 914 else 915 print_sys_errmsg ("ps_pdread (): write", errno); 916 917 do_cleanups (old_chain); 918 919 return PS_ERR; 920 } 921 size -= cc; 922 buf += cc; 923 } 924 925 do_cleanups (old_chain); 926 927 return PS_OK; 928 } 929 930 ps_err_e 931 ps_pdread (const struct ps_prochandle *ph, paddr_t addr, char *buf, int size) 932 { 933 return rw_common (0, ph, addr, buf, size); 934 } 935 936 ps_err_e 937 ps_pdwrite (const struct ps_prochandle *ph, paddr_t addr, char *buf, int size) 938 { 939 return rw_common (1, ph, addr, buf, size); 940 } 941 942 ps_err_e 943 ps_ptread (const struct ps_prochandle *ph, paddr_t addr, char *buf, int size) 944 { 945 return rw_common (0, ph, addr, buf, size); 946 } 947 948 ps_err_e 949 ps_ptwrite (const struct ps_prochandle *ph, paddr_t addr, char *buf, int size) 950 { 951 return rw_common (1, ph, addr, buf, size); 952 } 953 954 /* Get integer regs */ 955 956 ps_err_e 957 ps_lgetregs (const struct ps_prochandle *ph, lwpid_t lwpid, 958 prgregset_t gregset) 959 { 960 struct cleanup *old_chain; 961 962 old_chain = save_inferior_pid (); 963 964 inferior_pid = BUILD_LWP (lwpid, PIDGET (inferior_pid)); 965 966 procfs_ops.to_fetch_registers (-1); 967 fill_gregset (gregset, -1); 968 969 do_cleanups (old_chain); 970 971 return PS_OK; 972 } 973 974 /* Set integer regs */ 975 976 ps_err_e 977 ps_lsetregs (const struct ps_prochandle *ph, lwpid_t lwpid, 978 const prgregset_t gregset) 979 { 980 struct cleanup *old_chain; 981 982 old_chain = save_inferior_pid (); 983 984 inferior_pid = BUILD_LWP (lwpid, PIDGET (inferior_pid)); 985 986 supply_gregset (gregset); 987 procfs_ops.to_store_registers (-1); 988 989 do_cleanups (old_chain); 990 991 return PS_OK; 992 } 993 994 void 995 ps_plog (const char *fmt, ...) 996 { 997 va_list args; 998 999 va_start (args, fmt); 1000 1001 vfprintf_filtered (gdb_stderr, fmt, args); 1002 } 1003 1004 /* Get size of extra register set. Currently a noop. */ 1005 1006 ps_err_e 1007 ps_lgetxregsize (const struct ps_prochandle *ph, lwpid_t lwpid, int *xregsize) 1008 { 1009 #if 0 1010 int lwp_fd; 1011 int regsize; 1012 ps_err_e val; 1013 1014 val = get_lwp_fd (ph, lwpid, &lwp_fd); 1015 if (val != PS_OK) 1016 return val; 1017 1018 if (ioctl (lwp_fd, PIOCGXREGSIZE, ®size)) 1019 { 1020 if (errno == EINVAL) 1021 return PS_NOFREGS; /* XXX Wrong code, but this is the closest 1022 thing in proc_service.h */ 1023 1024 print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno); 1025 return PS_ERR; 1026 } 1027 #endif 1028 1029 return PS_OK; 1030 } 1031 1032 /* Get extra register set. Currently a noop. */ 1033 1034 ps_err_e 1035 ps_lgetxregs (const struct ps_prochandle *ph, lwpid_t lwpid, caddr_t xregset) 1036 { 1037 #if 0 1038 int lwp_fd; 1039 ps_err_e val; 1040 1041 val = get_lwp_fd (ph, lwpid, &lwp_fd); 1042 if (val != PS_OK) 1043 return val; 1044 1045 if (ioctl (lwp_fd, PIOCGXREG, xregset)) 1046 { 1047 print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno); 1048 return PS_ERR; 1049 } 1050 #endif 1051 1052 return PS_OK; 1053 } 1054 1055 /* Set extra register set. Currently a noop. */ 1056 1057 ps_err_e 1058 ps_lsetxregs (const struct ps_prochandle *ph, lwpid_t lwpid, caddr_t xregset) 1059 { 1060 #if 0 1061 int lwp_fd; 1062 ps_err_e val; 1063 1064 val = get_lwp_fd (ph, lwpid, &lwp_fd); 1065 if (val != PS_OK) 1066 return val; 1067 1068 if (ioctl (lwp_fd, PIOCSXREG, xregset)) 1069 { 1070 print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno); 1071 return PS_ERR; 1072 } 1073 #endif 1074 1075 return PS_OK; 1076 } 1077 1078 /* Get floating-point regs. */ 1079 1080 ps_err_e 1081 ps_lgetfpregs (const struct ps_prochandle *ph, lwpid_t lwpid, 1082 prfpregset_t *fpregset) 1083 { 1084 struct cleanup *old_chain; 1085 1086 old_chain = save_inferior_pid (); 1087 1088 inferior_pid = BUILD_LWP (lwpid, PIDGET (inferior_pid)); 1089 1090 procfs_ops.to_fetch_registers (-1); 1091 fill_fpregset (*fpregset, -1); 1092 1093 do_cleanups (old_chain); 1094 1095 return PS_OK; 1096 } 1097 1098 /* Set floating-point regs. */ 1099 1100 ps_err_e 1101 ps_lsetfpregs (const struct ps_prochandle *ph, lwpid_t lwpid, 1102 const prfpregset_t *fpregset) 1103 { 1104 struct cleanup *old_chain; 1105 1106 old_chain = save_inferior_pid (); 1107 1108 inferior_pid = BUILD_LWP (lwpid, PIDGET (inferior_pid)); 1109 1110 supply_fpregset (*fpregset); 1111 procfs_ops.to_store_registers (-1); 1112 1113 do_cleanups (old_chain); 1114 1115 return PS_OK; 1116 } 1117 1118 /* Convert a pid to printable form. */ 1119 1120 char * 1121 solaris_pid_to_str (pid) 1122 int pid; 1123 { 1124 static char buf[100]; 1125 1126 if (is_thread (pid)) 1127 { 1128 int lwp; 1129 1130 lwp = thread_to_lwp (pid, -2); 1131 1132 if (lwp != -2) 1133 sprintf (buf, "Thread %d (LWP %d)", GET_THREAD (pid), GET_LWP (lwp)); 1134 else 1135 sprintf (buf, "Thread %d ", GET_THREAD (pid)); 1136 } 1137 else 1138 sprintf (buf, "LWP %d ", GET_LWP (pid)); 1139 1140 return buf; 1141 } 1142 1143 struct target_ops sol_thread_ops = { 1144 "solaris-threads", /* to_shortname */ 1145 "Solaris threads and pthread.", /* to_longname */ 1146 "Solaris threads and pthread support.", /* to_doc */ 1147 sol_thread_open, /* to_open */ 1148 0, /* to_close */ 1149 sol_thread_attach, /* to_attach */ 1150 sol_thread_detach, /* to_detach */ 1151 sol_thread_resume, /* to_resume */ 1152 sol_thread_wait, /* to_wait */ 1153 sol_thread_fetch_registers, /* to_fetch_registers */ 1154 sol_thread_store_registers, /* to_store_registers */ 1155 sol_thread_prepare_to_store, /* to_prepare_to_store */ 1156 sol_thread_xfer_memory, /* to_xfer_memory */ 1157 sol_thread_files_info, /* to_files_info */ 1158 memory_insert_breakpoint, /* to_insert_breakpoint */ 1159 memory_remove_breakpoint, /* to_remove_breakpoint */ 1160 terminal_init_inferior, /* to_terminal_init */ 1161 terminal_inferior, /* to_terminal_inferior */ 1162 terminal_ours_for_output, /* to_terminal_ours_for_output */ 1163 terminal_ours, /* to_terminal_ours */ 1164 child_terminal_info, /* to_terminal_info */ 1165 sol_thread_kill_inferior, /* to_kill */ 1166 0, /* to_load */ 1167 0, /* to_lookup_symbol */ 1168 sol_thread_create_inferior, /* to_create_inferior */ 1169 sol_thread_mourn_inferior, /* to_mourn_inferior */ 1170 sol_thread_can_run, /* to_can_run */ 1171 sol_thread_notice_signals, /* to_notice_signals */ 1172 sol_thread_alive, /* to_thread_alive */ 1173 sol_thread_stop, /* to_stop */ 1174 process_stratum, /* to_stratum */ 1175 0, /* to_next */ 1176 1, /* to_has_all_memory */ 1177 1, /* to_has_memory */ 1178 1, /* to_has_stack */ 1179 1, /* to_has_registers */ 1180 1, /* to_has_execution */ 1181 0, /* sections */ 1182 0, /* sections_end */ 1183 OPS_MAGIC /* to_magic */ 1184 }; 1185 1186 void 1187 _initialize_sol_thread () 1188 { 1189 void *dlhandle; 1190 1191 dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW); 1192 if (!dlhandle) 1193 goto die; 1194 1195 #define resolve(X) \ 1196 if (!(p_##X = dlsym (dlhandle, #X))) \ 1197 goto die; 1198 1199 resolve (td_log); 1200 resolve (td_ta_new); 1201 resolve (td_ta_delete); 1202 resolve (td_init); 1203 resolve (td_ta_get_ph); 1204 resolve (td_ta_get_nthreads); 1205 resolve (td_ta_tsd_iter); 1206 resolve (td_ta_thr_iter); 1207 resolve (td_thr_validate); 1208 resolve (td_thr_tsd); 1209 resolve (td_thr_get_info); 1210 resolve (td_thr_getfpregs); 1211 resolve (td_thr_getxregsize); 1212 resolve (td_thr_getxregs); 1213 resolve (td_thr_sigsetmask); 1214 resolve (td_thr_setprio); 1215 resolve (td_thr_setsigpending); 1216 resolve (td_thr_setfpregs); 1217 resolve (td_thr_setxregs); 1218 resolve (td_ta_map_id2thr); 1219 resolve (td_ta_map_lwp2thr); 1220 resolve (td_thr_getgregs); 1221 resolve (td_thr_setgregs); 1222 1223 add_target (&sol_thread_ops); 1224 1225 procfs_suppress_run = 1; 1226 1227 return; 1228 1229 die: 1230 1231 fprintf_unfiltered (gdb_stderr, "[GDB will not be able to debug user-mode threads: %s]\n", dlerror ()); 1232 1233 if (dlhandle) 1234 dlclose (dlhandle); 1235 1236 return; 1237 } 1238