functions and pc values.
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
- 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software
Foundation, Inc.
This file is part of GDB.
#include "regcache.h"
#include "gdb_assert.h"
#include "dummy-frame.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "block.h"
/* Prototypes for exported functions. */
void _initialize_blockframe (void);
-/* A default FRAME_CHAIN_VALID, in the form that is suitable for most
- targets. If FRAME_CHAIN_VALID returns zero it means that the given
- frame is the outermost one and has no caller. */
-
-int
-file_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
-{
- return ((chain) != 0
- && !inside_entry_file (frame_pc_unwind (thisframe)));
-}
-
-/* Use the alternate method of avoiding running up off the end of the
- frame chain or following frames back into the startup code. See
- the comments in objfiles.h. */
-
-int
-func_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
-{
- return ((chain) != 0
- && !inside_main_func (get_frame_pc (thisframe))
- && !inside_entry_func (get_frame_pc (thisframe)));
-}
-
-/* A very simple method of determining a valid frame */
-
-int
-nonnull_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
-{
- return ((chain) != 0);
-}
-
-/* Is ADDR inside the startup file? Note that if your machine
- has a way to detect the bottom of the stack, there is no need
- to call this function from FRAME_CHAIN_VALID; the reason for
- doing so is that some machines have no way of detecting bottom
- of stack.
+/* Is ADDR inside the startup file? Note that if your machine has a
+ way to detect the bottom of the stack, there is no need to call
+ this function from DEPRECATED_FRAME_CHAIN_VALID; the reason for
+ doing so is that some machines have no way of detecting bottom of
+ stack.
A PC of zero is always considered to be the bottom of the stack. */
that correspond to the main() function. See comments above for why
we might want to do this.
- Typically called from FRAME_CHAIN_VALID.
+ Typically called from DEPRECATED_FRAME_CHAIN_VALID.
A PC of zero is always considered to be the bottom of the stack. */
if (symfile_objfile == 0)
return 0;
- /* If the addr range is not set up at symbol reading time, set it up now.
- This is for FRAME_CHAIN_VALID_ALTERNATE. I do this for coff, because
- it is unable to set it up and symbol reading time. */
+ /* If the addr range is not set up at symbol reading time, set it up
+ now. This is for DEPRECATED_FRAME_CHAIN_VALID_ALTERNATE. I do
+ this for coff, because it is unable to set it up and symbol
+ reading time. */
if (symfile_objfile->ei.main_func_lowpc == INVALID_ENTRY_LOWPC &&
symfile_objfile->ei.main_func_highpc == INVALID_ENTRY_HIGHPC)
{
struct symbol *mainsym;
- mainsym = lookup_symbol (main_name (), NULL, VAR_NAMESPACE, NULL, NULL);
+ mainsym = lookup_symbol (main_name (), NULL, VAR_DOMAIN, NULL, NULL);
if (mainsym && SYMBOL_CLASS (mainsym) == LOC_BLOCK)
{
symfile_objfile->ei.main_func_lowpc =
that correspond to the process entry point function. See comments
in objfiles.h for why we might want to do this.
- Typically called from FRAME_CHAIN_VALID.
+ Typically called from DEPRECATED_FRAME_CHAIN_VALID.
A PC of zero is always considered to be the bottom of the stack. */
int
frameless_look_for_prologue (struct frame_info *frame)
{
- CORE_ADDR func_start, after_prologue;
+ CORE_ADDR func_start;
- func_start = get_pc_function_start (get_frame_pc (frame));
+ func_start = get_frame_func (frame);
if (func_start)
{
func_start += FUNCTION_START_OFFSET;
CORE_ADDR
get_pc_function_start (CORE_ADDR pc)
{
- register struct block *bl;
- register struct symbol *symbol;
- register struct minimal_symbol *msymbol;
- CORE_ADDR fstart;
+ struct block *bl;
+ struct minimal_symbol *msymbol;
- if ((bl = block_for_pc (pc)) != NULL &&
- (symbol = block_function (bl)) != NULL)
- {
- bl = SYMBOL_BLOCK_VALUE (symbol);
- fstart = BLOCK_START (bl);
- }
- else if ((msymbol = lookup_minimal_symbol_by_pc (pc)) != NULL)
+ bl = block_for_pc (pc);
+ if (bl)
{
- fstart = SYMBOL_VALUE_ADDRESS (msymbol);
- if (!find_pc_section (fstart))
- return 0;
+ struct symbol *symbol = block_function (bl);
+
+ if (symbol)
+ {
+ bl = SYMBOL_BLOCK_VALUE (symbol);
+ return BLOCK_START (bl);
+ }
}
- else
+
+ msymbol = lookup_minimal_symbol_by_pc (pc);
+ if (msymbol)
{
- fstart = 0;
+ CORE_ADDR fstart = SYMBOL_VALUE_ADDRESS (msymbol);
+
+ if (find_pc_section (fstart))
+ return fstart;
}
- return (fstart);
+
+ return 0;
}
/* Return the symbol for the function executing in frame FRAME. */
}
\f
-/* Return the blockvector immediately containing the innermost lexical block
- containing the specified pc value and section, or 0 if there is none.
- PINDEX is a pointer to the index value of the block. If PINDEX
- is NULL, we don't pass this information back to the caller. */
-
-struct blockvector *
-blockvector_for_pc_sect (register CORE_ADDR pc, struct sec *section,
- int *pindex, struct symtab *symtab)
-{
- register struct block *b;
- register int bot, top, half;
- struct blockvector *bl;
-
- if (symtab == 0) /* if no symtab specified by caller */
- {
- /* First search all symtabs for one whose file contains our pc */
- if ((symtab = find_pc_sect_symtab (pc, section)) == 0)
- return 0;
- }
-
- bl = BLOCKVECTOR (symtab);
- b = BLOCKVECTOR_BLOCK (bl, 0);
-
- /* Then search that symtab for the smallest block that wins. */
- /* Use binary search to find the last block that starts before PC. */
-
- bot = 0;
- top = BLOCKVECTOR_NBLOCKS (bl);
-
- while (top - bot > 1)
- {
- half = (top - bot + 1) >> 1;
- b = BLOCKVECTOR_BLOCK (bl, bot + half);
- if (BLOCK_START (b) <= pc)
- bot += half;
- else
- top = bot + half;
- }
-
- /* Now search backward for a block that ends after PC. */
-
- while (bot >= 0)
- {
- b = BLOCKVECTOR_BLOCK (bl, bot);
- if (BLOCK_END (b) > pc)
- {
- if (pindex)
- *pindex = bot;
- return bl;
- }
- bot--;
- }
- return 0;
-}
-
-/* Return the blockvector immediately containing the innermost lexical block
- containing the specified pc value, or 0 if there is none.
- Backward compatibility, no section. */
-
-struct blockvector *
-blockvector_for_pc (register CORE_ADDR pc, int *pindex)
-{
- return blockvector_for_pc_sect (pc, find_pc_mapped_section (pc),
- pindex, NULL);
-}
-
-/* Return the innermost lexical block containing the specified pc value
- in the specified section, or 0 if there is none. */
-
-struct block *
-block_for_pc_sect (register CORE_ADDR pc, struct sec *section)
-{
- register struct blockvector *bl;
- int index;
-
- bl = blockvector_for_pc_sect (pc, section, &index, NULL);
- if (bl)
- return BLOCKVECTOR_BLOCK (bl, index);
- return 0;
-}
-
-/* Return the innermost lexical block containing the specified pc value,
- or 0 if there is none. Backward compatibility, no section. */
-
-struct block *
-block_for_pc (register CORE_ADDR pc)
-{
- return block_for_pc_sect (pc, find_pc_mapped_section (pc));
-}
-
/* Return the function containing pc value PC in section SECTION.
Returns 0 if function is not known. */
{
cache_pc_function_low = BLOCK_START (SYMBOL_BLOCK_VALUE (f));
cache_pc_function_high = BLOCK_END (SYMBOL_BLOCK_VALUE (f));
- cache_pc_function_name = SYMBOL_NAME (f);
+ cache_pc_function_name = DEPRECATED_SYMBOL_NAME (f);
cache_pc_function_section = section;
goto return_cached_value;
}
if (address)
*address = SYMBOL_VALUE_ADDRESS (psb);
if (name)
- *name = SYMBOL_NAME (psb);
+ *name = DEPRECATED_SYMBOL_NAME (psb);
/* endaddr non-NULL can't happen here. */
return 1;
}
}
cache_pc_function_low = SYMBOL_VALUE_ADDRESS (msymbol);
- cache_pc_function_name = SYMBOL_NAME (msymbol);
+ cache_pc_function_name = DEPRECATED_SYMBOL_NAME (msymbol);
cache_pc_function_section = section;
/* Use the lesser of the next minimal symbol in the same section, or
other sections, to find the next symbol in this section with
a different address. */
- for (i = 1; SYMBOL_NAME (msymbol + i) != NULL; i++)
+ for (i = 1; DEPRECATED_SYMBOL_NAME (msymbol + i) != NULL; i++)
{
if (SYMBOL_VALUE_ADDRESS (msymbol + i) != SYMBOL_VALUE_ADDRESS (msymbol)
&& SYMBOL_BFD_SECTION (msymbol + i) == SYMBOL_BFD_SECTION (msymbol))
break;
}
- if (SYMBOL_NAME (msymbol + i) != NULL
+ if (DEPRECATED_SYMBOL_NAME (msymbol + i) != NULL
&& SYMBOL_VALUE_ADDRESS (msymbol + i) < osect->endaddr)
cache_pc_function_high = SYMBOL_VALUE_ADDRESS (msymbol + i);
else
below is for infrun.c, which may give the macro a pc without that
subtracted out. */
-extern CORE_ADDR text_end;
-
-int
-deprecated_pc_in_call_dummy_before_text_end (CORE_ADDR pc, CORE_ADDR sp,
- CORE_ADDR frame_address)
-{
- return ((pc) >= text_end - CALL_DUMMY_LENGTH
- && (pc) <= text_end + DECR_PC_AFTER_BREAK);
-}
-
-int
-deprecated_pc_in_call_dummy_after_text_end (CORE_ADDR pc, CORE_ADDR sp,
- CORE_ADDR frame_address)
-{
- return ((pc) >= text_end
- && (pc) <= text_end + CALL_DUMMY_LENGTH + DECR_PC_AFTER_BREAK);
-}
-
/* Is the PC in a call dummy? SP and FRAME_ADDRESS are the bottom and
top of the stack frame which we are checking, where "bottom" and
"top" refer to some section of memory which contains the code for
the call dummy. Calls to this macro assume that the contents of
- SP_REGNUM and FP_REGNUM (or the saved values thereof), respectively,
- are the things to pass.
+ SP_REGNUM and DEPRECATED_FP_REGNUM (or the saved values thereof),
+ respectively, are the things to pass.
- This won't work on the 29k, where SP_REGNUM and FP_REGNUM don't
- have that meaning, but the 29k doesn't use ON_STACK. This could be
- fixed by generalizing this scheme, perhaps by passing in a frame
- and adding a few fields, at least on machines which need them for
- DEPRECATED_PC_IN_CALL_DUMMY.
+ This won't work on the 29k, where SP_REGNUM and
+ DEPRECATED_FP_REGNUM don't have that meaning, but the 29k doesn't
+ use ON_STACK. This could be fixed by generalizing this scheme,
+ perhaps by passing in a frame and adding a few fields, at least on
+ machines which need them for DEPRECATED_PC_IN_CALL_DUMMY.
Something simpler, like checking for the stack segment, doesn't work,
since various programs (threads implementations, gcc nested function
&& (pc) <= (CALL_DUMMY_ADDRESS () + DECR_PC_AFTER_BREAK));
}
-
-/* Function: frame_chain_valid
- Returns true for a user frame or a call_function_by_hand dummy frame,
- and false for the CRT0 start-up frame. Purpose is to terminate backtrace */
+/* Returns true for a user frame or a call_function_by_hand dummy
+ frame, and false for the CRT0 start-up frame. Purpose is to
+ terminate backtrace. */
int
-generic_file_frame_chain_valid (CORE_ADDR fp, struct frame_info *fi)
-{
- if (DEPRECATED_PC_IN_CALL_DUMMY (frame_pc_unwind (fi), fp, fp))
- return 1; /* don't prune CALL_DUMMY frames */
- else /* fall back to default algorithm (see frame.h) */
- return (fp != 0
- && (INNER_THAN (get_frame_base (fi), fp)
- || get_frame_base (fi) == fp)
- && !inside_entry_file (frame_pc_unwind (fi)));
-}
-
-int
-generic_func_frame_chain_valid (CORE_ADDR fp, struct frame_info *fi)
+legacy_frame_chain_valid (CORE_ADDR fp, struct frame_info *fi)
{
+ /* Don't prune CALL_DUMMY frames. */
if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES
&& DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), 0, 0))
- return 1; /* don't prune CALL_DUMMY frames */
- else /* fall back to default algorithm (see frame.h) */
- return (fp != 0
- && (INNER_THAN (get_frame_base (fi), fp)
- || get_frame_base (fi) == fp)
- && !inside_main_func (get_frame_pc (fi))
- && !inside_entry_func (get_frame_pc (fi)));
-}
+ return 1;
+ /* If the new frame pointer is zero, then it isn't valid. */
+ if (fp == 0)
+ return 0;
+
+ /* If the new frame would be inside (younger than) the previous frame,
+ then it isn't valid. */
+ if (INNER_THAN (fp, get_frame_base (fi)))
+ return 0;
+
+ /* If the architecture has a custom DEPRECATED_FRAME_CHAIN_VALID,
+ call it now. */
+ if (DEPRECATED_FRAME_CHAIN_VALID_P ())
+ return DEPRECATED_FRAME_CHAIN_VALID (fp, fi);
+
+ /* If we're already inside the entry function for the main objfile, then it
+ isn't valid. */
+ if (inside_entry_func (get_frame_pc (fi)))
+ return 0;
+
+ /* If we're inside the entry file, it isn't valid. */
+ /* NOTE/drow 2002-12-25: should there be a way to disable this check? It
+ assumes a single small entry file, and the way some debug readers (e.g.
+ dbxread) figure out which object is the entry file is somewhat hokey. */
+ if (inside_entry_file (frame_pc_unwind (fi)))
+ return 0;
+
+ return 1;
+}