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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [sol-thread.c] - Blame information for rev 853

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* Solaris threads debugging interface.
2
 
3
   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4
   2007, 2008, 2009, 2010 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
#include "gdb_string.h"
69
#include "procfs.h"
70
 
71
struct target_ops sol_thread_ops;
72
 
73
extern char *procfs_pid_to_str (struct target_ops *ops, ptid_t ptid);
74
 
75
/* Prototypes for supply_gregset etc. */
76
#include "gregset.h"
77
 
78
/* This struct is defined by us, but mainly used for the proc_service
79
   interface.  We don't have much use for it, except as a handy place
80
   to get a real PID for memory accesses.  */
81
 
82
struct ps_prochandle
83
{
84
  ptid_t ptid;
85
};
86
 
87
struct string_map
88
{
89
  int num;
90
  char *str;
91
};
92
 
93
static struct ps_prochandle main_ph;
94
static td_thragent_t *main_ta;
95
static int sol_thread_active = 0;
96
 
97
static void init_sol_thread_ops (void);
98
 
99
/* Default definitions: These must be defined in tm.h if they are to
100
   be shared with a process module such as procfs.  */
101
 
102
#define GET_PID(ptid)           ptid_get_pid (ptid)
103
#define GET_LWP(ptid)           ptid_get_lwp (ptid)
104
#define GET_THREAD(ptid)        ptid_get_tid (ptid)
105
 
106
#define is_lwp(ptid)            (GET_LWP (ptid) != 0)
107
#define is_thread(ptid)         (GET_THREAD (ptid) != 0)
108
 
109
#define BUILD_LWP(lwp, pid)     ptid_build (pid, lwp, 0)
110
#define BUILD_THREAD(tid, pid)  ptid_build (pid, 0, tid)
111
 
112
/* Pointers to routines from libthread_db resolved by dlopen().  */
113
 
114
static void (*p_td_log)(const int on_off);
115
static td_err_e (*p_td_ta_new)(const struct ps_prochandle *ph_p,
116
                               td_thragent_t **ta_pp);
117
static td_err_e (*p_td_ta_delete)(td_thragent_t *ta_p);
118
static td_err_e (*p_td_init)(void);
119
static td_err_e (*p_td_ta_get_ph)(const td_thragent_t *ta_p,
120
                                  struct ps_prochandle **ph_pp);
121
static td_err_e (*p_td_ta_get_nthreads)(const td_thragent_t *ta_p,
122
                                        int *nthread_p);
123
static td_err_e (*p_td_ta_tsd_iter)(const td_thragent_t *ta_p,
124
                                    td_key_iter_f *cb, void *cbdata_p);
125
static td_err_e (*p_td_ta_thr_iter)(const td_thragent_t *ta_p,
126
                                    td_thr_iter_f *cb, void *cbdata_p,
127
                                    td_thr_state_e state, int ti_pri,
128
                                    sigset_t *ti_sigmask_p,
129
                                    unsigned ti_user_flags);
130
static td_err_e (*p_td_thr_validate)(const td_thrhandle_t *th_p);
131
static td_err_e (*p_td_thr_tsd)(const td_thrhandle_t * th_p,
132
                                const thread_key_t key, void **data_pp);
133
static td_err_e (*p_td_thr_get_info)(const td_thrhandle_t *th_p,
134
                                     td_thrinfo_t *ti_p);
135
static td_err_e (*p_td_thr_getfpregs)(const td_thrhandle_t *th_p,
136
                                      prfpregset_t *fpregset);
137
static td_err_e (*p_td_thr_getxregsize)(const td_thrhandle_t *th_p,
138
                                        int *xregsize);
139
static td_err_e (*p_td_thr_getxregs)(const td_thrhandle_t *th_p,
140
                                     const caddr_t xregset);
141
static td_err_e (*p_td_thr_sigsetmask)(const td_thrhandle_t *th_p,
142
                                       const sigset_t ti_sigmask);
143
static td_err_e (*p_td_thr_setprio)(const td_thrhandle_t *th_p,
144
                                    const int ti_pri);
145
static td_err_e (*p_td_thr_setsigpending)(const td_thrhandle_t *th_p,
146
                                          const uchar_t ti_pending_flag,
147
                                          const sigset_t ti_pending);
148
static td_err_e (*p_td_thr_setfpregs)(const td_thrhandle_t *th_p,
149
                                      const prfpregset_t *fpregset);
150
static td_err_e (*p_td_thr_setxregs)(const td_thrhandle_t *th_p,
151
                                     const caddr_t xregset);
152
static td_err_e (*p_td_ta_map_id2thr)(const td_thragent_t *ta_p,
153
                                      thread_t tid,
154
                                      td_thrhandle_t *th_p);
155
static td_err_e (*p_td_ta_map_lwp2thr)(const td_thragent_t *ta_p,
156
                                       lwpid_t lwpid,
157
                                       td_thrhandle_t *th_p);
158
static td_err_e (*p_td_thr_getgregs)(const td_thrhandle_t *th_p,
159
                                     prgregset_t regset);
160
static td_err_e (*p_td_thr_setgregs)(const td_thrhandle_t *th_p,
161
                                     const prgregset_t regset);
162
 
163
 
164
/* Return the libthread_db error string associated with ERRCODE.  If
165
   ERRCODE is unknown, return an appropriate message.  */
166
 
