www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/02/25/11:52:09

From: "A.Appleyard" <A DOT APPLEYARD AT fs2 DOT mt DOT umist DOT ac DOT uk>
Organization: Materials Science Centre
To: DJGPP AT DELORIE DOT COM
Date: Tue, 25 Feb 1997 16:33:18 GMT
Subject: A program to find all unused symbols in a C program
Message-ID: <34DB2D72539@fs2.mt.umist.ac.uk>

  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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019