home *** CD-ROM | disk | FTP | other *** search
- /*
- * block profile support for gcc.
- * ++jrb bammi@cadence.com
- */
- #include <compiler.h>
- #include <stdio.h>
- #include <stdlib.h>
-
- /* block count struct produced by gcc -tcov */
- typedef struct _bb_count {
- long initialized; /* has __bb_init_func been called */
- char *filename; /* filename for .d file */
- long *block_counts; /* address of block count table */
- long ncount; /* sizeof block count table */
- /* ie: # of basic blocks in file */
- struct _bb_count *next; /* in memory link to next struct */
- char ***addr_table; /* addr of basic block address table */
- /* size of addr_table == ncount+1 */
- } BB_COUNT;
-
- void __bb_init_func __PROTO((BB_COUNT *));
- static void exit_func __PROTO((void)); /* installed to be called at exit */
- static void save_info __PROTO((BB_COUNT *));
-
- /* vars */
- static BB_COUNT *hdr = NULL; /* list of all bb_count for which
- __bb_init_func has been called */
- static char first_call = 1; /* flags first call to __bb_init_func */
- static char at_exit_failed = 0; /* flag to indicate that atexit() failed */
-
- /*
- * called by gcc -tcov generated code on first entry into a function
- */
- void __bb_init_func(bb_count)
- BB_COUNT *bb_count;
- {
- if(at_exit_failed)
- return;
-
- if(first_call)
- {
- if(atexit(exit_func))
- {
- fprintf(stderr, "Failed to install exit function. No block \
- profile information will be saved\n");
- at_exit_failed = 1;
- return;
- }
- first_call = 0;
- }
-
- if(bb_count->initialized == 0)
- { /* link into list of bb_counts */
- bb_count->next = hdr;
- hdr = bb_count;
- bb_count->initialized = 1;
- }
- }
-
- /*
- * called on normal exit
- * write out block profile files for each bb_count struct in list.
- */
- static void exit_func()
- {
- BB_COUNT *p;
-
- for(p = hdr; p; p = p->next)
- save_info(p);
- }
-
- typedef struct {
- long lineno; /* start of block */
- long count; /* # executions (cumulative over runs) */
- } DINFO;
-
- /*
- * given a bb_count struct, save info into .d file
- */
- static void save_info(p)
- BB_COUNT *p;
- {
- FILE *fp;
- long i, *bcounts;
- DINFO *dinfo = malloc(p->ncount * sizeof(DINFO));
-
- if(!dinfo)
- {
- fprintf(stderr, "No memory to process %s. Skipped\n", p->filename);
- return;
- }
-
- if((fp = fopen(p->filename, "r")) == NULL)
- {
- fprintf(stderr,"Failed to open %s for read. Skipped\n", p->filename);
- free(dinfo);
- return;
- }
- /* read .d file & accumulate counts */
- for(i = 0, bcounts = p->block_counts;
- fscanf(fp, "%ld%ld", &dinfo[i].lineno, &dinfo[i].count) == 2; i++)
- {
- if(i >= p->ncount)
- {
- fprintf(stderr, "Block counts in %s exceed expected %ld, rest skipped\n",
- p->filename, p->ncount);
- break;
- }
- dinfo[i].count += bcounts[i];
- }
- fclose(fp);
- if(i < p->ncount)
- {
- fprintf(stderr, "Warning Block counts in %s less than expected %ld\n",
- p->filename, p->ncount);
- }
- if((fp = fopen(p->filename, "w")) == NULL)
- {
- fprintf(stderr,"Failed to open %s for write. Skipped\n", p->filename);
- free(dinfo);
- return;
- }
- for(i = 0; i < p->ncount; i++)
- {
- if(fprintf(fp, "\t%ld\t%ld\n", dinfo[i].lineno, dinfo[i].count) == EOF)
- {
- fprintf(stderr,"Write Failed to %s\n", p->filename);
- free(dinfo);
- fclose(fp);
- return;
- }
- }
- fclose(fp);
- free(dinfo);
- }
-