167
static char *
168
td_err_string (td_err_e errcode)
169
{
170
  static struct string_map td_err_table[] =
171
  {
172
    { TD_OK, "generic \"call succeeded\"" },
173
    { TD_ERR, "generic error." },
174
    { TD_NOTHR, "no thread can be found to satisfy query" },
175
    { TD_NOSV, "no synch. variable can be found to satisfy query" },
176
    { TD_NOLWP, "no lwp can be found to satisfy query" },
177
    { TD_BADPH, "invalid process handle" },
178
    { TD_BADTH, "invalid thread handle" },
179
    { TD_BADSH, "invalid synchronization handle" },
180
    { TD_BADTA, "invalid thread agent" },
181
    { TD_BADKEY, "invalid key" },
182
    { TD_NOMSG, "td_thr_event_getmsg() called when there was no message" },
183
    { TD_NOFPREGS, "FPU register set not available for given thread" },
184
    { TD_NOLIBTHREAD, "application not linked with libthread" },
185
    { TD_NOEVENT, "requested event is not supported" },
186
    { TD_NOCAPAB, "capability not available" },
187
    { TD_DBERR, "Debugger service failed" },
188
    { TD_NOAPLIC, "Operation not applicable to" },
189
    { TD_NOTSD, "No thread specific data for this thread" },
190
    { TD_MALLOC, "Malloc failed" },
191
    { TD_PARTIALREG, "Only part of register set was written/read" },
192
    { TD_NOXREGS, "X register set not available for given thread" }
193
  };
194
  const int td_err_size = sizeof td_err_table / sizeof (struct string_map);
195
  int i;
196
  static char buf[50];
197
 
198
  for (i = 0; i < td_err_size; i++)
199
    if (td_err_table[i].num == errcode)
200
      return td_err_table[i].str;
201
 
202
  sprintf (buf, "Unknown libthread_db error code: %d", errcode);
203
 
204
  return buf;
205
}
206
 
207
/* Return the the libthread_db state string assicoated with STATECODE.
208
   If STATECODE is unknown, return an appropriate message.  */
209
 
210
static char *
211
td_state_string (td_thr_state_e statecode)
212
{
213
  static struct string_map td_thr_state_table[] =
214
  {
215
    { TD_THR_ANY_STATE, "any state" },
216
    { TD_THR_UNKNOWN, "unknown" },
217
    { TD_THR_STOPPED, "stopped" },
218
    { TD_THR_RUN, "run" },
219
    { TD_THR_ACTIVE, "active" },
220
    { TD_THR_ZOMBIE, "zombie" },
221
    { TD_THR_SLEEP, "sleep" },
222
    { TD_THR_STOPPED_ASLEEP, "stopped asleep" }
223
  };
224
  const int td_thr_state_table_size =
225
    sizeof td_thr_state_table / sizeof (struct string_map);
226
  int i;
227
  static char buf[50];
228
 
229
  for (i = 0; i < td_thr_state_table_size; i++)
230
    if (td_thr_state_table[i].num == statecode)
231
      return td_thr_state_table[i].str;
232
 
233
  sprintf (buf, "Unknown libthread_db state code: %d", statecode);
234
 
235
  return buf;
236
}
237
 
238
 
239
/* Convert a POSIX or Solaris thread ID into a LWP ID.  If THREAD_ID
240
   doesn't exist, that's an error.  If it's an inactive thread, return
241
   DEFAULT_LWP.
242
 
243
   NOTE: This function probably shouldn't call error().  */
244
 
245
static ptid_t
246
thread_to_lwp (ptid_t thread_id, int default_lwp)
247
{
248
  td_thrinfo_t ti;
249
  td_thrhandle_t th;
250
  td_err_e val;
251
 
252
  if (is_lwp (thread_id))
253
    return thread_id;           /* It's already an LWP ID.  */
254
 
255
  /* It's a thread.  Convert to LWP.  */
256
 
257
  val = p_td_ta_map_id2thr (main_ta, GET_THREAD (thread_id), &th);
258
  if (val == TD_NOTHR)
259
    return pid_to_ptid (-1);    /* Thread must have terminated.  */
260
  else if (val != TD_OK)
261
    error (_("thread_to_lwp: td_ta_map_id2thr %s"), td_err_string (val));
262
 
263
  val = p_td_thr_get_info (&th, &ti);
264
  if (val == TD_NOTHR)
265
    return pid_to_ptid (-1);    /* Thread must have terminated.  */
266
  else if (val != TD_OK)
267
    error (_("thread_to_lwp: td_thr_get_info: %s"), td_err_string (val));
268
 
269
  if (ti.ti_state != TD_THR_ACTIVE)
270
    {
271
      if (default_lwp != -1)
272
        return pid_to_ptid (default_lwp);
273
      error (_("thread_to_lwp: thread state not active: %s"),
274
             td_state_string (ti.ti_state));
275
    }
276
 
277
  return BUILD_LWP (ti.ti_lid, PIDGET (thread_id));
278
}
279
 
280
/* Convert an LWP ID into a POSIX or Solaris thread ID.  If LWP_ID
281
   doesn't exists, that's an error.
282
 
283
   NOTE: This function probably shouldn't call error().  */
284
 
285
static ptid_t
286
lwp_to_thread (ptid_t lwp)
287
{
288
  td_thrinfo_t ti;
289
  td_thrhandle_t th;
290
  td_err_e val;
291
 
292
  if (is_thread (lwp))
293
    return lwp;                 /* It's already a thread ID.  */
294
 
295
  /* It's an LWP.  Convert it to a thread ID.  */
296
 
297
  if (!target_thread_alive (lwp))
298
    return pid_to_ptid (-1);    /* Must be a defunct LPW.  */
299
 
300
  val = p_td_ta_map_lwp2thr (main_ta, GET_LWP (lwp), &th);
301
  if (val == TD_NOTHR)
302
    return pid_to_ptid (-1);    /* Thread must have terminated.  */
303
  else if (val != TD_OK)
304
    error (_("lwp_to_thread: td_ta_map_lwp2thr: %s."), td_err_string (val));
305
 
306
  val = p_td_thr_validate (&th);
307
  if (val == TD_NOTHR)
308
    return lwp;                 /* Unknown to libthread; just return LPW,  */
309
  else if (val != TD_OK)
310
    error (_("lwp_to_thread: td_thr_validate: %s."), td_err_string (val));
311
 
312
  val = p_td_thr_get_info (&th, &ti);
313
  if (val == TD_NOTHR)
314
    return pid_to_ptid (-1);    /* Thread must have terminated.  */
315
  else if (val != TD_OK)
316
    error (_("lwp_to_thread: td_thr_get_info: %s."), td_err_string (val));
317
 
318
  return BUILD_THREAD (ti.ti_tid, PIDGET (lwp));
319
}
320
 
