summaryrefslogtreecommitdiffstats
path: root/usr.bin/gprof
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>2002-03-06 11:25:58 +0000
committerbde <bde@FreeBSD.org>2002-03-06 11:25:58 +0000
commitacab62a802a890955c63730629ae1635151daef9 (patch)
tree1d204f3d5dc13a81eedf846e24d6eb5de1966db8 /usr.bin/gprof
parent7d6942219698b48fdb39fb2d4a402b775e9f96bf (diff)
downloadFreeBSD-src-acab62a802a890955c63730629ae1635151daef9.zip
FreeBSD-src-acab62a802a890955c63730629ae1635151daef9.tar.gz
Support runtime specification of the history counter type by whatever
generated the gmon data. The support is currently limited to what is easy to implement and/or needed: signedess: signed or insigned size: 8, 16, 32 or 64 bits format: a binary integer in gprof's format (gprof is not a cross-tool). High-resolution kernel profiling uses signed 64-bit counters. Normal kernel profiling and user profiling use unsigned 16-bit counters but should use 32-bit ones.
Diffstat (limited to 'usr.bin/gprof')
-rw-r--r--usr.bin/gprof/gprof.c54
-rw-r--r--usr.bin/gprof/gprof.h15
2 files changed, 51 insertions, 18 deletions
diff --git a/usr.bin/gprof/gprof.c b/usr.bin/gprof/gprof.c
index 8d529cb..81e50d6 100644
--- a/usr.bin/gprof/gprof.c
+++ b/usr.bin/gprof/gprof.c
@@ -46,6 +46,7 @@ static const char rcsid[] =
#endif /* not lint */
#include <err.h>
+#include <limits.h>
#include "gprof.h"
static int valcmp(const void *, const void *);
@@ -302,12 +303,20 @@ openpfile(filename)
filename, rate, "incompatible with clock rate", hz);
done();
}
+ if ( gmonhdr.histcounter_type == 0 ) {
+ /* Historical case. The type was u_short (2 bytes in practice). */
+ histcounter_type = 16;
+ histcounter_size = 2;
+ } else {
+ histcounter_type = gmonhdr.histcounter_type;
+ histcounter_size = abs(histcounter_type) / CHAR_BIT;
+ }
s_lowpc = (unsigned long) gmonhdr.lpc;
s_highpc = (unsigned long) gmonhdr.hpc;
lowpc = (unsigned long)gmonhdr.lpc / HISTORICAL_SCALE_2;
highpc = (unsigned long)gmonhdr.hpc / HISTORICAL_SCALE_2;
sampbytes = gmonhdr.ncnt - size;
- nsamples = sampbytes / sizeof (UNIT);
+ nsamples = sampbytes / histcounter_size;
# ifdef DEBUG
if ( debug & SAMPLEDEBUG ) {
printf( "[openpfile] hdr.lpc 0x%lx hdr.hpc 0x%lx hdr.ncnt %d\n",
@@ -374,7 +383,7 @@ dumpsum( sumfile )
/*
* dump the samples
*/
- if (fwrite(samples, sizeof (UNIT), nsamples, sfile) != nsamples) {
+ if (fwrite(samples, histcounter_size, nsamples, sfile) != nsamples) {
perror( sumfile );
done();
}
@@ -422,20 +431,47 @@ readsamples(pfile)
FILE *pfile;
{
register i;
- UNIT sample;
+ intmax_t sample;
if (samples == 0) {
- samples = (UNIT *) calloc(sampbytes, sizeof (UNIT));
+ samples = (double *) calloc(nsamples, sizeof(double));
if (samples == 0) {
- warnx("no room for %d sample pc's", sampbytes / sizeof (UNIT));
+ warnx("no room for %d sample pc's", nsamples);
done();
}
}
for (i = 0; i < nsamples; i++) {
- fread(&sample, sizeof (UNIT), 1, pfile);
+ fread(&sample, histcounter_size, 1, pfile);
if (feof(pfile))
break;
- samples[i] += sample;
+ switch ( histcounter_type ) {
+ case -8:
+ samples[i] += *(int8_t *)&sample;
+ break;
+ case 8:
+ samples[i] += *(u_int8_t *)&sample;
+ break;
+ case -16:
+ samples[i] += *(int16_t *)&sample;
+ break;
+ case 16:
+ samples[i] += *(u_int16_t *)&sample;
+ break;
+ case -32:
+ samples[i] += *(int32_t *)&sample;
+ break;
+ case 32:
+ samples[i] += *(u_int32_t *)&sample;
+ break;
+ case -64:
+ samples[i] += *(int64_t *)&sample;
+ break;
+ case 64:
+ samples[i] += *(u_int64_t *)&sample;
+ break;
+ default:
+ err(1, "unsupported histogram counter type %d", histcounter_type);
+ }
}
if (i != nsamples) {
warnx("unexpected EOF after reading %d/%d samples", --i , nsamples );
@@ -478,7 +514,7 @@ readsamples(pfile)
asgnsamples()
{
register int j;
- UNIT ccnt;
+ double ccnt;
double time;
unsigned long pcl, pch;
register int i;
@@ -498,7 +534,7 @@ asgnsamples()
time = ccnt;
# ifdef DEBUG
if ( debug & SAMPLEDEBUG ) {
- printf( "[asgnsamples] pcl 0x%lx pch 0x%lx ccnt %d\n" ,
+ printf( "[asgnsamples] pcl 0x%lx pch 0x%lx ccnt %.0f\n" ,
pcl , pch , ccnt );
}
# endif DEBUG
diff --git a/usr.bin/gprof/gprof.h b/usr.bin/gprof/gprof.h
index c37c00e..e17e085 100644
--- a/usr.bin/gprof/gprof.h
+++ b/usr.bin/gprof/gprof.h
@@ -89,11 +89,8 @@ typedef int bool;
*/
long hz;
-#ifdef GPROF4
-typedef int64_t UNIT;
-#else
-typedef u_short UNIT; /* unit of profiling */
-#endif
+size_t histcounter_size;
+int histcounter_type;
char *a_outname;
#define A_OUTNAME "a.out"
@@ -207,8 +204,8 @@ int ncycle; /* number of cycles discovered */
* Backward compatible old style header
*/
struct ophdr {
- UNIT *lpc;
- UNIT *hpc;
+ u_short *lpc;
+ u_short *hpc;
int ncnt;
};
@@ -218,11 +215,11 @@ int debug;
* Each discretized pc sample has
* a count of the number of samples in its range
*/
-UNIT *samples;
+double *samples;
unsigned long s_lowpc; /* lowpc from the profile file */
unsigned long s_highpc; /* highpc from the profile file */
-unsigned long lowpc, highpc; /* range profiled, in UNIT's */
+unsigned long lowpc, highpc; /* range profiled, in historical units */
unsigned sampbytes; /* number of bytes of samples */
int nsamples; /* number of samples */
double actime; /* accumulated time thus far for putprofline */
OpenPOWER on IntegriCloud