diff options
author | Richard Henderson <rth@redhat.com> | 1999-05-03 07:29:11 +0000 |
---|---|---|
committer | Richard Henderson <rth@redhat.com> | 1999-05-03 07:29:11 +0000 |
commit | 252b5132c753830d5fd56823373aed85f2a0db63 (patch) | |
tree | 1af963bfd8d3e55167b81def4207f175eaff3a56 /gprof/i386.c | |
download | gdb-252b5132c753830d5fd56823373aed85f2a0db63.zip gdb-252b5132c753830d5fd56823373aed85f2a0db63.tar.gz gdb-252b5132c753830d5fd56823373aed85f2a0db63.tar.bz2 |
19990502 sourceware importbinu_ss_19990502
Diffstat (limited to 'gprof/i386.c')
-rw-r--r-- | gprof/i386.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/gprof/i386.c b/gprof/i386.c new file mode 100644 index 0000000..18aad1c --- /dev/null +++ b/gprof/i386.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that: (1) source distributions retain this entire copyright + * notice and comment, and (2) distributions including binaries display + * the following acknowledgement: ``This product includes software + * developed by the University of California, Berkeley and its contributors'' + * in the documentation or other materials provided with the distribution + * and in all advertising materials mentioning features or use of this + * software. Neither the name of the University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#include "gprof.h" +#include "cg_arcs.h" +#include "corefile.h" +#include "hist.h" +#include "symtab.h" + + +int +DEFUN (i386_iscall, (ip), unsigned char *ip) +{ + if (*ip == 0xe8) + return 1; + return 0; +} + + +void +i386_find_call (parent, p_lowpc, p_highpc) + Sym *parent; + bfd_vma p_lowpc; + bfd_vma p_highpc; +{ + unsigned char *instructp; + Sym *child; + bfd_vma destpc, delta; + + if (core_text_space == 0) + { + return; + } + if (p_lowpc < s_lowpc) + { + p_lowpc = s_lowpc; + } + if (p_highpc > s_highpc) + { + p_highpc = s_highpc; + } + DBG (CALLDEBUG, printf ("[findcall] %s: 0x%lx to 0x%lx\n", + parent->name, p_lowpc, p_highpc)); + + delta = (bfd_vma) core_text_space - core_text_sect->vma; + + for (instructp = (unsigned char *) (p_lowpc + delta); + instructp < (unsigned char *) (p_highpc + delta); + instructp ++) + { + if (i386_iscall (instructp)) + { + DBG (CALLDEBUG, + 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) 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); + if (child && child->addr == destpc) + { + /* + * a hit + */ + DBG (CALLDEBUG, + printf ("\tdestpc 0x%lx (%s)\n", destpc, child->name)); + arc_add (parent, child, (unsigned long) 0); + instructp += 4; /* call is a 5 byte instruction */ + continue; + } + } + /* + * else: + * 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 ("\tbut it's a botch\n")); + } + } +} |