99ff5837534ff34ef1d7a6573aa3b20330d65e62
[dragonfly.git] / gnu / usr.bin / gdb / gdb / freebsd-uthread.c
1 /* Low level interface for debugging FreeBSD user threads for GDB, the GNU debugger.
2    Copyright 1996, 1999 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20 /* $FreeBSD: ports/devel/gdb6/files/freebsd-uthread.c,v 1.2 2004/06/20 18:45:36 obrien Exp $ */
21 /* $DragonFly: src/gnu/usr.bin/gdb/gdb/Attic/freebsd-uthread.c,v 1.2 2004/10/24 18:05:10 joerg Exp $ */
22
23 /* This module implements a sort of half target that sits between the
24    machine-independent parts of GDB and the ptrace interface (infptrace.c) to
25    provide access to the FreeBSD user-mode thread implementation.
26
27    FreeBSD threads are true user-mode threads, which are invoked via
28    the pthread_* interfaces.  These are mostly implemented in
29    user-space, with all thread context kept in various structures that
30    live in the user's heap.  For the most part, the kernel has no
31    knowlege of these threads.
32
33    Based largely on hpux-thread.c
34
35    */
36
37
38 #include "defs.h"
39 #include <sys/queue.h>
40 #include <signal.h>
41 #include <setjmp.h>
42 #include <string.h>
43 #include "gdbthread.h"
44 #include "target.h"
45 #include "inferior.h"
46 #include <fcntl.h>
47 #include <ucontext.h>
48 #include <unistd.h>
49 #include <sys/stat.h>
50 #include "gdbcore.h"
51 #include "regcache.h"
52
53 extern int child_suppress_run;
54 extern struct target_ops child_ops; /* target vector for inftarg.c */
55
56 extern void _initialize_freebsd_uthread PARAMS ((void));
57
58 /* Set to true while we are part-way through attaching */
59 static int freebsd_uthread_attaching;
60
61 static int freebsd_uthread_active = 0;
62 static CORE_ADDR P_thread_list;
63 static CORE_ADDR P_thread_run;
64
65 /* Pointer to the next function on the objfile event chain.  */
66 static void (*target_new_objfile_chain) (struct objfile *objfile);
67
68 static void freebsd_uthread_resume PARAMS ((ptid_t pid, int step,
69                                         enum target_signal signo));
70
71 static void init_freebsd_uthread_ops PARAMS ((void));
72
73 static struct target_ops freebsd_uthread_ops;
74 \f
75 static ptid_t find_active_ptid PARAMS ((void));
76
77 struct cached_pthread {
78   u_int64_t             uniqueid;
79   int                   state;
80   CORE_ADDR             name;
81   union {
82     ucontext_t  uc;
83     jmp_buf     jb;
84   }                     ctx;
85 };
86
87 static ptid_t cached_ptid;
88 static struct cached_pthread cached_pthread;
89 static CORE_ADDR cached_pthread_addr;
90
91 LIST_HEAD(idmaplist, idmap);
92
93 struct idmap {
94     LIST_ENTRY(idmap)   link;
95     u_int64_t           uniqueid;
96     int                 tid;
97 };
98
99 #define MAPHASH_SIZE    257
100 #define TID_MIN         1
101 #define TID_MAX         16383
102
103 static int tid_to_hash[TID_MAX + 1];            /* set to map_hash index */
104 static struct idmaplist map_hash[MAPHASH_SIZE];
105 static int next_free_tid = TID_MIN;             /* first available tid */
106 static int last_free_tid = TID_MIN;             /* first unavailable */
107
108 static CORE_ADDR P_thread_next_offset;
109 static CORE_ADDR P_thread_uniqueid_offset;
110 static CORE_ADDR P_thread_state_offset;
111 static CORE_ADDR P_thread_name_offset;
112 static CORE_ADDR P_thread_ctx_offset;
113 static CORE_ADDR P_thread_PS_RUNNING_value;
114 static CORE_ADDR P_thread_PS_DEAD_value;
115
116 static int next_offset;
117 static int uniqueid_offset;
118 static int state_offset;
119 static int name_offset;
120 static int ctx_offset;
121 static int PS_RUNNING_value;
122 static int PS_DEAD_value;
123
124 #define UNIQUEID_HASH(id)       (id % MAPHASH_SIZE)
125 #define TID_ADD1(tid)           (((tid) + 1) == TID_MAX + 1 \
126                                  ? TID_MIN : (tid) + 1)
127 #define IS_TID_FREE(tid)        (tid_to_hash[tid] == -1)
128
129 static int
130 get_new_tid(int h)
131 {
132   int tid = next_free_tid;
133
134   tid_to_hash[tid] = h;
135   next_free_tid = TID_ADD1(next_free_tid);
136   if (next_free_tid == last_free_tid)
137     {
138       int i;
139
140       for (i = last_free_tid; TID_ADD1(i) != last_free_tid; i = TID_ADD1(i))
141         if (IS_TID_FREE(i))
142           break;
143       if (TID_ADD1(i) == last_free_tid)
144         {
145           error("too many threads");
146           return 0;
147         }
148       next_free_tid = i;
149       for (i = TID_ADD1(i); IS_TID_FREE(i); i = TID_ADD1(i))
150         ;
151       last_free_tid = i;
152     }
153
154   return tid;
155 }
156
157 static ptid_t
158 find_ptid(u_int64_t uniqueid)
159 {
160   int h = UNIQUEID_HASH(uniqueid);
161   struct idmap *im;
162
163   LIST_FOREACH(im, &map_hash[h], link)
164     if (im->uniqueid == uniqueid)
165       return MERGEPID(PIDGET(inferior_ptid), im->tid);
166
167   im = xmalloc(sizeof(struct idmap));
168   im->uniqueid = uniqueid;
169   im->tid = get_new_tid(h);
170   LIST_INSERT_HEAD(&map_hash[h], im, link);
171
172   return MERGEPID(PIDGET(inferior_ptid), im->tid);
173 }
174
175 static void
176 free_ptid(ptid_t ptid)
177 {
178   int tid = TIDGET(ptid);
179   int h = tid_to_hash[tid];
180   struct idmap *im;
181
182   if (!tid) return;
183
184   LIST_FOREACH(im, &map_hash[h], link)
185     if (im->tid == tid)
186       break;
187
188   if (!im) return;
189
190   LIST_REMOVE(im, link);
191   tid_to_hash[tid] = -1;
192   free(im);
193 }
194
195 #define READ_OFFSET(field) read_memory(P_thread_##field##_offset,       \
196                                        (char *) &field##_offset,        \
197                                        sizeof(field##_offset))
198
199 #define READ_VALUE(name) read_memory(P_thread_##name##_value,   \
200                                      (char *) &name##_value,    \
201                                      sizeof(name##_value))
202
203 static void
204 read_thread_offsets (void)
205 {
206   READ_OFFSET(next);
207   READ_OFFSET(uniqueid);
208   READ_OFFSET(state);
209   READ_OFFSET(name);
210   READ_OFFSET(ctx);
211
212   READ_VALUE(PS_RUNNING);
213   READ_VALUE(PS_DEAD);
214 }
215
216 #define READ_FIELD(ptr, T, field, result) \
217   read_memory ((ptr) + field##_offset, (char *) &(result), sizeof result)
218
219 static u_int64_t
220 read_pthread_uniqueid (CORE_ADDR ptr)
221 {
222   u_int64_t uniqueid;
223   READ_FIELD(ptr, u_int64_t, uniqueid, uniqueid);
224   return uniqueid;
225 }
226
227 static CORE_ADDR
228 read_pthread_next (CORE_ADDR ptr)
229 {
230   CORE_ADDR next;
231   READ_FIELD(ptr, CORE_ADDR, next, next);
232   return next;
233 }
234
235 static void
236 read_cached_pthread (CORE_ADDR ptr, struct cached_pthread *cache)
237 {
238   READ_FIELD(ptr, u_int64_t,    uniqueid,       cache->uniqueid);
239   READ_FIELD(ptr, int,          state,          cache->state);
240   READ_FIELD(ptr, CORE_ADDR,    name,           cache->name);
241   READ_FIELD(ptr, ucontext_t,   ctx,            cache->ctx);
242 }
243
244 static ptid_t
245 find_active_ptid (void)
246 {
247   CORE_ADDR ptr;
248
249   read_memory ((CORE_ADDR)P_thread_run,
250                (char *)&ptr,
251                sizeof ptr);
252
253   return find_ptid(read_pthread_uniqueid(ptr));
254 }
255
256 static CORE_ADDR find_pthread_addr PARAMS ((ptid_t ptid));
257 static struct cached_pthread * find_pthread PARAMS ((ptid_t ptid));
258
259 static CORE_ADDR
260 find_pthread_addr (ptid_t ptid)
261 {
262   CORE_ADDR ptr;
263
264   if (ptid_equal(ptid, cached_ptid))
265     return cached_pthread_addr;
266
267   read_memory ((CORE_ADDR)P_thread_list,
268                (char *)&ptr,
269                sizeof ptr);
270
271   while (ptr != 0)
272     {
273       if (ptid_equal(find_ptid(read_pthread_uniqueid(ptr)), ptid))
274         {
275           cached_ptid = ptid;
276           cached_pthread_addr = ptr;
277           read_cached_pthread(ptr, &cached_pthread);
278           return ptr;
279         }
280       ptr = read_pthread_next(ptr);
281     }
282
283   return NULL;
284 }
285
286 static struct cached_pthread *
287 find_pthread (ptid_t ptid)
288 {
289   CORE_ADDR ptr;
290
291   if (ptid_equal(ptid, cached_ptid))
292     return &cached_pthread;
293
294   read_memory ((CORE_ADDR)P_thread_list,
295                (char *)&ptr,
296                sizeof ptr);
297
298   while (ptr != 0)
299     {
300       if (ptid_equal(find_ptid(read_pthread_uniqueid(ptr)), ptid))
301         {
302           cached_ptid = ptid;
303           cached_pthread_addr = ptr;
304           read_cached_pthread(ptr, &cached_pthread);
305           return &cached_pthread;
306         }
307       ptr = read_pthread_next(ptr);
308     }
309
310 #if 0
311   error ("Can't find pthread %d,%d", PIDGET(ptid), TIDGET(ptid));
312 #endif
313   return NULL;
314 }
315
316 \f
317 /* Most target vector functions from here on actually just pass through to
318    inftarg.c, as they don't need to do anything specific for threads.  */
319
320 /* ARGSUSED */
321 static void
322 freebsd_uthread_open (char *arg, int from_tty)
323 {
324   child_ops.to_open (arg, from_tty);
325 }
326
327 /* Attach to process PID, then initialize for debugging it
328    and wait for the trace-trap that results from attaching.  */
329
330 static void
331 freebsd_uthread_attach (char *args, int from_tty)
332 {
333   child_ops.to_attach (args, from_tty);
334   push_target (&freebsd_uthread_ops);
335   freebsd_uthread_attaching = 1;
336 }
337
338 /* After an attach, see if the target is threaded */
339
340 static void
341 freebsd_uthread_post_attach (int pid)
342 {
343   if (freebsd_uthread_active)
344     {
345       read_thread_offsets ();
346       inferior_ptid = find_active_ptid ();
347       add_thread (inferior_ptid);
348     }
349   else
350     {
351       unpush_target (&freebsd_uthread_ops);
352       push_target (&child_ops);
353     }
354
355   freebsd_uthread_attaching = 0;
356 }
357
358 /* Take a program previously attached to and detaches it.
359    The program resumes execution and will no longer stop
360    on signals, etc.  We'd better not have left any breakpoints
361    in the program or it'll die when it hits one.  For this
362    to work, it may be necessary for the process to have been
363    previously attached.  It *might* work if the program was
364    started via the normal ptrace (PTRACE_TRACEME).  */
365
366 static void
367 freebsd_uthread_detach (char *args, int from_tty)
368 {
369   child_ops.to_detach (args, from_tty);
370 }
371
372 /* Resume execution of process PID.  If STEP is nozero, then
373    just single step it.  If SIGNAL is nonzero, restart it with that
374    signal activated.  We may have to convert pid from a thread-id to an LWP id
375    for procfs.  */
376
377 static void
378 freebsd_uthread_resume (ptid_t ptid, int step, enum target_signal signo)
379 {
380   if (freebsd_uthread_attaching)
381     {
382       child_ops.to_resume (ptid, step, signo);
383       return;
384     }
385
386   child_ops.to_resume (ptid, step, signo);
387   cached_ptid = MERGEPID(0, 0);
388 }
389
390 /* Wait for any threads to stop.  We may have to convert PID from a thread id
391    to a LWP id, and vice versa on the way out.  */
392
393 static ptid_t
394 freebsd_uthread_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
395 {
396   ptid_t rtnval;
397
398   if (freebsd_uthread_attaching)
399     {
400       return child_ops.to_wait (ptid, ourstatus);
401     }
402
403   rtnval = child_ops.to_wait (ptid, ourstatus);
404
405   if (PIDGET(rtnval) >= 0)
406     {
407       rtnval = find_active_ptid ();
408       if (!in_thread_list (rtnval))
409         add_thread (rtnval);
410     }
411
412   return rtnval;
413 }
414
415 /* XXX: this needs to be selected by target, not [build] host */
416 #ifdef __i386__
417
418 #include "i386-tdep.h"
419
420 static char sigmap[I386_SSE_NUM_REGS] = /* map reg to sigcontext  */
421 {
422   12,                           /* eax */
423   11,                           /* ecx */
424   10,                           /* edx */
425   9,                            /* ebx */
426   8,                            /* esp */
427   7,                            /* ebp */
428   6,                            /* esi */
429   5,                            /* edi */
430   15,                           /* eip */
431   17,                           /* eflags */
432   16,                           /* cs */
433   19,                           /* ss */
434   4,                            /* ds */
435   3,                            /* es */
436   2,                            /* fs */
437   1,                            /* gs */
438   -1, -1, -1, -1, -1, -1, -1,   /* st0-st7 */
439   -1, -1, -1, -1, -1, -1, -1,   /* fctrl-fop */
440   -1, -1, -1, -1, -1, -1, -1,   /* xmm0-xmm7 */
441   -1,                           /* mxcsr */
442 };
443
444 static char jmpmap[I386_SSE_NUM_REGS] = /* map reg to jmp_buf */
445 {
446   6,                            /* eax */
447   -1,                           /* ecx */
448   -1,                           /* edx */
449   1,                            /* ebx */
450   2,                            /* esp */
451   3,                            /* ebp */
452   4,                            /* esi */
453   5,                            /* edi */
454   0,                            /* eip */
455   -1,                           /* eflags */
456   -1,                           /* cs */
457   -1,                           /* ss */
458   -1,                           /* ds */
459   -1,                           /* es */
460   -1,                           /* fs */
461   -1,                           /* gs */
462   -1, -1, -1, -1, -1, -1, -1,   /* st0-st7 */
463   -1, -1, -1, -1, -1, -1, -1,   /* fctrl-fop */
464   -1, -1, -1, -1, -1, -1, -1,   /* xmm0-xmm7 */
465   -1,                           /* mxcsr */
466 };
467
468 #endif
469
470 #ifdef __amd64__
471
472 #include "amd64-tdep.h"
473
474 // XXX:DEO      not fully ported from i386 yet!!
475
476 static char sigmap[AMD64_NUM_REGS_TOTAL] = /* map reg to sigcontext  */
477 {
478   12,                           /* rax */
479   11,                           /* rcx */
480   10,                           /* rdx */
481   9,                            /* rbx */
482   8,                            /* rsp */
483   7,                            /* rbp */
484   6,                            /* rsi */
485   5,                            /* rdi */
486   15,                           /* rip */
487   17,                           /* rflags */
488   16,                           /* cs */
489   19,                           /* ss */
490   4,                            /* ds */
491   3,                            /* es */
492   2,                            /* fs */
493   1,                            /* gs */
494   -1, -1, -1, -1, -1, -1, -1,   /* st0-st7 */
495   -1, -1, -1, -1, -1, -1, -1,   /* fctrl-fop */
496   -1, -1, -1, -1, -1, -1, -1,   /* xmm0-xmm7 */
497   -1,                           /* mxcsr */
498 };
499
500 static char jmpmap[AMD64_NUM_REGS_TOTAL] = /* map reg to jmp_buf */
501 {
502   6,                            /* rax */
503   -1,                           /* rcx */
504   -1,                           /* rdx */
505   1,                            /* rbx */
506   2,                            /* rsp */
507   3,                            /* rbp */
508   4,                            /* rsi */
509   5,                            /* rdi */
510   0,                            /* rip */
511   -1,                           /* rflags */
512   -1,                           /* cs */
513   -1,                           /* ss */
514   -1,                           /* ds */
515   -1,                           /* es */
516   -1,                           /* fs */
517   -1,                           /* gs */
518   -1, -1, -1, -1, -1, -1, -1,   /* st0-st7 */
519   -1, -1, -1, -1, -1, -1, -1,   /* fctrl-fop */
520   -1, -1, -1, -1, -1, -1, -1,   /* xmm0-xmm7 */
521   -1,                           /* mxcsr */
522 };
523
524 #endif
525
526 #ifdef __alpha__
527
528 #include "alpha-tdep.h"
529
530 static char sigmap[ALPHA_NUM_REGS] =    /* map reg to sigcontext  */
531 {
532   1,  2,  3,  4,  5,  6,  7,  8,  /* v0 - t6 */
533   9,  10, 11, 12, 13, 14, 15, 16, /* t7 - fp */
534   17, 18, 19, 20, 21, 22, 23, 24, /* a0 - t9 */
535   25, 26, 27, 28, 29, 30, 31, 32, /* t10 - zero */
536   38, 39, 40, 41, 42, 43, 44, 45, /* f0 - f7 */
537   46, 47, 48, 49, 50, 51, 52, 53, /* f8 - f15 */
538   54, 55, 56, 57, 58, 59, 60, 61, /* f16 - f23 */
539   62, 63, 64, 65, 66, 67, 68, 69, /* f24 - f31 */
540   33, -1                          /* pc, vfp */
541 };
542 static char jmpmap[ALPHA_NUM_REGS] = {
543   4,  5,  6,  7,  8,  9,  10, 11, /* v0 - t6 */
544   12, 13, 14, 15, 16, 17, 18, 19, /* t7 - fp */
545   20, 21, 22, 23, 24, 25, 26, 27, /* a0 - t9 */
546   28, 29, 30, 31, 32, 33, 34, 35, /* t10 - zero */
547   37, 38, 39, 40, 41, 42, 43, 44, /* f0 - f7 */
548   45, 46, 47, 48, 49, 50, 51, 52, /* f8 - f15 */
549   53, 54, 55, 56, 57, 58, 59, 60, /* f16 - f23 */
550   61, 62, 63, 64, 65, 66, 67, 68, /* f24 - f31 */
551   2,  -1,                         /* pc, vfp */
552 };
553
554 #endif
555
556 #ifdef __sparc64__
557
558 static char sigmap[125] =       /* map reg to sigcontext  */
559 {
560   -1
561 };
562 static char jmpmap[125] = {
563   -1
564 };
565
566 #endif
567
568 static void
569 freebsd_uthread_fetch_registers (int regno)
570 {
571   struct cached_pthread *thread;
572   int active;
573   int first_regno, last_regno;
574   register_t *regbase;
575   char *regmap;
576
577   if (freebsd_uthread_attaching || TIDGET(inferior_ptid) == 0)
578     {
579       child_ops.to_fetch_registers (regno);
580       return;
581     }
582
583   thread = find_pthread (inferior_ptid);
584   active = (ptid_equal(inferior_ptid, find_active_ptid()));
585
586   if (active)
587     {
588       child_ops.to_fetch_registers (regno);
589       return;
590     }
591
592   if (regno == -1)
593     {
594       first_regno = 0;
595       last_regno = NUM_REGS - 1;
596     }
597   else
598     {
599       first_regno = regno;
600       last_regno = regno;
601     }
602
603   regbase = (register_t*) &thread->ctx.jb[0];
604   regmap = jmpmap;
605
606   for (regno = first_regno; regno <= last_regno; regno++)
607     {
608       if (regmap[regno] == -1)
609         child_ops.to_fetch_registers (regno);
610       else
611         if (thread)
612           supply_register (regno, (char*) &regbase[regmap[regno]]);
613         else
614           supply_register (regno, NULL);
615     }
616 }
617
618 static void
619 freebsd_uthread_store_registers (int regno)
620 {
621   struct cached_pthread *thread;
622   CORE_ADDR ptr;
623   int first_regno, last_regno;
624   u_int32_t *regbase;
625   char *regmap;
626
627   if (freebsd_uthread_attaching)
628     {
629       child_ops.to_store_registers (regno);
630       return;
631     }
632
633   thread = find_pthread (inferior_ptid);
634
635   if (thread->state == PS_RUNNING_value)
636     {
637       child_ops.to_store_registers (regno);
638       return;
639     }
640
641   if (regno == -1)
642     {
643       first_regno = 0;
644       last_regno = NUM_REGS - 1;
645     }
646   else
647     {
648       first_regno = regno;
649       last_regno = regno;
650     }
651
652   regbase = (u_int32_t*) &thread->ctx.jb[0];
653   regmap = jmpmap;
654
655   ptr = find_pthread_addr (inferior_ptid);
656   for (regno = first_regno; regno <= last_regno; regno++)
657     {
658       if (regmap[regno] == -1)
659         child_ops.to_store_registers (regno);
660       else
661         {
662           u_int32_t *reg = &regbase[regmap[regno]];
663           int off;
664
665           /* Hang onto cached value */
666 /*DEO:XXX*/
667           memcpy(reg, deprecated_registers /*regcache_collect ()*/+ DEPRECATED_REGISTER_BYTE (regno),
668                  DEPRECATED_REGISTER_RAW_SIZE (regno));
669
670           /* And push out to inferior */
671           off = (char *) reg - (char *) thread;
672           write_memory (ptr + off, 
673 /*DEO:XXX*/
674                         deprecated_registers /*regcache_collect ()*/+ DEPRECATED_REGISTER_BYTE (regno),
675                         DEPRECATED_REGISTER_RAW_SIZE (regno));
676         }
677     }
678 }
679
680 /* Get ready to modify the registers array.  On machines which store
681    individual registers, this doesn't need to do anything.  On machines
682    which store all the registers in one fell swoop, this makes sure
683    that registers contains all the registers from the program being
684    debugged.  */
685
686 static void
687 freebsd_uthread_prepare_to_store (void)
688 {
689   child_ops.to_prepare_to_store ();
690 }
691
692 static int
693 freebsd_uthread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
694                              int dowrite, struct mem_attrib *attrib,
695                              struct target_ops *target)
696 {
697   return child_ops.to_xfer_memory (memaddr, myaddr, len, dowrite,
698                                    attrib, target);
699 }
700
701 /* Print status information about what we're accessing.  */
702
703 static void
704 freebsd_uthread_files_info (struct target_ops *ignore)
705 {
706   child_ops.to_files_info (ignore);
707 }
708
709 static void
710 freebsd_uthread_kill_inferior (void)
711 {
712   child_ops.to_kill ();
713 }
714
715 static void
716 freebsd_uthread_notice_signals (ptid_t ptid)
717 {
718   child_ops.to_notice_signals (ptid);
719 }
720
721 /* Fork an inferior process, and start debugging it with /proc.  */
722
723 static void
724 freebsd_uthread_create_inferior (char *exec_file, char *allargs, char **env,
725                                  int from_tty)
726 {
727   child_ops.to_create_inferior (exec_file, allargs, env, from_tty);
728
729   if (PIDGET(inferior_ptid) && freebsd_uthread_active)
730     {
731       read_thread_offsets ();
732       push_target (&freebsd_uthread_ops);
733       inferior_ptid = find_active_ptid ();
734       add_thread (inferior_ptid);
735     }
736 }
737
738 /* This routine is called to find out if the inferior is using threads.
739    We check for the _thread_run and _thread_list globals. */
740
741 void
742 freebsd_uthread_new_objfile (struct objfile *objfile)
743 {
744   struct minimal_symbol *ms;
745
746   if (!objfile)
747     {
748       freebsd_uthread_active = 0;
749       return;
750     }
751
752   ms = lookup_minimal_symbol ("_thread_run", NULL, objfile);
753
754   if (!ms)
755     return;
756
757   P_thread_run = SYMBOL_VALUE_ADDRESS (ms);
758
759   ms = lookup_minimal_symbol ("_thread_list", NULL, objfile);
760
761   if (!ms)
762     return;
763
764   P_thread_list = SYMBOL_VALUE_ADDRESS (ms);
765
766 #define OFFSET_SYM(field)       "_thread_" #field "_offset"
767 #define LOOKUP_OFFSET(field)                                            \
768   do {                                                                  \
769       ms = lookup_minimal_symbol (OFFSET_SYM(field), NULL, objfile);    \
770       if (!ms)                                                          \
771         return;                                                         \
772       P_thread_##field##_offset = SYMBOL_VALUE_ADDRESS (ms);            \
773   } while (0);
774
775 #define VALUE_SYM(name)         "_thread_" #name "_value"
776 #define LOOKUP_VALUE(name)                                              \
777   do {                                                                  \
778        ms = lookup_minimal_symbol (VALUE_SYM(name), NULL, objfile);     \
779       if (!ms)                                                          \
780         return;                                                         \
781       P_thread_##name##_value = SYMBOL_VALUE_ADDRESS (ms);              \
782   } while (0);
783
784   LOOKUP_OFFSET(next);
785   LOOKUP_OFFSET(uniqueid);
786   LOOKUP_OFFSET(state);
787   LOOKUP_OFFSET(name);
788   LOOKUP_OFFSET(ctx);
789
790   LOOKUP_VALUE(PS_RUNNING);
791   LOOKUP_VALUE(PS_DEAD);
792
793   freebsd_uthread_active = 1;
794 }
795
796 /* Clean up after the inferior dies.  */
797
798 static void
799 freebsd_uthread_mourn_inferior ()
800 {
801   child_ops.to_mourn_inferior ();
802   unpush_target (&freebsd_uthread_ops);
803 }
804
805 /* Mark our target-struct as eligible for stray "run" and "attach" commands.  */
806
807 static int
808 freebsd_uthread_can_run ()
809 {
810   return child_suppress_run;
811 }
812
813 static int
814 freebsd_uthread_thread_alive (ptid_t ptid)
815 {
816   struct cached_pthread *thread;
817   int ret = 0;
818
819   if (freebsd_uthread_attaching)
820     return 1;
821
822   /*
823    * We can get called from child_ops.to_wait() which passes the underlying
824    * pid (without a thread number).
825    */
826   if (TIDGET(ptid) == 0)
827     return 1;
828
829   if (find_pthread_addr (ptid) != 0)
830     {
831       thread = find_pthread (ptid);
832       ret = (thread->state != PS_DEAD_value);
833     }
834
835   if (!ret)
836     free_ptid(ptid);
837
838   return ret;
839 }
840
841 static void
842 freebsd_uthread_stop (void)
843 {
844   child_ops.to_stop ();
845 }
846
847 static void
848 freebsd_uthread_find_new_threads (void)
849 {
850   CORE_ADDR ptr;
851   int state;
852   u_int64_t uniqueid;
853
854   read_memory ((CORE_ADDR)P_thread_list,
855                (char *)&ptr,
856                sizeof ptr);
857
858   while (ptr != 0)
859     {
860       READ_FIELD(ptr, int, state, state);
861       READ_FIELD(ptr, u_int64_t, uniqueid, uniqueid);
862       if (state != PS_DEAD_value &&
863           !in_thread_list (find_ptid(uniqueid)))
864         add_thread (find_ptid(uniqueid));
865       ptr = read_pthread_next(ptr);
866     }
867 }
868
869 /* MUST MATCH enum pthread_state */
870 static const char *statenames[] = {
871   "RUNNING",
872   "SIGTHREAD",
873   "MUTEX_WAIT",
874   "COND_WAIT",
875   "FDLR_WAIT",
876   "FDLW_WAIT",
877   "FDR_WAIT",
878   "FDW_WAIT",
879   "POLL_WAIT",
880   "FILE_WAIT",
881   "SELECT_WAIT",
882   "SLEEP_WAIT",
883   "WAIT_WAIT",
884   "SIGSUSPEND",
885   "SIGWAIT",
886   "SPINBLOCK",
887   "JOIN",
888   "SUSPENDED",
889   "DEAD",
890   "DEADLOCK",
891 };
892
893 #if 0
894
895 static int
896 freebsd_uthread_get_thread_info (ref, selection, info)
897      gdb_threadref *ref;
898      int selection;
899      struct gdb_ext_thread_info *info;
900 {
901   int pid = *ref;
902   struct cached_pthread *thread = find_pthread (pid);
903   struct cleanup *old_chain;
904
905   old_chain = save_inferior_pid ();
906   inferior_pid = main_pid;
907
908   memset(&info->threadid, 0, OPAQUETHREADBYTES);
909
910   memcpy(&info->threadid, ref, sizeof *ref);
911   info->active = thread->state == PS_RUNNING_value;
912   strcpy(info->display, statenames[thread->state]);
913   if (thread->name)
914     read_memory ((CORE_ADDR) thread->name, info->shortname, 32);
915   else
916     strcpy(info->shortname, "");
917
918   do_cleanups (old_chain);
919   return (0);
920 }
921
922 #endif
923
924 char *
925 freebsd_uthread_pid_to_str (ptid_t ptid)
926 {
927   static char buf[30];
928
929   if (DEPRECATED_STREQ (current_target.to_shortname, "freebsd-uthreads"))
930     sprintf (buf, "Process %d, Thread %ld",
931              PIDGET(ptid), TIDGET(ptid));
932   else
933     sprintf (buf, "Process %d", PIDGET(ptid));
934
935   return buf;
936 }
937
938 \f
939 static void
940 init_freebsd_uthread_ops ()
941 {
942   freebsd_uthread_ops.to_shortname = "freebsd-uthreads";
943   freebsd_uthread_ops.to_longname = "FreeBSD uthreads";
944   freebsd_uthread_ops.to_doc = "FreeBSD user threads support.";
945   freebsd_uthread_ops.to_open = freebsd_uthread_open;
946   freebsd_uthread_ops.to_attach = freebsd_uthread_attach;
947   freebsd_uthread_ops.to_post_attach = freebsd_uthread_post_attach;
948   freebsd_uthread_ops.to_detach = freebsd_uthread_detach;
949   freebsd_uthread_ops.to_resume = freebsd_uthread_resume;
950   freebsd_uthread_ops.to_wait = freebsd_uthread_wait;
951   freebsd_uthread_ops.to_fetch_registers = freebsd_uthread_fetch_registers;
952   freebsd_uthread_ops.to_store_registers = freebsd_uthread_store_registers;
953   freebsd_uthread_ops.to_prepare_to_store = freebsd_uthread_prepare_to_store;
954   freebsd_uthread_ops.to_xfer_memory = freebsd_uthread_xfer_memory;
955   freebsd_uthread_ops.to_files_info = freebsd_uthread_files_info;
956   freebsd_uthread_ops.to_insert_breakpoint = memory_insert_breakpoint;
957   freebsd_uthread_ops.to_remove_breakpoint = memory_remove_breakpoint;
958   freebsd_uthread_ops.to_terminal_init = terminal_init_inferior;
959   freebsd_uthread_ops.to_terminal_inferior = terminal_inferior;
960   freebsd_uthread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
961   freebsd_uthread_ops.to_terminal_ours = terminal_ours;
962   freebsd_uthread_ops.to_terminal_info = child_terminal_info;
963   freebsd_uthread_ops.to_kill = freebsd_uthread_kill_inferior;
964   freebsd_uthread_ops.to_create_inferior = freebsd_uthread_create_inferior;
965   freebsd_uthread_ops.to_mourn_inferior = freebsd_uthread_mourn_inferior;
966   freebsd_uthread_ops.to_can_run = freebsd_uthread_can_run;
967   freebsd_uthread_ops.to_notice_signals = freebsd_uthread_notice_signals;
968   freebsd_uthread_ops.to_thread_alive = freebsd_uthread_thread_alive;
969   freebsd_uthread_ops.to_stop = freebsd_uthread_stop;
970   freebsd_uthread_ops.to_stratum = process_stratum;
971   freebsd_uthread_ops.to_has_all_memory = 1;
972   freebsd_uthread_ops.to_has_memory = 1;
973   freebsd_uthread_ops.to_has_stack = 1;
974   freebsd_uthread_ops.to_has_registers = 1;
975   freebsd_uthread_ops.to_has_execution = 1;
976   freebsd_uthread_ops.to_has_thread_control = 0;
977   freebsd_uthread_ops.to_magic = OPS_MAGIC;
978   freebsd_uthread_ops.to_find_new_threads = freebsd_uthread_find_new_threads;
979   freebsd_uthread_ops.to_pid_to_str = freebsd_uthread_pid_to_str;
980 #if 0
981   freebsd_uthread_vec.get_thread_info = freebsd_uthread_get_thread_info;
982 #endif
983 }
984
985 void
986 _initialize_freebsd_uthread ()
987 {
988   init_freebsd_uthread_ops ();
989   add_target (&freebsd_uthread_ops);
990
991   target_new_objfile_chain = deprecated_target_new_objfile_hook;
992   deprecated_target_new_objfile_hook = freebsd_uthread_new_objfile;
993
994   child_suppress_run = 1;
995 }