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

Annotation of src/usr.bin/gprof/vax.c, Revision 1.5

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