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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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