xref: /openbsd-src/gnu/usr.bin/binutils/gprof/sparc.c (revision c074d1c999f3e07019cd5e9a2f190b057ef3b935)
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