1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that: (1) source distributions retain this entire copyright 7 * notice and comment, and (2) distributions including binaries display 8 * the following acknowledgement: ``This product includes software 9 * developed by the University of California, Berkeley and its contributors'' 10 * in the documentation or other materials provided with the distribution 11 * and in all advertising materials mentioning features or use of this 12 * software. Neither the name of the University nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 18 */ 19 #include "gprof.h" 20 #include "cg_arcs.h" 21 #include "corefile.h" 22 #include "hist.h" 23 #include "symtab.h" 24 25 /* 26 * opcode of the `callf' instruction 27 */ 28 #define CALL (0xc0000000) 29 30 void 31 sparc_find_call (parent, p_lowpc, p_highpc) 32 Sym *parent; 33 bfd_vma p_lowpc; 34 bfd_vma p_highpc; 35 { 36 bfd_vma dest_pc, delta; 37 unsigned int *instr; 38 Sym *child; 39 40 delta = (bfd_vma) core_text_space - core_text_sect->vma; 41 42 if (core_text_space == 0) 43 { 44 return; 45 } 46 if (p_lowpc < s_lowpc) 47 { 48 p_lowpc = s_lowpc; 49 } 50 if (p_highpc > s_highpc) 51 { 52 p_highpc = s_highpc; 53 } 54 DBG (CALLDEBUG, printf ("[find_call] %s: 0x%lx to 0x%lx\n", 55 parent->name, (unsigned long) p_lowpc, 56 (unsigned long) p_highpc)); 57 for (instr = (unsigned int *) (((p_lowpc + delta) + 3) &~ 3); 58 instr < (unsigned int *) (p_highpc + delta); 59 ++instr) 60 { 61 if ((*instr & CALL)) 62 { 63 DBG (CALLDEBUG, 64 printf ("[find_call] 0x%lx: callf", 65 (unsigned long) instr - delta)); 66 /* 67 * Regular pc relative addressing check that this is the 68 * address of a function. 69 */ 70 dest_pc = ((bfd_vma) (instr + (*instr & ~CALL))) - delta; 71 if (dest_pc >= s_lowpc && dest_pc <= s_highpc) 72 { 73 child = sym_lookup (&symtab, dest_pc); 74 DBG (CALLDEBUG, 75 printf ("\tdest_pc=0x%lx, (name=%s, addr=0x%lx)\n", 76 (unsigned long) dest_pc, child->name, 77 (unsigned long) child->addr)); 78 if (child->addr == dest_pc) 79 { 80 /* a hit: */ 81 arc_add (parent, child, (unsigned long) 0); 82 continue; 83 } 84 } 85 /* 86 * Something funny going on. 87 */ 88 DBG (CALLDEBUG, printf ("\tbut it's a botch\n")); 89 } 90 } 91 } 92