[BACK]Return to gprof.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / gprof

Annotation of src/usr.bin/gprof/gprof.c, Revision 1.27

1.27    ! deraadt     1: /*     $OpenBSD: gprof.c,v 1.26 2016/10/08 19:55:39 guenther Exp $     */
1.1       deraadt     2: /*     $NetBSD: gprof.c,v 1.8 1995/04/19 07:15:59 cgd Exp $    */
                      3:
                      4: /*
                      5:  * Copyright (c) 1983, 1993
                      6:  *     The Regents of the University of California.  All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
1.12      millert    16:  * 3. Neither the name of the University nor the names of its contributors
1.1       deraadt    17:  *    may be used to endorse or promote products derived from this software
                     18:  *    without specific prior written permission.
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     21:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     22:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     23:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     24:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     25:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     26:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     27:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     28:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     29:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     30:  * SUCH DAMAGE.
                     31:  */
                     32:
                     33: #include "gprof.h"
                     34:
1.11      art        35: int valcmp(const void *, const void *);
1.1       deraadt    36:
                     37: static struct gmonhdr  gmonhdr;
1.8       mickey     38: extern char *__progname;
1.27    ! deraadt    39:
        !            40: long    hz;
        !            41: char    *a_outname;
        !            42: char    *gmonname;
        !            43: nltype  *nl;                    /* the whole namelist */
        !            44: nltype  *npe;                   /* the virtual end of the namelist */
        !            45: int     nname;                  /* the number of function names */
        !            46: arctype *archead;               /* the head of arcs in current cycle list */
        !            47: cltype  *cyclehead;             /* the head of the list */
        !            48: int     cyclecnt;               /* the number of cycles found */
        !            49: nltype  *cyclenl;               /* cycle header namelist */
        !            50: int     ncycle;                 /* number of cycles discovered */
        !            51: int     debug;
        !            52: UNIT    *samples;
        !            53: unsigned long   s_lowpc;        /* lowpc from the profile file */
        !            54: unsigned long   s_highpc;       /* highpc from the profile file */
        !            55: unsigned long   lowpc, highpc;  /* range profiled, in UNIT's */
        !            56: unsigned sampbytes;             /* number of bytes of samples */
        !            57: int     nsamples;               /* number of samples */
        !            58: double  actime;                 /* accumulated time thus far for putprofline */
        !            59: double  totime;                 /* total time for all routines */
        !            60: double  printtime;              /* total of time being printed */
        !            61: double  scale;                  /* scale factor converting samples to pc */
        !            62: unsigned char   *textspace;     /* text space of a.out in core */
        !            63: int     cyclethreshold;         /* with -C, minimum cycle size to ignore */
        !            64: bool    aflag;                          /* suppress static functions */
        !            65: bool    bflag;                          /* blurbs, too */
        !            66: bool    cflag;                          /* discovered call graph, too */
        !            67: bool    Cflag;                          /* find cut-set to eliminate cycles */
        !            68: bool    dflag;                          /* debugging options */
        !            69: bool    eflag;                          /* specific functions excluded */
        !            70: bool    Eflag;                          /* functions excluded with time */
        !            71: bool    fflag;                          /* specific functions requested */
        !            72: bool    Fflag;                          /* functions requested with time */
        !            73: bool    kflag;                          /* arcs to be deleted */
        !            74: bool    sflag;                          /* sum multiple gmon.out files */
        !            75: bool    zflag;                          /* zero time/called functions, too */
