[Lldb-commits] [lldb] r141352 - in /lldb/trunk: include/lldb/Core/RangeMap.h lldb.xcodeproj/project.pbxproj source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp

Greg Clayton gclayton at apple.com
Thu Oct 6 20:58:56 PDT 2011


Author: gclayton
Date: Thu Oct  6 22:58:56 2011
New Revision: 141352

URL: http://llvm.org/viewvc/llvm-project?rev=141352&view=rev
Log:
Since we use address ranges a lot I added a templatized class that allows us to easily control the base address type, the size type, and the data that is stored with each range. It is designed to be populated by appending all needed items, then sorting the resulting list, and optionally minimizing the list when done. I adopted this new list in the DWARFDebugAranges for even further memory savings.


Added:
    lldb/trunk/include/lldb/Core/RangeMap.h
Modified:
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp

Added: lldb/trunk/include/lldb/Core/RangeMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/RangeMap.h?rev=141352&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Core/RangeMap.h (added)
+++ lldb/trunk/include/lldb/Core/RangeMap.h Thu Oct  6 22:58:56 2011
@@ -0,0 +1,307 @@
+//===-- RangeMap.h ----------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RangeMap_h_
+#define liblldb_RangeMap_h_
+
+#include "lldb/lldb-private.h"
+#include <vector>
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// A vm address range. These can represent offsets ranges or actual
+// addresses.
+//----------------------------------------------------------------------
+template <typename B, typename S, class T>
+class RangeMap 
+{
+public:
+    typedef B RangeBaseType;
+    typedef S RangeSizeType;
+    typedef T EntryDataType;
+
+    struct Range
+    {
+        RangeBaseType base;
+        RangeSizeType size;
+        
+        Range () :
+            base (0),
+            size (0)
+        {
+        }
+        
+        Range (RangeBaseType b, RangeSizeType s) :
+            base (b),
+            size (s)
+        {
+        }
+        
+        // Set the start value for the range, and keep the same size
+        RangeBaseType
+        GetBase () const
+        {
+            return base;
+        }
+        
+        void
+        SetBase (RangeBaseType b)
+        {
+            base = b;
+        }
+        
+        RangeBaseType
+        GetEnd () const
+        {
+            return base + size;
+        }
+        
+        void
+        SetEnd (RangeBaseType end)
+        {
+            if (end > base)
+                size = end - base;
+            else
+                size = 0;
+        }
+        
+        RangeSizeType
+        GetSize () const
+        {
+            return size;
+        }
+        
+        void
+        SetSize (RangeSizeType s)
+        {
+            size = s;
+        }
+        
+        bool
+        IsValid() const
+        {
+            return size > 0;
+        }
+        
+        bool
+        Contains (RangeBaseType r) const
+        {
+            return (GetBase() <= r) && (r < GetEnd());
+        }
+        
+        bool
+        ContainsEndInclusive (RangeBaseType r) const
+        {
+            return (GetBase() <= r) && (r <= GetEnd());
+        }
+        
+        bool 
+        Contains (const Range& range) const
+        {
+            return Contains(range.GetBase()) && ContainsEndInclusive(range.GetEnd());
+        }
+        
+        bool
+        operator < (const Range &rhs)
+        {
+            if (base == rhs.base)
+                return size < rhs.size;
+            return base < rhs.base;
+        }
+        
+        bool
+        operator == (const Range &rhs)
+        {
+            return base == rhs.base && size == rhs.size;
+        }
+        
+        bool
+        operator != (const Range &rhs)
+        {
+            return  base != rhs.base || size != rhs.size;
+        }
+    };
+
+    struct Entry
+    {
+        Range range;
+        EntryDataType data;
+
+        Entry () :
+            range (),
+            data ()
+        {
+        }
+
+        Entry (RangeBaseType base, RangeSizeType size, EntryDataType d) :
+            range (base, size),
+            data (d)
+        {
+        }
+
+        bool
+        operator < (const Entry &rhs) const
+        {
+            const RangeBaseType lhs_base = range.GetBase();
+            const RangeBaseType rhs_base = rhs.range.GetBase();
+            if (lhs_base == rhs_base)
+            {
+                const RangeBaseType lhs_size = range.GetSize();
+                const RangeBaseType rhs_size = rhs.range.GetSize();
+                if (lhs_size == rhs_size)
+                    return data < rhs.data;
+                else
+                    return lhs_size < rhs_size;
+            }
+            return lhs_base < rhs_base;
+        }
+
+        bool
+        operator == (const Entry &rhs) const
+        {
+            return range.GetBase() == rhs.range.GetBase() &&
+                   range.GetSize() == rhs.range.GetSize() &&
+                   data == rhs.data;
+        }
+    
+        bool
+        operator != (const Entry &rhs) const
+        {
+            return  range.GetBase() != rhs.range.GetBase() ||
+                    range.GetSize() != rhs.range.GetSize() ||
+                    data != rhs.data;
+        }
+    };
+
+    RangeMap ()
+    {
+    }
+
+    ~RangeMap()
+    {
+    }
+
+    void
+    Append (const Entry &entry)
+    {
+        m_entries.push_back (entry);
+    }
+
+    void
+    Sort ()
+    {
+        if (m_entries.size() > 1)
+            std::stable_sort (m_entries.begin(), m_entries.end());
+    }
+    
+    void
+    CombineConsecutiveEntriesWithEqualData ()
+    {
+        typename std::vector<Entry>::iterator pos;
+        typename std::vector<Entry>::iterator end;
+        typename std::vector<Entry>::iterator prev;
+        bool can_combine = false;
+        // First we determine if we can combine any of the Entry objects so we
+        // don't end up allocating and making a new collection for no reason
+        for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+        {
+            if (prev != end && prev->data == pos->data)
+            {
+                can_combine = true;
+                break;
+            }
+        }
+        
+        // We we can combine at least one entry, then we make a new collection
+        // and populate it accordingly, and then swap it into place. 
+        if (can_combine)
+        {
+            std::vector<Entry> minimal_ranges;
+            for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+            {
+                if (prev != end && prev->data == pos->data)
+                    minimal_ranges.back().range.SetEnd (pos->range.GetEnd());
+                else
+                    minimal_ranges.push_back (*pos);
+            }
+            // Use the swap technique in case our new vector is much smaller.
+            // We must swap when using the STL because std::vector objects never
+            // release or reduce the memory once it has been allocated/reserved.
+            m_entries.swap (minimal_ranges);
+        }
+    }
+
+    void
+    Clear ()
+    {
+        m_entries.clear();
+    }
+
+    bool
+    IsEmpty () const
+    {
+        return m_entries.empty();
+    }
+
+    size_t
+    GetNumEntries () const
+    {
+        return m_entries.size();
+    }
+
+    const Entry *
+    GetEntryAtIndex (uint32_t i) const
+    {
+        if (i<m_entries.size())
+            return &m_entries[i];
+        return NULL;
+    }
+
+    static bool 
+    BaseLessThan (const Entry& lhs, const Entry& rhs)
+    {
+        return lhs.range.GetBase() < rhs.range.GetBase();
+    }
+
+    const Entry *
+    FindEntryThatContains (RangeBaseType addr) const
+    {
+        if ( !m_entries.empty() )
+        {
+            Entry entry;
+            entry.range.SetBase(addr);
+            typename std::vector<Entry>::const_iterator begin = m_entries.begin();
+            typename std::vector<Entry>::const_iterator end = m_entries.end();
+            typename std::vector<Entry>::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+            
+            if ((pos != end) && (pos->range.GetBase() <= addr && addr < pos->range.GetEnd()))
+            {
+                return &(*pos); 
+            }
+            else if (pos != begin)
+            {
+                --pos;
+                if ((pos->range.GetBase() <= addr) && (addr < pos->range.GetEnd()))
+                {
+                    return &(*pos); 
+                }
+            }
+        }
+        return NULL;
+    }
+
+protected:
+    std::vector<Entry> m_entries;
+};
+
+
+} // namespace lldb_private
+
+#endif  // liblldb_RangeMap_h_

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=141352&r1=141351&r2=141352&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Thu Oct  6 22:58:56 2011
@@ -12,6 +12,7 @@
 		260E07C8136FAB9200CF21D3 /* OptionGroupFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260E07C7136FAB9200CF21D3 /* OptionGroupFile.cpp */; };
 		261744781168585B005ADD65 /* SBType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 261744771168585B005ADD65 /* SBType.cpp */; };
 		2617447A11685869005ADD65 /* SBType.h in Headers */ = {isa = PBXBuildFile; fileRef = 2617447911685869005ADD65 /* SBType.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		2626B6AE143E1BEA00EF935C /* RangeMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 2626B6AD143E1BEA00EF935C /* RangeMap.h */; };
 		26274FA214030EEF006BA130 /* OperatingSystemDarwinKernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26274FA014030EEF006BA130 /* OperatingSystemDarwinKernel.cpp */; };
 		26274FA714030F79006BA130 /* DynamicLoaderDarwinKernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26274FA514030F79006BA130 /* DynamicLoaderDarwinKernel.cpp */; };
 		2628A4D513D4977900F5487A /* ThreadKDP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2628A4D313D4977900F5487A /* ThreadKDP.cpp */; };
