12159047fSniklas /*
2*c074d1c9Sdrahn * Copyright (c) 1983, 1993
36e421504Sfgsch * The Regents of the University of California. All rights reserved.
42159047fSniklas *
56e421504Sfgsch * Redistribution and use in source and binary forms, with or without
66e421504Sfgsch * modification, are permitted provided that the following conditions
76e421504Sfgsch * are met:
86e421504Sfgsch * 1. Redistributions of source code must retain the above copyright
96e421504Sfgsch * notice, this list of conditions and the following disclaimer.
106e421504Sfgsch * 2. Redistributions in binary form must reproduce the above copyright
116e421504Sfgsch * notice, this list of conditions and the following disclaimer in the
126e421504Sfgsch * documentation and/or other materials provided with the distribution.
136e421504Sfgsch * 3. Neither the name of the University nor the names of its contributors
146e421504Sfgsch * may be used to endorse or promote products derived from this software
156e421504Sfgsch * without specific prior written permission.
166e421504Sfgsch *
176e421504Sfgsch * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
186e421504Sfgsch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
196e421504Sfgsch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
206e421504Sfgsch * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
216e421504Sfgsch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
226e421504Sfgsch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
236e421504Sfgsch * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
246e421504Sfgsch * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
256e421504Sfgsch * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
266e421504Sfgsch * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
276e421504Sfgsch * SUCH DAMAGE.
282159047fSniklas */
292159047fSniklas #include "gprof.h"
30*c074d1c9Sdrahn #include "search_list.h"
31*c074d1c9Sdrahn #include "source.h"
32*c074d1c9Sdrahn #include "symtab.h"
332159047fSniklas #include "cg_arcs.h"
34b305b0f1Sespie #include "corefile.h"
352159047fSniklas #include "hist.h"
362159047fSniklas
37b305b0f1Sespie /*
38b305b0f1Sespie * opcode of the `callf' instruction
39b305b0f1Sespie */
40b305b0f1Sespie #define CALL (0xc0000000)
412159047fSniklas
42*c074d1c9Sdrahn void sparc_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
43*c074d1c9Sdrahn
442159047fSniklas void
sparc_find_call(parent,p_lowpc,p_highpc)45b305b0f1Sespie sparc_find_call (parent, p_lowpc, p_highpc)
462159047fSniklas Sym *parent;
472159047fSniklas bfd_vma p_lowpc;
482159047fSniklas bfd_vma p_highpc;
492159047fSniklas {
50*c074d1c9Sdrahn bfd_vma pc, dest_pc;
51*c074d1c9Sdrahn unsigned int insn;
522159047fSniklas Sym *child;
532159047fSniklas
542159047fSniklas if (core_text_space == 0)
552159047fSniklas {
562159047fSniklas return;
572159047fSniklas }
582159047fSniklas if (p_lowpc < s_lowpc)
592159047fSniklas {
602159047fSniklas p_lowpc = s_lowpc;
612159047fSniklas }
622159047fSniklas if (p_highpc > s_highpc)
632159047fSniklas {
642159047fSniklas p_highpc = s_highpc;
652159047fSniklas }
662159047fSniklas DBG (CALLDEBUG, printf ("[find_call] %s: 0x%lx to 0x%lx\n",
67b305b0f1Sespie parent->name, (unsigned long) p_lowpc,
68b305b0f1Sespie (unsigned long) p_highpc));
69*c074d1c9Sdrahn for (pc = (p_lowpc + 3) & ~(bfd_vma) 3; pc < p_highpc; pc += 4)
702159047fSniklas {
71*c074d1c9Sdrahn insn = bfd_get_32 (core_bfd, ((unsigned char *) core_text_space
72*c074d1c9Sdrahn + pc - core_text_sect->vma));
73*c074d1c9Sdrahn if (insn & CALL)
742159047fSniklas {
752159047fSniklas DBG (CALLDEBUG,
76*c074d1c9Sdrahn printf ("[find_call] 0x%lx: callf", (unsigned long) pc));
772159047fSniklas /*
782159047fSniklas * Regular pc relative addressing check that this is the
792159047fSniklas * address of a function.
802159047fSniklas */
81*c074d1c9Sdrahn dest_pc = pc + (((bfd_signed_vma) (insn & 0x3fffffff)
82*c074d1c9Sdrahn ^ 0x20000000) - 0x20000000);
832159047fSniklas if (dest_pc >= s_lowpc && dest_pc <= s_highpc)
842159047fSniklas {
852159047fSniklas child = sym_lookup (&symtab, dest_pc);
862159047fSniklas DBG (CALLDEBUG,
872159047fSniklas printf ("\tdest_pc=0x%lx, (name=%s, addr=0x%lx)\n",
88b305b0f1Sespie (unsigned long) dest_pc, child->name,
89b305b0f1Sespie (unsigned long) child->addr));
902159047fSniklas if (child->addr == dest_pc)
912159047fSniklas {
922159047fSniklas /* a hit: */
93b305b0f1Sespie arc_add (parent, child, (unsigned long) 0);
942159047fSniklas continue;
952159047fSniklas }
962159047fSniklas }
972159047fSniklas /*
982159047fSniklas * Something funny going on.
992159047fSniklas */
1002159047fSniklas DBG (CALLDEBUG, printf ("\tbut it's a botch\n"));
1012159047fSniklas }
1022159047fSniklas }
1032159047fSniklas }
104