* linux-nat.c (linux_nat_wait): Adjust.
[platform/upstream/binutils.git] / gdb / dec-thread.c
1 /* Copyright (C) 2008, 2009 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 (struct target_ops *ops,
457                  ptid_t ptid, struct target_waitstatus *status)
458 {
459   ptid_t active_ptid;
460
461   debug ("dec_thread_wait");
462
463   ptid = base_target.to_wait (&base_target, ptid, status);
464
465   /* The ptid returned by the base_target is the ptid of the process.
466      We need to find which thread is currently active and return its
467      ptid.  */
468   resync_thread_list ();
469   active_ptid = get_active_ptid ();
470   if (ptid_equal (active_ptid, null_ptid))
471     return ptid;
472   return active_ptid;
473 }
474
475 /* Fetch the general purpose and floating point registers for the given
476    thread TID, and store the result in GREGSET and FPREGSET.  Return
477    zero if successful.  */
478
479 static int
480 dec_thread_get_regsets (pthreadDebugId_t tid, gdb_gregset_t *gregset,
481                         gdb_fpregset_t *fpregset)
482 {
483   int res;
484   pthreadDebugRegs_t regs;
485   pthreadDebugFregs_t fregs;
486
487   res = pthreadDebugThdGetReg (debug_context, tid, &regs);
488   if (res != ESUCCESS)
489     {
490       debug ("dec_thread_fetch_registers: pthreadDebugThdGetReg -> %d", res);
491       return -1;
492     }
493   memcpy (gregset->regs, &regs, sizeof (regs));
494
495   res = pthreadDebugThdGetFreg (debug_context, tid, &fregs);
496   if (res != ESUCCESS)
497     {
498       debug ("dec_thread_fetch_registers: pthreadDebugThdGetFreg -> %d", res);
499       return -1;
500     }
501   memcpy (fpregset->regs, &fregs, sizeof (fregs));
502
503   return 0;
504 }
505
506 /* The "to_fetch_registers" method of the dec_thread_ops.
507
508    Because the dec-thread debug API doesn't allow us to fetch
509    only one register, we simply ignore regno and fetch+supply all
510    registers.  */
511
512 static void
513 dec_thread_fetch_registers (struct regcache *regcache, int regno)
514 {
515   pthreadDebugId_t tid = ptid_get_tid (inferior_ptid);
516   gregset_t gregset;
517   fpregset_t fpregset;
518   int res;
519
520   debug ("dec_thread_fetch_registers (tid=%ld, regno=%d)", tid, regno);
521
522
523   if (tid == 0 || ptid_equal (inferior_ptid, get_active_ptid ()))
524     {
525       base_target.to_fetch_registers (regcache, regno);
526       return;
527     }
528
529   res = dec_thread_get_regsets (tid, &gregset, &fpregset);
530   if (res != 0)
531     return;
532
533   supply_gregset (regcache, &gregset);
534   supply_fpregset (regcache, &fpregset);
535 }
536
537 /* Store the registers given in GREGSET and FPREGSET into the associated
538    general purpose and floating point registers of thread TID.  Return
539    zero if successful.  */
540
541 static int
542 dec_thread_set_regsets (pthreadDebugId_t tid, gdb_gregset_t gregset,
543                         gdb_fpregset_t fpregset)
544 {
545   int res;
546   pthreadDebugRegs_t regs;
547   pthreadDebugFregs_t fregs;
548
549   memcpy (&regs, gregset.regs, sizeof (regs));
550   res = pthreadDebugThdSetReg (debug_context, tid, &regs);
551   if (res != ESUCCESS)
552     {
553       debug ("dec_thread_fetch_registers: pthreadDebugThdSetReg -> %d", res);
554       return -1;
555     }
556
557   memcpy (&fregs, fpregset.regs, sizeof (fregs));
558   res = pthreadDebugThdSetFreg (debug_context, tid, &fregs);
559   if (res != ESUCCESS)
560     {
561       debug ("dec_thread_fetch_registers: pthreadDebugThdSetFreg -> %d", res);
562       return -1;
563     }
564
565   return 0;
566 }
567
568 /* The "to_store_registers" method of the dec_thread_ops.
569
570    Because the dec-thread debug API doesn't allow us to store
571    just one register, we store all the registers.  */
572
573 static void
574 dec_thread_store_registers (struct regcache *regcache, int regno)
575 {
576   pthreadDebugId_t tid = ptid_get_tid (inferior_ptid);
577   gregset_t gregset;
578   fpregset_t fpregset;
579   int res;
580
581   debug ("dec_thread_store_registers (tid=%ld, regno=%d)", tid, regno);
582
583   if (tid == 0 || ptid_equal (inferior_ptid, get_active_ptid ()))
584     {
585       base_target.to_store_registers (regcache, regno);
586       return;
587     }
588
589   /* FIXME: brobecker/2008-05-28: I wonder if we could simply check
590      in which register set the register is and then only store the
591      registers for that register set, instead of storing both register
592      sets.  */
593   fill_gregset (regcache, &gregset, -1);
594   fill_fpregset (regcache, &fpregset, -1);
595   
596   res = dec_thread_set_regsets (tid, gregset, fpregset);
597   if (res != 0)
598     warning (_("failed to store registers."));
599 }
600
601 /* The "to_mourn_inferior" method of the dec_thread_ops.  */
602
603 static void
604 dec_thread_mourn_inferior (void)
605 {
606   debug ("dec_thread_mourn_inferior");
607
608   disable_dec_thread ();
609   base_target.to_mourn_inferior (&base_target);
610 }
611
612 /* The "to_thread_alive" method of the dec_thread_ops.  */
613 static int
614 dec_thread_thread_alive (ptid_t ptid)
615 {
616   debug ("dec_thread_thread_alive (tid=%ld)", ptid_get_tid (ptid));
617
618   /* The thread list maintained by GDB is up to date, since we update
619      it everytime we stop.   So check this list.  */
620   return in_thread_list (ptid);
621 }
622
623 /* The "to_pid_to_str" method of the dec_thread_ops.  */
624
625 static char *
626 dec_thread_pid_to_str (struct target_ops *ops, ptid_t ptid)
627 {
628   static char *ret = NULL;
629
630   if (ptid_get_tid (ptid) == 0)
631     return base_target.to_pid_to_str (&base_target, ptid);
632
633   /* Free previous return value; a new one will be allocated by
634      xstrprintf().  */
635   xfree (ret);
636
637   ret = xstrprintf (_("Thread %ld"), ptid_get_tid (ptid));
638   return ret;
639 }
640
641 /* A "new-objfile" observer.  Used to activate/deactivate dec-thread
642    support.  */
643
644 static void
645 dec_thread_new_objfile_observer (struct objfile *objfile)
646 {
647   if (objfile != NULL)
648      enable_dec_thread ();
649   else
650      disable_dec_thread ();
651 }
652
653 static void
654 init_dec_thread_ops (void)
655 {
656   dec_thread_ops.to_shortname          = "dec-threads";
657   dec_thread_ops.to_longname           = _("DEC threads support");
658   dec_thread_ops.to_doc                = _("DEC threads support");
659   dec_thread_ops.to_detach             = dec_thread_detach;
660   dec_thread_ops.to_wait               = dec_thread_wait;
661   dec_thread_ops.to_fetch_registers    = dec_thread_fetch_registers;
662   dec_thread_ops.to_store_registers    = dec_thread_store_registers;
663   dec_thread_ops.to_mourn_inferior     = dec_thread_mourn_inferior;
664   dec_thread_ops.to_thread_alive       = dec_thread_thread_alive;
665   dec_thread_ops.to_pid_to_str         = dec_thread_pid_to_str;
666   dec_thread_ops.to_stratum            = thread_stratum;
667   dec_thread_ops.to_magic              = OPS_MAGIC;
668 }
669
670 void
671 _initialize_dec_thread (void)
672 {
673   init_dec_thread_ops ();
674   add_target (&dec_thread_ops);
675
676   observer_attach_new_objfile (dec_thread_new_objfile_observer);
677
678   add_setshow_boolean_cmd ("dec-thread", class_maintenance, &debug_dec_thread,
679                             _("Set debugging of DEC threads module."),
680                             _("Show debugging of DEC threads module."),
681                             _("Enables debugging output (used to debug GDB)."),
682                             NULL, NULL,
683                             &setdebuglist, &showdebuglist);
684 }