diff options
| author | Roland McGrath <[email protected]> | 2009-08-17 01:45:09 -0700 |
|---|---|---|
| committer | Roland McGrath <[email protected]> | 2009-08-17 01:45:09 -0700 |
| commit | 6d2a5e3f205a524b9736ff83277df8b85c535a46 (patch) | |
| tree | cff720a42ab4ed3da703a54394f1918710baed98 | |
| parent | 8b355bff8a9a863f24c29437472f338dc8954ed1 (diff) | |
passing dwarfcmp -T on self except the C++ ones and libelf
| -rw-r--r-- | libdw/c++/dwarf_output | 109 |
1 files changed, 38 insertions, 71 deletions
diff --git a/libdw/c++/dwarf_output b/libdw/c++/dwarf_output index 3eb776ed..08a1b154 100644 --- a/libdw/c++/dwarf_output +++ b/libdw/c++/dwarf_output @@ -1358,8 +1358,6 @@ namespace elfutils // Set if we are in promote_pending on this entry right now. bool *_m_resolving; - bool _m_circular; - // Completed DIE in the collector, or NULL. die_info_pair *_m_final; @@ -1374,7 +1372,7 @@ namespace elfutils backref_list _m_patch; inline seen () - : _m_building (NULL), _m_resolving (NULL), _m_circular (false), + : _m_building (NULL), _m_resolving (NULL), _m_final (NULL), _m_pending (NULL), _m_patch () {} @@ -1426,6 +1424,8 @@ namespace elfutils depth -= out; debug () << std::string (depth, ' ') << "XXX " << std::hex << _m_offset << std::dec; + if (_m_resolving != NULL) + debug () << " (promoting " << (void *) _m_resolving << ")"; depth += in; return debug (); } @@ -1473,43 +1473,22 @@ namespace elfutils inline void resolve_dangling (copier *c, bool final, const char *caller) { - if (_m_pending->dangling ()) + dump_resolve (true, final, caller); + if (_m_pending->resolve_dangling (final)) { - dump_resolve (true, final, caller); - if (_m_pending->resolve_dangling (final)) - { - // We no longer have any dangling references! - dump () << " resolved with " - << _m_pending->_m_pending_count << " pending\n"; + // We no longer have any dangling references! + dump () << " resolved with " + << _m_pending->_m_pending_count << " pending\n"; - promote_pending (c, _m_pending->complete (), true); - } - else - { - dump () << " unresolved with " - << _m_pending->_m_dangling_count << "/" - << _m_pending->_m_pending_count << "\n"; - dump_refs (); - dump_children (); - } + promote_pending (c, _m_pending->complete (), true); } else { - assert (!final); - - /* We're being called from back_patch, below. But our pending - entry is in fact not dangling. This means we're the root of - a circularity in the reference graph. A referrer is telling - us that it's no longer dangling, but we ourselves triggered - its conversion when we stopped dangling. */ - dump () << " circularity" - << (_m_circular ? " (again)" : "") - << "!\n"; - - _m_circular = true; - - assert (!_m_patch.empty ()); - back_patch (c, _m_pending->circular_reference (), false); + dump () << " unresolved with " + << _m_pending->_m_dangling_count << "/" + << _m_pending->_m_pending_count << "\n"; + dump_refs (); + dump_children (); } } @@ -1520,7 +1499,16 @@ namespace elfutils has a reference attribute pointing to us. */ inline void resolve_refs (copier *c) { - std::for_each (_m_patch.begin (), _m_patch.end (), resolve_one_ref (c)); + bool complete = false; + { + entry_promoter promoting (this, &complete, "refs"); + std::for_each (_m_patch.begin (), _m_patch.end (), + resolve_one_ref (c)); + } + if (complete) + /* Our pending_entry became complete! + This means we've just closed a circularity. */ + finish_pending (c, false, false); } struct resolve_one_ref @@ -1559,11 +1547,12 @@ namespace elfutils struct entry_promoter { seen *_m_die; - inline entry_promoter (seen *die, bool *final) + inline entry_promoter (seen *die, bool *final, const char *what) : _m_die (die) { + _m_die->dump (true) << " promoting " << what << " " + << (void *) final << "...\n"; _m_die->_m_resolving = final; - _m_die->dump (true) << " promoting...\n"; } inline ~entry_promoter () { @@ -1589,7 +1578,7 @@ namespace elfutils assert (was_dangling); ++c->_m_defined; - entry_promoter promoting (this, &final); + entry_promoter promoting (this, &final, "entry"); _m_pending->parents_resolve_dangling (c); @@ -1607,24 +1596,6 @@ namespace elfutils << final << "/" << (_m_final != NULL) << "\n"; } - /* Update everything using us to indicate we are no longer dangling. - Hereafter, all entries along the reference chain from us should - be accounted as pending but not dangling. */ - inline void prepare_circularity (copier *c) - { - dump (true) << " resolve refs...\n"; - if (!_m_patch.empty ()) - back_patch (c, _m_pending->circular_reference ()); - - dump (true, true) << " resolve parents...\n"; - _m_pending->parents_resolve_dangling (c); - dump (false, true) << " done with " - << _m_pending->_m_pending_count - << " pending\n"; - - //_m_pending->resolve_pending (false); - } - inline void resolve_pending (copier *c, bool was_dangling, const char *caller) { @@ -1674,7 +1645,9 @@ namespace elfutils } // Our pending_entry is complete. Resolve all pointers to us. - inline void finish_pending (copier *c, bool was_dangling) + inline void finish_pending (copier *c, + bool was_dangling, + bool refs_dangling = true) { assert (!_m_pending->dangling ()); assert (_m_pending->complete ()); @@ -1729,11 +1702,12 @@ namespace elfutils if (!_m_patch.empty ()) back_patch (c, _m_final->second.self (), - _m_building != NULL && _m_building->_m_out != NULL); + _m_building != NULL && refs_dangling); dump (false, true) << " final done\n"; } + /* This is called from pending_entry::final when resolving a reference attribute that points to us. */ inline value::value_reference *final_reference () const @@ -1860,24 +1834,17 @@ namespace elfutils throw; } + _m_out = NULL; + /* Resolve the phantom that stands for references yet to be added. We've added everything now, so we can complete this entry if it doesn't own any dangling references. */ _m_in->resolve_dangling (_m_copier, true, "populate"); - /* This serves as a marker that we have accounted references to - this entry as no longer dangling. */ - _m_out = NULL; - if (_m_in->_m_final == NULL) - { - /* If we're still pending, there may still be references to us. - Those were dangling before now, but are now just pending. */ - _m_in->dump (true) << " populate resolve_refs...nrefs " - << _m_in->_m_patch.size () << "\n"; - _m_in->resolve_refs (_m_copier); - _m_in->dump (false, true) << " resolve_refs done\n"; - } + /* If we're still pending, there may still be references to us. + Those were dangling before now, but are now just pending. */ + _m_in->resolve_refs (_m_copier); } /* Complain if we still have dangling references. |
