1 /* 2 * Copyright (c) 1992, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This software was developed by the Computer Systems Engineering group 6 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 7 * contributed to Berkeley. 8 * 9 * %sccs.include.redist.c% 10 */ 11 12 #ifndef lint 13 static char sccsid[] = "@(#)sparc.c 8.1 (Berkeley) 06/06/93"; 14 #endif /* not lint */ 15 16 #include "gprof.h" 17 18 /* 19 * a namelist entry to be the child of indirect calls 20 */ 21 nltype indirectchild = { 22 "(*)" , /* the name */ 23 (unsigned long) 0 , /* the pc entry point */ 24 (unsigned long) 0 , /* entry point aligned to histogram */ 25 (double) 0.0 , /* ticks in this routine */ 26 (double) 0.0 , /* cumulative ticks in children */ 27 (long) 0 , /* how many times called */ 28 (long) 0 , /* times called by live arcs */ 29 (long) 0 , /* how many calls to self */ 30 (double) 1.0 , /* propagation fraction */ 31 (double) 0.0 , /* self propagation time */ 32 (double) 0.0 , /* child propagation time */ 33 (short) 0 , /* print flag */ 34 (short) 0 , /* flags */ 35 (int) 0 , /* index in the graph list */ 36 (int) 0 , /* graph call chain top-sort order */ 37 (int) 0 , /* internal number of cycle on */ 38 (int) 0 , /* number of live parent arcs */ 39 (struct nl *) &indirectchild , /* pointer to head of cycle */ 40 (struct nl *) 0 , /* pointer to next member of cycle */ 41 (arctype *) 0 , /* list of caller arcs */ 42 (arctype *) 0 /* list of callee arcs */ 43 }; 44 45 findcall(parentp, p_lowpc, p_highpc) 46 nltype *parentp; 47 unsigned long p_lowpc; 48 unsigned long p_highpc; 49 { 50 register u_long pc; 51 nltype *childp; 52 unsigned long destpc; 53 register long op; 54 register int off; 55 56 if (textspace == 0) 57 return; 58 if (p_lowpc < s_lowpc) 59 p_lowpc = s_lowpc; 60 if (p_highpc > s_highpc) 61 p_highpc = s_highpc; 62 63 for (pc = p_lowpc; pc < p_highpc; pc += 4) { 64 off = pc - s_lowpc; 65 op = *(u_long *)&textspace[off]; 66 if ((op & 0xc0000000) == 0x40000000) { 67 /* 68 * a pc relative call insn -- check that this 69 * is the address of a function. 70 */ 71 off = (op & 0x3fffffff) << 2; 72 destpc = pc + off; 73 if (destpc >= s_lowpc && destpc <= s_highpc) { 74 childp = nllookup(destpc); 75 if (childp != 0 && childp->value == destpc) 76 addarc(parentp, childp, 0L); 77 } 78 } else if ((op & 0xfff80000) == 0x9fc00000) 79 /* 80 * A jmpl with rd = 15 (%o7) -- an indirect call. 81 */ 82 addarc(parentp, &indirectchild, 0L); 83 } 84 } 85