gdb-2.8.1
[deliverable/binutils-gdb.git] / gdb / blockframe.c
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.
4
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.
10
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.
17
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!
20 */
21
22 #include "defs.h"
23 #include "initialize.h"
24 #include "param.h"
25 #include "symtab.h"
26 #include "frame.h"
27
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. */
32
33 CORE_ADDR first_object_file_end;
34
35 /* Address of innermost stack frame (contents of FP register) */
36
37 static FRAME current_frame;
38
39 struct block *block_for_pc ();
40 CORE_ADDR get_pc_function_start ();
41
42 START_FILE
43
44 /* Return the innermost (currently executing) stack frame. */
45
46 FRAME
47 get_current_frame ()
48 {
49 /* We assume its address is kept in a general register;
50 param.h says which register. */
51
52 return current_frame;
53 }
54
55 void
56 set_current_frame (frame)
57 FRAME frame;
58 {
59 current_frame = frame;
60 }
61
62 /* Return the frame that called FRAME.
63 If FRAME is the original frame (it has no caller), return 0. */
64
65 FRAME
66 get_prev_frame (frame)
67 FRAME frame;
68 {
69 CORE_ADDR pointer;
70 /* The caller of "no frame" is the innermost frame. */
71 if (frame == 0)
72 return get_current_frame ();
73
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))
80 return 0;
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);
84 }
85
86 /* Return a structure containing various interesting information
87 about a specified stack frame. */
88
89 struct frame_info
90 get_frame_info (frame)
91 FRAME frame;
92 {
93 struct frame_info val;
94 FRAME current = get_current_frame ();
95 register FRAME frame1, frame2;
96
97 val.frame = frame;
98
99 if (frame == current)
100 {
101 val.pc = read_pc ();
102 val.next_frame = 0;
103 val.next_next_frame = 0;
104 }
105 else
106 {
107 for (frame1 = current, frame2 = 0;
108 frame1;
109 frame2 = frame1, frame1 = get_prev_frame (frame1))
110 {
111 QUIT;
112 if (frame1 == frame)
113 break;
114
115 val.pc = FRAME_SAVED_PC (frame1, frame2);
116 val.next_frame = frame1;
117 val.next_next_frame = frame2;
118 }
119 }
120
121 return val;
122 }
123
124 /* Return a structure containing various interesting information
125 about the frame that called FRAME.
126
127 This is much faster than get_frame_info (get_prev_frame (FRAME))
128 because it does not need to search the entire stack
129 to find the frame called by the one being described -- that is FRAME. */
130
131 struct frame_info
132 get_prev_frame_info (next_frame, next_next_frame)
133 FRAME next_frame, next_next_frame;
134 {
135 struct frame_info val;
136 register FRAME frame = get_prev_frame (next_frame);
137
138 val.frame = frame;
139 val.next_frame = next_frame;
140 val.next_next_frame = next_next_frame;
141
142 if (next_frame == 0)
143 {
144 val.pc = read_pc ();
145 }
146 else
147 {
148 val.pc = FRAME_SAVED_PC (next_frame, next_next_frame);
149 }
150
151 return val;
152 }
153
154 CORE_ADDR
155 get_frame_pc (frame)
156 FRAME frame;
157 {
158 struct frame_info fi;
159 fi = get_frame_info (frame);
160 return fi.pc;
161 }
162
163 /* Find the addresses in which registers are saved in FRAME. */
164
165 void
166 get_frame_saved_regs (frame_info_addr, saved_regs_addr)
167 struct frame_info *frame_info_addr;
168 struct frame_saved_regs *saved_regs_addr;
169 {
170 FRAME_FIND_SAVED_REGS (*frame_info_addr, *saved_regs_addr);
171 }
172
173 /* Return the innermost lexical block in execution
174 in a specified stack frame. The frame address is assumed valid. */
175
176 struct block *
177 get_frame_block (frame)
178 FRAME frame;
179 {
180 struct frame_info fi;
181
182 fi = get_frame_info (frame);
183 return block_for_pc (fi.pc);
184 }
185
186 struct block *
187 get_current_block ()
188 {
189 return block_for_pc (read_pc ());
190 }
191
192 CORE_ADDR
193 get_pc_function_start (pc)
194 CORE_ADDR pc;
195 {
196 register struct block *bl = block_for_pc (pc);
197 register struct symbol *symbol;
198 if (bl == 0)
199 {
200 register int misc_index = find_pc_misc_function (pc);
201 if (misc_index >= 0)
202 return misc_function_vector[misc_index].address;
203 return 0;
204 }
205 symbol = block_function (bl);
206 bl = SYMBOL_BLOCK_VALUE (symbol);
207 return BLOCK_START (bl);
208 }
209
210 /* Return the symbol for the function executing in frame FRAME. */
211
212 struct symbol *
213 get_frame_function (frame)
214 FRAME frame;
215 {
216 register struct block *bl = get_frame_block (frame);
217 if (bl == 0)
218 return 0;
219 return block_function (bl);
220 }
221 \f
222 /* Return the innermost lexical block containing the specified pc value,
223 or 0 if there is none. */
224
225 struct block *
226 block_for_pc (pc)
227 register CORE_ADDR pc;
228 {
229 register struct block *b;
230 register int bot, top, half;
231 register struct symtab *s;
232 struct blockvector *bl;
233
234 /* First search all symtabs for one whose file contains our pc */
235
236 for (s = symtab_list; s; s = s->next)
237 {
238 bl = BLOCKVECTOR (s);
239 b = BLOCKVECTOR_BLOCK (bl, 0);
240 if (BLOCK_START (b) <= pc
241 && BLOCK_END (b) > pc)
242 break;
243 }
244
245 if (s == 0)
246 return 0;
247
248 /* Then search that symtab for the smallest block that wins. */
249 /* Use binary search to find the last block that starts before PC. */
250
251 bot = 0;
252 top = BLOCKVECTOR_NBLOCKS (bl);
253
254 while (top - bot > 1)
255 {
256 half = (top - bot + 1) >> 1;
257 b = BLOCKVECTOR_BLOCK (bl, bot + half);
258 if (BLOCK_START (b) <= pc)
259 bot += half;
260 else
261 top = bot + half;
262 }
263
264 /* Now search backward for a block that ends after PC. */
265
266 while (bot >= 0)
267 {
268 b = BLOCKVECTOR_BLOCK (bl, bot);
269 if (BLOCK_END (b) > pc)
270 return b;
271 bot--;
272 }
273
274 return 0;
275 }
276
277 /* Return the function containing pc value PC.
278 Returns 0 if function is not known. */
279
280 struct symbol *
281 find_pc_function (pc)
282 CORE_ADDR pc;
283 {
284 register struct block *b = block_for_pc (pc);
285 if (b == 0)
286 return 0;
287 return block_function (b);
288 }
289
290 /* Find the misc function whose address is the largest
291 while being less than PC. Return its index in misc_function_vector.
292 Returns -1 if PC is not in suitable range. */
293
294 int
295 find_pc_misc_function (pc)
296 register CORE_ADDR pc;
297 {
298 register int lo = 0;
299 register int hi = misc_function_count-1;
300 register int new;
301 register int distance;
302
303 /* Note that the last thing in the vector is always _etext. */
304
305 /* Above statement is not *always* true - fix for case where there are */
306 /* no misc functions at all (ie no symbol table has been read). */
307 if (hi < 0) return -1; /* no misc functions recorded */
308
309 /* trivial reject range test */
310 if (pc < misc_function_vector[0].address ||
311 pc > misc_function_vector[hi].address)
312 return -1;
313
314 do {
315 new = (lo + hi) >> 1;
316 distance = misc_function_vector[new].address - pc;
317 if (distance == 0)
318 return new; /* an exact match */
319 else if (distance > 0)
320 hi = new;
321 else
322 lo = new;
323 } while (hi-lo != 1);
324
325 /* if here, we had no exact match, so return the lower choice */
326 return lo;
327 }
328
329 /* Return the innermost stack frame executing inside of the specified block,
330 or zero if there is no such frame. */
331
332 FRAME
333 block_innermost_frame (block)
334 struct block *block;
335 {
336 struct frame_info fi;
337 register FRAME frame;
338 register CORE_ADDR start = BLOCK_START (block);
339 register CORE_ADDR end = BLOCK_END (block);
340
341 frame = 0;
342 while (1)
343 {
344 fi = get_prev_frame_info (frame);
345 frame = fi.frame;
346 if (frame == 0)
347 return 0;
348 if (fi.pc >= start && fi.pc < end)
349 return frame;
350 }
351 }
352
353 static
354 initialize ()
355 {
356 }
357
358 END_FILE
This page took 0.037469 seconds and 5 git commands to generate.