* blockframe.c, frame.h (sigtramp_saved_pc): New routine to fetch
[deliverable/binutils-gdb.git] / gdb / blockframe.c
1 /* Get info from stack frames;
2 convert between frames, blocks, functions and pc values.
3 Copyright 1986, 1987, 1988, 1989, 1991 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
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
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 #include "defs.h"
22 #include "symtab.h"
23 #include "bfd.h"
24 #include "symfile.h"
25 #include "objfiles.h"
26 #include "frame.h"
27 #include "gdbcore.h"
28 #include "value.h" /* for read_register */
29 #include "target.h" /* for target_has_stack */
30 #include "inferior.h" /* for read_pc */
31
32 /* Is ADDR inside the startup file? Note that if your machine
33 has a way to detect the bottom of the stack, there is no need
34 to call this function from FRAME_CHAIN_VALID; the reason for
35 doing so is that some machines have no way of detecting bottom
36 of stack.
37
38 A PC of zero is always considered to be the bottom of the stack. */
39
40 int
41 inside_entry_file (addr)
42 CORE_ADDR addr;
43 {
44 if (addr == 0)
45 return 1;
46 if (symfile_objfile == 0)
47 return 0;
48 return (addr >= symfile_objfile -> ei.entry_file_lowpc &&
49 addr < symfile_objfile -> ei.entry_file_highpc);
50 }
51
52 /* Test a specified PC value to see if it is in the range of addresses
53 that correspond to the main() function. See comments above for why
54 we might want to do this.
55
56 Typically called from FRAME_CHAIN_VALID.
57
58 A PC of zero is always considered to be the bottom of the stack. */
59
60 int
61 inside_main_func (pc)
62 CORE_ADDR pc;
63 {
64 if (pc == 0)
65 return 1;
66 if (symfile_objfile == 0)
67 return 0;
68 return (symfile_objfile -> ei.main_func_lowpc <= pc &&
69 symfile_objfile -> ei.main_func_highpc > pc);
70 }
71
72 /* Test a specified PC value to see if it is in the range of addresses
73 that correspond to the process entry point function. See comments
74 in objfiles.h for why we might want to do this.
75
76 Typically called from FRAME_CHAIN_VALID.
77
78 A PC of zero is always considered to be the bottom of the stack. */
79
80 int
81 inside_entry_func (pc)
82 CORE_ADDR pc;
83 {
84 if (pc == 0)
85 return 1;
86 if (symfile_objfile == 0)
87 return 0;
88 return (symfile_objfile -> ei.entry_func_lowpc <= pc &&
89 symfile_objfile -> ei.entry_func_highpc > pc);
90 }
91
92 /* Address of innermost stack frame (contents of FP register) */
93
94 static FRAME current_frame;
95
96 /*
97 * Cache for frame addresses already read by gdb. Valid only while
98 * inferior is stopped. Control variables for the frame cache should
99 * be local to this module.
100 */
101 struct obstack frame_cache_obstack;
102
103 /* Return the innermost (currently executing) stack frame. */
104
105 FRAME
106 get_current_frame ()
107 {
108 /* We assume its address is kept in a general register;
109 param.h says which register. */
110
111 return current_frame;
112 }
113
114 void
115 set_current_frame (frame)
116 FRAME frame;
117 {
118 current_frame = frame;
119 }
120
121 FRAME
122 create_new_frame (addr, pc)
123 FRAME_ADDR addr;
124 CORE_ADDR pc;
125 {
126 struct frame_info *fci; /* Same type as FRAME */
127 char *name;
128
129 fci = (struct frame_info *)
130 obstack_alloc (&frame_cache_obstack,
131 sizeof (struct frame_info));
132
133 /* Arbitrary frame */
134 fci->next = (struct frame_info *) 0;
135 fci->prev = (struct frame_info *) 0;
136 fci->frame = addr;
137 fci->pc = pc;
138 find_pc_partial_function (pc, &name, (CORE_ADDR *)NULL,(CORE_ADDR *)NULL);
139 fci->signal_handler_caller = IN_SIGTRAMP (fci->pc, name);
140
141 #ifdef INIT_EXTRA_FRAME_INFO
142 INIT_EXTRA_FRAME_INFO (0, fci);
143 #endif
144
145 return fci;
146 }
147
148 /* Return the frame that called FRAME.
149 If FRAME is the original frame (it has no caller), return 0. */
150
151 FRAME
152 get_prev_frame (frame)
153 FRAME frame;
154 {
155 /* We're allowed to know that FRAME and "struct frame_info *" are
156 the same */
157 return get_prev_frame_info (frame);
158 }
159
160 /* Return the frame that FRAME calls (0 if FRAME is the innermost
161 frame). */
162
163 FRAME
164 get_next_frame (frame)
165 FRAME frame;
166 {
167 /* We're allowed to know that FRAME and "struct frame_info *" are
168 the same */
169 return frame->next;
170 }
171
172 /*
173 * Flush the entire frame cache.
174 */
175 void
176 flush_cached_frames ()
177 {
178 /* Since we can't really be sure what the first object allocated was */
179 obstack_free (&frame_cache_obstack, 0);
180 obstack_init (&frame_cache_obstack);
181
182 current_frame = (struct frame_info *) 0; /* Invalidate cache */
183 }
184
185 /* Flush the frame cache, and start a new one if necessary. */
186 void
187 reinit_frame_cache ()
188 {
189 FRAME fr = current_frame;
190 flush_cached_frames ();
191 if (fr)
192 set_current_frame ( create_new_frame (read_fp (), read_pc ()));
193 }
194
195 /* Return a structure containing various interesting information
196 about a specified stack frame. */
197 /* How do I justify including this function? Well, the FRAME
198 identifier format has gone through several changes recently, and
199 it's not completely inconceivable that it could happen again. If
200 it does, have this routine around will help */
201
202 struct frame_info *
203 get_frame_info (frame)
204 FRAME frame;
205 {
206 return frame;
207 }
208
209 /* If a machine allows frameless functions, it should define a macro
210 FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) in param.h. FI is the struct
211 frame_info for the frame, and FRAMELESS should be set to nonzero
212 if it represents a frameless function invocation. */
213
214 /* Return nonzero if the function for this frame lacks a prologue. Many
215 machines can define FRAMELESS_FUNCTION_INVOCATION to just call this
216 function. */
217
218 int
219 frameless_look_for_prologue (frame)
220 FRAME frame;
221 {
222 CORE_ADDR func_start, after_prologue;
223 func_start = (get_pc_function_start (frame->pc) +
224 FUNCTION_START_OFFSET);
225 if (func_start)
226 {
227 after_prologue = func_start;
228 #ifdef SKIP_PROLOGUE_FRAMELESS_P
229 /* This is faster, since only care whether there *is* a prologue,
230 not how long it is. */
231 SKIP_PROLOGUE_FRAMELESS_P (after_prologue);
232 #else
233 SKIP_PROLOGUE (after_prologue);
234 #endif
235 return after_prologue == func_start;
236 }
237 else
238 /* If we can't find the start of the function, we don't really
239 know whether the function is frameless, but we should be able
240 to get a reasonable (i.e. best we can do under the
241 circumstances) backtrace by saying that it isn't. */
242 return 0;
243 }
244
245 /* Default a few macros that people seldom redefine. */
246
247 #if !defined (INIT_FRAME_PC)
248 #define INIT_FRAME_PC(fromleaf, prev) \
249 prev->pc = (fromleaf ? SAVED_PC_AFTER_CALL (prev->next) : \
250 prev->next ? FRAME_SAVED_PC (prev->next) : read_pc ());
251 #endif
252
253 #ifndef FRAME_CHAIN_COMBINE
254 #define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
255 #endif
256
257 /* Return a structure containing various interesting information
258 about the frame that called NEXT_FRAME. Returns NULL
259 if there is no such frame. */
260
261 struct frame_info *
262 get_prev_frame_info (next_frame)
263 FRAME next_frame;
264 {
265 FRAME_ADDR address;
266 struct frame_info *prev;
267 int fromleaf = 0;
268 char *name;
269
270 /* If the requested entry is in the cache, return it.
271 Otherwise, figure out what the address should be for the entry
272 we're about to add to the cache. */
273
274 if (!next_frame)
275 {
276 if (!current_frame)
277 {
278 error ("You haven't set up a process's stack to examine.");
279 }
280
281 return current_frame;
282 }
283
284 /* If we have the prev one, return it */
285 if (next_frame->prev)
286 return next_frame->prev;
287
288 /* On some machines it is possible to call a function without
289 setting up a stack frame for it. On these machines, we
290 define this macro to take two args; a frameinfo pointer
291 identifying a frame and a variable to set or clear if it is
292 or isn't leafless. */
293 #ifdef FRAMELESS_FUNCTION_INVOCATION
294 /* Still don't want to worry about this except on the innermost
295 frame. This macro will set FROMLEAF if NEXT_FRAME is a
296 frameless function invocation. */
297 if (!(next_frame->next))
298 {
299 FRAMELESS_FUNCTION_INVOCATION (next_frame, fromleaf);
300 if (fromleaf)
301 address = next_frame->frame;
302 }
303 #endif
304
305 if (!fromleaf)
306 {
307 /* Two macros defined in tm.h specify the machine-dependent
308 actions to be performed here.
309 First, get the frame's chain-pointer.
310 If that is zero, the frame is the outermost frame or a leaf
311 called by the outermost frame. This means that if start
312 calls main without a frame, we'll return 0 (which is fine
313 anyway).
314
315 Nope; there's a problem. This also returns when the current
316 routine is a leaf of main. This is unacceptable. We move
317 this to after the ffi test; I'd rather have backtraces from
318 start go curfluy than have an abort called from main not show
319 main. */
320 address = FRAME_CHAIN (next_frame);
321 if (!FRAME_CHAIN_VALID (address, next_frame))
322 return 0;
323 address = FRAME_CHAIN_COMBINE (address, next_frame);
324 }
325 if (address == 0)
326 return 0;
327
328 prev = (struct frame_info *)
329 obstack_alloc (&frame_cache_obstack,
330 sizeof (struct frame_info));
331
332 if (next_frame)
333 next_frame->prev = prev;
334 prev->next = next_frame;
335 prev->prev = (struct frame_info *) 0;
336 prev->frame = address;
337 prev->signal_handler_caller = 0;
338
339 /* This change should not be needed, FIXME! We should
340 determine whether any targets *need* INIT_FRAME_PC to happen
341 after INIT_EXTRA_FRAME_INFO and come up with a simple way to
342 express what goes on here.
343
344 INIT_EXTRA_FRAME_INFO is called from two places: create_new_frame
345 (where the PC is already set up) and here (where it isn't).
346 INIT_FRAME_PC is only called from here, always after
347 INIT_EXTRA_FRAME_INFO.
348
349 The catch is the MIPS, where INIT_EXTRA_FRAME_INFO requires the PC
350 value (which hasn't been set yet). Some other machines appear to
351 require INIT_EXTRA_FRAME_INFO before they can do INIT_FRAME_PC. Phoo.
352
353 We shouldn't need INIT_FRAME_PC_FIRST to add more complication to
354 an already overcomplicated part of GDB. gnu@cygnus.com, 15Sep92.
355
356 To answer the question, yes the sparc needs INIT_FRAME_PC after
357 INIT_EXTRA_FRAME_INFO. Suggested scheme:
358
359 SETUP_INNERMOST_FRAME()
360 Default version is just create_new_frame (read_fp ()),
361 read_pc ()). Machines with extra frame info would do that (or the
362 local equivalent) and then set the extra fields.
363 SETUP_ARBITRARY_FRAME(argc, argv)
364 Only change here is that create_new_frame would no longer init extra
365 frame info; SETUP_ARBITRARY_FRAME would have to do that.
366 INIT_PREV_FRAME(fromleaf, prev)
367 Replace INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC.
368 std_frame_pc(fromleaf, prev)
369 This is the default setting for INIT_PREV_FRAME. It just does what
370 the default INIT_FRAME_PC does. Some machines will call it from
371 INIT_PREV_FRAME (either at the beginning, the end, or in the middle).
372 Some machines won't use it.
373 kingdon@cygnus.com, 13Apr93. */
374
375 #ifdef INIT_FRAME_PC_FIRST
376 INIT_FRAME_PC_FIRST (fromleaf, prev);
377 #endif
378
379 #ifdef INIT_EXTRA_FRAME_INFO
380 INIT_EXTRA_FRAME_INFO(fromleaf, prev);
381 #endif
382
383 /* This entry is in the frame queue now, which is good since
384 FRAME_SAVED_PC may use that queue to figure out it's value
385 (see tm-sparc.h). We want the pc saved in the inferior frame. */
386 INIT_FRAME_PC(fromleaf, prev);
387
388 find_pc_partial_function (prev->pc, &name,
389 (CORE_ADDR *)NULL,(CORE_ADDR *)NULL);
390 if (IN_SIGTRAMP (prev->pc, name))
391 prev->signal_handler_caller = 1;
392
393 return prev;
394 }
395
396 CORE_ADDR
397 get_frame_pc (frame)
398 FRAME frame;
399 {
400 struct frame_info *fi;
401 fi = get_frame_info (frame);
402 return fi->pc;
403 }
404
405 #if defined (FRAME_FIND_SAVED_REGS)
406 /* Find the addresses in which registers are saved in FRAME. */
407
408 void
409 get_frame_saved_regs (frame_info_addr, saved_regs_addr)
410 struct frame_info *frame_info_addr;
411 struct frame_saved_regs *saved_regs_addr;
412 {
413 FRAME_FIND_SAVED_REGS (frame_info_addr, *saved_regs_addr);
414 }
415 #endif
416
417 /* Return the innermost lexical block in execution
418 in a specified stack frame. The frame address is assumed valid. */
419
420 struct block *
421 get_frame_block (frame)
422 FRAME frame;
423 {
424 struct frame_info *fi;
425 CORE_ADDR pc;
426
427 fi = get_frame_info (frame);
428
429 pc = fi->pc;
430 if (fi->next != 0)
431 /* We are not in the innermost frame. We need to subtract one to
432 get the correct block, in case the call instruction was the
433 last instruction of the block. If there are any machines on
434 which the saved pc does not point to after the call insn, we
435 probably want to make fi->pc point after the call insn anyway. */
436 --pc;
437 return block_for_pc (pc);
438 }
439
440 struct block *
441 get_current_block ()
442 {
443 return block_for_pc (read_pc ());
444 }
445
446 CORE_ADDR
447 get_pc_function_start (pc)
448 CORE_ADDR pc;
449 {
450 register struct block *bl;
451 register struct symbol *symbol;
452 register struct minimal_symbol *msymbol;
453 CORE_ADDR fstart;
454
455 if ((bl = block_for_pc (pc)) != NULL &&
456 (symbol = block_function (bl)) != NULL)
457 {
458 bl = SYMBOL_BLOCK_VALUE (symbol);
459 fstart = BLOCK_START (bl);
460 }
461 else if ((msymbol = lookup_minimal_symbol_by_pc (pc)) != NULL)
462 {
463 fstart = SYMBOL_VALUE_ADDRESS (msymbol);
464 }
465 else
466 {
467 fstart = 0;
468 }
469 return (fstart);
470 }
471
472 /* Return the symbol for the function executing in frame FRAME. */
473
474 struct symbol *
475 get_frame_function (frame)
476 FRAME frame;
477 {
478 register struct block *bl = get_frame_block (frame);
479 if (bl == 0)
480 return 0;
481 return block_function (bl);
482 }
483 \f
484 /* Return the blockvector immediately containing the innermost lexical block
485 containing the specified pc value, or 0 if there is none.
486 PINDEX is a pointer to the index value of the block. If PINDEX
487 is NULL, we don't pass this information back to the caller. */
488
489 struct blockvector *
490 blockvector_for_pc (pc, pindex)
491 register CORE_ADDR pc;
492 int *pindex;
493 {
494 register struct block *b;
495 register int bot, top, half;
496 register struct symtab *s;
497 struct blockvector *bl;
498
499 /* First search all symtabs for one whose file contains our pc */
500 s = find_pc_symtab (pc);
501 if (s == 0)
502 return 0;
503
504 bl = BLOCKVECTOR (s);
505 b = BLOCKVECTOR_BLOCK (bl, 0);
506
507 /* Then search that symtab for the smallest block that wins. */
508 /* Use binary search to find the last block that starts before PC. */
509
510 bot = 0;
511 top = BLOCKVECTOR_NBLOCKS (bl);
512
513 while (top - bot > 1)
514 {
515 half = (top - bot + 1) >> 1;
516 b = BLOCKVECTOR_BLOCK (bl, bot + half);
517 if (BLOCK_START (b) <= pc)
518 bot += half;
519 else
520 top = bot + half;
521 }
522
523 /* Now search backward for a block that ends after PC. */
524
525 while (bot >= 0)
526 {
527 b = BLOCKVECTOR_BLOCK (bl, bot);
528 if (BLOCK_END (b) > pc)
529 {
530 if (pindex)
531 *pindex = bot;
532 return bl;
533 }
534 bot--;
535 }
536
537 return 0;
538 }
539
540 /* Return the innermost lexical block containing the specified pc value,
541 or 0 if there is none. */
542
543 struct block *
544 block_for_pc (pc)
545 register CORE_ADDR pc;
546 {
547 register struct blockvector *bl;
548 int index;
549
550 bl = blockvector_for_pc (pc, &index);
551 if (bl)
552 return BLOCKVECTOR_BLOCK (bl, index);
553 return 0;
554 }
555
556 /* Return the function containing pc value PC.
557 Returns 0 if function is not known. */
558
559 struct symbol *
560 find_pc_function (pc)
561 CORE_ADDR pc;
562 {
563 register struct block *b = block_for_pc (pc);
564 if (b == 0)
565 return 0;
566 return block_function (b);
567 }
568
569 /* These variables are used to cache the most recent result
570 * of find_pc_partial_function. */
571
572 static CORE_ADDR cache_pc_function_low = 0;
573 static CORE_ADDR cache_pc_function_high = 0;
574 static char *cache_pc_function_name = 0;
575
576 /* Clear cache, e.g. when symbol table is discarded. */
577
578 void
579 clear_pc_function_cache()
580 {
581 cache_pc_function_low = 0;
582 cache_pc_function_high = 0;
583 cache_pc_function_name = (char *)0;
584 }
585
586 /* Finds the "function" (text symbol) that is smaller than PC but
587 greatest of all of the potential text symbols. Sets *NAME and/or
588 *ADDRESS conditionally if that pointer is non-null. If ENDADDR is
589 non-null, then set *ENDADDR to be the end of the function
590 (exclusive), but passing ENDADDR as non-null means that the
591 function might cause symbols to be read. This function either
592 succeeds or fails (not halfway succeeds). If it succeeds, it sets
593 *NAME, *ADDRESS, and *ENDADDR to real information and returns 1.
594 If it fails, it sets *NAME, *ADDRESS, and *ENDADDR to zero
595 and returns 0. */
596
597 int
598 find_pc_partial_function (pc, name, address, endaddr)
599 CORE_ADDR pc;
600 char **name;
601 CORE_ADDR *address;
602 CORE_ADDR *endaddr;
603 {
604 struct partial_symtab *pst;
605 struct symbol *f;
606 struct minimal_symbol *msymbol;
607 struct partial_symbol *psb;
608
609 if (pc >= cache_pc_function_low && pc < cache_pc_function_high)
610 goto return_cached_value;
611
612 /* If sigtramp is in the u area, it counts as a function (especially
613 important for step_1). */
614 #if defined SIGTRAMP_START
615 if (IN_SIGTRAMP (pc, (char *)NULL))
616 {
617 cache_pc_function_low = SIGTRAMP_START;
618 cache_pc_function_high = SIGTRAMP_END;
619 cache_pc_function_name = "<sigtramp>";
620
621 goto return_cached_value;
622 }
623 #endif
624
625 msymbol = lookup_minimal_symbol_by_pc (pc);
626 pst = find_pc_psymtab (pc);
627 if (pst)
628 {
629 /* Need to read the symbols to get a good value for the end address. */
630 if (endaddr != NULL && !pst->readin)
631 PSYMTAB_TO_SYMTAB (pst);
632
633 if (pst->readin)
634 {
635 /* Checking whether the msymbol has a larger value is for the
636 "pathological" case mentioned in print_frame_info. */
637 f = find_pc_function (pc);
638 if (f != NULL
639 && (msymbol == NULL
640 || (BLOCK_START (SYMBOL_BLOCK_VALUE (f))
641 >= SYMBOL_VALUE_ADDRESS (msymbol))))
642 {
643 cache_pc_function_low = BLOCK_START (SYMBOL_BLOCK_VALUE (f));
644 cache_pc_function_high = BLOCK_END (SYMBOL_BLOCK_VALUE (f));
645 cache_pc_function_name = SYMBOL_NAME (f);
646 goto return_cached_value;
647 }
648 }
649
650 /* Now that static symbols go in the minimal symbol table, perhaps
651 we could just ignore the partial symbols. But at least for now
652 we use the partial or minimal symbol, whichever is larger. */
653 psb = find_pc_psymbol (pst, pc);
654
655 if (psb
656 && (msymbol == NULL ||
657 (SYMBOL_VALUE_ADDRESS (psb) >= SYMBOL_VALUE_ADDRESS (msymbol))))
658 {
659 /* This case isn't being cached currently. */
660 if (address)
661 *address = SYMBOL_VALUE_ADDRESS (psb);
662 if (name)
663 *name = SYMBOL_NAME (psb);
664 /* endaddr non-NULL can't happen here. */
665 return 1;
666 }
667 }
668
669 /* Must be in the minimal symbol table. */
670 if (msymbol == NULL)
671 {
672 /* No available symbol. */
673 if (name != NULL)
674 *name = 0;
675 if (address != NULL)
676 *address = 0;
677 if (endaddr != NULL)
678 *endaddr = 0;
679 return 0;
680 }
681
682 /* I believe the purpose of this check is to make sure that anything
683 beyond the end of the text segment does not appear as part of the
684 last function of the text segment. It assumes that there is something
685 other than a mst_text symbol after the text segment. It is broken in
686 various cases, so anything relying on this behavior (there might be
687 some places) should be using find_pc_section or some such instead. */
688 if (msymbol -> type == mst_text)
689 cache_pc_function_low = SYMBOL_VALUE_ADDRESS (msymbol);
690 else
691 /* It is a transfer table for Sun shared libraries. */
692 cache_pc_function_low = pc - FUNCTION_START_OFFSET;
693 cache_pc_function_name = SYMBOL_NAME (msymbol);
694
695 if (SYMBOL_NAME (msymbol + 1) != NULL)
696 /* This might be part of a different segment, which might be a bad
697 idea. Perhaps we should be using the smaller of this address or the
698 endaddr from find_pc_section. */
699 cache_pc_function_high = SYMBOL_VALUE_ADDRESS (msymbol + 1);
700 else
701 {
702 /* We got the start address from the last msymbol in the objfile.
703 So the end address is the end of the section. */
704 struct obj_section *sec;
705
706 sec = find_pc_section (pc);
707 if (sec == NULL)
708 {
709 /* Don't know if this can happen but if it does, then just say
710 that the function is 1 byte long. */
711 cache_pc_function_high = cache_pc_function_low + 1;
712 }
713 else
714 cache_pc_function_high = sec->endaddr;
715 }
716
717 return_cached_value:
718 if (address)
719 *address = cache_pc_function_low;
720 if (name)
721 *name = cache_pc_function_name;
722 if (endaddr)
723 *endaddr = cache_pc_function_high;
724 return 1;
725 }
726
727 /* Return the innermost stack frame executing inside of the specified block,
728 or zero if there is no such frame. */
729
730 #if 0 /* Currently unused */
731
732 FRAME
733 block_innermost_frame (block)
734 struct block *block;
735 {
736 struct frame_info *fi;
737 register FRAME frame;
738 register CORE_ADDR start = BLOCK_START (block);
739 register CORE_ADDR end = BLOCK_END (block);
740
741 frame = 0;
742 while (1)
743 {
744 frame = get_prev_frame (frame);
745 if (frame == 0)
746 return 0;
747 fi = get_frame_info (frame);
748 if (fi->pc >= start && fi->pc < end)
749 return frame;
750 }
751 }
752
753 #endif /* 0 */
754
755 #ifdef SIGCONTEXT_PC_OFFSET
756 /* Get saved user PC for sigtramp from sigcontext for BSD style sigtramp. */
757
758 CORE_ADDR
759 sigtramp_saved_pc (frame)
760 FRAME frame;
761 {
762 CORE_ADDR sigcontext_addr;
763 char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
764 int ptrbytes = TARGET_PTR_BIT / TARGET_CHAR_BIT;
765 int sigcontext_offs = (2 * TARGET_INT_BIT) / TARGET_CHAR_BIT;
766
767 /* Get sigcontext address, it is the third parameter on the stack. */
768 if (frame->next)
769 sigcontext_addr = read_memory_integer (FRAME_ARGS_ADDRESS (frame->next)
770 + FRAME_ARGS_SKIP + sigcontext_offs,
771 ptrbytes);
772 else
773 sigcontext_addr = read_memory_integer (read_register (SP_REGNUM)
774 + sigcontext_offs,
775 ptrbytes);
776
777 /* Don't cause a memory_error when accessing sigcontext in case the stack
778 layout has changed or the stack is corrupt. */
779 target_read_memory (sigcontext_addr + SIGCONTEXT_PC_OFFSET, buf, ptrbytes);
780 return extract_unsigned_integer (buf, ptrbytes);
781 }
782 #endif /* SIGCONTEXT_PC_OFFSET */
783
784 void
785 _initialize_blockframe ()
786 {
787 obstack_init (&frame_cache_obstack);
788 }
This page took 0.044995 seconds and 5 git commands to generate.