#include "gdbsupport/selftest.h"
#include "rust-lang.h"
#include "gdbsupport/pathstuff.h"
+#include "count-one-bits.h"
/* When == 1, print basic high level tracing messages.
When > 1, be more verbose.
/* 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
cutu_reader (struct dwarf2_per_cu_data *this_cu,
struct abbrev_table *abbrev_table,
- int use_existing_cu, int keep,
+ int use_existing_cu,
bool skip_partial);
explicit cutu_reader (struct dwarf2_per_cu_data *this_cu,
struct dwarf2_cu *parent_cu = nullptr,
struct dwo_file *dwo_file = nullptr);
- ~cutu_reader ();
-
DISABLE_COPY_AND_ASSIGN (cutu_reader);
const gdb_byte *info_ptr = nullptr;
struct die_info *comp_unit_die = nullptr;
bool dummy_p = false;
+ /* Release the new CU, putting it on the chain. This cannot be done
+ for dummy CUs. */
+ void keep ();
+
private:
void init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
- int use_existing_cu, int keep);
+ int use_existing_cu);
struct dwarf2_per_cu_data *m_this_cu;
- int m_keep = 0;
std::unique_ptr<dwarf2_cu> m_new_cu;
/* The ordinary abbreviation table. */
(struct dwarf2_per_objfile *dwarf2_per_objfile,
struct dwarf2_section_info *, sect_offset);
-static const gdb_byte *read_n_bytes (bfd *, const gdb_byte *, unsigned int);
-
-static const char *read_direct_string (bfd *, const gdb_byte *, unsigned int *);
-
static const char *read_indirect_string
(struct dwarf2_per_objfile *dwarf2_per_objfile, bfd *, const gdb_byte *,
const struct comp_unit_head *, unsigned int *);
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 (),
void
cutu_reader::init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
- int use_existing_cu, int keep)
+ int use_existing_cu)
{
struct signatured_type *sig_type;
struct die_reader_specs reader;
This is an optimization for when we already have the abbrev table.
If USE_EXISTING_CU is non-zero, and THIS_CU->cu is non-NULL, then use it.
- Otherwise, a new CU is allocated with xmalloc.
-
- If KEEP is non-zero, then if we allocated a dwarf2_cu we add it to
- read_in_chain. Otherwise the dwarf2_cu data is freed at the
- end. */
+ Otherwise, a new CU is allocated with xmalloc. */
cutu_reader::cutu_reader (struct dwarf2_per_cu_data *this_cu,
struct abbrev_table *abbrev_table,
- int use_existing_cu, int keep,
+ int use_existing_cu,
bool skip_partial)
: die_reader_specs {},
- m_this_cu (this_cu),
- m_keep (keep)
+ m_this_cu (this_cu)
{
struct dwarf2_per_objfile *dwarf2_per_objfile = this_cu->dwarf2_per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
this_cu->is_debug_types ? "type" : "comp",
sect_offset_str (this_cu->sect_off));
- if (use_existing_cu)
- gdb_assert (keep);
-
/* If we're reading a TU directly from a DWO file, including a virtual DWO
file (instead of going through the stub), short-circuit all of this. */
if (this_cu->reading_dwo_directly)
/* Narrow down the scope of possibilities to have to understand. */
gdb_assert (this_cu->is_debug_types);
gdb_assert (abbrev_table == NULL);
- init_tu_and_read_dwo_dies (this_cu, use_existing_cu, keep);
+ init_tu_and_read_dwo_dies (this_cu, use_existing_cu);
return;
}
}
}
-cutu_reader::~cutu_reader ()
+void
+cutu_reader::keep ()
{
/* Done, clean up. */
- if (m_new_cu != NULL && m_keep && !dummy_p)
+ gdb_assert (!dummy_p);
+ if (m_new_cu != NULL)
{
struct dwarf2_per_objfile *dwarf2_per_objfile
= m_this_cu->dwarf2_per_objfile;
/* 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? */
process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
const gdb_byte *info_ptr,
struct die_info *comp_unit_die,
- int want_partial_unit,
enum language pretend_language)
{
struct dwarf2_cu *cu = reader->cu;
enum pc_bounds_kind cu_bounds_kind;
const char *filename;
- if (comp_unit_die->tag == DW_TAG_partial_unit && !want_partial_unit)
- return;
-
gdb_assert (! per_cu->is_debug_types);
prepare_one_comp_unit (cu, comp_unit_die, pretend_language);
/* Allocate a new partial symbol table structure. */
+ gdb::unique_xmalloc_ptr<char> debug_filename;
+ static const char artificial[] = "<artificial>";
filename = dwarf2_string_attr (comp_unit_die, DW_AT_name, cu);
if (filename == NULL)
filename = "";
+ else if (strcmp (filename, artificial) == 0)
+ {
+ debug_filename.reset (concat (artificial, "@",
+ sect_offset_str (per_cu->sect_off),
+ (char *) NULL));
+ filename = debug_filename.get ();
+ }
pst = create_partial_symtab (per_cu, filename);
static void
process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu,
- int want_partial_unit,
+ bool want_partial_unit,
enum language pretend_language)
{
/* If this compilation unit was already read in, free the
if (this_cu->cu != NULL)
free_one_cached_comp_unit (this_cu);
- cutu_reader reader (this_cu, NULL, 0, 0, false);
+ cutu_reader reader (this_cu, NULL, 0, false);
if (reader.dummy_p)
{
else if (this_cu->is_debug_types)
build_type_psymtabs_reader (&reader, reader.info_ptr,
reader.comp_unit_die);
- else
+ else if (want_partial_unit
+ || reader.comp_unit_die->tag != DW_TAG_partial_unit)
process_psymtab_comp_unit_reader (&reader, reader.info_ptr,
reader.comp_unit_die,
- want_partial_unit,
pretend_language);
/* Age out any secondary CUs. */
}
cutu_reader reader (&tu.sig_type->per_cu, abbrev_table.get (),
- 0, 0, false);
+ 0, false);
if (!reader.dummy_p)
build_type_psymtabs_reader (&reader, reader.info_ptr,
reader.comp_unit_die);
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 (),
*slot = entry;
/* This does the job that build_type_psymtabs_1 would have done. */
- cutu_reader reader (&entry->per_cu, NULL, 0, 0, false);
+ cutu_reader reader (&entry->per_cu, NULL, 0, false);
if (!reader.dummy_p)
build_type_psymtabs_reader (&reader, reader.info_ptr,
reader.comp_unit_die);
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);
addrmap_create_mutable (&temp_obstack));
for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
- process_psymtab_comp_unit (per_cu, 0, language_minimal);
+ process_psymtab_comp_unit (per_cu, false, language_minimal);
/* This has to wait until we read the CUs, we need the list of DWOs. */
process_skeletonless_type_units (dwarf2_per_objfile);
static void
load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu)
{
- cutu_reader reader (this_cu, NULL, 1, 1, false);
+ cutu_reader reader (this_cu, NULL, 1, false);
if (!reader.dummy_p)
{
If not, there's no more debug_info for this comp unit. */
if (reader.comp_unit_die->has_children)
load_partial_dies (&reader, reader.info_ptr, 0);
+
+ reader.keep ();
}
}
/* Go read the partial unit, if needed. */
if (per_cu->v.psymtab == NULL)
- process_psymtab_comp_unit (per_cu, 1, cu->language);
+ process_psymtab_comp_unit (per_cu, true, cu->language);
cu->per_cu->imported_symtabs_push (per_cu);
}
= dpo_backlink->has_section_at_zero;
}
- dwarf2_per_objfile->reading_partial_symbols = 0;
-
expand_psymtab (objfile);
process_cu_includes (dwarf2_per_objfile);
{
gdb_assert (! this_cu->is_debug_types);
- cutu_reader reader (this_cu, NULL, 1, 1, skip_partial);
+ cutu_reader reader (this_cu, NULL, 1, skip_partial);
if (reader.dummy_p)
return;
Similarly, if we do not read the producer, we can not apply
producer-specific interpretation. */
prepare_one_comp_unit (cu, cu->dies, pretend_language);
+
+ reader.keep ();
}
/* Add a DIE to the delayed physname list. */
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;
unsigned_enum = 0;
flag_enum = 0;
}
- else if ((mask & value) != 0)
- flag_enum = 0;
else
- mask |= value;
+ {
+ if (count_one_bits_ll (value) >= 2)
+ flag_enum = 0;
+ }
/* If we already know that the enum type is neither unsigned, nor
a flag type, no need to look at the rest of the enumerates. */
return length;
}
-static const gdb_byte *
-read_n_bytes (bfd *abfd, const gdb_byte *buf, unsigned int size)
-{
- /* If the size of a host char is 8 bits, we can return a pointer
- to the buffer, otherwise we have to copy the data to a buffer
- allocated on the temporary obstack. */
- gdb_assert (HOST_CHAR_BIT == 8);
- return buf;
-}
-
-static const char *
-read_direct_string (bfd *abfd, const gdb_byte *buf,
- unsigned int *bytes_read_ptr)
-{
- /* If the size of a host char is 8 bits, we can return a pointer
- to the string, otherwise we have to copy the string to a buffer
- allocated on the temporary obstack. */
- gdb_assert (HOST_CHAR_BIT == 8);
- if (*buf == '\0')
- {
- *bytes_read_ptr = 1;
- return NULL;
- }
- *bytes_read_ptr = strlen ((const char *) buf) + 1;
- return (const char *) buf;
-}
-
/* Return pointer to string at section SECT offset STR_OFFSET with error
reporting strings FORM_NAME and SECT_NAME. */
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;
}
else
{
- cutu_reader reader (per_cu, NULL, 0, 0, false);
+ cutu_reader reader (per_cu, NULL, 0, false);
addr_base = reader.cu->addr_base;
addr_size = reader.cu->header.addr_size;
}
lnp_state_machine::handle_special_opcode (unsigned char op_code)
{
unsigned char adj_opcode = op_code - m_line_header->opcode_base;
- CORE_ADDR addr_adj = (((m_op_index
- + (adj_opcode / m_line_header->line_range))
+ unsigned char adj_opcode_d = adj_opcode / m_line_header->line_range;
+ unsigned char adj_opcode_r = adj_opcode % m_line_header->line_range;
+ CORE_ADDR addr_adj = (((m_op_index + adj_opcode_d)
/ m_line_header->maximum_ops_per_instruction)
* m_line_header->minimum_instruction_length);
m_address += gdbarch_adjust_dwarf2_line (m_gdbarch, addr_adj, true);
- m_op_index = ((m_op_index + (adj_opcode / m_line_header->line_range))
+ m_op_index = ((m_op_index + adj_opcode_d)
% m_line_header->maximum_ops_per_instruction);
- int line_delta = (m_line_header->line_base
- + (adj_opcode % m_line_header->line_range));
+ int line_delta = m_line_header->line_base + adj_opcode_r;
advance_line (line_delta);
record_line (false);
m_discriminator = 0;
{
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. */
gdb_assert (per_cu->is_debug_types);
gdb_assert (per_cu->cu == NULL);
- cutu_reader reader (per_cu, NULL, 0, 1, false);
+ cutu_reader reader (per_cu, NULL, 0, false);
if (!reader.dummy_p)
{
correctly. Similarly, if we do not read the producer, we can
not apply producer-specific interpretation. */
prepare_one_comp_unit (cu, cu->dies, language_minimal);
+
+ reader.keep ();
}
sig_type->per_cu.tu_read = 1;
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
}