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