home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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;
- }
-