| 1 | /* sccsid: @(#)gprof.h 1.10 (Berkeley) %G% */ |
| 2 | |
| 3 | #include <stdio.h> |
| 4 | #include <sys/types.h> |
| 5 | #include <sys/stat.h> |
| 6 | #include <a.out.h> |
| 7 | #include <pagsiz.h> |
| 8 | #include "gcrt0.h" |
| 9 | |
| 10 | /* |
| 11 | * ticks per second |
| 12 | */ |
| 13 | #define HZ 60 |
| 14 | |
| 15 | typedef short UNIT; /* unit of profiling */ |
| 16 | char *a_outname; |
| 17 | #define A_OUTNAME "a.out" |
| 18 | |
| 19 | char *gmonname; |
| 20 | #define GMONNAME "gmon.out" |
| 21 | #define GMONSUM "gmon.sum" |
| 22 | |
| 23 | /* |
| 24 | * the directory where the descriptions of the fields |
| 25 | * of the profiles are kept. |
| 26 | */ |
| 27 | #define BLURBLIB "/usr/lib/" |
| 28 | |
| 29 | /* |
| 30 | * a constructed arc, |
| 31 | * with pointers to the namelist entry of the parent and the child, |
| 32 | * a count of how many times this arc was traversed, |
| 33 | * and pointers to the next parent of this child and |
| 34 | * the next child of this parent. |
| 35 | */ |
| 36 | struct arcstruct { |
| 37 | struct nl *arc_parentp; /* pointer to parent's nl entry */ |
| 38 | struct nl *arc_childp; /* pointer to child's nl entry */ |
| 39 | long arc_count; /* how calls from parent to child */ |
| 40 | double arc_time; /* time inherited along arc */ |
| 41 | double arc_childtime; /* childtime inherited along arc */ |
| 42 | struct arcstruct *arc_parentlist; /* parents-of-this-child list */ |
| 43 | struct arcstruct *arc_childlist; /* children-of-this-parent list */ |
| 44 | }; |
| 45 | typedef struct arcstruct arctype; |
| 46 | |
| 47 | /* |
| 48 | * The symbol table; |
| 49 | * for each external in the specified file we gather |
| 50 | * its address, the number of calls and compute its share of cpu time. |
| 51 | */ |
| 52 | struct nl { |
| 53 | char *name; /* the name */ |
| 54 | unsigned long value; /* the pc entry point */ |
| 55 | double time; /* ticks in this routine */ |
| 56 | double childtime; /* cumulative ticks in children */ |
| 57 | long ncall; /* how many times called */ |
| 58 | long selfcalls; /* how many calls to self */ |
| 59 | int index; /* index in the graph list */ |
| 60 | int toporder; /* graph call chain top-sort order */ |
| 61 | int cycleno; /* internal number of cycle on */ |
| 62 | struct nl *cyclehead; /* pointer to head of cycle */ |
| 63 | struct nl *cnext; /* pointer to next member of cycle */ |
| 64 | arctype *parents; /* list of caller arcs */ |
| 65 | arctype *children; /* list of callee arcs */ |
| 66 | }; |
| 67 | typedef struct nl nltype; |
| 68 | |
| 69 | nltype *nl; /* the whole namelist */ |
| 70 | nltype *npe; /* the virtual end of the namelist */ |
| 71 | int nname; /* the number of function names */ |
| 72 | |
| 73 | /* |
| 74 | * flag which marks a nl entry as topologically ``busy'' |
| 75 | */ |
| 76 | #define DFN_BUSY -1 |
| 77 | |
| 78 | /* |
| 79 | * the number of cycles is estimated as this fraction of nnames |
| 80 | * ncycles, the number of allocated cycle namelist entries, |
| 81 | * not to be confused with cyclemax, the number of discovered cycles. |
| 82 | */ |
| 83 | #define CYCLEFRACTION ( 0.10 ) |
| 84 | int ncycles; /* maximum allocated cycle headers */ |
| 85 | int cyclemax; /* number of cycles discovered */ |
| 86 | |
| 87 | /* |
| 88 | * The header on the gmon.out file. |
| 89 | * gmon.out consists of one of these headers, |
| 90 | * and then an array of ncnt samples |
| 91 | * representing the discretized program counter values. |
| 92 | * this should be a struct phdr, but since everything is done |
| 93 | * as UNITs, this is in UNITs too. |
| 94 | */ |
| 95 | struct hdr { |
| 96 | UNIT *lowpc; |
| 97 | UNIT *highpc; |
| 98 | int ncnt; |
| 99 | }; |
| 100 | |
| 101 | struct hdr h; |
| 102 | |
| 103 | int debug; |
| 104 | |
| 105 | /* |
| 106 | * Each discretized pc sample has |
| 107 | * a count of the number of samples in its range |
| 108 | */ |
| 109 | unsigned UNIT *samples; |
| 110 | |
| 111 | unsigned long s_lowpc; /* lowpc from the profile file */ |
| 112 | unsigned long s_highpc; /* highpc from the profile file */ |
| 113 | unsigned lowpc, highpc; /* range profiled, in UNIT's */ |
| 114 | unsigned sampbytes; /* number of bytes of samples */ |
| 115 | int nsamples; /* number of samples */ |
| 116 | double actime; /* accumulated time thus far for putprofline */ |
| 117 | double totime; /* total time for all routines */ |
| 118 | double scale; /* scale factor converting samples to pc |
| 119 | values: each sample covers scale bytes */ |
| 120 | char *strtab; /* string table in core */ |
| 121 | off_t ssiz; /* size of the string table */ |
| 122 | struct exec xbuf; /* exec header of a.out */ |
| 123 | unsigned char *textspace; /* text space of a.out in core */ |
| 124 | |
| 125 | /* |
| 126 | * option flags, from a to z. |
| 127 | */ |
| 128 | int aflag; /* static functions, too */ |
| 129 | int bflag; /* blurbs, too */ |
| 130 | int cflag; /* discovered call graph, too */ |
| 131 | int sflag; /* sum multiple gmon.out files */ |
| 132 | int zflag; /* zero time/called functions, too */ |
| 133 | |
| 134 | /* |
| 135 | * booleans |
| 136 | */ |
| 137 | typedef int bool; |
| 138 | #define FALSE 0 |
| 139 | #define TRUE 1 |
| 140 | |
| 141 | /* |
| 142 | * opcode of the `calls' instruction |
| 143 | */ |
| 144 | #define CALLS 0xfb |
| 145 | |
| 146 | /* |
| 147 | * register for pc relative addressing |
| 148 | */ |
| 149 | #define PC 0xf |
| 150 | |
| 151 | enum opermodes { |
| 152 | literal, indexed, reg, regdef, autodec, autoinc, autoincdef, |
| 153 | bytedisp, bytedispdef, worddisp, worddispdef, longdisp, longdispdef, |
| 154 | immediate, absolute, byterel, bytereldef, wordrel, wordreldef, |
| 155 | longrel, longreldef |
| 156 | }; |
| 157 | typedef enum opermodes operandenum; |
| 158 | |
| 159 | struct modebyte { |
| 160 | unsigned int regfield:4; |
| 161 | unsigned int modefield:4; |
| 162 | }; |
| 163 | |
| 164 | /* |
| 165 | * function declarations |
| 166 | */ |
| 167 | addarc(); |
| 168 | int arccmp(); |
| 169 | arctype *arclookup(); |
| 170 | asgnsamples(); |
| 171 | printblurb(); |
| 172 | cyclelink(); |
| 173 | dfn(); |
| 174 | bool dfn_busy(); |
| 175 | dfn_findcycle(); |
| 176 | bool dfn_numbered(); |
| 177 | dfn_post_visit(); |
| 178 | dfn_pre_visit(); |
| 179 | dfn_self_cycle(); |
| 180 | doarcs(); |
| 181 | done(); |
| 182 | findcalls(); |
| 183 | flatprofheader(); |
| 184 | flatprofline(); |
| 185 | bool funcsymbol(); |
| 186 | getnfile(); |
| 187 | getpfile(); |
| 188 | getstrtab(); |
| 189 | getsymtab(); |
| 190 | gettextspace(); |
| 191 | gprofheader(); |
| 192 | gprofline(); |
| 193 | main(); |
| 194 | unsigned long max(); |
| 195 | int membercmp(); |
| 196 | unsigned long min(); |
| 197 | nltype *nllookup(); |
| 198 | FILE *openpfile(); |
| 199 | long operandlength(); |
| 200 | operandenum operandmode(); |
| 201 | char *operandname(); |
| 202 | printchildren(); |
| 203 | printcycle(); |
| 204 | printgprof(); |
| 205 | printmembers(); |
| 206 | printname(); |
| 207 | printparents(); |
| 208 | printprof(); |
| 209 | readsamples(); |
| 210 | unsigned long reladdr(); |
| 211 | sortchildren(); |
| 212 | sortmembers(); |
| 213 | sortparents(); |
| 214 | tally(); |
| 215 | timecmp(); |
| 216 | topcmp(); |
| 217 | int totalcmp(); |
| 218 | valcmp(); |
| 219 | |
| 220 | #define LESSTHAN -1 |
| 221 | #define EQUALTO 0 |
| 222 | #define GREATERTHAN 1 |
| 223 | |
| 224 | #define DFNDEBUG 1 |
| 225 | #define CYCLEDEBUG 2 |
| 226 | #define ARCDEBUG 4 |
| 227 | #define TALLYDEBUG 8 |
| 228 | #define TIMEDEBUG 16 |
| 229 | #define SAMPLEDEBUG 32 |
| 230 | #define AOUTDEBUG 64 |
| 231 | #define CALLSDEBUG 128 |
| 232 | #define LOOKUPDEBUG 256 |
| 233 | #define ANYDEBUG 512 |