1.1       deraadt    76:
1.7       mickey     77: int
1.13      deraadt    78: main(int argc, char *argv[])
1.1       deraadt    79: {
                     80:     char       **sp;
                     81:     nltype     **timesortnlp;
1.11      art        82:     char       **defaultEs;
1.1       deraadt    83:
1.23      pascal     84:     if (pledge("stdio rpath wpath cpath", NULL) == -1)
                     85:         err(1, NULL);
                     86:
1.1       deraadt    87:     --argc;
                     88:     argv++;
                     89:     debug = 0;
                     90:     bflag = TRUE;
                     91:     while ( *argv != 0 && **argv == '-' ) {
                     92:        (*argv)++;
                     93:        switch ( **argv ) {
                     94:        case 'a':
                     95:            aflag = TRUE;
                     96:            break;
                     97:        case 'b':
                     98:            bflag = FALSE;
                     99:            break;
                    100:        case 'C':
                    101:            Cflag = TRUE;
                    102:            cyclethreshold = atoi( *++argv );
                    103:            break;
                    104:        case 'c':
1.26      guenther  105: #if defined(__i386__) || defined(__mips64__)
1.1       deraadt   106:            cflag = TRUE;
                    107: #else
1.7       mickey    108:            fprintf(stderr, "%s: -c isn't supported on this architecture yet\n", __progname);
1.1       deraadt   109:            exit(1);
                    110: #endif
                    111:            break;
                    112:        case 'd':
                    113:            dflag = TRUE;
1.20      millert   114:            setvbuf(stdout, NULL, _IOLBF, 0);
1.1       deraadt   115:            debug |= atoi( *++argv );
                    116:            debug |= ANYDEBUG;
                    117: #          ifdef DEBUG
                    118:                printf("[main] debug = %d\n", debug);
1.10      danh      119: #          else /* not DEBUG */
1.7       mickey    120:                warnx("-d ignored");
1.10      danh      121: #          endif /* DEBUG */
1.1       deraadt   122:            break;
                    123:        case 'E':
                    124:            ++argv;
                    125:            addlist( Elist , *argv );
                    126:            Eflag = TRUE;
                    127:            addlist( elist , *argv );
                    128:            eflag = TRUE;
                    129:            break;
                    130:        case 'e':
                    131:            addlist( elist , *++argv );
                    132:            eflag = TRUE;
                    133:            break;
                    134:        case 'F':
                    135:            ++argv;
                    136:            addlist( Flist , *argv );
                    137:            Fflag = TRUE;
                    138:            addlist( flist , *argv );
                    139:            fflag = TRUE;
                    140:            break;
                    141:        case 'f':
                    142:            addlist( flist , *++argv );
                    143:            fflag = TRUE;
                    144:            break;
                    145:        case 'k':
                    146:            addlist( kfromlist , *++argv );
                    147:            addlist( ktolist , *++argv );
                    148:            kflag = TRUE;
                    149:            break;
                    150:        case 's':
                    151:            sflag = TRUE;
                    152:            break;
                    153:        case 'z':
                    154:            zflag = TRUE;
                    155:            break;
                    156:        }
                    157:        argv++;
                    158:     }
                    159:     if ( *argv != 0 ) {
                    160:        a_outname  = *argv;
                    161:        argv++;
                    162:     } else {
                    163:        a_outname  = A_OUTNAME;
                    164:     }
                    165:     if ( *argv != 0 ) {
                    166:        gmonname = *argv;
                    167:        argv++;
                    168:     } else {
                    169:        gmonname = GMONNAME;
1.23      pascal    170:     }
                    171:     if ( sflag == FALSE ) {
                    172:         if (pledge("stdio rpath", NULL) == -1)
                    173:             err(1, "pledge");
1.1       deraadt   174:     }
                    175:        /*
1.11      art       176:         *      get information about a.out file.
                    177:         */
                    178:     if (getnfile(a_outname, &defaultEs) == -1)
                    179:        errx(1, "%s: bad format", a_outname);
                    180:        /*
                    181:         *      sort symbol table.
                    182:         */
                    183:     qsort(nl, nname, sizeof(nltype), valcmp);
                    184:        /*
1.1       deraadt   185:         *      turn off default functions
                    186:         */
                    187:     for ( sp = &defaultEs[0] ; *sp ; sp++ ) {
                    188:        Eflag = TRUE;
                    189:        addlist( Elist , *sp );
                    190:        eflag = TRUE;
                    191:        addlist( elist , *sp );
                    192:     }
                    193:        /*
                    194:         *      get information about mon.out file(s).
                    195:         */
                    196:     do {
                    197:        getpfile( gmonname );
                    198:        if ( *argv != 0 ) {
                    199:            gmonname = *argv;
                    200:        }
                    201:     } while ( *argv++ != 0 );
                    202:        /*
                    203:         *      how many ticks per second?
                    204:         *      if we can't tell, report time in ticks.
                    205:         */
                    206:     if (hz == 0) {
                    207:        hz = 1;
1.7       mickey    208:        warnx("time is in ticks, not seconds");
1.1       deraadt   209:     }
                    210:        /*
                    211:         *      dump out a gmon.sum file if requested
                    212:         */
                    213:     if ( sflag ) {
                    214:        dumpsum( GMONSUM );
                    215:     }
                    216:        /*
                    217:         *      assign samples to procedures
                    218:         */
                    219:     asgnsamples();
                    220:        /*
                    221:         *      assemble the dynamic profile
                    222:         */
                    223:     timesortnlp = doarcs();
                    224:        /*
                    225:         *      print the dynamic profile
                    226:         */
                    227:     printgprof( timesortnlp );
                    228:        /*
                    229:         *      print the flat profile
                    230:         */
                    231:     printprof();
                    232:        /*
                    233:         *      print the index
                    234:         */
                    235:     printindex();
1.7       mickey    236:
                    237:     return (0);
1.1       deraadt   238: }
                    239:
                    240:     /*
                    241:      * information from a gmon.out file is in two parts:
                    242:      * an array of sampling hits within pc ranges,
                    243:      * and the arcs.
                    244:      */
