/* $OpenBSD: i386.c,v 1.6 2002/04/20 03:37:40 tholo Exp $ */ /* $NetBSD: i386.c,v 1.5 1995/04/19 07:16:04 cgd Exp $ */ /*- * Copyright (c) 1996 SigmaSoft, Th. Lockert * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef lint static char rcsid[] = "$OpenBSD: i386.c,v 1.6 2002/04/20 03:37:40 tholo Exp $"; #endif /* not lint */ #include "gprof.h" #define iscall(pc) ((*pc) == 0xE8) void findcall( parentp , p_lowpc , p_highpc ) nltype *parentp; unsigned long p_lowpc; unsigned long p_highpc; { unsigned char *pc; long len; nltype *childp; unsigned long destpc; if (textspace == 0) return; if (p_lowpc < s_lowpc) p_lowpc = s_lowpc; if (p_highpc > s_highpc) p_highpc = s_highpc; # ifdef DEBUG if ( debug & CALLDEBUG ) { printf( "[findcall] %s: 0x%x to 0x%x\n" , parentp -> name , p_lowpc , p_highpc ); } # endif /* DEBUG */ for (pc = textspace + p_lowpc - N_TXTADDR(xbuf) ; pc < textspace + p_highpc - N_TXTADDR(xbuf) ; pc += len) { len = 1; if (iscall(pc)) { destpc = *(unsigned long *)(pc + 1) + (pc - textspace + N_TXTADDR(xbuf)) + 5; # ifdef DEBUG if ( debug & CALLDEBUG ) { printf( "[findcall]\t0x%x:calls" , pc - textspace ); printf( "\tdestpc 0x%x" , destpc ); } # endif /* DEBUG */ if (destpc >= s_lowpc && destpc <= s_highpc) { childp = nllookup(destpc); # ifdef DEBUG if ( debug & CALLDEBUG ) { printf( " childp->name %s" , childp -> name ); printf( " childp->value 0x%x\n" , childp -> value ); } # endif /* DEBUG */ if (childp != NULL && childp->value == destpc) { addarc(parentp, childp, 0L); len += 4; continue; } } # ifdef DEBUG if ( debug & CALLDEBUG ) { printf( "\tbut it's a botch\n" ); } # endif /* DEBUG */ } } }