@@ -664,6 +665,7 @@
 		26217930133BC8640083B112 /* lldb-private-types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "lldb-private-types.h"; path = "include/lldb/lldb-private-types.h"; sourceTree = "<group>"; };
 		26217932133BCB850083B112 /* lldb-private-enumerations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "lldb-private-enumerations.h"; path = "include/lldb/lldb-private-enumerations.h"; sourceTree = "<group>"; };
 		2623096E13D0EFFB006381D9 /* StreamBuffer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = StreamBuffer.h; path = include/lldb/Core/StreamBuffer.h; sourceTree = "<group>"; };
+		2626B6AD143E1BEA00EF935C /* RangeMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RangeMap.h; path = include/lldb/Core/RangeMap.h; sourceTree = "<group>"; };
 		26274FA014030EEF006BA130 /* OperatingSystemDarwinKernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OperatingSystemDarwinKernel.cpp; sourceTree = "<group>"; };
 		26274FA114030EEF006BA130 /* OperatingSystemDarwinKernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OperatingSystemDarwinKernel.h; sourceTree = "<group>"; };
 		26274FA514030F79006BA130 /* DynamicLoaderDarwinKernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DynamicLoaderDarwinKernel.cpp; sourceTree = "<group>"; };
@@ -2137,6 +2139,7 @@
 				26BC7D7010F1B77400F91463 /* PluginInterface.h */,
 				26BC7D7110F1B77400F91463 /* PluginManager.h */,
 				26BC7E8A10F1B85900F91463 /* PluginManager.cpp */,
+				2626B6AD143E1BEA00EF935C /* RangeMap.h */,
 				26C6886D137880B900407EDF /* RegisterValue.h */,
 				26C6886E137880C400407EDF /* RegisterValue.cpp */,
 				26BC7D7310F1B77400F91463 /* RegularExpression.h */,
