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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [gdb/] [sol-thread.c] - Blame information for rev 297

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

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

powered by: WebSVN 2.1.0

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