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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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