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.
26 * A symbol to be the child of indirect calls:
33 struct modebyte
*modep
;
35 long usesreg
= modep
->regfield
;
37 switch (modep
->modefield
)
53 return usesreg
!= PC
? autoinc
: immediate
;
55 return usesreg
!= PC
? autoincdef
: absolute
;
57 return usesreg
!= PC
? bytedisp
: byterel
;
59 return usesreg
!= PC
? bytedispdef
: bytereldef
;
61 return usesreg
!= PC
? worddisp
: wordrel
;
63 return usesreg
!= PC
? worddispdef
: wordreldef
;
65 return usesreg
!= PC
? longdisp
: longrel
;
67 return usesreg
!= PC
? longdispdef
: longreldef
;
86 return "register deferred";
88 return "autodecrement";
90 return "autoincrement";
92 return "autoincrement deferred";
94 return "byte displacement";
96 return "byte displacement deferred";
98 return "byte relative";
100 return "byte relative deferred";
102 return "word displacement";
104 return "word displacement deferred";
106 return "word relative";
108 return "word relative deferred";
114 return "long displacement";
116 return "long displacement deferred";
118 return "long relative";
120 return "long relative deferred";
126 operandlength (modep
)
127 struct modebyte
*modep
;
130 switch (operandmode (modep
))
157 return 1 + operandlength ((struct modebyte
*) ((char *) modep
) + 1);
164 struct modebyte
*modep
;
166 operandenum mode
= operandmode (modep
);
172 ++cp
; /* skip over the mode */
176 fprintf (stderr
, "[reladdr] not relative address\n");
177 return (bfd_vma
) modep
;
179 return (bfd_vma
) (cp
+ sizeof *cp
+ *cp
);
182 return (bfd_vma
) (cp
+ sizeof *sp
+ *sp
);
185 return (bfd_vma
) (cp
+ sizeof *lp
+ *lp
);
191 find_call (parent
, p_lowpc
, p_highpc
)
196 unsigned char *instructp
;
200 operandenum firstmode
;
202 static bool inited
= FALSE
;
207 sym_init (&indirectchild
);
208 indirectchild
.cg
.prop
.fract
= 1.0;
209 indirectchild
.cg
.cyc
.head
= &indirectchild
;
212 if (core_text_space
== 0)
216 if (p_lowpc
< s_lowpc
)
220 if (p_highpc
> s_highpc
)
224 DBG (CALLDEBUG
, printf ("[findcall] %s: 0x%lx to 0x%lx\n",
225 parent
->name
, p_lowpc
, p_highpc
));
226 for (instructp
= (unsigned char *) core_text_space
+ p_lowpc
;
227 instructp
< (unsigned char *) core_text_space
+ p_highpc
;
231 if (*instructp
== CALLS
)
234 * maybe a calls, better check it out.
235 * skip the count of the number of arguments.
238 printf ("[findcall]\t0x%x:calls",
239 instructp
- (unsigned char *) core_text_space
));
240 firstmode
= operandmode ((struct modebyte
*) (instructp
+ length
));
249 length
+= operandlength ((struct modebyte
*) (instructp
+ length
));
250 mode
= operandmode ((struct modebyte
*) (instructp
+ length
));
252 printf ("\tfirst operand is %s", operandname (firstmode
));
253 printf ("\tsecond operand is %s\n", operandname (mode
)));
264 * indirect call: call through pointer
265 * either *d(r) as a parameter or local
266 * (r) as a return value
267 * *f as a global pointer
268 * [are there others that we miss?,
269 * e.g. arrays of pointers to functions???]
271 arc_add (parent
, &indirectchild
, (long) 0);
272 length
+= operandlength (
273 (struct modebyte
*) (instructp
+ length
));
279 * regular pc relative addressing
280 * check that this is the address of
283 destpc
= reladdr ((struct modebyte
*) (instructp
+ length
))
284 - (bfd_vma
) core_text_space
;
285 if (destpc
>= s_lowpc
&& destpc
<= s_highpc
)
287 child
= sym_lookup (&symtab
, destpc
);
289 printf ("[findcall]\tdestpc 0x%lx", destpc
);
290 printf (" child->name %s", child
->name
);
291 printf (" child->addr 0x%lx\n", child
->addr
);
293 if (child
->addr
== destpc
)
298 arc_add (parent
, child
, (long) 0);
299 length
+= operandlength ((struct modebyte
*)
300 (instructp
+ length
));
307 * it looked like a calls,
308 * but it wasn't to anywhere.
314 * something funny going on.
316 DBG (CALLDEBUG
, printf ("[findcall]\tbut it's a botch\n"));
This page took 0.035928 seconds and 4 git commands to generate.