* dwarf2read.c (create_partial_symtab): Add forward decl.

(create_partial_symtab): Move to be closer to other psymtab functions.
	(process_psymtab_comp_unit_reader, process_psymtab_comp_unit): Ditto.
This commit is contained in:
Doug Evans 2013-03-28 17:41:03 +00:00
parent ca69b9e6ad
commit 0018ea6f8f
2 changed files with 203 additions and 186 deletions

View File

@ -1,5 +1,9 @@
2013-03-28 Doug Evans <dje@google.com>
* dwarf2read.c (create_partial_symtab): Add forward decl.
(create_partial_symtab): Move to be closer to other psymtab functions.
(process_psymtab_comp_unit_reader, process_psymtab_comp_unit): Ditto.
* dwarf2read.c (dwarf2_physname): Move declaration to better spot.
(compute_symtab_includes): Remove unnecessary forward declaration.
(die_needs_namespace): Add comment marking group of functions for

View File

@ -1278,6 +1278,9 @@ static void dwarf2_create_include_psymtab (char *, struct partial_symtab *,
static void dwarf2_find_base_address (struct die_info *die,
struct dwarf2_cu *cu);
static struct partial_symtab *create_partial_symtab
(struct dwarf2_per_cu_data *per_cu, const char *name);
static void dwarf2_build_psymtabs_hard (struct objfile *);
static void scan_partial_symbols (struct partial_die_info *,
@ -4873,193 +4876,14 @@ init_cutu_and_read_dies_simple (struct dwarf2_per_cu_data *this_cu,
NULL,
die_reader_func, data);
}
/* Type Unit Groups.
/* Create a psymtab named NAME and assign it to PER_CU.
The caller must fill in the following details:
dirname, textlow, texthigh. */
static struct partial_symtab *
create_partial_symtab (struct dwarf2_per_cu_data *per_cu, const char *name)
{
struct objfile *objfile = per_cu->objfile;
struct partial_symtab *pst;
pst = start_psymtab_common (objfile, objfile->section_offsets,
name, 0,
objfile->global_psymbols.next,
objfile->static_psymbols.next);
pst->psymtabs_addrmap_supported = 1;
/* This is the glue that links PST into GDB's symbol API. */
pst->read_symtab_private = per_cu;
pst->read_symtab = dwarf2_read_symtab;
per_cu->v.psymtab = pst;
return pst;
}
/* die_reader_func for process_psymtab_comp_unit. */
static void
process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
gdb_byte *info_ptr,
struct die_info *comp_unit_die,
int has_children,
void *data)
{
struct dwarf2_cu *cu = reader->cu;
struct objfile *objfile = cu->objfile;
struct dwarf2_per_cu_data *per_cu = cu->per_cu;
struct attribute *attr;
CORE_ADDR baseaddr;
CORE_ADDR best_lowpc = 0, best_highpc = 0;
struct partial_symtab *pst;
int has_pc_info;
const char *filename;
int *want_partial_unit_ptr = data;
if (comp_unit_die->tag == DW_TAG_partial_unit
&& (want_partial_unit_ptr == NULL
|| !*want_partial_unit_ptr))
return;
gdb_assert (! per_cu->is_debug_types);
prepare_one_comp_unit (cu, comp_unit_die, language_minimal);
cu->list_in_scope = &file_symbols;
/* Allocate a new partial symbol table structure. */
attr = dwarf2_attr (comp_unit_die, DW_AT_name, cu);
if (attr == NULL || !DW_STRING (attr))
filename = "";
else
filename = DW_STRING (attr);
pst = create_partial_symtab (per_cu, filename);
/* This must be done before calling dwarf2_build_include_psymtabs. */
attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, cu);
if (attr != NULL)
pst->dirname = DW_STRING (attr);
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
dwarf2_find_base_address (comp_unit_die, cu);
/* Possibly set the default values of LOWPC and HIGHPC from
`DW_AT_ranges'. */
has_pc_info = dwarf2_get_pc_bounds (comp_unit_die, &best_lowpc,
&best_highpc, cu, pst);
if (has_pc_info == 1 && best_lowpc < best_highpc)
/* Store the contiguous range if it is not empty; it can be empty for
CUs with no code. */
addrmap_set_empty (objfile->psymtabs_addrmap,
best_lowpc + baseaddr,
best_highpc + baseaddr - 1, pst);
/* Check if comp unit has_children.
If so, read the rest of the partial symbols from this comp unit.
If not, there's no more debug_info for this comp unit. */
if (has_children)
{
struct partial_die_info *first_die;
CORE_ADDR lowpc, highpc;
lowpc = ((CORE_ADDR) -1);
highpc = ((CORE_ADDR) 0);
first_die = load_partial_dies (reader, info_ptr, 1);
scan_partial_symbols (first_die, &lowpc, &highpc,
! has_pc_info, cu);
/* If we didn't find a lowpc, set it to highpc to avoid
complaints from `maint check'. */
if (lowpc == ((CORE_ADDR) -1))
lowpc = highpc;
/* If the compilation unit didn't have an explicit address range,
then use the information extracted from its child dies. */
if (! has_pc_info)
{
best_lowpc = lowpc;
best_highpc = highpc;
}
}
pst->textlow = best_lowpc + baseaddr;
pst->texthigh = best_highpc + baseaddr;
pst->n_global_syms = objfile->global_psymbols.next -
(objfile->global_psymbols.list + pst->globals_offset);
pst->n_static_syms = objfile->static_psymbols.next -
(objfile->static_psymbols.list + pst->statics_offset);
sort_pst_symbols (objfile, pst);
if (!VEC_empty (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs))
{
int i;
int len = VEC_length (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs);
struct dwarf2_per_cu_data *iter;
/* Fill in 'dependencies' here; we fill in 'users' in a
post-pass. */
pst->number_of_dependencies = len;
pst->dependencies = obstack_alloc (&objfile->objfile_obstack,
len * sizeof (struct symtab *));
for (i = 0;
VEC_iterate (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs,
i, iter);
++i)
pst->dependencies[i] = iter->v.psymtab;
VEC_free (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs);
}
/* Get the list of files included in the current compilation unit,
and build a psymtab for each of them. */
dwarf2_build_include_psymtabs (cu, comp_unit_die, pst);
if (dwarf2_read_debug)
{
struct gdbarch *gdbarch = get_objfile_arch (objfile);
fprintf_unfiltered (gdb_stdlog,
"Psymtab for %s unit @0x%x: %s - %s"
", %d global, %d static syms\n",
per_cu->is_debug_types ? "type" : "comp",
per_cu->offset.sect_off,
paddress (gdbarch, pst->textlow),
paddress (gdbarch, pst->texthigh),
pst->n_global_syms, pst->n_static_syms);
}
}
/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
Process compilation unit THIS_CU for a psymtab. */
static void
process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu,
int want_partial_unit)
{
/* If this compilation unit was already read in, free the
cached copy in order to read it in again. This is
necessary because we skipped some symbols when we first
read in the compilation unit (see load_partial_dies).
This problem could be avoided, but the benefit is unclear. */
if (this_cu->cu != NULL)
free_one_cached_comp_unit (this_cu);
gdb_assert (! this_cu->is_debug_types);
init_cutu_and_read_dies (this_cu, NULL, 0, 0,
process_psymtab_comp_unit_reader,
&want_partial_unit);
/* Age out any secondary CUs. */
age_cached_comp_units ();
}
Type Unit Groups are a way to collapse the set of all TUs (type units) into
a more manageable set. The grouping is done by DW_AT_stmt_list entry
so that all types coming from the same compilation (.o file) are grouped
together. A future step could be to put the types in the same symtab as
the CU the types ultimately came from. */
static hashval_t
hash_type_unit_group (const void *item)
@ -5380,6 +5204,195 @@ build_type_unit_groups (die_reader_func_ftype *func, void *data)
tu_stats->nr_stmt_less_type_units);
}
}
/* Partial symbol tables. */
/* Create a psymtab named NAME and assign it to PER_CU.
The caller must fill in the following details:
dirname, textlow, texthigh. */
static struct partial_symtab *
create_partial_symtab (struct dwarf2_per_cu_data *per_cu, const char *name)
{
struct objfile *objfile = per_cu->objfile;
struct partial_symtab *pst;
pst = start_psymtab_common (objfile, objfile->section_offsets,
name, 0,
objfile->global_psymbols.next,
objfile->static_psymbols.next);
pst->psymtabs_addrmap_supported = 1;
/* This is the glue that links PST into GDB's symbol API. */
pst->read_symtab_private = per_cu;
pst->read_symtab = dwarf2_read_symtab;
per_cu->v.psymtab = pst;
return pst;
}
/* die_reader_func for process_psymtab_comp_unit. */
static void
process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
gdb_byte *info_ptr,
struct die_info *comp_unit_die,
int has_children,
void *data)
{
struct dwarf2_cu *cu = reader->cu;
struct objfile *objfile = cu->objfile;
struct dwarf2_per_cu_data *per_cu = cu->per_cu;
struct attribute *attr;
CORE_ADDR baseaddr;
CORE_ADDR best_lowpc = 0, best_highpc = 0;
struct partial_symtab *pst;
int has_pc_info;
const char *filename;
int *want_partial_unit_ptr = data;
if (comp_unit_die->tag == DW_TAG_partial_unit
&& (want_partial_unit_ptr == NULL
|| !*want_partial_unit_ptr))
return;
gdb_assert (! per_cu->is_debug_types);
prepare_one_comp_unit (cu, comp_unit_die, language_minimal);
cu->list_in_scope = &file_symbols;
/* Allocate a new partial symbol table structure. */
attr = dwarf2_attr (comp_unit_die, DW_AT_name, cu);
if (attr == NULL || !DW_STRING (attr))
filename = "";
else
filename = DW_STRING (attr);
pst = create_partial_symtab (per_cu, filename);
/* This must be done before calling dwarf2_build_include_psymtabs. */
attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, cu);
if (attr != NULL)
pst->dirname = DW_STRING (attr);
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
dwarf2_find_base_address (comp_unit_die, cu);
/* Possibly set the default values of LOWPC and HIGHPC from
`DW_AT_ranges'. */
has_pc_info = dwarf2_get_pc_bounds (comp_unit_die, &best_lowpc,
&best_highpc, cu, pst);
if (has_pc_info == 1 && best_lowpc < best_highpc)
/* Store the contiguous range if it is not empty; it can be empty for
CUs with no code. */
addrmap_set_empty (objfile->psymtabs_addrmap,
best_lowpc + baseaddr,
best_highpc + baseaddr - 1, pst);
/* Check if comp unit has_children.
If so, read the rest of the partial symbols from this comp unit.
If not, there's no more debug_info for this comp unit. */
if (has_children)
{
struct partial_die_info *first_die;
CORE_ADDR lowpc, highpc;
lowpc = ((CORE_ADDR) -1);
highpc = ((CORE_ADDR) 0);
first_die = load_partial_dies (reader, info_ptr, 1);
scan_partial_symbols (first_die, &lowpc, &highpc,
! has_pc_info, cu);
/* If we didn't find a lowpc, set it to highpc to avoid
complaints from `maint check'. */
if (lowpc == ((CORE_ADDR) -1))
lowpc = highpc;
/* If the compilation unit didn't have an explicit address range,
then use the information extracted from its child dies. */
if (! has_pc_info)
{
best_lowpc = lowpc;
best_highpc = highpc;
}
}
pst->textlow = best_lowpc + baseaddr;
pst->texthigh = best_highpc + baseaddr;
pst->n_global_syms = objfile->global_psymbols.next -
(objfile->global_psymbols.list + pst->globals_offset);
pst->n_static_syms = objfile->static_psymbols.next -
(objfile->static_psymbols.list + pst->statics_offset);
sort_pst_symbols (objfile, pst);
if (!VEC_empty (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs))
{
int i;
int len = VEC_length (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs);
struct dwarf2_per_cu_data *iter;
/* Fill in 'dependencies' here; we fill in 'users' in a
post-pass. */
pst->number_of_dependencies = len;
pst->dependencies = obstack_alloc (&objfile->objfile_obstack,
len * sizeof (struct symtab *));
for (i = 0;
VEC_iterate (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs,
i, iter);
++i)
pst->dependencies[i] = iter->v.psymtab;
VEC_free (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs);
}
/* Get the list of files included in the current compilation unit,
and build a psymtab for each of them. */
dwarf2_build_include_psymtabs (cu, comp_unit_die, pst);
if (dwarf2_read_debug)
{
struct gdbarch *gdbarch = get_objfile_arch (objfile);
fprintf_unfiltered (gdb_stdlog,
"Psymtab for %s unit @0x%x: %s - %s"
", %d global, %d static syms\n",
per_cu->is_debug_types ? "type" : "comp",
per_cu->offset.sect_off,
paddress (gdbarch, pst->textlow),
paddress (gdbarch, pst->texthigh),
pst->n_global_syms, pst->n_static_syms);
}
}
/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
Process compilation unit THIS_CU for a psymtab. */
static void
process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu,
int want_partial_unit)
{
/* If this compilation unit was already read in, free the
cached copy in order to read it in again. This is
necessary because we skipped some symbols when we first
read in the compilation unit (see load_partial_dies).
This problem could be avoided, but the benefit is unclear. */
if (this_cu->cu != NULL)
free_one_cached_comp_unit (this_cu);
gdb_assert (! this_cu->is_debug_types);
init_cutu_and_read_dies (this_cu, NULL, 0, 0,
process_psymtab_comp_unit_reader,
&want_partial_unit);
/* Age out any secondary CUs. */
age_cached_comp_units ();
}
/* Reader function for build_type_psymtabs. */