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