This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / gnu / usr.bin / kgdb / blockframe.c
CommitLineData
04497f0b
NW
1/*-
2 * This code is derived from software copyrighted by the Free Software
3 * Foundation.
4 *
5 * Modified 1991 by Donn Seeley at UUNET Technologies, Inc.
6 * Modified 1990 by Van Jacobson at Lawrence Berkeley Laboratory.
7 */
8
9#ifndef lint
10static char sccsid[] = "@(#)blockframe.c 6.4 (Berkeley) 5/11/91";
11#endif /* not lint */
12
13/* Get info from stack frames;
14 convert between frames, blocks, functions and pc values.
15 Copyright (C) 1986, 1987, 1988, 1989 Free Software Foundation, Inc.
16
17This file is part of GDB.
18
19GDB is free software; you can redistribute it and/or modify
20it under the terms of the GNU General Public License as published by
21the Free Software Foundation; either version 1, or (at your option)
22any later version.
23
24GDB is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29You should have received a copy of the GNU General Public License
30along with GDB; see the file COPYING. If not, write to
31the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
32
33#include "defs.h"
34#include "param.h"
35#include "symtab.h"
36#include "frame.h"
37
38#include <obstack.h>
39
40#if defined(NEWVM) && defined(KERNELDEBUG)
41#include <sys/param.h> /* XXX for FRAME_CHAIN_VALID */
42#endif
43
44/* Start and end of object file containing the entry point.
45 STARTUP_FILE_END is the first address of the next file.
46 This file is assumed to be a startup file
47 and frames with pc's inside it
48 are treated as nonexistent.
49
50 Setting these variables is necessary so that backtraces do not fly off
51 the bottom of the stack. */
52CORE_ADDR startup_file_start;
53CORE_ADDR startup_file_end;
54
55/* Is ADDR outside the startup file? */
56int
57outside_startup_file (addr)
58 CORE_ADDR addr;
59{
60 return !(addr >= startup_file_start && addr < startup_file_end);
61}
62
63/* Address of innermost stack frame (contents of FP register) */
64
65static FRAME current_frame;
66
67struct block *block_for_pc ();
68CORE_ADDR get_pc_function_start ();
69
70/*
71 * Cache for frame addresses already read by gdb. Valid only while
72 * inferior is stopped. Control variables for the frame cache should
73 * be local to this module.
74 */
75struct obstack frame_cache_obstack;
76
77/* Return the innermost (currently executing) stack frame. */
78
79FRAME
80get_current_frame ()
81{
82 /* We assume its address is kept in a general register;
83 param.h says which register. */
84
85 return current_frame;
86}
87
88void
89set_current_frame (frame)
90 FRAME frame;
91{
92 current_frame = frame;
93}
94
95FRAME
96create_new_frame (addr, pc)
97 FRAME_ADDR addr;
98 CORE_ADDR pc;
99{
100 struct frame_info *fci; /* Same type as FRAME */
101
102 fci = (struct frame_info *)
103 obstack_alloc (&frame_cache_obstack,
104 sizeof (struct frame_info));
105
106 /* Arbitrary frame */
107 fci->next = (struct frame_info *) 0;
108 fci->prev = (struct frame_info *) 0;
109 fci->frame = addr;
110 fci->next_frame = 0; /* Since arbitrary */
111 fci->pc = pc;
112
113#ifdef INIT_EXTRA_FRAME_INFO
114 INIT_EXTRA_FRAME_INFO (fci);
115#endif
116
117 return fci;
118}
119
120/* Return the frame that called FRAME.
121 If FRAME is the original frame (it has no caller), return 0. */
122
123FRAME
124get_prev_frame (frame)
125 FRAME frame;
126{
127 /* We're allowed to know that FRAME and "struct frame_info *" are
128 the same */
129 return get_prev_frame_info (frame);
130}
131
132/* Return the frame that FRAME calls (0 if FRAME is the innermost
133 frame). */
134
135FRAME
136get_next_frame (frame)
137 FRAME frame;
138{
139 /* We're allowed to know that FRAME and "struct frame_info *" are
140 the same */
141 return frame->next;
142}
143
144/*
145 * Flush the entire frame cache.
146 */
147void
148flush_cached_frames ()
149{
150 /* Since we can't really be sure what the first object allocated was */
151 obstack_free (&frame_cache_obstack, 0);
152 obstack_init (&frame_cache_obstack);
153
154 current_frame = (struct frame_info *) 0; /* Invalidate cache */
155}
156
157/* Return a structure containing various interesting information
158 about a specified stack frame. */
159/* How do I justify including this function? Well, the FRAME
160 identifier format has gone through several changes recently, and
161 it's not completely inconceivable that it could happen again. If
162 it does, have this routine around will help */
163
164struct frame_info *
165get_frame_info (frame)
166 FRAME frame;
167{
168 return frame;
169}
170
171/* If a machine allows frameless functions, it should define a macro
172 FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) in param.h. FI is the struct
173 frame_info for the frame, and FRAMELESS should be set to nonzero
174 if it represents a frameless function invocation. */
175
176/* Many machines which allow frameless functions can detect them using
177 this macro. Such machines should define FRAMELESS_FUNCTION_INVOCATION
178 to just call this macro. */
179#define FRAMELESS_LOOK_FOR_PROLOGUE(FI, FRAMELESS) \
180{ \
181 CORE_ADDR func_start, after_prologue; \
182 func_start = (get_pc_function_start ((FI)->pc) + \
183 FUNCTION_START_OFFSET); \
184 if (func_start) \
185 { \
186 after_prologue = func_start; \
187 SKIP_PROLOGUE (after_prologue); \
188 (FRAMELESS) = (after_prologue == func_start); \
189 } \
190 else \
191 /* If we can't find the start of the function, we don't really */ \
192 /* know whether the function is frameless, but we should be */ \
193 /* able to get a reasonable (i.e. best we can do under the */ \
194 /* circumstances) backtrace by saying that it isn't. */ \
195 (FRAMELESS) = 0; \
196}
197
198/* Return a structure containing various interesting information
199 about the frame that called NEXT_FRAME. Returns NULL
200 if there is no such frame. */
201
202struct frame_info *
203get_prev_frame_info (next_frame)
204 FRAME next_frame;
205{
206 FRAME_ADDR address;
207 struct frame_info *prev;
208 int fromleaf = 0;
209
210 /* If the requested entry is in the cache, return it.
211 Otherwise, figure out what the address should be for the entry
212 we're about to add to the cache. */
213
214 if (!next_frame)
215 {
216 if (!current_frame)
217 {
218 if (!have_inferior_p () && !have_core_file_p ())
219 fatal ("get_prev_frame_info: Called before cache primed. \"Shouldn't happen.\"");
220 else
221 error ("No inferior or core file.");
222 }
223
224 return current_frame;
225 }
226
227 /* If we have the prev one, return it */
228 if (next_frame->prev)
229 return next_frame->prev;
230
231 /* On some machines it is possible to call a function without
232 setting up a stack frame for it. On these machines, we
233 define this macro to take two args; a frameinfo pointer
234 identifying a frame and a variable to set or clear if it is
235 or isn't leafless. */
236#ifdef FRAMELESS_FUNCTION_INVOCATION
237 /* Still don't want to worry about this except on the innermost
238 frame. This macro will set FROMLEAF if NEXT_FRAME is a
239 frameless function invocation. */
240 if (!(next_frame->next))
241 {
242 FRAMELESS_FUNCTION_INVOCATION (next_frame, fromleaf);
243 if (fromleaf)
244 address = next_frame->frame;
245 }
246#endif
247
248 if (!fromleaf)
249 {
250 /* Two macros defined in param.h specify the machine-dependent
251 actions to be performed here.
252 First, get the frame's chain-pointer.
253 If that is zero, the frame is the outermost frame or a leaf
254 called by the outermost frame. This means that if start
255 calls main without a frame, we'll return 0 (which is fine
256 anyway).
257
258 Nope; there's a problem. This also returns when the current
259 routine is a leaf of main. This is unacceptable. We move
260 this to after the ffi test; I'd rather have backtraces from
261 start go curfluy than have an abort called from main not show
262 main. */
263 address = FRAME_CHAIN (next_frame);
264 if (!FRAME_CHAIN_VALID (address, next_frame))
265 return 0;
266 /* If this frame is a leaf, this will be superceeded by the
267 code below. */
268 address = FRAME_CHAIN_COMBINE (address, next_frame);
269 }
270 if (address == 0)
271 return 0;
272
273 prev = (struct frame_info *)
274 obstack_alloc (&frame_cache_obstack,
275 sizeof (struct frame_info));
276
277 if (next_frame)
278 next_frame->prev = prev;
279 prev->next = next_frame;
280 prev->prev = (struct frame_info *) 0;
281 prev->frame = address;
282 prev->next_frame = prev->next ? prev->next->frame : 0;
283
284#ifdef INIT_EXTRA_FRAME_INFO
285 INIT_EXTRA_FRAME_INFO(prev);
286#endif
287
288 /* This entry is in the frame queue now, which is good since
289 FRAME_SAVED_PC may use that queue to figure out it's value
290 (see m-sparc.h). We want the pc saved in the inferior frame. */
291 prev->pc = (fromleaf ? SAVED_PC_AFTER_CALL (next_frame) :
292 next_frame ? FRAME_SAVED_PC (next_frame) : read_pc ());
293
294 return prev;
295}
296
297CORE_ADDR
298get_frame_pc (frame)
299 FRAME frame;
300{
301 struct frame_info *fi;
302 fi = get_frame_info (frame);
303 return fi->pc;
304}
305
306/* Find the addresses in which registers are saved in FRAME. */
307
308void
309get_frame_saved_regs (frame_info_addr, saved_regs_addr)
310 struct frame_info *frame_info_addr;
311 struct frame_saved_regs *saved_regs_addr;
312{
313 FRAME_FIND_SAVED_REGS (frame_info_addr, *saved_regs_addr);
314}
315
316/* Return the innermost lexical block in execution
317 in a specified stack frame. The frame address is assumed valid. */
318
319struct block *
320get_frame_block (frame)
321 FRAME frame;
322{
323 struct frame_info *fi;
324 CORE_ADDR pc;
325
326 fi = get_frame_info (frame);
327
328 pc = fi->pc;
329 if (fi->next_frame != 0)
330 /* We are not in the innermost frame. We need to subtract one to
331 get the correct block, in case the call instruction was the
332 last instruction of the block. If there are any machines on
333 which the saved pc does not point to after the call insn, we
334 probably want to make fi->pc point after the call insn anyway. */
335 --pc;
336 return block_for_pc (pc);
337}
338
339struct block *
340get_current_block ()
341{
342 return block_for_pc (read_pc ());
343}
344
345CORE_ADDR
346get_pc_function_start (pc)
347 CORE_ADDR pc;
348{
349 register struct block *bl = block_for_pc (pc);
350 register struct symbol *symbol;
351 if (bl == 0 || (symbol = block_function (bl)) == 0)
352 {
353 register int misc_index = find_pc_misc_function (pc);
354 if (misc_index >= 0)
355 return misc_function_vector[misc_index].address;
356 return 0;
357 }
358 bl = SYMBOL_BLOCK_VALUE (symbol);
359 return BLOCK_START (bl);
360}
361
362/* Return the symbol for the function executing in frame FRAME. */
363
364struct symbol *
365get_frame_function (frame)
366 FRAME frame;
367{
368 register struct block *bl = get_frame_block (frame);
369 if (bl == 0)
370 return 0;
371 return block_function (bl);
372}
373\f
374/* Return the innermost lexical block containing the specified pc value,
375 or 0 if there is none. */
376
377extern struct symtab *psymtab_to_symtab ();
378
379struct block *
380block_for_pc (pc)
381 register CORE_ADDR pc;
382{
383 register struct block *b;
384 register int bot, top, half;
385 register struct symtab *s;
386 register struct partial_symtab *ps;
387 struct blockvector *bl;
388
389 /* First search all symtabs for one whose file contains our pc */
390
391 for (s = symtab_list; s; s = s->next)
392 {
393 bl = BLOCKVECTOR (s);
394 b = BLOCKVECTOR_BLOCK (bl, 0);
395 if (BLOCK_START (b) <= pc
396 && BLOCK_END (b) > pc)
397 break;
398 }
399
400 if (s == 0)
401 for (ps = partial_symtab_list; ps; ps = ps->next)
402 {
403 if (ps->textlow <= pc
404 && ps->texthigh > pc)
405 {
406 if (ps->readin)
407 fatal ("Internal error: pc found in readin psymtab and not in any symtab.");
408 s = psymtab_to_symtab (ps);
409 bl = BLOCKVECTOR (s);
410 b = BLOCKVECTOR_BLOCK (bl, 0);
411 break;
412 }
413 }
414
415 if (s == 0)
416 return 0;
417
418 /* Then search that symtab for the smallest block that wins. */
419 /* Use binary search to find the last block that starts before PC. */
420
421 bot = 0;
422 top = BLOCKVECTOR_NBLOCKS (bl);
423
424 while (top - bot > 1)
425 {
426 half = (top - bot + 1) >> 1;
427 b = BLOCKVECTOR_BLOCK (bl, bot + half);
428 if (BLOCK_START (b) <= pc)
429 bot += half;
430 else
431 top = bot + half;
432 }
433
434 /* Now search backward for a block that ends after PC. */
435
436 while (bot >= 0)
437 {
438 b = BLOCKVECTOR_BLOCK (bl, bot);
439 if (BLOCK_END (b) > pc)
440 return b;
441 bot--;
442 }
443
444 return 0;
445}
446
447/* Return the function containing pc value PC.
448 Returns 0 if function is not known. */
449
450struct symbol *
451find_pc_function (pc)
452 CORE_ADDR pc;
453{
454 register struct block *b = block_for_pc (pc);
455 if (b == 0)
456 return 0;
457 return block_function (b);
458}
459
460/* Finds the "function" (text symbol) that is smaller than PC
461 but greatest of all of the potential text symbols. Sets
462 *NAME and/or *ADDRESS conditionally if that pointer is non-zero.
463 Returns 0 if it couldn't find anything, 1 if it did. On a zero
464 return, *NAME and *ADDRESS are always set to zero. On a 1 return,
465 *NAME and *ADDRESS contain real information. */
466
467int
468find_pc_partial_function (pc, name, address)
469 CORE_ADDR pc;
470 char **name;
471 CORE_ADDR *address;
472{
473 struct partial_symtab *pst = find_pc_psymtab (pc);
474 struct symbol *f;
475 int miscfunc;
476 struct partial_symbol *psb;
477
478 if (pst)
479 {
480 if (pst->readin)
481 {
482 /* The information we want has already been read in.
483 We can go to the already readin symbols and we'll get
484 the best possible answer. */
485 f = find_pc_function (pc);
486 if (!f)
487 {
488 return_error:
489 /* No availible symbol. */
490 if (name != 0)
491 *name = 0;
492 if (address != 0)
493 *address = 0;
494 return 0;
495 }
496
497 if (name)
498 *name = SYMBOL_NAME (f);
499 if (address)
500 *address = BLOCK_START (SYMBOL_BLOCK_VALUE (f));
501 return 1;
502 }
503
504 /* Get the information from a combination of the pst
505 (static symbols), and the misc function vector (extern
506 symbols). */
507 miscfunc = find_pc_misc_function (pc);
508 psb = find_pc_psymbol (pst, pc);
509
510 if (!psb && miscfunc == -1)
511 {
512 goto return_error;
513 }
514 if (!psb
515 || (miscfunc != -1
516 && (SYMBOL_VALUE(psb)
517 < misc_function_vector[miscfunc].address)))
518 {
519 if (address)
520 *address = misc_function_vector[miscfunc].address;
521 if (name)
522 *name = misc_function_vector[miscfunc].name;
523 return 1;
524 }
525 else
526 {
527 if (address)
528 *address = SYMBOL_VALUE (psb);
529 if (name)
530 *name = SYMBOL_NAME (psb);
531 return 1;
532 }
533 }
534 else
535 /* Must be in the misc function stuff. */
536 {
537 miscfunc = find_pc_misc_function (pc);
538 if (miscfunc == -1)
539 goto return_error;
540 if (address)
541 *address = misc_function_vector[miscfunc].address;
542 if (name)
543 *name = misc_function_vector[miscfunc].name;
544 return 1;
545 }
546}
547
548/* Find the misc function whose address is the largest
549 while being less than PC. Return its index in misc_function_vector.
550 Returns -1 if PC is not in suitable range. */
551
552int
553find_pc_misc_function (pc)
554 register CORE_ADDR pc;
555{
556 register int lo = 0;
557 register int hi = misc_function_count-1;
558 register int new;
559 register int distance;
560
561 /* Note that the last thing in the vector is always _etext. */
562 /* Actually, "end", now that non-functions
563 go on the misc_function_vector. */
564
565 /* Above statement is not *always* true - fix for case where there are */
566 /* no misc functions at all (ie no symbol table has been read). */
567 if (hi < 0) return -1; /* no misc functions recorded */
568
569 /* trivial reject range test */
570 if (pc < misc_function_vector[0].address ||
571 pc > misc_function_vector[hi].address)
572 return -1;
573
574 /* Note that the following search will not return hi if
575 pc == misc_function_vector[hi].address. If "end" points to the
576 first unused location, this is correct and the above test
577 simply needs to be changed to
578 "pc >= misc_function_vector[hi].address". */
579 do {
580 new = (lo + hi) >> 1;
581 distance = misc_function_vector[new].address - pc;
582 if (distance == 0)
583 return new; /* an exact match */
584 else if (distance > 0)
585 hi = new;
586 else
587 lo = new;
588 } while (hi-lo != 1);
589
590 /* if here, we had no exact match, so return the lower choice */
591 return lo;
592}
593
594/* Return the innermost stack frame executing inside of the specified block,
595 or zero if there is no such frame. */
596
597FRAME
598block_innermost_frame (block)
599 struct block *block;
600{
601 struct frame_info *fi;
602 register FRAME frame;
603 register CORE_ADDR start = BLOCK_START (block);
604 register CORE_ADDR end = BLOCK_END (block);
605
606 frame = 0;
607 while (1)
608 {
609 frame = get_prev_frame (frame);
610 if (frame == 0)
611 return 0;
612 fi = get_frame_info (frame);
613 if (fi->pc >= start && fi->pc < end)
614 return frame;
615 }
616}
617
618void
619_initialize_blockframe ()
620{
621 obstack_init (&frame_cache_obstack);
622}