xref: /openbsd/gnu/usr.bin/binutils/gdb/bsd-uthread.c (revision 5af055cd)
1 /* BSD user-level threads support.
2 
3    Copyright 2005 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,
20    Boston, MA 02111-1307, USA.  */
21 
22 #include "defs.h"
23 #include "gdbcore.h"
24 #include "gdbthread.h"
25 #include "inferior.h"
26 #include "objfiles.h"
27 #include "observer.h"
28 #include "regcache.h"
29 #include "solib.h"
30 #include "solist.h"
31 #include "symfile.h"
32 #include "target.h"
33 
34 #include "gdb_assert.h"
35 #include "gdb_obstack.h"
36 
37 #include "bsd-uthread.h"
38 
39 /* HACK: Save the bsd_uthreads ops returned by bsd_uthread_target.  */
40 static struct target_ops *bsd_uthread_ops_hack;
41 
42 
43 /* Architecture-specific operations.  */
44 
45 /* Per-architecture data key.  */
46 static struct gdbarch_data *bsd_uthread_data;
47 
48 struct bsd_uthread_ops
49 {
50   /* Supply registers for an inactive thread to a register cache.  */
51   void (*supply_uthread)(struct regcache *, int, CORE_ADDR, int);
52 
53   /* Collect registers for an inactive thread from a register cache.  */
54   void (*collect_uthread)(const struct regcache *, int, CORE_ADDR, int);
55 };
56 
57 static void *
58 bsd_uthread_init (struct obstack *obstack)
59 {
60   struct bsd_uthread_ops *ops;
61 
62   ops = OBSTACK_ZALLOC (obstack, struct bsd_uthread_ops);
63   return ops;
64 }
65 
66 /* Set the function that supplies registers from an inactive thread
67    for architecture GDBARCH to SUPPLY_UTHREAD.  */
68 
69 void
70 bsd_uthread_set_supply_uthread (struct gdbarch *gdbarch,
71 				void (*supply_uthread) (struct regcache *,
72 							int, CORE_ADDR, int))
73 {
74   struct bsd_uthread_ops *ops = gdbarch_data (gdbarch, bsd_uthread_data);
75   ops->supply_uthread = supply_uthread;
76 }
77 
78 /* Set the function that collects registers for an inactive thread for
79    architecture GDBARCH to SUPPLY_UTHREAD.  */
80 
81 void
82 bsd_uthread_set_collect_uthread (struct gdbarch *gdbarch,
83 			 void (*collect_uthread) (const struct regcache *,
84 						  int, CORE_ADDR, int))
85 {
86   struct bsd_uthread_ops *ops = gdbarch_data (gdbarch, bsd_uthread_data);
87   ops->collect_uthread = collect_uthread;
88 }
89 
90 /* Magic number to help recognize a valid thread structure.  */
91 #define BSD_UTHREAD_PTHREAD_MAGIC	0xd09ba115
92 
93 /* Check whether the thread structure at ADDR is valid.  */
94 
95 static void
96 bsd_uthread_check_magic (CORE_ADDR addr)
97 {
98   ULONGEST magic = read_memory_unsigned_integer (addr, 4);
99 
100   if (magic != BSD_UTHREAD_PTHREAD_MAGIC)
101     error (_("Bad magic"));
102 }
103 
104 /* Thread states.  */
105 #define BSD_UTHREAD_PS_RUNNING	0
106 #define BSD_UTHREAD_PS_DEAD	18
107 
108 /* Address of the pointer to the the thread structure for the running
109    thread.  */
110 static CORE_ADDR bsd_uthread_thread_run_addr;
111 
112 /* Address of the list of all threads.  */
113 static CORE_ADDR bsd_uthread_thread_list_addr;
114 
115 /* Offsets of various "interesting" bits in the thread structure.  */
116 static int bsd_uthread_thread_state_offset = -1;
117 static int bsd_uthread_thread_next_offset = -1;
118 static int bsd_uthread_thread_ctx_offset;
119 
120 /* Name of shared threads library.  */
121 static const char *bsd_uthread_solib_name;
122 
123 /* Non-zero if the thread startum implemented by this module is active.  */
124 static int bsd_uthread_active;
125 
126 static CORE_ADDR
127 bsd_uthread_lookup_address (const char *name, struct objfile *objfile)
128 {
129   struct minimal_symbol *sym;
130 
131   sym = lookup_minimal_symbol (name, NULL, objfile);
132   if (sym)
133     return SYMBOL_VALUE_ADDRESS (sym);
134 
135   return 0;
136 }
137 
138 static int
139 bsd_uthread_lookup_offset (const char *name, struct objfile *objfile)
140 {
141   CORE_ADDR addr;
142 
143   addr = bsd_uthread_lookup_address (name, objfile);
144   if (addr == 0)
145     return 0;
146 
147   return read_memory_unsigned_integer (addr, 4);
148 }
149 
150 /* If OBJFILE contains the symbols corresponding to one of the
151    supported user-level threads libraries, activate the thread stratum
152    implemented by this module.  */
153 
154 static int
155 bsd_uthread_activate (struct objfile *objfile)
156 {
157   struct gdbarch *gdbarch = current_gdbarch;
158   struct bsd_uthread_ops *ops = gdbarch_data (gdbarch, bsd_uthread_data);
159 
160   /* Skip if the thread stratum has already been activated.  */
161   if (bsd_uthread_active)
162     return 0;
163 
164   /* There's no point in enabling this module if no
165      architecture-specific operations are provided.  */
166   if (!ops->supply_uthread)
167     return 0;
168 
169   bsd_uthread_thread_run_addr =
170     bsd_uthread_lookup_address ("_thread_run", objfile);
171   if (bsd_uthread_thread_run_addr == 0)
172     return 0;
173 
174   bsd_uthread_thread_list_addr =
175     bsd_uthread_lookup_address ("_thread_list", objfile);
176   if (bsd_uthread_thread_list_addr == 0)
177     return 0;
178 
179   bsd_uthread_thread_state_offset =
180     bsd_uthread_lookup_offset ("_thread_state_offset", objfile);
181   if (bsd_uthread_thread_state_offset == 0)
182     return 0;
183 
184   bsd_uthread_thread_next_offset =
185     bsd_uthread_lookup_offset ("_thread_next_offset", objfile);
186   if (bsd_uthread_thread_next_offset == 0)
187     return 0;
188 
189   bsd_uthread_thread_ctx_offset =
190     bsd_uthread_lookup_offset ("_thread_ctx_offset", objfile);
191 
192   push_target (bsd_uthread_ops_hack);
193   bsd_uthread_active = 1;
194   return 1;
195 }
196 
197 /* Deactivate the thread stratum implemented by this module.  */
198 
199 static void
200 bsd_uthread_deactivate (void)
201 {
202   /* Skip if the thread stratum has already been deactivated.  */
203   if (!bsd_uthread_active)
204     return;
205 
206   bsd_uthread_active = 0;
207   unpush_target (bsd_uthread_ops_hack);
208 
209   bsd_uthread_thread_run_addr = 0;
210   bsd_uthread_thread_list_addr = 0;
211   bsd_uthread_thread_state_offset = 0;
212   bsd_uthread_thread_next_offset = 0;
213   bsd_uthread_thread_ctx_offset = 0;
214   bsd_uthread_solib_name = NULL;
215 }
216 
217 void
218 bsd_uthread_inferior_created (struct target_ops *ops, int from_tty)
219 {
220   bsd_uthread_activate (NULL);
221 }
222 
223 /* Likely candidates for the threads library.  */
224 static const char *bsd_uthread_solib_names[] =
225 {
226   "/usr/lib/libc_r.so",		/* FreeBSD */
227   "/usr/lib/libpthread.so",	/* OpenBSD */
228   NULL
229 };
230 
231 void
232 bsd_uthread_solib_loaded (struct so_list *so)
233 {
234   const char **names = bsd_uthread_solib_names;
235 
236   for (names = bsd_uthread_solib_names; *names; names++)
237     {
238       if (strncmp (so->so_original_name, *names, strlen (*names)) == 0)
239 	{
240 	  solib_read_symbols (so, so->from_tty);
241 
242 	  if (bsd_uthread_activate (so->objfile))
243 	    {
244 	      bsd_uthread_solib_name = so->so_original_name;
245 	      return;
246 	    }
247 	}
248     }
249 }
250 
251 void
252 bsd_uthread_solib_unloaded (struct so_list *so)
253 {
254   if (!bsd_uthread_solib_name)
255     return;
256 
257   if (strcmp (so->so_original_name, bsd_uthread_solib_name) == 0)
258     bsd_uthread_deactivate ();
259 }
260 
261 static void
262 bsd_uthread_mourn_inferior (void)
263 {
264   find_target_beneath (bsd_uthread_ops_hack)->to_mourn_inferior ();
265   bsd_uthread_deactivate ();
266 }
267 
268 static void
269 bsd_uthread_fetch_registers (int regnum)
270 {
271   struct gdbarch *gdbarch = current_gdbarch;
272   struct bsd_uthread_ops *ops = gdbarch_data (gdbarch, bsd_uthread_data);
273   CORE_ADDR addr = ptid_get_tid (inferior_ptid);
274   CORE_ADDR active_addr;
275 
276   /* Always fetch the appropriate registers from the layer beneath.  */
277   find_target_beneath (bsd_uthread_ops_hack)->to_fetch_registers (regnum);
278 
279   /* FIXME: That might have gotten us more than we asked for.  Make
280      sure we overwrite all relevant registers with values from the
281      thread structure.  This can go once we fix the underlying target.  */
282   regnum = -1;
283 
284   active_addr = read_memory_typed_address (bsd_uthread_thread_run_addr,
285 					   builtin_type_void_data_ptr);
286   if (addr != 0 && addr != active_addr)
287     {
288       bsd_uthread_check_magic (addr);
289       ops->supply_uthread (current_regcache, regnum,
290 			   addr, bsd_uthread_thread_ctx_offset);
291     }
292 }
293 
294 static void
295 bsd_uthread_store_registers (int regnum)
296 {
297   struct gdbarch *gdbarch = current_gdbarch;
298   struct bsd_uthread_ops *ops = gdbarch_data (gdbarch, bsd_uthread_data);
299   CORE_ADDR addr = ptid_get_tid (inferior_ptid);
300   CORE_ADDR active_addr;
301 
302   active_addr = read_memory_typed_address (bsd_uthread_thread_run_addr,
303 					   builtin_type_void_data_ptr);
304   if (addr != 0 && addr != active_addr)
305     {
306       bsd_uthread_check_magic (addr);
307       ops->collect_uthread (current_regcache, regnum,
308 			    addr, bsd_uthread_thread_ctx_offset);
309     }
310   else
311     {
312       /* Updating the thread that is currently running; pass the
313          request to the layer beneath.  */
314       find_target_beneath (bsd_uthread_ops_hack)->to_store_registers (regnum);
315     }
316 }
317 
318 /* FIXME: This function is only there because otherwise GDB tries to
319    invoke deprecate_xfer_memory.  */
320 
321 static LONGEST
322 bsd_uthread_xfer_partial (struct target_ops *ops, enum target_object object,
323 			  const char *annex, void *readbuf,
324 			  const void *writebuf,
325 			  ULONGEST offset, LONGEST len)
326 {
327   gdb_assert (ops->beneath->to_xfer_partial);
328   return ops->beneath->to_xfer_partial (ops->beneath, object, annex, readbuf,
329 					writebuf, offset, len);
330 }
331 
332 static ptid_t
333 bsd_uthread_wait (ptid_t ptid, struct target_waitstatus *status)
334 {
335   CORE_ADDR addr;
336 
337   /* Pass the request to the layer beneath.  */
338   ptid = find_target_beneath (bsd_uthread_ops_hack)->to_wait (ptid, status);
339 
340   /* Fetch the corresponding thread ID, and augment the returned
341      process ID with it.  */
342   addr = read_memory_typed_address (bsd_uthread_thread_run_addr,
343 				    builtin_type_void_data_ptr);
344   if (addr != 0)
345     {
346       char buf[4];
347 
348       /* FIXME: For executables linked statically with the threads
349          library, we end up here before the program has actually been
350          executed.  In that case ADDR will be garbage since it has
351          been read from the wrong virtual memory image.  */
352       if (target_read_memory (addr, buf, 4) == 0)
353 	{
354 	  ULONGEST magic = extract_unsigned_integer (buf, 4);
355 	  if (magic == BSD_UTHREAD_PTHREAD_MAGIC)
356 	    ptid = ptid_build (ptid_get_pid (ptid), 0, addr);
357 	}
358     }
359 
360   /* HACK: Twiddle INFERIOR_PTID such that the initial thread of a
361      process isn't recognized as a new thread.  */
362   if (ptid_get_tid (ptid) != 0 && !in_thread_list (ptid)
363       && ptid_get_tid (inferior_ptid) == 0)
364     {
365       add_thread (ptid);
366       inferior_ptid = ptid;
367     }
368 
369   return ptid;
370 }
371 
372 static void
373 bsd_uthread_resume (ptid_t ptid, int step, enum target_signal sig)
374 {
375   /* Pass the request to the layer beneath.  */
376   find_target_beneath (bsd_uthread_ops_hack)->to_resume (ptid, step, sig);
377 }
378 
379 static int
380 bsd_uthread_thread_alive (ptid_t ptid)
381 {
382   CORE_ADDR addr = ptid_get_tid (inferior_ptid);
383 
384   if (addr != 0)
385     {
386       int offset = bsd_uthread_thread_state_offset;
387       ULONGEST state;
388 
389       bsd_uthread_check_magic (addr);
390 
391       state = read_memory_unsigned_integer (addr + offset, 4);
392       if (state == BSD_UTHREAD_PS_DEAD)
393 	return 0;
394     }
395 
396   return find_target_beneath (bsd_uthread_ops_hack)->to_thread_alive (ptid);
397 }
398 
399 static void
400 bsd_uthread_find_new_threads (void)
401 {
402   pid_t pid = ptid_get_pid (inferior_ptid);
403   int offset = bsd_uthread_thread_next_offset;
404   CORE_ADDR addr;
405 
406   addr = read_memory_typed_address (bsd_uthread_thread_list_addr,
407 				    builtin_type_void_data_ptr);
408   while (addr != 0)
409     {
410       ptid_t ptid = ptid_build (pid, 0, addr);
411 
412       if (!in_thread_list (ptid))
413 	add_thread (ptid);
414 
415       addr = read_memory_typed_address (addr + offset,
416 					builtin_type_void_data_ptr);
417     }
418 }
419 
420 /* Possible states a thread can be in.  */
421 static char *bsd_uthread_state[] =
422 {
423   "RUNNING",
424   "SIGTHREAD",
425   "MUTEX_WAIT",
426   "COND_WAIT",
427   "FDLR_WAIT",
428   "FDLW_WAIT",
429   "FDR_WAIT",
430   "FDW_WAIT",
431   "FILE_WAIT",
432   "POLL_WAIT",
433   "SELECT_WAIT",
434   "SLEEP_WAIT",
435   "WAIT_WAIT",
436   "SIGSUSPEND",
437   "SIGWAIT",
438   "SPINBLOCK",
439   "JOIN",
440   "SUSPENDED",
441   "DEAD",
442   "DEADLOCK"
443 };
444 
445 /* Return a string describing th state of the thread specified by
446    INFO.  */
447 
448 static char *
449 bsd_uthread_extra_thread_info (struct thread_info *info)
450 {
451   CORE_ADDR addr = ptid_get_tid (info->ptid);
452 
453   if (addr != 0)
454     {
455       int offset = bsd_uthread_thread_state_offset;
456       ULONGEST state;
457 
458       state = read_memory_unsigned_integer (addr + offset, 4);
459       if (state < ARRAY_SIZE (bsd_uthread_state))
460 	return bsd_uthread_state[state];
461     }
462 
463   return NULL;
464 }
465 
466 static char *
467 bsd_uthread_pid_to_str (ptid_t ptid)
468 {
469   if (ptid_get_tid (ptid) != 0)
470     {
471       static char buf[64];
472 
473       xsnprintf (buf, sizeof buf, "process %d, thread 0x%lx",
474 		 ptid_get_pid (ptid), ptid_get_tid (ptid));
475       return buf;
476     }
477 
478   return normal_pid_to_str (ptid);
479 }
480 
481 struct target_ops *
482 bsd_uthread_target (void)
483 {
484   struct target_ops *t = XZALLOC (struct target_ops);
485 
486   t->to_shortname = "bsd-uthreads";
487   t->to_longname = "BSD user-level threads";
488   t->to_doc = "BSD user-level threads";
489   t->to_mourn_inferior = bsd_uthread_mourn_inferior;
490   t->to_fetch_registers = bsd_uthread_fetch_registers;
491   t->to_store_registers = bsd_uthread_store_registers;
492   t->to_xfer_partial = bsd_uthread_xfer_partial;
493   t->to_wait = bsd_uthread_wait;
494   t->to_resume = bsd_uthread_resume;
495   t->to_thread_alive = bsd_uthread_thread_alive;
496   t->to_find_new_threads = bsd_uthread_find_new_threads;
497   t->to_extra_thread_info = bsd_uthread_extra_thread_info;
498   t->to_pid_to_str = bsd_uthread_pid_to_str;
499   t->to_stratum = thread_stratum;
500   t->to_magic = OPS_MAGIC;
501   bsd_uthread_ops_hack = t;
502 
503   return t;
504 }
505 
506 void
507 _initialize_bsd_uthread (void)
508 {
509   add_target (bsd_uthread_target ());
510 
511   bsd_uthread_data = gdbarch_data_register_pre_init (bsd_uthread_init);
512 
513   observer_attach_inferior_created (bsd_uthread_inferior_created);
514   observer_attach_solib_loaded (bsd_uthread_solib_loaded);
515   observer_attach_solib_unloaded (bsd_uthread_solib_unloaded);
516 }
517