aboutsummaryrefslogtreecommitdiff
path: root/gprof/i386.c
diff options
context:
space:
mode:
Diffstat (limited to 'gprof/i386.c')
-rw-r--r--gprof/i386.c56
1 files changed, 25 insertions, 31 deletions
diff --git a/gprof/i386.c b/gprof/i386.c
index 01202a7..d09d34e 100644
--- a/gprof/i386.c
+++ b/gprof/i386.c
@@ -24,24 +24,23 @@
int
-DEFUN (iscall, (ip), unsigned char *ip)
+DEFUN (i386_iscall, (ip), unsigned char *ip)
{
- if (*ip == 0xeb || *ip == 0x9a)
+ if (*ip == 0xe8)
return 1;
return 0;
}
void
-find_call (parent, p_lowpc, p_highpc)
+i386_find_call (parent, p_lowpc, p_highpc)
Sym *parent;
bfd_vma p_lowpc;
bfd_vma p_highpc;
{
unsigned char *instructp;
- long length;
Sym *child;
- bfd_vma destpc;
+ bfd_vma destpc, delta;
if (core_text_space == 0)
{
@@ -57,54 +56,49 @@ find_call (parent, p_lowpc, p_highpc)
}
DBG (CALLDEBUG, printf ("[findcall] %s: 0x%lx to 0x%lx\n",
parent->name, p_lowpc, p_highpc));
- for (instructp = (unsigned char *) core_text_space + p_lowpc;
- instructp < (unsigned char *) core_text_space + p_highpc;
- instructp += length)
+
+ delta = (bfd_vma) core_text_space - core_text_sect->vma;
+
+ for (instructp = (unsigned char *) (p_lowpc + delta);
+ instructp < (unsigned char *) (p_highpc + delta);
+ instructp ++)
{
- length = 1;
- if (iscall (instructp))
+ if (i386_iscall (instructp))
{
DBG (CALLDEBUG,
- printf ("[findcall]\t0x%x:callf",
- instructp - (unsigned char *) core_text_space));
- length = 4;
+ printf ("[findcall]\t0x%x:call",
+ instructp - (unsigned char *) delta));
/*
* regular pc relative addressing
* check that this is the address of
* a function.
*/
- destpc = ((bfd_vma) instructp + 5 - (bfd_vma) core_text_space);
+
+ destpc = ((bfd_vma) bfd_get_32 (core_bfd, instructp + 1)
+ + (bfd_vma) instructp - (bfd_vma) delta + 5);
if (destpc >= s_lowpc && destpc <= s_highpc)
{
child = sym_lookup (&symtab, destpc);
- DBG (CALLDEBUG,
- printf ("[findcall]\tdestpc 0x%lx", destpc);
- printf (" child->name %s", child->name);
- printf (" child->addr 0x%lx\n", child->addr);
- );
- if (child->addr == destpc)
+ if (child && child->addr == destpc)
{
/*
* a hit
*/
+ DBG (CALLDEBUG,
+ printf ("\tdestpc 0x%lx (%s)\n", destpc, child->name));
arc_add (parent, child, (long) 0);
- length += 4; /* constant lengths */
+ instructp += 4; /* call is a 5 byte instruction */
continue;
}
- goto botched;
}
/*
* else:
- * it looked like a callf,
- * but it wasn't to anywhere.
- */
- botched:
- /*
- * something funny going on.
+ * it looked like a callf, but it:
+ * a) wasn't actually a callf, or
+ * b) didn't point to a known function in the symtab, or
+ * c) something funny is going on.
*/
- DBG (CALLDEBUG, printf ("[findcall]\tbut it's a botch\n"));
- length = 1;
- continue;
+ DBG (CALLDEBUG, printf ("\tbut it's a botch\n"));
}
}
}