FreeBSD/usr.sbin/pmcannotate/pmcannotate.c
/*
 * Printout a single block inside an "objdump -S" function.
 * The block is composed of a first part in C and subsequent translation
 * in assembly.
 * This code also operates a second-level aggregation packing together
 * samples relative to PCs into a (lower bottom) block with their
 * C (higher half) counterpart.
 */
Printout a single block inside an "objdump -S" function.
The block is composed of a first part in C and subsequent translation
in assembly.
This code also operates a second-level aggregation packing together
samples relative to PCs into a (lower bottom) block with their
C (higher half) counterpart.
Printout a single block inside an " objdump - S " function . The block is composed of a first part in C and subsequent translation in assembly . This code also operates a second - level aggregation packing together samples relative to PCs into a ( lower bottom ) block with their C ( higher half ) counterpart .
static int
printblock(FILE *fp, struct aggent *agg)
{
	char buffer[LNBUFF];
	long lstart;
	struct entry *obj;
	u_int tnsamples;
	int done, nbytes, sentinel;
	void *ptr;
	lstart = ftell(fp);
	sentinel = 0;
	for (;;) {
		if (fgets(buffer, LNBUFF, fp) == NULL)
			return (0);
		if (isasminline(buffer) != 0)
			break;
		sentinel = 1;
		nbytes = newfunction(buffer);
		if (nbytes != 0) {
			if (fseek(fp, nbytes * -1, SEEK_CUR) == -1)
				return (-1);
			return (0);
		}
	}
	tnsamples = 0;
	do {
		if (sentinel == 0)
			return (-1);
		if (sscanf(buffer, " %p:", &ptr) != 1)
			return (-1);
		obj = general_findent((uintptr_t)ptr);
		if (obj != NULL)
			tnsamples += obj->en_nsamples;
	} while (fgets(buffer, LNBUFF, fp) != NULL && isasminline(buffer) != 0);
	if (fseek(fp, lstart, SEEK_SET) == -1)
		return (-1);
	done = 0;
	while (fgets(buffer, LNBUFF, fp) != NULL && isasminline(buffer) == 0) {
		if (tnsamples == 0 || done != 0)
			printf("\t| %s", buffer);
		else {
			done = 1;
			printf("%.2f%%\t| %s",
			    (float)tnsamples * 100 / agg->ag_nsamples, buffer);
		}
	}
	for (;;) {
		if (fgets(buffer, LNBUFF, fp) == NULL)
			return (0);
		if (isasminline(buffer) == 0)
			break;
		nbytes = newfunction(buffer);
		if (nbytes != 0) {
			if (fseek(fp, nbytes * -1, SEEK_CUR) == -1)
				return (-1);
			return (0);
		}
	}
	if (fseek(fp, strlen(buffer) * -1, SEEK_CUR) == -1)
		return (-1);
	return (0);
}
static int printblock ( FILE * fp , struct aggent * agg ) { char buffer [ LNBUFF ] ; long lstart ; struct entry * obj ; u_int tnsamples ; int done , nbytes , sentinel ; void * ptr ; lstart = ftell ( fp ) ; sentinel = 0 ; for ( ; ; ) { if ( fgets ( buffer , LNBUFF , fp ) == NULL ) return ( 0 ) ; if ( isasminline ( buffer ) != 0 ) break ; sentinel = 1 ; nbytes = newfunction ( buffer ) ; if ( nbytes != 0 ) { if ( fseek ( fp , nbytes * -1 , SEEK_CUR ) == -1 ) return ( -1 ) ; return ( 0 ) ; } } tnsamples = 0 ; do { if ( sentinel == 0 ) return ( -1 ) ; if ( sscanf ( buffer , " " , & ptr ) != 1 ) return ( -1 ) ; obj = general_findent ( ( uintptr_t ) ptr ) ; if ( obj != NULL ) tnsamples += obj -> en_nsamples ; } while ( fgets ( buffer , LNBUFF , fp ) != NULL && isasminline ( buffer ) != 0 ) ; if ( fseek ( fp , lstart , SEEK_SET ) == -1 ) return ( -1 ) ; done = 0 ; while ( fgets ( buffer , LNBUFF , fp ) != NULL && isasminline ( buffer ) == 0 ) { if ( tnsamples == 0 || done != 0 ) printf ( " \t " , buffer ) ; else { done = 1 ; printf ( " \t " , ( float ) tnsamples * 100 / agg -> ag_nsamples , buffer ) ; } } for ( ; ; ) { if ( fgets ( buffer , LNBUFF , fp ) == NULL ) return ( 0 ) ; if ( isasminline ( buffer ) == 0 ) break ; nbytes = newfunction ( buffer ) ; if ( nbytes != 0 ) { if ( fseek ( fp , nbytes * -1 , SEEK_CUR ) == -1 ) return ( -1 ) ; return ( 0 ) ; } } if ( fseek ( fp , strlen ( buffer ) * -1 , SEEK_CUR ) == -1 ) return ( -1 ) ; return ( 0 ) ; }
Printout a single block inside an "objdump -S" function.
Printout a single block inside an " objdump - S " function .
/*
	 * We expect the first thing of the block is C code, so simply give
	 * up if asm line is found.
	 */ /*
	 * If the sentinel is not set, it means it did not match any
	 * "high half" for this code so simply give up.
	 * Operates the second-level aggregation.
	 */ /* Rewind to the start of the block in order to start the printout. */ /* Again the high half of the block rappresenting the C part. */ /*
	 * Again the low half of the block rappresenting the asm
	 * translation part.
	 */