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