I've added some read-side C++ support for rangelistptr attr values and for
aranges. The dwarf::range_list class is really just for the DW_AT_ranges
attr comparisons. debug_info_entry.ranges () is what things will use for
semantics (it uses dwarf_ranges, i.e. combining either ranges or lo/hi pc).
dwarf.aranges () is a slow, copying presentation of the aranges suitable
for comparing elements to a compile_unit.ranges (). I didn't make it a
thin reader because we won't really use this outside of dwarflint.
(The unit_by_addr, whenever I get to it, will be a thin layer on
dwarf.aranges () yields a map of compile_unit to arange_list.
arange_list and the other flavors from die.ranges () or attr_value.ranges ()
all act like set<pair<Dwarf_Addr, Dwarf_Addr>> (or unordered_set) for
templatey purposes. You can compare them to each other, and all have
a .to_string () for pretty-printing.
The comparisons canonicalize by coalescing contiguous adjacent ranges.
That is true for "semantically equal", and also notes for later what we can
do as an optimization in generating ranges and aranges for output. But
possibly one might want not to coalesce for dwarflint comparison, since
ranges/aranges not matching exactly from the generator seems suspicious.
Lots of tiny ranges that are actually adjacent and contiguous but generated
as many entries can be normal. It's especially common for C++ where
everything is in a zillion tiny little .gnu.linkonce sections. When the
program is finally linked, it all winds up in .text and packed in, so the
many entries have adjacent addresses and look superfluous. In fact they
are superfluous and we can coalesce them away for smaller .debug_aranges
sections. But they're not suspicious, since they made perfect sense as
emitted before the final link.
Another thing to note for output-side optimization is that it's common to
have many entries that are adjacent except for a gap of a few bytes. This
too is normal and correct as generated. The gaps are alignment bits in
.text between multiple entry points in a CU. It's correct precision to
leave the gaps there in DIE range lists. But .debug_aranges exists purely
for quick lookup of the containing CU. So when a gap that's not part of
any CU is small (i.e. less than sh_addralign of the section containing both
addresses), we can just coalesce across it so the addresses in the gap map
to the CU it's in the middle of. If someone is actually searching for the
gap addresses, they will just descend the CU and not find it, which is
fine. More commonly, we'll reduce the entries to just a few for each CU
and keep the table small so searches are fast.
The following is what I used to test this. But it really belongs in a
dwarflint high-level check, not in dwarfcmp. This code already showed some
interesting anomalies. dwarflint should eventually show the differences in
some way that's especially helpful for debugging the generators. That will
be handy in diagnosing and reporting the details of what GCC does wrong.
Someone should investigate these anomalies, but for now it will have to
take a back seat to our critical path on DWARF writing/transformation work.
diff --git a/src/dwarfcmp.cc b/src/dwarfcmp.cc
index 522b719..0000000 100644
@@ -304,6 +304,20 @@ main (int argc, char *argv)
dwarf file1 (dw1);
dwarf file2 (dw2);
+ const dwarf::aranges_map aranges = file1.aranges ();
+ for (dwarf::aranges_map::const_iterator i = aranges.begin ();
+ i != aranges.end ();
+ const dwarf::compile_unit &cu = (*i).first;
+ const dwarf::arange_list &ranges = (*i).second;
+ cout << (cu.ranges () == ranges ? "match" : "mismatch")
+ << " aranges " << ranges.to_string () << " vs CU-ranges "
+ << cu.ranges ().to_string () << endl;
result = !(file1 == file2);
Sorry for delayed report, I was really out of it early this week.
Actual time on elfutils: 80%
* attr value interfaces
** misc fixes
** location/location lists
** dwarf_edit counterpart
*** now complete for copying purposes, modulo: macinfo, pubnames, refs
** germinating plan for references
*** iterator for value type
*** interfile equality and copying require non-generic solution
-> contemplating parameterizing by "reference resolver" class
Expected time on elfutils: 10%
There was a meeting last week at which it was acknowledged that the
debuginfo revamp is not going to make Fedora 11. It was always an
extremely aggressive schedule, even with the most generous estimates of how
late in the Fedora cycle we could be done. So it's not really a surprise
that we won't make this cycle, though I was glad to act like we might and
concentrate on fast progress. This takes some of the immediate pressure
off since we don't have a target deadline looming very soon.
Unfortunately, I will not be keeping up quite the same pace in my
contributions because I need now to give some neglected other projects
their fair share of my time. But I still want to keep up the momentum and
try to hit all the same marks as soon as we can, not let it all slide all
the way into the next cycle.