Kill pthread_ops_hack
[external/binutils.git] / gdb / dec-thread.c
1 /* Copyright (C) 2008 Free Software Foundation, Inc.
2
3    This file is part of GDB.
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18 #include "defs.h"
19 #include "command.h"
20 #include "gdbcmd.h"
21 #include "target.h"
22 #include "observer.h"
23 #include <sys/procfs.h>
24 #include "gregset.h"
25 #include "regcache.h"
26 #include "inferior.h"
27 #include "gdbthread.h"
28
29 #include <pthread_debug.h>
30
31 /* Print debugging traces if set to non-zero.  */
32 static int debug_dec_thread = 0;
33
34 /* Non-zero if the dec-thread layer is active.  */
35 static int dec_thread_active = 0;
36
37 /* The pthread_debug context.  */
38 pthreadDebugContext_t debug_context;
39
40 /* The dec-thread target_ops structure.  */
41 static struct target_ops dec_thread_ops;
42
43 /* A copy of the target_ops over which our dec_thread_ops is pushed.  */
44 static struct target_ops base_target;
45
46 /* Print a debug trace if DEBUG_DEC_THREAD is set (its value is adjusted
47    by the user using "set debug dec-thread ...").  */
48
49 static void
50 debug (char *format, ...)
51 {
52   if (debug_dec_thread)
53     {
54       va_list args;
55
56       va_start (args, format);
57       printf_unfiltered ("DEC Threads: ");
58       vprintf_unfiltered (format, args);
59       printf_unfiltered ("\n");
60       va_end (args);
61     }
62 }
63
64 /* pthread debug callbacks.  */
65
66 static int
67 suspend_clbk (void *caller_context)
68 {
69   return ESUCCESS;
70 }
71
72 static int
73 resume_clbk (void *caller_context)
74 {
75   return ESUCCESS;
76
77
78 static int
79 hold_clbk (void *caller_context, pthreadDebugKId_t kernel_tid)
80
81   return ESUCCESS;
82 }
83
84 static int
85 unhold_clbk (void *caller_context, pthreadDebugKId_t kernel_tid)
86 {
87   return ESUCCESS;
88 }
89
90 static int
91 read_clbk (void *caller_context, void *address, void *buffer,
92            unsigned long size)
93 {
94   int status = target_read_memory ((CORE_ADDR) address, buffer, size);
95
96   if (status != 0)
97     return EINVAL;
98
99   return ESUCCESS;
100 }
101
102 static int
103 write_clbk (void *caller_context, void *address, void *buffer,
104             unsigned long size)
105 {
106   int status = target_write_memory ((CORE_ADDR) address, buffer, size);
107   
108   if (status != 0)
109     return EINVAL;
110
111   return ESUCCESS;
112 }
113
114 /* Get integer regs */
115
116 static int
117 get_reg_clbk(void *caller_context, pthreadDebugGetRegRtn_t regs,
118              pthreadDebugKId_t kernel_tid)
119 {
120   debug ("get_reg_clbk");
121
122   /* Not sure that we actually need to do anything in this callback.  */
123   return ESUCCESS;
124 }
125
126 /* Set integer regs */
127
128 static int
129 set_reg_clbk(void *caller_context, const pthreadDebugRegs_t *regs,
130              pthreadDebugKId_t kernel_tid)
131 {
132   debug ("set_reg_clbk");
133
134   /* Not sure that we actually need to do anything in this callback.  */
135   return ESUCCESS;
136 }
137
138 static int
139 output_clbk (void *caller_context, char *line)
140 {
141   printf_filtered ("%s\n", line);
142   return ESUCCESS;
143 }
144
145 static int
146 error_clbk (void *caller_context, char *line)
147 {
148   fprintf_filtered (gdb_stderr, "%s\n", line);
149   return ESUCCESS;
150 }
151
152 /* Get floating-point regs.  */
153
154 static int
155 get_fpreg_clbk (void *caller_context, pthreadDebugFregs_p fregs,
156                 pthreadDebugKId_t kernel_tid)
157 {
158   debug ("get_fpreg_clbk");
159
160   /* Not sure that we actually need to do anything in this callback.  */
161   return ESUCCESS;
162 }
163
164 /* Set floating-point regs.  */
165
166 static int
167 set_fpreg_clbk (void *caller_context, const pthreadDebugFregs_t *fregs,
168                 pthreadDebugKId_t kernel_tid)
169 {
170   debug ("set_fpreg_clbk");
171
172   /* Not sure that we actually need to do anything in this callback.  */
173   return ESUCCESS;
174 }
175
176 static void *
177 malloc_clbk (void *caller_context, size_t size)
178 {
179   return xmalloc (size);
180 }
181
182 static void
183 free_clbk (void *caller_context, void *address)
184 {
185   xfree (address);
186 }
187
188 static int
189 kthdinfo_clbk (pthreadDebugClient_t caller_context,
190                pthreadDebugKId_t kernel_tid,
191                pthreadDebugKThreadInfo_p thread_info)
192 {
193   return ENOTSUP;
194 }
195
196 static int
197 speckthd_clbk (pthreadDebugClient_t caller_context,
198                pthreadDebugSpecialType_t type,
199                pthreadDebugKId_t *kernel_tid)
200 {
201   return ENOTSUP;
202 }
203
204 static pthreadDebugCallbacks_t debug_callbacks =
205 {
206   PTHREAD_DEBUG_VERSION,
207   (pthreadDebugGetMemRtn_t) read_clbk,
208   (pthreadDebugSetMemRtn_t) write_clbk,
209   suspend_clbk,
210   resume_clbk,
211   kthdinfo_clbk,
212   hold_clbk,
213   unhold_clbk,
214   (pthreadDebugGetFregRtn_t) get_fpreg_clbk,
215   (pthreadDebugSetFregRtn_t) set_fpreg_clbk,
216   (pthreadDebugGetRegRtn_t) get_reg_clbk,
217   (pthreadDebugSetRegRtn_t) set_reg_clbk,
218   (pthreadDebugOutputRtn_t) output_clbk,
219   (pthreadDebugOutputRtn_t) error_clbk,
220   malloc_clbk,
221   free_clbk,
222   speckthd_clbk
223 };
224
225 /* Activate thread support if appropriate.  Do nothing if thread
226    support is already active.  */
227
228 static void
229 enable_dec_thread (void)
230 {
231   struct minimal_symbol *msym;
232   void* caller_context;
233   int status;
234
235   /* If already active, nothing more to do.  */
236   if (dec_thread_active)
237     return;
238
239   msym = lookup_minimal_symbol ("__pthread_dbg_symtable", NULL, NULL);
240   if (msym == NULL)
241     {
242       debug ("enable_dec_thread: No __pthread_dbg_symtable");
243       return;
244     }
245
246   status = pthreadDebugContextInit (&caller_context, &debug_callbacks,
247                                     (void *) SYMBOL_VALUE_ADDRESS (msym),
248                                     &debug_context);
249   if (status != ESUCCESS)
250     {
251       debug ("enable_dec_thread: pthreadDebugContextInit -> %d",
252              status);
253       return;
254     }
255
256   base_target = current_target;
257   push_target (&dec_thread_ops);
258   dec_thread_active = 1;
259
260   debug ("enable_dec_thread: Thread support enabled.");
261 }
262
263 /* Deactivate thread support.  Do nothing is thread support is
264    already inactive.  */
265
266 static void
267 disable_dec_thread (void)
268 {
269   if (!dec_thread_active)
270     return;
271
272   pthreadDebugContextDestroy (debug_context);
273   unpush_target (&dec_thread_ops);
274   dec_thread_active = 0;
275 }
276
277 /* A structure that contains a thread ID and is associated
278    pthreadDebugThreadInfo_t data.  */
279
280 struct dec_thread_info
281 {
282   pthreadDebugId_t thread;
283   pthreadDebugThreadInfo_t info;
284 };
285 typedef struct dec_thread_info dec_thread_info_s;
286
287 /* The list of user threads.  */
288
289 DEF_VEC_O (dec_thread_info_s);
290 VEC(dec_thread_info_s) *dec_thread_list;
291
292 /* Release the memory used by the given VECP thread list pointer.
293    Then set *VECP to NULL.  */
294
295 static void
296 free_dec_thread_info_vec (VEC(dec_thread_info_s) **vecp)
297 {
298   int i;
299   struct dec_thread_info *item;
300   VEC(dec_thread_info_s) *vec = *vecp;
301
302   for (i = 0; VEC_iterate (dec_thread_info_s, vec, i, item); i++)
303      xfree (item);
304   VEC_free (dec_thread_info_s, vec);
305   *vecp = NULL;
306 }
307
308 /* Return a thread's ptid given its associated INFO.  */
309
310 static ptid_t
311 ptid_build_from_info (struct dec_thread_info info)
312 {
313   int pid = ptid_get_pid (inferior_ptid);
314
315   return ptid_build (pid, 0, (long) info.thread);
316 }
317
318 /* Recompute the list of user threads and store the result in
319    DEC_THREAD_LIST.  */
320
321 static void
322 update_dec_thread_list (void)
323 {
324   pthreadDebugId_t thread;
325   pthreadDebugThreadInfo_t info;
326   int res;
327
328   free_dec_thread_info_vec (&dec_thread_list);
329   res = pthreadDebugThdSeqInit (debug_context, &thread);
330   while (res == ESUCCESS)
331     {
332
333       res = pthreadDebugThdGetInfo (debug_context, thread, &info);
334       if (res != ESUCCESS)
335         warning (_("unable to get thread info, ignoring thread %ld"),
336                    thread);
337       else if (info.kind == PTHREAD_DEBUG_THD_KIND_INITIAL
338                || info.kind == PTHREAD_DEBUG_THD_KIND_NORMAL)
339         {
340           struct dec_thread_info *item = 
341             xmalloc (sizeof (struct dec_thread_info));
342
343           item->thread = thread;
344           item->info = info;
345           VEC_safe_push (dec_thread_info_s, dec_thread_list, item);
346         }
347       res = pthreadDebugThdSeqNext (debug_context, &thread);
348     }
349   pthreadDebugThdSeqDestroy (debug_context);
350 }
351
352 /* A callback to count the number of threads known to GDB.  */
353
354 static int
355 dec_thread_count_gdb_threads (struct thread_info *ignored, void *context)
356 {
357   int *count = (int *) context;
358
359   *count++;
360   return 0;
361 }
362
363 /* A callback that saves the given thread INFO at the end of an
364    array.  The end of the array is given in the CONTEXT and is
365    incremented once the info has been added.  */
366
367 static int
368 dec_thread_add_gdb_thread (struct thread_info *info, void *context)
369 {
370   struct thread_info ***listp = (struct thread_info ***) context;
371   
372   **listp = info;
373   *listp++;
374   return 0;
375 }
376
377 /* Resynchronize the list of threads known by GDB with the actual
378    list of threads reported by libpthread_debug.  */
379
380 static void
381 resync_thread_list (void)
382 {
383   int i;
384   struct dec_thread_info *info;
385   int num_gdb_threads = 0;
386   struct thread_info **gdb_thread_list;
387   struct thread_info **next_thread_info;
388
389   update_dec_thread_list ();
390
391   /* Add new threads.  */
392
393   for (i = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, i, info);
394        i++)
395     {
396       ptid_t ptid = ptid_build_from_info (*info);
397
398       if (!in_thread_list (ptid))
399         add_thread (ptid);
400     }
401
402   /* Remove threads that no longer exist.  To help with the search,
403      we build an array of GDB threads, and then iterate over this
404      array.  */
405
406   iterate_over_threads (dec_thread_count_gdb_threads,
407                         (void *) &num_gdb_threads);
408   gdb_thread_list = alloca (num_gdb_threads * sizeof (struct thread_info *));
409   next_thread_info = gdb_thread_list;
410   iterate_over_threads (dec_thread_add_gdb_thread, (void *) &next_thread_info);
411   for (i = 0; i < num_gdb_threads; i++)
412     {
413       int j;
414
415       for (j = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, j, info);
416            j++)
417         if (ptid_equal (gdb_thread_list[i]->ptid,
418                          ptid_build_from_info (*info)))
419           break;
420       delete_thread (gdb_thread_list[i]->ptid);
421     }
422 }
423
424 /* The "to_detach" method of the dec_thread_ops.  */
425
426 static void
427 dec_thread_detach (char *args, int from_tty)
428 {   
429   debug ("dec_thread_detach");
430
431   disable_dec_thread ();
432   base_target.to_detach (&base_target, args, from_tty);
433 }
434
435 /* Return the ptid of the thread that is currently active.  */
436
437 static ptid_t
438 get_active_ptid (void)
439 {
440   int i;
441   struct dec_thread_info *info;
442
443   for (i = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, i, info);
444        i++)
445     if (info->info.state == PTHREAD_DEBUG_STATE_RUNNING)
446       return ptid_build_from_info (*info);
447
448   /* No active thread found.  This can happen when the program
449      has just exited.  */
450   return null_ptid;
451 }
452
453 /* The "to_wait" method of the dec_thread_ops.  */
454
455 static ptid_t
456 dec_thread_wait (ptid_t ptid, struct target_waitstatus *status)
457 {
458   ptid_t active_ptid;
459
460   debug ("dec_thread_wait");
461
462   ptid = base_target.to_wait (ptid, status);
463
464   /* The ptid returned by the base_target is the ptid of the process.
465      We need to find which thread is currently active and return its
466      ptid.  */
467   resync_thread_list ();
468   active_ptid = get_active_ptid ();
469   if (ptid_equal (active_ptid, null_ptid))
470     return ptid;
471   return active_ptid;
472 }
473
474 /* Fetch the general purpose and floating point registers for the given
475    thread TID, and store the result in GREGSET and FPREGSET.  Return
476    zero if successful.  */
477
478 static int
479 dec_thread_get_regsets (pthreadDebugId_t tid, gdb_gregset_t *gregset,
480                         gdb_fpregset_t *fpregset)
481 {
482   int res;
483   pthreadDebugRegs_t regs;
484   pthreadDebugFregs_t fregs;
485
486   res = pthreadDebugThdGetReg (debug_context, tid, &regs);
487   if (res != ESUCCESS)
488     {
489       debug ("dec_thread_fetch_registers: pthreadDebugThdGetReg -> %d", res);
490       return -1;
491     }
492   memcpy (gregset->regs, &regs, sizeof (regs));
493
494   res = pthreadDebugThdGetFreg (debug_context, tid, &fregs);
495   if (res != ESUCCESS)
496     {
497       debug ("dec_thread_fetch_registers: pthreadDebugThdGetFreg -> %d", res);
498       return -1;
499     }
500   memcpy (fpregset->regs, &fregs, sizeof (fregs));
501
502   return 0;
503 }
504
505 /* The "to_fetch_registers" method of the dec_thread_ops.
506
507    Because the dec-thread debug API doesn't allow us to fetch
508    only one register, we simply ignore regno and fetch+supply all
509    registers.  */
510
511 static void
512 dec_thread_fetch_registers (struct regcache *regcache, int regno)
513 {
514   pthreadDebugId_t tid = ptid_get_tid (inferior_ptid);
515   gregset_t gregset;
516   fpregset_t fpregset;
517   int res;
518
519   debug ("dec_thread_fetch_registers (tid=%ld, regno=%d)", tid, regno);
520
521
522   if (tid == 0 || ptid_equal (inferior_ptid, get_active_ptid ()))
523     {
524       base_target.to_fetch_registers (regcache, regno);
525       return;
526     }
527
528   res = dec_thread_get_regsets (tid, &gregset, &fpregset);
529   if (res != 0)
530     return;
531
532   supply_gregset (regcache, &gregset);
533   supply_fpregset (regcache, &fpregset);
534 }
535
536 /* Store the registers given in GREGSET and FPREGSET into the associated
537    general purpose and floating point registers of thread TID.  Return
538    zero if successful.  */
539
540 static int
541 dec_thread_set_regsets (pthreadDebugId_t tid, gdb_gregset_t gregset,
542                         gdb_fpregset_t fpregset)
543 {
544   int res;
545   pthreadDebugRegs_t regs;
546   pthreadDebugFregs_t fregs;
547
548   memcpy (&regs, gregset.regs, sizeof (regs));
549   res = pthreadDebugThdSetReg (debug_context, tid, &regs);
550   if (res != ESUCCESS)
551     {
552       debug ("dec_thread_fetch_registers: pthreadDebugThdSetReg -> %d", res);
553       return -1;
554     }
555
556   memcpy (&fregs, fpregset.regs, sizeof (fregs));
557   res = pthreadDebugThdSetFreg (debug_context, tid, &fregs);
558   if (res != ESUCCESS)
559     {
560       debug ("dec_thread_fetch_registers: pthreadDebugThdSetFreg -> %d", res);
561       return -1;
562     }
563
564   return 0;
565 }
566
567 /* The "to_store_registers" method of the dec_thread_ops.
568
569    Because the dec-thread debug API doesn't allow us to store
570    just one register, we store all the registers.  */
571
572 static void
573 dec_thread_store_registers (struct regcache *regcache, int regno)
574 {
575   pthreadDebugId_t tid = ptid_get_tid (inferior_ptid);
576   gregset_t gregset;
577   fpregset_t fpregset;
578   int res;
579
580   debug ("dec_thread_store_registers (tid=%ld, regno=%d)", tid, regno);
581
582   if (tid == 0 || ptid_equal (inferior_ptid, get_active_ptid ()))
583     {
584       base_target.to_store_registers (regcache, regno);
585       return;
586     }
587
588   /* FIXME: brobecker/2008-05-28: I wonder if we could simply check
589      in which register set the register is and then only store the
590      registers for that register set, instead of storing both register
591      sets.  */
592   fill_gregset (regcache, &gregset, -1);
593   fill_fpregset (regcache, &fpregset, -1);
594   
595   res = dec_thread_set_regsets (tid, gregset, fpregset);
596   if (res != 0)
597     warning (_("failed to store registers."));
598 }
599
600 /* The "to_mourn_inferior" method of the dec_thread_ops.  */
601
602 static void
603 dec_thread_mourn_inferior (void)
604 {
605   debug ("dec_thread_mourn_inferior");
606
607   disable_dec_thread ();
608   base_target.to_mourn_inferior (&base_target);
609 }
610
611 /* The "to_thread_alive" method of the dec_thread_ops.  */
612 static int
613 dec_thread_thread_alive (ptid_t ptid)
614 {
615   debug ("dec_thread_thread_alive (tid=%ld)", ptid_get_tid (ptid));
616
617   /* The thread list maintained by GDB is up to date, since we update
618      it everytime we stop.   So check this list.  */
619   return in_thread_list (ptid);
620 }
621
622 /* The "to_pid_to_str" method of the dec_thread_ops.  */
623
624 static char *
625 dec_thread_pid_to_str (ptid_t ptid)
626 {
627   static char *ret = NULL;
628
629   if (ptid_get_tid (ptid) == 0)
630     return base_target.to_pid_to_str (ptid);
631
632   /* Free previous return value; a new one will be allocated by
633      xstrprintf().  */
634   xfree (ret);
635
636   ret = xstrprintf (_("Thread %ld"), ptid_get_tid (ptid));
637   return ret;
638 }
639
640 /* A "new-objfile" observer.  Used to activate/deactivate dec-thread
641    support.  */
642
643 static void
644 dec_thread_new_objfile_observer (struct objfile *objfile)
645 {
646   if (objfile != NULL)
647      enable_dec_thread ();
648   else
649      disable_dec_thread ();
650 }
651
652 static void
653 init_dec_thread_ops (void)
654 {
655   dec_thread_ops.to_shortname          = "dec-threads";
656   dec_thread_ops.to_longname           = _("DEC threads support");
657   dec_thread_ops.to_doc                = _("DEC threads support");
658   dec_thread_ops.to_detach             = dec_thread_detach;
659   dec_thread_ops.to_wait               = dec_thread_wait;
660   dec_thread_ops.to_fetch_registers    = dec_thread_fetch_registers;
661   dec_thread_ops.to_store_registers    = dec_thread_store_registers;
662   dec_thread_ops.to_mourn_inferior     = dec_thread_mourn_inferior;
663   dec_thread_ops.to_thread_alive       = dec_thread_thread_alive;
664   dec_thread_ops.to_pid_to_str         = dec_thread_pid_to_str;
665   dec_thread_ops.to_stratum            = thread_stratum;
666   dec_thread_ops.to_magic              = OPS_MAGIC;
667 }
668
669 void
670 _initialize_dec_thread (void)
671 {
672   init_dec_thread_ops ();
673   add_target (&dec_thread_ops);
674
675   observer_attach_new_objfile (dec_thread_new_objfile_observer);
676
677   add_setshow_boolean_cmd ("dec-thread", class_maintenance, &debug_dec_thread,
678                             _("Set debugging of DEC threads module."),
679                             _("Show debugging of DEC threads module."),
680                             _("Enables debugging output (used to debug GDB)."),
681                             NULL, NULL,
682                             &setdebuglist, &showdebuglist);
683 }