xref: /freebsd/usr.bin/gprof/gprof.h (revision bdcbfde31e8e9b343f113a1956384bdf30d1ed62)
18a16b7a1SPedro F. Giffuni /*-
28a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
38a16b7a1SPedro F. Giffuni  *
49b50d902SRodney W. Grimes  * Copyright (c) 1983, 1993
59b50d902SRodney W. Grimes  *	The Regents of the University of California.  All rights reserved.
69b50d902SRodney W. Grimes  *
79b50d902SRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
89b50d902SRodney W. Grimes  * modification, are permitted provided that the following conditions
99b50d902SRodney W. Grimes  * are met:
109b50d902SRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
119b50d902SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer.
129b50d902SRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
139b50d902SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer in the
149b50d902SRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
15fbbd9655SWarner Losh  * 3. Neither the name of the University nor the names of its contributors
169b50d902SRodney W. Grimes  *    may be used to endorse or promote products derived from this software
179b50d902SRodney W. Grimes  *    without specific prior written permission.
189b50d902SRodney W. Grimes  *
199b50d902SRodney W. Grimes  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
209b50d902SRodney W. Grimes  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
219b50d902SRodney W. Grimes  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
229b50d902SRodney W. Grimes  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
239b50d902SRodney W. Grimes  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
249b50d902SRodney W. Grimes  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
259b50d902SRodney W. Grimes  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
269b50d902SRodney W. Grimes  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
279b50d902SRodney W. Grimes  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
289b50d902SRodney W. Grimes  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
299b50d902SRodney W. Grimes  * SUCH DAMAGE.
309b50d902SRodney W. Grimes  */
319b50d902SRodney W. Grimes 
329b50d902SRodney W. Grimes #include <sys/types.h>
339b50d902SRodney W. Grimes #include <sys/stat.h>
349b50d902SRodney W. Grimes #include <sys/gmon.h>
359b50d902SRodney W. Grimes 
369b50d902SRodney W. Grimes #include <stdio.h>
379b50d902SRodney W. Grimes #include <stdlib.h>
389b50d902SRodney W. Grimes 
39*e7b841aeSAndrew Turner     /*
40*e7b841aeSAndrew Turner      *	offset (in bytes) of the code from the entry address of a routine.
41*e7b841aeSAndrew Turner      *	(see asgnsamples for use and explanation.)
42*e7b841aeSAndrew Turner      */
43*e7b841aeSAndrew Turner #define OFFSET_OF_CODE	0
44*e7b841aeSAndrew Turner 
45*e7b841aeSAndrew Turner enum opermodes { dummy };
46*e7b841aeSAndrew Turner typedef enum opermodes	operandenum;
479b50d902SRodney W. Grimes 
489b50d902SRodney W. Grimes     /*
499b50d902SRodney W. Grimes      * booleans
509b50d902SRodney W. Grimes      */
519b50d902SRodney W. Grimes typedef int	bool;
529b50d902SRodney W. Grimes #define	FALSE	0
539b50d902SRodney W. Grimes #define	TRUE	1
549b50d902SRodney W. Grimes 
559b50d902SRodney W. Grimes     /*
568109a9afSBruce Evans      *	Historical scale factor in profil(2)'s algorithm for converting
578109a9afSBruce Evans      *	pc addresses to bucket numbers.  This now just complicates the
588109a9afSBruce Evans      *	scaling and makes bucket:pc densities of more than 1/2 useless.
598109a9afSBruce Evans      */
608109a9afSBruce Evans #define	HISTORICAL_SCALE_2	2
618109a9afSBruce Evans 
62a86ddfe8SKyle Evans #ifndef EXTERN
63a86ddfe8SKyle Evans #define	EXTERN	extern
64a86ddfe8SKyle Evans #endif
65a86ddfe8SKyle Evans 
668109a9afSBruce Evans     /*
679b50d902SRodney W. Grimes      *	ticks per second
689b50d902SRodney W. Grimes      */
69a86ddfe8SKyle Evans EXTERN long	hz;
709b50d902SRodney W. Grimes 
71a86ddfe8SKyle Evans EXTERN size_t	histcounter_size;
72a86ddfe8SKyle Evans EXTERN int	histcounter_type;
734cd016e8SBruce Evans 
74a86ddfe8SKyle Evans EXTERN char	*a_outname;
759b50d902SRodney W. Grimes #define	A_OUTNAME		"a.out"
769b50d902SRodney W. Grimes 
77a86ddfe8SKyle Evans EXTERN char	*gmonname;
789b50d902SRodney W. Grimes #define	GMONSUM			"gmon.sum"
799b50d902SRodney W. Grimes 
809b50d902SRodney W. Grimes     /*
819b50d902SRodney W. Grimes      *	a constructed arc,
829b50d902SRodney W. Grimes      *	    with pointers to the namelist entry of the parent and the child,
839b50d902SRodney W. Grimes      *	    a count of how many times this arc was traversed,
849b50d902SRodney W. Grimes      *	    and pointers to the next parent of this child and
859b50d902SRodney W. Grimes      *		the next child of this parent.
869b50d902SRodney W. Grimes      */
879b50d902SRodney W. Grimes struct arcstruct {
889b50d902SRodney W. Grimes     struct nl		*arc_parentp;	/* pointer to parent's nl entry */
899b50d902SRodney W. Grimes     struct nl		*arc_childp;	/* pointer to child's nl entry */
909b50d902SRodney W. Grimes     long		arc_count;	/* num calls from parent to child */
919b50d902SRodney W. Grimes     double		arc_time;	/* time inherited along arc */
929b50d902SRodney W. Grimes     double		arc_childtime;	/* childtime inherited along arc */
939b50d902SRodney W. Grimes     struct arcstruct	*arc_parentlist; /* parents-of-this-child list */
949b50d902SRodney W. Grimes     struct arcstruct	*arc_childlist;	/* children-of-this-parent list */
959b50d902SRodney W. Grimes     struct arcstruct	*arc_next;	/* list of arcs on cycle */
969b50d902SRodney W. Grimes     unsigned short	arc_cyclecnt;	/* num cycles involved in */
979b50d902SRodney W. Grimes     unsigned short	arc_flags;	/* see below */
989b50d902SRodney W. Grimes };
999b50d902SRodney W. Grimes typedef struct arcstruct	arctype;
1009b50d902SRodney W. Grimes 
1019b50d902SRodney W. Grimes     /*
1029b50d902SRodney W. Grimes      * arc flags
1039b50d902SRodney W. Grimes      */
1049b50d902SRodney W. Grimes #define	DEADARC	0x01	/* time should not propagate across the arc */
1059b50d902SRodney W. Grimes #define	ONLIST	0x02	/* arc is on list of arcs in cycles */
1069b50d902SRodney W. Grimes 
1079b50d902SRodney W. Grimes     /*
1089b50d902SRodney W. Grimes      * The symbol table;
1099b50d902SRodney W. Grimes      * for each external in the specified file we gather
11097fa9b77SPhilippe Charnier      * its address, the number of calls and compute its share of CPU time.
1119b50d902SRodney W. Grimes      */
1129b50d902SRodney W. Grimes struct nl {
1135584f22bSJohn Polstra     const char		*name;		/* the name */
1149b50d902SRodney W. Grimes     unsigned long	value;		/* the pc entry point */
1159b50d902SRodney W. Grimes     unsigned long	svalue;		/* entry point aligned to histograms */
1169b50d902SRodney W. Grimes     double		time;		/* ticks in this routine */
1179b50d902SRodney W. Grimes     double		childtime;	/* cumulative ticks in children */
1189b50d902SRodney W. Grimes     long		ncall;		/* how many times called */
1199b50d902SRodney W. Grimes     long		npropcall;	/* times called by live arcs */
1209b50d902SRodney W. Grimes     long		selfcalls;	/* how many calls to self */
1219b50d902SRodney W. Grimes     double		propfraction;	/* what % of time propagates */
1229b50d902SRodney W. Grimes     double		propself;	/* how much self time propagates */
1239b50d902SRodney W. Grimes     double		propchild;	/* how much child time propagates */
1249b50d902SRodney W. Grimes     short		printflag;	/* should this be printed? */
1259b50d902SRodney W. Grimes     short		flags;		/* see below */
1269b50d902SRodney W. Grimes     int			index;		/* index in the graph list */
1279b50d902SRodney W. Grimes     int			toporder;	/* graph call chain top-sort order */
1289b50d902SRodney W. Grimes     int			cycleno;	/* internal number of cycle on */
1299b50d902SRodney W. Grimes     int			parentcnt;	/* number of live parent arcs */
1309b50d902SRodney W. Grimes     struct nl		*cyclehead;	/* pointer to head of cycle */
1319b50d902SRodney W. Grimes     struct nl		*cnext;		/* pointer to next member of cycle */
1329b50d902SRodney W. Grimes     arctype		*parents;	/* list of caller arcs */
1339b50d902SRodney W. Grimes     arctype		*children;	/* list of callee arcs */
1349b50d902SRodney W. Grimes };
1359b50d902SRodney W. Grimes typedef struct nl	nltype;
1369b50d902SRodney W. Grimes 
137a86ddfe8SKyle Evans EXTERN nltype	*nl;			/* the whole namelist */
138a86ddfe8SKyle Evans EXTERN nltype	*npe;			/* the virtual end of the namelist */
139a86ddfe8SKyle Evans EXTERN int	nname;			/* the number of function names */
1409b50d902SRodney W. Grimes 
1419b50d902SRodney W. Grimes #define	HASCYCLEXIT	0x08	/* node has arc exiting from cycle */
1429b50d902SRodney W. Grimes #define	CYCLEHEAD	0x10	/* node marked as head of a cycle */
1439b50d902SRodney W. Grimes #define	VISITED		0x20	/* node visited during a cycle */
1449b50d902SRodney W. Grimes 
1459b50d902SRodney W. Grimes     /*
1469b50d902SRodney W. Grimes      * The cycle list.
1479b50d902SRodney W. Grimes      * for each subcycle within an identified cycle, we gather
1489b50d902SRodney W. Grimes      * its size and the list of included arcs.
1499b50d902SRodney W. Grimes      */
1509b50d902SRodney W. Grimes struct cl {
1519b50d902SRodney W. Grimes     int		size;		/* length of cycle */
1529b50d902SRodney W. Grimes     struct cl	*next;		/* next member of list */
1539b50d902SRodney W. Grimes     arctype	*list[1];	/* list of arcs in cycle */
1549b50d902SRodney W. Grimes     /* actually longer */
1559b50d902SRodney W. Grimes };
1569b50d902SRodney W. Grimes typedef struct cl cltype;
1579b50d902SRodney W. Grimes 
158a86ddfe8SKyle Evans EXTERN arctype	*archead;	/* the head of arcs in current cycle list */
159a86ddfe8SKyle Evans EXTERN cltype	*cyclehead;	/* the head of the list */
160a86ddfe8SKyle Evans EXTERN int	cyclecnt;	/* the number of cycles found */
1619b50d902SRodney W. Grimes #define	CYCLEMAX	100	/* maximum cycles before cutting one of them */
1629b50d902SRodney W. Grimes 
1639b50d902SRodney W. Grimes     /*
1649b50d902SRodney W. Grimes      *	flag which marks a nl entry as topologically ``busy''
1659b50d902SRodney W. Grimes      *	flag which marks a nl entry as topologically ``not_numbered''
1669b50d902SRodney W. Grimes      */
1679b50d902SRodney W. Grimes #define	DFN_BUSY	-1
1689b50d902SRodney W. Grimes #define	DFN_NAN		0
1699b50d902SRodney W. Grimes 
1709b50d902SRodney W. Grimes     /*
1719b50d902SRodney W. Grimes      *	namelist entries for cycle headers.
1729b50d902SRodney W. Grimes      *	the number of discovered cycles.
1739b50d902SRodney W. Grimes      */
174a86ddfe8SKyle Evans EXTERN nltype	*cyclenl;		/* cycle header namelist */
175a86ddfe8SKyle Evans EXTERN int	ncycle;			/* number of cycles discovered */
1769b50d902SRodney W. Grimes 
1779b50d902SRodney W. Grimes     /*
1789b50d902SRodney W. Grimes      * The header on the gmon.out file.
1799b50d902SRodney W. Grimes      * gmon.out consists of a struct phdr (defined in gmon.h)
1809b50d902SRodney W. Grimes      * and then an array of ncnt samples representing the
1819b50d902SRodney W. Grimes      * discretized program counter values.
1829b50d902SRodney W. Grimes      *
1839b50d902SRodney W. Grimes      *	Backward compatible old style header
1849b50d902SRodney W. Grimes      */
1859b50d902SRodney W. Grimes struct ophdr {
186275ffbc6SBruce Evans     u_short	*lpc;
187275ffbc6SBruce Evans     u_short	*hpc;
1889b50d902SRodney W. Grimes     int		ncnt;
1899b50d902SRodney W. Grimes };
1909b50d902SRodney W. Grimes 
191a86ddfe8SKyle Evans EXTERN int	debug;
1929b50d902SRodney W. Grimes 
1939b50d902SRodney W. Grimes     /*
1949b50d902SRodney W. Grimes      * Each discretized pc sample has
1959b50d902SRodney W. Grimes      * a count of the number of samples in its range
1969b50d902SRodney W. Grimes      */
197a86ddfe8SKyle Evans EXTERN double	*samples;
1989b50d902SRodney W. Grimes 
199a86ddfe8SKyle Evans EXTERN unsigned long	s_lowpc;	/* lowpc from the profile file */
200a86ddfe8SKyle Evans EXTERN unsigned long	s_highpc;	/* highpc from the profile file */
201a86ddfe8SKyle Evans /* range profiled, in historical units  */
202a86ddfe8SKyle Evans EXTERN unsigned long	lowpc, highpc;
203a86ddfe8SKyle Evans EXTERN unsigned sampbytes;		/* number of bytes of samples */
204a86ddfe8SKyle Evans EXTERN int	nsamples;		/* number of samples */
205a86ddfe8SKyle Evans /* accumulated time thus far for putprofline */
206a86ddfe8SKyle Evans EXTERN double	actime;
207a86ddfe8SKyle Evans EXTERN double	totime;			/* total time for all routines */
208a86ddfe8SKyle Evans EXTERN double	printtime;		/* total of time being printed */
209a86ddfe8SKyle Evans EXTERN double	scale;			/* scale factor converting samples to pc
2109b50d902SRodney W. Grimes 				   values: each sample covers scale bytes */
211a86ddfe8SKyle Evans EXTERN unsigned char	*textspace;	/* text space of a.out in core */
212a86ddfe8SKyle Evans /* with -C, minimum cycle size to ignore */
213a86ddfe8SKyle Evans EXTERN int	cyclethreshold;
2149b50d902SRodney W. Grimes 
2159b50d902SRodney W. Grimes     /*
2169b50d902SRodney W. Grimes      *	option flags, from a to z.
2179b50d902SRodney W. Grimes      */
218a86ddfe8SKyle Evans EXTERN bool	aflag;			/* suppress static functions */
219a86ddfe8SKyle Evans EXTERN bool	bflag;			/* blurbs, too */
220a86ddfe8SKyle Evans EXTERN bool	Cflag;			/* find cut-set to eliminate cycles */
221a86ddfe8SKyle Evans EXTERN bool	dflag;			/* debugging options */
222a86ddfe8SKyle Evans EXTERN bool	eflag;			/* specific functions excluded */
223a86ddfe8SKyle Evans EXTERN bool	Eflag;			/* functions excluded with time */
224a86ddfe8SKyle Evans EXTERN bool	fflag;			/* specific functions requested */
225a86ddfe8SKyle Evans EXTERN bool	Fflag;			/* functions requested with time */
226a86ddfe8SKyle Evans EXTERN bool	kflag;			/* arcs to be deleted */
227a86ddfe8SKyle Evans EXTERN bool	Kflag;			/* use the running kernel for symbols */
228a86ddfe8SKyle Evans EXTERN bool	sflag;			/* sum multiple gmon.out files */
229a86ddfe8SKyle Evans EXTERN bool	uflag;			/* suppress symbols hidden from C */
230a86ddfe8SKyle Evans EXTERN bool	zflag;			/* zero time/called functions, too */
2319b50d902SRodney W. Grimes 
2329b50d902SRodney W. Grimes     /*
2339b50d902SRodney W. Grimes      *	structure for various string lists
2349b50d902SRodney W. Grimes      */
2359b50d902SRodney W. Grimes struct stringlist {
2369b50d902SRodney W. Grimes     struct stringlist	*next;
2379b50d902SRodney W. Grimes     char		*string;
2389b50d902SRodney W. Grimes };
239a86ddfe8SKyle Evans extern struct stringlist	*elist;
240a86ddfe8SKyle Evans extern struct stringlist	*Elist;
241a86ddfe8SKyle Evans extern struct stringlist	*flist;
242a86ddfe8SKyle Evans extern struct stringlist	*Flist;
243a86ddfe8SKyle Evans extern struct stringlist	*kfromlist;
244a86ddfe8SKyle Evans extern struct stringlist	*ktolist;
2459b50d902SRodney W. Grimes 
2469b50d902SRodney W. Grimes     /*
2479b50d902SRodney W. Grimes      *	function declarations
2489b50d902SRodney W. Grimes      */
24997fa9b77SPhilippe Charnier void		addarc(nltype *, nltype *, long);
25097fa9b77SPhilippe Charnier bool		addcycle(arctype **, arctype **);
25197fa9b77SPhilippe Charnier void		addlist(struct stringlist *, char *);
25297fa9b77SPhilippe Charnier void		alignentries(void);
253af2637dbSPhilippe Charnier int		arccmp(arctype *, arctype *);
254af2637dbSPhilippe Charnier arctype		*arclookup(nltype *, nltype *);
25597fa9b77SPhilippe Charnier void		asgnsamples(void);
25697fa9b77SPhilippe Charnier void		compresslist(void);
25797fa9b77SPhilippe Charnier bool		cycleanalyze(void);
25897fa9b77SPhilippe Charnier void		cyclelink(void);
25997fa9b77SPhilippe Charnier void		cycletime(void);
26097fa9b77SPhilippe Charnier bool		descend(nltype *, arctype **, arctype **);
26197fa9b77SPhilippe Charnier void		dfn(nltype *);
262af2637dbSPhilippe Charnier bool		dfn_busy(nltype *);
26397fa9b77SPhilippe Charnier void		dfn_findcycle(nltype *);
26497fa9b77SPhilippe Charnier void		dfn_init(void);
265af2637dbSPhilippe Charnier bool		dfn_numbered(nltype *);
26697fa9b77SPhilippe Charnier void		dfn_post_visit(nltype *);
26797fa9b77SPhilippe Charnier void		dfn_pre_visit(nltype *);
26897fa9b77SPhilippe Charnier void		dfn_self_cycle(nltype *);
269af2637dbSPhilippe Charnier nltype		**doarcs(void);
27097fa9b77SPhilippe Charnier void		doflags(void);
27197fa9b77SPhilippe Charnier void		dotime(void);
272af2637dbSPhilippe Charnier void		dumpsum(const char *);
2735584f22bSJohn Polstra int		elf_getnfile(const char *, char ***);
27497fa9b77SPhilippe Charnier void		flatprofheader(void);
27597fa9b77SPhilippe Charnier void		flatprofline(nltype *);
27697fa9b77SPhilippe Charnier void		getpfile(char *);
277af2637dbSPhilippe Charnier void		gprofheader(void);
278af2637dbSPhilippe Charnier void		gprofline(register nltype *);
279bd6da6a5SStefan Farfeleder int		hertz(void);
28097fa9b77SPhilippe Charnier void		inheritflags(nltype *);
2813fc980b1SBrian Feldman int		kernel_getnfile(const char *, char ***);
2823fc980b1SBrian Feldman /*
2839b50d902SRodney W. Grimes 		main();
2849b50d902SRodney W. Grimes */
285af2637dbSPhilippe Charnier unsigned long	max(unsigned long, unsigned long);
286af2637dbSPhilippe Charnier int		membercmp(nltype *, nltype *);
287af2637dbSPhilippe Charnier unsigned long	min(unsigned long, unsigned long);
288af2637dbSPhilippe Charnier nltype		*nllookup(unsigned long);
28997fa9b77SPhilippe Charnier bool		onlist(struct stringlist *, const char *);
290af2637dbSPhilippe Charnier FILE		*openpfile(char *);
291af2637dbSPhilippe Charnier void		printblurb(const char *);
29297fa9b77SPhilippe Charnier void		printchildren(nltype *);
29397fa9b77SPhilippe Charnier void		printcycle(nltype *);
29497fa9b77SPhilippe Charnier void		printgprof(nltype **);
29597fa9b77SPhilippe Charnier void		printindex(void);
29697fa9b77SPhilippe Charnier void		printmembers(nltype *);
29797fa9b77SPhilippe Charnier void		printname(nltype *);
29897fa9b77SPhilippe Charnier void		printparents(nltype *);
29997fa9b77SPhilippe Charnier void		printprof(void);
30097fa9b77SPhilippe Charnier void		printsubcycle(cltype *);
30197fa9b77SPhilippe Charnier void		readsamples(FILE *);
30297fa9b77SPhilippe Charnier void		sortchildren(nltype *);
30397fa9b77SPhilippe Charnier void		sortmembers(nltype *);
30497fa9b77SPhilippe Charnier void		sortparents(nltype *);
30597fa9b77SPhilippe Charnier void		tally(struct rawarc *);
30697fa9b77SPhilippe Charnier void		timepropagate(nltype *);
307af2637dbSPhilippe Charnier int		totalcmp(const void *, const void *);
3089b50d902SRodney W. Grimes 
3099b50d902SRodney W. Grimes #define	LESSTHAN	-1
3109b50d902SRodney W. Grimes #define	EQUALTO		0
3119b50d902SRodney W. Grimes #define	GREATERTHAN	1
3129b50d902SRodney W. Grimes 
3139b50d902SRodney W. Grimes #define	DFNDEBUG	1
3149b50d902SRodney W. Grimes #define	CYCLEDEBUG	2
3159b50d902SRodney W. Grimes #define	ARCDEBUG	4
3169b50d902SRodney W. Grimes #define	TALLYDEBUG	8
3179b50d902SRodney W. Grimes #define	TIMEDEBUG	16
3189b50d902SRodney W. Grimes #define	SAMPLEDEBUG	32
3199b50d902SRodney W. Grimes #define	CALLDEBUG	128
3209b50d902SRodney W. Grimes #define	LOOKUPDEBUG	256
3219b50d902SRodney W. Grimes #define	PROPDEBUG	512
3229b50d902SRodney W. Grimes #define	BREAKCYCLE	1024
3239b50d902SRodney W. Grimes #define	SUBCYCLELIST	2048
3249b50d902SRodney W. Grimes #define	ANYDEBUG	4096
325