1 /* Low level interface for debugging FreeBSD user threads for GDB, the GNU debugger.
2 Copyright 1996, 1999 Free Software Foundation, Inc.
4 This file is part of GDB.
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.
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.
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. */
20 /* $FreeBSD: ports/devel/gdb6/files/freebsd-uthread.c,v 1.2 2004/06/20 18:45:36 obrien Exp $ */
22 /* This module implements a sort of half target that sits between the
23 machine-independent parts of GDB and the ptrace interface (infptrace.c) to
24 provide access to the FreeBSD user-mode thread implementation.
26 FreeBSD threads are true user-mode threads, which are invoked via
27 the pthread_* interfaces. These are mostly implemented in
28 user-space, with all thread context kept in various structures that
29 live in the user's heap. For the most part, the kernel has no
30 knowlege of these threads.
32 Based largely on hpux-thread.c
38 #include <sys/queue.h>
42 #include "gdbthread.h"
52 extern int child_suppress_run;
53 extern struct target_ops child_ops; /* target vector for inftarg.c */
55 extern void _initialize_freebsd_uthread PARAMS ((void));
57 /* Set to true while we are part-way through attaching */
58 static int freebsd_uthread_attaching;
60 static int freebsd_uthread_active = 0;
61 static CORE_ADDR P_thread_list;
62 static CORE_ADDR P_thread_run;
63 static CORE_ADDR P_thread_kern_thread;
65 /* Pointer to the next function on the objfile event chain. */
66 static void (*target_new_objfile_chain) (struct objfile *objfile);
68 static void freebsd_uthread_resume PARAMS ((ptid_t pid, int step,
69 enum target_signal signo));
71 static void init_freebsd_uthread_ops PARAMS ((void));
73 static struct target_ops freebsd_uthread_ops;
75 static ptid_t find_active_ptid PARAMS ((void));
77 struct cached_pthread {
87 static ptid_t cached_ptid;
88 static struct cached_pthread cached_pthread;
89 static CORE_ADDR cached_pthread_addr;
91 LIST_HEAD(idmaplist, idmap);
94 LIST_ENTRY(idmap) link;
99 #define MAPHASH_SIZE 257
101 #define TID_MAX 16383
103 static int tid_to_hash[TID_MAX + 1]; /* set to map_hash index */
104 static struct idmaplist map_hash[MAPHASH_SIZE];
105 static int next_free_tid = TID_MIN; /* first available tid */
106 static int last_free_tid = TID_MIN; /* first unavailable */
108 static CORE_ADDR P_thread_next_offset;
109 static CORE_ADDR P_thread_uniqueid_offset;
110 static CORE_ADDR P_thread_state_offset;
111 static CORE_ADDR P_thread_name_offset;
112 static CORE_ADDR P_thread_ctx_offset;
113 static CORE_ADDR P_thread_PS_RUNNING_value;
114 static CORE_ADDR P_thread_PS_DEAD_value;
116 static int next_offset;
117 static int uniqueid_offset;
118 static int state_offset;
119 static int name_offset;
120 static int ctx_offset;
121 static int PS_RUNNING_value;
122 static int PS_DEAD_value;
124 #define UNIQUEID_HASH(id) (id % MAPHASH_SIZE)
125 #define TID_ADD1(tid) (((tid) + 1) == TID_MAX + 1 \
126 ? TID_MIN : (tid) + 1)
127 #define IS_TID_FREE(tid) (tid_to_hash[tid] == -1)
132 int tid = next_free_tid;
134 tid_to_hash[tid] = h;
135 next_free_tid = TID_ADD1(next_free_tid);
136 if (next_free_tid == last_free_tid)
140 for (i = last_free_tid; TID_ADD1(i) != last_free_tid; i = TID_ADD1(i))
143 if (TID_ADD1(i) == last_free_tid)
145 error("too many threads");
149 for (i = TID_ADD1(i); IS_TID_FREE(i); i = TID_ADD1(i))
158 find_ptid(u_int64_t uniqueid)
160 int h = UNIQUEID_HASH(uniqueid);
163 LIST_FOREACH(im, &map_hash[h], link)
164 if (im->uniqueid == uniqueid)
165 return MERGEPID(PIDGET(inferior_ptid), im->tid);
167 im = xmalloc(sizeof(struct idmap));
168 im->uniqueid = uniqueid;
169 im->tid = get_new_tid(h);
170 LIST_INSERT_HEAD(&map_hash[h], im, link);
172 return MERGEPID(PIDGET(inferior_ptid), im->tid);
176 free_ptid(ptid_t ptid)
178 int tid = TIDGET(ptid);
179 int h = tid_to_hash[tid];
184 LIST_FOREACH(im, &map_hash[h], link)
190 LIST_REMOVE(im, link);
191 tid_to_hash[tid] = -1;
195 #define READ_OFFSET(field) read_memory(P_thread_##field##_offset, \
196 (char *) &field##_offset, \
197 sizeof(field##_offset))
199 #define READ_VALUE(name) read_memory(P_thread_##name##_value, \
200 (char *) &name##_value, \
201 sizeof(name##_value))
204 read_thread_offsets (void)
207 READ_OFFSET(uniqueid);
212 READ_VALUE(PS_RUNNING);
216 #define READ_FIELD(ptr, T, field, result) \
217 read_memory ((ptr) + field##_offset, (char *) &(result), sizeof result)
220 read_pthread_uniqueid (CORE_ADDR ptr)
223 READ_FIELD(ptr, u_int64_t, uniqueid, uniqueid);
228 read_pthread_next (CORE_ADDR ptr)
231 READ_FIELD(ptr, CORE_ADDR, next, next);
236 read_cached_pthread (CORE_ADDR ptr, struct cached_pthread *cache)
238 READ_FIELD(ptr, u_int64_t, uniqueid, cache->uniqueid);
239 READ_FIELD(ptr, int, state, cache->state);
240 READ_FIELD(ptr, CORE_ADDR, name, cache->name);
241 READ_FIELD(ptr, ucontext_t, ctx, cache->ctx);
245 find_active_ptid (void)
249 read_memory ((CORE_ADDR)P_thread_run,
253 return find_ptid(read_pthread_uniqueid(ptr));
256 static CORE_ADDR find_pthread_addr PARAMS ((ptid_t ptid));
257 static struct cached_pthread * find_pthread PARAMS ((ptid_t ptid));
260 find_pthread_addr (ptid_t ptid)
264 if (ptid_equal(ptid, cached_ptid))
265 return cached_pthread_addr;
267 read_memory ((CORE_ADDR)P_thread_list,
273 if (ptid_equal(find_ptid(read_pthread_uniqueid(ptr)), ptid))
276 cached_pthread_addr = ptr;
277 read_cached_pthread(ptr, &cached_pthread);
280 ptr = read_pthread_next(ptr);
286 static struct cached_pthread *
287 find_pthread (ptid_t ptid)
291 if (ptid_equal(ptid, cached_ptid))
292 return &cached_pthread;
294 read_memory ((CORE_ADDR)P_thread_list,
299 * uthreads might not be initialized yet, so we have to use the
300 * kernel thread instead.
303 ptr = P_thread_kern_thread;
307 if (ptid_equal(find_ptid(read_pthread_uniqueid(ptr)), ptid))
310 cached_pthread_addr = ptr;
311 read_cached_pthread(ptr, &cached_pthread);
312 return &cached_pthread;
314 ptr = read_pthread_next(ptr);
318 error ("Can't find pthread %d,%d", PIDGET(ptid), TIDGET(ptid));
324 /* Most target vector functions from here on actually just pass through to
325 inftarg.c, as they don't need to do anything specific for threads. */
329 freebsd_uthread_open (char *arg, int from_tty)
331 child_ops.to_open (arg, from_tty);
334 /* Attach to process PID, then initialize for debugging it
335 and wait for the trace-trap that results from attaching. */
338 freebsd_uthread_attach (char *args, int from_tty)
340 child_ops.to_attach (args, from_tty);
341 push_target (&freebsd_uthread_ops);
342 freebsd_uthread_attaching = 1;
345 /* After an attach, see if the target is threaded */
348 freebsd_uthread_post_attach (int pid)
350 if (freebsd_uthread_active)
352 read_thread_offsets ();
353 inferior_ptid = find_active_ptid ();
354 add_thread (inferior_ptid);
358 unpush_target (&freebsd_uthread_ops);
359 push_target (&child_ops);
362 freebsd_uthread_attaching = 0;
365 /* Take a program previously attached to and detaches it.
366 The program resumes execution and will no longer stop
367 on signals, etc. We'd better not have left any breakpoints
368 in the program or it'll die when it hits one. For this
369 to work, it may be necessary for the process to have been
370 previously attached. It *might* work if the program was
371 started via the normal ptrace (PTRACE_TRACEME). */
374 freebsd_uthread_detach (char *args, int from_tty)
376 child_ops.to_detach (args, from_tty);
379 /* Resume execution of process PID. If STEP is nozero, then
380 just single step it. If SIGNAL is nonzero, restart it with that
381 signal activated. We may have to convert pid from a thread-id to an LWP id
385 freebsd_uthread_resume (ptid_t ptid, int step, enum target_signal signo)
387 if (freebsd_uthread_attaching)
389 child_ops.to_resume (ptid, step, signo);
393 child_ops.to_resume (ptid, step, signo);
394 cached_ptid = MERGEPID(0, 0);
397 /* Wait for any threads to stop. We may have to convert PID from a thread id
398 to a LWP id, and vice versa on the way out. */
401 freebsd_uthread_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
405 if (freebsd_uthread_attaching)
407 return child_ops.to_wait (ptid, ourstatus);
410 rtnval = child_ops.to_wait (ptid, ourstatus);
412 if (PIDGET(rtnval) >= 0)
414 rtnval = find_active_ptid ();
415 if (!in_thread_list (rtnval))
422 /* XXX: this needs to be selected by target, not [build] host */
425 #include "i386-tdep.h"
427 static char sigmap[I386_SSE_NUM_REGS] = /* map reg to sigcontext */
445 -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */
446 -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */
447 -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */
451 static char jmpmap[I386_SSE_NUM_REGS] = /* map reg to jmp_buf */
469 -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */
470 -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */
471 -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */
479 #include "amd64-tdep.h"
481 // XXX:DEO not fully ported from i386 yet!!
484 #define AMD64_NUM_REGS_TOTAL 57
486 static char sigmap[AMD64_NUM_REGS_TOTAL] = /* map reg to sigcontext */
506 21, 24, -1, -1, -1, -1, /* %cs - %gs */
507 -1, -1, -1, -1, -1 -1, -1, -1,/* %st0 - %st7 */
508 -1, -1, -1, -1, -1 -1, -1, -1,/* %fctrl - %fop */
509 -1, -1, -1, -1, -1 -1, -1, -1,/* %xmm0 - %xmm7 */
510 -1, -1, -1, -1, -1 -1, -1, -1,/* %xmm8 - %xmm15 */
514 static char jmpmap[AMD64_NUM_REGS_TOTAL] = /* map reg to jmp_buf */
534 -1, -1, -1, -1, -1, -1, /* %cs - %gs */
535 -1, -1, -1, -1, -1 -1, -1, -1,/* %st0 - %st7 */
536 -1, -1, -1, -1, -1 -1, -1, -1,/* %fctrl - %fop */
537 -1, -1, -1, -1, -1 -1, -1, -1,/* %xmm0 - %xmm7 */
538 -1, -1, -1, -1, -1 -1, -1, -1,/* %xmm8 - %xmm15 */
546 #include "alpha-tdep.h"
548 static char sigmap[ALPHA_NUM_REGS] = /* map reg to sigcontext */
550 1, 2, 3, 4, 5, 6, 7, 8, /* v0 - t6 */
551 9, 10, 11, 12, 13, 14, 15, 16, /* t7 - fp */
552 17, 18, 19, 20, 21, 22, 23, 24, /* a0 - t9 */
553 25, 26, 27, 28, 29, 30, 31, 32, /* t10 - zero */
554 38, 39, 40, 41, 42, 43, 44, 45, /* f0 - f7 */
555 46, 47, 48, 49, 50, 51, 52, 53, /* f8 - f15 */
556 54, 55, 56, 57, 58, 59, 60, 61, /* f16 - f23 */
557 62, 63, 64, 65, 66, 67, 68, 69, /* f24 - f31 */
560 static char jmpmap[ALPHA_NUM_REGS] = {
561 4, 5, 6, 7, 8, 9, 10, 11, /* v0 - t6 */
562 12, 13, 14, 15, 16, 17, 18, 19, /* t7 - fp */
563 20, 21, 22, 23, 24, 25, 26, 27, /* a0 - t9 */
564 28, 29, 30, 31, 32, 33, 34, 35, /* t10 - zero */
565 37, 38, 39, 40, 41, 42, 43, 44, /* f0 - f7 */
566 45, 46, 47, 48, 49, 50, 51, 52, /* f8 - f15 */
567 53, 54, 55, 56, 57, 58, 59, 60, /* f16 - f23 */
568 61, 62, 63, 64, 65, 66, 67, 68, /* f24 - f31 */
576 static char sigmap[125] = /* map reg to sigcontext */
580 static char jmpmap[125] = {
587 freebsd_uthread_fetch_registers (int regno)
589 struct cached_pthread *thread;
591 int first_regno, last_regno;
595 if (freebsd_uthread_attaching || TIDGET(inferior_ptid) == 0)
597 child_ops.to_fetch_registers (regno);
601 thread = find_pthread (inferior_ptid);
602 active = (ptid_equal(inferior_ptid, find_active_ptid()));
606 child_ops.to_fetch_registers (regno);
613 last_regno = NUM_REGS - 1;
621 regbase = (register_t*) &thread->ctx.jb[0];
624 for (regno = first_regno; regno <= last_regno; regno++)
626 if (regmap[regno] == -1)
627 child_ops.to_fetch_registers (regno);
630 supply_register (regno, (char*) ®base[regmap[regno]]);
632 supply_register (regno, NULL);
637 freebsd_uthread_store_registers (int regno)
639 struct cached_pthread *thread;
641 int first_regno, last_regno;
645 if (freebsd_uthread_attaching)
647 child_ops.to_store_registers (regno);
651 thread = find_pthread (inferior_ptid);
653 if (thread->state == PS_RUNNING_value)
655 child_ops.to_store_registers (regno);
662 last_regno = NUM_REGS - 1;
670 regbase = (u_int32_t*) &thread->ctx.jb[0];
673 ptr = find_pthread_addr (inferior_ptid);
674 for (regno = first_regno; regno <= last_regno; regno++)
676 if (regmap[regno] == -1)
677 child_ops.to_store_registers (regno);
680 u_int32_t *reg = ®base[regmap[regno]];
683 /* Hang onto cached value */
685 memcpy(reg, deprecated_registers /*regcache_collect ()*/+ DEPRECATED_REGISTER_BYTE (regno),
686 DEPRECATED_REGISTER_RAW_SIZE (regno));
688 /* And push out to inferior */
689 off = (char *) reg - (char *) thread;
690 write_memory (ptr + off,
692 deprecated_registers /*regcache_collect ()*/+ DEPRECATED_REGISTER_BYTE (regno),
693 DEPRECATED_REGISTER_RAW_SIZE (regno));
698 /* Get ready to modify the registers array. On machines which store
699 individual registers, this doesn't need to do anything. On machines
700 which store all the registers in one fell swoop, this makes sure
701 that registers contains all the registers from the program being
705 freebsd_uthread_prepare_to_store (void)
707 child_ops.to_prepare_to_store ();
711 freebsd_uthread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
712 int dowrite, struct mem_attrib *attrib,
713 struct target_ops *target)
715 return child_ops.to_xfer_memory (memaddr, myaddr, len, dowrite,
719 /* Print status information about what we're accessing. */
722 freebsd_uthread_files_info (struct target_ops *ignore)
724 child_ops.to_files_info (ignore);
728 freebsd_uthread_kill_inferior (void)
730 child_ops.to_kill ();
734 freebsd_uthread_notice_signals (ptid_t ptid)
736 child_ops.to_notice_signals (ptid);
739 /* Fork an inferior process, and start debugging it with /proc. */
742 freebsd_uthread_create_inferior (char *exec_file, char *allargs, char **env,
745 child_ops.to_create_inferior (exec_file, allargs, env, from_tty);
747 if (PIDGET(inferior_ptid) && freebsd_uthread_active)
749 read_thread_offsets ();
750 push_target (&freebsd_uthread_ops);
751 inferior_ptid = find_active_ptid ();
752 add_thread (inferior_ptid);
756 /* This routine is called to find out if the inferior is using threads.
757 We check for the _thread_run and _thread_list globals. */
760 freebsd_uthread_new_objfile (struct objfile *objfile)
762 struct minimal_symbol *ms;
766 freebsd_uthread_active = 0;
770 ms = lookup_minimal_symbol ("_thread_run", NULL, objfile);
775 P_thread_run = SYMBOL_VALUE_ADDRESS (ms);
777 ms = lookup_minimal_symbol ("_thread_list", NULL, objfile);
782 P_thread_list = SYMBOL_VALUE_ADDRESS (ms);
784 ms = lookup_minimal_symbol ("_thread_kern_thread", NULL, objfile);
789 P_thread_kern_thread = SYMBOL_VALUE_ADDRESS (ms);
791 #define OFFSET_SYM(field) "_thread_" #field "_offset"
792 #define LOOKUP_OFFSET(field) \
794 ms = lookup_minimal_symbol (OFFSET_SYM(field), NULL, objfile); \
797 P_thread_##field##_offset = SYMBOL_VALUE_ADDRESS (ms); \
800 #define VALUE_SYM(name) "_thread_" #name "_value"
801 #define LOOKUP_VALUE(name) \
803 ms = lookup_minimal_symbol (VALUE_SYM(name), NULL, objfile); \
806 P_thread_##name##_value = SYMBOL_VALUE_ADDRESS (ms); \
810 LOOKUP_OFFSET(uniqueid);
811 LOOKUP_OFFSET(state);
815 LOOKUP_VALUE(PS_RUNNING);
816 LOOKUP_VALUE(PS_DEAD);
818 freebsd_uthread_active = 1;
821 /* Clean up after the inferior dies. */
824 freebsd_uthread_mourn_inferior ()
826 child_ops.to_mourn_inferior ();
827 unpush_target (&freebsd_uthread_ops);
830 /* Mark our target-struct as eligible for stray "run" and "attach" commands. */
833 freebsd_uthread_can_run ()
835 return child_suppress_run;
839 freebsd_uthread_thread_alive (ptid_t ptid)
841 struct cached_pthread *thread;
844 if (freebsd_uthread_attaching)
848 * We can get called from child_ops.to_wait() which passes the underlying
849 * pid (without a thread number).
851 if (TIDGET(ptid) == 0)
854 if (find_pthread_addr (ptid) != 0)
856 thread = find_pthread (ptid);
857 ret = (thread->state != PS_DEAD_value);
867 freebsd_uthread_stop (void)
869 child_ops.to_stop ();
873 freebsd_uthread_find_new_threads (void)
879 read_memory ((CORE_ADDR)P_thread_list,
885 READ_FIELD(ptr, int, state, state);
886 READ_FIELD(ptr, u_int64_t, uniqueid, uniqueid);
887 if (state != PS_DEAD_value &&
888 !in_thread_list (find_ptid(uniqueid)))
889 add_thread (find_ptid(uniqueid));
890 ptr = read_pthread_next(ptr);
894 /* MUST MATCH enum pthread_state */
895 static const char *statenames[] = {
921 freebsd_uthread_get_thread_info (ref, selection, info)
924 struct gdb_ext_thread_info *info;
927 struct cached_pthread *thread = find_pthread (pid);
928 struct cleanup *old_chain;
930 old_chain = save_inferior_pid ();
931 inferior_pid = main_pid;
933 memset(&info->threadid, 0, OPAQUETHREADBYTES);
935 memcpy(&info->threadid, ref, sizeof *ref);
936 info->active = thread->state == PS_RUNNING_value;
937 strcpy(info->display, statenames[thread->state]);
939 read_memory ((CORE_ADDR) thread->name, info->shortname, 32);
941 strcpy(info->shortname, "");
943 do_cleanups (old_chain);
950 freebsd_uthread_pid_to_str (ptid_t ptid)
954 if (DEPRECATED_STREQ (current_target.to_shortname, "freebsd-uthreads"))
955 sprintf (buf, "Process %d, Thread %ld",
956 PIDGET(ptid), TIDGET(ptid));
958 sprintf (buf, "Process %d", PIDGET(ptid));
965 init_freebsd_uthread_ops ()
967 freebsd_uthread_ops.to_shortname = "freebsd-uthreads";
968 freebsd_uthread_ops.to_longname = "FreeBSD uthreads";
969 freebsd_uthread_ops.to_doc = "FreeBSD user threads support.";
970 freebsd_uthread_ops.to_open = freebsd_uthread_open;
971 freebsd_uthread_ops.to_attach = freebsd_uthread_attach;
972 freebsd_uthread_ops.to_post_attach = freebsd_uthread_post_attach;
973 freebsd_uthread_ops.to_detach = freebsd_uthread_detach;
974 freebsd_uthread_ops.to_resume = freebsd_uthread_resume;
975 freebsd_uthread_ops.to_wait = freebsd_uthread_wait;
976 freebsd_uthread_ops.to_fetch_registers = freebsd_uthread_fetch_registers;
977 freebsd_uthread_ops.to_store_registers = freebsd_uthread_store_registers;
978 freebsd_uthread_ops.to_prepare_to_store = freebsd_uthread_prepare_to_store;
979 freebsd_uthread_ops.to_xfer_memory = freebsd_uthread_xfer_memory;
980 freebsd_uthread_ops.to_files_info = freebsd_uthread_files_info;
981 freebsd_uthread_ops.to_insert_breakpoint = memory_insert_breakpoint;
982 freebsd_uthread_ops.to_remove_breakpoint = memory_remove_breakpoint;
983 freebsd_uthread_ops.to_terminal_init = terminal_init_inferior;
984 freebsd_uthread_ops.to_terminal_inferior = terminal_inferior;
985 freebsd_uthread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
986 freebsd_uthread_ops.to_terminal_ours = terminal_ours;
987 freebsd_uthread_ops.to_terminal_info = child_terminal_info;
988 freebsd_uthread_ops.to_kill = freebsd_uthread_kill_inferior;
989 freebsd_uthread_ops.to_create_inferior = freebsd_uthread_create_inferior;
990 freebsd_uthread_ops.to_mourn_inferior = freebsd_uthread_mourn_inferior;
991 freebsd_uthread_ops.to_can_run = freebsd_uthread_can_run;
992 freebsd_uthread_ops.to_notice_signals = freebsd_uthread_notice_signals;
993 freebsd_uthread_ops.to_thread_alive = freebsd_uthread_thread_alive;
994 freebsd_uthread_ops.to_stop = freebsd_uthread_stop;
995 freebsd_uthread_ops.to_stratum = process_stratum;
996 freebsd_uthread_ops.to_has_all_memory = 1;
997 freebsd_uthread_ops.to_has_memory = 1;
998 freebsd_uthread_ops.to_has_stack = 1;
999 freebsd_uthread_ops.to_has_registers = 1;
1000 freebsd_uthread_ops.to_has_execution = 1;
1001 freebsd_uthread_ops.to_has_thread_control = 0;
1002 freebsd_uthread_ops.to_magic = OPS_MAGIC;
1003 freebsd_uthread_ops.to_find_new_threads = freebsd_uthread_find_new_threads;
1004 freebsd_uthread_ops.to_pid_to_str = freebsd_uthread_pid_to_str;
1006 freebsd_uthread_vec.get_thread_info = freebsd_uthread_get_thread_info;
1011 _initialize_freebsd_uthread ()
1013 init_freebsd_uthread_ops ();
1014 add_target (&freebsd_uthread_ops);
1016 target_new_objfile_chain = deprecated_target_new_objfile_hook;
1017 deprecated_target_new_objfile_hook = freebsd_uthread_new_objfile;
1019 child_suppress_run = 1;