Annotation of 43BSDReno/pgrm/gprof/tahoe.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1983 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted
                      6:  * provided that: (1) source distributions retain this entire copyright
                      7:  * notice and comment, and (2) distributions including binaries display
                      8:  * the following acknowledgement:  ``This product includes software
                      9:  * developed by the University of California, Berkeley and its contributors''
                     10:  * in the documentation or other materials provided with the distribution
                     11:  * and in all advertising materials mentioning features or use of this
                     12:  * software. Neither the name of the University nor the names of its
                     13:  * contributors may be used to endorse or promote products derived
                     14:  * from this software without specific prior written permission.
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     16:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     18:  */
                     19: 
                     20: #ifndef lint
                     21: static char sccsid[] = "@(#)tahoe.c    1.5 (Berkeley) 6/1/90";
                     22: #endif /* not lint */
                     23: 
                     24: #include       "gprof.h"
                     25: 
                     26:     /*
                     27:      * a namelist entry to be the child of indirect callf
                     28:      */
                     29: nltype indirectchild = {
                     30:        "(*)" ,                         /* the name */
                     31:        (unsigned long) 0 ,             /* the pc entry point */
                     32:        (unsigned long) 0 ,             /* entry point aligned to histogram */
                     33:        (double) 0.0 ,                  /* ticks in this routine */
                     34:        (double) 0.0 ,                  /* cumulative ticks in children */
                     35:        (long) 0 ,                      /* how many times called */
                     36:        (long) 0 ,                      /* how many calls to self */
                     37:        (double) 1.0 ,                  /* propagation fraction */
                     38:        (double) 0.0 ,                  /* self propagation time */
                     39:        (double) 0.0 ,                  /* child propagation time */
                     40:        (bool) 0 ,                      /* print flag */
                     41:        (int) 0 ,                       /* index in the graph list */
                     42:        (int) 0 ,                       /* graph call chain top-sort order */
                     43:        (int) 0 ,                       /* internal number of cycle on */
                     44:        (struct nl *) &indirectchild ,  /* pointer to head of cycle */
                     45:        (struct nl *) 0 ,               /* pointer to next member of cycle */
                     46:        (arctype *) 0 ,                 /* list of caller arcs */
                     47:        (arctype *) 0                   /* list of callee arcs */
                     48:     };
                     49: 
                     50: operandenum
                     51: operandmode( modep )
                     52:     unsigned char      *modep;
                     53: {
                     54:     long       usesreg = ((long)*modep) & 0xf;
                     55:     
                     56:     switch ( ((long)*modep) >> 4 ) {
                     57:        case 0:
                     58:        case 1:
                     59:        case 2:
                     60:        case 3:
                     61:            return literal;
                     62:        case 4:
                     63:            return indexed;
                     64:        case 5:
                     65:            return reg;
                     66:        case 6:
                     67:            return regdef;
                     68:        case 7:
                     69:            return autodec;
                     70:        case 8:
                     71:            return ( usesreg != 0xe ? autoinc : immediate );
                     72:        case 9:
                     73:            return ( usesreg != PC ? autoincdef : absolute );
                     74:        case 10:
                     75:            return ( usesreg != PC ? bytedisp : byterel );
                     76:        case 11:
                     77:            return ( usesreg != PC ? bytedispdef : bytereldef );
                     78:        case 12:
                     79:            return ( usesreg != PC ? worddisp : wordrel );
                     80:        case 13:
                     81:            return ( usesreg != PC ? worddispdef : wordreldef );
                     82:        case 14:
                     83:            return ( usesreg != PC ? longdisp : longrel );
                     84:        case 15:
                     85:            return ( usesreg != PC ? longdispdef : longreldef );
                     86:     }
                     87:     /* NOTREACHED */
                     88: }
                     89: 
                     90: char *
                     91: operandname( mode )
                     92:     operandenum        mode;
                     93: {
                     94:     
                     95:     switch ( mode ) {
                     96:        case literal:
                     97:            return "literal";
                     98:        case indexed:
                     99:            return "indexed";
                    100:        case reg:
                    101:            return "register";
                    102:        case regdef:
                    103:            return "register deferred";
                    104:        case autodec:
                    105:            return "autodecrement";
                    106:        case autoinc:
                    107:            return "autoincrement";
                    108:        case autoincdef:
                    109:            return "autoincrement deferred";
                    110:        case bytedisp:
                    111:            return "byte displacement";
                    112:        case bytedispdef:
                    113:            return "byte displacement deferred";
                    114:        case byterel:
                    115:            return "byte relative";
                    116:        case bytereldef:
                    117:            return "byte relative deferred";
                    118:        case worddisp:
                    119:            return "word displacement";
                    120:        case worddispdef:
                    121:            return "word displacement deferred";
                    122:        case wordrel:
                    123:            return "word relative";
                    124:        case wordreldef:
                    125:            return "word relative deferred";
                    126:        case immediate:
                    127:            return "immediate";
                    128:        case absolute:
                    129:            return "absolute";
                    130:        case longdisp:
                    131:            return "long displacement";
                    132:        case longdispdef:
                    133:            return "long displacement deferred";
                    134:        case longrel:
                    135:            return "long relative";
                    136:        case longreldef:
                    137:            return "long relative deferred";
                    138:     }
                    139:     /* NOTREACHED */
                    140: }
                    141: 
                    142: long
                    143: operandlength( modep )
                    144:     unsigned char      *modep;
                    145: {
                    146:     
                    147:     switch ( operandmode( modep ) ) {
                    148:        case literal:
                    149:        case reg:
                    150:        case regdef:
                    151:        case autodec:
                    152:        case autoinc:
                    153:        case autoincdef:
                    154:            return 1;
                    155:        case bytedisp:
                    156:        case bytedispdef:
                    157:        case byterel:
                    158:        case bytereldef:
                    159:            return 2;
                    160:        case worddisp:
                    161:        case worddispdef:
                    162:        case wordrel:
                    163:        case wordreldef:
                    164:            return 3;
                    165:        case immediate:
                    166:        case absolute:
                    167:        case longdisp:
                    168:        case longdispdef:
                    169:        case longrel:
                    170:        case longreldef:
                    171:            return 5;
                    172:        case indexed:
                    173:            return 1+operandlength( modep + 1 );
                    174:     }
                    175:     /* NOTREACHED */
                    176: }
                    177: 
                    178: unsigned long
                    179: reladdr( modep )
                    180:     char       *modep;
                    181: {
                    182:     operandenum        mode = operandmode( modep );
                    183:     char       *cp;
                    184:     short      *sp;
                    185:     long       *lp;
                    186:     int                i;
                    187:     long       value = 0;
                    188: 
                    189:     cp = modep;
                    190:     cp += 1;                   /* skip over the mode */
                    191:     switch ( mode ) {
                    192:        default:
                    193:            fprintf( stderr , "[reladdr] not relative address\n" );
                    194:            return (unsigned long) modep;
                    195:        case byterel:
                    196:            return (unsigned long) ( cp + sizeof *cp + *cp );
                    197:        case wordrel:
                    198:            for (i = 0; i < sizeof *sp; i++)
                    199:                value = (value << 8) + (cp[i] & 0xff);
                    200:            return (unsigned long) ( cp + sizeof *sp + value );
                    201:        case longrel:
                    202:            for (i = 0; i < sizeof *lp; i++)
                    203:                value = (value << 8) + (cp[i] & 0xff);
                    204:            return (unsigned long) ( cp + sizeof *lp + value );
                    205:     }
                    206: }
                    207: 
                    208: findcall( parentp , p_lowpc , p_highpc )
                    209:     nltype             *parentp;
                    210:     unsigned long      p_lowpc;
                    211:     unsigned long      p_highpc;
                    212: {
                    213:     unsigned char      *instructp;
                    214:     long               length;
                    215:     nltype             *childp;
                    216:     operandenum                mode;
                    217:     operandenum                firstmode;
                    218:     unsigned long      destpc;
                    219: 
                    220:     if ( textspace == 0 ) {
                    221:        return;
                    222:     }
                    223:     if ( p_lowpc < s_lowpc ) {
                    224:        p_lowpc = s_lowpc;
                    225:     }
                    226:     if ( p_highpc > s_highpc ) {
                    227:        p_highpc = s_highpc;
                    228:     }
                    229: #   ifdef DEBUG
                    230:        if ( debug & CALLDEBUG ) {
                    231:            printf( "[findcall] %s: 0x%x to 0x%x\n" ,
                    232:                    parentp -> name , p_lowpc , p_highpc );
                    233:        }
                    234: #   endif DEBUG
                    235:     for (   instructp = textspace + p_lowpc ;
                    236:            instructp < textspace + p_highpc ;
                    237:            instructp += length ) {
                    238:        length = 1;
                    239:        if ( *instructp == CALLF ) {
                    240:                /*
                    241:                 *      maybe a callf, better check it out.
                    242:                 *      skip the count of the number of arguments.
                    243:                 */
                    244: #          ifdef DEBUG
                    245:                if ( debug & CALLDEBUG ) {
                    246:                    printf( "[findcall]\t0x%x:callf" , instructp - textspace );
                    247:                }
                    248: #          endif DEBUG
                    249:            firstmode = operandmode( instructp+length );
                    250:            switch ( firstmode ) {
                    251:                case literal:
                    252:                case immediate:
                    253:                    break;
                    254:                default:
                    255:                    goto botched;
                    256:            }
                    257:            length += operandlength( instructp+length );
                    258:            mode = operandmode( instructp + length );
                    259: #          ifdef DEBUG
                    260:                if ( debug & CALLDEBUG ) {
                    261:                    printf( "\tfirst operand is %s", operandname( firstmode ) );
                    262:                    printf( "\tsecond operand is %s\n" , operandname( mode ) );
                    263:                }
                    264: #          endif DEBUG
                    265:            switch ( mode ) {
                    266:                case regdef:
                    267:                case bytedispdef:
                    268:                case worddispdef:
                    269:                case longdispdef:
                    270:                case bytereldef:
                    271:                case wordreldef:
                    272:                case longreldef:
                    273:                        /*
                    274:                         *      indirect call: call through pointer
                    275:                         *      either  *d(r)   as a parameter or local
                    276:                         *              (r)     as a return value
                    277:                         *              *f      as a global pointer
                    278:                         *      [are there others that we miss?,
                    279:                         *       e.g. arrays of pointers to functions???]
                    280:                         */
                    281:                    addarc( parentp , &indirectchild , (long) 0 );
                    282:                    length += operandlength( instructp + length );
                    283:                    continue;
                    284:                case byterel:
                    285:                case wordrel:
                    286:                case longrel:
                    287:                        /*
                    288:                         *      regular pc relative addressing
                    289:                         *      check that this is the address of 
                    290:                         *      a function.
                    291:                         */
                    292:                    destpc = reladdr( instructp+length )
                    293:                                - (unsigned long) textspace;
                    294:                    if ( destpc >= s_lowpc && destpc <= s_highpc ) {
                    295:                        childp = nllookup( destpc );
                    296: #                      ifdef DEBUG
                    297:                            if ( debug & CALLDEBUG ) {
                    298:                                printf( "[findcall]\tdestpc 0x%x" , destpc );
                    299:                                printf( " childp->name %s" , childp -> name );
                    300:                                printf( " childp->value 0x%x\n" ,
                    301:                                        childp -> value );
                    302:                            }
                    303: #                      endif DEBUG
                    304:                        if ( childp -> value == destpc ) {
                    305:                                /*
                    306:                                 *      a hit
                    307:                                 */
                    308:                            addarc( parentp , childp , (long) 0 );
                    309:                            length += operandlength( instructp + length );
                    310:                            continue;
                    311:                        }
                    312:                        goto botched;
                    313:                    }
                    314:                        /*
                    315:                         *      else:
                    316:                         *      it looked like a callf,
                    317:                         *      but it wasn't to anywhere.
                    318:                         */
                    319:                    goto botched;
                    320:                default:
                    321:                botched:
                    322:                        /*
                    323:                         *      something funny going on.
                    324:                         */
                    325: #                  ifdef DEBUG
                    326:                        if ( debug & CALLDEBUG ) {
                    327:                            printf( "[findcall]\tbut it's a botch\n" );
                    328:                        }
                    329: #                  endif DEBUG
                    330:                    length = 1;
                    331:                    continue;
                    332:            }
                    333:        }
                    334:     }
                    335: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.