OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [dec-thread.c] - Blame information for rev 835

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* 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
/* 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\n"), 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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.