1.7       mickey    245: void
1.17      espie     246: getpfile(const char *filename)
1.1       deraadt   247: {
                    248:     FILE               *pfile;
                    249:     struct rawarc      arc;
                    250:
                    251:     pfile = openpfile(filename);
                    252:     readsamples(pfile);
                    253:        /*
                    254:         *      the rest of the file consists of
                    255:         *      a bunch of <from,self,count> tuples.
                    256:         */
                    257:     while ( fread( &arc , sizeof arc , 1 , pfile ) == 1 ) {
                    258: #      ifdef DEBUG
                    259:            if ( debug & SAMPLEDEBUG ) {
1.14      art       260:                printf( "[getpfile] frompc 0x%lx selfpc 0x%lx count %ld\n" ,
1.1       deraadt   261:                        arc.raw_frompc , arc.raw_selfpc , arc.raw_count );
                    262:            }
1.10      danh      263: #      endif /* DEBUG */
1.1       deraadt   264:            /*
                    265:             *  add this arc
                    266:             */
                    267:        tally( &arc );
                    268:     }
                    269:     fclose(pfile);
                    270: }
                    271:
                    272: FILE *
1.17      espie     273: openpfile(const char *filename)
1.1       deraadt   274: {
                    275:     struct gmonhdr     tmp;
                    276:     FILE               *pfile;
                    277:     int                        size;
                    278:     int                        rate;
                    279:
1.7       mickey    280:     if((pfile = fopen(filename, "r")) == NULL)
                    281:        err(1, "fopen: %s", filename);
1.16      millert   282:     if (fread(&tmp, sizeof(struct gmonhdr), 1, pfile) != 1)
                    283:        errx(1, "%s: bad gmon header", filename);
1.1       deraadt   284:     if ( s_highpc != 0 && ( tmp.lpc != gmonhdr.lpc ||
1.7       mickey    285:         tmp.hpc != gmonhdr.hpc || tmp.ncnt != gmonhdr.ncnt))
                    286:        errx(1, "%s: incompatible with first gmon file", filename);
1.1       deraadt   287:     gmonhdr = tmp;
                    288:     if ( gmonhdr.version == GMONVERSION ) {
                    289:        rate = gmonhdr.profrate;
                    290:        size = sizeof(struct gmonhdr);
                    291:     } else {
                    292:        fseek(pfile, sizeof(struct ophdr), SEEK_SET);
                    293:        size = sizeof(struct ophdr);
                    294:        gmonhdr.profrate = rate = hertz();
                    295:        gmonhdr.version = GMONVERSION;
                    296:     }
                    297:     if (hz == 0) {
                    298:        hz = rate;
1.7       mickey    299:     } else if (hz != rate)
                    300:        errx(1, "%s: profile clock rate (%d) incompatible with clock rate "
                    301:            "(%ld) in first gmon file", filename, rate, hz);
1.1       deraadt   302:     s_lowpc = (unsigned long) gmonhdr.lpc;
                    303:     s_highpc = (unsigned long) gmonhdr.hpc;
                    304:     lowpc = (unsigned long)gmonhdr.lpc / sizeof(UNIT);
                    305:     highpc = (unsigned long)gmonhdr.hpc / sizeof(UNIT);
                    306:     sampbytes = gmonhdr.ncnt - size;
                    307:     nsamples = sampbytes / sizeof (UNIT);
                    308: #   ifdef DEBUG
                    309:        if ( debug & SAMPLEDEBUG ) {
1.14      art       310:            printf( "[openpfile] hdr.lpc 0x%lx hdr.hpc 0x%lx hdr.ncnt %d\n",
1.1       deraadt   311:                gmonhdr.lpc , gmonhdr.hpc , gmonhdr.ncnt );
1.14      art       312:            printf( "[openpfile]   s_lowpc 0x%lx   s_highpc 0x%lx\n" ,
1.1       deraadt   313:                s_lowpc , s_highpc );
1.14      art       314:            printf( "[openpfile]     lowpc 0x%lx     highpc 0x%lx\n" ,
1.1       deraadt   315:                lowpc , highpc );
                    316:            printf( "[openpfile] sampbytes %d nsamples %d\n" ,
                    317:                sampbytes , nsamples );
1.14      art       318:            printf( "[openpfile] sample rate %ld\n" , hz );
1.1       deraadt   319:        }
1.10      danh      320: #   endif /* DEBUG */
1.1       deraadt   321:     return(pfile);
                    322: }
                    323:
