1 /* Get info from stack frames;
2 convert between frames, blocks, functions and pc values.
3 Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
5 GDB is distributed in the hope that it will be useful, but WITHOUT ANY
6 WARRANTY. No author or distributor accepts responsibility to anyone
7 for the consequences of using it or for whether it serves any
8 particular purpose or works at all, unless he says so in writing.
9 Refer to the GDB General Public License for full details.
11 Everyone is granted permission to copy, modify and redistribute GDB,
12 but only under the conditions described in the GDB General Public
13 License. A copy of this license is supposed to have been given to you
14 along with GDB so you can know your rights and responsibilities. It
15 should be in a file named COPYING. Among other things, the copyright
16 notice and this notice must be preserved on all copies.
18 In other words, go ahead and share GDB, but don't try to stop
19 anyone else from sharing it farther. Help stamp out software hoarding!
23 #include "initialize.h"
28 /* Address of end of first object file.
29 This file is assumed to be a startup file
30 and frames with pc's inside it
31 are treated as nonexistent. */
33 CORE_ADDR first_object_file_end
;
35 /* Address of innermost stack frame (contents of FP register) */
37 static FRAME current_frame
;
39 struct block
*block_for_pc ();
40 CORE_ADDR
get_pc_function_start ();
44 /* Return the innermost (currently executing) stack frame. */
49 /* We assume its address is kept in a general register;
50 param.h says which register. */
56 set_current_frame (frame
)
59 current_frame
= frame
;
62 /* Return the frame that called FRAME.
63 If FRAME is the original frame (it has no caller), return 0. */
66 get_prev_frame (frame
)
70 /* The caller of "no frame" is the innermost frame. */
72 return get_current_frame ();
74 /* Two macros defined in param.h specify the machine-dependent
75 actions to be performed here. */
76 /* First, get the frame's chain-pointer.
77 If that is zero, the frame is the outermost frame. */
78 pointer
= FRAME_CHAIN (frame
);
79 if (!FRAME_CHAIN_VALID (pointer
, frame
))
81 /* If frame has a caller, combine the chain pointer and the frame's own
82 address to get the address of the caller. */
83 return FRAME_CHAIN_COMBINE (pointer
, frame
);
86 /* Return a structure containing various interesting information
87 about a specified stack frame. */
90 get_frame_info (frame
)
93 struct frame_info val
;
94 FRAME current
= get_current_frame ();
95 register FRAME frame1
;
106 for (frame1
= current
; frame1
; frame1
= get_prev_frame (frame1
))
112 val
.pc
= FRAME_SAVED_PC (frame1
);
113 val
.next_frame
= frame1
;
120 /* Return a structure containing various interesting information
121 about the frame that called FRAME.
123 This is much faster than get_frame_info (get_prev_frame (FRAME))
124 because it does not need to search the entire stack
125 to find the frame called by the one being described -- that is FRAME. */
128 get_prev_frame_info (next_frame
)
131 struct frame_info val
;
132 register FRAME frame
= get_prev_frame (next_frame
);
135 val
.next_frame
= next_frame
;
143 val
.pc
= FRAME_SAVED_PC (next_frame
);
153 struct frame_info fi
;
154 fi
= get_frame_info (frame
);
158 /* Find the addresses in which registers are saved in FRAME. */
161 get_frame_saved_regs (frame_info_addr
, saved_regs_addr
)
162 struct frame_info
*frame_info_addr
;
163 struct frame_saved_regs
*saved_regs_addr
;
165 FRAME_FIND_SAVED_REGS (*frame_info_addr
, *saved_regs_addr
);
168 /* Return the innermost lexical block in execution
169 in a specified stack frame. The frame address is assumed valid. */
172 get_frame_block (frame
)
175 struct frame_info fi
;
177 fi
= get_frame_info (frame
);
178 return block_for_pc (fi
.pc
);
184 return block_for_pc (read_pc ());
188 get_pc_function_start (pc
)
191 register struct block
*bl
= block_for_pc (pc
);
192 register struct symbol
*symbol
;
195 register int misc_index
= find_pc_misc_function (pc
);
197 return misc_function_vector
[misc_index
].address
;
200 symbol
= block_function (bl
);
201 bl
= SYMBOL_BLOCK_VALUE (symbol
);
202 return BLOCK_START (bl
);
205 /* Return the symbol for the function executing in frame FRAME. */
208 get_frame_function (frame
)
211 register struct block
*bl
= get_frame_block (frame
);
214 return block_function (bl
);
217 /* Return the innermost lexical block containing the specified pc value,
218 or 0 if there is none. */
222 register CORE_ADDR pc
;
224 register struct block
*b
;
225 register int bot
, top
, half
;
226 register struct symtab
*s
;
227 struct blockvector
*bl
;
229 /* First search all symtabs for one whose file contains our pc */
231 for (s
= symtab_list
; s
; s
= s
->next
)
233 bl
= BLOCKVECTOR (s
);
234 b
= BLOCKVECTOR_BLOCK (bl
, 0);
235 if (BLOCK_START (b
) <= pc
236 && BLOCK_END (b
) > pc
)
243 /* Then search that symtab for the smallest block that wins. */
244 /* Use binary search to find the last block that starts before PC. */
247 top
= BLOCKVECTOR_NBLOCKS (bl
);
249 while (top
- bot
> 1)
251 half
= (top
- bot
+ 1) >> 1;
252 b
= BLOCKVECTOR_BLOCK (bl
, bot
+ half
);
253 if (BLOCK_START (b
) <= pc
)
259 /* Now search backward for a block that ends after PC. */
263 b
= BLOCKVECTOR_BLOCK (bl
, bot
);
264 if (BLOCK_END (b
) > pc
)
272 /* Return the function containing pc value PC.
273 Returns 0 if function is not known. */
276 find_pc_function (pc
)
279 register struct block
*b
= block_for_pc (pc
);
282 return block_function (b
);
285 /* Find the misc function whose address is the largest
286 while being less than PC. Return its index in misc_function_vector.
287 Returns -1 if PC is not in suitable range. */
290 find_pc_misc_function (pc
)
291 register CORE_ADDR pc
;
294 register int hi
= misc_function_count
-1;
296 register int distance
;
298 /* Note that the last thing in the vector is always _etext. */
300 /* Above statement is not *always* true - fix for case where there are */
301 /* no misc functions at all (ie no symbol table has been read). */
302 if (hi
< 0) return -1; /* no misc functions recorded */
304 /* trivial reject range test */
305 if (pc
< misc_function_vector
[0].address
||
306 pc
> misc_function_vector
[hi
].address
)
310 new = (lo
+ hi
) >> 1;
311 distance
= misc_function_vector
[new].address
- pc
;
313 return new; /* an exact match */
314 else if (distance
> 0)
318 } while (hi
-lo
!= 1);
320 /* if here, we had no exact match, so return the lower choice */
324 /* Return the innermost stack frame executing inside of the specified block,
325 or zero if there is no such frame. */
328 block_innermost_frame (block
)
331 struct frame_info fi
;
332 register FRAME frame
;
333 register CORE_ADDR start
= BLOCK_START (block
);
334 register CORE_ADDR end
= BLOCK_END (block
);
339 fi
= get_prev_frame_info (frame
);
343 if (fi
.pc
>= start
&& fi
.pc
< end
)