321
 
322
/* Most target vector functions from here on actually just pass
323
   through to the layer beneath, as they don't need to do anything
324
   specific for threads.  */
325
 
326
/* Take a program previously attached to and detaches it.  The program
327
   resumes execution and will no longer stop on signals, etc.  We'd
328
   better not have left any breakpoints in the program or it'll die
329
   when it hits one.  For this to work, it may be necessary for the
330
   process to have been previously attached.  It *might* work if the
331
   program was started via the normal ptrace (PTRACE_TRACEME).  */
332
 
333
static void
334
sol_thread_detach (struct target_ops *ops, char *args, int from_tty)
335
{
336
  struct target_ops *beneath = find_target_beneath (ops);
337
 
338
  sol_thread_active = 0;
339
  inferior_ptid = pid_to_ptid (PIDGET (main_ph.ptid));
340
  unpush_target (ops);
341
  beneath->to_detach (beneath, args, from_tty);
342
}
343
 
344
/* Resume execution of process PTID.  If STEP is nozero, then just
345
   single step it.  If SIGNAL is nonzero, restart it with that signal
346
   activated.  We may have to convert PTID from a thread ID to an LWP
347
   ID for procfs.  */
348
 
349
static void
350
sol_thread_resume (struct target_ops *ops,
351
                   ptid_t ptid, int step, enum target_signal signo)
352
{
353
  struct cleanup *old_chain;
354
  struct target_ops *beneath = find_target_beneath (ops);
355
 
356
  old_chain = save_inferior_ptid ();
357
 
358
  inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
359
  if (PIDGET (inferior_ptid) == -1)
360
    inferior_ptid = procfs_first_available ();
361
 
362
  if (PIDGET (ptid) != -1)
363
    {
364
      ptid_t save_ptid = ptid;
365
 
366
      ptid = thread_to_lwp (ptid, -2);
367
      if (PIDGET (ptid) == -2)          /* Inactive thread.  */
368
        error (_("This version of Solaris can't start inactive threads."));
369
      if (info_verbose && PIDGET (ptid) == -1)
370
        warning (_("Specified thread %ld seems to have terminated"),
371
                 GET_THREAD (save_ptid));
372
    }
373
 
374
  beneath->to_resume (beneath, ptid, step, signo);
375
 
376
  do_cleanups (old_chain);
377
}
378
 
379
/* Wait for any threads to stop.  We may have to convert PTID from a
380
   thread ID to an LWP ID, and vice versa on the way out.  */
381
 
382
static ptid_t
383
sol_thread_wait (struct target_ops *ops,
384
                 ptid_t ptid, struct target_waitstatus *ourstatus, int options)
385
{
386
  ptid_t rtnval;
387
  ptid_t save_ptid;
388
  struct target_ops *beneath = find_target_beneath (ops);
389
  struct cleanup *old_chain;
390
 
391
  save_ptid = inferior_ptid;
392
  old_chain = save_inferior_ptid ();
393
 
394
  inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
395
  if (PIDGET (inferior_ptid) == -1)
396
    inferior_ptid = procfs_first_available ();
397
 
398
  if (PIDGET (ptid) != -1)
399
    {
400
      ptid_t save_ptid = ptid;
401
 
402
      ptid = thread_to_lwp (ptid, -2);
403
      if (PIDGET (ptid) == -2)          /* Inactive thread.  */
404
        error (_("This version of Solaris can't start inactive threads."));
405
      if (info_verbose && PIDGET (ptid) == -1)
406
        warning (_("Specified thread %ld seems to have terminated"),
407
                 GET_THREAD (save_ptid));
408
    }
409
 
410
  rtnval = beneath->to_wait (beneath, ptid, ourstatus, options);
411
 
412
  if (ourstatus->kind != TARGET_WAITKIND_EXITED)
413
    {
414
      /* Map the LWP of interest back to the appropriate thread ID.  */
415
      rtnval = lwp_to_thread (rtnval);
416
      if (PIDGET (rtnval) == -1)
417
        rtnval = save_ptid;
418
 
419
      /* See if we have a new thread.  */
420
      if (is_thread (rtnval)
421
          && !ptid_equal (rtnval, save_ptid)
422
          && (!in_thread_list (rtnval)
423
              || is_exited (rtnval)))
424
        add_thread (rtnval);
425
    }
426
 
427
  /* During process initialization, we may get here without the thread
428
     package being initialized, since that can only happen after we've
429
     found the shared libs.  */
430
 
431
  do_cleanups (old_chain);
432
 
433
  return rtnval;
434
}
435
 
436
static void
437
sol_thread_fetch_registers (struct target_ops *ops,
438
                            struct regcache *regcache, int regnum)
439
{
440
  thread_t thread;
441
  td_thrhandle_t thandle;
442
  td_err_e val;
443
  prgregset_t gregset;
444
  prfpregset_t fpregset;
445
  gdb_gregset_t *gregset_p = &gregset;
446
  gdb_fpregset_t *fpregset_p = &fpregset;
447
  struct target_ops *beneath = find_target_beneath (ops);
448
 
449
#if 0
450
  int xregsize;
451
  caddr_t xregset;
452
#endif
453
 
454
  if (!is_thread (inferior_ptid))
455
    {
456
      /* It's an LWP; pass the request on to the layer beneath.  */
457
      beneath->to_fetch_registers (beneath, regcache, regnum);
458
      return;
459
    }
460
 
461
  /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t.  */
462
  thread = GET_THREAD (inferior_ptid);
463
  if (thread == 0)
464
    error (_("sol_thread_fetch_registers: thread == 0"));
465
 
466
  val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
467
  if (val != TD_OK)
468
    error (_("sol_thread_fetch_registers: td_ta_map_id2thr: %s"),
469
           td_err_string (val));
470
 
471
  /* Get the general-purpose registers.  */
472
 
473
  val = p_td_thr_getgregs (&thandle, gregset);
474
  if (val != TD_OK && val != TD_PARTIALREG)
475
    error (_("sol_thread_fetch_registers: td_thr_getgregs %s"),
476
           td_err_string (val));
477
 
478
  /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
479
     and %sp are saved (by a thread context switch).  */
480
 
481
  /* And, now the floating-point registers.  */
482
 
483
  val = p_td_thr_getfpregs (&thandle, &fpregset);
484
  if (val != TD_OK && val != TD_NOFPREGS)
485
    error (_("sol_thread_fetch_registers: td_thr_getfpregs %s"),
486
           td_err_string (val));
487
 
488
  /* Note that we must call supply_gregset and supply_fpregset *after*
489
     calling the td routines because the td routines call ps_lget*
490
     which affect the values stored in the registers array.  */
491
 
492
  supply_gregset (regcache, (const gdb_gregset_t *) gregset_p);
493
  supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset_p);