1.7       mickey    324: void
1.13      deraadt   325: tally(struct rawarc *rawp)
1.1       deraadt   326: {
                    327:     nltype             *parentp;
                    328:     nltype             *childp;
                    329:
                    330:     parentp = nllookup( rawp -> raw_frompc );
                    331:     childp = nllookup( rawp -> raw_selfpc );
                    332:     if ( parentp == 0 || childp == 0 )
                    333:        return;
                    334:     if ( kflag
                    335:         && onlist( kfromlist , parentp -> name )
                    336:         && onlist( ktolist , childp -> name ) ) {
                    337:        return;
                    338:     }
                    339:     childp -> ncall += rawp -> raw_count;
                    340: #   ifdef DEBUG
                    341:        if ( debug & TALLYDEBUG ) {
1.14      art       342:            printf( "[tally] arc from %s to %s traversed %ld times\n" ,
1.1       deraadt   343:                    parentp -> name , childp -> name , rawp -> raw_count );
                    344:        }
1.10      danh      345: #   endif /* DEBUG */
1.1       deraadt   346:     addarc( parentp , childp , rawp -> raw_count );
                    347: }
                    348:
                    349: /*
                    350:  * dump out the gmon.sum file
                    351:  */
1.7       mickey    352: void
1.17      espie     353: dumpsum(const char *sumfile)
1.1       deraadt   354: {
1.9       mpech     355:     nltype *nlp;
                    356:     arctype *arcp;
1.1       deraadt   357:     struct rawarc arc;
                    358:     FILE *sfile;
                    359:
1.7       mickey    360:     if ( ( sfile = fopen ( sumfile , "w" ) ) == NULL )
                    361:        err(1, "fopen: %s", sumfile);
1.1       deraadt   362:     /*
                    363:      * dump the header; use the last header read in
                    364:      */
1.7       mickey    365:     if ( fwrite( &gmonhdr , sizeof gmonhdr , 1 , sfile ) != 1 )
                    366:        err(1, "fwrite: %s", sumfile);
1.1       deraadt   367:     /*
                    368:      * dump the samples
                    369:      */
1.7       mickey    370:     if (fwrite(samples, sizeof (UNIT), nsamples, sfile) != nsamples)
                    371:        err(1, "fwrite: %s", sumfile);
1.1       deraadt   372:     /*
                    373:      * dump the normalized raw arc information
                    374:      */
                    375:     for ( nlp = nl ; nlp < npe ; nlp++ ) {
                    376:        for ( arcp = nlp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
                    377:            arc.raw_frompc = arcp -> arc_parentp -> value;
                    378:            arc.raw_selfpc = arcp -> arc_childp -> value;
                    379:            arc.raw_count = arcp -> arc_count;
1.7       mickey    380:            if (fwrite ( &arc , sizeof arc , 1 , sfile ) != 1)
                    381:                err(1, "fwrite: %s", sumfile);
1.1       deraadt   382: #          ifdef DEBUG
                    383:                if ( debug & SAMPLEDEBUG ) {
1.14      art       384:                    printf( "[dumpsum] frompc 0x%lx selfpc 0x%lx count %ld\n" ,
1.1       deraadt   385:                            arc.raw_frompc , arc.raw_selfpc , arc.raw_count );
                    386:                }
1.10      danh      387: #          endif /* DEBUG */
1.1       deraadt   388:        }
                    389:     }
                    390:     fclose( sfile );
                    391: }
                    392:
