]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Fix dwarf_path_finder::jump for the general case.
authorRoland McGrath <roland@redhat.com>
Thu, 24 Feb 2011 23:11:58 +0000 (15:11 -0800)
committerRoland McGrath <roland@redhat.com>
Thu, 24 Feb 2011 23:11:58 +0000 (15:11 -0800)
libdw/c++/dwarf_tracker

index 07317ca278b48558b856d7f915a3caa6ae1593dc..917502c38a23dbdb8a4da6529ad971fe539730e5 100644 (file)
@@ -257,7 +257,6 @@ namespace elfutils
        assert (_m_tracker->_m_path.empty ());
        assert (_m_tracker->_m_steps_taken == 0);
        assert (_m_tracker->_m_walkahead == NULL);
-       ::Dwarf_Off cu_offset = (*root).offset (); cu_offset = cu_offset;
        _m_tracker->_m_root = root;
       }
 
@@ -301,12 +300,41 @@ namespace elfutils
 
     inline void prime_path_to (const typename dw::debug_info_entry &there)
     {
-      /* Since we can only used on a cloned tracker, _m_steps_taken
-        counting does not matter.  */
-      assert (_m_owner != NULL);
-      assert (this != _m_owner->_m_walkahead);
-      assert (at_top ());
-      _m_path = path_to (there);
+      if (_m_owner != NULL)
+       {
+         /* Since this is a cloned tracker,
+            _m_steps_taken counting does not matter.  */
+         assert (this != _m_owner->_m_walkahead);
+         _m_path = path_to (there);
+       }
+      else
+       {
+         /* Spin the walk ahead until we get THERE.  */
+         const dwarf::debug_info_entry::identity_type id = there.identity ();
+         if (_m_seen->find (id) != _m_seen->end ())
+           {
+             /* We're walking backwards now.  We have to repeat the
+                whole walk to recover our _m_steps_taken state correctly.  */
+             _m_path.clear ();
+             clear_walk ();
+           }
+
+         if (at_top ())
+           {
+             /* We have to get the walk started.  */
+             const die first = (*_m_root).children ().begin ();
+             if (first == (*_m_root).children ().end ())
+               unreachable (there); // Empty CU!
+
+             step_forward (first);
+             if ((*first).identity () == id)
+               return;
+           }
+
+         /* We have not walked past it yet, so just keep walking.  */
+         if (! walk_to (id))
+           unreachable (there);
+       }
     }
 
     // Random access to a DIE, find the path of the walk that gets there.