@@ -2889,6 +2892,7 @@
 			files = (
 				496B015B1406DEB100F830D5 /* IRInterpreter.h in Headers */,
 				2682100D143A59AE004BCF2D /* MappedHash.h in Headers */,
+				2626B6AE143E1BEA00EF935C /* RangeMap.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp?rev=141352&r1=141351&r2=141352&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp Thu Oct  6 22:58:56 2011
@@ -363,8 +363,7 @@
                          m_offset);
         DIE()->BuildFunctionAddressRangeTable (m_dwarf2Data, this, m_func_aranges_ap.get());
         const bool minimize = false;
-        const uint32_t fudge_size = 0;        
-        m_func_aranges_ap->Sort(minimize, fudge_size);
+        m_func_aranges_ap->Sort(minimize);
     }
     return *m_func_aranges_ap.get();
 }

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h?rev=141352&r1=141351&r2=141352&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h Thu Oct  6 22:58:56 2011
@@ -18,21 +18,21 @@
 class DWARFDebugArangeSet
 {
 public:
-    typedef struct HeaderTag
+    struct Header
     {
         uint32_t    length;     // The total length of the entries for that set, not including the length field itself.
         uint16_t    version;    // The DWARF version number
         uint32_t    cu_offset;  // The offset from the beginning of the .debug_info section of the compilation unit entry referenced by the table.
         uint8_t     addr_size;  // The size in bytes of an address on the target architecture. For segmented addressing, this is the size of the offset portion of the address
         uint8_t     seg_size;   // The size in bytes of a segment descriptor on the target architecture. If the target system uses a flat address space, this value is 0.
-    } Header;
+    };
 
-    typedef struct DescriptorTag
+    struct Descriptor
     {
         dw_addr_t   address;
         dw_addr_t   length;
         dw_addr_t end_address() const { return address + length; }
-    } Descriptor;
+    };
 
 
                     DWARFDebugArangeSet();
@@ -55,6 +55,12 @@
             return NULL;
         }
 
+        const Descriptor &  
+        GetDescriptorRef (uint32_t i) const
+        {
+            return m_arange_descriptors[i];
+        }
+
 
 protected:
     typedef std::vector<Descriptor>         DescriptorColl;

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp?rev=141352&r1=141351&r2=141352&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp Thu Oct  6 22:58:56 2011
@@ -34,15 +34,6 @@
 {
 }
 
-
-//----------------------------------------------------------------------
-// Compare function DWARFDebugAranges::Range structures
-//----------------------------------------------------------------------
-static bool RangeLessThan (const DWARFDebugAranges::Range& range1, const DWARFDebugAranges::Range& range2)
-{
-    return range1.lo_pc < range2.lo_pc;
-}
-
 //----------------------------------------------------------------------
 // CountArangeDescriptors
 //----------------------------------------------------------------------
@@ -60,41 +51,6 @@
     uint32_t& count;
 };
 
-//----------------------------------------------------------------------
-// AddArangeDescriptors
-//----------------------------------------------------------------------
-class AddArangeDescriptors
-{
-public:
-    AddArangeDescriptors (DWARFDebugAranges::RangeColl& ranges) : range_collection(ranges) {}
-    void operator() (const DWARFDebugArangeSet& set)
-    {
-        const DWARFDebugArangeSet::Descriptor* arange_desc_ptr;
-        DWARFDebugAranges::Range range;
-        range.offset = set.GetCompileUnitDIEOffset();
-
-        for (uint32_t i=0; (arange_desc_ptr = set.GetDescriptor(i)) != NULL; ++i)
-        {
-            range.lo_pc = arange_desc_ptr->address;
-            range.length = arange_desc_ptr->length;
-
-            // Insert each item in increasing address order so binary searching
-            // can later be done!
-            DWARFDebugAranges::RangeColl::iterator insert_pos = lower_bound(range_collection.begin(), range_collection.end(), range, RangeLessThan);
-            range_collection.insert(insert_pos, range);
-        }
-    }
-    DWARFDebugAranges::RangeColl& range_collection;
-};
-
-//----------------------------------------------------------------------
-// PrintRange
-//----------------------------------------------------------------------
-static void PrintRange(const DWARFDebugAranges::Range& range)
-{
-    // Cast the address values in case the address type is compiled as 32 bit
-    printf("0x%8.8x: [0x%8.8llx - 0x%8.8llx)\n", range.offset, (long long)range.lo_pc, (long long)range.hi_pc());
-}
 
 //----------------------------------------------------------------------
 // Extract
@@ -106,28 +62,23 @@
     {
         uint32_t offset = 0;
 
-        typedef std::vector<DWARFDebugArangeSet>    SetCollection;
-        typedef SetCollection::const_iterator       SetCollectionIter;
-        SetCollection sets;
-
         DWARFDebugArangeSet set;
         Range range;
         while (set.Extract(debug_aranges_data, &offset))
-            sets.push_back(set);
-
-        uint32_t count = 0;
-
-        for_each(sets.begin(), sets.end(), CountArangeDescriptors(count));
-
-        if (count > 0)
         {
-            m_aranges.reserve(count);
-            AddArangeDescriptors range_adder(m_aranges);
-            for_each(sets.begin(), sets.end(), range_adder);
+            const uint32_t num_descriptors = set.NumDescriptors();
+            if (num_descriptors > 0)
+            {
+                const dw_offset_t cu_offset = set.GetCompileUnitDIEOffset();
+                
+                for (uint32_t i=0; i<num_descriptors; ++i)
+                {
+                    const DWARFDebugArangeSet::Descriptor &descriptor = set.GetDescriptorRef(i);
+                    m_aranges.Append(RangeToDIE::Entry (descriptor.address, descriptor.length, cu_offset));
+                }
+            }
+            set.Clear();
         }
-
-    //  puts("\n\nDWARFDebugAranges list is:\n");
-    //  for_each(m_aranges.begin(), m_aranges.end(), PrintRange);
     }
     return false;
 }
@@ -161,177 +112,51 @@
 {
     if (log == NULL)
         return;
-    const uint32_t num_ranges = NumRanges();
-    for (uint32_t i = 0; i < num_ranges; ++i)
+    
+    const size_t num_entries = m_aranges.GetNumEntries();
+    for (size_t i=0; i<num_entries; ++i)
     {
-        const Range &range = m_aranges[i];
-        log->Printf ("0x%8.8x: [0x%8.8llx - 0x%8.8llx)", range.offset, (uint64_t)range.lo_pc, (uint64_t)range.hi_pc());
+        const RangeToDIE::Entry *entry = m_aranges.GetEntryAtIndex(i);
+        log->Printf ("0x%8.8x: [0x%llx - 0x%llx)", 
+                     entry->data,
+                     entry->range.GetBase(),
+                     entry->range.GetEnd());
     }
 }
 
-
-void
-DWARFDebugAranges::Range::Dump(Stream *s) const
-{
-    s->Printf("{0x%8.8x}: [0x%8.8llx - 0x%8.8llx)\n", offset, lo_pc, hi_pc());
-}
-
-//----------------------------------------------------------------------
-// Dump
-//----------------------------------------------------------------------
-//void
-//DWARFDebugAranges::Dump(SymbolFileDWARF* dwarf2Data, Stream *s)
-//{
-//    const DataExtractor &debug_aranges_data = dwarf2Data->get_debug_aranges_data();
-//    if (debug_aranges_data.ValidOffset(0))
-//    {
-//        uint32_t offset = 0;
-//
-//        DWARFDebugArangeSet set;
-//        while (set.Extract(debug_aranges_data, &offset))
-//            set.Dump(s);
-//    }
-//    else
-//        s->PutCString("< EMPTY >\n");
-//}
-//
-
-//----------------------------------------------------------------------
-// AppendDebugRanges
-//----------------------------------------------------------------------
-//void
-//DWARFDebugAranges::AppendDebugRanges(BinaryStreamBuf& debug_ranges, dw_addr_t cu_base_addr, uint32_t addr_size) const
-//{
-//  if (!m_aranges.empty())
-//  {
-//      RangeCollIterator end = m_aranges.end();
-//      RangeCollIterator pos;
-//      RangeCollIterator lo_pos = end;
-//      for (pos = m_aranges.begin(); pos != end; ++pos)
-//      {
-//          if (lo_pos == end)
-//              lo_pos = pos;
-//
-//          RangeCollIterator next = pos + 1;
-//          if (next != end)
-//          {
-//              // Check to see if we can combine two consecutive ranges?
-//              if (pos->hi_pc == next->lo_pc)
-//                  continue;   // We can combine them!
-//          }
-//
-//          if (cu_base_addr == 0 || cu_base_addr == DW_INVALID_ADDRESS)
-//          {
-//              debug_ranges.AppendMax64(lo_pos->lo_pc, addr_size);
-//              debug_ranges.AppendMax64(pos->hi_pc, addr_size);
-//          }
-//          else
-//          {
-//              assert(lo_pos->lo_pc >= cu_base_addr);
-//              assert(pos->hi_pc >= cu_base_addr);
-//              debug_ranges.AppendMax64(lo_pos->lo_pc - cu_base_addr, addr_size);
-//              debug_ranges.AppendMax64(pos->hi_pc - cu_base_addr, addr_size);
-//          }
-//
-//          // Reset the low part of the next address range
-//          lo_pos = end;
-//      }
-//  }
-//  // Terminate the .debug_ranges with two zero addresses
-//  debug_ranges.AppendMax64(0, addr_size);
-//  debug_ranges.AppendMax64(0, addr_size);
-//
-//}
 void
 DWARFDebugAranges::AppendRange (dw_offset_t offset, dw_addr_t low_pc, dw_addr_t high_pc)
 {
-    if (!m_aranges.empty())
-    {
-        if (m_aranges.back().offset == offset && m_aranges.back().hi_pc() == low_pc)
-        {
-            m_aranges.back().set_hi_pc(high_pc);
-            return;
-        }
-    }
-    m_aranges.push_back (DWARFDebugAranges::Range(low_pc, high_pc, offset));
+    if (high_pc > low_pc)
+        m_aranges.Append(RangeToDIE::Entry (low_pc, high_pc - low_pc, offset));
 }
 
 void
-DWARFDebugAranges::Sort (bool minimize, uint32_t n)
+DWARFDebugAranges::Sort (bool minimize)
 {    
     Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
                        __PRETTY_FUNCTION__, this);
 
     LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
-    const size_t orig_arange_size = m_aranges.size();
+    size_t orig_arange_size = 0;
     if (log)
     {
-        log->Printf ("DWARFDebugAranges::Sort(minimize = %u, n = %u) with %zu entries", minimize, n, orig_arange_size);
-        Dump (log.get());
+        orig_arange_size = m_aranges.GetNumEntries();
+        log->Printf ("DWARFDebugAranges::Sort(minimize = %u) with %zu entries", minimize, orig_arange_size);
     }
 
-    // Size of one? If so, no sorting is needed
-    if (orig_arange_size <= 1)
-        return;
-    // Sort our address range entries
-    std::stable_sort (m_aranges.begin(), m_aranges.end(), RangeLessThan);
-
-    
-    if (!minimize)
-        return;
-
-    // Most address ranges are contiguous from function to function
-    // so our new ranges will likely be smaller. We calculate the size
-    // of the new ranges since although std::vector objects can be resized, 
-    // the will never reduce their allocated block size and free any excesss
-    // memory, so we might as well start a brand new collection so it is as
-    // small as possible.
-
-    // First calculate the size of the new minimal arange vector
-    // so we don't have to do a bunch of re-allocations as we 
-    // copy the new minimal stuff over to the new collection
-    size_t minimal_size = 1;
-    size_t i;
-    for (i=1; i<orig_arange_size; ++i)
-    {
-        if (!DWARFDebugAranges::Range::SortedOverlapCheck (m_aranges[i-1], m_aranges[i], n))
-            ++minimal_size;
-    }
-
-    // If the sizes are the same, then no consecutive aranges can be 
-    // combined, we are done
-    if (minimal_size == orig_arange_size)
-        return;
+    m_aranges.Sort();
+    m_aranges.CombineConsecutiveEntriesWithEqualData();
 
-    // Else, make a new RangeColl that _only_ contains what we need.
-    RangeColl minimal_aranges;
-    minimal_aranges.resize(minimal_size);
-    uint32_t j=0;
-    minimal_aranges[j] = m_aranges[0];
-    for (i=1; i<orig_arange_size; ++i)
+    if (log)
     {
-        if (DWARFDebugAranges::Range::SortedOverlapCheck (minimal_aranges[j], m_aranges[i], n))
-        {
-            minimal_aranges[j].set_hi_pc (m_aranges[i].hi_pc());
-        }
-        else
+        if (minimize)
         {
-            // Only increment j if we aren't merging
-            minimal_aranges[++j] = m_aranges[i];            
+            const size_t new_arange_size = m_aranges.GetNumEntries();
+            const size_t delta = orig_arange_size - new_arange_size;
+            log->Printf ("DWARFDebugAranges::Sort() %zu entries after minimizing (%zu entries combined for %zu bytes saved)", 
+                         new_arange_size, delta, delta * sizeof(Range));
         }
-    }
-    assert (j+1 == minimal_size);
-    
-    // Now swap our new minimal aranges into place. The local
-    // minimal_aranges will then contian the old big collection
-    // which will get freed.
-    minimal_aranges.swap(m_aranges);
-    
-    if (log)
-    {
-        size_t delta = orig_arange_size - m_aranges.size();
-        log->Printf ("DWARFDebugAranges::Sort() %zu entries after minimizing (%zu entries combined for %zu bytes saved)", 
-                     m_aranges.size(), delta, delta * sizeof(Range));
         Dump (log.get());
     }
 }
@@ -342,64 +167,8 @@
 dw_offset_t
 DWARFDebugAranges::FindAddress(dw_addr_t address) const
 {
-    if ( !m_aranges.empty() )
-    {
-        DWARFDebugAranges::Range range(address);
-        DWARFDebugAranges::RangeCollIterator begin = m_aranges.begin();
-        DWARFDebugAranges::RangeCollIterator end = m_aranges.end();
-        DWARFDebugAranges::RangeCollIterator pos = lower_bound(begin, end, range, RangeLessThan);
-
-        if ((pos != end) && (pos->lo_pc <= address && address < pos->hi_pc()))
-        {
-        //  printf("FindAddress(1) found 0x%8.8x in compile unit: 0x%8.8x\n", address, pos->offset);
-            return pos->offset;
-        }
-        else if (pos != begin)
-        {
-            --pos;
-            if ((pos->lo_pc <= address) && (address < pos->hi_pc()))
-            {
-            //  printf("FindAddress(2) found 0x%8.8x in compile unit: 0x%8.8x\n", address, pos->offset);
-                return (*pos).offset;
-            }
-        }
-    }
+    const RangeToDIE::Entry *entry = m_aranges.FindEntryThatContains(address);
+    if (entry)
+        return entry->data;
     return DW_INVALID_OFFSET;
 }
-
-//----------------------------------------------------------------------
-// AllRangesAreContiguous
-//----------------------------------------------------------------------
-bool
-DWARFDebugAranges::AllRangesAreContiguous(dw_addr_t& lo_pc, dw_addr_t& hi_pc) const
-{
-    if (m_aranges.empty())
-        return false;
-
-    DWARFDebugAranges::RangeCollIterator begin = m_aranges.begin();
-    DWARFDebugAranges::RangeCollIterator end = m_aranges.end();
-    DWARFDebugAranges::RangeCollIterator pos;
-    dw_addr_t next_addr = 0;
-
-    for (pos = begin; pos != end; ++pos)
-    {
-        if ((pos != begin) && (pos->lo_pc != next_addr))
-            return false;
-        next_addr = pos->hi_pc();
-    }
-    lo_pc = m_aranges.front().lo_pc;    // We checked for empty at the start of function so front() will be valid
-    hi_pc = m_aranges.back().hi_pc();     // We checked for empty at the start of function so back() will be valid
-    return true;
-}
-
-bool
-DWARFDebugAranges::GetMaxRange(dw_addr_t& lo_pc, dw_addr_t& hi_pc) const
-{
-    if (m_aranges.empty())
-        return false;
-
-    lo_pc = m_aranges.front().lo_pc;    // We checked for empty at the start of function so front() will be valid
-    hi_pc = m_aranges.back().hi_pc();   // We checked for empty at the start of function so back() will be valid
-    return true;
-}
-

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h?rev=141352&r1=141351&r2=141352&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h Thu Oct  6 22:58:56 2011
@@ -13,113 +13,81 @@
 #include "DWARFDebugArangeSet.h"
 #include <list>
 
+#include "lldb/Core/RangeMap.h"
+
 class SymbolFileDWARF;
 
 class DWARFDebugAranges
 {
+protected:
+    typedef lldb_private::RangeMap<dw_addr_t, uint32_t, dw_offset_t> RangeToDIE;
+
 public:
-    struct Range
+    typedef RangeToDIE::Entry Range;
+    typedef std::vector<RangeToDIE::Entry> RangeColl;
+
+    DWARFDebugAranges();
+
+    void
+    Clear() 
     {
-        explicit 
-        Range (dw_addr_t lo = DW_INVALID_ADDRESS,
-               dw_addr_t hi = DW_INVALID_ADDRESS,
-               dw_offset_t off = DW_INVALID_OFFSET) :
-                lo_pc  (lo),
-                length (hi-lo),
-                offset (off)
-        {
-        }
-
-        void Clear()
-        {
-            lo_pc = DW_INVALID_ADDRESS;
-            length = 0;
-            offset = DW_INVALID_OFFSET;
-        }
-
-        void
-        set_hi_pc (dw_addr_t hi_pc)
-        {
-            if (hi_pc == DW_INVALID_ADDRESS || hi_pc <= lo_pc)
-                length = 0;
-            else
-                length = hi_pc - lo_pc;
-        }
-        dw_addr_t
-        hi_pc() const
-        {
-            if (length)
-                return lo_pc + length;
-            return DW_INVALID_ADDRESS;
-        }
-        bool 
-        ValidRange() const
-        {
-            return length > 0;
-        }
-        
-        static bool 
-        SortedOverlapCheck (const Range& curr_range, const Range& next_range, uint32_t n)
-        {
-            if (curr_range.offset != next_range.offset)
-                return false;
-            return curr_range.hi_pc() + n >= next_range.lo_pc;
-        }
-
-        bool Contains(const Range& range) const
-        {
-            return lo_pc <= range.lo_pc && range.hi_pc() <= hi_pc();
-        }
-
-        void Dump(lldb_private::Stream *s) const;
-        dw_addr_t   lo_pc;      // Start of address range
-        uint32_t    length;      // End of address range (not including this address)
-        dw_offset_t offset;     // Offset of the compile unit or die
-    };
-
-                DWARFDebugAranges();
-
-    void        Clear() { m_aranges.clear(); }
-    bool        AllRangesAreContiguous(dw_addr_t& lo_pc, dw_addr_t& hi_pc) const;
-    bool        GetMaxRange(dw_addr_t& lo_pc, dw_addr_t& hi_pc) const;
-    bool        Extract(const lldb_private::DataExtractor &debug_aranges_data);
-    bool        Generate(SymbolFileDWARF* dwarf2Data);
+        m_aranges.Clear(); 
+    }
+
+    bool
+    Extract(const lldb_private::DataExtractor &debug_aranges_data);
+
+    bool
+    Generate(SymbolFileDWARF* dwarf2Data);
     
                 // Use append range multiple times and then call sort
-    void        AppendRange (dw_offset_t cu_offset, dw_addr_t low_pc, dw_addr_t high_pc);
-    void        Sort (bool minimize, uint32_t n);
+    void
+    AppendRange (dw_offset_t cu_offset, 
+                 dw_addr_t low_pc, 
+                 dw_addr_t high_pc);
+
+    void 
+    Sort (bool minimize);
 
-    const Range* RangeAtIndex(uint32_t idx) const
-                {
-                    if (idx < m_aranges.size())
-                        return &m_aranges[idx];
-                    return NULL;
-                }
-    void        Dump (lldb_private::Log *log) const;
-    dw_offset_t FindAddress(dw_addr_t address) const;
-    bool        IsEmpty() const { return m_aranges.empty(); }
-//    void        Dump(lldb_private::Stream *s);
-    uint32_t    NumRanges() const
-                {
-                    return m_aranges.size();
-                }
-
-    dw_offset_t OffsetAtIndex(uint32_t idx) const
-                {
-                    if (idx < m_aranges.size())
-                        return m_aranges[idx].offset;
-                    return DW_INVALID_OFFSET;
-                }
-//  void    AppendDebugRanges(BinaryStreamBuf& debug_ranges, dw_addr_t cu_base_addr, uint32_t addr_size) const;
+    const Range* 
+    RangeAtIndex(uint32_t idx) const
+    {
+        return m_aranges.GetEntryAtIndex (idx);
+    }
+    
+    void
+    Dump (lldb_private::Log *log) const;
+    
+    dw_offset_t
+    FindAddress(dw_addr_t address) const;
 
-    static void Dump(SymbolFileDWARF* dwarf2Data, lldb_private::Stream *s);
+    bool
+    IsEmpty() const 
+    {
+        return m_aranges.IsEmpty(); 
+    }
+    uint32_t
+    GetNumRanges() const
+    {
+        return m_aranges.GetNumEntries();
+    }
 
-    typedef std::vector<Range>              RangeColl;
-    typedef RangeColl::const_iterator       RangeCollIterator;
+    dw_offset_t 
+    OffsetAtIndex(uint32_t idx) const
+    {
+        const Range *range = m_aranges.GetEntryAtIndex (idx);
+        if (range)
+            return range->data;
+        return DW_INVALID_OFFSET;
+    }
 
+    static void 
+    Dump(SymbolFileDWARF* dwarf2Data, lldb_private::Stream *s);
+    
 protected:
 
-    RangeColl m_aranges;
+
+    RangeToDIE m_aranges;
 };
 
 

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp?rev=141352&r1=141351&r2=141352&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp Thu Oct  6 22:58:56 2011
@@ -84,19 +84,8 @@
             }
         }
 
-        // Sort with a fudge factor of 16 to make sure if we have a lot
-        // of functions in the compile unit whose end address if followed
-        // a start address that is "fudge_size" bytes close, it will combine
-        // the arange entries. This currently happens a lot on x86_64. This
-        // will help reduce the size of the aranges since sort will sort all
-        // of them and combine aranges that are consecutive for ranges in the
-        // same compile unit and we really don't need it to be all that 
-        // accurate since we will get exact accuracy when we search the 
-        // actual compile unit aranges which point to the exact range and 
-        // the exact DIE offset of the function.
         const bool minimize = true;
-        const uint32_t fudge_factor = 16;
-        m_cu_aranges_ap->Sort (minimize, fudge_factor);
+        m_cu_aranges_ap->Sort (minimize);
     }
     return *m_cu_aranges_ap.get();
 }
@@ -447,461 +436,6 @@
     }
 }
 
-/*
-typedef struct AddressRangeTag
-{
-    dw_addr_t   lo_pc;
-    dw_addr_t   hi_pc;
-    dw_offset_t die_offset;
-} AddressRange;
-*/
-struct DIERange
-{
-    DIERange() :
-        range(),
-        lo_die_offset(),
-        hi_die_offset()
-    {
-    }
-
-    DWARFDebugAranges::Range range;
-    dw_offset_t lo_die_offset;
-    dw_offset_t hi_die_offset;
-};
-
-typedef struct DwarfStat
-{
-    DwarfStat() : count(0), byte_size(0) {}
-    uint32_t count;
-    uint32_t byte_size;
-} DwarfStat;
-
-typedef map<dw_attr_t, DwarfStat> DwarfAttrStatMap;
-
-typedef struct DIEStat
-{
-    DIEStat() : count(0), byte_size(0), attr_stats() {}
-    uint32_t count;
-    uint32_t byte_size;
-    DwarfAttrStatMap attr_stats;
-} DIEStat;
-
-typedef map<dw_tag_t, DIEStat> DIEStatMap;
-struct VerifyInfo
-{
-    VerifyInfo(Stream* the_strm) :
-        strm(the_strm),
-        die_ranges(),
-        addr_range_errors(0),
-        sibling_errors(0),
-        die_stats()
-    {
-    }
-
-    Stream* strm;
-    vector<DIERange> die_ranges;
-    uint32_t addr_range_errors;
-    uint32_t sibling_errors;
-    DIEStatMap die_stats;
-
-    DISALLOW_COPY_AND_ASSIGN(VerifyInfo);
-
-};
-
-
-//----------------------------------------------------------------------
-// VerifyCallback
-//
-// A callback function for the static DWARFDebugInfo::Parse() function
-// that gets called each time a compile unit header or debug information
-// entry is successfully parsed.
-//
-// This function will verify the DWARF information is well formed by
-// making sure that any DW_TAG_compile_unit tags that have valid address
-// ranges (DW_AT_low_pc and DW_AT_high_pc) have no gaps in the address
-// ranges of it contained DW_TAG_subprogram tags. Also the sibling chain
-// and relationships are verified to make sure nothing gets hosed up
-// when dead stripping occurs.
-//----------------------------------------------------------------------
-
-static dw_offset_t
-VerifyCallback
-(
-    SymbolFileDWARF* dwarf2Data,
-    DWARFCompileUnitSP& cu_sp,
-    DWARFDebugInfoEntry* die,
-    const dw_offset_t next_offset,
-    const uint32_t curr_depth,
-    void* userData
-)
-{
-    VerifyInfo* verifyInfo = (VerifyInfo*)userData;
-
-    const DWARFCompileUnit* cu = cu_sp.get();
-    Stream *s = verifyInfo->strm;
-    bool verbose = s->GetVerbose();
-    if (die)
-    {
-    //  die->Dump(dwarf2Data, cu, f);
-        const DWARFAbbreviationDeclaration* abbrevDecl = die->GetAbbreviationDeclarationPtr();
-        // We have a DIE entry
-        if (abbrevDecl)
-        {
-            const dw_offset_t die_offset = die->GetOffset();
-            const dw_offset_t sibling = die->GetAttributeValueAsReference(dwarf2Data, cu, DW_AT_sibling, DW_INVALID_OFFSET);
-
-            if (sibling != DW_INVALID_OFFSET)
-            {
-                if (sibling <= next_offset)
-                {
-                    if (verifyInfo->sibling_errors++ == 0)
-                        s->Printf("ERROR\n");
-                    s->Printf("    0x%8.8x: sibling attribute (0x%8.8x) in this die is not valid: it is less than this DIE or some of its contents.\n", die->GetOffset(), sibling);
-                }
-                else if (sibling > verifyInfo->die_ranges.back().hi_die_offset)
-                {
-                    if (verifyInfo->sibling_errors++ == 0)
-                        s->Printf("ERROR\n");
-                    s->Printf("    0x%8.8x: sibling attribute (0x%8.8x) in this DIE is not valid: it is greater than the end of the parent scope.\n", die->GetOffset(), sibling);
-                }
-            }
-
-            if ((die_offset < verifyInfo->die_ranges.back().lo_die_offset) || (die_offset >= verifyInfo->die_ranges.back().hi_die_offset))
-            {
-                if (verifyInfo->sibling_errors++ == 0)
-                    s->Printf("ERROR\n");
-                s->Printf("    0x%8.8x: DIE offset is not within the parent DIE range {0x%8.8x}: (0x%8.8x - 0x%8.8x)\n",
-                        die->GetOffset(),
-                        verifyInfo->die_ranges.back().range.offset,
-                        verifyInfo->die_ranges.back().lo_die_offset,
-                        verifyInfo->die_ranges.back().hi_die_offset);
-
-            }
-
-            dw_tag_t tag = abbrevDecl->Tag();
-
-            // Keep some stats on this DWARF file
-            verifyInfo->die_stats[tag].count++;
-            verifyInfo->die_stats[tag].byte_size += (next_offset - die->GetOffset());
-
-            if (verbose)
-            {
-                DIEStat& tag_stat = verifyInfo->die_stats[tag];
-
-                const DataExtractor& debug_info = dwarf2Data->get_debug_info_data();
-
-                dw_offset_t offset = die->GetOffset();
-                // Skip the abbreviation code so we are at the data for the attributes
-                debug_info.Skip_LEB128(&offset);
-
-                const uint32_t numAttributes = abbrevDecl->NumAttributes();
-                dw_attr_t attr;
-                dw_form_t form;
-                for (uint32_t idx = 0; idx < numAttributes; ++idx)
-                {
-                    dw_offset_t start_offset = offset;
-                    abbrevDecl->GetAttrAndFormByIndexUnchecked(idx, attr, form);
-                    DWARFFormValue::SkipValue(form, debug_info, &offset, cu);
-
-                    if (tag_stat.attr_stats.find(attr) == tag_stat.attr_stats.end())
-                    {
-                        tag_stat.attr_stats[attr].count = 0;
-                        tag_stat.attr_stats[attr].byte_size = 0;
-                    }
-
-                    tag_stat.attr_stats[attr].count++;
-                    tag_stat.attr_stats[attr].byte_size += offset - start_offset;
-                }
-            }
-
-            DWARFDebugAranges::Range range;
-            range.offset = die->GetOffset();
-
-            switch (tag)
-            {
-            case DW_TAG_compile_unit:
-                // Check for previous subroutines that were within a previous
-                //
-            //  VerifyAddressRangesForCU(verifyInfo);
-                // Remember which compile unit we are dealing with so we can verify
-                // the address ranges within it (if any) are contiguous. The DWARF
-                // spec states that if a compile unit TAG has high and low PC
-                // attributes, there must be no gaps in the address ranges of it's
-                // contained subroutines. If there are gaps, the high and low PC
-                // must not be in the DW_TAG_compile_unit's attributes. Errors like
-                // this can crop up when optimized code is dead stripped and the debug
-                // information isn't properly fixed up for output.
-                range.lo_pc = die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
-                if (range.lo_pc != DW_INVALID_ADDRESS)
-                {
-                    range.set_hi_pc (die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS));
-                    if (s->GetVerbose())
-                    {
-                        s->Printf("\n    CU ");
-                        range.Dump(s);
-                    }
-                }
-                else
-                {
-                    range.lo_pc = die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_entry_pc, DW_INVALID_ADDRESS);
-                }
-                break;
-
-            case DW_TAG_subprogram:
-                // If the DW_TAG_compile_unit that contained this function had a
-                // valid address range, add all of the valid subroutine address
-                // ranges to a collection of addresses which will be sorted
-                // and verified right before the next DW_TAG_compile_unit is
-                // processed to make sure that there are no gaps in the address
-                // range.
-                range.lo_pc = die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
-                if (range.lo_pc != DW_INVALID_ADDRESS)
-                {
-                    range.set_hi_pc (die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS));
-                    if (range.hi_pc() != DW_INVALID_ADDRESS)
-                    {
-                        range.offset = die->GetOffset();
-                        bool valid = range.ValidRange();
-                        if (!valid || s->GetVerbose())
-                        {
-                            s->Printf("\n  FUNC ");
-                            range.Dump(s);
-                            if (!valid)
-                            {
-                                ++verifyInfo->addr_range_errors;
-                                s->Printf(" ERROR: Invalid address range for function.");
-                            }
-                        }
-                    }
-                }
-                break;
-
-            case DW_TAG_lexical_block:
-            case DW_TAG_inlined_subroutine:
-                {
-                    range.lo_pc = die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
-                    if (range.lo_pc != DW_INVALID_ADDRESS)
-                    {
-                        range.set_hi_pc (die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS));
-                        if (range.hi_pc() != DW_INVALID_ADDRESS)
-                        {
-                            range.offset = die->GetOffset();
-                            bool valid = range.ValidRange();
-                            if (!valid || s->GetVerbose())
-                            {
-                                s->Printf("\n  BLCK ");
-                                range.Dump(s);
-                                if (!valid)
-                                {
-                                    ++verifyInfo->addr_range_errors;
-                                    s->Printf(" ERROR: Invalid address range for block or inlined subroutine.");
-                                }
-                            }
-                        }
-                    }
-                }
-                break;
-            }
-
-            if (range.ValidRange() && verifyInfo->die_ranges.back().range.ValidRange())
-            {
-                if (!verifyInfo->die_ranges.back().range.Contains(range))
-                {
-                    ++verifyInfo->addr_range_errors;
-                    s->Printf("\n       ");
-                    range.Dump(s);
-                    s->Printf(" ERROR: Range is not in parent");
-                    verifyInfo->die_ranges.back().range.Dump(s);
-                }
-            }
-
-            if (die->HasChildren())
-            {
-                // Keep tabs on the valid address ranges for the current item to make
-                // sure that it all fits (make sure the sibling offsets got fixed up
-                // correctly if any functions were dead stripped).
-                DIERange die_range;
-                die_range.range = range;
-                die_range.lo_die_offset = next_offset;
-                die_range.hi_die_offset = sibling;
-                if (die_range.hi_die_offset == DW_INVALID_OFFSET)
-                    die_range.hi_die_offset = verifyInfo->die_ranges.back().hi_die_offset;
-                verifyInfo->die_ranges.push_back(die_range);
-            }
-        }
-        else
-        {
-            // NULL entry
-            verifyInfo->die_ranges.pop_back();
-        }
-    }
-    else
-    {
-    //  cu->Dump(ostrm_ptr); // Dump the compile unit for the DIE
-        // We have a new compile unit header
-        verifyInfo->die_ranges.clear();
-        DIERange die_range;
-        die_range.range.offset  = cu->GetOffset();
-        die_range.lo_die_offset = next_offset;
-        die_range.hi_die_offset = cu->GetNextCompileUnitOffset();
-        verifyInfo->die_ranges.push_back(die_range);
-    }
-
-    // Just return the current offset to parse the next CU or DIE entry
-    return next_offset;
-}
-
-
-class CompareDIEStatSizes
-{
-public:
-    bool operator() (const DIEStatMap::const_iterator& pos1, const DIEStatMap::const_iterator& pos2) const
-    {
-        return pos1->second.byte_size <= pos2->second.byte_size;
-    }
-};
-
-class CompareAttrDIEStatSizes
-{
-public:
-    bool operator() (const DwarfAttrStatMap::const_iterator& pos1, const DwarfAttrStatMap::const_iterator& pos2) const
-    {
-        return pos1->second.byte_size <= pos2->second.byte_size;
-    }
-};
-
-//----------------------------------------------------------------------
-// Verify
-//
-// Verifies the DWARF information is valid.
-//----------------------------------------------------------------------
-void
-DWARFDebugInfo::Verify(Stream *s, SymbolFileDWARF* dwarf2Data)
-{
-    s->Printf("Verifying Compile Unit Header chain.....");
-    VerifyInfo verifyInfo(s);
-    verifyInfo.addr_range_errors = 0;
-    verifyInfo.sibling_errors = 0;
-
-    bool verbose = s->GetVerbose();
-
-    uint32_t offset = 0;
-    if (verbose)
-        s->EOL();
-//  vector<dw_offset_t> valid_cu_offsets;
-    DWARFCompileUnit cu (dwarf2Data);
-    bool success = true;
-    while ( success && dwarf2Data->get_debug_info_data().ValidOffset(offset+cu.Size()) )
-    {
-        success = cu.Extract (dwarf2Data->get_debug_info_data(), &offset);
-        if (!success)
-            s->Printf("ERROR\n");
-    //  else
-    //      valid_cu_offsets.push_back(cu.GetOffset());
-
-        cu.Verify(verifyInfo.strm);
-        offset = cu.GetNextCompileUnitOffset();
-    }
-
-    if (success)
-        s->Printf("OK\n");
-
-    s->Printf("Verifying address ranges and siblings...");
-    if (verbose)
-        s->EOL();
-    DWARFDebugInfo::Parse(dwarf2Data, VerifyCallback, &verifyInfo);
-
-//  VerifyAddressRangesForCU(&verifyInfo);
-
-    if (verifyInfo.addr_range_errors > 0)
-        s->Printf("\nERRORS - %u error(s) were found.\n", verifyInfo.addr_range_errors);
-    else
-        s->Printf("OK\n");
-
-    uint32_t total_category_sizes[kNumTagCategories] = {0};
-    uint32_t total_category_count[kNumTagCategories] = {0};
-    uint32_t total_die_count = 0;
-    uint32_t total_die_size = 0;
-
-    typedef set<DIEStatMap::const_iterator, CompareDIEStatSizes> DIEStatBySizeMap;
-
-    s->PutCString(  "\n"
-                "DWARF Statistics\n"
-                "Count    Size     Size %   Tag\n"
-                "-------- -------- -------- -------------------------------------------\n");
-    DIEStatBySizeMap statBySizeMap;
-    DIEStatMap::const_iterator pos;
-    DIEStatMap::const_iterator end_pos = verifyInfo.die_stats.end();
-    for (pos = verifyInfo.die_stats.begin(); pos != end_pos; ++pos)
-    {
-        const uint32_t die_count = pos->second.count;
-        const uint32_t die_size = pos->second.byte_size;
-
-        statBySizeMap.insert(pos);
-        total_die_count += die_count;
-        total_die_size += die_size;
-        DW_TAG_CategoryEnum category = get_tag_category(pos->first);
-        total_category_sizes[category] += die_size;
-        total_category_count[category] += die_count;
-    }
-
-    float total_die_size_float = total_die_size;
-
-    DIEStatBySizeMap::const_reverse_iterator size_pos;
-    DIEStatBySizeMap::const_reverse_iterator size_pos_end = statBySizeMap.rend();
-    float percentage;
-    for (size_pos = statBySizeMap.rbegin(); size_pos != size_pos_end; ++size_pos)
-    {
-        pos = *size_pos;
-
-        const DIEStat& tag_stat = pos->second;
-
-        const uint32_t die_count = tag_stat.count;
-        const uint32_t die_size = tag_stat.byte_size;
-        percentage = ((float)die_size/total_die_size_float)*100.0;
-        s->Printf("%7u %8u %2.2f%%     %s\n", die_count, die_size, percentage, DW_TAG_value_to_name(pos->first));
-
-        const DwarfAttrStatMap& attr_stats = tag_stat.attr_stats;
-        if (!attr_stats.empty())
-        {
-            typedef set<DwarfAttrStatMap::const_iterator, CompareAttrDIEStatSizes> DwarfAttrStatBySizeMap;
-            DwarfAttrStatBySizeMap attrStatBySizeMap;
-            DwarfAttrStatMap::const_iterator attr_stat_pos;
-            DwarfAttrStatMap::const_iterator attr_stat_pos_end = attr_stats.end();
-            for (attr_stat_pos = attr_stats.begin(); attr_stat_pos != attr_stat_pos_end; ++attr_stat_pos)
-            {
-                attrStatBySizeMap.insert(attr_stat_pos);
-            }
-
-            DwarfAttrStatBySizeMap::const_reverse_iterator attr_size_pos;
-            DwarfAttrStatBySizeMap::const_reverse_iterator attr_size_pos_end = attrStatBySizeMap.rend();
-            for (attr_size_pos = attrStatBySizeMap.rbegin(); attr_size_pos != attr_size_pos_end; ++attr_size_pos)
-            {
-                attr_stat_pos = *attr_size_pos;
-                percentage = ((float)attr_stat_pos->second.byte_size/die_size)*100.0;
-                s->Printf("%7u %8u %2.2f%%    %s\n", attr_stat_pos->second.count, attr_stat_pos->second.byte_size, percentage, DW_AT_value_to_name(attr_stat_pos->first));
-            }
-            s->EOL();
-        }
-    }
-
-    s->Printf("-------- -------- -------- -------------------------------------------\n");
-    s->Printf("%7u %8u 100.00%% Total for all DIEs\n", total_die_count, total_die_size);
-
-    float total_category_percentages[kNumTagCategories] =
-    {
-        ((float)total_category_sizes[TagCategoryVariable]/total_die_size_float)*100.0,
-        ((float)total_category_sizes[TagCategoryType]/total_die_size_float)*100.0,
-        ((float)total_category_sizes[TagCategoryProgram]/total_die_size_float)*100.0
-    };
-
-    s->EOL();
-    s->Printf("%7u %8u %2.2f%%    %s\n", total_category_count[TagCategoryVariable], total_category_sizes[TagCategoryVariable],  total_category_percentages[TagCategoryVariable],    "Total for variable related DIEs");
-    s->Printf("%7u %8u %2.2f%%    %s\n", total_category_count[TagCategoryType],     total_category_sizes[TagCategoryType],      total_category_percentages[TagCategoryType],        "Total for type related DIEs");
-    s->Printf("%7u %8u %2.2f%%    %s\n", total_category_count[TagCategoryProgram],      total_category_sizes[TagCategoryProgram],   total_category_percentages[TagCategoryProgram],     "Total for program related DIEs");
-    s->Printf("\n\n");
-}
-
 typedef struct DumpInfo
 {
     DumpInfo(Stream* init_strm, uint32_t off, uint32_t depth) :





More information about the lldb-commits mailing list