xref: /openbsd-src/usr.bin/gprof/i386.c (revision 043fbe51c197dbbcd422e917b65f765d8b5f8874)
1*043fbe51Sderaadt /*	$OpenBSD: i386.c,v 1.10 2009/10/27 23:59:38 deraadt Exp $	*/
2df930be7Sderaadt /*	$NetBSD: i386.c,v 1.5 1995/04/19 07:16:04 cgd Exp $	*/
3df930be7Sderaadt 
4ee75288fStholo /*-
5ee75288fStholo  * Copyright (c) 1996 SigmaSoft, Th. Lockert
6ee75288fStholo  * All rights reserved.
7ee75288fStholo  *
8ee75288fStholo  * Redistribution and use in source and binary forms, with or without
9ee75288fStholo  * modification, are permitted provided that the following conditions
10ee75288fStholo  * are met:
11ee75288fStholo  * 1. Redistributions of source code must retain the above copyright
12ee75288fStholo  *    notice, this list of conditions and the following disclaimer.
13ee75288fStholo  * 2. Redistributions in binary form must reproduce the above copyright
14ee75288fStholo  *    notice, this list of conditions and the following disclaimer in the
15ee75288fStholo  *    documentation and/or other materials provided with the distribution.
16ee75288fStholo  *
17ee75288fStholo  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18ee75288fStholo  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19ee75288fStholo  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20ee75288fStholo  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21ee75288fStholo  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22ee75288fStholo  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23ee75288fStholo  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24ee75288fStholo  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25ee75288fStholo  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26ee75288fStholo  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27ee75288fStholo  */
28ee75288fStholo 
29df930be7Sderaadt #include "gprof.h"
30df930be7Sderaadt 
3190a99070Sart #define	iscall(off)	((*(u_char *)&textspace[off]) == 0xE8)
32858fe8b1Stholo 
33d2559c65Smickey void
findcall(nltype * parentp,unsigned long p_lowpc,unsigned long p_highpc)349bd74cdeSespie findcall(nltype *parentp, unsigned long p_lowpc, unsigned long p_highpc)
35df930be7Sderaadt {
3690a99070Sart 	unsigned long pc;
37858fe8b1Stholo 	long len;
38858fe8b1Stholo 	nltype *childp;
39858fe8b1Stholo 	unsigned long destpc;
4090a99070Sart 	int off;
41858fe8b1Stholo 
42858fe8b1Stholo 	if (textspace == 0)
43858fe8b1Stholo 		return;
44858fe8b1Stholo 	if (p_lowpc < s_lowpc)
45858fe8b1Stholo 		p_lowpc = s_lowpc;
46858fe8b1Stholo 	if (p_highpc > s_highpc)
47858fe8b1Stholo 		p_highpc = s_highpc;
48858fe8b1Stholo #	ifdef DEBUG
49858fe8b1Stholo 		if ( debug & CALLDEBUG ) {
50858fe8b1Stholo 			printf( "[findcall] %s: 0x%x to 0x%x\n" ,
51858fe8b1Stholo 				parentp -> name , p_lowpc , p_highpc );
52858fe8b1Stholo 		}
53e90a6b02Sdanh #	endif /* DEBUG */
5490a99070Sart 	for (pc = p_lowpc; pc < p_highpc; pc += len) {
5590a99070Sart 		off = pc - s_lowpc;
56858fe8b1Stholo 		len = 1;
5790a99070Sart 		if (iscall(off)) {
589bd74cdeSespie 			destpc = *(unsigned long *)&textspace[off + 1] + off + 5;
59858fe8b1Stholo #			ifdef DEBUG
60858fe8b1Stholo 				if ( debug & CALLDEBUG ) {
61858fe8b1Stholo 					printf( "[findcall]\t0x%x:calls" , pc - textspace );
62858fe8b1Stholo 					printf( "\tdestpc 0x%x" , destpc );
63858fe8b1Stholo 				}
64e90a6b02Sdanh #			endif /* DEBUG */
65858fe8b1Stholo 			if (destpc >= s_lowpc && destpc <= s_highpc) {
66858fe8b1Stholo 				childp = nllookup(destpc);
67858fe8b1Stholo #				ifdef DEBUG
68858fe8b1Stholo 					if ( debug & CALLDEBUG ) {
69858fe8b1Stholo 						printf( " childp->name %s" , childp -> name );
70858fe8b1Stholo 						printf( " childp->value 0x%x\n" ,
71858fe8b1Stholo 							childp -> value );
72858fe8b1Stholo 					}
73e90a6b02Sdanh #				endif /* DEBUG */
74858fe8b1Stholo 				if (childp != NULL && childp->value == destpc) {
75858fe8b1Stholo 					addarc(parentp, childp, 0L);
76858fe8b1Stholo 					len += 4;
77858fe8b1Stholo 					continue;
78858fe8b1Stholo 				}
79858fe8b1Stholo 			}
80858fe8b1Stholo #			ifdef DEBUG
81858fe8b1Stholo 				if ( debug & CALLDEBUG ) {
82858fe8b1Stholo 					printf( "\tbut it's a botch\n" );
83858fe8b1Stholo 				}
84e90a6b02Sdanh #			endif /* DEBUG */
85858fe8b1Stholo 		}
86858fe8b1Stholo 	}
87df930be7Sderaadt }
88