home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
c
/
prf.arc
/
PRFPRINT.C
< prev
next >
Wrap
Text File
|
1988-11-24
|
4KB
|
184 lines
/*
* This routine merges a profile.out file and a
* microsoft linker map file to produce an approximate listing
* of times spent in each routine.
*/
#define NAMESIZE 12
#define TAB_SIZE 512
#include <stdio.h>
#include <ctype.h>
main(int argc,char *argv[])
{
extern int usage(),process();
if( argc != 2){
return usage();
}
else {
return process( argv[1] );
}
}
usage()
{
fprintf(stderr,"USAGE: makeat <mapfile>\n");
return 1;
}
static contains(char *s,char *substr)
{
int substrlen,len;
register char *p;
substrlen = strlen(substr);
for( p = s ; *p ; p++){
if( *p != *substr)continue;
if(strncmp(substr,p,substrlen) == 0)return 1;
}
return 0;
}
process(char *mapfile)
{
FILE *fp,*fx;
unsigned int total;
char line[256];
if((fp = fopen(mapfile,"r")) == NULL){
perror(mapfile);
return 1;
}
/*
* this routine depends critically on the EXACT
* format of the Microsoft linker map file.
* we expect the line ' Publics by Value ' to
* appear, followed by lines of the form ' 'cs:ip name
* (note the preceding blank)
* These lines appear continuously until the end of the section.
* so as soon as we encounter a line with the second character a
* non-digit we stop.
*/
/* SEARCH FOR RELEVANT SECTION */
while ( ! feof(fp) ){
if( NULL == fgets ( line, sizeof(line) , fp )){
perror(mapfile);
fclose(fp);
return 1;
}
/* only get out if we test equal... */
if(contains(line,"Publics by Value"))break;
}
while ( fgets(line,sizeof(line),fp) && ! isxdigit(line[1]) );
for(;(!feof(fp)) && isxdigit(line[1]) ; fgets(line,sizeof(line),fp))
{
short cs,ip;
char name[32],junk[32];
if( sscanf(line,"%x:%x %s %s",&cs,&ip,name,junk) !=3 )continue;
insert(name,ip);
}
/*
* we now have a sorted table of names versus ip
* ( there are some subtleties in insert..... )
*
* so now we open profil.out and merge info from there into
* the table and print the output.....
*/
if((fx = fopen("PROFIL.OUT","r") ) == NULL){
perror("PROFIL.OUT");
return 1;
}
total = 0;
while( ! feof(fx) && fgets(line,sizeof(line), fx) != NULL){
short ip,cnt;
if( sscanf(line,"%x %d",&ip,&cnt) != 2)continue;
total += cnt;
merge(ip, cnt);
}
fclose(fx);
fclose(fp);
dump(total);
}
typedef struct {
char name[NAMESIZE];
unsigned short ip;
unsigned short cnt;
} element;
static element table[TAB_SIZE];
static int table_ptr = 0;
static int no_more_add = 0;
insert(char *name, unsigned short ip)
{
if( no_more_add )return 1;
if ( table_ptr >= TAB_SIZE ){
fprintf(stderr,"Table Full \n");
}
/*
* if we move into a new segment then IP will drop and so
* we just stop adding.......
*/
if( table_ptr > 0 && ip < table[table_ptr-1].ip)
return (no_more_add = 1);
name[sizeof(table[0].name)-1] = 0;
strcpy(table[table_ptr].name, name);
table[table_ptr].ip = ip;
table[table_ptr].cnt = 0;
table_ptr++;
strcpy(table[table_ptr].name,"???");
table[table_ptr].ip = 0xFFFF;
return 0;
}
merge(unsigned short ip,unsigned short cnt)
{
register element *p;
for( p = table ; p < table + table_ptr ; p++){
if( ip < (p+1)->ip ){
p->cnt += cnt;
break;
}
}
return;
}
dump(unsigned int total)
{
FILE *out;
register int i;
register element *p;
float percent;
unsigned int table_total = 0;
for( i = 0 ; i < table_ptr ; i++){
p = &(table[i]);
if( p->cnt != 0)
percent = (p->cnt*100.0)/((float)total);
else
percent = 0.0;
printf("%-16s %d %5.2f%%\n",p->name,p->cnt,percent);
table_total += p->cnt;
}
printf("------------------"); fflush(stdout);
percent = (100.0 * table_total)/((float)total);
printf("Above entries account for %5.2f%% of total time\n",percent);
printf(" ( %d out of %d samples)\n",table_total,total);
fflush(stdout);
fclose(out);
return;
}