* psymtab.c (find_pc_sect_symtab_from_partial): Return the symtab

directly corresponding to the found psymtab.
	* dwarf2read.c (recursively_find_pc_sect_symtab): New function.
	(dw2_find_pc_sect_symtab): Use it.
	* block.h (blockvector_contains_pc): Declare.
	* block.c (find_block_in_blockvector): New function.
	(blockvector_for_pc_sect): Use it.
	(blockvector_contains_pc): New function.
This commit is contained in:
Tom Tromey 2012-05-18 14:26:26 +00:00
parent 5a4398495b
commit 9703b51377
5 changed files with 91 additions and 40 deletions

View File

@ -1,3 +1,14 @@
2012-05-18 Tom Tromey <tromey@redhat.com>
* psymtab.c (find_pc_sect_symtab_from_partial): Return the symtab
directly corresponding to the found psymtab.
* dwarf2read.c (recursively_find_pc_sect_symtab): New function.
(dw2_find_pc_sect_symtab): Use it.
* block.h (blockvector_contains_pc): Declare.
* block.c (find_block_in_blockvector): New function.
(blockvector_for_pc_sect): Use it.
(blockvector_contains_pc): New function.
2012-05-18 Maciej W. Rozycki <macro@codesourcery.com>
* mips-tdep.h (mips_write_pc): New prototype.

View File

@ -103,46 +103,19 @@ block_inlined_p (const struct block *bl)
return BLOCK_FUNCTION (bl) != NULL && SYMBOL_INLINED (BLOCK_FUNCTION (bl));
}
/* Return the blockvector immediately containing the innermost lexical
block containing the specified pc value and section, or 0 if there
is none. PBLOCK is a pointer to the block. If PBLOCK is NULL, we
don't pass this information back to the caller. */
/* A helper function that checks whether PC is in the blockvector BL.
It returns the containing block if there is one, or else NULL. */
struct blockvector *
blockvector_for_pc_sect (CORE_ADDR pc, struct obj_section *section,
struct block **pblock, struct symtab *symtab)
static struct block *
find_block_in_blockvector (struct blockvector *bl, CORE_ADDR pc)
{
struct block *b;
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 */
symtab = find_pc_sect_symtab (pc, section);
if (symtab == 0)
return 0;
}
bl = BLOCKVECTOR (symtab);
/* Then search that symtab for the smallest block that wins. */
/* If we have an addrmap mapping code addresses to blocks, then use
that. */
if (BLOCKVECTOR_MAP (bl))
{
b = addrmap_find (BLOCKVECTOR_MAP (bl), pc);
if (b)
{
if (pblock)
*pblock = b;
return bl;
}
else
return 0;
}
return addrmap_find (BLOCKVECTOR_MAP (bl), pc);
/* Otherwise, use binary search to find the last block that starts
before PC. */
@ -165,14 +138,51 @@ blockvector_for_pc_sect (CORE_ADDR pc, struct obj_section *section,
{
b = BLOCKVECTOR_BLOCK (bl, bot);
if (BLOCK_END (b) > pc)
{
if (pblock)
*pblock = b;
return bl;
}
return b;
bot--;
}
return 0;
return NULL;
}
/* Return the blockvector immediately containing the innermost lexical
block containing the specified pc value and section, or 0 if there
is none. PBLOCK is a pointer to the block. If PBLOCK is NULL, we
don't pass this information back to the caller. */
struct blockvector *
blockvector_for_pc_sect (CORE_ADDR pc, struct obj_section *section,
struct block **pblock, struct symtab *symtab)
{
struct blockvector *bl;
struct block *b;
if (symtab == 0) /* if no symtab specified by caller */
{
/* First search all symtabs for one whose file contains our pc */
symtab = find_pc_sect_symtab (pc, section);
if (symtab == 0)
return 0;
}
bl = BLOCKVECTOR (symtab);
/* Then search that symtab for the smallest block that wins. */
b = find_block_in_blockvector (bl, pc);
if (b == NULL)
return NULL;
if (pblock)
*pblock = b;
return bl;
}
/* Return true if the blockvector BV contains PC, false otherwise. */
int
blockvector_contains_pc (struct blockvector *bv, CORE_ADDR pc)
{
return find_block_in_blockvector (bv, pc) != NULL;
}
/* Return call_site for specified PC in GDBARCH. PC must match exactly, it

View File

@ -152,6 +152,8 @@ extern struct blockvector *blockvector_for_pc_sect (CORE_ADDR,
struct block **,
struct symtab *);
extern int blockvector_contains_pc (struct blockvector *bv, CORE_ADDR pc);
extern struct call_site *call_site_for_pc (struct gdbarch *gdbarch,
CORE_ADDR pc);

View File

@ -2992,6 +2992,30 @@ dw2_expand_symtabs_matching
}
}
/* A helper for dw2_find_pc_sect_symtab which finds the most specific
symtab. */
static struct symtab *
recursively_find_pc_sect_symtab (struct symtab *symtab, CORE_ADDR pc)
{
int i;
if (BLOCKVECTOR (symtab) != NULL
&& blockvector_contains_pc (BLOCKVECTOR (symtab), pc))
return symtab;
for (i = 0; symtab->includes[i]; ++i)
{
struct symtab *s;
s = recursively_find_pc_sect_symtab (s, pc);
if (s != NULL)
return s;
}
return NULL;
}
static struct symtab *
dw2_find_pc_sect_symtab (struct objfile *objfile,
struct minimal_symbol *msymbol,
@ -3000,6 +3024,7 @@ dw2_find_pc_sect_symtab (struct objfile *objfile,
int warn_if_readin)
{
struct dwarf2_per_cu_data *data;
struct symtab *result;
dw2_setup (objfile);
@ -3014,7 +3039,9 @@ dw2_find_pc_sect_symtab (struct objfile *objfile,
warning (_("(Internal error: pc %s in read in CU, but not in symtab.)"),
paddress (get_objfile_arch (objfile), pc));
return dw2_instantiate_symtab (data);
result = recursively_find_pc_sect_symtab (dw2_instantiate_symtab (data), pc);
gdb_assert (result != NULL);
return result;
}
static void

View File

@ -397,7 +397,8 @@ find_pc_sect_symtab_from_partial (struct objfile *objfile,
warning (_("\
(Internal error: pc %s in read in psymtab, but not in symtab.)\n"),
paddress (get_objfile_arch (ps->objfile), pc));
return psymtab_to_symtab (ps);
psymtab_to_symtab (ps);
return ps->symtab;
}
return NULL;
}