Mail Archives: djgpp/1997/02/25/11:52:09
Re the thread that I started re how to find unused global symbols in a big
multi-file program, I just now quickly threw together this C program. Its call
args should be the names of one or more *.S files created by djgpp -S . It
will report in file `_.O' (in mangled form) all symbols declared but not used
in those *.S files (which should be the *.S forms of all the files that make
up one multi-file program). If you want to develop it further, you can.
CXXFILT < _.O > _.OO
will then produce in _.OO the same output with the symbol names demangled.
-------------------------------------------------------
#include<stdio.h>
#include<string.h>
#include<std.h>
/*-----*/ /* the args should be names of *.S files created by djgpp -S */
int main(int nargs,char**arg){
FILE*F; int i,j,k,l,m,n=0,z=0; char*sw,L[1024],**sym,*x;
puts("READING DEFINED SYMBOLS");
sym=(char**)(malloc(0x10000));
for(m=1;m<nargs;m++) { /* loop for each file */
F=fopen(arg[m],"r"); puts(arg[m]);
while(fgets(L,1024,F),!feof(F)) {
if(!strncmp(L,"\011.ln\011",5)) sscanf(L+5,"%d",&z);
/*I thought the /ln numbers were source line numbers, but they seem not to be*/
if(L[0]=='_') if(!strchr(L,'.')) { /* only accept C program symbols */
if((j=strlen(L))) if(L[j-1]=='\n') L[--j]=0; /* remove \n */
if(j) if(L[j-1]==':') L[--j]=0; /* remove colon */
sym[n++]=(char*)malloc(j+4); /* string */
if(j) strcpy(sym[n-1],L); else sym[n-1][0]=0;
sw=sym[n-1]+j; sw[1]=m; /* number of file it is in */
sw[2]=z&255; sw[3]=z>>8; /* .ln number */ }}
fclose(F);}
for(k=i=n-1;k;i--) for(k=j=0;j<i;j++) /* bubble sort */
if(strcmp(sym[j],sym[j+1])>0) {sw=sym[j+1]; sym[j+1]=sym[j]; sym[j]=sw; k=1;}
for(i=n-1;i>0;i--) if(!strcmp(sym[i-1],sym[i])) sym[i][0]=0;
/* mark the duplicates */
x=(char*)malloc(n); for(i=0;i<n;i++) x[i]=1;
m=0; puts("LOOKING FOR USES OF SYMBOLS");
for(m=1;m<nargs;m++) {
F=fopen(arg[m],"r"); puts(arg[m]);
while(fgets(L,1024,F),!feof(F)) if(L[0]==9) /* this time ignore labels */
if(strncmp(L+1,".def",4)) { /* ignore .def lines */
j=strlen(L);
for(i=0;i<j;i++) if((k=L[i])!='$') if(k!='_') if(k<'0'?:k>'9')
if(k<'0'?:k>'9') if(k<'A'?:k>'Z') if(k<'a'?:k>'z') L[i]=0;
/* replace all non-symbol chars by ascii 0 */
for(i=0;i<j;i++) if(L[i]) if(L[i]!='$') {
/* look for symbols, ignore leading $ */
k=strlen(L+i);
if(L[i]=='_') for(l=0;l<n;l++) if(*sym[l]) if(!strcmp(L+i,sym[l])) {
x[l]=0; break;} /* if in symbol list, mark as used */
i+=k;}}
fclose(F);}
F=fopen("_.o","w");
fprintf(F,"SYMBOLS DEFINED BUT NOT USED\n");
for(i=0;i<n;i++) if(x[i]) if(*(sw=sym[i])) {
fprintf(F,"%s",sw+1);
Y: sw+=strlen(sw); fprintf(F,", in %s",arg[sw[1]]);
if(i+1<n) if(!sym[i+1][0]) {sw=sym[++i]; sw[0]='_'; goto Y;}
fprintf(F,"\n");}
fclose(F); free(sym); free(x); return 0;}
- Raw text -