2 * Copyright (c) 1983 Regents of the University of California.
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.
20 #include "time_host.h"
23 * A symbol to be the child of indirect callf:
32 long usesreg = ((long) *modep) & 0xf;
34 switch (((long) *modep) >> 4)
50 return usesreg != 0xe ? autoinc : immediate;
52 return usesreg != PC ? autoincdef : absolute;
54 return usesreg != PC ? bytedisp : byterel;
56 return usesreg != PC ? bytedispdef : bytereldef;
58 return usesreg != PC ? worddisp : wordrel;
60 return usesreg != PC ? worddispdef : wordreldef;
62 return usesreg != PC ? longdisp : longrel;
64 return usesreg != PC ? longdispdef : longreldef;
83 return "register deferred";
85 return "autodecrement";
87 return "autoincrement";
89 return "autoincrement deferred";
91 return "byte displacement";
93 return "byte displacement deferred";
95 return "byte relative";
97 return "byte relative deferred";
99 return "word displacement";
101 return "word displacement deferred";
103 return "word relative";
105 return "word relative deferred";
111 return "long displacement";
113 return "long displacement deferred";
115 return "long relative";
117 return "long relative deferred";
123 operandlength (modep)
124 unsigned char *modep;
127 switch (operandmode (modep))
154 return 1 + operandlength (modep + 1);
163 operandenum mode = operandmode (modep);
171 ++cp; /* skip over the mode */
175 fprintf (stderr, "[reladdr] not relative address\n");
176 return (bfd_vma) modep;
178 return (bfd_vma) (cp + sizeof *cp + *cp);
180 for (i = 0; i < sizeof *sp; i++)
181 value = (value << 8) + (cp[i] & 0xff);
182 return (bfd_vma) (cp + sizeof *sp + value);
184 for (i = 0; i < sizeof *lp; i++)
185 value = (value << 8) + (cp[i] & 0xff);
186 return (bfd_vma) (cp + sizeof *lp + value);
190 find_call (parent, p_lowpc, p_highpc)
195 unsigned char *instructp;
199 operandenum firstmode;
201 static bool inited = FALSE;
206 sym_init (&indirectchild);
207 indirectchild.cg.prop.fract = 1.0;
208 indirectchild.cg.cyc.head = &indirectchild;
215 if (p_lowpc < s_lowpc)
219 if (p_highpc > s_highpc)
223 DBG (CALLDEBUG, printf ("[findcall] %s: 0x%x to 0x%x\n",
224 parent->name, p_lowpc, p_highpc));
225 for (instructp = textspace + p_lowpc;
226 instructp < textspace + p_highpc;
230 if (*instructp == CALLF)
233 * maybe a callf, better check it out.
234 * skip the count of the number of arguments.
236 DBG (CALLDEBUG, printf ("[findcall]\t0x%x:callf",
237 instructp - textspace));
238 firstmode = operandmode (instructp + length);
247 length += operandlength (instructp + length);
248 mode = operandmode (instructp + length);
250 printf ("\tfirst operand is %s", operandname (firstmode));
251 printf ("\tsecond operand is %s\n", operandname (mode));
263 * indirect call: call through pointer
264 * either *d(r) as a parameter or local
265 * (r) as a return value
266 * *f as a global pointer
267 * [are there others that we miss?,
268 * e.g. arrays of pointers to functions???]
270 arc_add (parent, &indirectchild, (long) 0);
271 length += operandlength (instructp + length);
277 * regular pc relative addressing
278 * check that this is the address of
281 destpc = reladdr (instructp + length)
282 - (bfd_vma) textspace;
283 if (destpc >= s_lowpc && destpc <= s_highpc)
285 child = sym_lookup (destpc);
287 printf ("[findcall]\tdestpc 0x%x", destpc);
288 printf (" child->name %s", child->name);
289 printf (" child->addr 0x%x\n", child->addr);
291 if (child->addr == destpc)
296 arc_add (parent, child, (long) 0);
297 length += operandlength (instructp + length);
304 * it looked like a callf,
305 * but it wasn't to anywhere.
311 * something funny going on.
313 DBG (CALLDEBUG, printf ("[findcall]\tbut it's a botch\n"));