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