OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [sol-thread.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.