Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 #include <stdio.h> 00037 #include <stdlib.h> 00038 #include <string.h> 00039 #include <sys/types.h> 00040 #include <unistd.h> 00041 00042 #include "mstack.h" 00043 00044 static int getsp ( int a ); 00045 static int fra ( int a ); 00046 static char *savestr ( char *str ); 00047 #ifndef MONGOOSE_BE 00048 static void make_ftab ( void ); 00049 #endif /* MONGOOSE_BE */ 00050 static struct frec *search_in_ftab ( int adr ); 00051 00052 #if mips 00053 static int ftab_problems = 0; 00054 /*-------------------------------------------------------------- 00055 * extremely dependent on mips calling convention. returns sp 00056 * of the calling routine 00057 *------------------------------------------------------------*/ 00058 static getsp(int a) 00059 { 00060 return (int) &a; 00061 } 00062 /*-------------------------------------------------------------- 00063 * extremely dependent on mips calling convention. returns 00064 * return address in the caller of getra. Intent is to find 00065 * current value of pc. 00066 *------------------------------------------------------------*/ 00067 static fra(int a) 00068 { 00069 int *p = &a; 00070 return p[5]; 00071 } 00072 00073 static getra(void) 00074 { 00075 return fra(3); 00076 } 00077 00078 struct frec { 00079 char *name, *file; 00080 int addr, fsize, raofst; 00081 }; 00082 00083 #define STRSP_SIZE 512 00084 static char *strsp; 00085 static int strsp_left = 0; 00086 00087 static char *savestr(char *str) 00088 { 00089 int l; 00090 char *x; 00091 00092 l = strlen(str); 00093 if (strsp_left < (l+1)) { 00094 strsp = (char *) malloc(STRSP_SIZE); 00095 strsp_left = STRSP_SIZE; 00096 } 00097 x = strsp; 00098 strcpy(x, str); 00099 strsp += (l+1); 00100 strsp_left -= (l+1); 00101 return x; 00102 } 00103 00104 static struct frec *ftab; 00105 static struct frec *main_fr; 00106 static struct frec *trst_fr; 00107 static char *tmpname = " "; 00108 00109 #ifndef MONGOOSE_BE 00110 static void make_ftab() 00111 { 00112 FILE *fp; 00113 char *curfile = "", buf1[200], buf[200]; 00114 int adr, j1, j2, j3, j4, j5, ro, fs, l, i, lc, ch; 00115 struct frec *cf; 00116 extern char **__Argv; 00117 00118 sprintf(tmpname, "/tmp/TPF%1d", getpid()); 00119 sprintf(buf, "odump -P %s > %s", __Argv[0], tmpname); 00120 system(buf); 00121 fp = fopen(tmpname, "r"); 00122 unlink(tmpname); 00123 lc = 0; 00124 while ((ch = getc(fp)) != EOF) { 00125 if (ch == '\n') 00126 lc++; 00127 } 00128 /* check for a problem with odump */ 00129 if (lc < 100) { 00130 ftab_problems++; 00131 fclose(fp); 00132 } 00133 fseek(fp, 0, 0); 00134 ftab = (struct frec *) malloc(lc * sizeof(struct frec)); 00135 cf = ftab; 00136 for (i=0; i<8; i++) 00137 fgets(buf, 200, fp); 00138 while (fgets(buf, 200, fp)) { 00139 l = strlen(buf); 00140 if (buf[l-2] == ']') { 00141 sscanf(buf, " %s", buf1); 00142 curfile = savestr(buf1); 00143 } else if (buf[l-2] != ':') { 00144 sscanf(buf, "%s 0x%x %d %d %d 0x%x %d %d %d", buf1, &adr, &j1, &j2, 00145 &j3, &j4, &ro, &fs, &j5); 00146 00147 cf->file = curfile; 00148 cf->name = savestr(buf1); 00149 cf->addr = adr; 00150 cf->raofst = ro; 00151 cf->fsize = fs; 00152 if (strcmp(buf1, "main") == 0) main_fr = cf; 00153 if (strcmp(buf1, "trace_stack") == 0) trst_fr = cf; 00154 cf++; 00155 fgets(buf, 200, fp); 00156 } 00157 } 00158 fclose(fp); 00159 cf->addr = 0x7fffffff; 00160 } 00161 #endif /* MONGOOSE_BE */ 00162 /*---------------------------------------------------------------------- 00163 * do it by binary search 00164 *--------------------------------------------------------------------*/ 00165 static struct frec *search_in_ftab(int adr) 00166 { 00167 struct frec *f; 00168 00169 /* handle problem with odump */ 00170 if (ftab_problems) { 00171 return NULL; 00172 } 00173 f = ftab; 00174 while (f->addr <= adr) 00175 f++; 00176 return f-1; 00177 } 00178 00179 static struct frec *this_func; 00180 00181 #ifndef MONGOOSE_BE 00182 int trace_stack(prfunc, prfile) 00183 int prfunc, prfile; 00184 { 00185 int sp, ra, fc; 00186 struct frec *cf; 00187 00188 #ifndef BACK_END 00189 return ( 1 ); /* STREICH: figure out what's wrong later... */ 00190 #endif /* BACK_END */ 00191 00192 #define SPOFST -36 00193 /*sp = ((int) &sp) + SPOFST;*/ 00194 fc = 0; 00195 sp = getsp(0); 00196 if (ftab_problems == 0 && ftab == NULL) 00197 make_ftab(); 00198 /*cf = trst_fr;*/ 00199 cf = search_in_ftab(getra()); 00200 /* RAT: There is a bug in odump which sometimes causes it not 00201 * to find the whole procedure table. So search_in_ftab will 00202 * sometimes fail (in a perfect world it would never fail). 00203 * So check for a nil cf and return 0 00204 */ 00205 if (cf == NULL) return fc; 00206 while (1) { 00207 if (prfunc) { 00208 if (prfile) 00209 printf("%s:", cf->file); 00210 printf("%s\n", cf->name); 00211 } 00212 if (cf == main_fr) 00213 break; 00214 ra = * ((int *)(sp + cf->fsize + cf->raofst)); 00215 sp += cf->fsize; 00216 cf = search_in_ftab(ra); 00217 fc++; 00218 } 00219 return fc; 00220 } 00221 00222 #endif /* MONGOOSE_BE */ 00223 00224 #else /* not mips */ 00225 00226 #if A_UX 00227 00228 struct x { 00229 struct x *next; 00230 }; 00231 00232 stack_lev(b) 00233 int b; 00234 { 00235 struct x *l = (struct x *) (((int)(&b)) - 8); 00236 int a = 0; 00237 while (l) { 00238 a++; 00239 l = l->next; 00240 } 00241 return a; 00242 } 00243 00244 trace_stack(a, b) 00245 { 00246 return stack_lev()-1; 00247 } 00248 00249 #else /* not A_UX */ 00250 00251 char **__Argv; 00252 00253 /*ARGSUSED*/ 00254 trace_stack(a, b) 00255 int a; 00256 int b; 00257 { 00258 return 1; /* not implemented */ 00259 } 00260 00261 #endif /* not A_UX */ 00262 #endif /* not mips */ 00263