functions and pc values.
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
- 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software
- Foundation, Inc.
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
This file is part of GDB.
#include "defs.h"
#include "symtab.h"
#include "bfd.h"
-#include "symfile.h"
#include "objfiles.h"
#include "frame.h"
#include "gdbcore.h"
void _initialize_blockframe (void);
-/* 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.
-
- A PC of zero is always considered to be the bottom of the stack. */
-
-int
-inside_entry_file (CORE_ADDR addr)
-{
- if (addr == 0)
- return 1;
- if (symfile_objfile == 0)
- return 0;
- if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
- {
- /* Do not stop backtracing if the pc is in the call dummy
- at the entry point. */
- /* FIXME: Won't always work with zeros for the last two arguments */
- if (DEPRECATED_PC_IN_CALL_DUMMY (addr, 0, 0))
- return 0;
- }
- return (addr >= symfile_objfile->ei.entry_file_lowpc &&
- addr < symfile_objfile->ei.entry_file_highpc);
-}
-
-/* Test a specified PC value to see if it is in the range of addresses
- that correspond to the main() function. See comments above for why
- we might want to do this.
-
- Typically called from FRAME_CHAIN_VALID.
-
- A PC of zero is always considered to be the bottom of the stack. */
-
-int
-inside_main_func (CORE_ADDR pc)
-{
- if (pc == 0)
- return 1;
- 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 (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);
- if (mainsym && SYMBOL_CLASS (mainsym) == LOC_BLOCK)
- {
- symfile_objfile->ei.main_func_lowpc =
- BLOCK_START (SYMBOL_BLOCK_VALUE (mainsym));
- symfile_objfile->ei.main_func_highpc =
- BLOCK_END (SYMBOL_BLOCK_VALUE (mainsym));
- }
- }
- return (symfile_objfile->ei.main_func_lowpc <= pc &&
- symfile_objfile->ei.main_func_highpc > pc);
-}
-
-/* Test a specified PC value to see if it is in the range of addresses
- 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.
-
- A PC of zero is always considered to be the bottom of the stack. */
-
-int
-inside_entry_func (CORE_ADDR pc)
-{
- if (pc == 0)
- return 1;
- if (symfile_objfile == 0)
- return 0;
- if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
- {
- /* Do not stop backtracing if the pc is in the call dummy
- at the entry point. */
- /* FIXME: Won't always work with zeros for the last two arguments */
- if (DEPRECATED_PC_IN_CALL_DUMMY (pc, 0, 0))
- return 0;
- }
- return (symfile_objfile->ei.entry_func_lowpc <= pc &&
- symfile_objfile->ei.entry_func_highpc > pc);
-}
-
-/* Return nonzero if the function for this frame lacks a prologue. Many
- machines can define FRAMELESS_FUNCTION_INVOCATION to just call this
- function. */
-
-int
-frameless_look_for_prologue (struct frame_info *frame)
-{
- CORE_ADDR func_start, after_prologue;
-
- func_start = get_pc_function_start (get_frame_pc (frame));
- if (func_start)
- {
- func_start += FUNCTION_START_OFFSET;
- /* This is faster, since only care whether there *is* a
- prologue, not how long it is. */
- return PROLOGUE_FRAMELESS_P (func_start);
- }
- else if (get_frame_pc (frame) == 0)
- /* A frame with a zero PC is usually created by dereferencing a
- NULL function pointer, normally causing an immediate core dump
- of the inferior. Mark function as frameless, as the inferior
- has no chance of setting up a stack frame. */
- return 1;
- else
- /* If we can't find the start of the function, we don't really
- know whether the function is frameless, but we should be able
- to get a reasonable (i.e. best we can do under the
- circumstances) backtrace by saying that it isn't. */
- return 0;
-}
-
-/* return the address of the PC for the given FRAME, ie the current PC value
- if FRAME is the innermost frame, or the address adjusted to point to the
- call instruction if not. */
-
-CORE_ADDR
-frame_address_in_block (struct frame_info *frame)
-{
- CORE_ADDR pc = get_frame_pc (frame);
-
- /* If we are not in the innermost frame, and we are not interrupted
- by a signal, frame->pc points to the instruction following the
- call. As a consequence, we need to get the address of the previous
- instruction. Unfortunately, this is not straightforward to do, so
- we just use the address minus one, which is a good enough
- approximation. */
- /* FIXME: cagney/2002-11-10: Should this instead test for
- NORMAL_FRAME? A dummy frame (in fact all the abnormal frames)
- save the PC value in the block. */
- if (get_next_frame (frame) != 0
- && get_frame_type (get_next_frame (frame)) != SIGTRAMP_FRAME)
- --pc;
-
- return pc;
-}
-
/* Return the innermost lexical block in execution
in a specified stack frame. The frame address is assumed valid.
struct block *
get_frame_block (struct frame_info *frame, CORE_ADDR *addr_in_block)
{
- const CORE_ADDR pc = frame_address_in_block (frame);
+ const CORE_ADDR pc = get_frame_address_in_block (frame);
if (addr_in_block)
*addr_in_block = pc;
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. */
struct symbol *
get_frame_function (struct frame_info *frame)
{
- register struct block *bl = get_frame_block (frame, 0);
+ struct block *bl = get_frame_block (frame, 0);
if (bl == 0)
return 0;
return block_function (bl);
Returns 0 if function is not known. */
struct symbol *
-find_pc_sect_function (CORE_ADDR pc, struct sec *section)
+find_pc_sect_function (CORE_ADDR pc, struct bfd_section *section)
{
- register struct block *b = block_for_pc_sect (pc, section);
+ struct block *b = block_for_pc_sect (pc, section);
if (b == 0)
return 0;
return block_function (b);
static CORE_ADDR cache_pc_function_low = 0;
static CORE_ADDR cache_pc_function_high = 0;
static char *cache_pc_function_name = 0;
-static struct sec *cache_pc_function_section = NULL;
+static struct bfd_section *cache_pc_function_section = NULL;
/* Clear cache, e.g. when symbol table is discarded. */
If it fails, it sets *NAME, *ADDRESS, and *ENDADDR to zero and
returns 0. */
+/* Backward compatibility, no section argument. */
+
int
-find_pc_sect_partial_function (CORE_ADDR pc, asection *section, char **name,
- CORE_ADDR *address, CORE_ADDR *endaddr)
+find_pc_partial_function (CORE_ADDR pc, char **name, CORE_ADDR *address,
+ CORE_ADDR *endaddr)
{
+ struct bfd_section *section;
struct partial_symtab *pst;
struct symbol *f;
struct minimal_symbol *msymbol;
int i;
CORE_ADDR mapped_pc;
+ /* To ensure that the symbol returned belongs to the correct setion
+ (and that the last [random] symbol from the previous section
+ isn't returned) try to find the section containing PC. First try
+ the overlay code (which by default returns NULL); and second try
+ the normal section code (which almost always succeeds). */
+ section = find_pc_overlay (pc);
+ if (section == NULL)
+ {
+ struct obj_section *obj_section = find_pc_section (pc);
+ if (obj_section == NULL)
+ section = NULL;
+ else
+ section = obj_section->the_bfd_section;
+ }
+
mapped_pc = overlay_mapped_address (pc, section);
if (mapped_pc >= cache_pc_function_low
&& section == cache_pc_function_section)
goto return_cached_value;
- /* If sigtramp is in the u area, it counts as a function (especially
- important for step_1). */
- if (SIGTRAMP_START_P () && PC_IN_SIGTRAMP (mapped_pc, (char *) NULL))
- {
- cache_pc_function_low = SIGTRAMP_START (mapped_pc);
- cache_pc_function_high = SIGTRAMP_END (mapped_pc);
- cache_pc_function_name = "<sigtramp>";
- cache_pc_function_section = section;
- goto return_cached_value;
- }
-
msymbol = lookup_minimal_symbol_by_pc_section (mapped_pc, section);
pst = find_pc_sect_psymtab (mapped_pc, section);
if (pst)
return 1;
}
-/* Backward compatibility, no section argument. */
-
-int
-find_pc_partial_function (CORE_ADDR pc, char **name, CORE_ADDR *address,
- CORE_ADDR *endaddr)
-{
- asection *section;
-
- section = find_pc_overlay (pc);
- return find_pc_sect_partial_function (pc, section, name, address, endaddr);
-}
-
/* Return the innermost stack frame executing inside of BLOCK,
or NULL if there is no such frame. If BLOCK is NULL, just return NULL. */
block_innermost_frame (struct block *block)
{
struct frame_info *frame;
- register CORE_ADDR start;
- register CORE_ADDR end;
+ CORE_ADDR start;
+ CORE_ADDR end;
CORE_ADDR calling_pc;
if (block == NULL)
frame = get_prev_frame (frame);
if (frame == NULL)
return NULL;
- calling_pc = frame_address_in_block (frame);
+ calling_pc = get_frame_address_in_block (frame);
if (calling_pc >= start && calling_pc < end)
return frame;
}
}
-
-/* Are we in a call dummy? The code below which allows DECR_PC_AFTER_BREAK
- below is for infrun.c, which may give the macro a pc without that
- subtracted out. */
-
-/* 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.
-
- 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.
-
- Something simpler, like checking for the stack segment, doesn't work,
- since various programs (threads implementations, gcc nested function
- stubs, etc) may either allocate stack frames in another segment, or
- allocate other kinds of code on the stack. */
-
-int
-deprecated_pc_in_call_dummy_on_stack (CORE_ADDR pc, CORE_ADDR sp,
- CORE_ADDR frame_address)
-{
- return (INNER_THAN ((sp), (pc))
- && (frame_address != 0)
- && INNER_THAN ((pc), (frame_address)));
-}
-
-int
-deprecated_pc_in_call_dummy_at_entry_point (CORE_ADDR pc, CORE_ADDR sp,
- CORE_ADDR frame_address)
-{
- return ((pc) >= CALL_DUMMY_ADDRESS ()
- && (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. */
-
-int
-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;
-
- /* 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 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;
-
- /* If the architecture has a custom FRAME_CHAIN_VALID, call it now. */
- if (FRAME_CHAIN_VALID_P ())
- return FRAME_CHAIN_VALID (fp, fi);
-
- return 1;
-}