]>
Commit | Line | Data |
---|---|---|
cc5697d7 SEF |
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 | */ | |
5489fcc3 KR |
19 | #include "gprof.h" |
20 | #include "cg_arcs.h" | |
21 | #include "core.h" | |
22 | #include "hist.h" | |
23 | #include "symtab.h" | |
cc5697d7 | 24 | |
cc5697d7 | 25 | |
cc5697d7 | 26 | int |
12516a37 | 27 | DEFUN (iscall, (ip), unsigned char *ip) |
46f88c11 | 28 | { |
12516a37 | 29 | if (*ip == 0xeb || *ip == 0x9a) |
cc5697d7 SEF |
30 | return 1; |
31 | return 0; | |
32 | } | |
33 | ||
5489fcc3 KR |
34 | |
35 | void | |
12516a37 KR |
36 | find_call (parent, p_lowpc, p_highpc) |
37 | Sym *parent; | |
38 | bfd_vma p_lowpc; | |
39 | bfd_vma p_highpc; | |
cc5697d7 | 40 | { |
12516a37 KR |
41 | unsigned char *instructp; |
42 | long length; | |
43 | Sym *child; | |
44 | bfd_vma destpc; | |
cc5697d7 | 45 | |
12516a37 KR |
46 | if (core_text_space == 0) |
47 | { | |
48 | return; | |
cc5697d7 | 49 | } |
12516a37 KR |
50 | if (p_lowpc < s_lowpc) |
51 | { | |
52 | p_lowpc = s_lowpc; | |
cc5697d7 | 53 | } |
12516a37 KR |
54 | if (p_highpc > s_highpc) |
55 | { | |
56 | p_highpc = s_highpc; | |
cc5697d7 | 57 | } |
12516a37 | 58 | DBG (CALLDEBUG, printf ("[findcall] %s: 0x%lx to 0x%lx\n", |
5489fcc3 | 59 | parent->name, p_lowpc, p_highpc)); |
12516a37 KR |
60 | for (instructp = (unsigned char *) core_text_space + p_lowpc; |
61 | instructp < (unsigned char *) core_text_space + p_highpc; | |
62 | instructp += length) | |
63 | { | |
64 | length = 1; | |
65 | if (iscall (instructp)) | |
66 | { | |
67 | DBG (CALLDEBUG, | |
68 | printf ("[findcall]\t0x%x:callf", | |
69 | instructp - (unsigned char *) core_text_space)); | |
cc5697d7 SEF |
70 | length = 4; |
71 | /* | |
12516a37 KR |
72 | * regular pc relative addressing |
73 | * check that this is the address of | |
74 | * a function. | |
cc5697d7 | 75 | */ |
12516a37 KR |
76 | destpc = ((bfd_vma) instructp + 5 - (bfd_vma) core_text_space); |
77 | if (destpc >= s_lowpc && destpc <= s_highpc) | |
78 | { | |
79 | child = sym_lookup (&symtab, destpc); | |
80 | DBG (CALLDEBUG, | |
81 | printf ("[findcall]\tdestpc 0x%lx", destpc); | |
82 | printf (" child->name %s", child->name); | |
83 | printf (" child->addr 0x%lx\n", child->addr); | |
5489fcc3 | 84 | ); |
12516a37 KR |
85 | if (child->addr == destpc) |
86 | { | |
87 | /* | |
88 | * a hit | |
89 | */ | |
90 | arc_add (parent, child, (long) 0); | |
91 | length += 4; /* constant lengths */ | |
92 | continue; | |
93 | } | |
94 | goto botched; | |
cc5697d7 | 95 | } |
cc5697d7 | 96 | /* |
12516a37 KR |
97 | * else: |
98 | * it looked like a callf, | |
99 | * but it wasn't to anywhere. | |
cc5697d7 SEF |
100 | */ |
101 | botched: | |
102 | /* | |
12516a37 | 103 | * something funny going on. |
cc5697d7 | 104 | */ |
12516a37 KR |
105 | DBG (CALLDEBUG, printf ("[findcall]\tbut it's a botch\n")); |
106 | length = 1; | |
107 | continue; | |
cc5697d7 | 108 | } |
12516a37 KR |
109 | } |
110 | } |