summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/gprof/gprof.c6
-rw-r--r--usr.bin/gprof/i386.c55
2 files changed, 56 insertions, 5 deletions
diff --git a/usr.bin/gprof/gprof.c b/usr.bin/gprof/gprof.c
index 0530adf7402..9db9fe58329 100644
--- a/usr.bin/gprof/gprof.c
+++ b/usr.bin/gprof/gprof.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gprof.c,v 1.2 1996/06/26 05:33:51 deraadt Exp $ */
+/* $OpenBSD: gprof.c,v 1.3 1996/10/02 02:59:49 tholo Exp $ */
/* $NetBSD: gprof.c,v 1.8 1995/04/19 07:15:59 cgd Exp $ */
/*
@@ -44,7 +44,7 @@ static char copyright[] =
#if 0
static char sccsid[] = "@(#)gprof.c 8.1 (Berkeley) 6/6/93";
#else
-static char rcsid[] = "$OpenBSD: gprof.c,v 1.2 1996/06/26 05:33:51 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: gprof.c,v 1.3 1996/10/02 02:59:49 tholo Exp $";
#endif
#endif /* not lint */
@@ -84,7 +84,7 @@ main(argc, argv)
cyclethreshold = atoi( *++argv );
break;
case 'c':
-#if defined(vax) || defined(tahoe) || defined(sparc)
+#if defined(i386) || defined(vax) || defined(tahoe) || defined(sparc)
cflag = TRUE;
#else
fprintf(stderr, "gprof: -c isn't supported on this architecture yet\n");
diff --git a/usr.bin/gprof/i386.c b/usr.bin/gprof/i386.c
index ab3f51d0c2c..250852b167f 100644
--- a/usr.bin/gprof/i386.c
+++ b/usr.bin/gprof/i386.c
@@ -1,12 +1,14 @@
-/* $OpenBSD: i386.c,v 1.2 1996/06/26 05:33:52 deraadt Exp $ */
+/* $OpenBSD: i386.c,v 1.3 1996/10/02 02:59:50 tholo Exp $ */
/* $NetBSD: i386.c,v 1.5 1995/04/19 07:16:04 cgd Exp $ */
#ifndef lint
-static char rcsid[] = "$OpenBSD: i386.c,v 1.2 1996/06/26 05:33:52 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: i386.c,v 1.3 1996/10/02 02:59:50 tholo Exp $";
#endif /* not lint */
#include "gprof.h"
+#define iscall(pc) ((*pc) == 0xE8)
+
/*
* gprof -c isn't currently supported...
*/
@@ -15,4 +17,53 @@ findcall( parentp , p_lowpc , p_highpc )
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
+ }
+ }
}