]>
Commit | Line | Data |
---|---|---|
bd5635a1 RP |
1 | /* Get info from stack frames; |
2 | convert between frames, blocks, functions and pc values. | |
3 | Copyright (C) 1986, 1987, 1988, 1989 Free Software Foundation, Inc. | |
4 | ||
5 | This file is part of GDB. | |
6 | ||
5259796b | 7 | This program is free software; you can redistribute it and/or modify |
bd5635a1 | 8 | it under the terms of the GNU General Public License as published by |
5259796b JG |
9 | the Free Software Foundation; either version 2 of the License, or |
10 | (at your option) any later version. | |
bd5635a1 | 11 | |
5259796b | 12 | This program is distributed in the hope that it will be useful, |
bd5635a1 RP |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
5259796b JG |
18 | along with this program; if not, write to the Free Software |
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
bd5635a1 | 20 | |
d11c44f1 | 21 | #include <stdio.h> |
bd5635a1 RP |
22 | #include "defs.h" |
23 | #include "param.h" | |
24 | #include "symtab.h" | |
25 | #include "frame.h" | |
26 | #include "gdbcore.h" | |
27 | #include "value.h" /* for read_register */ | |
28 | #include "target.h" /* for target_has_stack */ | |
29 | ||
bd5635a1 RP |
30 | CORE_ADDR read_pc (); /* In infcmd.c */ |
31 | ||
32 | /* Start and end of object file containing the entry point. | |
33 | STARTUP_FILE_END is the first address of the next file. | |
34 | This file is assumed to be a startup file | |
35 | and frames with pc's inside it | |
36 | are treated as nonexistent. | |
37 | ||
38 | Setting these variables is necessary so that backtraces do not fly off | |
39 | the bottom of the stack. */ | |
40 | CORE_ADDR startup_file_start; | |
41 | CORE_ADDR startup_file_end; | |
42 | ||
43 | /* Is ADDR outside the startup file? Note that if your machine | |
44 | has a way to detect the bottom of the stack, there is no need | |
45 | to call this function from FRAME_CHAIN_VALID; the reason for | |
46 | doing so is that some machines have no way of detecting bottom | |
47 | of stack. */ | |
48 | int | |
49 | outside_startup_file (addr) | |
50 | CORE_ADDR addr; | |
51 | { | |
52 | return !(addr >= startup_file_start && addr < startup_file_end); | |
53 | } | |
54 | ||
e140f1da JG |
55 | /* Support an alternate method to avoid running off the bottom of |
56 | the stack (or top, depending upon your stack orientation). | |
57 | ||
58 | There are two frames that are "special", the frame for the function | |
59 | containing the process entry point, since it has no predecessor frame, | |
60 | and the frame for the function containing the user code entry point | |
61 | (the main() function), since all the predecessor frames are for the | |
62 | process startup code. Since we have no guarantee that the linked | |
63 | in startup modules have any debugging information that gdb can use, | |
64 | we need to avoid following frame pointers back into frames that might | |
65 | have been built in the startup code, as we might get hopelessly | |
66 | confused. However, we almost always have debugging information | |
67 | available for main(). | |
68 | ||
69 | These variables are used to save the range of PC values which are valid | |
70 | within the main() function and within the function containing the process | |
71 | entry point. If we always consider the frame for main() as the outermost | |
72 | frame when debugging user code, and the frame for the process entry | |
73 | point function as the outermost frame when debugging startup code, then | |
74 | all we have to do is have FRAME_CHAIN_VALID return false whenever a | |
75 | frame's current PC is within the range specified by these variables. | |
76 | In essence, we set "blocks" in the frame chain beyond which we will | |
77 | not proceed when following the frame chain. | |
78 | ||
79 | A nice side effect is that we can still debug startup code without | |
80 | running off the end of the frame chain, assuming that we have usable | |
81 | debugging information in the startup modules, and if we choose to not | |
82 | use the block at main, or can't find it for some reason, everything | |
83 | still works as before. And if we have no startup code debugging | |
84 | information but we do have usable information for main(), backtraces | |
85 | from user code don't go wandering off into the startup code. | |
86 | ||
87 | To use this method, define your FRAME_CHAIN_VALID macro like: | |
88 | ||
89 | #define FRAME_CHAIN_VALID(chain, thisframe) \ | |
90 | (chain != 0 \ | |
91 | && !(inside_main_scope ((thisframe)->pc)) \ | |
92 | && !(inside_entry_scope ((thisframe)->pc))) | |
93 | ||
94 | and add initializations of the four scope controlling variables inside | |
95 | the object file / debugging information processing modules. */ | |
96 | ||
97 | CORE_ADDR entry_scope_lowpc; | |
98 | CORE_ADDR entry_scope_highpc; | |
99 | CORE_ADDR main_scope_lowpc; | |
100 | CORE_ADDR main_scope_highpc; | |
101 | ||
102 | /* Test a specified PC value to see if it is in the range of addresses | |
103 | that correspond to the main() function. See comments above for why | |
104 | we might want to do this. | |
105 | ||
106 | Typically called from FRAME_CHAIN_VALID. */ | |
107 | ||
108 | int | |
109 | inside_main_scope (pc) | |
110 | CORE_ADDR pc; | |
111 | { | |
112 | return (main_scope_lowpc <= pc && pc < main_scope_highpc); | |
113 | } | |
114 | ||
115 | /* Test a specified PC value to see if it is in the range of addresses | |
116 | that correspond to the process entry point function. See comments above | |
117 | for why we might want to do this. | |
118 | ||
119 | Typically called from FRAME_CHAIN_VALID. */ | |
120 | ||
121 | int | |
122 | inside_entry_scope (pc) | |
123 | CORE_ADDR pc; | |
124 | { | |
125 | return (entry_scope_lowpc <= pc && pc < entry_scope_highpc); | |
126 | } | |
127 | ||
bd5635a1 RP |
128 | /* Address of innermost stack frame (contents of FP register) */ |
129 | ||
130 | static FRAME current_frame; | |
131 | ||
132 | /* | |
133 | * Cache for frame addresses already read by gdb. Valid only while | |
134 | * inferior is stopped. Control variables for the frame cache should | |
135 | * be local to this module. | |
136 | */ | |
137 | struct obstack frame_cache_obstack; | |
138 | ||
139 | /* Return the innermost (currently executing) stack frame. */ | |
140 | ||
141 | FRAME | |
142 | get_current_frame () | |
143 | { | |
144 | /* We assume its address is kept in a general register; | |
145 | param.h says which register. */ | |
146 | ||
147 | return current_frame; | |
148 | } | |
149 | ||
150 | void | |
151 | set_current_frame (frame) | |
152 | FRAME frame; | |
153 | { | |
154 | current_frame = frame; | |
155 | } | |
156 | ||
157 | FRAME | |
158 | create_new_frame (addr, pc) | |
159 | FRAME_ADDR addr; | |
160 | CORE_ADDR pc; | |
161 | { | |
162 | struct frame_info *fci; /* Same type as FRAME */ | |
163 | ||
164 | fci = (struct frame_info *) | |
165 | obstack_alloc (&frame_cache_obstack, | |
166 | sizeof (struct frame_info)); | |
167 | ||
168 | /* Arbitrary frame */ | |
169 | fci->next = (struct frame_info *) 0; | |
170 | fci->prev = (struct frame_info *) 0; | |
171 | fci->frame = addr; | |
172 | fci->next_frame = 0; /* Since arbitrary */ | |
173 | fci->pc = pc; | |
174 | ||
175 | #ifdef INIT_EXTRA_FRAME_INFO | |
e140f1da | 176 | INIT_EXTRA_FRAME_INFO (0, fci); |
bd5635a1 RP |
177 | #endif |
178 | ||
179 | return fci; | |
180 | } | |
181 | ||
182 | /* Return the frame that called FRAME. | |
183 | If FRAME is the original frame (it has no caller), return 0. */ | |
184 | ||
185 | FRAME | |
186 | get_prev_frame (frame) | |
187 | FRAME frame; | |
188 | { | |
189 | /* We're allowed to know that FRAME and "struct frame_info *" are | |
190 | the same */ | |
191 | return get_prev_frame_info (frame); | |
192 | } | |
193 | ||
194 | /* Return the frame that FRAME calls (0 if FRAME is the innermost | |
195 | frame). */ | |
196 | ||
197 | FRAME | |
198 | get_next_frame (frame) | |
199 | FRAME frame; | |
200 | { | |
201 | /* We're allowed to know that FRAME and "struct frame_info *" are | |
202 | the same */ | |
203 | return frame->next; | |
204 | } | |
205 | ||
206 | /* | |
207 | * Flush the entire frame cache. | |
208 | */ | |
209 | void | |
210 | flush_cached_frames () | |
211 | { | |
212 | /* Since we can't really be sure what the first object allocated was */ | |
213 | obstack_free (&frame_cache_obstack, 0); | |
214 | obstack_init (&frame_cache_obstack); | |
215 | ||
216 | current_frame = (struct frame_info *) 0; /* Invalidate cache */ | |
217 | } | |
218 | ||
2403f49b JK |
219 | /* Flush the frame cache, and start a new one if necessary. */ |
220 | void | |
221 | reinit_frame_cache () | |
222 | { | |
223 | FRAME fr = current_frame; | |
224 | flush_cached_frames (); | |
225 | if (fr) | |
226 | set_current_frame ( create_new_frame (read_register (FP_REGNUM), | |
227 | read_pc ())); | |
228 | } | |
229 | ||
bd5635a1 RP |
230 | /* Return a structure containing various interesting information |
231 | about a specified stack frame. */ | |
232 | /* How do I justify including this function? Well, the FRAME | |
233 | identifier format has gone through several changes recently, and | |
234 | it's not completely inconceivable that it could happen again. If | |
235 | it does, have this routine around will help */ | |
236 | ||
237 | struct frame_info * | |
238 | get_frame_info (frame) | |
239 | FRAME frame; | |
240 | { | |
241 | return frame; | |
242 | } | |
243 | ||
244 | /* If a machine allows frameless functions, it should define a macro | |
245 | FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) in param.h. FI is the struct | |
246 | frame_info for the frame, and FRAMELESS should be set to nonzero | |
247 | if it represents a frameless function invocation. */ | |
248 | ||
249 | /* Return nonzero if the function for this frame has a prologue. Many | |
250 | machines can define FRAMELESS_FUNCTION_INVOCATION to just call this | |
251 | function. */ | |
252 | ||
253 | int | |
254 | frameless_look_for_prologue (frame) | |
255 | FRAME frame; | |
256 | { | |
257 | CORE_ADDR func_start, after_prologue; | |
258 | func_start = (get_pc_function_start (frame->pc) + | |
259 | FUNCTION_START_OFFSET); | |
260 | if (func_start) | |
261 | { | |
262 | after_prologue = func_start; | |
5259796b JG |
263 | #ifdef SKIP_PROLOGUE_FRAMELESS_P |
264 | /* This is faster, since only care whether there *is* a prologue, | |
265 | not how long it is. */ | |
266 | SKIP_PROLOGUE_FRAMELESS_P (after_prologue); | |
267 | #else | |
bd5635a1 | 268 | SKIP_PROLOGUE (after_prologue); |
5259796b | 269 | #endif |
bd5635a1 RP |
270 | return after_prologue == func_start; |
271 | } | |
272 | else | |
273 | /* If we can't find the start of the function, we don't really | |
274 | know whether the function is frameless, but we should be able | |
275 | to get a reasonable (i.e. best we can do under the | |
276 | circumstances) backtrace by saying that it isn't. */ | |
277 | return 0; | |
278 | } | |
279 | ||
e140f1da JG |
280 | /* Default a few macros that people seldom redefine. */ |
281 | ||
bd5635a1 RP |
282 | #if !defined (INIT_FRAME_PC) |
283 | #define INIT_FRAME_PC(fromleaf, prev) \ | |
284 | prev->pc = (fromleaf ? SAVED_PC_AFTER_CALL (prev->next) : \ | |
285 | prev->next ? FRAME_SAVED_PC (prev->next) : read_pc ()); | |
286 | #endif | |
287 | ||
e140f1da JG |
288 | #ifndef FRAME_CHAIN_COMBINE |
289 | #define FRAME_CHAIN_COMBINE(chain, thisframe) (chain) | |
290 | #endif | |
291 | ||
bd5635a1 RP |
292 | /* Return a structure containing various interesting information |
293 | about the frame that called NEXT_FRAME. Returns NULL | |
294 | if there is no such frame. */ | |
295 | ||
296 | struct frame_info * | |
297 | get_prev_frame_info (next_frame) | |
298 | FRAME next_frame; | |
299 | { | |
300 | FRAME_ADDR address; | |
301 | struct frame_info *prev; | |
302 | int fromleaf = 0; | |
303 | ||
304 | /* If the requested entry is in the cache, return it. | |
305 | Otherwise, figure out what the address should be for the entry | |
306 | we're about to add to the cache. */ | |
307 | ||
308 | if (!next_frame) | |
309 | { | |
310 | if (!current_frame) | |
311 | { | |
312 | error ("You haven't set up a process's stack to examine."); | |
313 | } | |
314 | ||
315 | return current_frame; | |
316 | } | |
317 | ||
318 | /* If we have the prev one, return it */ | |
319 | if (next_frame->prev) | |
320 | return next_frame->prev; | |
321 | ||
322 | /* On some machines it is possible to call a function without | |
323 | setting up a stack frame for it. On these machines, we | |
324 | define this macro to take two args; a frameinfo pointer | |
325 | identifying a frame and a variable to set or clear if it is | |
326 | or isn't leafless. */ | |
327 | #ifdef FRAMELESS_FUNCTION_INVOCATION | |
328 | /* Still don't want to worry about this except on the innermost | |
329 | frame. This macro will set FROMLEAF if NEXT_FRAME is a | |
330 | frameless function invocation. */ | |
331 | if (!(next_frame->next)) | |
332 | { | |
333 | FRAMELESS_FUNCTION_INVOCATION (next_frame, fromleaf); | |
334 | if (fromleaf) | |
335 | address = next_frame->frame; | |
336 | } | |
337 | #endif | |
338 | ||
339 | if (!fromleaf) | |
340 | { | |
341 | /* Two macros defined in tm.h specify the machine-dependent | |
342 | actions to be performed here. | |
343 | First, get the frame's chain-pointer. | |
344 | If that is zero, the frame is the outermost frame or a leaf | |
345 | called by the outermost frame. This means that if start | |
346 | calls main without a frame, we'll return 0 (which is fine | |
347 | anyway). | |
348 | ||
349 | Nope; there's a problem. This also returns when the current | |
350 | routine is a leaf of main. This is unacceptable. We move | |
351 | this to after the ffi test; I'd rather have backtraces from | |
352 | start go curfluy than have an abort called from main not show | |
353 | main. */ | |
354 | address = FRAME_CHAIN (next_frame); | |
355 | if (!FRAME_CHAIN_VALID (address, next_frame)) | |
356 | return 0; | |
357 | address = FRAME_CHAIN_COMBINE (address, next_frame); | |
358 | } | |
e140f1da JG |
359 | if (address == 0) |
360 | return 0; | |
bd5635a1 RP |
361 | |
362 | prev = (struct frame_info *) | |
363 | obstack_alloc (&frame_cache_obstack, | |
364 | sizeof (struct frame_info)); | |
365 | ||
366 | if (next_frame) | |
367 | next_frame->prev = prev; | |
368 | prev->next = next_frame; | |
369 | prev->prev = (struct frame_info *) 0; | |
370 | prev->frame = address; | |
371 | prev->next_frame = prev->next ? prev->next->frame : 0; | |
372 | ||
373 | #ifdef INIT_EXTRA_FRAME_INFO | |
e140f1da | 374 | INIT_EXTRA_FRAME_INFO(fromleaf, prev); |
bd5635a1 RP |
375 | #endif |
376 | ||
377 | /* This entry is in the frame queue now, which is good since | |
378 | FRAME_SAVED_PC may use that queue to figure out it's value | |
e140f1da | 379 | (see tm-sparc.h). We want the pc saved in the inferior frame. */ |
bd5635a1 RP |
380 | INIT_FRAME_PC(fromleaf, prev); |
381 | ||
382 | return prev; | |
383 | } | |
384 | ||
385 | CORE_ADDR | |
386 | get_frame_pc (frame) | |
387 | FRAME frame; | |
388 | { | |
389 | struct frame_info *fi; | |
390 | fi = get_frame_info (frame); | |
391 | return fi->pc; | |
392 | } | |
393 | ||
394 | #if defined (FRAME_FIND_SAVED_REGS) | |
395 | /* Find the addresses in which registers are saved in FRAME. */ | |
396 | ||
397 | void | |
398 | get_frame_saved_regs (frame_info_addr, saved_regs_addr) | |
399 | struct frame_info *frame_info_addr; | |
400 | struct frame_saved_regs *saved_regs_addr; | |
401 | { | |
402 | FRAME_FIND_SAVED_REGS (frame_info_addr, *saved_regs_addr); | |
403 | } | |
404 | #endif | |
405 | ||
406 | /* Return the innermost lexical block in execution | |
407 | in a specified stack frame. The frame address is assumed valid. */ | |
408 | ||
409 | struct block * | |
410 | get_frame_block (frame) | |
411 | FRAME frame; | |
412 | { | |
413 | struct frame_info *fi; | |
414 | CORE_ADDR pc; | |
415 | ||
416 | fi = get_frame_info (frame); | |
417 | ||
418 | pc = fi->pc; | |
419 | if (fi->next_frame != 0) | |
420 | /* We are not in the innermost frame. We need to subtract one to | |
421 | get the correct block, in case the call instruction was the | |
422 | last instruction of the block. If there are any machines on | |
423 | which the saved pc does not point to after the call insn, we | |
424 | probably want to make fi->pc point after the call insn anyway. */ | |
425 | --pc; | |
426 | return block_for_pc (pc); | |
427 | } | |
428 | ||
429 | struct block * | |
430 | get_current_block () | |
431 | { | |
432 | return block_for_pc (read_pc ()); | |
433 | } | |
434 | ||
435 | CORE_ADDR | |
436 | get_pc_function_start (pc) | |
437 | CORE_ADDR pc; | |
438 | { | |
439 | register struct block *bl = block_for_pc (pc); | |
440 | register struct symbol *symbol; | |
441 | if (bl == 0 || (symbol = block_function (bl)) == 0) | |
442 | { | |
443 | register int misc_index = find_pc_misc_function (pc); | |
444 | if (misc_index >= 0) | |
445 | return misc_function_vector[misc_index].address; | |
446 | return 0; | |
447 | } | |
448 | bl = SYMBOL_BLOCK_VALUE (symbol); | |
449 | return BLOCK_START (bl); | |
450 | } | |
451 | ||
452 | /* Return the symbol for the function executing in frame FRAME. */ | |
453 | ||
454 | struct symbol * | |
455 | get_frame_function (frame) | |
456 | FRAME frame; | |
457 | { | |
458 | register struct block *bl = get_frame_block (frame); | |
459 | if (bl == 0) | |
460 | return 0; | |
461 | return block_function (bl); | |
462 | } | |
463 | \f | |
464 | /* Return the blockvector immediately containing the innermost lexical block | |
465 | containing the specified pc value, or 0 if there is none. | |
466 | PINDEX is a pointer to the index value of the block. If PINDEX | |
467 | is NULL, we don't pass this information back to the caller. */ | |
468 | ||
469 | struct blockvector * | |
470 | blockvector_for_pc (pc, pindex) | |
471 | register CORE_ADDR pc; | |
472 | int *pindex; | |
473 | { | |
474 | register struct block *b; | |
475 | register int bot, top, half; | |
476 | register struct symtab *s; | |
477 | struct blockvector *bl; | |
478 | ||
479 | /* First search all symtabs for one whose file contains our pc */ | |
480 | s = find_pc_symtab (pc); | |
481 | if (s == 0) | |
482 | return 0; | |
483 | ||
484 | bl = BLOCKVECTOR (s); | |
485 | b = BLOCKVECTOR_BLOCK (bl, 0); | |
486 | ||
487 | /* Then search that symtab for the smallest block that wins. */ | |
488 | /* Use binary search to find the last block that starts before PC. */ | |
489 | ||
490 | bot = 0; | |
491 | top = BLOCKVECTOR_NBLOCKS (bl); | |
492 | ||
493 | while (top - bot > 1) | |
494 | { | |
495 | half = (top - bot + 1) >> 1; | |
496 | b = BLOCKVECTOR_BLOCK (bl, bot + half); | |
497 | if (BLOCK_START (b) <= pc) | |
498 | bot += half; | |
499 | else | |
500 | top = bot + half; | |
501 | } | |
502 | ||
503 | /* Now search backward for a block that ends after PC. */ | |
504 | ||
505 | while (bot >= 0) | |
506 | { | |
507 | b = BLOCKVECTOR_BLOCK (bl, bot); | |
508 | if (BLOCK_END (b) > pc) | |
509 | { | |
510 | if (pindex) | |
511 | *pindex = bot; | |
512 | return bl; | |
513 | } | |
514 | bot--; | |
515 | } | |
516 | ||
517 | return 0; | |
518 | } | |
519 | ||
520 | /* Return the innermost lexical block containing the specified pc value, | |
521 | or 0 if there is none. */ | |
522 | ||
523 | struct block * | |
524 | block_for_pc (pc) | |
525 | register CORE_ADDR pc; | |
526 | { | |
527 | register struct blockvector *bl; | |
528 | int index; | |
529 | ||
530 | bl = blockvector_for_pc (pc, &index); | |
531 | if (bl) | |
532 | return BLOCKVECTOR_BLOCK (bl, index); | |
533 | return 0; | |
534 | } | |
535 | ||
536 | /* Return the function containing pc value PC. | |
537 | Returns 0 if function is not known. */ | |
538 | ||
539 | struct symbol * | |
540 | find_pc_function (pc) | |
541 | CORE_ADDR pc; | |
542 | { | |
543 | register struct block *b = block_for_pc (pc); | |
544 | if (b == 0) | |
545 | return 0; | |
546 | return block_function (b); | |
547 | } | |
548 | ||
549 | /* These variables are used to cache the most recent result | |
550 | * of find_pc_partial_function. */ | |
551 | ||
552 | static CORE_ADDR cache_pc_function_low = 0; | |
553 | static CORE_ADDR cache_pc_function_high = 0; | |
554 | static char *cache_pc_function_name = 0; | |
555 | ||
556 | /* Clear cache, e.g. when symbol table is discarded. */ | |
557 | ||
558 | void | |
559 | clear_pc_function_cache() | |
560 | { | |
561 | cache_pc_function_low = 0; | |
562 | cache_pc_function_high = 0; | |
563 | cache_pc_function_name = (char *)0; | |
564 | } | |
565 | ||
566 | /* Finds the "function" (text symbol) that is smaller than PC | |
567 | but greatest of all of the potential text symbols. Sets | |
568 | *NAME and/or *ADDRESS conditionally if that pointer is non-zero. | |
569 | Returns 0 if it couldn't find anything, 1 if it did. On a zero | |
570 | return, *NAME and *ADDRESS are always set to zero. On a 1 return, | |
571 | *NAME and *ADDRESS contain real information. */ | |
572 | ||
573 | int | |
574 | find_pc_partial_function (pc, name, address) | |
575 | CORE_ADDR pc; | |
576 | char **name; | |
577 | CORE_ADDR *address; | |
578 | { | |
579 | struct partial_symtab *pst; | |
580 | struct symbol *f; | |
581 | int miscfunc; | |
582 | struct partial_symbol *psb; | |
583 | ||
584 | if (pc >= cache_pc_function_low && pc < cache_pc_function_high) | |
585 | { | |
586 | if (address) | |
587 | *address = cache_pc_function_low; | |
588 | if (name) | |
589 | *name = cache_pc_function_name; | |
590 | return 1; | |
591 | } | |
592 | ||
593 | pst = find_pc_psymtab (pc); | |
594 | if (pst) | |
595 | { | |
596 | if (pst->readin) | |
597 | { | |
598 | /* The information we want has already been read in. | |
599 | We can go to the already readin symbols and we'll get | |
600 | the best possible answer. */ | |
601 | f = find_pc_function (pc); | |
602 | if (!f) | |
603 | { | |
604 | return_error: | |
605 | /* No available symbol. */ | |
606 | if (name != 0) | |
607 | *name = 0; | |
608 | if (address != 0) | |
609 | *address = 0; | |
610 | return 0; | |
611 | } | |
612 | ||
613 | cache_pc_function_low = BLOCK_START (SYMBOL_BLOCK_VALUE (f)); | |
614 | cache_pc_function_high = BLOCK_END (SYMBOL_BLOCK_VALUE (f)); | |
615 | cache_pc_function_name = SYMBOL_NAME (f); | |
616 | if (name) | |
617 | *name = cache_pc_function_name; | |
618 | if (address) | |
619 | *address = cache_pc_function_low; | |
620 | return 1; | |
621 | } | |
622 | ||
623 | /* Get the information from a combination of the pst | |
624 | (static symbols), and the misc function vector (extern | |
625 | symbols). */ | |
626 | miscfunc = find_pc_misc_function (pc); | |
627 | psb = find_pc_psymbol (pst, pc); | |
628 | ||
629 | if (!psb && miscfunc == -1) | |
630 | { | |
631 | goto return_error; | |
632 | } | |
633 | if (psb | |
634 | && (miscfunc == -1 | |
635 | || (SYMBOL_VALUE_ADDRESS (psb) | |
636 | >= misc_function_vector[miscfunc].address))) | |
637 | { | |
638 | /* This case isn't being cached currently. */ | |
639 | if (address) | |
640 | *address = SYMBOL_VALUE_ADDRESS (psb); | |
641 | if (name) | |
642 | *name = SYMBOL_NAME (psb); | |
643 | return 1; | |
644 | } | |
645 | } | |
646 | else | |
647 | /* Must be in the misc function stuff. */ | |
648 | { | |
649 | miscfunc = find_pc_misc_function (pc); | |
650 | if (miscfunc == -1) | |
651 | goto return_error; | |
652 | } | |
653 | ||
654 | { | |
655 | if (misc_function_vector[miscfunc].type == mf_text) | |
656 | cache_pc_function_low = misc_function_vector[miscfunc].address; | |
657 | else | |
658 | /* It is a transfer table for Sun shared libraries. */ | |
659 | cache_pc_function_low = pc - FUNCTION_START_OFFSET; | |
660 | } | |
661 | cache_pc_function_name = misc_function_vector[miscfunc].name; | |
d11c44f1 | 662 | if (miscfunc < misc_function_count /* && FIXME mf_text again? */ ) |
bd5635a1 RP |
663 | cache_pc_function_high = misc_function_vector[miscfunc+1].address; |
664 | else | |
665 | cache_pc_function_high = cache_pc_function_low + 1; | |
666 | if (address) | |
667 | *address = cache_pc_function_low; | |
668 | if (name) | |
669 | *name = cache_pc_function_name; | |
670 | return 1; | |
671 | } | |
672 | ||
673 | /* Find the misc function whose address is the largest | |
674 | while being less than PC. Return its index in misc_function_vector. | |
675 | Returns -1 if PC is not in suitable range. */ | |
676 | ||
677 | int | |
678 | find_pc_misc_function (pc) | |
679 | register CORE_ADDR pc; | |
680 | { | |
681 | register int lo = 0; | |
682 | register int hi = misc_function_count-1; | |
683 | register int new; | |
684 | ||
685 | /* Note that the last thing in the vector is always _etext. */ | |
686 | /* Actually, "end", now that non-functions | |
687 | go on the misc_function_vector. */ | |
688 | ||
689 | /* Above statement is not *always* true - fix for case where there are */ | |
690 | /* no misc functions at all (ie no symbol table has been read). */ | |
691 | if (hi < 0) return -1; /* no misc functions recorded */ | |
692 | ||
693 | /* trivial reject range test */ | |
694 | if (pc < misc_function_vector[0].address || | |
695 | pc > misc_function_vector[hi].address) | |
696 | return -1; | |
697 | ||
698 | /* Note that the following search will not return hi if | |
699 | pc == misc_function_vector[hi].address. If "end" points to the | |
700 | first unused location, this is correct and the above test | |
701 | simply needs to be changed to | |
702 | "pc >= misc_function_vector[hi].address". */ | |
703 | do { | |
704 | new = (lo + hi) >> 1; | |
705 | if (misc_function_vector[new].address == pc) | |
706 | return new; /* an exact match */ | |
707 | else if (misc_function_vector[new].address > pc) | |
708 | hi = new; | |
709 | else | |
710 | lo = new; | |
711 | } while (hi-lo != 1); | |
712 | ||
713 | /* if here, we had no exact match, so return the lower choice */ | |
714 | return lo; | |
715 | } | |
716 | ||
717 | /* Return the innermost stack frame executing inside of the specified block, | |
718 | or zero if there is no such frame. */ | |
719 | ||
720 | FRAME | |
721 | block_innermost_frame (block) | |
722 | struct block *block; | |
723 | { | |
724 | struct frame_info *fi; | |
725 | register FRAME frame; | |
726 | register CORE_ADDR start = BLOCK_START (block); | |
727 | register CORE_ADDR end = BLOCK_END (block); | |
728 | ||
729 | frame = 0; | |
730 | while (1) | |
731 | { | |
732 | frame = get_prev_frame (frame); | |
733 | if (frame == 0) | |
734 | return 0; | |
735 | fi = get_frame_info (frame); | |
736 | if (fi->pc >= start && fi->pc < end) | |
737 | return frame; | |
738 | } | |
739 | } | |
740 | ||
741 | void | |
742 | _initialize_blockframe () | |
743 | { | |
744 | obstack_init (&frame_cache_obstack); | |
745 | } |