xref: /openbsd-src/usr.bin/gprof/i386.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: i386.c,v 1.4 2001/03/22 05:18:30 mickey Exp $	*/
2 /*	$NetBSD: i386.c,v 1.5 1995/04/19 07:16:04 cgd Exp $	*/
3 
4 #ifndef lint
5 static char rcsid[] = "$OpenBSD: i386.c,v 1.4 2001/03/22 05:18:30 mickey Exp $";
6 #endif /* not lint */
7 
8 #include "gprof.h"
9 
10 #define	iscall(pc)	((*pc) == 0xE8)
11 
12 /*
13  * gprof -c isn't currently supported...
14  */
15 void
16 findcall( parentp , p_lowpc , p_highpc )
17     nltype		*parentp;
18     unsigned long	p_lowpc;
19     unsigned long	p_highpc;
20 {
21 	unsigned char *pc;
22 	long len;
23 	nltype *childp;
24 	unsigned long destpc;
25 
26 	if (textspace == 0)
27 		return;
28 	if (p_lowpc < s_lowpc)
29 		p_lowpc = s_lowpc;
30 	if (p_highpc > s_highpc)
31 		p_highpc = s_highpc;
32 #	ifdef DEBUG
33 		if ( debug & CALLDEBUG ) {
34 			printf( "[findcall] %s: 0x%x to 0x%x\n" ,
35 				parentp -> name , p_lowpc , p_highpc );
36 		}
37 #	endif DEBUG
38 	for (pc = textspace + p_lowpc - N_TXTADDR(xbuf) ; pc < textspace + p_highpc - N_TXTADDR(xbuf) ; pc += len) {
39 		len = 1;
40 		if (iscall(pc)) {
41 			destpc = *(unsigned long *)(pc + 1) + (pc - textspace + N_TXTADDR(xbuf)) + 5;
42 #			ifdef DEBUG
43 				if ( debug & CALLDEBUG ) {
44 					printf( "[findcall]\t0x%x:calls" , pc - textspace );
45 					printf( "\tdestpc 0x%x" , destpc );
46 				}
47 #			endif DEBUG
48 			if (destpc >= s_lowpc && destpc <= s_highpc) {
49 				childp = nllookup(destpc);
50 #				ifdef DEBUG
51 					if ( debug & CALLDEBUG ) {
52 						printf( " childp->name %s" , childp -> name );
53 						printf( " childp->value 0x%x\n" ,
54 							childp -> value );
55 					}
56 #				endif DEBUG
57 				if (childp != NULL && childp->value == destpc) {
58 					addarc(parentp, childp, 0L);
59 					len += 4;
60 					continue;
61 				}
62 			}
63 #			ifdef DEBUG
64 				if ( debug & CALLDEBUG ) {
65 					printf( "\tbut it's a botch\n" );
66 				}
67 #			endif DEBUG
68 		}
69 	}
70 }
71