1.7       mickey    393: int
1.11      art       394: valcmp(const void *vp1, const void *vp2)
1.1       deraadt   395: {
1.11      art       396:     const nltype *p1 = vp1;
                    397:     const nltype *p2 = vp2;
                    398:
1.1       deraadt   399:     if ( p1 -> value < p2 -> value ) {
                    400:        return LESSTHAN;
                    401:     }
                    402:     if ( p1 -> value > p2 -> value ) {
                    403:        return GREATERTHAN;
                    404:     }
                    405:     return EQUALTO;
                    406: }
                    407:
1.7       mickey    408: void
1.13      deraadt   409: readsamples(FILE *pfile)
1.1       deraadt   410: {
                    411:     UNIT       sample;
1.9       mpech     412:     int i;
1.1       deraadt   413:
                    414:     if (samples == 0) {
1.22      deraadt   415:        samples = calloc(sampbytes, sizeof (UNIT));
1.7       mickey    416:        if (samples == 0)
1.14      art       417:            errx(1, "No room for %ld sample pc's", sampbytes / sizeof (UNIT));
1.1       deraadt   418:     }
                    419:     for (i = 0; i < nsamples; i++) {
                    420:        fread(&sample, sizeof (UNIT), 1, pfile);
                    421:        if (feof(pfile))
                    422:                break;
                    423:        samples[i] += sample;
                    424:     }
1.7       mickey    425:     if (i != nsamples)
                    426:        errx(1, "unexpected EOF after reading %d/%d samples", i, nsamples );
1.1       deraadt   427: }
                    428:
                    429: /*
                    430:  *     Assign samples to the procedures to which they belong.
                    431:  *
                    432:  *     There are three cases as to where pcl and pch can be
                    433:  *     with respect to the routine entry addresses svalue0 and svalue1
                    434:  *     as shown in the following diagram.  overlap computes the
                    435:  *     distance between the arrows, the fraction of the sample
                    436:  *     that is to be credited to the routine which starts at svalue0.
                    437:  *
                    438:  *         svalue0                                         svalue1
                    439:  *            |                                               |
                    440:  *            v                                               v
                    441:  *
                    442:  *            +-----------------------------------------------+
                    443:  *            |                                               |
                    444:  *       |  ->|    |<-         ->|         |<-         ->|    |<-  |
                    445:  *       |         |             |         |             |         |
                    446:  *       +---------+             +---------+             +---------+
                    447:  *
                    448:  *       ^         ^             ^         ^             ^         ^
                    449:  *       |         |             |         |             |         |
                    450:  *      pcl       pch           pcl       pch           pcl       pch
                    451:  *
                    452:  *     For the vax we assert that samples will never fall in the first
                    453:  *     two bytes of any routine, since that is the entry mask,
                    454:  *     thus we give call alignentries() to adjust the entry points if
                    455:  *     the entry mask falls in one bucket but the code for the routine
                    456:  *     doesn't start until the next bucket.  In conjunction with the
                    457:  *     alignment of routine addresses, this should allow us to have
                    458:  *     only one sample for every four bytes of text space and never
                    459:  *     have any overlap (the two end cases, above).
                    460:  */