494
 
495
#if 0
496
  /* FIXME: libthread_db doesn't seem to handle this right.  */
497
  val = td_thr_getxregsize (&thandle, &xregsize);
498
  if (val != TD_OK && val != TD_NOXREGS)
499
    error (_("sol_thread_fetch_registers: td_thr_getxregsize %s"),
500
           td_err_string (val));
501
 
502
  if (val == TD_OK)
503
    {
504
      xregset = alloca (xregsize);
505
      val = td_thr_getxregs (&thandle, xregset);
506
      if (val != TD_OK)
507
        error (_("sol_thread_fetch_registers: td_thr_getxregs %s"),
508
               td_err_string (val));
509
    }
510
#endif
511
}
512
 
513
static void
514
sol_thread_store_registers (struct target_ops *ops,
515
                            struct regcache *regcache, int regnum)
516
{
517
  thread_t thread;
518
  td_thrhandle_t thandle;
519
  td_err_e val;
520
  prgregset_t gregset;
521
  prfpregset_t fpregset;
522
#if 0
523
  int xregsize;
524
  caddr_t xregset;
525
#endif
526
 
527
  if (!is_thread (inferior_ptid))
528
    {
529
      struct target_ops *beneath = find_target_beneath (ops);
530
 
531
      /* It's an LWP; pass the request on to the layer beneath.  */
532
      beneath->to_store_registers (beneath, regcache, regnum);
533
      return;
534
    }
535
 
536
  /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t.  */
537
  thread = GET_THREAD (inferior_ptid);
538
 
539
  val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
540
  if (val != TD_OK)
541
    error (_("sol_thread_store_registers: td_ta_map_id2thr %s"),
542
           td_err_string (val));
543
 
544
  if (regnum != -1)
545
    {
546
      /* Not writing all the registers.  */
547
      char old_value[MAX_REGISTER_SIZE];
548
 
549
      /* Save new register value.  */
550
      regcache_raw_collect (regcache, regnum, old_value);
551
 
552
      val = p_td_thr_getgregs (&thandle, gregset);
553
      if (val != TD_OK)
554
        error (_("sol_thread_store_registers: td_thr_getgregs %s"),
555
               td_err_string (val));
556
      val = p_td_thr_getfpregs (&thandle, &fpregset);
557
      if (val != TD_OK)
558
        error (_("sol_thread_store_registers: td_thr_getfpregs %s"),
559
               td_err_string (val));
560
 
561
      /* Restore new register value.  */
562
      regcache_raw_supply (regcache, regnum, old_value);
563
 
564
#if 0
565
      /* FIXME: libthread_db doesn't seem to handle this right.  */
566
      val = td_thr_getxregsize (&thandle, &xregsize);
567
      if (val != TD_OK && val != TD_NOXREGS)
568
        error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
569
               td_err_string (val));
570
 
571
      if (val == TD_OK)
572
        {
573
          xregset = alloca (xregsize);
574
          val = td_thr_getxregs (&thandle, xregset);
575
          if (val != TD_OK)
576
            error (_("sol_thread_store_registers: td_thr_getxregs %s"),
577
                   td_err_string (val));
578
        }
579
#endif
580
    }
581
 
582
  fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum);
583
  fill_fpregset (regcache, (gdb_fpregset_t *) &fpregset, regnum);
584
 
585
  val = p_td_thr_setgregs (&thandle, gregset);
586
  if (val != TD_OK)
587
    error (_("sol_thread_store_registers: td_thr_setgregs %s"),
588
           td_err_string (val));
589
  val = p_td_thr_setfpregs (&thandle, &fpregset);
590
  if (val != TD_OK)
591
    error (_("sol_thread_store_registers: td_thr_setfpregs %s"),
592
           td_err_string (val));
593
 
594
#if 0
595
  /* FIXME: libthread_db doesn't seem to handle this right.  */
596
  val = td_thr_getxregsize (&thandle, &xregsize);
597
  if (val != TD_OK && val != TD_NOXREGS)
598
    error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
599
           td_err_string (val));
600
 
601
  /* ??? Should probably do something about writing the xregs here,
602
     but what are they?  */
603
#endif
604
}
605
 
606
/* Perform partial transfers on OBJECT.  See target_read_partial and
607
   target_write_partial for details of each variant.  One, and only
608
   one, of readbuf or writebuf must be non-NULL.  */
609
 
610
static LONGEST
611
sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
612
                          const char *annex, gdb_byte *readbuf,
613
                          const gdb_byte *writebuf,
614
                         ULONGEST offset, LONGEST len)
615
{
616
  int retval;
617
  struct cleanup *old_chain;
618
  struct target_ops *beneath = find_target_beneath (ops);
619
 
620
  old_chain = save_inferior_ptid ();
621
 
622
  if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
623
    {
624
      /* It's either a thread or an LWP that isn't alive.  Any live
625
         LWP will do so use the first available.
626
 
627
         NOTE: We don't need to call switch_to_thread; we're just
628
         reading memory.  */
629
      inferior_ptid = procfs_first_available ();
630
    }
631
 
632
  retval = beneath->to_xfer_partial (beneath, object, annex,
633
                                     readbuf, writebuf, offset, len);
634
 
635
  do_cleanups (old_chain);
636
 
637
  return retval;
638
}
639
 
