functions and pc values.
Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "symtab.h"
#include "objfiles.h"
#include "frame.h"
#include "gdbcore.h"
-#include "value.h" /* for read_register */
-#include "target.h" /* for target_has_stack */
-#include "inferior.h" /* for read_pc */
+#include "value.h"
+#include "target.h"
+#include "inferior.h"
#include "annotate.h"
#include "regcache.h"
#include "gdb_assert.h"
#include "command.h"
#include "gdbcmd.h"
#include "block.h"
+#include "inline-frame.h"
/* Prototypes for exported functions. */
get_frame_block (struct frame_info *frame, CORE_ADDR *addr_in_block)
{
const CORE_ADDR pc = get_frame_address_in_block (frame);
+ struct frame_info *next_frame;
+ struct block *bl;
+ int inline_count;
if (addr_in_block)
*addr_in_block = pc;
- return block_for_pc (pc);
+ bl = block_for_pc (pc);
+ if (bl == NULL)
+ return NULL;
+
+ inline_count = frame_inlined_callees (frame);
+
+ while (inline_count > 0)
+ {
+ if (block_inlined_p (bl))
+ inline_count--;
+
+ bl = BLOCK_SUPERBLOCK (bl);
+ gdb_assert (bl != NULL);
+ }
+
+ return bl;
}
CORE_ADDR
bl = block_for_pc (pc);
if (bl)
{
- struct symbol *symbol = block_function (bl);
+ struct symbol *symbol = block_linkage_function (bl);
if (symbol)
{
get_frame_function (struct frame_info *frame)
{
struct block *bl = get_frame_block (frame, 0);
- if (bl == 0)
- return 0;
- return block_function (bl);
+
+ if (bl == NULL)
+ return NULL;
+
+ while (BLOCK_FUNCTION (bl) == NULL && BLOCK_SUPERBLOCK (bl) != NULL)
+ bl = BLOCK_SUPERBLOCK (bl);
+
+ return BLOCK_FUNCTION (bl);
}
\f
Returns 0 if function is not known. */
struct symbol *
-find_pc_sect_function (CORE_ADDR pc, struct bfd_section *section)
+find_pc_sect_function (CORE_ADDR pc, struct obj_section *section)
{
struct block *b = block_for_pc_sect (pc, section);
if (b == 0)
return 0;
- return block_function (b);
+ return block_linkage_function (b);
}
/* Return the function containing pc value PC.
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 bfd_section *cache_pc_function_section = NULL;
+static struct obj_section *cache_pc_function_section = NULL;
/* Clear cache, e.g. when symbol table is discarded. */
find_pc_partial_function (CORE_ADDR pc, char **name, CORE_ADDR *address,
CORE_ADDR *endaddr)
{
- struct bfd_section *section;
+ struct obj_section *section;
struct partial_symtab *pst;
struct symbol *f;
struct minimal_symbol *msymbol;
struct partial_symbol *psb;
- struct obj_section *osect;
int i;
CORE_ADDR mapped_pc;
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;
- }
+ section = find_pc_section (pc);
mapped_pc = overlay_mapped_address (pc, section);
{
cache_pc_function_low = BLOCK_START (SYMBOL_BLOCK_VALUE (f));
cache_pc_function_high = BLOCK_END (SYMBOL_BLOCK_VALUE (f));
- cache_pc_function_name = DEPRECATED_SYMBOL_NAME (f);
+ cache_pc_function_name = SYMBOL_LINKAGE_NAME (f);
cache_pc_function_section = section;
goto return_cached_value;
}
psb = find_pc_sect_psymbol (pst, mapped_pc, section);
if (psb
- && (msymbol == NULL ||
- (SYMBOL_VALUE_ADDRESS (psb)
- >= SYMBOL_VALUE_ADDRESS (msymbol))))
+ && (msymbol == NULL
+ || (SYMBOL_VALUE_ADDRESS (psb)
+ >= SYMBOL_VALUE_ADDRESS (msymbol))))
{
/* This case isn't being cached currently. */
if (address)
*address = SYMBOL_VALUE_ADDRESS (psb);
if (name)
- *name = DEPRECATED_SYMBOL_NAME (psb);
+ *name = SYMBOL_LINKAGE_NAME (psb);
/* endaddr non-NULL can't happen here. */
return 1;
}
of the text seg doesn't appear to be part of the last function in the
text segment. */
- osect = find_pc_sect_section (mapped_pc, section);
-
- if (!osect)
+ if (!section)
msymbol = NULL;
/* Must be in the minimal symbol table. */
}
cache_pc_function_low = SYMBOL_VALUE_ADDRESS (msymbol);
- cache_pc_function_name = DEPRECATED_SYMBOL_NAME (msymbol);
+ cache_pc_function_name = SYMBOL_LINKAGE_NAME (msymbol);
cache_pc_function_section = section;
/* If the minimal symbol has a size, use it for the cache.
other sections, to find the next symbol in this section with
a different address. */
- for (i = 1; DEPRECATED_SYMBOL_NAME (msymbol + i) != NULL; i++)
+ for (i = 1; SYMBOL_LINKAGE_NAME (msymbol + i) != NULL; i++)
{
if (SYMBOL_VALUE_ADDRESS (msymbol + i) != SYMBOL_VALUE_ADDRESS (msymbol)
- && SYMBOL_BFD_SECTION (msymbol + i) == SYMBOL_BFD_SECTION (msymbol))
+ && SYMBOL_OBJ_SECTION (msymbol + i) == SYMBOL_OBJ_SECTION (msymbol))
break;
}
- if (DEPRECATED_SYMBOL_NAME (msymbol + i) != NULL
- && SYMBOL_VALUE_ADDRESS (msymbol + i) < osect->endaddr)
+ if (SYMBOL_LINKAGE_NAME (msymbol + i) != NULL
+ && SYMBOL_VALUE_ADDRESS (msymbol + i) < obj_section_endaddr (section))
cache_pc_function_high = SYMBOL_VALUE_ADDRESS (msymbol + i);
else
/* We got the start address from the last msymbol in the objfile.
So the end address is the end of the section. */
- cache_pc_function_high = osect->endaddr;
+ cache_pc_function_high = obj_section_endaddr (section);
}
return_cached_value:
struct frame_info *frame;
CORE_ADDR start;
CORE_ADDR end;
- CORE_ADDR calling_pc;
if (block == NULL)
return NULL;
frame = get_current_frame ();
while (frame != NULL)
{
- calling_pc = get_frame_address_in_block (frame);
- if (calling_pc >= start && calling_pc < end)
+ struct block *frame_block = get_frame_block (frame, NULL);
+ if (frame_block != NULL && contained_in (frame_block, block))
return frame;
frame = get_prev_frame (frame);