OpenADFortTk (including Open64 and OpenAnalysis references)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
mstack.c
Go to the documentation of this file.
1 /*
2 
3  Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved.
4 
5  This program is free software; you can redistribute it and/or modify it
6  under the terms of version 2 of the GNU General Public License as
7  published by the Free Software Foundation.
8 
9  This program is distributed in the hope that it would be useful, but
10  WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13  Further, this software is distributed without any warranty that it is
14  free of the rightful claim of any third person regarding infringement
15  or the like. Any license provided herein, whether implied or
16  otherwise, applies only to this software file. Patent licenses, if
17  any, provided herein do not apply to combinations of this program with
18  other software, or any other product whatsoever.
19 
20  You should have received a copy of the GNU General Public License along
21  with this program; if not, write the Free Software Foundation, Inc., 59
22  Temple Place - Suite 330, Boston MA 02111-1307, USA.
23 
24  Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky,
25  Mountain View, CA 94043, or:
26 
27  http://www.sgi.com
28 
29  For further information regarding this notice, see:
30 
31  http://oss.sgi.com/projects/GenInfo/NoticeExplan
32 
33 */
34 
35 
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <sys/types.h>
40 #include <unistd.h>
41 
42 #include "mstack.h"
43 
44 static int getsp ( int a );
45 static int fra ( int a );
46 static char *savestr ( char *str );
47 #ifndef MONGOOSE_BE
48 static void make_ftab ( void );
49 #endif /* MONGOOSE_BE */
50 static struct frec *search_in_ftab ( int adr );
51 
52 #if mips
53 static int ftab_problems = 0;
54 /*--------------------------------------------------------------
55  * extremely dependent on mips calling convention. returns sp
56  * of the calling routine
57  *------------------------------------------------------------*/
58 static getsp(int a)
59 {
60  return (int) &a;
61 }
62 /*--------------------------------------------------------------
63  * extremely dependent on mips calling convention. returns
64  * return address in the caller of getra. Intent is to find
65  * current value of pc.
66  *------------------------------------------------------------*/
67 static fra(int a)
68 {
69  int *p = &a;
70  return p[5];
71 }
72 
73 static getra(void)
74 {
75  return fra(3);
76 }
77 
78 struct frec {
79  char *name, *file;
80  int addr, fsize, raofst;
81 };
82 
83 #define STRSP_SIZE 512
84 static char *strsp;
85 static int strsp_left = 0;
86 
87 static char *savestr(char *str)
88 {
89  int l;
90  char *x;
91 
92  l = strlen(str);
93  if (strsp_left < (l+1)) {
94  strsp = (char *) malloc(STRSP_SIZE);
95  strsp_left = STRSP_SIZE;
96  }
97  x = strsp;
98  strcpy(x, str);
99  strsp += (l+1);
100  strsp_left -= (l+1);
101  return x;
102 }
103 
104 static struct frec *ftab;
105 static struct frec *main_fr;
106 static struct frec *trst_fr;
107 static char *tmpname = " ";
108 
109 #ifndef MONGOOSE_BE
110 static void make_ftab()
111 {
112  FILE *fp;
113  char *curfile = "", buf1[200], buf[200];
114  int adr, j1, j2, j3, j4, j5, ro, fs, l, i, lc, ch;
115  struct frec *cf;
116  extern char **__Argv;
117 
118  sprintf(tmpname, "/tmp/TPF%1d", getpid());
119  sprintf(buf, "odump -P %s > %s", __Argv[0], tmpname);
120  system(buf);
121  fp = fopen(tmpname, "r");
122  unlink(tmpname);
123  lc = 0;
124  while ((ch = getc(fp)) != EOF) {
125  if (ch == '\n')
126  lc++;
127  }
128  /* check for a problem with odump */
129  if (lc < 100) {
130  ftab_problems++;
131  fclose(fp);
132  }
133  fseek(fp, 0, 0);
134  ftab = (struct frec *) malloc(lc * sizeof(struct frec));
135  cf = ftab;
136  for (i=0; i<8; i++)
137  fgets(buf, 200, fp);
138  while (fgets(buf, 200, fp)) {
139  l = strlen(buf);
140  if (buf[l-2] == ']') {
141  sscanf(buf, " %s", buf1);
142  curfile = savestr(buf1);
143  } else if (buf[l-2] != ':') {
144  sscanf(buf, "%s 0x%x %d %d %d 0x%x %d %d %d", buf1, &adr, &j1, &j2,
145  &j3, &j4, &ro, &fs, &j5);
146 
147  cf->file = curfile;
148  cf->name = savestr(buf1);
149  cf->addr = adr;
150  cf->raofst = ro;
151  cf->fsize = fs;
152  if (strcmp(buf1, "main") == 0) main_fr = cf;
153  if (strcmp(buf1, "trace_stack") == 0) trst_fr = cf;
154  cf++;
155  fgets(buf, 200, fp);
156  }
157  }
158  fclose(fp);
159  cf->addr = 0x7fffffff;
160 }
161 #endif /* MONGOOSE_BE */
162 /*----------------------------------------------------------------------
163  * do it by binary search
164  *--------------------------------------------------------------------*/
165 static struct frec *search_in_ftab(int adr)
166 {
167  struct frec *f;
168 
169  /* handle problem with odump */
170  if (ftab_problems) {
171  return NULL;
172  }
173  f = ftab;
174  while (f->addr <= adr)
175  f++;
176  return f-1;
177 }
178 
179 static struct frec *this_func;
180 
181 #ifndef MONGOOSE_BE
182 int trace_stack(prfunc, prfile)
183  int prfunc, prfile;
184 {
185  int sp, ra, fc;
186  struct frec *cf;
187 
188 #ifndef BACK_END
189  return ( 1 ); /* STREICH: figure out what's wrong later... */
190 #endif /* BACK_END */
191 
192 #define SPOFST -36
193  /*sp = ((int) &sp) + SPOFST;*/
194  fc = 0;
195  sp = getsp(0);
196  if (ftab_problems == 0 && ftab == NULL)
197  make_ftab();
198  /*cf = trst_fr;*/
199  cf = search_in_ftab(getra());
200  /* RAT: There is a bug in odump which sometimes causes it not
201  * to find the whole procedure table. So search_in_ftab will
202  * sometimes fail (in a perfect world it would never fail).
203  * So check for a nil cf and return 0
204  */
205  if (cf == NULL) return fc;
206  while (1) {
207  if (prfunc) {
208  if (prfile)
209  printf("%s:", cf->file);
210  printf("%s\n", cf->name);
211  }
212  if (cf == main_fr)
213  break;
214  ra = * ((int *)(sp + cf->fsize + cf->raofst));
215  sp += cf->fsize;
216  cf = search_in_ftab(ra);
217  fc++;
218  }
219  return fc;
220 }
221 
222 #endif /* MONGOOSE_BE */
223 
224 #else /* not mips */
225 
226 #if A_UX
227 
228 struct x {
229  struct x *next;
230 };
231 
232 stack_lev(b)
233  int b;
234 {
235  struct x *l = (struct x *) (((int)(&b)) - 8);
236  int a = 0;
237  while (l) {
238  a++;
239  l = l->next;
240  }
241  return a;
242 }
243 
244 trace_stack(a, b)
245 {
246  return stack_lev()-1;
247 }
248 
249 #else /* not A_UX */
250 
251 char **__Argv;
252 
253 /*ARGSUSED*/
255  int a;
256  int b;
257 {
258  return 1; /* not implemented */
259 }
260 
261 #endif /* not A_UX */
262 #endif /* not mips */
263