640
static void
641
check_for_thread_db (void)
642
{
643
  td_err_e err;
644
  ptid_t ptid;
645
 
646
  /* Do nothing if we couldn't load libthread_db.so.1.  */
647
  if (p_td_ta_new == NULL)
648
    return;
649
 
650
  if (sol_thread_active)
651
    /* Nothing to do.  The thread library was already detected and the
652
       target vector was already activated.  */
653
    return;
654
 
655
  /* Now, initialize libthread_db.  This needs to be done after the
656
     shared libraries are located because it needs information from
657
     the user's thread library.  */
658
 
659
  err = p_td_init ();
660
  if (err != TD_OK)
661
    {
662
      warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (err));
663
      return;
664
    }
665
 
666
  /* Now attempt to open a connection to the thread library.  */
667
  err = p_td_ta_new (&main_ph, &main_ta);
668
  switch (err)
669
    {
670
    case TD_NOLIBTHREAD:
671
      /* No thread library was detected.  */
672
      break;
673
 
674
    case TD_OK:
675
      printf_unfiltered (_("[Thread debugging using libthread_db enabled]\n"));
676
 
677
      /* The thread library was detected.  Activate the sol_thread target.  */
678
      push_target (&sol_thread_ops);
679
      sol_thread_active = 1;
680
 
681
      main_ph.ptid = inferior_ptid; /* Save for xfer_memory.  */
682
      ptid = lwp_to_thread (inferior_ptid);
683
      if (PIDGET (ptid) != -1)
684
        inferior_ptid = ptid;
685
 
686
      target_find_new_threads ();
687
      break;
688
 
689
    default:
690
      warning (_("Cannot initialize thread debugging library: %s"),
691
               td_err_string (err));
692
      break;
693
    }
694
}
695
 
696
/* This routine is called whenever a new symbol table is read in, or
697
   when all symbol tables are removed.  libthread_db can only be
698
   initialized when it finds the right variables in libthread.so.
699
   Since it's a shared library, those variables don't show up until
700
   the library gets mapped and the symbol table is read in.  */
701
 
702
static void
703
sol_thread_new_objfile (struct objfile *objfile)
704
{
705
  if (objfile != NULL)
706
    check_for_thread_db ();
707
}
708
 
709
/* Clean up after the inferior dies.  */
710
 
711
static void
712
sol_thread_mourn_inferior (struct target_ops *ops)
713
{
714
  struct target_ops *beneath = find_target_beneath (ops);
715
 
716
  sol_thread_active = 0;
717
 
718
  unpush_target (ops);
719
 
720
  beneath->to_mourn_inferior (beneath);
721
}
722
 
723
/* Return true if PTID is still active in the inferior.  */
724
 
725
static int
726
sol_thread_alive (struct target_ops *ops, ptid_t ptid)
727
{
728
  if (is_thread (ptid))
729
    {
730
      /* It's a (user-level) thread.  */
731
      td_err_e val;
732
      td_thrhandle_t th;
733
      int pid;
734
 
735
      pid = GET_THREAD (ptid);
736
      if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
737
        return 0;                /* Thread not found.  */
738
      if ((val = p_td_thr_validate (&th)) != TD_OK)
739
        return 0;                /* Thread not valid.  */
740
      return 1;                 /* Known thread.  */
741
    }
742
  else
743
    {
744
      struct target_ops *beneath = find_target_beneath (ops);
745
 
746
      /* It's an LPW; pass the request on to the layer below.  */
747
      return beneath->to_thread_alive (beneath, ptid);
748
    }
749
}
750
 
751
 
752
/* These routines implement the lower half of the thread_db interface,
753
   i.e. the ps_* routines.  */
754
 
755
/* Various versions of <proc_service.h> have slightly different
756
   function prototypes.  In particular, we have
757
 
758
   NEWER                        OLDER
759
   struct ps_prochandle *       const struct ps_prochandle *
760
   void*                        char*
761
   const void*                  char*
762
   int                          size_t
763
 
764
   Which one you have depends on the Solaris version and what patches
765
   you've applied.  On the theory that there are only two major
766
   variants, we have configure check the prototype of ps_pdwrite (),
767
   and use that info to make appropriate typedefs here. */
768
 
769
#ifdef PROC_SERVICE_IS_OLD
770
typedef const struct ps_prochandle *gdb_ps_prochandle_t;
771
typedef char *gdb_ps_read_buf_t;
772
typedef char *gdb_ps_write_buf_t;
773
typedef int gdb_ps_size_t;
774
typedef psaddr_t gdb_ps_addr_t;
775
#else
776
typedef struct ps_prochandle *gdb_ps_prochandle_t;
777
typedef void *gdb_ps_read_buf_t;
778
typedef const void *gdb_ps_write_buf_t;
779
typedef size_t gdb_ps_size_t;
780
typedef psaddr_t gdb_ps_addr_t;
781
#endif
782
 
783
/* The next four routines are called by libthread_db to tell us to
784
   stop and stop a particular process or lwp.  Since GDB ensures that
785
   these are all stopped by the time we call anything in thread_db,
786
   these routines need to do nothing.  */
787
 
788
/* Process stop.  */
789
 
790
ps_err_e
791
ps_pstop (gdb_ps_prochandle_t ph)
792
{
793
  return PS_OK;
794
}
795
 
796
/* Process continue.  */
797
 
798
ps_err_e
799
ps_pcontinue (gdb_ps_prochandle_t ph)
800
{
801
  return PS_OK;
802
}
803
 
804
/* LWP stop.  */
805
 
806
ps_err_e
807
ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
808
{
809
  return PS_OK;
810
}
811
 
812
/* LWP continue.  */
813
 
814
ps_err_e
815
ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
816
{
817
  return PS_OK;
818
}
819
 
820
/* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table.  */
821
 
822
ps_err_e
823
ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
824
                   const char *ld_symbol_name, gdb_ps_addr_t *ld_symbol_addr)
825
{
826
  struct minimal_symbol *ms;
827
 
828
  ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
829
  if (!ms)
830
    return PS_NOSYM;
831
 
832
  *ld_symbol_addr = SYMBOL_VALUE_ADDRESS (ms);
833
  return PS_OK;
834
}
835
 
