/* dwarf2read.c's main "handle" on a TU symtab.
To simplify things we create an artificial CU that "includes" all the
type units using this stmt_list so that the rest of the code still has
- a "per_cu" handle on the symtab.
- This PER_CU is recognized by having no section. */
-#define IS_TYPE_UNIT_GROUP(per_cu) ((per_cu)->section == NULL)
+ a "per_cu" handle on the symtab. */
struct dwarf2_per_cu_data per_cu;
/* The TUs that share this DW_AT_stmt_list entry.
/* The data used to construct the hash key. */
struct stmt_list_hash hash;
- /* The number of symtabs from the line header.
- The value here must match line_header.num_file_names. */
- unsigned int num_symtabs;
-
/* The symbol tables for this TU (obtained from the files listed in
DW_AT_stmt_list).
WARNING: The order of entries here must match the order of entries
static file_and_directory find_file_and_directory (struct die_info *die,
struct dwarf2_cu *cu);
-static htab_up allocate_signatured_type_table (struct objfile *objfile);
+static htab_up allocate_signatured_type_table ();
-static htab_up allocate_dwo_unit_table (struct objfile *objfile);
+static htab_up allocate_dwo_unit_table ();
static struct dwo_unit *lookup_dwo_unit_in_dwp
(struct dwarf2_per_objfile *dwarf2_per_objfile,
/* Skip type_unit_groups, reading the type units they contain
is handled elsewhere. */
- if (IS_TYPE_UNIT_GROUP (per_cu))
+ if (per_cu->type_unit_group_p ())
return;
/* The destructor of dwarf2_queue_guard frees any entries left on
gdb_assert (dwarf2_per_objfile->all_type_units.empty ());
dwarf2_per_objfile->all_type_units.reserve (elements / 3);
- htab_up sig_types_hash = allocate_signatured_type_table (objfile);
+ htab_up sig_types_hash = allocate_signatured_type_table ();
for (offset_type i = 0; i < elements; i += 3)
{
gdb_assert (dwarf2_per_objfile->all_type_units.empty ());
dwarf2_per_objfile->all_type_units.reserve (map.tu_count);
- htab_up sig_types_hash = allocate_signatured_type_table (objfile);
+ htab_up sig_types_hash = allocate_signatured_type_table ();
for (uint32_t i = 0; i < map.tu_count; ++i)
{
/* This should never be called for TUs. */
gdb_assert (! this_cu->is_debug_types);
/* Nor type unit groups. */
- gdb_assert (! IS_TYPE_UNIT_GROUP (this_cu));
+ gdb_assert (! this_cu->type_unit_group_p ());
if (this_cu->v.quick->file_names != NULL)
return this_cu->v.quick->file_names;
/* Allocate a hash table for signatured types. */
static htab_up
-allocate_signatured_type_table (struct objfile *objfile)
+allocate_signatured_type_table ()
{
return htab_up (htab_create_alloc (41,
hash_signatured_type,
if (types_htab == NULL)
{
if (dwo_file)
- types_htab = allocate_dwo_unit_table (objfile);
+ types_htab = allocate_dwo_unit_table ();
else
- types_htab = allocate_signatured_type_table (objfile);
+ types_htab = allocate_signatured_type_table ();
}
if (dwo_file)
{
struct dwarf2_per_objfile *dwarf2_per_objfile
= cu->per_cu->dwarf2_per_objfile;
- struct objfile *objfile = dwarf2_per_objfile->objfile;
struct dwo_file *dwo_file;
struct dwo_unit find_dwo_entry, *dwo_entry;
struct signatured_type find_sig_entry, *sig_entry;
/* If TU skeletons have been removed then we may not have read in any
TUs yet. */
if (dwarf2_per_objfile->signatured_types == NULL)
- {
- dwarf2_per_objfile->signatured_types
- = allocate_signatured_type_table (objfile);
- }
+ dwarf2_per_objfile->signatured_types = allocate_signatured_type_table ();
/* We only ever need to read in one copy of a signatured type.
Use the global signatured_types array to do our own comdat-folding
{
struct dwarf2_per_objfile *dwarf2_per_objfile
= cu->per_cu->dwarf2_per_objfile;
- struct objfile *objfile = dwarf2_per_objfile->objfile;
struct dwp_file *dwp_file = get_dwp_file (dwarf2_per_objfile);
struct dwo_unit *dwo_entry;
struct signatured_type find_sig_entry, *sig_entry;
/* If TU skeletons have been removed then we may not have read in any
TUs yet. */
if (dwarf2_per_objfile->signatured_types == NULL)
- {
- dwarf2_per_objfile->signatured_types
- = allocate_signatured_type_table (objfile);
- }
+ dwarf2_per_objfile->signatured_types = allocate_signatured_type_table ();
find_sig_entry.signature = sig;
slot = htab_find_slot (dwarf2_per_objfile->signatured_types.get (),
/* Allocate a hash table for type unit groups. */
static htab_up
-allocate_type_unit_groups_table (struct objfile *objfile)
+allocate_type_unit_groups_table ()
{
return htab_up (htab_create_alloc (3,
hash_type_unit_group,
struct type_unit_group type_unit_group_for_lookup;
if (dwarf2_per_objfile->type_unit_groups == NULL)
- {
- dwarf2_per_objfile->type_unit_groups =
- allocate_type_unit_groups_table (dwarf2_per_objfile->objfile);
- }
+ dwarf2_per_objfile->type_unit_groups = allocate_type_unit_groups_table ();
/* Do we need to create a new group, or can we use an existing one? */
int i;
gdb_assert (len > 0);
- gdb_assert (IS_TYPE_UNIT_GROUP (per_cu));
+ gdb_assert (per_cu->type_unit_group_p ());
pst->number_of_dependencies = len;
pst->dependencies = objfile->partial_symtabs->allocate_dependencies (len);
/* If this TU doesn't exist in the global table, add it and read it in. */
if (dwarf2_per_objfile->signatured_types == NULL)
- {
- dwarf2_per_objfile->signatured_types
- = allocate_signatured_type_table (dwarf2_per_objfile->objfile);
- }
+ dwarf2_per_objfile->signatured_types = allocate_signatured_type_table ();
find_entry.signature = dwo_unit->signature;
slot = htab_find_slot (dwarf2_per_objfile->signatured_types.get (),
objfile_name (objfile));
}
- dwarf2_per_objfile->reading_partial_symbols = 1;
+ scoped_restore restore_reading_psyms
+ = make_scoped_restore (&dwarf2_per_objfile->reading_partial_symbols,
+ true);
dwarf2_per_objfile->info.read (objfile);
= dpo_backlink->has_section_at_zero;
}
- dwarf2_per_objfile->reading_partial_symbols = 0;
-
expand_psymtab (objfile);
process_cu_includes (dwarf2_per_objfile);
process_full_type_unit still needs to know if this is the first
time. */
- tu_group->num_symtabs = line_header->file_names_size ();
- tu_group->symtabs = XNEWVEC (struct symtab *,
- line_header->file_names_size ());
+ tu_group->symtabs
+ = XOBNEWVEC (&COMPUNIT_OBJFILE (cust)->objfile_obstack,
+ struct symtab *, line_header->file_names_size ());
auto &file_names = line_header->file_names ();
for (i = 0; i < file_names.size (); ++i)
/* Allocate a hash table for DWO files. */
static htab_up
-allocate_dwo_file_hash_table (struct objfile *objfile)
+allocate_dwo_file_hash_table ()
{
auto delete_dwo_file = [] (void *item)
{
void **slot;
if (dwarf2_per_objfile->dwo_files == NULL)
- dwarf2_per_objfile->dwo_files
- = allocate_dwo_file_hash_table (dwarf2_per_objfile->objfile);
+ dwarf2_per_objfile->dwo_files = allocate_dwo_file_hash_table ();
find_entry.dwo_name = dwo_name;
find_entry.comp_dir = comp_dir;
There is one of these tables for each of CUs,TUs for each DWO file. */
static htab_up
-allocate_dwo_unit_table (struct objfile *objfile)
+allocate_dwo_unit_table ()
{
/* Start out with a pretty small number.
Generally DWO files contain only one CU and maybe some TUs. */
continue;
if (cus_htab == NULL)
- cus_htab = allocate_dwo_unit_table (objfile);
+ cus_htab = allocate_dwo_unit_table ();
dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
*dwo_unit = read_unit;
/* Allocate a hash table for dwp_file loaded CUs/TUs. */
static htab_up
-allocate_dwp_loaded_cutus_table (struct objfile *objfile)
+allocate_dwp_loaded_cutus_table ()
{
return htab_up (htab_create_alloc (3,
hash_dwp_loaded_cutus,
dwarf2_locate_v2_dwp_sections,
dwp_file.get ());
- dwp_file->loaded_cus = allocate_dwp_loaded_cutus_table (objfile);
- dwp_file->loaded_tus = allocate_dwp_loaded_cutus_table (objfile);
+ dwp_file->loaded_cus = allocate_dwp_loaded_cutus_table ();
+ dwp_file->loaded_tus = allocate_dwp_loaded_cutus_table ();
if (dwarf_read_debug)
{
struct die_info *child_die;
int unsigned_enum = 1;
int flag_enum = 1;
- ULONGEST mask = 0;
auto_obstack obstack;
{
if (count_one_bits_ll (value) >= 2)
flag_enum = 0;
- else if ((mask & value) != 0)
- flag_enum = 0;
- else
- mask |= value;
}
/* If we already know that the enum type is neither unsigned, nor
return read_addr_index (cu, addr_index);
}
-/* Given an index in .debug_addr, fetch the value.
- NOTE: This can be called during dwarf expression evaluation,
- long after the debug information has been read, and thus per_cu->cu
- may no longer exist. */
+/* See read.h. */
CORE_ADDR
-dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu,
- unsigned int addr_index)
+dwarf2_read_addr_index (dwarf2_per_cu_data *per_cu, unsigned int addr_index)
{
struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
struct dwarf2_cu *cu = per_cu->cu;
{
gdb::unique_xmalloc_ptr<char> demangled
(gdb_demangle (DW_STRING (attr), DMGL_TYPES));
+ if (demangled == nullptr)
+ return nullptr;
const char *base;
return die;
}
-/* Return DWARF block referenced by DW_AT_location of DIE at SECT_OFF at PER_CU.
- Returned value is intended for DW_OP_call*. Returned
- dwarf2_locexpr_baton->data has lifetime of
- PER_CU->DWARF2_PER_OBJFILE->OBJFILE. */
+/* See read.h. */
struct dwarf2_locexpr_baton
dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
- struct dwarf2_per_cu_data *per_cu,
+ dwarf2_per_cu_data *per_cu,
CORE_ADDR (*get_frame_pc) (void *baton),
void *baton, bool resolve_abstract_p)
{
return retval;
}
-/* Like dwarf2_fetch_die_loc_sect_off, but take a CU
- offset. */
+/* See read.h. */
struct dwarf2_locexpr_baton
dwarf2_fetch_die_loc_cu_off (cu_offset offset_in_cu,
- struct dwarf2_per_cu_data *per_cu,
+ dwarf2_per_cu_data *per_cu,
CORE_ADDR (*get_frame_pc) (void *baton),
void *baton)
{
return result;
}
-/* If the DIE at OFFSET in PER_CU has a DW_AT_const_value, return a
- pointer to the constant bytes and set LEN to the length of the
- data. If memory is needed, allocate it on OBSTACK. If the DIE
- does not have a DW_AT_const_value, return NULL. */
+/* See read.h. */
const gdb_byte *
dwarf2_fetch_constant_bytes (sect_offset sect_off,
- struct dwarf2_per_cu_data *per_cu,
- struct obstack *obstack,
+ dwarf2_per_cu_data *per_cu,
+ obstack *obstack,
LONGEST *len)
{
struct dwarf2_cu *cu;
return result;
}
-/* Return the type of the die at OFFSET in PER_CU. Return NULL if no
- valid type for this die is found. */
+/* See read.h. */
struct type *
dwarf2_fetch_die_type_sect_off (sect_offset sect_off,
- struct dwarf2_per_cu_data *per_cu)
+ dwarf2_per_cu_data *per_cu)
{
struct dwarf2_cu *cu;
struct die_info *die;
return die_type (die, cu);
}
-/* Return the type of the DIE at DIE_OFFSET in the CU named by
- PER_CU. */
+/* See read.h. */
struct type *
dwarf2_get_die_type (cu_offset die_offset,
struct signatured_type *sig_type;
/* Caller is responsible for ensuring type_unit_groups don't get here. */
- gdb_assert (! IS_TYPE_UNIT_GROUP (per_cu));
+ gdb_assert (! per_cu->type_unit_group_p ());
/* We have the per_cu, but we need the signatured_type.
Fortunately this is an easy translation. */
return addr_type;
}
-/* Locate the .debug_info compilation unit from CU's objfile which contains
- the DIE at OFFSET. Raises an error on failure. */
+/* A helper function for dwarf2_find_containing_comp_unit that returns
+ the index of the result, and that searches a vector. It will
+ return a result even if the offset in question does not actually
+ occur in any CU. This is separate so that it can be unit
+ tested. */
-static struct dwarf2_per_cu_data *
-dwarf2_find_containing_comp_unit (sect_offset sect_off,
- unsigned int offset_in_dwz,
- struct dwarf2_per_objfile *dwarf2_per_objfile)
+static int
+dwarf2_find_containing_comp_unit
+ (sect_offset sect_off,
+ unsigned int offset_in_dwz,
+ const std::vector<dwarf2_per_cu_data *> &all_comp_units)
{
- struct dwarf2_per_cu_data *this_cu;
int low, high;
low = 0;
- high = dwarf2_per_objfile->all_comp_units.size () - 1;
+ high = all_comp_units.size () - 1;
while (high > low)
{
struct dwarf2_per_cu_data *mid_cu;
int mid = low + (high - low) / 2;
- mid_cu = dwarf2_per_objfile->all_comp_units[mid];
+ mid_cu = all_comp_units[mid];
if (mid_cu->is_dwz > offset_in_dwz
|| (mid_cu->is_dwz == offset_in_dwz
- && mid_cu->sect_off + mid_cu->length >= sect_off))
+ && mid_cu->sect_off + mid_cu->length > sect_off))
high = mid;
else
low = mid + 1;
}
gdb_assert (low == high);
- this_cu = dwarf2_per_objfile->all_comp_units[low];
+ return low;
+}
+
+/* Locate the .debug_info compilation unit from CU's objfile which contains
+ the DIE at OFFSET. Raises an error on failure. */
+
+static struct dwarf2_per_cu_data *
+dwarf2_find_containing_comp_unit (sect_offset sect_off,
+ unsigned int offset_in_dwz,
+ struct dwarf2_per_objfile *dwarf2_per_objfile)
+{
+ int low
+ = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
+ dwarf2_per_objfile->all_comp_units);
+ struct dwarf2_per_cu_data *this_cu
+ = dwarf2_per_objfile->all_comp_units[low];
+
if (this_cu->is_dwz != offset_in_dwz || this_cu->sect_off > sect_off)
{
if (low == 0 || this_cu->is_dwz != offset_in_dwz)
}
}
+#if GDB_SELF_TEST
+
+namespace selftests {
+namespace find_containing_comp_unit {
+
+static void
+run_test ()
+{
+ struct dwarf2_per_cu_data one {};
+ struct dwarf2_per_cu_data two {};
+ struct dwarf2_per_cu_data three {};
+ struct dwarf2_per_cu_data four {};
+
+ one.length = 5;
+ two.sect_off = sect_offset (one.length);
+ two.length = 7;
+
+ three.length = 5;
+ three.is_dwz = 1;
+ four.sect_off = sect_offset (three.length);
+ four.length = 7;
+ four.is_dwz = 1;
+
+ std::vector<dwarf2_per_cu_data *> units;
+ units.push_back (&one);
+ units.push_back (&two);
+ units.push_back (&three);
+ units.push_back (&four);
+
+ int result;
+
+ result = dwarf2_find_containing_comp_unit (sect_offset (0), 0, units);
+ SELF_CHECK (units[result] == &one);
+ result = dwarf2_find_containing_comp_unit (sect_offset (3), 0, units);
+ SELF_CHECK (units[result] == &one);
+ result = dwarf2_find_containing_comp_unit (sect_offset (5), 0, units);
+ SELF_CHECK (units[result] == &two);
+
+ result = dwarf2_find_containing_comp_unit (sect_offset (0), 1, units);
+ SELF_CHECK (units[result] == &three);
+ result = dwarf2_find_containing_comp_unit (sect_offset (3), 1, units);
+ SELF_CHECK (units[result] == &three);
+ result = dwarf2_find_containing_comp_unit (sect_offset (5), 1, units);
+ SELF_CHECK (units[result] == &four);
+}
+
+}
+}
+
+#endif /* GDB_SELF_TEST */
+
/* Initialize dwarf2_cu CU, owned by PER_CU. */
dwarf2_cu::dwarf2_cu (struct dwarf2_per_cu_data *per_cu_)
#if GDB_SELF_TEST
selftests::register_test ("dw2_expand_symtabs_matching",
selftests::dw2_expand_symtabs_matching::run_test);
+ selftests::register_test ("dwarf2_find_containing_comp_unit",
+ selftests::find_containing_comp_unit::run_test);
#endif
}