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