1.7       mickey    461: void
1.13      deraadt   462: asgnsamples(void)
1.1       deraadt   463: {
1.9       mpech     464:     int        j;
1.1       deraadt   465:     UNIT               ccnt;
                    466:     double             time;
                    467:     unsigned long      pcl, pch;
1.15      art       468:     unsigned long      i;
1.1       deraadt   469:     unsigned long      overlap;
                    470:     unsigned long      svalue0, svalue1;
                    471:
                    472:     /* read samples and assign to namelist symbols */
                    473:     scale = highpc - lowpc;
                    474:     scale /= nsamples;
                    475:     alignentries();
                    476:     for (i = 0, j = 1; i < nsamples; i++) {
                    477:        ccnt = samples[i];
                    478:        if (ccnt == 0)
                    479:                continue;
1.15      art       480:        pcl = lowpc + (unsigned long)(scale * i);
                    481:        pch = lowpc + (unsigned long)(scale * (i + 1));
1.1       deraadt   482:        time = ccnt;
                    483: #      ifdef DEBUG
                    484:            if ( debug & SAMPLEDEBUG ) {
1.14      art       485:                printf( "[asgnsamples] pcl 0x%lx pch 0x%lx ccnt %d\n" ,
1.1       deraadt   486:                        pcl , pch , ccnt );
                    487:            }
1.10      danh      488: #      endif /* DEBUG */
1.1       deraadt   489:        totime += time;
                    490:        for (j = j - 1; j < nname; j++) {
                    491:            svalue0 = nl[j].svalue;
                    492:            svalue1 = nl[j+1].svalue;
                    493:                /*
                    494:                 *      if high end of tick is below entry address,
                    495:                 *      go for next tick.
                    496:                 */
                    497:            if (pch < svalue0)
                    498:                    break;
                    499:                /*
                    500:                 *      if low end of tick into next routine,
                    501:                 *      go for next routine.
                    502:                 */
                    503:            if (pcl >= svalue1)
                    504:                    continue;
                    505:            overlap = min(pch, svalue1) - max(pcl, svalue0);
                    506:            if (overlap > 0) {
                    507: #              ifdef DEBUG
                    508:                    if (debug & SAMPLEDEBUG) {
1.14      art       509:                        printf("[asgnsamples] (0x%lx->0x%lx-0x%lx) %s gets %f ticks %ld overlap\n",
1.1       deraadt   510:                                nl[j].value/sizeof(UNIT), svalue0, svalue1,
                    511:                                nl[j].name,
                    512:                                overlap * time / scale, overlap);
                    513:                    }
1.10      danh      514: #              endif /* DEBUG */
1.1       deraadt   515:                nl[j].time += overlap * time / scale;
                    516:            }
                    517:        }
                    518:     }
                    519: #   ifdef DEBUG
                    520:        if (debug & SAMPLEDEBUG) {
                    521:            printf("[asgnsamples] totime %f\n", totime);
                    522:        }
1.10      danh      523: #   endif /* DEBUG */
1.1       deraadt   524: }
                    525:
                    526:
                    527: unsigned long
1.13      deraadt   528: min(unsigned long a, unsigned long b)
1.1       deraadt   529: {
                    530:     if (a<b)
                    531:        return(a);
                    532:     return(b);
                    533: }
                    534:
                    535: unsigned long
1.13      deraadt   536: max(unsigned long a, unsigned long b)
1.1       deraadt   537: {
                    538:     if (a>b)
                    539:        return(a);
                    540:     return(b);
                    541: }
                    542:
                    543:     /*
                    544:      * calculate scaled entry point addresses (to save time in asgnsamples),
                    545:      * and possibly push the scaled entry points over the entry mask,
                    546:      * if it turns out that the entry point is in one bucket and the code
                    547:      * for a routine is in the next bucket.
                    548:      */
1.7       mickey    549: void
1.13      deraadt   550: alignentries(void)
1.1       deraadt   551: {
1.9       mpech     552:     struct nl          *nlp;
1.1       deraadt   553:     unsigned long      bucket_of_entry;
                    554:     unsigned long      bucket_of_code;
                    555:
                    556:     for (nlp = nl; nlp < npe; nlp++) {
                    557:        nlp -> svalue = nlp -> value / sizeof(UNIT);
                    558:        bucket_of_entry = (nlp->svalue - lowpc) / scale;
                    559:        bucket_of_code = (nlp->svalue + UNITS_TO_CODE - lowpc) / scale;
                    560:        if (bucket_of_entry < bucket_of_code) {
                    561: #          ifdef DEBUG
                    562:                if (debug & SAMPLEDEBUG) {
1.14      art       563:                    printf("[alignentries] pushing svalue 0x%lx to 0x%lx\n",
1.1       deraadt   564:                            nlp->svalue, nlp->svalue + UNITS_TO_CODE);
                    565:                }
1.10      danh      566: #          endif /* DEBUG */
1.1       deraadt   567:            nlp->svalue += UNITS_TO_CODE;
                    568:        }
                    569:     }
                    570: }