OSDN Git Service

* gc.h (gc_process_relocs): Call is_section_foldable_candidate to
[pf3gnuchains/pf3gnuchains3x.git] / gdb / dec-thread.c
1 /* Copyright (C) 2008, 2009, 2010 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 is 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 /* Recompute the list of user threads and store the result in
315    DEC_THREAD_LIST.  */
316
317 static void
318 update_dec_thread_list (void)
319 {
320   pthreadDebugId_t thread;
321   pthreadDebugThreadInfo_t info;
322   int res;
323
324   free_dec_thread_info_vec (&dec_thread_list);
325   res = pthreadDebugThdSeqInit (debug_context, &thread);
326   while (res == ESUCCESS)
327     {
328
329       res = pthreadDebugThdGetInfo (debug_context, thread, &info);
330       if (res != ESUCCESS)
331         warning (_("unable to get thread info, ignoring thread %ld"),
332                    thread);
333       else if (info.kind == PTHREAD_DEBUG_THD_KIND_INITIAL
334                || info.kind == PTHREAD_DEBUG_THD_KIND_NORMAL)
335         {
336           struct dec_thread_info *item = 
337             xmalloc (sizeof (struct dec_thread_info));
338
339           item->thread = thread;
340           item->info = info;
341           VEC_safe_push (dec_thread_info_s, dec_thread_list, item);
342         }
343       res = pthreadDebugThdSeqNext (debug_context, &thread);
344     }
345   pthreadDebugThdSeqDestroy (debug_context);
346 }
347
348 /* A callback to count the number of threads known to GDB.  */
349
350 static int
351 dec_thread_count_gdb_threads (struct thread_info *ignored, void *context)
352 {
353   int *count = (int *) context;
354
355   *count++;
356   return 0;
357 }
358
359 /* A callback that saves the given thread INFO at the end of an
360    array.  The end of the array is given in the CONTEXT and is
361    incremented once the info has been added.  */
362
363 static int
364 dec_thread_add_gdb_thread (struct thread_info *info, void *context)
365 {
366   struct thread_info ***listp = (struct thread_info ***) context;
367   
368   **listp = info;
369   *listp++;
370   return 0;
371 }
372
373 /* Resynchronize the list of threads known by GDB with the actual
374    list of threads reported by libpthread_debug.  */
375
376 static void
377 resync_thread_list (void)
378 {
379   int i;
380   struct dec_thread_info *info;
381   int num_gdb_threads = 0;
382   struct thread_info **gdb_thread_list;
383   struct thread_info **next_thread_info;
384
385   update_dec_thread_list ();
386
387   /* Add new threads.  */
388
389   for (i = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, i, info);
390        i++)
391     {
392       ptid_t ptid = ptid_build_from_info (*info);
393
394       if (!in_thread_list (ptid))
395         add_thread (ptid);
396     }
397
398   /* Remove threads that no longer exist.  To help with the search,
399      we build an array of GDB threads, and then iterate over this
400      array.  */
401
402   iterate_over_threads (dec_thread_count_gdb_threads,
403                         (void *) &num_gdb_threads);
404   gdb_thread_list = alloca (num_gdb_threads * sizeof (struct thread_info *));
405   next_thread_info = gdb_thread_list;
406   iterate_over_threads (dec_thread_add_gdb_thread, (void *) &next_thread_info);
407   for (i = 0; i < num_gdb_threads; i++)
408     {
409       int j;
410
411       for (j = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, j, info);
412            j++)
413         if (ptid_equal (gdb_thread_list[i]->ptid,
414                          ptid_build_from_info (*info)))
415           break;
416       delete_thread (gdb_thread_list[i]->ptid);
417     }
418 }
419
420 /* The "to_detach" method of the dec_thread_ops.  */
421
422 static void
423 dec_thread_detach (struct target_ops *ops, char *args, int from_tty)
424 {   
425   struct target_ops *beneath = find_target_beneath (ops);
426
427   debug ("dec_thread_detach");
428
429   disable_dec_thread ();
430   beneath->to_detach (beneath, args, from_tty);
431 }
432
433 /* Return the ptid of the thread that is currently active.  */
434
435 static ptid_t
436 get_active_ptid (void)
437 {
438   int i;
439   struct dec_thread_info *info;
440
441   for (i = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, i, info);
442        i++)
443     if (info->info.state == PTHREAD_DEBUG_STATE_RUNNING)
444       return ptid_build_from_info (*info);
445
446   /* No active thread found.  This can happen when the program
447      has just exited.  */
448   return null_ptid;
449 }
450
451 /* The "to_wait" method of the dec_thread_ops.  */
452
453 static ptid_t
454 dec_thread_wait (struct target_ops *ops,
455                  ptid_t ptid, struct target_waitstatus *status, int options)
456 {
457   ptid_t active_ptid;
458   struct target_ops *beneath = find_target_beneath (ops);
459
460   debug ("dec_thread_wait");
461
462   ptid = beneath->to_wait (beneath, ptid, status, options);
463
464   /* The ptid returned by the target beneath us is the ptid of the process.
465      We need to find which thread is currently active and return its ptid.  */
466   resync_thread_list ();
467   active_ptid = get_active_ptid ();
468   if (ptid_equal (active_ptid, null_ptid))
469     return ptid;
470   return active_ptid;
471 }
472
473 /* Fetch the general purpose and floating point registers for the given
474    thread TID, and store the result in GREGSET and FPREGSET.  Return
475    zero if successful.  */
476
477 static int
478 dec_thread_get_regsets (pthreadDebugId_t tid, gdb_gregset_t *gregset,
479                         gdb_fpregset_t *fpregset)
480 {
481   int res;
482   pthreadDebugRegs_t regs;
483   pthreadDebugFregs_t fregs;
484
485   res = pthreadDebugThdGetReg (debug_context, tid, &regs);
486   if (res != ESUCCESS)
487     {
488       debug ("dec_thread_get_regsets: pthreadDebugThdGetReg -> %d", res);
489       return -1;
490     }
491   memcpy (gregset->regs, &regs, sizeof (regs));
492
493   res = pthreadDebugThdGetFreg (debug_context, tid, &fregs);
494   if (res != ESUCCESS)
495     {
496       debug ("dec_thread_get_regsets: pthreadDebugThdGetFreg -> %d", res);
497       return -1;
498     }
499   memcpy (fpregset->regs, &fregs, sizeof (fregs));
500
501   return 0;
502 }
503
504 /* The "to_fetch_registers" method of the dec_thread_ops.
505
506    Because the dec-thread debug API doesn't allow us to fetch
507    only one register, we simply ignore regno and fetch+supply all
508    registers.  */
509
510 static void
511 dec_thread_fetch_registers (struct target_ops *ops,
512                             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       struct target_ops *beneath = find_target_beneath (ops);
525
526       beneath->to_fetch_registers (beneath, regcache, regno);
527       return;
528     }
529
530   res = dec_thread_get_regsets (tid, &gregset, &fpregset);
531   if (res != 0)
532     return;
533
534   supply_gregset (regcache, &gregset);
535   supply_fpregset (regcache, &fpregset);
536 }
537
538 /* Store the registers given in GREGSET and FPREGSET into the associated
539    general purpose and floating point registers of thread TID.  Return
540    zero if successful.  */
541
542 static int
543 dec_thread_set_regsets (pthreadDebugId_t tid, gdb_gregset_t gregset,
544                         gdb_fpregset_t fpregset)
545 {
546   int res;
547   pthreadDebugRegs_t regs;
548   pthreadDebugFregs_t fregs;
549
550   memcpy (&regs, gregset.regs, sizeof (regs));
551   res = pthreadDebugThdSetReg (debug_context, tid, &regs);
552   if (res != ESUCCESS)
553     {
554       debug ("dec_thread_set_regsets: pthreadDebugThdSetReg -> %d", res);
555       return -1;
556     }
557
558   memcpy (&fregs, fpregset.regs, sizeof (fregs));
559   res = pthreadDebugThdSetFreg (debug_context, tid, &fregs);
560   if (res != ESUCCESS)
561     {
562       debug ("dec_thread_set_regsets: pthreadDebugThdSetFreg -> %d", res);
563       return -1;
564     }
565
566   return 0;
567 }
568
569 /* The "to_store_registers" method of the dec_thread_ops.
570
571    Because the dec-thread debug API doesn't allow us to store
572    just one register, we store all the registers.  */
573
574 static void
575 dec_thread_store_registers (struct target_ops *ops,
576                             struct regcache *regcache, int regno)
577 {
578   pthreadDebugId_t tid = ptid_get_tid (inferior_ptid);
579   gregset_t gregset;
580   fpregset_t fpregset;
581   int res;
582
583   debug ("dec_thread_store_registers (tid=%ld, regno=%d)", tid, regno);
584
585   if (tid == 0 || ptid_equal (inferior_ptid, get_active_ptid ()))
586     {
587       struct target_ops *beneath = find_target_beneath (ops);
588
589       beneath->to_store_registers (beneath, regcache, regno);
590       return;
591     }
592
593   /* FIXME: brobecker/2008-05-28: I wonder if we could simply check
594      in which register set the register is and then only store the
595      registers for that register set, instead of storing both register
596      sets.  */
597   fill_gregset (regcache, &gregset, -1);
598   fill_fpregset (regcache, &fpregset, -1);
599   
600   res = dec_thread_set_regsets (tid, gregset, fpregset);
601   if (res != 0)
602     warning (_("failed to store registers."));
603 }
604
605 /* The "to_mourn_inferior" method of the dec_thread_ops.  */
606
607 static void
608 dec_thread_mourn_inferior (struct target_ops *ops)
609 {
610   struct target_ops *beneath = find_target_beneath (ops);
611
612   debug ("dec_thread_mourn_inferior");
613
614   disable_dec_thread ();
615   beneath->to_mourn_inferior (beneath);
616 }
617
618 /* The "to_thread_alive" method of the dec_thread_ops.  */
619 static int
620 dec_thread_thread_alive (struct target_ops *ops, ptid_t ptid)
621 {
622   debug ("dec_thread_thread_alive (tid=%ld)", ptid_get_tid (ptid));
623
624   /* The thread list maintained by GDB is up to date, since we update
625      it everytime we stop.   So check this list.  */
626   return in_thread_list (ptid);
627 }
628
629 /* The "to_pid_to_str" method of the dec_thread_ops.  */
630
631 static char *
632 dec_thread_pid_to_str (struct target_ops *ops, ptid_t ptid)
633 {
634   static char *ret = NULL;
635
636   if (ptid_get_tid (ptid) == 0)
637     {
638       struct target_ops *beneath = find_target_beneath (ops);
639
640       return beneath->to_pid_to_str (beneath, ptid);
641     }
642
643   /* Free previous return value; a new one will be allocated by
644      xstrprintf().  */
645   xfree (ret);
646
647   ret = xstrprintf (_("Thread %ld"), ptid_get_tid (ptid));
648   return ret;
649 }
650
651 /* A "new-objfile" observer.  Used to activate/deactivate dec-thread
652    support.  */
653
654 static void
655 dec_thread_new_objfile_observer (struct objfile *objfile)
656 {
657   if (objfile != NULL)
658      enable_dec_thread ();
659   else
660      disable_dec_thread ();
661 }
662
663 /* The "to_get_ada_task_ptid" method of the dec_thread_ops.  */
664
665 static ptid_t
666 dec_thread_get_ada_task_ptid (long lwp, long thread)
667 {
668   int i;
669   struct dec_thread_info *info;
670
671   debug ("dec_thread_get_ada_task_ptid (lwp=0x%lx, thread=0x%lx)",
672          lwp, thread);
673
674   for (i = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, i, info);
675        i++)
676     if (info->info.teb == (pthread_t) thread)
677       return ptid_build_from_info (*info);
678   
679   warning (_("Could not find thread id from THREAD = 0x%lx\n"), thread);
680   return inferior_ptid;
681 }
682
683 static void
684 init_dec_thread_ops (void)
685 {
686   dec_thread_ops.to_shortname          = "dec-threads";
687   dec_thread_ops.to_longname           = _("DEC threads support");
688   dec_thread_ops.to_doc                = _("DEC threads support");
689   dec_thread_ops.to_detach             = dec_thread_detach;
690   dec_thread_ops.to_wait               = dec_thread_wait;
691   dec_thread_ops.to_fetch_registers    = dec_thread_fetch_registers;
692   dec_thread_ops.to_store_registers    = dec_thread_store_registers;
693   dec_thread_ops.to_mourn_inferior     = dec_thread_mourn_inferior;
694   dec_thread_ops.to_thread_alive       = dec_thread_thread_alive;
695   dec_thread_ops.to_pid_to_str         = dec_thread_pid_to_str;
696   dec_thread_ops.to_stratum            = thread_stratum;
697   dec_thread_ops.to_get_ada_task_ptid  = dec_thread_get_ada_task_ptid;
698   dec_thread_ops.to_magic              = OPS_MAGIC;
699 }
700
701 void
702 _initialize_dec_thread (void)
703 {
704   init_dec_thread_ops ();
705   add_target (&dec_thread_ops);
706
707   observer_attach_new_objfile (dec_thread_new_objfile_observer);
708
709   add_setshow_boolean_cmd ("dec-thread", class_maintenance, &debug_dec_thread,
710                             _("Set debugging of DEC threads module."),
711                             _("Show debugging of DEC threads module."),
712                             _("Enables debugging output (used to debug GDB)."),
713                             NULL, NULL,
714                             &setdebuglist, &showdebuglist);
715 }