836
/* Common routine for reading and writing memory.  */
837
 
838
static ps_err_e
839
rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
840
           char *buf, int size)
841
{
842
  int ret;
843
  struct cleanup *old_chain;
844
 
845
  old_chain = save_inferior_ptid ();
846
 
847
  if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
848
    {
849
      /* It's either a thread or an LWP that isn't alive.  Any live
850
         LWP will do so use the first available.
851
 
852
         NOTE: We don't need to call switch_to_thread; we're just
853
         reading memory.  */
854
      inferior_ptid = procfs_first_available ();
855
    }
856
 
857
#if defined (__sparcv9)
858
  /* For Sparc64 cross Sparc32, make sure the address has not been
859
     accidentally sign-extended (or whatever) to beyond 32 bits.  */
860
  if (bfd_get_arch_size (exec_bfd) == 32)
861
    addr &= 0xffffffff;
862
#endif
863
 
864
  if (dowrite)
865
    ret = target_write_memory (addr, buf, size);
866
  else
867
    ret = target_read_memory (addr, buf, size);
868
 
869
  do_cleanups (old_chain);
870
 
871
  return (ret == 0 ? PS_OK : PS_ERR);
872
}
873
 
874
/* Copies SIZE bytes from target process .data segment to debugger memory.  */
875
 
876
ps_err_e
877
ps_pdread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
878
           gdb_ps_read_buf_t buf, gdb_ps_size_t size)
879
{
880
  return rw_common (0, ph, addr, buf, size);
881
}
882
 
883
/* Copies SIZE bytes from debugger memory .data segment to target process.  */
884
 
885
ps_err_e
886
ps_pdwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
887
            gdb_ps_write_buf_t buf, gdb_ps_size_t size)
888
{
889
  return rw_common (1, ph, addr, (char *) buf, size);
890
}
891
 
892
/* Copies SIZE bytes from target process .text segment to debugger memory.  */
893
 
894
ps_err_e
895
ps_ptread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
896
           gdb_ps_read_buf_t buf, gdb_ps_size_t size)
897
{
898
  return rw_common (0, ph, addr, buf, size);
899
}
900
 
901
/* Copies SIZE bytes from debugger memory .text segment to target process.  */
902
 
903
ps_err_e
904
ps_ptwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
905
            gdb_ps_write_buf_t buf, gdb_ps_size_t size)
906
{
907
  return rw_common (1, ph, addr, (char *) buf, size);
908
}
909
 
910
/* Get general-purpose registers for LWP.  */
911
 
912
ps_err_e
913
ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
914
{
915
  struct cleanup *old_chain;
916
  struct regcache *regcache;
917
 
918
  old_chain = save_inferior_ptid ();
919
 
920
  inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
921
  regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch);
922
 
923
  target_fetch_registers (regcache, -1);
924
  fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
925
 
926
  do_cleanups (old_chain);
927
 
928
  return PS_OK;
929
}
930
 
931
/* Set general-purpose registers for LWP.  */
932
 
933
ps_err_e
934
ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
935
             const prgregset_t gregset)
936
{
937
  struct cleanup *old_chain;
938
  struct regcache *regcache;
939
 
940
  old_chain = save_inferior_ptid ();
941
 
942
  inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
943
  regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch);
944
 
945
  supply_gregset (regcache, (const gdb_gregset_t *) gregset);
946
  target_store_registers (regcache, -1);
947
 
948
  do_cleanups (old_chain);
949
 
950
  return PS_OK;
951
}
952
 
953
/* Log a message (sends to gdb_stderr).  */
954
 
955
void
956
ps_plog (const char *fmt, ...)
957
{
958
  va_list args;
959
 
960
  va_start (args, fmt);
961
 
962
  vfprintf_filtered (gdb_stderr, fmt, args);
963
}
964
 
965
/* Get size of extra register set.  Currently a noop.  */
966
 
967
ps_err_e
968
ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
969
{
970
#if 0
971
  int lwp_fd;
972
  int regsize;
973
  ps_err_e val;
974
 
975
  val = get_lwp_fd (ph, lwpid, &lwp_fd);
976
  if (val != PS_OK)
977
    return val;
978
 
979
  if (ioctl (lwp_fd, PIOCGXREGSIZE, &regsize))
980
    {
981
      if (errno == EINVAL)
982
        return PS_NOFREGS;      /* XXX Wrong code, but this is the closest
983
                                   thing in proc_service.h  */
984
 
985
      print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno);
986
      return PS_ERR;
987
    }
988
#endif
989
 
990
  return PS_OK;
991
}
992
 
993
/* Get extra register set.  Currently a noop.  */
994
 
995
ps_err_e
996
ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
997
{
998
#if 0
999
  int lwp_fd;
1000
  ps_err_e val;
1001
 
1002
  val = get_lwp_fd (ph, lwpid, &lwp_fd);
1003
  if (val != PS_OK)
1004
    return val;
1005
 
1006
  if (ioctl (lwp_fd, PIOCGXREG, xregset))
1007
    {
1008
      print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno);
1009
      return PS_ERR;
1010
    }
1011
#endif
1012
 
1013
  return PS_OK;
1014
}
1015
 
1016
/* Set extra register set.  Currently a noop.  */
1017
 
1018
ps_err_e
1019
ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
1020
{
1021
#if 0
1022
  int lwp_fd;
1023
  ps_err_e val;
1024
 
1025
  val = get_lwp_fd (ph, lwpid, &lwp_fd);
1026
  if (val != PS_OK)
1027
    return val;
1028
 
1029
  if (ioctl (lwp_fd, PIOCSXREG, xregset))
1030
    {
1031
      print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno);
1032
      return PS_ERR;
1033
    }
1034
#endif
1035
 
1036
  return PS_OK;
1037
}
1038
 
1039
/* Get floating-point registers for LWP.  */
1040
 
1041
ps_err_e
1042
ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1043
               prfpregset_t *fpregset)
