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. */
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>
41 #include "gdbthread.h"
50 extern int child_suppress_run;
51 extern struct target_ops child_ops; /* target vector for inftarg.c */
53 extern void _initialize_freebsd_uthread PARAMS ((void));
55 /* Set to true while we are part-way through attaching */
56 static int freebsd_uthread_attaching;
58 static int freebsd_uthread_active = 0;
59 static CORE_ADDR P_thread_list;
60 static CORE_ADDR P_thread_run;
62 /* Pointer to the next function on the objfile event chain. */
63 static void (*target_new_objfile_chain) (struct objfile *objfile);
65 static void freebsd_uthread_resume PARAMS ((ptid_t pid, int step,
66 enum target_signal signo));
68 static void init_freebsd_uthread_ops PARAMS ((void));
70 static struct target_ops freebsd_uthread_ops;
72 static ptid_t find_active_ptid PARAMS ((void));
74 struct cached_pthread {
84 static ptid_t cached_ptid;
85 static struct cached_pthread cached_pthread;
86 static CORE_ADDR cached_pthread_addr;
88 LIST_HEAD(idmaplist, idmap);
91 LIST_ENTRY(idmap) link;
96 #define MAPHASH_SIZE 257
100 static int tid_to_hash[TID_MAX + 1]; /* set to map_hash index */
101 static struct idmaplist map_hash[MAPHASH_SIZE];
102 static int next_free_tid = TID_MIN; /* first available tid */
103 static int last_free_tid = TID_MIN; /* first unavailable */
105 static CORE_ADDR P_thread_next_offset;
106 static CORE_ADDR P_thread_uniqueid_offset;
107 static CORE_ADDR P_thread_state_offset;
108 static CORE_ADDR P_thread_name_offset;
109 static CORE_ADDR P_thread_ctx_offset;
110 static CORE_ADDR P_thread_PS_RUNNING_value;
111 static CORE_ADDR P_thread_PS_DEAD_value;
113 static int next_offset;
114 static int uniqueid_offset;
115 static int state_offset;
116 static int name_offset;
117 static int ctx_offset;
118 static int PS_RUNNING_value;
119 static int PS_DEAD_value;
121 #define UNIQUEID_HASH(id) (id % MAPHASH_SIZE)
122 #define TID_ADD1(tid) (((tid) + 1) == TID_MAX + 1 \
123 ? TID_MIN : (tid) + 1)
124 #define IS_TID_FREE(tid) (tid_to_hash[tid] == -1)
129 int tid = next_free_tid;
131 tid_to_hash[tid] = h;
132 next_free_tid = TID_ADD1(next_free_tid);
133 if (next_free_tid == last_free_tid)
137 for (i = last_free_tid; TID_ADD1(i) != last_free_tid; i = TID_ADD1(i))
140 if (TID_ADD1(i) == last_free_tid)
142 error("too many threads");
146 for (i = TID_ADD1(i); IS_TID_FREE(i); i = TID_ADD1(i))
155 find_ptid(u_int64_t uniqueid)
157 int h = UNIQUEID_HASH(uniqueid);
160 LIST_FOREACH(im, &map_hash[h], link)
161 if (im->uniqueid == uniqueid)
162 return MERGEPID(PIDGET(inferior_ptid), im->tid);
164 im = xmalloc(sizeof(struct idmap));
165 im->uniqueid = uniqueid;
166 im->tid = get_new_tid(h);
167 LIST_INSERT_HEAD(&map_hash[h], im, link);
169 return MERGEPID(PIDGET(inferior_ptid), im->tid);
173 free_ptid(ptid_t ptid)
175 int tid = TIDGET(ptid);
176 int h = tid_to_hash[tid];
181 LIST_FOREACH(im, &map_hash[h], link)
187 LIST_REMOVE(im, link);
188 tid_to_hash[tid] = -1;
192 #define READ_OFFSET(field) read_memory(P_thread_##field##_offset, \
193 (char *) &field##_offset, \
194 sizeof(field##_offset))
196 #define READ_VALUE(name) read_memory(P_thread_##name##_value, \
197 (char *) &name##_value, \
198 sizeof(name##_value))
201 read_thread_offsets (void)
204 READ_OFFSET(uniqueid);
209 READ_VALUE(PS_RUNNING);
213 #define READ_FIELD(ptr, T, field, result) \
214 read_memory ((ptr) + field##_offset, (char *) &(result), sizeof result)
217 read_pthread_uniqueid (CORE_ADDR ptr)
220 READ_FIELD(ptr, u_int64_t, uniqueid, uniqueid);
225 read_pthread_next (CORE_ADDR ptr)
228 READ_FIELD(ptr, CORE_ADDR, next, next);
233 read_cached_pthread (CORE_ADDR ptr, struct cached_pthread *cache)
235 READ_FIELD(ptr, u_int64_t, uniqueid, cache->uniqueid);
236 READ_FIELD(ptr, int, state, cache->state);
237 READ_FIELD(ptr, CORE_ADDR, name, cache->name);
238 READ_FIELD(ptr, ucontext_t, ctx, cache->ctx);
242 find_active_ptid (void)
246 read_memory ((CORE_ADDR)P_thread_run,
250 return find_ptid(read_pthread_uniqueid(ptr));
253 static CORE_ADDR find_pthread_addr PARAMS ((ptid_t ptid));
254 static struct cached_pthread * find_pthread PARAMS ((ptid_t ptid));
257 find_pthread_addr (ptid_t ptid)
261 if (ptid_equal(ptid, cached_ptid))
262 return cached_pthread_addr;
264 read_memory ((CORE_ADDR)P_thread_list,
270 if (ptid_equal(find_ptid(read_pthread_uniqueid(ptr)), ptid))
273 cached_pthread_addr = ptr;
274 read_cached_pthread(ptr, &cached_pthread);
277 ptr = read_pthread_next(ptr);
283 static struct cached_pthread *
284 find_pthread (ptid_t ptid)
288 if (ptid_equal(ptid, cached_ptid))
289 return &cached_pthread;
291 read_memory ((CORE_ADDR)P_thread_list,
297 if (ptid_equal(find_ptid(read_pthread_uniqueid(ptr)), ptid))
300 cached_pthread_addr = ptr;
301 read_cached_pthread(ptr, &cached_pthread);
302 return &cached_pthread;
304 ptr = read_pthread_next(ptr);
308 error ("Can't find pthread %d,%d", PIDGET(ptid), TIDGET(ptid));
314 /* Most target vector functions from here on actually just pass through to
315 inftarg.c, as they don't need to do anything specific for threads. */
319 freebsd_uthread_open (char *arg, int from_tty)
321 child_ops.to_open (arg, from_tty);
324 /* Attach to process PID, then initialize for debugging it
325 and wait for the trace-trap that results from attaching. */
328 freebsd_uthread_attach (char *args, int from_tty)
330 child_ops.to_attach (args, from_tty);
331 push_target (&freebsd_uthread_ops);
332 freebsd_uthread_attaching = 1;
335 /* After an attach, see if the target is threaded */
338 freebsd_uthread_post_attach (int pid)
340 if (freebsd_uthread_active)
342 read_thread_offsets ();
343 inferior_ptid = find_active_ptid ();
344 add_thread (inferior_ptid);
348 unpush_target (&freebsd_uthread_ops);
349 push_target (&child_ops);
352 freebsd_uthread_attaching = 0;
355 /* Take a program previously attached to and detaches it.
356 The program resumes execution and will no longer stop
357 on signals, etc. We'd better not have left any breakpoints
358 in the program or it'll die when it hits one. For this
359 to work, it may be necessary for the process to have been
360 previously attached. It *might* work if the program was
361 started via the normal ptrace (PTRACE_TRACEME). */
364 freebsd_uthread_detach (char *args, int from_tty)
366 child_ops.to_detach (args, from_tty);
369 /* Resume execution of process PID. If STEP is nozero, then
370 just single step it. If SIGNAL is nonzero, restart it with that
371 signal activated. We may have to convert pid from a thread-id to an LWP id
375 freebsd_uthread_resume (ptid_t ptid, int step, enum target_signal signo)
377 if (freebsd_uthread_attaching)
379 child_ops.to_resume (ptid, step, signo);
383 child_ops.to_resume (ptid, step, signo);
384 cached_ptid = MERGEPID(0, 0);
387 /* Wait for any threads to stop. We may have to convert PID from a thread id
388 to a LWP id, and vice versa on the way out. */
391 freebsd_uthread_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
395 if (freebsd_uthread_attaching)
397 return child_ops.to_wait (ptid, ourstatus);
400 rtnval = child_ops.to_wait (ptid, ourstatus);
402 if (PIDGET(rtnval) >= 0)
404 rtnval = find_active_ptid ();
405 if (!in_thread_list (rtnval))
412 /* XXX: this needs to be selected by target, not [build] host */
415 static char jmpmap[MAX_NUM_REGS] = /* map reg to jmp_buf */
433 -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */
434 -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */
435 -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */
443 static char jmpmap[NUM_REGS] = {
444 4, 5, 6, 7, 8, 9, 10, 11, /* v0 - t6 */
445 12, 13, 14, 15, 16, 17, 18, 19, /* t7 - fp */
446 20, 21, 22, 23, 24, 25, 26, 27, /* a0 - t9 */
447 28, 29, 30, 31, 32, 33, 34, 35, /* t10 - zero */
448 37, 38, 39, 40, 41, 42, 43, 44, /* f0 - f7 */
449 45, 46, 47, 48, 49, 50, 51, 52, /* f8 - f15 */
450 53, 54, 55, 56, 57, 58, 59, 60, /* f16 - f23 */
451 61, 62, 63, 64, 65, 66, 67, 68, /* f24 - f31 */
459 static char jmpmap[125] = {
466 freebsd_uthread_fetch_registers (int regno)
468 struct cached_pthread *thread;
470 int first_regno, last_regno;
474 if (freebsd_uthread_attaching || TIDGET(inferior_ptid) == 0)
476 child_ops.to_fetch_registers (regno);
480 thread = find_pthread (inferior_ptid);
481 active = (ptid_equal(inferior_ptid, find_active_ptid()));
485 child_ops.to_fetch_registers (regno);
492 last_regno = NUM_REGS - 1;
500 regbase = (register_t*) &thread->ctx.jb[0];
503 for (regno = first_regno; regno <= last_regno; regno++)
505 if (regmap[regno] == -1)
506 child_ops.to_fetch_registers (regno);
509 supply_register (regno, (char*) ®base[regmap[regno]]);
511 supply_register (regno, NULL);
516 freebsd_uthread_store_registers (int regno)
518 struct cached_pthread *thread;
520 int first_regno, last_regno;
524 if (freebsd_uthread_attaching)
526 child_ops.to_store_registers (regno);
530 thread = find_pthread (inferior_ptid);
532 if (thread->state == PS_RUNNING_value)
534 child_ops.to_store_registers (regno);
541 last_regno = NUM_REGS - 1;
549 regbase = (u_int32_t*) &thread->ctx.jb[0];
552 ptr = find_pthread_addr (inferior_ptid);
553 for (regno = first_regno; regno <= last_regno; regno++)
555 if (regmap[regno] == -1)
556 child_ops.to_store_registers (regno);
559 u_int32_t *reg = ®base[regmap[regno]];
562 /* Hang onto cached value */
563 memcpy(reg, registers + REGISTER_BYTE (regno),
564 REGISTER_RAW_SIZE (regno));
566 /* And push out to inferior */
567 off = (char *) reg - (char *) thread;
568 write_memory (ptr + off,
569 registers + REGISTER_BYTE (regno),
570 REGISTER_RAW_SIZE (regno));
575 /* Get ready to modify the registers array. On machines which store
576 individual registers, this doesn't need to do anything. On machines
577 which store all the registers in one fell swoop, this makes sure
578 that registers contains all the registers from the program being
582 freebsd_uthread_prepare_to_store (void)
584 child_ops.to_prepare_to_store ();
588 freebsd_uthread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
589 int dowrite, struct mem_attrib *attrib,
590 struct target_ops *target)
592 return child_ops.to_xfer_memory (memaddr, myaddr, len, dowrite,
596 /* Print status information about what we're accessing. */
599 freebsd_uthread_files_info (struct target_ops *ignore)
601 child_ops.to_files_info (ignore);
605 freebsd_uthread_kill_inferior (void)
607 child_ops.to_kill ();
611 freebsd_uthread_notice_signals (ptid_t ptid)
613 child_ops.to_notice_signals (ptid);
616 /* Fork an inferior process, and start debugging it with /proc. */
619 freebsd_uthread_create_inferior (char *exec_file, char *allargs, char **env)
621 child_ops.to_create_inferior (exec_file, allargs, env);
623 if (PIDGET(inferior_ptid) && freebsd_uthread_active)
625 read_thread_offsets ();
626 push_target (&freebsd_uthread_ops);
627 inferior_ptid = find_active_ptid ();
628 add_thread (inferior_ptid);
632 /* This routine is called to find out if the inferior is using threads.
633 We check for the _thread_run and _thread_list globals. */
636 freebsd_uthread_new_objfile (struct objfile *objfile)
638 struct minimal_symbol *ms;
642 freebsd_uthread_active = 0;
646 ms = lookup_minimal_symbol ("_thread_run", NULL, objfile);
651 P_thread_run = SYMBOL_VALUE_ADDRESS (ms);
653 ms = lookup_minimal_symbol ("_thread_list", NULL, objfile);
658 P_thread_list = SYMBOL_VALUE_ADDRESS (ms);
660 #define OFFSET_SYM(field) "_thread_" #field "_offset"
661 #define LOOKUP_OFFSET(field) \
663 ms = lookup_minimal_symbol (OFFSET_SYM(field), NULL, objfile); \
666 P_thread_##field##_offset = SYMBOL_VALUE_ADDRESS (ms); \
669 #define VALUE_SYM(name) "_thread_" #name "_value"
670 #define LOOKUP_VALUE(name) \
672 ms = lookup_minimal_symbol (VALUE_SYM(name), NULL, objfile); \
675 P_thread_##name##_value = SYMBOL_VALUE_ADDRESS (ms); \
679 LOOKUP_OFFSET(uniqueid);
680 LOOKUP_OFFSET(state);
684 LOOKUP_VALUE(PS_RUNNING);
685 LOOKUP_VALUE(PS_DEAD);
687 freebsd_uthread_active = 1;
690 /* Clean up after the inferior dies. */
693 freebsd_uthread_mourn_inferior ()
695 child_ops.to_mourn_inferior ();
696 unpush_target (&freebsd_uthread_ops);
699 /* Mark our target-struct as eligible for stray "run" and "attach" commands. */
702 freebsd_uthread_can_run ()
704 return child_suppress_run;
708 freebsd_uthread_thread_alive (ptid_t ptid)
710 struct cached_pthread *thread;
713 if (freebsd_uthread_attaching)
717 * We can get called from child_ops.to_wait() which passes the underlying
718 * pid (without a thread number).
720 if (TIDGET(ptid) == 0)
723 if (find_pthread_addr (ptid) != 0)
725 thread = find_pthread (ptid);
726 ret = (thread->state != PS_DEAD_value);
736 freebsd_uthread_stop (void)
738 child_ops.to_stop ();
742 freebsd_uthread_find_new_threads (void)
748 read_memory ((CORE_ADDR)P_thread_list,
754 READ_FIELD(ptr, int, state, state);
755 READ_FIELD(ptr, u_int64_t, uniqueid, uniqueid);
756 if (state != PS_DEAD_value &&
757 !in_thread_list (find_ptid(uniqueid)))
758 add_thread (find_ptid(uniqueid));
759 ptr = read_pthread_next(ptr);
763 /* MUST MATCH enum pthread_state */
764 static const char *statenames[] = {
790 freebsd_uthread_get_thread_info (ref, selection, info)
793 struct gdb_ext_thread_info *info;
796 struct cached_pthread *thread = find_pthread (pid);
797 struct cleanup *old_chain;
799 old_chain = save_inferior_pid ();
800 inferior_pid = main_pid;
802 memset(&info->threadid, 0, OPAQUETHREADBYTES);
804 memcpy(&info->threadid, ref, sizeof *ref);
805 info->active = thread->state == PS_RUNNING_value;
806 strcpy(info->display, statenames[thread->state]);
808 read_memory ((CORE_ADDR) thread->name, info->shortname, 32);
810 strcpy(info->shortname, "");
812 do_cleanups (old_chain);
819 freebsd_uthread_pid_to_str (ptid_t ptid)
823 if (STREQ (current_target.to_shortname, "freebsd-uthreads"))
824 sprintf (buf, "Process %d, Thread %ld",
825 PIDGET(ptid), TIDGET(ptid));
827 sprintf (buf, "Process %d", PIDGET(ptid));
834 init_freebsd_uthread_ops ()
836 freebsd_uthread_ops.to_shortname = "freebsd-uthreads";
837 freebsd_uthread_ops.to_longname = "FreeBSD uthreads";
838 freebsd_uthread_ops.to_doc = "FreeBSD user threads support.";
839 freebsd_uthread_ops.to_open = freebsd_uthread_open;
840 freebsd_uthread_ops.to_attach = freebsd_uthread_attach;
841 freebsd_uthread_ops.to_post_attach = freebsd_uthread_post_attach;
842 freebsd_uthread_ops.to_detach = freebsd_uthread_detach;
843 freebsd_uthread_ops.to_resume = freebsd_uthread_resume;
844 freebsd_uthread_ops.to_wait = freebsd_uthread_wait;
845 freebsd_uthread_ops.to_fetch_registers = freebsd_uthread_fetch_registers;
846 freebsd_uthread_ops.to_store_registers = freebsd_uthread_store_registers;
847 freebsd_uthread_ops.to_prepare_to_store = freebsd_uthread_prepare_to_store;
848 freebsd_uthread_ops.to_xfer_memory = freebsd_uthread_xfer_memory;
849 freebsd_uthread_ops.to_files_info = freebsd_uthread_files_info;
850 freebsd_uthread_ops.to_insert_breakpoint = memory_insert_breakpoint;
851 freebsd_uthread_ops.to_remove_breakpoint = memory_remove_breakpoint;
852 freebsd_uthread_ops.to_terminal_init = terminal_init_inferior;
853 freebsd_uthread_ops.to_terminal_inferior = terminal_inferior;
854 freebsd_uthread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
855 freebsd_uthread_ops.to_terminal_ours = terminal_ours;
856 freebsd_uthread_ops.to_terminal_info = child_terminal_info;
857 freebsd_uthread_ops.to_kill = freebsd_uthread_kill_inferior;
858 freebsd_uthread_ops.to_create_inferior = freebsd_uthread_create_inferior;
859 freebsd_uthread_ops.to_mourn_inferior = freebsd_uthread_mourn_inferior;
860 freebsd_uthread_ops.to_can_run = freebsd_uthread_can_run;
861 freebsd_uthread_ops.to_notice_signals = freebsd_uthread_notice_signals;
862 freebsd_uthread_ops.to_thread_alive = freebsd_uthread_thread_alive;
863 freebsd_uthread_ops.to_stop = freebsd_uthread_stop;
864 freebsd_uthread_ops.to_stratum = process_stratum;
865 freebsd_uthread_ops.to_has_all_memory = 1;
866 freebsd_uthread_ops.to_has_memory = 1;
867 freebsd_uthread_ops.to_has_stack = 1;
868 freebsd_uthread_ops.to_has_registers = 1;
869 freebsd_uthread_ops.to_has_execution = 1;
870 freebsd_uthread_ops.to_has_thread_control = 0;
871 freebsd_uthread_ops.to_magic = OPS_MAGIC;
872 freebsd_uthread_ops.to_find_new_threads = freebsd_uthread_find_new_threads;
873 freebsd_uthread_ops.to_pid_to_str = freebsd_uthread_pid_to_str;
875 freebsd_uthread_vec.get_thread_info = freebsd_uthread_get_thread_info;
880 _initialize_freebsd_uthread ()
882 init_freebsd_uthread_ops ();
883 add_target (&freebsd_uthread_ops);
885 target_new_objfile_chain = target_new_objfile_hook;
886 target_new_objfile_hook = freebsd_uthread_new_objfile;
888 child_suppress_run = 1;