OSDN Git Service

PR target/50678
[pf3gnuchains/gcc-fork.git] / gcc / ada / tb-ivms.c
1 /****************************************************************************
2  *                                                                          *
3  *                         GNAT COMPILER COMPONENTS                         *
4  *                                                                          *
5  *                 T R A C E B A C K - I t a n i u m  / V M S               *
6  *                                                                          *
7  *                          C Implementation File                           *
8  *                                                                          *
9  *                     Copyright (C) 2007, AdaCore                          *
10  *                                                                          *
11  * GNAT is free software;  you can  redistribute it  and/or modify it under *
12  * terms of the  GNU General Public License as published  by the Free Soft- *
13  * ware  Foundation;  either version 2,  or (at your option) any later ver- *
14  * sion.  GNAT is distributed in the hope that it will be useful, but WITH- *
15  * OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY *
16  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License *
17  * for  more details.  You should have  received  a copy of the GNU General *
18  * Public License  distributed with GNAT;  see file COPYING.  If not, write *
19  * to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, *
20  * Boston, MA 02110-1301, USA.                                              *
21  *                                                                          *
22  * As a  special  exception,  if you  link  this file  with other  files to *
23  * produce an executable,  this file does not by itself cause the resulting *
24  * executable to be covered by the GNU General Public License. This except- *
25  * ion does not  however invalidate  any other reasons  why the  executable *
26  * file might be covered by the  GNU Public License.                        *
27  *                                                                          *
28  * GNAT was originally developed  by the GNAT team at  New York University. *
29  * Extensive contributions were provided by Ada Core Technologies Inc.      *
30  *                                                                          *
31  ****************************************************************************/
32
33 /* Itanium Open/VMS implementation of backtrace.  Use ICB (Invocation
34    Context Block) routines.  */
35 #include <stdlib.h>
36 #include <vms/libicb.h>
37
38 /* Declare libicb routines.  */
39 extern INVO_CONTEXT_BLK *LIB$I64_CREATE_INVO_CONTEXT (void *(*)(size_t),
40                                                       void (*)(void *),
41                                                       int);
42 extern void LIB$I64_FREE_INVO_CONTEXT (INVO_CONTEXT_BLK *);
43 extern int LIB$I64_GET_CURR_INVO_CONTEXT(INVO_CONTEXT_BLK *);
44 extern int LIB$I64_GET_PREV_INVO_CONTEXT(INVO_CONTEXT_BLK *);
45
46 /* Gcc internal headers poison malloc.  So use xmalloc() when building the
47    compiler.  */
48 #ifdef IN_RTS
49 #define BT_MALLOC malloc
50 #else
51 #define BT_MALLOC xmalloc
52 #endif
53
54 int
55 __gnat_backtrace (void **array, int size,
56                   void *exclude_min, void *exclude_max, int skip_frames)
57 {
58   INVO_CONTEXT_BLK *ctxt;
59   int res = 0;
60   int n = 0;
61
62   /* Create the context.  */
63   ctxt = LIB$I64_CREATE_INVO_CONTEXT (BT_MALLOC, free, 0);
64   if (ctxt == NULL)
65     return 0;
66
67   LIB$I64_GET_CURR_INVO_CONTEXT (ctxt);
68
69   while (1)
70     {
71       void *pc = (void *)ctxt->libicb$ih_pc;
72       if (pc == (void *)0)
73         break;
74       if (ctxt->libicb$v_bottom_of_stack)
75         break;
76       if (n >= skip_frames && (pc < exclude_min || pc > exclude_max))
77         {
78           array[res++] = (void *)(ctxt->libicb$ih_pc);
79           if (res == size)
80             break;
81         }
82       n++;
83       LIB$I64_GET_PREV_INVO_CONTEXT (ctxt);
84     }
85
86   /* Free the context.  */
87   LIB$I64_FREE_INVO_CONTEXT (ctxt);
88   return res;
89 }