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