* Makefile.in: Update dependencies.
	* dwarf2read.c: Include "addrmap.h"
	(struct dwarf2_cu): New fields RANGES_OFFSET and HAS_RANGES_OFFSET.
	(dwarf2_ranges_read): New prototype.
	(dwarf2_build_psymtabs_hard): Initialize and prepare PSYMTABS_ADDRMAP.
	Add discontiguous range to PSYMTABS_ADDRMAP by DWARF2_RANGES_READ on
	HAS_RANGES_OFFSET, otherwise add there the contiguous range.
	(dwarf2_ranges_read): New parameter RANGES_PST, update the function
	comment for it.  Add the found ranges to RANGES_PST.  New variable
	BASEADDR, initialize it the common way.
	(dwarf2_get_pc_bounds): Update the caller for the new parameter.
	(read_partial_die): `DW_AT_ranges' now only sets RANGES_OFFSET and
	HAS_RANGES_OFFSET for the later processing.
	* objfiles.h (struct objfile): New field PSYMTABS_ADDRMAP.
	* symtab.c: Include "addrmap.h"
	(find_pc_sect_psymtab): Support reading the field PSYMTABS_ADDRMAP.
	Move the psymtab locator into ...
	(find_pc_sect_psymtab_closer): ... a new function.

	gdb/testsuite/
	* gdb.dwarf2/dw2-ranges.S: Merge the secondary section with `.fini'.
	* gdb.dwarf2/dw2-ranges.exp: Compile also `dw2-ranges2.S' and
	`dw2-ranges3.S' and test also their MAIN2, FUNC2 and MAIN3 symbols.
	* gdb.dwarf2/dw2-ranges2.S, gdb.dwarf2/dw2-ranges3.S: New files.
This commit is contained in:
Jan Kratochvil
2008-05-04 17:27:01 +00:00
parent 85cbf3d35d
commit ff013f42f4
10 changed files with 314 additions and 80 deletions

View File

