Initial revision
[platform/upstream/binutils.git] / gprof / i386.c
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 int
51 iscall (unsigned char *ip) {
52   if (*ip == 0xeb || *ip = 0x9a) 
53     return 1;
54   return 0;
55 }
56
57 findcall( parentp , p_lowpc , p_highpc )
58     nltype              *parentp;
59     unsigned long       p_lowpc;
60     unsigned long       p_highpc;
61 {
62     unsigned char       *instructp;
63     long                length;
64     nltype              *childp;
65     unsigned long       destpc;
66
67     if ( textspace == 0 ) {
68         return;
69     }
70     if ( p_lowpc < s_lowpc ) {
71         p_lowpc = s_lowpc;
72     }
73     if ( p_highpc > s_highpc ) {
74         p_highpc = s_highpc;
75     }
76 #   ifdef DEBUG
77         if ( debug & CALLDEBUG ) {
78             printf( "[findcall] %s: 0x%x to 0x%x\n" ,
79                     parentp -> name , p_lowpc , p_highpc );
80         }
81 #   endif DEBUG
82     for (   instructp = textspace + p_lowpc ;
83             instructp < textspace + p_highpc ;
84             instructp += length ) {
85         length = 1;
86         if ( iscall (instructp) ) {
87 #           ifdef DEBUG
88           if ( debug & CALLDEBUG ) {
89             printf( "[findcall]\t0x%x:callf" , instructp - textspace );
90           }
91 #           endif DEBUG
92           length = 4;
93           /*
94            *    regular pc relative addressing
95            *    check that this is the address of 
96            *    a function.
97            */
98           destpc = ( (unsigned long)instructp + 5 
99             - (unsigned long) textspace;
100           if ( destpc >= s_lowpc && destpc <= s_highpc ) {
101             childp = nllookup( destpc );
102 #                       ifdef DEBUG
103             if ( debug & CALLDEBUG ) {
104               printf( "[findcall]\tdestpc 0x%x" , destpc );
105               printf( " childp->name %s" , childp -> name );
106               printf( " childp->value 0x%x\n" ,
107                      childp -> value );
108             }
109 #                       endif DEBUG
110             if ( childp -> value == destpc ) {
111               /*
112                *        a hit
113                */
114               addarc( parentp , childp , (long) 0 );
115               length += 4;      /* constant lengths */
116               continue;
117             }
118             goto botched;
119           }
120           /*
121            *    else:
122            *    it looked like a callf,
123            *    but it wasn't to anywhere.
124            */
125         botched:
126           /*
127            *    something funny going on.
128            */
129 #                   ifdef DEBUG
130           if ( debug & CALLDEBUG ) {
131             printf( "[findcall]\tbut it's a botch\n" );
132           }
133 #                   endif DEBUG
134           length = 1;
135           continue;
136         }
137       }
138   }