1/* Solaris threads debugging interface. 2 3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4 2007 Free Software Foundation, Inc. 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 10 the Free Software Foundation; either version 3 of the License, or 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 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20 21/* This module implements a sort of half target that sits between the 22 machine-independent parts of GDB and the /proc interface (procfs.c) 23 to provide access to the Solaris user-mode thread implementation. 24 25 Solaris threads are true user-mode threads, which are invoked via 26 the thr_* and pthread_* (native and POSIX respectivly) interfaces. 27 These are mostly implemented in user-space, with all thread context 28 kept in various structures that live in the user's heap. These 29 should not be confused with lightweight processes (LWPs), which are 30 implemented by the kernel, and scheduled without explicit 31 intervention by the process. 32 33 Just to confuse things a little, Solaris threads (both native and 34 POSIX) are actually implemented using LWPs. In general, there are 35 going to be more threads than LWPs. There is no fixed 36 correspondence between a thread and an LWP. When a thread wants to 37 run, it gets scheduled onto the first available LWP and can 38 therefore migrate from one LWP to another as time goes on. A 39 sleeping thread may not be associated with an LWP at all! 40 41 To make it possible to mess with threads, Sun provides a library 42 called libthread_db.so.1 (not to be confused with 43 libthread_db.so.0, which doesn't have a published interface). This 44 interface has an upper part, which it provides, and a lower part 45 which we provide. The upper part consists of the td_* routines, 46 which allow us to find all the threads, query their state, etc... 47 The lower part consists of all of the ps_*, which are used by the 48 td_* routines to read/write memory, manipulate LWPs, lookup 49 symbols, etc... The ps_* routines actually do most of their work 50 by calling functions in procfs.c. */ 51 52#include "defs.h" 53#include <thread.h> 54#include <proc_service.h> 55#include <thread_db.h> 56#include "gdbthread.h" 57#include "target.h" 58#include "inferior.h" 59#include <fcntl.h> 60#include "gdb_stat.h" 61#include <dlfcn.h> 62#include "gdbcmd.h" 63#include "gdbcore.h" 64#include "regcache.h" 65#include "solib.h" 66#include "symfile.h" 67#include "observer.h" 68 69#include "gdb_string.h" 70 71extern struct target_ops sol_thread_ops; /* Forward declaration */ 72extern struct target_ops sol_core_ops; /* Forward declaration */ 73 74/* place to store core_ops before we overwrite it */ 75static struct target_ops orig_core_ops; 76 77struct target_ops sol_thread_ops; 78struct target_ops sol_core_ops; 79 80extern int procfs_suppress_run; 81extern struct target_ops procfs_ops; /* target vector for procfs.c */ 82extern struct target_ops core_ops; /* target vector for corelow.c */ 83extern char *procfs_pid_to_str (ptid_t ptid); 84 85/* Prototypes for supply_gregset etc. */ 86#include "gregset.h" 87 88/* This struct is defined by us, but mainly used for the proc_service 89 interface. We don't have much use for it, except as a handy place 90 to get a real PID for memory accesses. */ 91 92struct ps_prochandle 93{ 94 ptid_t ptid; 95}; 96 97struct string_map 98{ 99 int num; 100 char *str; 101}; 102 103static struct ps_prochandle main_ph; 104static td_thragent_t *main_ta; 105static int sol_thread_active = 0; 106 107static void sol_thread_resume (ptid_t ptid, int step, enum target_signal signo); 108static int sol_thread_alive (ptid_t ptid); 109static void sol_core_close (int quitting); 110 111static void init_sol_thread_ops (void); 112static void init_sol_core_ops (void); 113 114/* Default definitions: These must be defined in tm.h if they are to 115 be shared with a process module such as procfs. */ 116 117#define GET_PID(ptid) ptid_get_pid (ptid) 118#define GET_LWP(ptid) ptid_get_lwp (ptid) 119#define GET_THREAD(ptid) ptid_get_tid (ptid) 120 121#define is_lwp(ptid) (GET_LWP (ptid) != 0) 122#define is_thread(ptid) (GET_THREAD (ptid) != 0) 123 124#define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0) 125#define BUILD_THREAD(tid, pid) ptid_build (pid, 0, tid) 126 127/* Pointers to routines from libthread_db resolved by dlopen(). */ 128 129static void (*p_td_log)(const int on_off); 130static td_err_e (*p_td_ta_new)(const struct ps_prochandle *ph_p, 131 td_thragent_t **ta_pp); 132static td_err_e (*p_td_ta_delete)(td_thragent_t *ta_p); 133static td_err_e (*p_td_init)(void); 134static td_err_e (*p_td_ta_get_ph)(const td_thragent_t *ta_p, 135 struct ps_prochandle **ph_pp); 136static td_err_e (*p_td_ta_get_nthreads)(const td_thragent_t *ta_p, 137 int *nthread_p); 138static td_err_e (*p_td_ta_tsd_iter)(const td_thragent_t *ta_p, 139 td_key_iter_f *cb, void *cbdata_p); 140static td_err_e (*p_td_ta_thr_iter)(const td_thragent_t *ta_p, 141 td_thr_iter_f *cb, void *cbdata_p, 142 td_thr_state_e state, int ti_pri, 143 sigset_t *ti_sigmask_p, 144 unsigned ti_user_flags); 145static td_err_e (*p_td_thr_validate)(const td_thrhandle_t *th_p); 146static td_err_e (*p_td_thr_tsd)(const td_thrhandle_t * th_p, 147 const thread_key_t key, void **data_pp); 148static td_err_e (*p_td_thr_get_info)(const td_thrhandle_t *th_p, 149 td_thrinfo_t *ti_p); 150static td_err_e (*p_td_thr_getfpregs)(const td_thrhandle_t *th_p, 151 prfpregset_t *fpregset); 152static td_err_e (*p_td_thr_getxregsize)(const td_thrhandle_t *th_p, 153 int *xregsize); 154static td_err_e (*p_td_thr_getxregs)(const td_thrhandle_t *th_p, 155 const caddr_t xregset); 156static td_err_e (*p_td_thr_sigsetmask)(const td_thrhandle_t *th_p, 157 const sigset_t ti_sigmask); 158static td_err_e (*p_td_thr_setprio)(const td_thrhandle_t *th_p, 159 const int ti_pri); 160static td_err_e (*p_td_thr_setsigpending)(const td_thrhandle_t *th_p, 161 const uchar_t ti_pending_flag, 162 const sigset_t ti_pending); 163static td_err_e (*p_td_thr_setfpregs)(const td_thrhandle_t *th_p, 164 const prfpregset_t *fpregset); 165static td_err_e (*p_td_thr_setxregs)(const td_thrhandle_t *th_p, 166 const caddr_t xregset); 167static td_err_e (*p_td_ta_map_id2thr)(const td_thragent_t *ta_p, 168 thread_t tid, 169 td_thrhandle_t *th_p); 170static td_err_e (*p_td_ta_map_lwp2thr)(const td_thragent_t *ta_p, 171 lwpid_t lwpid, 172 td_thrhandle_t *th_p); 173static td_err_e (*p_td_thr_getgregs)(const td_thrhandle_t *th_p, 174 prgregset_t regset); 175static td_err_e (*p_td_thr_setgregs)(const td_thrhandle_t *th_p, 176 const prgregset_t regset); 177 178 179/* Return the libthread_db error string associated with ERRCODE. If 180 ERRCODE is unknown, return an appropriate message. */ 181 182static char * 183td_err_string (td_err_e errcode) 184{ 185 static struct string_map td_err_table[] = 186 { 187 { TD_OK, "generic \"call succeeded\"" }, 188 { TD_ERR, "generic error." }, 189 { TD_NOTHR, "no thread can be found to satisfy query" }, 190 { TD_NOSV, "no synch. variable can be found to satisfy query" }, 191 { TD_NOLWP, "no lwp can be found to satisfy query" }, 192 { TD_BADPH, "invalid process handle" }, 193 { TD_BADTH, "invalid thread handle" }, 194 { TD_BADSH, "invalid synchronization handle" }, 195 { TD_BADTA, "invalid thread agent" }, 196 { TD_BADKEY, "invalid key" }, 197 { TD_NOMSG, "td_thr_event_getmsg() called when there was no message" }, 198 { TD_NOFPREGS, "FPU register set not available for given thread" }, 199 { TD_NOLIBTHREAD, "application not linked with libthread" }, 200 { TD_NOEVENT, "requested event is not supported" }, 201 { TD_NOCAPAB, "capability not available" }, 202 { TD_DBERR, "Debugger service failed" }, 203 { TD_NOAPLIC, "Operation not applicable to" }, 204 { TD_NOTSD, "No thread specific data for this thread" }, 205 { TD_MALLOC, "Malloc failed" }, 206 { TD_PARTIALREG, "Only part of register set was written/read" }, 207 { TD_NOXREGS, "X register set not available for given thread" } 208 }; 209 const int td_err_size = sizeof td_err_table / sizeof (struct string_map); 210 int i; 211 static char buf[50]; 212 213 for (i = 0; i < td_err_size; i++) 214 if (td_err_table[i].num == errcode) 215 return td_err_table[i].str; 216 217 sprintf (buf, "Unknown libthread_db error code: %d", errcode); 218 219 return buf; 220} 221 222/* Return the the libthread_db state string assicoated with STATECODE. 223 If STATECODE is unknown, return an appropriate message. */ 224 225static char * 226td_state_string (td_thr_state_e statecode) 227{ 228 static struct string_map td_thr_state_table[] = 229 { 230 { TD_THR_ANY_STATE, "any state" }, 231 { TD_THR_UNKNOWN, "unknown" }, 232 { TD_THR_STOPPED, "stopped" }, 233 { TD_THR_RUN, "run" }, 234 { TD_THR_ACTIVE, "active" }, 235 { TD_THR_ZOMBIE, "zombie" }, 236 { TD_THR_SLEEP, "sleep" }, 237 { TD_THR_STOPPED_ASLEEP, "stopped asleep" } 238 }; 239 const int td_thr_state_table_size = 240 sizeof td_thr_state_table / sizeof (struct string_map); 241 int i; 242 static char buf[50]; 243 244 for (i = 0; i < td_thr_state_table_size; i++) 245 if (td_thr_state_table[i].num == statecode) 246 return td_thr_state_table[i].str; 247 248 sprintf (buf, "Unknown libthread_db state code: %d", statecode); 249 250 return buf; 251} 252 253 254/* Convert a POSIX or Solaris thread ID into a LWP ID. If THREAD_ID 255 doesn't exist, that's an error. If it's an inactive thread, return 256 DEFAULT_LPW. 257 258 NOTE: This function probably shouldn't call error(). */ 259 260static ptid_t 261thread_to_lwp (ptid_t thread_id, int default_lwp) 262{ 263 td_thrinfo_t ti; 264 td_thrhandle_t th; 265 td_err_e val; 266 267 if (is_lwp (thread_id)) 268 return thread_id; /* It's already an LWP ID. */ 269 270 /* It's a thread. Convert to LWP. */ 271 272 val = p_td_ta_map_id2thr (main_ta, GET_THREAD (thread_id), &th); 273 if (val == TD_NOTHR) 274 return pid_to_ptid (-1); /* Thread must have terminated. */ 275 else if (val != TD_OK) 276 error (_("thread_to_lwp: td_ta_map_id2thr %s"), td_err_string (val)); 277 278 val = p_td_thr_get_info (&th, &ti); 279 if (val == TD_NOTHR) 280 return pid_to_ptid (-1); /* Thread must have terminated. */ 281 else if (val != TD_OK) 282 error (_("thread_to_lwp: td_thr_get_info: %s"), td_err_string (val)); 283 284 if (ti.ti_state != TD_THR_ACTIVE) 285 { 286 if (default_lwp != -1) 287 return pid_to_ptid (default_lwp); 288 error (_("thread_to_lwp: thread state not active: %s"), 289 td_state_string (ti.ti_state)); 290 } 291 292 return BUILD_LWP (ti.ti_lid, PIDGET (thread_id)); 293} 294 295/* Convert an LWP ID into a POSIX or Solaris thread ID. If LWP_ID 296 doesn't exists, that's an error. 297 298 NOTE: This function probably shouldn't call error(). */ 299 300static ptid_t 301lwp_to_thread (ptid_t lwp) 302{ 303 td_thrinfo_t ti; 304 td_thrhandle_t th; 305 td_err_e val; 306 307 if (is_thread (lwp)) 308 return lwp; /* It's already a thread ID. */ 309 310 /* It's an LWP. Convert it to a thread ID. */ 311 312 if (!sol_thread_alive (lwp)) 313 return pid_to_ptid (-1); /* Must be a defunct LPW. */ 314 315 val = p_td_ta_map_lwp2thr (main_ta, GET_LWP (lwp), &th); 316 if (val == TD_NOTHR) 317 return pid_to_ptid (-1); /* Thread must have terminated. */ 318 else if (val != TD_OK) 319 error (_("lwp_to_thread: td_ta_map_lwp2thr: %s."), td_err_string (val)); 320 321 val = p_td_thr_validate (&th); 322 if (val == TD_NOTHR) 323 return lwp; /* Unknown to libthread; just return LPW, */ 324 else if (val != TD_OK) 325 error (_("lwp_to_thread: td_thr_validate: %s."), td_err_string (val)); 326 327 val = p_td_thr_get_info (&th, &ti); 328 if (val == TD_NOTHR) 329 return pid_to_ptid (-1); /* Thread must have terminated. */ 330 else if (val != TD_OK) 331 error (_("lwp_to_thread: td_thr_get_info: %s."), td_err_string (val)); 332 333 return BUILD_THREAD (ti.ti_tid, PIDGET (lwp)); 334} 335 336 337/* Most target vector functions from here on actually just pass 338 through to procfs.c, as they don't need to do anything specific for 339 threads. */ 340 341static void 342sol_thread_open (char *arg, int from_tty) 343{ 344 procfs_ops.to_open (arg, from_tty); 345} 346 347/* Attach to process PID, then initialize for debugging it and wait 348 for the trace-trap that results from attaching. */ 349 350static void 351sol_thread_attach (char *args, int from_tty) 352{ 353 procfs_ops.to_attach (args, from_tty); 354 355 /* Must get symbols from shared libraries before libthread_db can run! */ 356 solib_add (NULL, from_tty, (struct target_ops *) 0, auto_solib_add); 357 358 if (sol_thread_active) 359 { 360 printf_filtered ("sol-thread active.\n"); 361 main_ph.ptid = inferior_ptid; /* Save for xfer_memory. */ 362 push_target (&sol_thread_ops); 363 inferior_ptid = lwp_to_thread (inferior_ptid); 364 if (PIDGET (inferior_ptid) == -1) 365 inferior_ptid = main_ph.ptid; 366 else 367 add_thread (inferior_ptid); 368 } 369 370 /* FIXME: Might want to iterate over all the threads and register 371 them. */ 372} 373 374/* Take a program previously attached to and detaches it. The program 375 resumes execution and will no longer stop on signals, etc. We'd 376 better not have left any breakpoints in the program or it'll die 377 when it hits one. For this to work, it may be necessary for the 378 process to have been previously attached. It *might* work if the 379 program was started via the normal ptrace (PTRACE_TRACEME). */ 380 381static void 382sol_thread_detach (char *args, int from_tty) 383{ 384 inferior_ptid = pid_to_ptid (PIDGET (main_ph.ptid)); 385 unpush_target (&sol_thread_ops); 386 procfs_ops.to_detach (args, from_tty); 387} 388 389/* Resume execution of process PTID. If STEP is nozero, then just 390 single step it. If SIGNAL is nonzero, restart it with that signal 391 activated. We may have to convert PTID from a thread ID to an LWP 392 ID for procfs. */ 393 394static void 395sol_thread_resume (ptid_t ptid, int step, enum target_signal signo) 396{ 397 struct cleanup *old_chain; 398 399 old_chain = save_inferior_ptid (); 400 401 inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid)); 402 if (PIDGET (inferior_ptid) == -1) 403 inferior_ptid = procfs_first_available (); 404 405 if (PIDGET (ptid) != -1) 406 { 407 ptid_t save_ptid = ptid; 408 409 ptid = thread_to_lwp (ptid, -2); 410 if (PIDGET (ptid) == -2) /* Inactive thread. */ 411 error (_("This version of Solaris can't start inactive threads.")); 412 if (info_verbose && PIDGET (ptid) == -1) 413 warning (_("Specified thread %ld seems to have terminated"), 414 GET_THREAD (save_ptid)); 415 } 416 417 procfs_ops.to_resume (ptid, step, signo); 418 419 do_cleanups (old_chain); 420} 421 422/* Wait for any threads to stop. We may have to convert PIID from a 423 thread ID to an LWP ID, and vice versa on the way out. */ 424 425static ptid_t 426sol_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus) 427{ 428 ptid_t rtnval; 429 ptid_t save_ptid; 430 struct cleanup *old_chain; 431 432 save_ptid = inferior_ptid; 433 old_chain = save_inferior_ptid (); 434 435 inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid)); 436 if (PIDGET (inferior_ptid) == -1) 437 inferior_ptid = procfs_first_available (); 438 439 if (PIDGET (ptid) != -1) 440 { 441 ptid_t save_ptid = ptid; 442 443 ptid = thread_to_lwp (ptid, -2); 444 if (PIDGET (ptid) == -2) /* Inactive thread. */ 445 error (_("This version of Solaris can't start inactive threads.")); 446 if (info_verbose && PIDGET (ptid) == -1) 447 warning (_("Specified thread %ld seems to have terminated"), 448 GET_THREAD (save_ptid)); 449 } 450 451 rtnval = procfs_ops.to_wait (ptid, ourstatus); 452 453 if (ourstatus->kind != TARGET_WAITKIND_EXITED) 454 { 455 /* Map the LWP of interest back to the appropriate thread ID. */ 456 rtnval = lwp_to_thread (rtnval); 457 if (PIDGET (rtnval) == -1) 458 rtnval = save_ptid; 459 460 /* See if we have a new thread. */ 461 if (is_thread (rtnval) 462 && !ptid_equal (rtnval, save_ptid) 463 && !in_thread_list (rtnval)) 464 { 465 printf_filtered ("[New %s]\n", target_pid_to_str (rtnval)); 466 add_thread (rtnval); 467 } 468 } 469 470 /* During process initialization, we may get here without the thread 471 package being initialized, since that can only happen after we've 472 found the shared libs. */ 473 474 do_cleanups (old_chain); 475 476 return rtnval; 477} 478 479static void 480sol_thread_fetch_registers (struct regcache *regcache, int regnum) 481{ 482 thread_t thread; 483 td_thrhandle_t thandle; 484 td_err_e val; 485 prgregset_t gregset; 486 prfpregset_t fpregset; 487 gdb_gregset_t *gregset_p = &gregset; 488 gdb_fpregset_t *fpregset_p = &fpregset; 489 490#if 0 491 int xregsize; 492 caddr_t xregset; 493#endif 494 495 if (!is_thread (inferior_ptid)) 496 { 497 /* It's an LWP; pass the request on to procfs. */ 498 if (target_has_execution) 499 procfs_ops.to_fetch_registers (regcache, regnum); 500 else 501 orig_core_ops.to_fetch_registers (regcache, regnum); 502 return; 503 } 504 505 /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */ 506 thread = GET_THREAD (inferior_ptid); 507 if (thread == 0) 508 error (_("sol_thread_fetch_registers: thread == 0")); 509 510 val = p_td_ta_map_id2thr (main_ta, thread, &thandle); 511 if (val != TD_OK) 512 error (_("sol_thread_fetch_registers: td_ta_map_id2thr: %s"), 513 td_err_string (val)); 514 515 /* Get the general-purpose registers. */ 516 517 val = p_td_thr_getgregs (&thandle, gregset); 518 if (val != TD_OK && val != TD_PARTIALREG) 519 error (_("sol_thread_fetch_registers: td_thr_getgregs %s"), 520 td_err_string (val)); 521 522 /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc 523 and %sp are saved (by a thread context switch). */ 524 525 /* And, now the floating-point registers. */ 526 527 val = p_td_thr_getfpregs (&thandle, &fpregset); 528 if (val != TD_OK && val != TD_NOFPREGS) 529 error (_("sol_thread_fetch_registers: td_thr_getfpregs %s"), 530 td_err_string (val)); 531 532 /* Note that we must call supply_gregset and supply_fpregset *after* 533 calling the td routines because the td routines call ps_lget* 534 which affect the values stored in the registers array. */ 535 536 supply_gregset (regcache, (const gdb_gregset_t *) gregset_p); 537 supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset_p); 538 539#if 0 540 /* FIXME: libthread_db doesn't seem to handle this right. */ 541 val = td_thr_getxregsize (&thandle, &xregsize); 542 if (val != TD_OK && val != TD_NOXREGS) 543 error (_("sol_thread_fetch_registers: td_thr_getxregsize %s"), 544 td_err_string (val)); 545 546 if (val == TD_OK) 547 { 548 xregset = alloca (xregsize); 549 val = td_thr_getxregs (&thandle, xregset); 550 if (val != TD_OK) 551 error (_("sol_thread_fetch_registers: td_thr_getxregs %s"), 552 td_err_string (val)); 553 } 554#endif 555} 556 557static void 558sol_thread_store_registers (struct regcache *regcache, int regnum) 559{ 560 thread_t thread; 561 td_thrhandle_t thandle; 562 td_err_e val; 563 prgregset_t gregset; 564 prfpregset_t fpregset; 565#if 0 566 int xregsize; 567 caddr_t xregset; 568#endif 569 570 if (!is_thread (inferior_ptid)) 571 { 572 /* It's an LWP; pass the request on to procfs.c. */ 573 procfs_ops.to_store_registers (regcache, regnum); 574 return; 575 } 576 577 /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */ 578 thread = GET_THREAD (inferior_ptid); 579 580 val = p_td_ta_map_id2thr (main_ta, thread, &thandle); 581 if (val != TD_OK) 582 error (_("sol_thread_store_registers: td_ta_map_id2thr %s"), 583 td_err_string (val)); 584 585 if (regnum != -1) 586 { 587 /* Not writing all the registers. */ 588 char old_value[MAX_REGISTER_SIZE]; 589 590 /* Save new register value. */ 591 regcache_raw_collect (regcache, regnum, old_value); 592 593 val = p_td_thr_getgregs (&thandle, gregset); 594 if (val != TD_OK) 595 error (_("sol_thread_store_registers: td_thr_getgregs %s"), 596 td_err_string (val)); 597 val = p_td_thr_getfpregs (&thandle, &fpregset); 598 if (val != TD_OK) 599 error (_("sol_thread_store_registers: td_thr_getfpregs %s"), 600 td_err_string (val)); 601 602 /* Restore new register value. */ 603 regcache_raw_supply (regcache, regnum, old_value); 604 605#if 0 606 /* FIXME: libthread_db doesn't seem to handle this right. */ 607 val = td_thr_getxregsize (&thandle, &xregsize); 608 if (val != TD_OK && val != TD_NOXREGS) 609 error (_("sol_thread_store_registers: td_thr_getxregsize %s"), 610 td_err_string (val)); 611 612 if (val == TD_OK) 613 { 614 xregset = alloca (xregsize); 615 val = td_thr_getxregs (&thandle, xregset); 616 if (val != TD_OK) 617 error (_("sol_thread_store_registers: td_thr_getxregs %s"), 618 td_err_string (val)); 619 } 620#endif 621 } 622 623 fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum); 624 fill_fpregset (regcache, (gdb_fpregset_t *) &fpregset, regnum); 625 626 val = p_td_thr_setgregs (&thandle, gregset); 627 if (val != TD_OK) 628 error (_("sol_thread_store_registers: td_thr_setgregs %s"), 629 td_err_string (val)); 630 val = p_td_thr_setfpregs (&thandle, &fpregset); 631 if (val != TD_OK) 632 error (_("sol_thread_store_registers: td_thr_setfpregs %s"), 633 td_err_string (val)); 634 635#if 0 636 /* FIXME: libthread_db doesn't seem to handle this right. */ 637 val = td_thr_getxregsize (&thandle, &xregsize); 638 if (val != TD_OK && val != TD_NOXREGS) 639 error (_("sol_thread_store_registers: td_thr_getxregsize %s"), 640 td_err_string (val)); 641 642 /* ??? Should probably do something about writing the xregs here, 643 but what are they? */ 644#endif 645} 646 647/* Get ready to modify the registers array. On machines which store 648 individual registers, this doesn't need to do anything. On 649 machines which store all the registers in one fell swoop, this 650 makes sure that registers contains all the registers from the 651 program being debugged. */ 652 653static void 654sol_thread_prepare_to_store (struct regcache *regcache) 655{ 656 procfs_ops.to_prepare_to_store (regcache); 657} 658 659/* Transfer LEN bytes between GDB address MYADDR and target address 660 MEMADDR. If DOWRITE is non-zero, transfer them to the target, 661 otherwise transfer them from the target. TARGET is unused. 662 663 Returns the number of bytes transferred. */ 664 665static int 666sol_thread_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, 667 int dowrite, struct mem_attrib *attrib, 668 struct target_ops *target) 669{ 670 int retval; 671 struct cleanup *old_chain; 672 673 old_chain = save_inferior_ptid (); 674 675 if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid)) 676 { 677 /* It's either a thread or an LWP that isn't alive. Any live 678 LWP will do so use the first available. 679 680 NOTE: We don't need to call switch_to_thread; we're just 681 reading memory. */ 682 inferior_ptid = procfs_first_available (); 683 } 684 685 if (target_has_execution) 686 retval = procfs_ops.deprecated_xfer_memory (memaddr, myaddr, len, 687 dowrite, attrib, target); 688 else 689 retval = orig_core_ops.deprecated_xfer_memory (memaddr, myaddr, len, 690 dowrite, attrib, target); 691 692 do_cleanups (old_chain); 693 694 return retval; 695} 696 697/* Perform partial transfers on OBJECT. See target_read_partial and 698 target_write_partial for details of each variant. One, and only 699 one, of readbuf or writebuf must be non-NULL. */ 700 701static LONGEST 702sol_thread_xfer_partial (struct target_ops *ops, enum target_object object, 703 const char *annex, gdb_byte *readbuf, 704 const gdb_byte *writebuf, 705 ULONGEST offset, LONGEST len) 706{ 707 int retval; 708 struct cleanup *old_chain; 709 710 old_chain = save_inferior_ptid (); 711 712 if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid)) 713 { 714 /* It's either a thread or an LWP that isn't alive. Any live 715 LWP will do so use the first available. 716 717 NOTE: We don't need to call switch_to_thread; we're just 718 reading memory. */ 719 inferior_ptid = procfs_first_available (); 720 } 721 722 if (target_has_execution) 723 retval = procfs_ops.to_xfer_partial (ops, object, annex, 724 readbuf, writebuf, offset, len); 725 else 726 retval = orig_core_ops.to_xfer_partial (ops, object, annex, 727 readbuf, writebuf, offset, len); 728 729 do_cleanups (old_chain); 730 731 return retval; 732} 733 734/* Print status information about what we're accessing. */ 735 736static void 737sol_thread_files_info (struct target_ops *ignore) 738{ 739 procfs_ops.to_files_info (ignore); 740} 741 742static void 743sol_thread_kill_inferior (void) 744{ 745 procfs_ops.to_kill (); 746} 747 748static void 749sol_thread_notice_signals (ptid_t ptid) 750{ 751 procfs_ops.to_notice_signals (pid_to_ptid (PIDGET (ptid))); 752} 753 754/* Fork an inferior process, and start debugging it with /proc. */ 755 756static void 757sol_thread_create_inferior (char *exec_file, char *allargs, char **env, 758 int from_tty) 759{ 760 procfs_ops.to_create_inferior (exec_file, allargs, env, from_tty); 761 762 if (sol_thread_active && !ptid_equal (inferior_ptid, null_ptid)) 763 { 764 /* Save for xfer_memory. */ 765 main_ph.ptid = inferior_ptid; 766 767 push_target (&sol_thread_ops); 768 769 inferior_ptid = lwp_to_thread (inferior_ptid); 770 if (PIDGET (inferior_ptid) == -1) 771 inferior_ptid = main_ph.ptid; 772 773 if (!in_thread_list (inferior_ptid)) 774 add_thread (inferior_ptid); 775 } 776} 777 778/* This routine is called whenever a new symbol table is read in, or 779 when all symbol tables are removed. libthread_db can only be 780 initialized when it finds the right variables in libthread.so. 781 Since it's a shared library, those variables don't show up until 782 the library gets mapped and the symbol table is read in. */ 783 784static void 785sol_thread_new_objfile (struct objfile *objfile) 786{ 787 td_err_e val; 788 789 if (!objfile) 790 { 791 sol_thread_active = 0; 792 return; 793 } 794 795 /* Don't do anything if init failed to resolve the libthread_db 796 library. */ 797 if (!procfs_suppress_run) 798 return; 799 800 /* Now, initialize libthread_db. This needs to be done after the 801 shared libraries are located because it needs information from 802 the user's thread library. */ 803 804 val = p_td_init (); 805 if (val != TD_OK) 806 { 807 warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (val)); 808 return; 809 } 810 811 val = p_td_ta_new (&main_ph, &main_ta); 812 if (val == TD_NOLIBTHREAD) 813 return; 814 else if (val != TD_OK) 815 { 816 warning (_("sol_thread_new_objfile: td_ta_new: %s"), td_err_string (val)); 817 return; 818 } 819 820 sol_thread_active = 1; 821} 822 823/* Clean up after the inferior dies. */ 824 825static void 826sol_thread_mourn_inferior (void) 827{ 828 unpush_target (&sol_thread_ops); 829 procfs_ops.to_mourn_inferior (); 830} 831 832/* Mark our target-struct as eligible for stray "run" and "attach" 833 commands. */ 834 835static int 836sol_thread_can_run (void) 837{ 838 return procfs_suppress_run; 839} 840 841/* 842 843 LOCAL FUNCTION 844 845 sol_thread_alive - test thread for "aliveness" 846 847 SYNOPSIS 848 849 static bool sol_thread_alive (ptid_t ptid); 850 851 DESCRIPTION 852 853 returns true if thread still active in inferior. 854 855 */ 856 857/* Return true if PTID is still active in the inferior. */ 858 859static int 860sol_thread_alive (ptid_t ptid) 861{ 862 if (is_thread (ptid)) 863 { 864 /* It's a (user-level) thread. */ 865 td_err_e val; 866 td_thrhandle_t th; 867 int pid; 868 869 pid = GET_THREAD (ptid); 870 if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK) 871 return 0; /* Thread not found. */ 872 if ((val = p_td_thr_validate (&th)) != TD_OK) 873 return 0; /* Thread not valid. */ 874 return 1; /* Known thread. */ 875 } 876 else 877 { 878 /* It's an LPW; pass the request on to procfs. */ 879 if (target_has_execution) 880 return procfs_ops.to_thread_alive (ptid); 881 else 882 return orig_core_ops.to_thread_alive (ptid); 883 } 884} 885 886static void 887sol_thread_stop (void) 888{ 889 procfs_ops.to_stop (); 890} 891 892/* These routines implement the lower half of the thread_db interface, 893 i.e. the ps_* routines. */ 894 895/* Various versions of <proc_service.h> have slightly different 896 function prototypes. In particular, we have 897 898 NEWER OLDER 899 struct ps_prochandle * const struct ps_prochandle * 900 void* char* 901 const void* char* 902 int size_t 903 904 Which one you have depends on the Solaris version and what patches 905 you've applied. On the theory that there are only two major 906 variants, we have configure check the prototype of ps_pdwrite (), 907 and use that info to make appropriate typedefs here. */ 908 909#ifdef PROC_SERVICE_IS_OLD 910typedef const struct ps_prochandle *gdb_ps_prochandle_t; 911typedef char *gdb_ps_read_buf_t; 912typedef char *gdb_ps_write_buf_t; 913typedef int gdb_ps_size_t; 914typedef psaddr_t gdb_ps_addr_t; 915#else 916typedef struct ps_prochandle *gdb_ps_prochandle_t; 917typedef void *gdb_ps_read_buf_t; 918typedef const void *gdb_ps_write_buf_t; 919typedef size_t gdb_ps_size_t; 920typedef psaddr_t gdb_ps_addr_t; 921#endif 922 923/* The next four routines are called by libthread_db to tell us to 924 stop and stop a particular process or lwp. Since GDB ensures that 925 these are all stopped by the time we call anything in thread_db, 926 these routines need to do nothing. */ 927 928/* Process stop. */ 929 930ps_err_e 931ps_pstop (gdb_ps_prochandle_t ph) 932{ 933 return PS_OK; 934} 935 936/* Process continue. */ 937 938ps_err_e 939ps_pcontinue (gdb_ps_prochandle_t ph) 940{ 941 return PS_OK; 942} 943 944/* LWP stop. */ 945 946ps_err_e 947ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid) 948{ 949 return PS_OK; 950} 951 952/* LWP continue. */ 953 954ps_err_e 955ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid) 956{ 957 return PS_OK; 958} 959 960/* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table. */ 961 962ps_err_e 963ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name, 964 const char *ld_symbol_name, gdb_ps_addr_t *ld_symbol_addr) 965{ 966 struct minimal_symbol *ms; 967 968 ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL); 969 if (!ms) 970 return PS_NOSYM; 971 972 *ld_symbol_addr = SYMBOL_VALUE_ADDRESS (ms); 973 return PS_OK; 974} 975 976/* Common routine for reading and writing memory. */ 977 978static ps_err_e 979rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr, 980 char *buf, int size) 981{ 982 struct cleanup *old_chain; 983 984 old_chain = save_inferior_ptid (); 985 986 if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid)) 987 { 988 /* It's either a thread or an LWP that isn't alive. Any live 989 LWP will do so use the first available. 990 991 NOTE: We don't need to call switch_to_thread; we're just 992 reading memory. */ 993 inferior_ptid = procfs_first_available (); 994 } 995 996#if defined (__sparcv9) 997 /* For Sparc64 cross Sparc32, make sure the address has not been 998 accidentally sign-extended (or whatever) to beyond 32 bits. */ 999 if (bfd_get_arch_size (exec_bfd) == 32) 1000 addr &= 0xffffffff; 1001#endif 1002 1003 while (size > 0) 1004 { 1005 int cc; 1006 1007 /* FIXME: passing 0 as attrib argument. */ 1008 if (target_has_execution) 1009 cc = procfs_ops.deprecated_xfer_memory (addr, buf, size, 1010 dowrite, 0, &procfs_ops); 1011 else 1012 cc = orig_core_ops.deprecated_xfer_memory (addr, buf, size, 1013 dowrite, 0, &core_ops); 1014 1015 if (cc < 0) 1016 { 1017 if (dowrite == 0) 1018 print_sys_errmsg ("rw_common (): read", errno); 1019 else 1020 print_sys_errmsg ("rw_common (): write", errno); 1021 1022 do_cleanups (old_chain); 1023 1024 return PS_ERR; 1025 } 1026 else if (cc == 0) 1027 { 1028 if (dowrite == 0) 1029 warning (_("rw_common (): unable to read at addr 0x%lx"), 1030 (long) addr); 1031 else 1032 warning (_("rw_common (): unable to write at addr 0x%lx"), 1033 (long) addr); 1034 1035 do_cleanups (old_chain); 1036 1037 return PS_ERR; 1038 } 1039 1040 size -= cc; 1041 buf += cc; 1042 } 1043 1044 do_cleanups (old_chain); 1045 1046 return PS_OK; 1047} 1048 1049/* Copies SIZE bytes from target process .data segment to debugger memory. */ 1050 1051ps_err_e 1052ps_pdread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr, 1053 gdb_ps_read_buf_t buf, gdb_ps_size_t size) 1054{ 1055 return rw_common (0, ph, addr, buf, size); 1056} 1057 1058/* Copies SIZE bytes from debugger memory .data segment to target process. */ 1059 1060ps_err_e 1061ps_pdwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr, 1062 gdb_ps_write_buf_t buf, gdb_ps_size_t size) 1063{ 1064 return rw_common (1, ph, addr, (char *) buf, size); 1065} 1066 1067/* Copies SIZE bytes from target process .text segment to debugger memory. */ 1068 1069ps_err_e 1070ps_ptread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr, 1071 gdb_ps_read_buf_t buf, gdb_ps_size_t size) 1072{ 1073 return rw_common (0, ph, addr, buf, size); 1074} 1075 1076/* Copies SIZE bytes from debugger memory .text segment to target process. */ 1077 1078ps_err_e 1079ps_ptwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr, 1080 gdb_ps_write_buf_t buf, gdb_ps_size_t size) 1081{ 1082 return rw_common (1, ph, addr, (char *) buf, size); 1083} 1084 1085/* Get general-purpose registers for LWP. */ 1086 1087ps_err_e 1088ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset) 1089{ 1090 struct cleanup *old_chain; 1091 struct regcache *regcache; 1092 1093 old_chain = save_inferior_ptid (); 1094 1095 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid)); 1096 regcache = get_thread_regcache (inferior_ptid); 1097 1098 if (target_has_execution) 1099 procfs_ops.to_fetch_registers (regcache, -1); 1100 else 1101 orig_core_ops.to_fetch_registers (regcache, -1); 1102 fill_gregset (regcache, (gdb_gregset_t *) gregset, -1); 1103 1104 do_cleanups (old_chain); 1105 1106 return PS_OK; 1107} 1108 1109/* Set general-purpose registers for LWP. */ 1110 1111ps_err_e 1112ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, 1113 const prgregset_t gregset) 1114{ 1115 struct cleanup *old_chain; 1116 struct regcache *regcache; 1117 1118 old_chain = save_inferior_ptid (); 1119 1120 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid)); 1121 regcache = get_thread_regcache (inferior_ptid); 1122 1123 supply_gregset (regcache, (const gdb_gregset_t *) gregset); 1124 if (target_has_execution) 1125 procfs_ops.to_store_registers (regcache, -1); 1126 else 1127 orig_core_ops.to_store_registers (regcache, -1); 1128 1129 do_cleanups (old_chain); 1130 1131 return PS_OK; 1132} 1133 1134/* Log a message (sends to gdb_stderr). */ 1135 1136void 1137ps_plog (const char *fmt, ...) 1138{ 1139 va_list args; 1140 1141 va_start (args, fmt); 1142 1143 vfprintf_filtered (gdb_stderr, fmt, args); 1144} 1145 1146/* Get size of extra register set. Currently a noop. */ 1147 1148ps_err_e 1149ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize) 1150{ 1151#if 0 1152 int lwp_fd; 1153 int regsize; 1154 ps_err_e val; 1155 1156 val = get_lwp_fd (ph, lwpid, &lwp_fd); 1157 if (val != PS_OK) 1158 return val; 1159 1160 if (ioctl (lwp_fd, PIOCGXREGSIZE, ®size)) 1161 { 1162 if (errno == EINVAL) 1163 return PS_NOFREGS; /* XXX Wrong code, but this is the closest 1164 thing in proc_service.h */ 1165 1166 print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno); 1167 return PS_ERR; 1168 } 1169#endif 1170 1171 return PS_OK; 1172} 1173 1174/* Get extra register set. Currently a noop. */ 1175 1176ps_err_e 1177ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset) 1178{ 1179#if 0 1180 int lwp_fd; 1181 ps_err_e val; 1182 1183 val = get_lwp_fd (ph, lwpid, &lwp_fd); 1184 if (val != PS_OK) 1185 return val; 1186 1187 if (ioctl (lwp_fd, PIOCGXREG, xregset)) 1188 { 1189 print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno); 1190 return PS_ERR; 1191 } 1192#endif 1193 1194 return PS_OK; 1195} 1196 1197/* Set extra register set. Currently a noop. */ 1198 1199ps_err_e 1200ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset) 1201{ 1202#if 0 1203 int lwp_fd; 1204 ps_err_e val; 1205 1206 val = get_lwp_fd (ph, lwpid, &lwp_fd); 1207 if (val != PS_OK) 1208 return val; 1209 1210 if (ioctl (lwp_fd, PIOCSXREG, xregset)) 1211 { 1212 print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno); 1213 return PS_ERR; 1214 } 1215#endif 1216 1217 return PS_OK; 1218} 1219 1220/* Get floating-point registers for LWP. */ 1221 1222ps_err_e 1223ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, 1224 prfpregset_t *fpregset) 1225{ 1226 struct cleanup *old_chain; 1227 struct regcache *regcache; 1228 1229 old_chain = save_inferior_ptid (); 1230 1231 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid)); 1232 regcache = get_thread_regcache (inferior_ptid); 1233 1234 if (target_has_execution) 1235 procfs_ops.to_fetch_registers (regcache, -1); 1236 else 1237 orig_core_ops.to_fetch_registers (regcache, -1); 1238 fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1); 1239 1240 do_cleanups (old_chain); 1241 1242 return PS_OK; 1243} 1244 1245/* Set floating-point regs for LWP */ 1246 1247ps_err_e 1248ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, 1249 const prfpregset_t * fpregset) 1250{ 1251 struct cleanup *old_chain; 1252 struct regcache *regcache; 1253 1254 old_chain = save_inferior_ptid (); 1255 1256 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid)); 1257 regcache = get_thread_regcache (inferior_ptid); 1258 1259 supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset); 1260 if (target_has_execution) 1261 procfs_ops.to_store_registers (regcache, -1); 1262 else 1263 orig_core_ops.to_store_registers (regcache, -1); 1264 1265 do_cleanups (old_chain); 1266 1267 return PS_OK; 1268} 1269 1270#ifdef PR_MODEL_LP64 1271/* Identify process as 32-bit or 64-bit. At the moment we're using 1272 BFD to do this. There might be a more Solaris-specific 1273 (e.g. procfs) method, but this ought to work. */ 1274 1275ps_err_e 1276ps_pdmodel (gdb_ps_prochandle_t ph, int *data_model) 1277{ 1278 if (exec_bfd == 0) 1279 *data_model = PR_MODEL_UNKNOWN; 1280 else if (bfd_get_arch_size (exec_bfd) == 32) 1281 *data_model = PR_MODEL_ILP32; 1282 else 1283 *data_model = PR_MODEL_LP64; 1284 1285 return PS_OK; 1286} 1287#endif /* PR_MODEL_LP64 */ 1288 1289#ifdef TM_I386SOL2_H 1290 1291/* Reads the local descriptor table of a LWP. */ 1292 1293ps_err_e 1294ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid, 1295 struct ssd *pldt) 1296{ 1297 /* NOTE: only used on Solaris, therefore OK to refer to procfs.c. */ 1298 extern struct ssd *procfs_find_LDT_entry (ptid_t); 1299 struct ssd *ret; 1300 1301 /* FIXME: can't I get the process ID from the prochandle or 1302 something? */ 1303 1304 if (PIDGET (inferior_ptid) <= 0 || lwpid <= 0) 1305 return PS_BADLID; 1306 1307 ret = procfs_find_LDT_entry (BUILD_LWP (lwpid, PIDGET (inferior_ptid))); 1308 if (ret) 1309 { 1310 memcpy (pldt, ret, sizeof (struct ssd)); 1311 return PS_OK; 1312 } 1313 else 1314 /* LDT not found. */ 1315 return PS_ERR; 1316} 1317#endif /* TM_I386SOL2_H */ 1318 1319 1320/* Convert PTID to printable form. */ 1321 1322char * 1323solaris_pid_to_str (ptid_t ptid) 1324{ 1325 static char buf[100]; 1326 1327 /* In case init failed to resolve the libthread_db library. */ 1328 if (!procfs_suppress_run) 1329 return procfs_pid_to_str (ptid); 1330 1331 if (is_thread (ptid)) 1332 { 1333 ptid_t lwp; 1334 1335 lwp = thread_to_lwp (ptid, -2); 1336 1337 if (PIDGET (lwp) == -1) 1338 sprintf (buf, "Thread %ld (defunct)", GET_THREAD (ptid)); 1339 else if (PIDGET (lwp) != -2) 1340 sprintf (buf, "Thread %ld (LWP %ld)", 1341 GET_THREAD (ptid), GET_LWP (lwp)); 1342 else 1343 sprintf (buf, "Thread %ld ", GET_THREAD (ptid)); 1344 } 1345 else if (GET_LWP (ptid) != 0) 1346 sprintf (buf, "LWP %ld ", GET_LWP (ptid)); 1347 else 1348 sprintf (buf, "process %d ", PIDGET (ptid)); 1349 1350 return buf; 1351} 1352 1353 1354/* Worker bee for find_new_threads. Callback function that gets 1355 called once per user-level thread (i.e. not for LWP's). */ 1356 1357static int 1358sol_find_new_threads_callback (const td_thrhandle_t *th, void *ignored) 1359{ 1360 td_err_e retval; 1361 td_thrinfo_t ti; 1362 ptid_t ptid; 1363 1364 retval = p_td_thr_get_info (th, &ti); 1365 if (retval != TD_OK) 1366 return -1; 1367 1368 ptid = BUILD_THREAD (ti.ti_tid, PIDGET (inferior_ptid)); 1369 if (!in_thread_list (ptid)) 1370 add_thread (ptid); 1371 1372 return 0; 1373} 1374 1375static void 1376sol_find_new_threads (void) 1377{ 1378 /* Don't do anything if init failed to resolve the libthread_db 1379 library. */ 1380 if (!procfs_suppress_run) 1381 return; 1382 1383 if (PIDGET (inferior_ptid) == -1) 1384 { 1385 printf_filtered ("No process.\n"); 1386 return; 1387 } 1388 1389 /* First Find any new LWP's. */ 1390 procfs_ops.to_find_new_threads (); 1391 1392 /* Then find any new user-level threads. */ 1393 p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0, 1394 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY, 1395 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS); 1396} 1397 1398static void 1399sol_core_open (char *filename, int from_tty) 1400{ 1401 orig_core_ops.to_open (filename, from_tty); 1402} 1403 1404static void 1405sol_core_close (int quitting) 1406{ 1407 orig_core_ops.to_close (quitting); 1408} 1409 1410static void 1411sol_core_detach (char *args, int from_tty) 1412{ 1413 unpush_target (&core_ops); 1414 orig_core_ops.to_detach (args, from_tty); 1415} 1416 1417static void 1418sol_core_files_info (struct target_ops *t) 1419{ 1420 orig_core_ops.to_files_info (t); 1421} 1422 1423/* Worker bee for the "info sol-thread" command. This is a callback 1424 function that gets called once for each Solaris user-level thread 1425 (i.e. not for LWPs) in the inferior. Print anything interesting 1426 that we can think of. */ 1427 1428static int 1429info_cb (const td_thrhandle_t *th, void *s) 1430{ 1431 td_err_e ret; 1432 td_thrinfo_t ti; 1433 1434 ret = p_td_thr_get_info (th, &ti); 1435 if (ret == TD_OK) 1436 { 1437 printf_filtered ("%s thread #%d, lwp %d, ", 1438 ti.ti_type == TD_THR_SYSTEM ? "system" : "user ", 1439 ti.ti_tid, ti.ti_lid); 1440 switch (ti.ti_state) 1441 { 1442 default: 1443 case TD_THR_UNKNOWN: 1444 printf_filtered ("<unknown state>"); 1445 break; 1446 case TD_THR_STOPPED: 1447 printf_filtered ("(stopped)"); 1448 break; 1449 case TD_THR_RUN: 1450 printf_filtered ("(run) "); 1451 break; 1452 case TD_THR_ACTIVE: 1453 printf_filtered ("(active) "); 1454 break; 1455 case TD_THR_ZOMBIE: 1456 printf_filtered ("(zombie) "); 1457 break; 1458 case TD_THR_SLEEP: 1459 printf_filtered ("(asleep) "); 1460 break; 1461 case TD_THR_STOPPED_ASLEEP: 1462 printf_filtered ("(stopped asleep)"); 1463 break; 1464 } 1465 /* Print thr_create start function. */ 1466 if (ti.ti_startfunc != 0) 1467 { 1468 struct minimal_symbol *msym; 1469 msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc); 1470 if (msym) 1471 printf_filtered (" startfunc: %s\n", 1472 DEPRECATED_SYMBOL_NAME (msym)); 1473 else 1474 printf_filtered (" startfunc: 0x%s\n", paddr (ti.ti_startfunc)); 1475 } 1476 1477 /* If thread is asleep, print function that went to sleep. */ 1478 if (ti.ti_state == TD_THR_SLEEP) 1479 { 1480 struct minimal_symbol *msym; 1481 msym = lookup_minimal_symbol_by_pc (ti.ti_pc); 1482 if (msym) 1483 printf_filtered (" - Sleep func: %s\n", 1484 DEPRECATED_SYMBOL_NAME (msym)); 1485 else 1486 printf_filtered (" - Sleep func: 0x%s\n", paddr (ti.ti_startfunc)); 1487 } 1488 1489 /* Wrap up line, if necessary. */ 1490 if (ti.ti_state != TD_THR_SLEEP && ti.ti_startfunc == 0) 1491 printf_filtered ("\n"); /* don't you hate counting newlines? */ 1492 } 1493 else 1494 warning (_("info sol-thread: failed to get info for thread.")); 1495 1496 return 0; 1497} 1498 1499/* List some state about each Solaris user-level thread in the 1500 inferior. */ 1501 1502static void 1503info_solthreads (char *args, int from_tty) 1504{ 1505 p_td_ta_thr_iter (main_ta, info_cb, args, 1506 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY, 1507 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS); 1508} 1509 1510static int 1511sol_find_memory_regions (int (*func) (CORE_ADDR, unsigned long, 1512 int, int, int, void *), 1513 void *data) 1514{ 1515 return procfs_ops.to_find_memory_regions (func, data); 1516} 1517 1518static char * 1519sol_make_note_section (bfd *obfd, int *note_size) 1520{ 1521 return procfs_ops.to_make_corefile_notes (obfd, note_size); 1522} 1523 1524static int 1525ignore (struct bp_target_info *bp_tgt) 1526{ 1527 return 0; 1528} 1529 1530static void 1531init_sol_thread_ops (void) 1532{ 1533 sol_thread_ops.to_shortname = "solaris-threads"; 1534 sol_thread_ops.to_longname = "Solaris threads and pthread."; 1535 sol_thread_ops.to_doc = "Solaris threads and pthread support."; 1536 sol_thread_ops.to_open = sol_thread_open; 1537 sol_thread_ops.to_attach = sol_thread_attach; 1538 sol_thread_ops.to_detach = sol_thread_detach; 1539 sol_thread_ops.to_resume = sol_thread_resume; 1540 sol_thread_ops.to_wait = sol_thread_wait; 1541 sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers; 1542 sol_thread_ops.to_store_registers = sol_thread_store_registers; 1543 sol_thread_ops.to_prepare_to_store = sol_thread_prepare_to_store; 1544 sol_thread_ops.deprecated_xfer_memory = sol_thread_xfer_memory; 1545 sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial; 1546 sol_thread_ops.to_files_info = sol_thread_files_info; 1547 sol_thread_ops.to_insert_breakpoint = memory_insert_breakpoint; 1548 sol_thread_ops.to_remove_breakpoint = memory_remove_breakpoint; 1549 sol_thread_ops.to_terminal_init = terminal_init_inferior; 1550 sol_thread_ops.to_terminal_inferior = terminal_inferior; 1551 sol_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output; 1552 sol_thread_ops.to_terminal_ours = terminal_ours; 1553 sol_thread_ops.to_terminal_save_ours = terminal_save_ours; 1554 sol_thread_ops.to_terminal_info = child_terminal_info; 1555 sol_thread_ops.to_kill = sol_thread_kill_inferior; 1556 sol_thread_ops.to_create_inferior = sol_thread_create_inferior; 1557 sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior; 1558 sol_thread_ops.to_can_run = sol_thread_can_run; 1559 sol_thread_ops.to_notice_signals = sol_thread_notice_signals; 1560 sol_thread_ops.to_thread_alive = sol_thread_alive; 1561 sol_thread_ops.to_pid_to_str = solaris_pid_to_str; 1562 sol_thread_ops.to_find_new_threads = sol_find_new_threads; 1563 sol_thread_ops.to_stop = sol_thread_stop; 1564 sol_thread_ops.to_stratum = process_stratum; 1565 sol_thread_ops.to_has_all_memory = 1; 1566 sol_thread_ops.to_has_memory = 1; 1567 sol_thread_ops.to_has_stack = 1; 1568 sol_thread_ops.to_has_registers = 1; 1569 sol_thread_ops.to_has_execution = 1; 1570 sol_thread_ops.to_has_thread_control = tc_none; 1571 sol_thread_ops.to_find_memory_regions = sol_find_memory_regions; 1572 sol_thread_ops.to_make_corefile_notes = sol_make_note_section; 1573 sol_thread_ops.to_magic = OPS_MAGIC; 1574} 1575 1576static void 1577init_sol_core_ops (void) 1578{ 1579 sol_core_ops.to_shortname = "solaris-core"; 1580 sol_core_ops.to_longname = "Solaris core threads and pthread."; 1581 sol_core_ops.to_doc = "Solaris threads and pthread support for core files."; 1582 sol_core_ops.to_open = sol_core_open; 1583 sol_core_ops.to_close = sol_core_close; 1584 sol_core_ops.to_attach = sol_thread_attach; 1585 sol_core_ops.to_detach = sol_core_detach; 1586 sol_core_ops.to_fetch_registers = sol_thread_fetch_registers; 1587 sol_core_ops.deprecated_xfer_memory = sol_thread_xfer_memory; 1588 sol_core_ops.to_xfer_partial = sol_thread_xfer_partial; 1589 sol_core_ops.to_files_info = sol_core_files_info; 1590 sol_core_ops.to_insert_breakpoint = ignore; 1591 sol_core_ops.to_remove_breakpoint = ignore; 1592 sol_core_ops.to_create_inferior = sol_thread_create_inferior; 1593 sol_core_ops.to_stratum = core_stratum; 1594 sol_core_ops.to_has_memory = 1; 1595 sol_core_ops.to_has_stack = 1; 1596 sol_core_ops.to_has_registers = 1; 1597 sol_core_ops.to_has_thread_control = tc_none; 1598 sol_core_ops.to_thread_alive = sol_thread_alive; 1599 sol_core_ops.to_pid_to_str = solaris_pid_to_str; 1600 /* On Solaris/x86, when debugging a threaded core file from process 1601 <n>, the following causes "info threads" to produce "procfs: 1602 couldn't find pid <n> in procinfo list" where <n> is the pid of 1603 the process that produced the core file. Disable it for now. */ 1604#if 0 1605 sol_core_ops.to_find_new_threads = sol_find_new_threads; 1606#endif 1607 sol_core_ops.to_magic = OPS_MAGIC; 1608} 1609 1610/* We suppress the call to add_target of core_ops in corelow because 1611 if there are two targets in the stratum core_stratum, 1612 find_core_target won't know which one to return. See corelow.c for 1613 an additonal comment on coreops_suppress_target. */ 1614int coreops_suppress_target = 1; 1615 1616void 1617_initialize_sol_thread (void) 1618{ 1619 void *dlhandle; 1620 1621 init_sol_thread_ops (); 1622 init_sol_core_ops (); 1623 1624 dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW); 1625 if (!dlhandle) 1626 goto die; 1627 1628#define resolve(X) \ 1629 if (!(p_##X = dlsym (dlhandle, #X))) \ 1630 goto die; 1631 1632 resolve (td_log); 1633 resolve (td_ta_new); 1634 resolve (td_ta_delete); 1635 resolve (td_init); 1636 resolve (td_ta_get_ph); 1637 resolve (td_ta_get_nthreads); 1638 resolve (td_ta_tsd_iter); 1639 resolve (td_ta_thr_iter); 1640 resolve (td_thr_validate); 1641 resolve (td_thr_tsd); 1642 resolve (td_thr_get_info); 1643 resolve (td_thr_getfpregs); 1644 resolve (td_thr_getxregsize); 1645 resolve (td_thr_getxregs); 1646 resolve (td_thr_sigsetmask); 1647 resolve (td_thr_setprio); 1648 resolve (td_thr_setsigpending); 1649 resolve (td_thr_setfpregs); 1650 resolve (td_thr_setxregs); 1651 resolve (td_ta_map_id2thr); 1652 resolve (td_ta_map_lwp2thr); 1653 resolve (td_thr_getgregs); 1654 resolve (td_thr_setgregs); 1655 1656 add_target (&sol_thread_ops); 1657 1658 procfs_suppress_run = 1; 1659 1660 add_cmd ("sol-threads", class_maintenance, info_solthreads, 1661 _("Show info on Solaris user threads."), &maintenanceinfolist); 1662 1663 memcpy (&orig_core_ops, &core_ops, sizeof (struct target_ops)); 1664 memcpy (&core_ops, &sol_core_ops, sizeof (struct target_ops)); 1665 add_target (&core_ops); 1666 1667 /* Hook into new_objfile notification. */ 1668 observer_attach_new_objfile (sol_thread_new_objfile); 1669 return; 1670 1671 die: 1672 fprintf_unfiltered (gdb_stderr, "\ 1673[GDB will not be able to debug user-mode threads: %s]\n", dlerror ()); 1674 1675 if (dlhandle) 1676 dlclose (dlhandle); 1677 1678 /* Allow the user to debug non-threaded core files. */ 1679 add_target (&core_ops); 1680 1681 return; 1682} 1683