@ -41,6 +41,7 @@
#include "objc-lang.h"
#include "ada-lang.h"
#include "p-lang.h"
#include "addrmap.h"
#include "hashtab.h"
@ -767,6 +768,83 @@ matching_bfd_sections (asection *first, asection *second)
return 0;
}
/* Find which partial symtab contains PC and SECTION starting at psymtab PST.
We may find a different psymtab than PST. See FIND_PC_SECT_PSYMTAB. */
struct partial_symtab *
find_pc_sect_psymtab_closer (CORE_ADDR pc, asection *section,
struct partial_symtab *pst,
struct minimal_symbol *msymbol)
{
struct objfile *objfile = pst->objfile;
struct partial_symtab *tpst;
struct partial_symtab *best_pst = pst;
CORE_ADDR best_addr = pst->textlow;
/* An objfile that has its functions reordered might have
many partial symbol tables containing the PC, but
we want the partial symbol table that contains the
function containing the PC. */
if (!(objfile->flags & OBJF_REORDERED) &&
section == 0) /* can't validate section this way */
return pst;
if (msymbol == NULL)
return (pst);
/* The code range of partial symtabs sometimes overlap, so, in
the loop below, we need to check all partial symtabs and
find the one that fits better for the given PC address. We
select the partial symtab that contains a symbol whose
address is closest to the PC address. By closest we mean
that find_pc_sect_symbol returns the symbol with address
that is closest and still less than the given PC. */
for (tpst = pst; tpst != NULL; tpst = tpst->next)
{
if (pc >= tpst->textlow && pc < tpst->texthigh)
{
struct partial_symbol *p;
CORE_ADDR this_addr;
/* NOTE: This assumes that every psymbol has a
corresponding msymbol, which is not necessarily
true; the debug info might be much richer than the
object's symbol table. */
p = find_pc_sect_psymbol (tpst, pc, section);
if (p != NULL
&& SYMBOL_VALUE_ADDRESS (p)
== SYMBOL_VALUE_ADDRESS (msymbol))
return tpst;
/* Also accept the textlow value of a psymtab as a
"symbol", to provide some support for partial
symbol tables with line information but no debug
symbols (e.g. those produced by an assembler). */
if (p != NULL)
this_addr = SYMBOL_VALUE_ADDRESS (p);
else
this_addr = tpst->textlow;
/* Check whether it is closer than our current
BEST_ADDR. Since this symbol address is
necessarily lower or equal to PC, the symbol closer
to PC is the symbol which address is the highest.
This way we return the psymtab which contains such
best match symbol. This can help in cases where the
symbol information/debuginfo is not complete, like
for instance on IRIX6 with gcc, where no debug info
is emitted for statics. (See also the nodebug.exp
testcase.) */
if (this_addr > best_addr)
{
best_addr = this_addr;
best_pst = tpst;
}
}
}
return best_pst;
}
/* Find which partial symtab contains PC and SECTION. Return 0 if
none. We return the psymtab that contains a symbol whose address
exactly matches PC, or, if we cannot find an exact match, the
@ -774,7 +852,6 @@ matching_bfd_sections (asection *first, asection *second)
struct partial_symtab *
find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
{
struct partial_symtab *pst;
struct objfile *objfile;
struct minimal_symbol *msymbol;
@ -790,79 +867,53 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
|| msymbol->type == mst_file_bss))
return NULL;
ALL_PSYMTABS (objfile, pst)
{
if (pc >= pst->textlow && pc < pst->texthigh)
/* Try just the PSYMTABS_ADDRMAP mapping first as it has better granularity
than the later used TEXTLOW/TEXTHIGH one. */
ALL_OBJFILES (objfile)
if (objfile->psymtabs_addrmap != NULL)
{
struct partial_symtab *tpst;
struct partial_symtab *best_pst = pst;
CORE_ADDR best_addr = pst->textlow;
struct partial_symtab *pst;
/* An objfile that has its functions reordered might have
many partial symbol tables containing the PC, but
we want the partial symbol table that contains the
function containing the PC. */
if (!(objfile->flags & OBJF_REORDERED) &&
section == 0) /* can't validate section this way */
return (pst);
if (msymbol == NULL)
return (pst);
/* The code range of partial symtabs sometimes overlap, so, in
the loop below, we need to check all partial symtabs and
find the one that fits better for the given PC address. We
select the partial symtab that contains a symbol whose
address is closest to the PC address. By closest we mean
that find_pc_sect_symbol returns the symbol with address
that is closest and still less than the given PC. */
for (tpst = pst; tpst != NULL; tpst = tpst->next)
pst = addrmap_find (objfile->psymtabs_addrmap, pc);
if (pst != NULL)
{
if (pc >= tpst->textlow && pc < tpst->texthigh)
{
struct partial_symbol *p;
CORE_ADDR this_addr;
/* We do not try to call FIND_PC_SECT_PSYMTAB_CLOSER as
PSYMTABS_ADDRMAP we used has already the best 1-byte
granularity and FIND_PC_SECT_PSYMTAB_CLOSER may mislead us into
a worse chosen section due to the TEXTLOW/TEXTHIGH ranges
overlap. */
/* NOTE: This assumes that every psymbol has a
corresponding msymbol, which is not necessarily
true; the debug info might be much richer than the
object's symbol table. */
p = find_pc_sect_psymbol (tpst, pc, section);
if (p != NULL
&& SYMBOL_VALUE_ADDRESS (p)
== SYMBOL_VALUE_ADDRESS (msymbol))
return (tpst);
/* Also accept the textlow value of a psymtab as a
"symbol", to provide some support for partial
symbol tables with line information but no debug
symbols (e.g. those produced by an assembler). */
if (p != NULL)
this_addr = SYMBOL_VALUE_ADDRESS (p);
else
this_addr = tpst->textlow;
/* Check whether it is closer than our current
BEST_ADDR. Since this symbol address is
necessarily lower or equal to PC, the symbol closer
to PC is the symbol which address is the highest.
This way we return the psymtab which contains such
best match symbol. This can help in cases where the
symbol information/debuginfo is not complete, like
for instance on IRIX6 with gcc, where no debug info
is emitted for statics. (See also the nodebug.exp
testcase.) */
if (this_addr > best_addr)
{
best_addr = this_addr;
best_pst = tpst;
}
}
return pst;
}
return (best_pst);
}
}
return (NULL);
/* Existing PSYMTABS_ADDRMAP mapping is present even for PARTIAL_SYMTABs
which still have no corresponding full SYMTABs read. But it is not
present for non-DWARF2 debug infos not supporting PSYMTABS_ADDRMAP in GDB
so far. */
ALL_OBJFILES (objfile)
{
struct partial_symtab *pst;
/* Check even OBJFILE with non-zero PSYMTABS_ADDRMAP as only several of
its CUs may be missing in PSYMTABS_ADDRMAP as they may be varying
debug info type in single OBJFILE. */
ALL_OBJFILE_PSYMTABS (objfile, pst)
if (pc >= pst->textlow && pc < pst->texthigh)
{
struct partial_symtab *best_pst;
best_pst = find_pc_sect_psymtab_closer (pc, section, pst,
msymbol);
if (best_pst != NULL)
return best_pst;
}
}
return NULL;
}
/* Find which partial symtab contains PC. Return 0 if none.