1044
{
1045
  struct cleanup *old_chain;
1046
  struct regcache *regcache;
1047
 
1048
  old_chain = save_inferior_ptid ();
1049
 
1050
  inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1051
  regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch);
1052
 
1053
  target_fetch_registers (regcache, -1);
1054
  fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
1055
 
1056
  do_cleanups (old_chain);
1057
 
1058
  return PS_OK;
1059
}
1060
 
1061
/* Set floating-point regs for LWP */
1062
 
1063
ps_err_e
1064
ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1065
               const prfpregset_t * fpregset)
1066
{
1067
  struct cleanup *old_chain;
1068
  struct regcache *regcache;
1069
 
1070
  old_chain = save_inferior_ptid ();
1071
 
1072
  inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1073
  regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch);
1074
 
1075
  supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
1076
  target_store_registers (regcache, -1);
1077
 
1078
  do_cleanups (old_chain);
1079
 
1080
  return PS_OK;
1081
}
1082
 
1083
#ifdef PR_MODEL_LP64
1084
/* Identify process as 32-bit or 64-bit.  At the moment we're using
1085
   BFD to do this.  There might be a more Solaris-specific
1086
   (e.g. procfs) method, but this ought to work.  */
1087
 
1088
ps_err_e
1089
ps_pdmodel (gdb_ps_prochandle_t ph, int *data_model)
1090
{
1091
  if (exec_bfd == 0)
1092
    *data_model = PR_MODEL_UNKNOWN;
1093
  else if (bfd_get_arch_size (exec_bfd) == 32)
1094
    *data_model = PR_MODEL_ILP32;
1095
  else
1096
    *data_model = PR_MODEL_LP64;
1097
 
1098
  return PS_OK;
1099
}
1100
#endif /* PR_MODEL_LP64 */
1101
 
1102
#if (defined(__i386__) || defined(__x86_64__)) && defined (sun)
1103
 
1104
/* Reads the local descriptor table of a LWP.
1105
 
1106
   This function is necessary on x86-solaris only.  Without it, the loading
1107
   of libthread_db would fail because of ps_lgetLDT being undefined.  */
1108
 
1109
ps_err_e
1110
ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1111
            struct ssd *pldt)
1112
{
1113
  /* NOTE: only used on Solaris, therefore OK to refer to procfs.c.  */
1114
  extern struct ssd *procfs_find_LDT_entry (ptid_t);
1115
  struct ssd *ret;
1116
 
1117
  /* FIXME: can't I get the process ID from the prochandle or
1118
     something?  */
1119
 
1120
  if (PIDGET (inferior_ptid) <= 0 || lwpid <= 0)
1121
    return PS_BADLID;
1122
 
1123
  ret = procfs_find_LDT_entry (BUILD_LWP (lwpid, PIDGET (inferior_ptid)));
1124
  if (ret)
1125
    {
1126
      memcpy (pldt, ret, sizeof (struct ssd));
1127
      return PS_OK;
1128
    }
1129
  else
1130
    /* LDT not found.  */
1131
    return PS_ERR;
1132
}
1133
#endif
1134
 
1135
 
1136
/* Convert PTID to printable form.  */
1137
 
1138
char *
1139
solaris_pid_to_str (struct target_ops *ops, ptid_t ptid)
1140
{
1141
  static char buf[100];
1142
 
1143
  if (is_thread (ptid))
1144
    {
1145
      ptid_t lwp;
1146
 
1147
      lwp = thread_to_lwp (ptid, -2);
1148
 
1149
      if (PIDGET (lwp) == -1)
1150
        sprintf (buf, "Thread %ld (defunct)", GET_THREAD (ptid));
1151
      else if (PIDGET (lwp) != -2)
1152
        sprintf (buf, "Thread %ld (LWP %ld)",
1153
                 GET_THREAD (ptid), GET_LWP (lwp));
1154
      else
1155
        sprintf (buf, "Thread %ld        ", GET_THREAD (ptid));
1156
    }
1157
  else if (GET_LWP (ptid) != 0)
1158
    sprintf (buf, "LWP    %ld        ", GET_LWP (ptid));
1159
  else
1160
    sprintf (buf, "process %d    ", PIDGET (ptid));
1161
 
1162
  return buf;
1163
}
1164
 
1165
 
1166
/* Worker bee for find_new_threads.  Callback function that gets
1167
   called once per user-level thread (i.e. not for LWP's).  */
1168
 
1169
static int
1170
sol_find_new_threads_callback (const td_thrhandle_t *th, void *ignored)
1171
{
1172
  td_err_e retval;
1173
  td_thrinfo_t ti;
1174
  ptid_t ptid;
1175
 
1176
  retval = p_td_thr_get_info (th, &ti);
1177
  if (retval != TD_OK)
1178
    return -1;
1179
 
1180
  ptid = BUILD_THREAD (ti.ti_tid, PIDGET (inferior_ptid));
1181
  if (!in_thread_list (ptid) || is_exited (ptid))
1182
    add_thread (ptid);
1183
 
1184
  return 0;
1185
}
1186
 
1187
static void
1188
sol_find_new_threads (struct target_ops *ops)
1189
{
1190
  struct target_ops *beneath = find_target_beneath (ops);
1191
 
1192
  /* First Find any new LWP's.  */
1193
  if (beneath->to_find_new_threads != NULL)
1194
    beneath->to_find_new_threads (beneath);
1195
 
1196
  /* Then find any new user-level threads.  */
1197
  p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0,
1198
                    TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1199
                    TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1200
}
1201
 
1202
/* Worker bee for the "info sol-thread" command.  This is a callback
1203
   function that gets called once for each Solaris user-level thread
1204
   (i.e. not for LWPs) in the inferior.  Print anything interesting
1205
   that we can think of.  */
1206
 
