aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/dwarf2/read.c')
-rw-r--r--gdb/dwarf2/read.c382
1 files changed, 239 insertions, 143 deletions
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 634d67a..ec8d376 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1690,6 +1690,7 @@ dwarf2_per_bfd::allocate_per_cu (dwarf2_section_info *section,
dwarf2_per_cu_up result (new dwarf2_per_cu (this, section, sect_off,
length, is_dwz));
result->index = all_units.size ();
+ this->num_comp_units++;
return result;
}
@@ -1706,7 +1707,7 @@ dwarf2_per_bfd::allocate_signatured_type (dwarf2_section_info *section,
= std::make_unique<signatured_type> (this, section, sect_off, length,
is_dwz, signature);
result->index = all_units.size ();
- tu_stats.nr_tus++;
+ this->num_type_units++;
return result;
}
@@ -2370,6 +2371,24 @@ get_abbrev_section_for_cu (dwarf2_per_cu *this_cu)
return abbrev;
}
+/* "less than" function used to both sort and bisect units in the
+ `dwarf2_per_bfd::all_units` vector. Return true if the LHS CU comes before
+ (is "less" than) the section and offset in RHS.
+
+ For simplicity, sort sections by their pointer. This is not ideal, because
+ it can cause the behavior to change across runs, making some bugs harder to
+ investigate. An improvement would be for sections to be sorted by their
+ properties. */
+
+static bool
+all_units_less_than (const dwarf2_per_cu &lhs, const section_and_offset &rhs)
+{
+ if (lhs.section != rhs.section)
+ return lhs.section < rhs.section;
+
+ return lhs.sect_off < rhs.offset;
+}
+
/* Fetch the abbreviation table offset from a comp or type unit header. */
static sect_offset
@@ -2413,7 +2432,17 @@ add_type_unit (dwarf2_per_bfd *per_bfd, dwarf2_section_info *section,
false /* is_dwz */, sig);
signatured_type *sig_type = sig_type_holder.get ();
- per_bfd->all_units.emplace_back (sig_type_holder.release ());
+ /* Preserve the ordering of per_bfd->all_units. */
+ auto insert_it
+ = std::lower_bound (per_bfd->all_units.begin (), per_bfd->all_units.end (),
+ sig_type,
+ [] (const dwarf2_per_cu_up &lhs,
+ const signatured_type *rhs) {
+ return all_units_less_than (*lhs, { rhs->section,
+ rhs->sect_off });
+ });
+
+ per_bfd->all_units.emplace (insert_it, sig_type_holder.release ());
auto emplace_ret = per_bfd->signatured_types.emplace (sig_type);
/* Assert that an insertion took place - that there wasn't a type unit with
@@ -3212,10 +3241,11 @@ private:
void print_tu_stats (dwarf2_per_objfile *per_objfile)
{
- struct tu_stats *tu_stats = &per_objfile->per_bfd->tu_stats;
+ dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
+ tu_stats *tu_stats = &per_bfd->tu_stats;
dwarf_read_debug_printf ("Type unit statistics:");
- dwarf_read_debug_printf (" %d TUs", tu_stats->nr_tus);
+ dwarf_read_debug_printf (" %d TUs", per_bfd->num_type_units);
dwarf_read_debug_printf (" %d uniq abbrev tables",
tu_stats->nr_uniq_abbrev_tables);
dwarf_read_debug_printf (" %d symtabs from stmt_list entries",
@@ -3365,7 +3395,7 @@ cooked_index_worker_debug_info::process_type_units
abbrev_table_up abbrev_table;
sect_offset abbrev_offset;
- if (per_objfile->per_bfd->all_type_units.size () == 0)
+ if (per_objfile->per_bfd->num_type_units == 0)
return;
/* TUs typically share abbrev tables, and there can be way more TUs than
@@ -3392,7 +3422,7 @@ cooked_index_worker_debug_info::process_type_units
/* Sort in a separate table to maintain the order of all_units
for .gdb_index: TU indices directly index all_type_units. */
std::vector<tu_abbrev_offset> sorted_by_abbrev;
- sorted_by_abbrev.reserve (per_objfile->per_bfd->all_type_units.size ());
+ sorted_by_abbrev.reserve (per_objfile->per_bfd->num_type_units);
for (const auto &cu : per_objfile->per_bfd->all_units)
if (cu->is_debug_types)
@@ -3644,16 +3674,18 @@ read_comp_units_from_section (dwarf2_per_objfile *per_objfile,
}
}
-/* Initialize the views on all_units. */
+/* See read.h. */
void
finalize_all_units (dwarf2_per_bfd *per_bfd)
{
- size_t nr_tus = per_bfd->tu_stats.nr_tus;
- size_t nr_cus = per_bfd->all_units.size () - nr_tus;
- gdb::array_view<dwarf2_per_cu_up> tmp = per_bfd->all_units;
- per_bfd->all_comp_units = tmp.slice (0, nr_cus);
- per_bfd->all_type_units = tmp.slice (nr_cus, nr_tus);
+ /* Ensure that the all_units vector is in the expected order for
+ dwarf2_find_containing_unit to be able to perform a binary search. */
+ std::sort (per_bfd->all_units.begin (), per_bfd->all_units.end (),
+ [] (const dwarf2_per_cu_up &a, const dwarf2_per_cu_up &b)
+ {
+ return all_units_less_than (*a, { b->section, b->sect_off });
+ });
}
/* See read.h. */
@@ -4909,6 +4941,21 @@ process_full_type_unit (dwarf2_cu *cu)
cu->reset_builder ();
}
+/* See read.h. */
+
+const dwarf2_section_info &
+get_section_for_ref (const attribute &attr, dwarf2_cu *cu)
+{
+ gdb_assert (attr.form_is_ref ());
+
+ if (attr.form_is_alt ())
+ return cu->per_cu->per_bfd->get_dwz_file (true)->info;
+
+ /* If the source is already in the supplementary (dwz) file, then CU->SECTION
+ already represents the section in the supplementary file. */
+ return cu->section ();
+}
+
/* Process an imported unit DIE. */
static void
@@ -4928,12 +4975,11 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
attr = dwarf2_attr (die, DW_AT_import, cu);
if (attr != NULL)
{
+ const dwarf2_section_info &section = get_section_for_ref (*attr, cu);
sect_offset sect_off = attr->get_ref_die_offset ();
- bool is_dwz = attr->form_is_alt () || cu->per_cu->is_dwz;
dwarf2_per_objfile *per_objfile = cu->per_objfile;
dwarf2_per_cu *per_cu
- = dwarf2_find_containing_comp_unit (sect_off, is_dwz,
- per_objfile->per_bfd);
+ = dwarf2_find_containing_unit ({ &section, sect_off }, per_objfile);
/* We're importing a C++ compilation unit with tag DW_TAG_compile_unit
into another compilation unit, at root level. Regard this as a hint,
@@ -6054,6 +6100,20 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
}
}
+/* See cu.h.
+
+ This function is defined in this file (instead of cu.c) because it needs
+ to see the definition of struct dwo_unit. */
+
+const dwarf2_section_info &
+dwarf2_cu::section () const
+{
+ if (this->dwo_unit != nullptr)
+ return *this->dwo_unit->section;
+ else
+ return *this->per_cu->section;
+}
+
void
dwarf2_cu::setup_type_unit_groups (struct die_info *die)
{
@@ -17472,9 +17532,10 @@ lookup_die_type (struct die_info *die, const struct attribute *attr,
if (attr->form_is_alt ())
{
+ const auto &section = get_section_for_ref (*attr, cu);
sect_offset sect_off = attr->get_ref_die_offset ();
dwarf2_per_cu *per_cu
- = dwarf2_find_containing_comp_unit (sect_off, 1, per_objfile->per_bfd);
+ = dwarf2_find_containing_unit ({ &section, sect_off }, per_objfile);
this_type = get_die_type_at_offset (sect_off, per_cu, per_objfile);
}
@@ -18175,14 +18236,13 @@ follow_die_ref_or_sig (struct die_info *src_die, const struct attribute *attr,
return die;
}
-/* Follow reference OFFSET.
- On entry *REF_CU is the CU of the source die referencing OFFSET.
+/* Follow reference TARGET.
+ On entry *REF_CU is the CU of the source die referencing TARGET.
On exit *REF_CU is the CU of the result.
- Returns NULL if OFFSET is invalid. */
+ Returns nullptr if TARGET is invalid. */
-static struct die_info *
-follow_die_offset (sect_offset sect_off, int offset_in_dwz,
- struct dwarf2_cu **ref_cu)
+static die_info *
+follow_die_offset (const section_and_offset &target, dwarf2_cu **ref_cu)
{
dwarf2_cu *source_cu = *ref_cu;
dwarf2_cu *target_cu = source_cu;
@@ -18194,23 +18254,23 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz,
dwarf_read_debug_printf_v ("source CU offset: %s, target offset: %s, "
"source CU contains target offset: %d",
sect_offset_str (source_cu->per_cu->sect_off),
- sect_offset_str (sect_off),
- source_cu->header.offset_in_unit_p (sect_off));
+ sect_offset_str (target.offset),
+ (target.section == &source_cu->section ()
+ && source_cu->header.offset_in_unit_p (target.offset)));
if (source_cu->per_cu->is_debug_types)
{
/* .debug_types CUs cannot reference anything outside their CU.
If they need to, they have to reference a signatured type via
DW_FORM_ref_sig8. */
- if (!source_cu->header.offset_in_unit_p (sect_off))
+ if (!source_cu->header.offset_in_unit_p (target.offset))
return NULL;
}
- else if (offset_in_dwz != source_cu->per_cu->is_dwz
- || !source_cu->header.offset_in_unit_p (sect_off))
+ else if (target.section != &source_cu->section ()
+ || !source_cu->header.offset_in_unit_p (target.offset))
{
dwarf2_per_cu *target_per_cu
- = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
- per_objfile->per_bfd);
+ = dwarf2_find_containing_unit (target, per_objfile);
dwarf_read_debug_printf_v ("target CU offset: %s, "
"target CU DIEs loaded: %d",
@@ -18232,13 +18292,13 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz,
error (_(DWARF_ERROR_PREFIX
"cannot follow reference to DIE at %s"
" [in module %s]"),
- sect_offset_str (sect_off),
+ sect_offset_str (target.offset),
objfile_name (per_objfile->objfile));
}
*ref_cu = target_cu;
- return target_cu->find_die (sect_off);
+ return target_cu->find_die (target.offset);
}
/* Follow reference attribute ATTR of SRC_DIE.
@@ -18250,8 +18310,7 @@ follow_die_ref (struct die_info *src_die, const struct attribute *attr,
struct dwarf2_cu **ref_cu)
{
sect_offset sect_off = attr->get_ref_die_offset ();
- struct dwarf2_cu *cu = *ref_cu;
- struct die_info *die;
+ struct dwarf2_cu *src_cu = *ref_cu;
if (!attr->form_is_alt () && src_die->sect_off == sect_off)
{
@@ -18259,14 +18318,13 @@ follow_die_ref (struct die_info *src_die, const struct attribute *attr,
return src_die;
}
- die = follow_die_offset (sect_off,
- attr->form_is_alt () || cu->per_cu->is_dwz,
- ref_cu);
- if (!die)
+ const dwarf2_section_info &section = get_section_for_ref (*attr, src_cu);
+ die_info *die = follow_die_offset ({ &section, sect_off }, ref_cu);
+ if (die == nullptr)
error (_(DWARF_ERROR_PREFIX
"Cannot find DIE at %s referenced from DIE at %s [in module %s]"),
sect_offset_str (sect_off), sect_offset_str (src_die->sect_off),
- objfile_name (cu->per_objfile->objfile));
+ objfile_name (src_cu->per_objfile->objfile));
return die;
}
@@ -18279,7 +18337,6 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off, dwarf2_per_cu *per_cu,
gdb::function_view<CORE_ADDR ()> get_frame_pc,
bool resolve_abstract_p)
{
- struct die_info *die;
struct attribute *attr;
struct dwarf2_locexpr_baton retval;
struct objfile *objfile = per_objfile->objfile;
@@ -18297,8 +18354,8 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off, dwarf2_per_cu *per_cu,
sect_offset_str (sect_off), objfile_name (objfile));
}
- die = follow_die_offset (sect_off, per_cu->is_dwz, &cu);
- if (!die)
+ die_info *die = follow_die_offset ({ &cu->section (), sect_off }, &cu);
+ if (die == nullptr)
error (_(DWARF_ERROR_PREFIX
"Cannot find DIE at %s referenced [in module %s]"),
sect_offset_str (sect_off), objfile_name (objfile));
@@ -18314,8 +18371,8 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off, dwarf2_per_cu *per_cu,
: per_objfile->per_bfd->abstract_to_concrete[die->sect_off])
{
struct dwarf2_cu *cand_cu = cu;
- struct die_info *cand
- = follow_die_offset (cand_off, per_cu->is_dwz, &cand_cu);
+ die_info *cand
+ = follow_die_offset ({ &cu->section (), cand_off }, &cand_cu);
if (!cand
|| !cand->parent
|| cand->parent->tag != DW_TAG_subprogram)
@@ -18417,7 +18474,6 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
obstack *obstack,
LONGEST *len)
{
- struct die_info *die;
struct attribute *attr;
const gdb_byte *result = NULL;
struct type *type;
@@ -18438,7 +18494,7 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
sect_offset_str (sect_off), objfile_name (objfile));
}
- die = follow_die_offset (sect_off, per_cu->is_dwz, &cu);
+ die_info *die = follow_die_offset ({ &cu->section (), sect_off }, &cu);
if (!die)
error (_(DWARF_ERROR_PREFIX
"Cannot find DIE at %s referenced [in module %s]"),
@@ -18528,8 +18584,6 @@ dwarf2_fetch_die_type_sect_off (sect_offset sect_off, dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile,
const char **var_name)
{
- struct die_info *die;
-
dwarf2_cu *cu = per_objfile->get_cu (per_cu);
if (cu == nullptr)
cu = load_cu (per_cu, per_objfile, false);
@@ -18537,7 +18591,7 @@ dwarf2_fetch_die_type_sect_off (sect_offset sect_off, dwarf2_per_cu *per_cu,
if (cu == nullptr)
return nullptr;
- die = follow_die_offset (sect_off, per_cu->is_dwz, &cu);
+ die_info *die = follow_die_offset ({ &cu->section (), sect_off }, &cu);
if (!die)
return NULL;
@@ -19287,69 +19341,115 @@ dwarf2_per_cu::ensure_lang (dwarf2_per_objfile *per_objfile)
true, language_minimal, nullptr);
}
-/* 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. */
+/* Return the unit from ALL_UNITS that potentially contains TARGET.
-static int
-dwarf2_find_containing_comp_unit
- (sect_offset sect_off,
- unsigned int offset_in_dwz,
- const std::vector<dwarf2_per_cu_up> &all_units)
+ Since the unit lengths may not be known yet, this function doesn't check that
+ TARGET.OFFSET actually falls within the range of the returned unit. The
+ caller is responsible for this.
+
+ If no units possibly match TARGET, return nullptr. */
+
+static dwarf2_per_cu *
+dwarf2_find_containing_unit (const section_and_offset &target,
+ const std::vector<dwarf2_per_cu_up> &all_units)
{
- int low, high;
+ auto it = std::lower_bound (all_units.begin (), all_units.end (), target,
+ [] (const dwarf2_per_cu_up &per_cu,
+ const section_and_offset &key)
+ {
+ return all_units_less_than (*per_cu, key);
+ });
- low = 0;
- high = all_units.size () - 1;
- while (high > low)
+ if (it == all_units.begin ())
{
- int mid = low + (high - low) / 2;
- dwarf2_per_cu *mid_cu = all_units[mid].get ();
-
- if (mid_cu->is_dwz > offset_in_dwz
- || (mid_cu->is_dwz == offset_in_dwz
- && mid_cu->sect_off + mid_cu->length () > sect_off))
- high = mid;
+ /* TARGET falls before the first unit of the first section, or is an
+ exact match with the first. */
+ if ((*it)->section == target.section && (*it)->sect_off == target.offset)
+ return it->get ();
else
- low = mid + 1;
+ return nullptr;
+ }
+
+ if (it != all_units.end ()
+ && (*it)->section == target.section
+ && (*it)->sect_off == target.offset)
+ {
+ /* TARGET is an exact match with the start of *IT, so *IT is what we're
+ looking for. */
+ return it->get ();
}
- gdb_assert (low == high);
- return low;
+
+ /* Otherwise, the match is the one just before, as long as it matches the
+ section we're looking for. */
+ --it;
+
+ if ((*it)->section == target.section)
+ return it->get ();
+
+ return nullptr;
}
/* See read.h. */
dwarf2_per_cu *
-dwarf2_find_containing_comp_unit (sect_offset sect_off,
- unsigned int offset_in_dwz,
- dwarf2_per_bfd *per_bfd)
+dwarf2_find_containing_unit (const section_and_offset &target,
+ dwarf2_per_objfile *per_objfile)
{
- int low = dwarf2_find_containing_comp_unit
- (sect_off, offset_in_dwz, per_bfd->all_units);
- dwarf2_per_cu *this_cu = per_bfd->all_units[low].get ();
-
- if (this_cu->is_dwz != offset_in_dwz || this_cu->sect_off > sect_off)
+ dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
+ dwarf2_per_cu *per_cu
+ = dwarf2_find_containing_unit (target, per_bfd->all_units);
+ auto error_out = [&target, per_bfd] ()
{
- if (low == 0 || this_cu->is_dwz != offset_in_dwz)
- error (_(DWARF_ERROR_PREFIX
- "could not find CU containing offset %s [in module %s]"),
- sect_offset_str (sect_off),
- per_bfd->filename ());
+ error (_(DWARF_ERROR_PREFIX
+ "could not find unit containing offset %s [in module %s]"),
+ sect_offset_str (target.offset), per_bfd->filename ());
+ };
- gdb_assert (per_bfd->all_units[low-1]->sect_off
- <= sect_off);
- return per_bfd->all_units[low - 1].get ();
- }
- else
- {
- if (low == per_bfd->all_units.size () - 1
- && sect_off >= this_cu->sect_off + this_cu->length ())
- error (_("invalid dwarf2 offset %s"), sect_offset_str (sect_off));
- gdb_assert (sect_off < this_cu->sect_off + this_cu->length ());
- return this_cu;
- }
+ if (per_cu == nullptr)
+ error_out ();
+
+ gdb_assert (per_cu->section == target.section);
+
+ /* Some producers of dwarf2_per_cu objects (thinking of the .gdb_index reader)
+ do not set the length ahead of time. The length is needed to check if
+ the target is truly within PER_CU's range, so compute it now. Constructing
+ the cutu_reader object has the side-effect of setting PER_CU's length.
+ Even though it should happen too often, it could be replaced with
+ something more lightweight that has the same effect. */
+ if (!per_cu->length_is_set ())
+ cutu_reader (*per_cu, *per_objfile, nullptr, nullptr, false,
+ language_minimal);
+
+ /* Now we can check if the target section offset is within PER_CU's range. */
+ if (target.offset < per_cu->sect_off
+ || target.offset >= per_cu->sect_off + per_cu->length ())
+ error_out ();
+
+ return per_cu;
+}
+
+/* See read.h. */
+
+dwarf2_per_cu *
+dwarf2_find_unit (const section_and_offset &start, dwarf2_per_bfd *per_bfd)
+{
+ auto it = std::lower_bound (per_bfd->all_units.begin (),
+ per_bfd->all_units.end (), start,
+ [] (const dwarf2_per_cu_up &per_cu,
+ const section_and_offset &key)
+ {
+ return all_units_less_than (*per_cu, key);
+ });
+
+ if (it == per_bfd->all_units.end ())
+ return nullptr;
+
+ dwarf2_per_cu *per_cu = it->get ();
+
+ if (per_cu->section != start.section || per_cu->sect_off != start.offset)
+ return nullptr;
+
+ return per_cu;
}
#if GDB_SELF_TEST
@@ -19360,59 +19460,55 @@ namespace find_containing_comp_unit {
static void
run_test ()
{
- char dummy_per_bfd;
- char dummy_section;
-
- const auto create_dummy_per_cu = [&] (sect_offset sect_off,
- unsigned int length,
- bool is_dwz)
- {
- auto per_bfd = reinterpret_cast<dwarf2_per_bfd *> (&dummy_per_bfd);
- auto section = reinterpret_cast<dwarf2_section_info *> (&dummy_section);
+ auto dummy_per_bfd = reinterpret_cast<dwarf2_per_bfd *> (0x3000);
+ auto &main_section = *reinterpret_cast<dwarf2_section_info *> (0x4000);
+ auto &dwz_section = *reinterpret_cast<dwarf2_section_info *> (0x5000);
+ std::vector<dwarf2_per_cu_up> units;
- return dwarf2_per_cu_up (new dwarf2_per_cu (per_bfd, section, sect_off,
- length, is_dwz));
+ /* Create one dummy unit, append it to UNITS, return a non-owning
+ reference. */
+ auto create_dummy_per_unit = [&] (dwarf2_section_info &section,
+ unsigned int sect_off, bool is_dwz)
+ -> dwarf2_per_cu &
+ {
+ /* Omit the length, because dwarf2_find_containing_unit does not consider
+ it. */
+ return *units.emplace_back (new dwarf2_per_cu (dummy_per_bfd, &section,
+ sect_offset (sect_off),
+ 0, is_dwz));
};
- /* Units in the main file. */
- dwarf2_per_cu_up one = create_dummy_per_cu (sect_offset (0), 5, false);
- dwarf2_per_cu *one_ptr = one.get ();
- dwarf2_per_cu_up two
- = create_dummy_per_cu (sect_offset (one->length ()), 7, false);
- dwarf2_per_cu *two_ptr = two.get ();
-
- /* Units in the supplementary (dwz) file. */
- dwarf2_per_cu_up three = create_dummy_per_cu (sect_offset (0), 5, true);
- dwarf2_per_cu *three_ptr = three.get ();
- dwarf2_per_cu_up four
- = create_dummy_per_cu (sect_offset (three->length ()), 7, true);
- dwarf2_per_cu *four_ptr = four.get ();
-
- std::vector<dwarf2_per_cu_up> units;
- units.push_back (std::move (one));
- units.push_back (std::move (two));
- units.push_back (std::move (three));
- units.push_back (std::move (four));
-
- int result;
+ /* Create 2 units in the main file and 2 units in the supplementary (dwz)
+ file. */
+ auto &main1 = create_dummy_per_unit (main_section, 10, false);
+ auto &main2 = create_dummy_per_unit (main_section, 20, false);
+ auto &dwz1 = create_dummy_per_unit (dwz_section, 10, false);
+ auto &dwz2 = create_dummy_per_unit (dwz_section, 20, false);
+
+ /* Check that looking up a unit at all offsets in the range [START,END[ in
+ section SECTION finds EXPECTED. */
+ auto check_range = [&units] (dwarf2_section_info &section, unsigned int start,
+ unsigned int end, dwarf2_per_cu *expected)
+ {
+ for (unsigned int sect_off = start; sect_off < end; ++sect_off)
+ {
+ section_and_offset target { &section, sect_offset (sect_off) };
+ dwarf2_per_cu *result = dwarf2_find_containing_unit (target, units);
- result = dwarf2_find_containing_comp_unit (sect_offset (0), 0, units);
- SELF_CHECK (units[result].get () == one_ptr);
- result = dwarf2_find_containing_comp_unit (sect_offset (3), 0, units);
- SELF_CHECK (units[result].get () == one_ptr);
- result = dwarf2_find_containing_comp_unit (sect_offset (5), 0, units);
- SELF_CHECK (units[result].get () == two_ptr);
+ SELF_CHECK (result == expected);
+ }
+ };
- result = dwarf2_find_containing_comp_unit (sect_offset (0), 1, units);
- SELF_CHECK (units[result].get () == three_ptr);
- result = dwarf2_find_containing_comp_unit (sect_offset (3), 1, units);
- SELF_CHECK (units[result].get () == three_ptr);
- result = dwarf2_find_containing_comp_unit (sect_offset (5), 1, units);
- SELF_CHECK (units[result].get () == four_ptr);
-}
+ check_range (main_section, 0, 10, nullptr);
+ check_range (main_section, 10, 20, &main1);
+ check_range (main_section, 20, 30, &main2);
+ check_range (dwz_section, 0, 10, nullptr);
+ check_range (dwz_section, 10, 20, &dwz1);
+ check_range (dwz_section, 20, 30, &dwz2);
}
-}
+} /* namespace find_containing_comp_unit */
+} /* namespace selftests */
#endif /* GDB_SELF_TEST */