1207
static int
1208
info_cb (const td_thrhandle_t *th, void *s)
1209
{
1210
  td_err_e ret;
1211
  td_thrinfo_t ti;
1212
 
1213
  ret = p_td_thr_get_info (th, &ti);
1214
  if (ret == TD_OK)
1215
    {
1216
      printf_filtered ("%s thread #%d, lwp %d, ",
1217
                       ti.ti_type == TD_THR_SYSTEM ? "system" : "user  ",
1218
                       ti.ti_tid, ti.ti_lid);
1219
      switch (ti.ti_state)
1220
        {
1221
        default:
1222
        case TD_THR_UNKNOWN:
1223
          printf_filtered ("<unknown state>");
1224
          break;
1225
        case TD_THR_STOPPED:
1226
          printf_filtered ("(stopped)");
1227
          break;
1228
        case TD_THR_RUN:
1229
          printf_filtered ("(run)    ");
1230
          break;
1231
        case TD_THR_ACTIVE:
1232
          printf_filtered ("(active) ");
1233
          break;
1234
        case TD_THR_ZOMBIE:
1235
          printf_filtered ("(zombie) ");
1236
          break;
1237
        case TD_THR_SLEEP:
1238
          printf_filtered ("(asleep) ");
1239
          break;
1240
        case TD_THR_STOPPED_ASLEEP:
1241
          printf_filtered ("(stopped asleep)");
1242
          break;
1243
        }
1244
      /* Print thr_create start function.  */
1245
      if (ti.ti_startfunc != 0)
1246
        {
1247
          struct minimal_symbol *msym;
1248
          msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
1249
          if (msym)
1250
            printf_filtered ("   startfunc: %s\n",
1251
                             SYMBOL_PRINT_NAME (msym));
1252
          else
1253
            printf_filtered ("   startfunc: %s\n",
1254
                             paddress (target_gdbarch, ti.ti_startfunc));
1255
        }
1256
 
1257
      /* If thread is asleep, print function that went to sleep.  */
1258
      if (ti.ti_state == TD_THR_SLEEP)
1259
        {
1260
          struct minimal_symbol *msym;
1261
          msym = lookup_minimal_symbol_by_pc (ti.ti_pc);
1262
          if (msym)
1263
            printf_filtered (" - Sleep func: %s\n",
1264
                             SYMBOL_PRINT_NAME (msym));
1265
          else
1266
            printf_filtered (" - Sleep func: %s\n",
1267
                             paddress (target_gdbarch, ti.ti_startfunc));
1268
        }
1269
 
1270
      /* Wrap up line, if necessary.  */
1271
      if (ti.ti_state != TD_THR_SLEEP && ti.ti_startfunc == 0)
1272
        printf_filtered ("\n"); /* don't you hate counting newlines? */
1273
    }
1274
  else
1275
    warning (_("info sol-thread: failed to get info for thread."));
1276
 
1277
  return 0;
1278
}
1279
 
1280
/* List some state about each Solaris user-level thread in the
1281
   inferior.  */
1282
 
1283
static void
1284
info_solthreads (char *args, int from_tty)
1285
{
1286
  p_td_ta_thr_iter (main_ta, info_cb, args,
1287
                    TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1288
                    TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1289
}
1290
 
1291
static void
1292
init_sol_thread_ops (void)
1293
{
1294
  sol_thread_ops.to_shortname = "solaris-threads";
1295
  sol_thread_ops.to_longname = "Solaris threads and pthread.";
1296
  sol_thread_ops.to_doc = "Solaris threads and pthread support.";
1297
  sol_thread_ops.to_detach = sol_thread_detach;
1298
  sol_thread_ops.to_resume = sol_thread_resume;
1299
  sol_thread_ops.to_wait = sol_thread_wait;
1300
  sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
1301
  sol_thread_ops.to_store_registers = sol_thread_store_registers;
1302
  sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
1303
  sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
1304
  sol_thread_ops.to_thread_alive = sol_thread_alive;
1305
  sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
1306
  sol_thread_ops.to_find_new_threads = sol_find_new_threads;
1307
  sol_thread_ops.to_stratum = thread_stratum;
1308
  sol_thread_ops.to_magic = OPS_MAGIC;
1309
}
1310
 
1311
void
1312
_initialize_sol_thread (void)
1313
{
1314
  void *dlhandle;
1315
 
1316
  init_sol_thread_ops ();
1317
 
1318
  dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
1319
  if (!dlhandle)
1320
    goto die;
1321
 
1322
#define resolve(X) \
1323
  if (!(p_##X = dlsym (dlhandle, #X))) \
1324
    goto die;
1325
 
1326
  resolve (td_log);
1327
  resolve (td_ta_new);
1328
  resolve (td_ta_delete);
1329
  resolve (td_init);
1330
  resolve (td_ta_get_ph);
1331
  resolve (td_ta_get_nthreads);
1332
  resolve (td_ta_tsd_iter);
1333
  resolve (td_ta_thr_iter);
1334
  resolve (td_thr_validate);
1335
  resolve (td_thr_tsd);
1336
  resolve (td_thr_get_info);
1337
  resolve (td_thr_getfpregs);
1338
  resolve (td_thr_getxregsize);
1339
  resolve (td_thr_getxregs);
1340
  resolve (td_thr_sigsetmask);
1341
  resolve (td_thr_setprio);
1342
  resolve (td_thr_setsigpending);
1343
  resolve (td_thr_setfpregs);
1344
  resolve (td_thr_setxregs);
1345
  resolve (td_ta_map_id2thr);
1346
  resolve (td_ta_map_lwp2thr);
1347
  resolve (td_thr_getgregs);
1348
  resolve (td_thr_setgregs);
1349
 
1350
  add_target (&sol_thread_ops);
1351
 
1352
  add_cmd ("sol-threads", class_maintenance, info_solthreads,
1353
           _("Show info on Solaris user threads."), &maintenanceinfolist);
1354
 
1355
  /* Hook into new_objfile notification.  */
1356
  observer_attach_new_objfile (sol_thread_new_objfile);
1357
  return;
1358
 
1359
 die:
1360
  fprintf_unfiltered (gdb_stderr, "\
1361
[GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
1362
 
1363
  if (dlhandle)
1364
    dlclose (dlhandle);
1365
 
1366
  return;
1367
}

powered by: WebSVN 2.1.0

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