[Lldb-commits] [lldb] r176454 - <rdar://problem/13338643>

Greg Clayton gclayton at apple.com
Mon Mar 4 13:46:17 PST 2013


Author: gclayton
Date: Mon Mar  4 15:46:16 2013
New Revision: 176454

URL: http://llvm.org/viewvc/llvm-project?rev=176454&view=rev
Log:
<rdar://problem/13338643>

DWARF with .o files now uses 40-60% less memory!

Big fixes include:
- Change line table internal representation to contain "file addresses". Since each line table is owned by a compile unit that is owned by a module, it makes address translation into lldb_private::Address easy to do when needed.
- Removed linked address members/methods from lldb_private::Section and lldb_private::Address
- lldb_private::LineTable can now relink itself using a FileRangeMap to make it easier to re-link line tables in the future
- Added ObjectFile::ClearSymtab() so that we can get rid of the object file symbol tables after we parse them once since they are not needed and kept memory allocated for no reason
- Moved the m_sections_ap (std::auto_ptr to section list) and m_symtab_ap (std::auto_ptr to the lldb_private::Symtab) out of each of the ObjectFile subclasses and put it into lldb_private::ObjectFile.
- Changed how the debug map is parsed and stored to be able to:
    - Lazily parse the debug map for each object file
    - not require the address map for a .o file until debug information is linked for a .o file


Modified:
    lldb/trunk/include/lldb/Core/Address.h
    lldb/trunk/include/lldb/Core/RangeMap.h
    lldb/trunk/include/lldb/Core/Section.h
    lldb/trunk/include/lldb/Expression/DWARFExpression.h
    lldb/trunk/include/lldb/Symbol/LineTable.h
    lldb/trunk/include/lldb/Symbol/ObjectFile.h
    lldb/trunk/source/Core/Address.cpp
    lldb/trunk/source/Core/Section.cpp
    lldb/trunk/source/Expression/DWARFExpression.cpp
    lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
    lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
    lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
    lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
    lldb/trunk/source/Symbol/Function.cpp
    lldb/trunk/source/Symbol/LineTable.cpp
    lldb/trunk/source/Symbol/ObjectFile.cpp
    lldb/trunk/source/Symbol/Symtab.cpp

Modified: lldb/trunk/include/lldb/Core/Address.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Address.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Address.h (original)
+++ lldb/trunk/include/lldb/Core/Address.h Mon Mar  4 15:46:16 2013
@@ -393,12 +393,6 @@ public:
     bool
     ResolveAddressUsingFileSections (lldb::addr_t addr, const SectionList *sections);
 
-    bool
-    IsLinkedAddress () const;
-
-    void
-    ResolveLinkedAddress ();
-
     //------------------------------------------------------------------
     /// Set the address to represent \a load_addr.
     ///

Modified: lldb/trunk/include/lldb/Core/RangeMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/RangeMap.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/RangeMap.h (original)
+++ lldb/trunk/include/lldb/Core/RangeMap.h Mon Mar  4 15:46:16 2013
@@ -10,6 +10,8 @@
 #ifndef liblldb_RangeMap_h_
 #define liblldb_RangeMap_h_
 
+#include <vector>
+
 #include "lldb/lldb-private.h"
 #include "llvm/ADT/SmallVector.h"
 
@@ -171,7 +173,6 @@ namespace lldb_private {
         typedef B BaseType;
         typedef S SizeType;
         typedef Range<B,S> Entry;
-        //typedef std::vector<Entry> Collection;
         typedef llvm::SmallVector<Entry, N> Collection;
         
         RangeArray () :
@@ -445,90 +446,48 @@ namespace lldb_private {
         Collection m_entries;
     };
 
-    //----------------------------------------------------------------------
-    // A simple range  with data class where you get to define the type of
-    // the range base "B", the type used for the range byte size "S", and
-    // the type for the associated data "T".
-    //----------------------------------------------------------------------
-    template <typename B, typename S, typename T>
-    struct RangeData : public Range<B,S>
+    template <typename B, typename S>
+    class RangeVector
     {
-        typedef T DataType;
-        
-        DataType data;
-        
-        RangeData () :
-            Range<B,S> (),
-            data ()
-        {
-        }
+    public:
+        typedef B BaseType;
+        typedef S SizeType;
+        typedef Range<B,S> Entry;
+        typedef std::vector<Entry> Collection;
         
-        RangeData (B base, S size, DataType d) :
-            Range<B,S> (base, size),
-            data (d)
+        RangeVector () :
+            m_entries ()
         {
         }
         
-        bool
-        operator < (const RangeData &rhs) const
+        ~RangeVector()
         {
-            if (this->base == rhs.base)
-            {
-                if (this->size == rhs.size)
-                    return this->data < rhs.data;
-                else
-                    return this->size < rhs.size;
-            }
-            return this->base < rhs.base;
         }
         
-        bool
-        operator == (const RangeData &rhs) const
+        void
+        Append (const Entry &entry)
         {
-            return this->GetRangeBase() == rhs.GetRangeBase() &&
-                   this->GetByteSize() == rhs.GetByteSize() &&
-                   this->data      == rhs.data;
+            m_entries.push_back (entry);
         }
         
         bool
-        operator != (const RangeData &rhs) const
-        {
-            return this->GetRangeBase() != rhs.GetRangeBase() ||
-                   this->GetByteSize() != rhs.GetByteSize() ||
-                   this->data      != rhs.data;
-        }
-    };
-    
-    template <typename B, typename S, typename T, unsigned N>
-    class RangeDataArray
-    {
-    public:
-        typedef RangeData<B,S,T> Entry;
-        //typedef std::vector<Entry> Collection;
-        typedef llvm::SmallVector<Entry, N> Collection;
-
-
-        RangeDataArray ()
-        {
-        }
-        
-        ~RangeDataArray()
+        RemoveEntrtAtIndex (uint32_t idx)
         {
+            if (idx < m_entries.size())
+            {
+                m_entries.erase (m_entries.begin() + idx);
+                return true;
+            }
+            return false;
         }
         
         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());
         }
-    
+        
 #ifdef ASSERT_RANGEMAP_ARE_SORTED
         bool
         IsSorted () const
@@ -544,47 +503,86 @@ namespace lldb_private {
             return true;
         }
 #endif
-
         void
-        CombineConsecutiveEntriesWithEqualData ()
+        CombineConsecutiveRanges ()
         {
 #ifdef ASSERT_RANGEMAP_ARE_SORTED
             assert (IsSorted());
 #endif
-            typename Collection::iterator pos;
-            typename Collection::iterator end;
-            typename Collection::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++)
+            // Can't combine if ranges if we have zero or one range
+            if (m_entries.size() > 1)
             {
-                if (prev != end && prev->data == pos->data)
+                // The list should be sorted prior to calling this function
+                typename Collection::iterator pos;
+                typename Collection::iterator end;
+                typename Collection::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++)
                 {
-                    can_combine = true;
-                    break;
+                    if (prev != end && prev->Overlap(*pos))
+                    {
+                        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)
-            {
-                Collection minimal_ranges;
-                for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+                
+                // 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)
                 {
-                    if (prev != end && prev->data == pos->data)
-                        minimal_ranges.back().SetRangeEnd (pos->GetRangeEnd());
-                    else
-                        minimal_ranges.push_back (*pos);
+                    Collection minimal_ranges;
+                    for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+                    {
+                        if (prev != end && prev->Overlap(*pos))
+                            minimal_ranges.back().SetRangeEnd (std::max<BaseType>(prev->GetRangeEnd(), pos->GetRangeEnd()));
+                        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);
                 }
-                // 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);
             }
         }
-    
+        
+        
+        BaseType
+        GetMinRangeBase (BaseType fail_value) const
+        {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+            assert (IsSorted());
+#endif
+            if (m_entries.empty())
+                return fail_value;
+            // m_entries must be sorted, so if we aren't empty, we grab the
+            // first range's base
+            return m_entries.front().GetRangeBase();
+        }
+        
+        BaseType
+        GetMaxRangeEnd (BaseType fail_value) const
+        {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+            assert (IsSorted());
+#endif
+            if (m_entries.empty())
+                return fail_value;
+            // m_entries must be sorted, so if we aren't empty, we grab the
+            // last range's end
+            return m_entries.back().GetRangeEnd();
+        }
+        
+        void
+        Slide (BaseType slide)
+        {
+            typename Collection::iterator pos, end;
+            for (pos = m_entries.begin(), end = m_entries.end(); pos != end; ++pos)
+                pos->Slide (slide);
+        }
+        
         void
         Clear ()
         {
@@ -610,14 +608,30 @@ namespace lldb_private {
                 return &m_entries[i];
             return NULL;
         }
-
+        
         // Clients must ensure that "i" is a valid index prior to calling this function
         const Entry &
         GetEntryRef (size_t i) const
         {
             return m_entries[i];
         }
-
+        
+        Entry *
+        Back()
+        {
+            if (m_entries.empty())
+                return NULL;
+            return &m_entries.back();
+        }
+        
+        const Entry *
+        Back() const
+        {
+            if (m_entries.empty())
+                return NULL;
+            return &m_entries.back();
+        }
+        
         static bool
         BaseLessThan (const Entry& lhs, const Entry& rhs)
         {
@@ -630,7 +644,7 @@ namespace lldb_private {
 #ifdef ASSERT_RANGEMAP_ARE_SORTED
             assert (IsSorted());
 #endif
-            if ( !m_entries.empty() )
+            if (!m_entries.empty())
             {
                 Entry entry (addr, 1);
                 typename Collection::const_iterator begin = m_entries.begin();
@@ -650,62 +664,30 @@ namespace lldb_private {
             }
             return UINT32_MAX;
         }
-
-        Entry *
-        FindEntryThatContains (B addr)
-        {
-#ifdef ASSERT_RANGEMAP_ARE_SORTED
-            assert (IsSorted());
-#endif
-            if ( !m_entries.empty() )
-            {
-                Entry entry;
-                entry.SetRangeBase(addr);
-                entry.SetByteSize(1);
-                typename Collection::iterator begin = m_entries.begin();
-                typename Collection::iterator end = m_entries.end();
-                typename Collection::iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
-                
-                if (pos != end && pos->Contains(addr))
-                {
-                    return &(*pos); 
-                }
-                else if (pos != begin)
-                {
-                    --pos;
-                    if (pos->Contains(addr))
-                    {
-                        return &(*pos); 
-                    }
-                }
-            }
-            return NULL;
-        }
+        
         const Entry *
         FindEntryThatContains (B addr) const
         {
 #ifdef ASSERT_RANGEMAP_ARE_SORTED
             assert (IsSorted());
 #endif
-            if ( !m_entries.empty() )
+            if (!m_entries.empty())
             {
-                Entry entry;
-                entry.SetRangeBase(addr);
-                entry.SetByteSize(1);
+                Entry entry (addr, 1);
                 typename Collection::const_iterator begin = m_entries.begin();
                 typename Collection::const_iterator end = m_entries.end();
                 typename Collection::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
                 
                 if (pos != end && pos->Contains(addr))
                 {
-                    return &(*pos); 
+                    return &(*pos);
                 }
                 else if (pos != begin)
                 {
                     --pos;
                     if (pos->Contains(addr))
                     {
-                        return &(*pos); 
+                        return &(*pos);
                     }
                 }
             }
@@ -718,7 +700,7 @@ namespace lldb_private {
 #ifdef ASSERT_RANGEMAP_ARE_SORTED
             assert (IsSorted());
 #endif
-            if ( !m_entries.empty() )
+            if (!m_entries.empty())
             {
                 typename Collection::const_iterator begin = m_entries.begin();
                 typename Collection::const_iterator end = m_entries.end();
@@ -726,32 +708,336 @@ namespace lldb_private {
                 
                 if (pos != end && pos->Contains(range))
                 {
-                    return &(*pos); 
+                    return &(*pos);
                 }
                 else if (pos != begin)
                 {
                     --pos;
                     if (pos->Contains(range))
                     {
-                        return &(*pos); 
+                        return &(*pos);
                     }
                 }
             }
             return NULL;
         }
         
-        Entry *
-        Back()
-        {
-            if (!m_entries.empty())
-                return &m_entries.back();
-            return NULL;
-        }
+    protected:
+        Collection m_entries;
+    };
 
-        const Entry *
-        Back() const
-        {
-            if (!m_entries.empty())
+    //----------------------------------------------------------------------
+    // A simple range  with data class where you get to define the type of
+    // the range base "B", the type used for the range byte size "S", and
+    // the type for the associated data "T".
+    //----------------------------------------------------------------------
+    template <typename B, typename S, typename T>
+    struct RangeData : public Range<B,S>
+    {
+        typedef T DataType;
+        
+        DataType data;
+        
+        RangeData () :
+            Range<B,S> (),
+            data ()
+        {
+        }
+        
+        RangeData (B base, S size) :
+            Range<B,S> (base, size),
+            data ()
+        {
+        }
+        
+        RangeData (B base, S size, DataType d) :
+            Range<B,S> (base, size),
+            data (d)
+        {
+        }
+        
+        bool
+        operator < (const RangeData &rhs) const
+        {
+            if (this->base == rhs.base)
+            {
+                if (this->size == rhs.size)
+                    return this->data < rhs.data;
+                else
+                    return this->size < rhs.size;
+            }
+            return this->base < rhs.base;
+        }
+        
+        bool
+        operator == (const RangeData &rhs) const
+        {
+            return this->GetRangeBase() == rhs.GetRangeBase() &&
+                   this->GetByteSize() == rhs.GetByteSize() &&
+                   this->data      == rhs.data;
+        }
+        
+        bool
+        operator != (const RangeData &rhs) const
+        {
+            return this->GetRangeBase() != rhs.GetRangeBase() ||
+                   this->GetByteSize() != rhs.GetByteSize() ||
+                   this->data      != rhs.data;
+        }
+    };
+    
+    template <typename B, typename S, typename T, unsigned N>
+    class RangeDataArray
+    {
+    public:
+        typedef RangeData<B,S,T> Entry;
+        typedef llvm::SmallVector<Entry, N> Collection;
+
+
+        RangeDataArray ()
+        {
+        }
+        
+        ~RangeDataArray()
+        {
+        }
+        
+        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());
+        }
+    
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+        bool
+        IsSorted () const
+        {
+            typename Collection::const_iterator pos, end, prev;
+            // 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 && *pos < *prev)
+                    return false;
+            }
+            return true;
+        }
+#endif
+
+        void
+        CombineConsecutiveEntriesWithEqualData ()
+        {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+            assert (IsSorted());
+#endif
+            typename Collection::iterator pos;
+            typename Collection::iterator end;
+            typename Collection::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)
+            {
+                Collection 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().SetRangeEnd (pos->GetRangeEnd());
+                    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
+        GetSize () const
+        {
+            return m_entries.size();
+        }
+        
+        const Entry *
+        GetEntryAtIndex (size_t i) const
+        {
+            if (i<m_entries.size())
+                return &m_entries[i];
+            return NULL;
+        }
+
+        // Clients must ensure that "i" is a valid index prior to calling this function
+        const Entry &
+        GetEntryRef (size_t i) const
+        {
+            return m_entries[i];
+        }
+
+        static bool
+        BaseLessThan (const Entry& lhs, const Entry& rhs)
+        {
+            return lhs.GetRangeBase() < rhs.GetRangeBase();
+        }
+        
+        uint32_t
+        FindEntryIndexThatContains (B addr) const
+        {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+            assert (IsSorted());
+#endif
+            if ( !m_entries.empty() )
+            {
+                Entry entry (addr, 1);
+                typename Collection::const_iterator begin = m_entries.begin();
+                typename Collection::const_iterator end = m_entries.end();
+                typename Collection::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+                
+                if (pos != end && pos->Contains(addr))
+                {
+                    return std::distance (begin, pos);
+                }
+                else if (pos != begin)
+                {
+                    --pos;
+                    if (pos->Contains(addr))
+                        return std::distance (begin, pos);
+                }
+            }
+            return UINT32_MAX;
+        }
+
+        Entry *
+        FindEntryThatContains (B addr)
+        {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+            assert (IsSorted());
+#endif
+            if ( !m_entries.empty() )
+            {
+                Entry entry;
+                entry.SetRangeBase(addr);
+                entry.SetByteSize(1);
+                typename Collection::iterator begin = m_entries.begin();
+                typename Collection::iterator end = m_entries.end();
+                typename Collection::iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+                
+                if (pos != end && pos->Contains(addr))
+                {
+                    return &(*pos); 
+                }
+                else if (pos != begin)
+                {
+                    --pos;
+                    if (pos->Contains(addr))
+                    {
+                        return &(*pos); 
+                    }
+                }
+            }
+            return NULL;
+        }
+        const Entry *
+        FindEntryThatContains (B addr) const
+        {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+            assert (IsSorted());
+#endif
+            if ( !m_entries.empty() )
+            {
+                Entry entry;
+                entry.SetRangeBase(addr);
+                entry.SetByteSize(1);
+                typename Collection::const_iterator begin = m_entries.begin();
+                typename Collection::const_iterator end = m_entries.end();
+                typename Collection::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+                
+                if (pos != end && pos->Contains(addr))
+                {
+                    return &(*pos); 
+                }
+                else if (pos != begin)
+                {
+                    --pos;
+                    if (pos->Contains(addr))
+                    {
+                        return &(*pos); 
+                    }
+                }
+            }
+            return NULL;
+        }
+        
+        const Entry *
+        FindEntryThatContains (const Entry &range) const
+        {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+            assert (IsSorted());
+#endif
+            if ( !m_entries.empty() )
+            {
+                typename Collection::const_iterator begin = m_entries.begin();
+                typename Collection::const_iterator end = m_entries.end();
+                typename Collection::const_iterator pos = std::lower_bound (begin, end, range, BaseLessThan);
+                
+                if (pos != end && pos->Contains(range))
+                {
+                    return &(*pos); 
+                }
+                else if (pos != begin)
+                {
+                    --pos;
+                    if (pos->Contains(range))
+                    {
+                        return &(*pos); 
+                    }
+                }
+            }
+            return NULL;
+        }
+        
+        Entry *
+        Back()
+        {
+            if (!m_entries.empty())
+                return &m_entries.back();
+            return NULL;
+        }
+
+        const Entry *
+        Back() const
+        {
+            if (!m_entries.empty())
                 return &m_entries.back();
             return NULL;
         }
@@ -759,7 +1045,268 @@ namespace lldb_private {
     protected:
         Collection m_entries;
     };
+
+    // Same as RangeDataArray, but uses std::vector as to not
+    // require static storage of N items in the class itself
+    template <typename B, typename S, typename T>
+    class RangeDataVector
+    {
+    public:
+        typedef RangeData<B,S,T> Entry;
+        typedef std::vector<Entry> Collection;
+        
+        RangeDataVector ()
+        {
+        }
+        
+        ~RangeDataVector()
+        {
+        }
+        
+        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());
+        }
+        
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+        bool
+        IsSorted () const
+        {
+            typename Collection::const_iterator pos, end, prev;
+            // 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 && *pos < *prev)
+                    return false;
+            }
+            return true;
+        }
+#endif
+        
+        void
+        CombineConsecutiveEntriesWithEqualData ()
+        {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+            assert (IsSorted());
+#endif
+            typename Collection::iterator pos;
+            typename Collection::iterator end;
+            typename Collection::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)
+            {
+                Collection 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().SetRangeEnd (pos->GetRangeEnd());
+                    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
+        GetSize () const
+        {
+            return m_entries.size();
+        }
+        
+        const Entry *
+        GetEntryAtIndex (size_t i) const
+        {
+            if (i<m_entries.size())
+                return &m_entries[i];
+            return NULL;
+        }
+        
+        // Clients must ensure that "i" is a valid index prior to calling this function
+        const Entry &
+        GetEntryRef (size_t i) const
+        {
+            return m_entries[i];
+        }
+        
+        static bool
+        BaseLessThan (const Entry& lhs, const Entry& rhs)
+        {
+            return lhs.GetRangeBase() < rhs.GetRangeBase();
+        }
+        
+        uint32_t
+        FindEntryIndexThatContains (B addr) const
+        {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+            assert (IsSorted());
+#endif
+            if ( !m_entries.empty() )
+            {
+                Entry entry (addr, 1);
+                typename Collection::const_iterator begin = m_entries.begin();
+                typename Collection::const_iterator end = m_entries.end();
+                typename Collection::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+                
+                if (pos != end && pos->Contains(addr))
+                {
+                    return std::distance (begin, pos);
+                }
+                else if (pos != begin)
+                {
+                    --pos;
+                    if (pos->Contains(addr))
+                        return std::distance (begin, pos);
+                }
+            }
+            return UINT32_MAX;
+        }
+        
+        Entry *
+        FindEntryThatContains (B addr)
+        {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+            assert (IsSorted());
+#endif
+            if ( !m_entries.empty() )
+            {
+                Entry entry;
+                entry.SetRangeBase(addr);
+                entry.SetByteSize(1);
+                typename Collection::iterator begin = m_entries.begin();
+                typename Collection::iterator end = m_entries.end();
+                typename Collection::iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+                
+                if (pos != end && pos->Contains(addr))
+                {
+                    return &(*pos);
+                }
+                else if (pos != begin)
+                {
+                    --pos;
+                    if (pos->Contains(addr))
+                    {
+                        return &(*pos);
+                    }
+                }
+            }
+            return NULL;
+        }
+        const Entry *
+        FindEntryThatContains (B addr) const
+        {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+            assert (IsSorted());
+#endif
+            if ( !m_entries.empty() )
+            {
+                Entry entry;
+                entry.SetRangeBase(addr);
+                entry.SetByteSize(1);
+                typename Collection::const_iterator begin = m_entries.begin();
+                typename Collection::const_iterator end = m_entries.end();
+                typename Collection::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+                
+                if (pos != end && pos->Contains(addr))
+                {
+                    return &(*pos); 
+                }
+                else if (pos != begin)
+                {
+                    --pos;
+                    if (pos->Contains(addr))
+                    {
+                        return &(*pos); 
+                    }
+                }
+            }
+            return NULL;
+        }
+        
+        const Entry *
+        FindEntryThatContains (const Entry &range) const
+        {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+            assert (IsSorted());
+#endif
+            if ( !m_entries.empty() )
+            {
+                typename Collection::const_iterator begin = m_entries.begin();
+                typename Collection::const_iterator end = m_entries.end();
+                typename Collection::const_iterator pos = std::lower_bound (begin, end, range, BaseLessThan);
                 
+                if (pos != end && pos->Contains(range))
+                {
+                    return &(*pos); 
+                }
+                else if (pos != begin)
+                {
+                    --pos;
+                    if (pos->Contains(range))
+                    {
+                        return &(*pos); 
+                    }
+                }
+            }
+            return NULL;
+        }
+        
+        Entry *
+        Back()
+        {
+            if (!m_entries.empty())
+                return &m_entries.back();
+            return NULL;
+        }
+        
+        const Entry *
+        Back() const
+        {
+            if (!m_entries.empty())
+                return &m_entries.back();
+            return NULL;
+        }
+        
+    protected:
+        Collection m_entries;
+    };
+                    
                 
     //----------------------------------------------------------------------
     // A simple range  with data class where you get to define the type of
@@ -816,7 +1363,6 @@ namespace lldb_private {
     {
     public:
         typedef AddressData<B,T> Entry;
-        //typedef std::vector<Entry> Collection;
         typedef llvm::SmallVector<Entry, N> Collection;
 
 

Modified: lldb/trunk/include/lldb/Core/Section.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Section.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Section.h (original)
+++ lldb/trunk/include/lldb/Core/Section.h Mon Mar  4 15:46:16 2013
@@ -61,9 +61,6 @@ public:
     lldb::SectionSP
     FindSectionContainingFileAddress (lldb::addr_t addr, uint32_t depth = UINT32_MAX) const;
 
-    lldb::SectionSP
-    FindSectionContainingLinkedFileAddress (lldb::addr_t vm_addr, uint32_t depth) const;
-
     bool
     GetSectionData (const DataExtractor& module_data, DataExtractor& section_data) const;
 
@@ -93,16 +90,6 @@ public:
 
 protected:
     collection  m_sections;
-
-    typedef RangeDataArray<uint64_t, uint64_t, collection::size_type, 1> SectionRangeCache;
-    mutable SectionRangeCache   m_range_cache;
-#ifdef LLDB_CONFIGURATION_DEBUG
-    mutable bool                m_finalized;
-#endif
-    
-    void BuildRangeCache() const;
-    
-    void InvalidateRangeCache() const;
 };
 
 
@@ -120,8 +107,8 @@ public:
              lldb::SectionType sect_type,
              lldb::addr_t file_vm_addr,
              lldb::addr_t vm_size,
-             uint64_t file_offset,
-             uint64_t file_size,
+             lldb::offset_t file_offset,
+             lldb::offset_t file_size,
              uint32_t flags);
 
     // Create a section that is a child of parent_section_sp
@@ -132,8 +119,8 @@ public:
              lldb::SectionType sect_type,
              lldb::addr_t file_vm_addr,
              lldb::addr_t vm_size,
-             uint64_t file_offset,
-             uint64_t file_size,
+             lldb::offset_t file_offset,
+             lldb::offset_t file_size,
              uint32_t flags);
 
     ~Section ();
@@ -168,26 +155,26 @@ public:
     bool
     ResolveContainedAddress (lldb::addr_t offset, Address &so_addr) const;
 
-    uint64_t
+    lldb::offset_t
     GetFileOffset () const
     {
         return m_file_offset;
     }
 
     void
-    SetFileOffset (uint64_t file_offset) 
+    SetFileOffset (lldb::offset_t file_offset) 
     {
         m_file_offset = file_offset;
     }
 
-    uint64_t
+    lldb::offset_t
     GetFileSize () const
     {
         return m_file_size;
     }
 
     void
-    SetFileSize (uint64_t file_size)
+    SetFileSize (lldb::offset_t file_size)
     {
         m_file_size = file_size;
     }
@@ -239,31 +226,14 @@ public:
     IsDescendant (const Section *section);
 
     const ConstString&
-    GetName () const;
-
-    bool
-    Slide (lldb::addr_t slide_amount, bool slide_children);
-
-    void
-    SetLinkedLocation (const lldb::SectionSP &linked_section_sp, uint64_t linked_offset);
-
-    bool
-    ContainsLinkedFileAddress (lldb::addr_t vm_addr) const;
-
-    lldb::SectionSP
-    GetLinkedSection () const
+    GetName () const
     {
-        return m_linked_section_wp.lock();
+        return m_name;
     }
 
-    uint64_t
-    GetLinkedOffset () const
-    {
-        return m_linked_offset;
-    }
+    bool
+    Slide (lldb::addr_t slide_amount, bool slide_children);
 
-    lldb::addr_t
-    GetLinkedFileAddress () const;
 
     lldb::SectionType
     GetType () const
@@ -304,8 +274,8 @@ protected:
     lldb::addr_t    m_file_addr;        // The absolute file virtual address range of this section if m_parent == NULL,
                                         // offset from parent file virtual address if m_parent != NULL
     lldb::addr_t    m_byte_size;        // Size in bytes that this section will occupy in memory at runtime
-    uint64_t        m_file_offset;      // Object file offset (if any)
-    uint64_t        m_file_size;        // Object file size (can be smaller than m_byte_size for zero filled sections...)
+    lldb::offset_t  m_file_offset;      // Object file offset (if any)
+    lldb::offset_t  m_file_size;        // Object file size (can be smaller than m_byte_size for zero filled sections...)
     SectionList     m_children;         // Child sections
     bool            m_fake:1,           // If true, then this section only can contain the address if one of its
                                         // children contains an address. This allows for gaps between the children
@@ -313,8 +283,6 @@ protected:
                                         // hits unless the children contain the address.
                     m_encrypted:1,      // Set to true if the contents are encrypted
                     m_thread_specific:1;// This section is thread specific
-    lldb::SectionWP m_linked_section_wp;
-    uint64_t        m_linked_offset;
 private:
     DISALLOW_COPY_AND_ASSIGN (Section);
 };

Modified: lldb/trunk/include/lldb/Expression/DWARFExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/DWARFExpression.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/DWARFExpression.h (original)
+++ lldb/trunk/include/lldb/Expression/DWARFExpression.h Mon Mar  4 15:46:16 2013
@@ -139,21 +139,20 @@ public:
     /// us detect if a variable is a global or static variable since
     /// there is no other indication from DWARF debug info.
     ///
-    /// @param[in] file_addr
-    ///     The file address to search for in the location. 
+    /// @param[in] op_addr_idx
+    ///     The DW_OP_addr index to retrieve in case there is more than
+    ///     one DW_OP_addr opcode in the location byte stream.
     ///
     /// @param[out] error
     ///     If the location stream contains unknown DW_OP opcodes or the
     ///     data is missing, \a error will be set to \b true.
     ///
     /// @return
-    ///     True if IsLocationList() is false and the \a file_addr was
-    ///     is contained in a DW_OP_addr location opcode or if \a file_addr
-    ///     was invalid and there are any DW_OP_addr opcodes, false 
-    ///     otherwise.
+    ///     LLDB_INVALID_ADDRESS if the location doesn't contain a
+    ///     DW_OP_addr for \a op_addr_idx, otherwise a valid file address
     //------------------------------------------------------------------
-    bool
-    LocationContains_DW_OP_addr (lldb::addr_t file_addr, bool &error) const;
+    lldb::addr_t
+    GetLocation_DW_OP_addr (uint32_t op_addr_idx, bool &error) const;
 
     bool
     Update_DW_OP_addr (lldb::addr_t file_addr);

Modified: lldb/trunk/include/lldb/Symbol/LineTable.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/LineTable.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/LineTable.h (original)
+++ lldb/trunk/include/lldb/Symbol/LineTable.h Mon Mar  4 15:46:16 2013
@@ -75,8 +75,7 @@ public:
 
     // Called when you can't guarantee the addresses are in increasing order
     void
-    InsertLineEntry (const lldb::SectionSP& section_sp,
-                     lldb::addr_t section_offset,
+    InsertLineEntry (lldb::addr_t file_addr,
                      uint32_t line,
                      uint16_t column,
                      uint16_t file_idx,
@@ -94,8 +93,7 @@ public:
     // inserted in this line table.
     void
     AppendLineEntryToSequence (LineSequence* sequence,
-                               const lldb::SectionSP& section_sp,
-                               lldb::addr_t section_offset,
+                               lldb::addr_t file_addr,
                                uint32_t line,
                                uint16_t column,
                                uint16_t file_idx,
@@ -253,15 +251,29 @@ public:
     size_t
     GetContiguousFileAddressRanges (FileAddressRanges &file_ranges, bool append);
 
+    //------------------------------------------------------------------
+    /// Given a file range link map, relink the current line table
+    /// and return a fixed up line table.
+    ///
+    /// @param[out] file_range_map
+    ///     A collection of file ranges that maps to new file ranges
+    ///     that will be used when linking the line table.
+    ///
+    /// @return
+    ///     A new line table if at least one line table entry was able
+    ///     to be mapped.
+    //------------------------------------------------------------------
+    typedef RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t> FileRangeMap;
+
+    LineTable *
+    LinkLineTable (const FileRangeMap &file_range_map);
+
 protected:
 
     struct Entry
     {
-        enum { kInvalidSectIdx = UINT32_MAX };
-
         Entry () :
-            sect_idx (kInvalidSectIdx),
-            sect_offset (0),
+            file_addr (LLDB_INVALID_ADDRESS),
             line (0),
             column (0),
             file_idx (0),
@@ -273,8 +285,7 @@ protected:
         {
         }
 
-        Entry ( uint32_t _sect_idx,
-                lldb::addr_t _sect_offset,
+        Entry ( lldb::addr_t _file_addr,
                 uint32_t _line,
                 uint16_t _column,
                 uint16_t _file_idx,
@@ -283,8 +294,7 @@ protected:
                 bool _is_prologue_end,
                 bool _is_epilogue_begin,
                 bool _is_terminal_entry) :
-            sect_idx (_sect_idx),
-            sect_offset (_sect_offset),
+            file_addr (_file_addr),
             line (_line),
             column (_column),
             file_idx (_file_idx),
@@ -294,10 +304,6 @@ protected:
             is_epilogue_begin (_is_epilogue_begin),
             is_terminal_entry (_is_terminal_entry)
         {
-            // We have reserved 32 bits for the section offset which should
-            // be enough, but if it isn't then we need to make m_section_offset
-            // bigger
-            assert(_sect_offset <= UINT32_MAX);
         }
 
         int
@@ -306,8 +312,7 @@ protected:
         void
         Clear ()
         {
-            sect_idx = kInvalidSectIdx;
-            sect_offset = 0;
+            file_addr = LLDB_INVALID_ADDRESS;
             line = 0;
             column = 0;
             file_idx = 0;
@@ -323,7 +328,7 @@ protected:
         {
             // Compare the sections before calling
             #define SCALAR_COMPARE(a,b) if (a < b) return -1; if (a > b) return +1
-            SCALAR_COMPARE (lhs.sect_offset, rhs.sect_offset);
+            SCALAR_COMPARE (lhs.file_addr, rhs.file_addr);
             SCALAR_COMPARE (lhs.line, rhs.line);
             SCALAR_COMPARE (lhs.column, rhs.column);
             SCALAR_COMPARE (lhs.is_start_of_statement, rhs.is_start_of_statement);
@@ -350,16 +355,13 @@ protected:
 
         static bool EntryAddressLessThan (const Entry& lhs, const Entry& rhs)
         {
-            if (lhs.sect_idx == rhs.sect_idx)
-                return lhs.sect_offset < rhs.sect_offset;
-            return lhs.sect_idx < rhs.sect_idx;
+            return lhs.file_addr < rhs.file_addr;
         }
 
         //------------------------------------------------------------------
         // Member variables.
         //------------------------------------------------------------------
-        uint32_t    sect_idx;                   ///< The section index for this line entry.
-        uint32_t    sect_offset;                ///< The offset into the section for this line entry.
+        lldb::addr_t file_addr;                 ///< The file address for this line entry
         uint32_t    line;                       ///< The source line number, or zero if there is no line number information.
         uint16_t    column;                     ///< The column number of the source line, or zero if there is no column information.
         uint16_t    file_idx:11,                ///< The file index into CompileUnit's file table, or zero if there is no file information.
@@ -386,7 +388,6 @@ protected:
     // Member variables.
     //------------------------------------------------------------------
     CompileUnit* m_comp_unit;   ///< The compile unit that this line table belongs to.
-    SectionList m_section_list; ///< The list of sections that at least one of the line entries exists in.
     entry_collection m_entries; ///< The collection of line entries in this line table.
 
     //------------------------------------------------------------------
@@ -406,14 +407,12 @@ protected:
         virtual void
         Clear();
 
-        entry_collection m_seq_entries; ///< The collection of line entries in this sequence.
+        entry_collection m_entries; ///< The collection of line entries in this sequence.
     };
 
     bool
     ConvertEntryAtIndexToLineEntry (uint32_t idx, LineEntry &line_entry);
 
-    lldb_private::Section *
-    GetSectionForEntryIndex (uint32_t idx);
 private:
     DISALLOW_COPY_AND_ASSIGN (LineTable);
 };

Modified: lldb/trunk/include/lldb/Symbol/ObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ObjectFile.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ObjectFile.h (original)
+++ lldb/trunk/include/lldb/Symbol/ObjectFile.h Mon Mar  4 15:46:16 2013
@@ -351,6 +351,17 @@ public:
     GetSymtab () = 0;
 
     //------------------------------------------------------------------
+    /// Frees the symbol table.
+    ///
+    /// This function should only be used when an object file is
+    ///
+    /// @return
+    ///     The symbol table for this object file.
+    //------------------------------------------------------------------
+    virtual void
+    ClearSymtab ();
+    
+    //------------------------------------------------------------------
     /// Gets the UUID for this object file.
     ///
     /// If the object file format contains a UUID, the value should be
@@ -610,6 +621,8 @@ protected:
     lldb_private::UnwindTable m_unwind_table; /// < Table of FuncUnwinders objects created for this ObjectFile's functions
     lldb::ProcessWP m_process_wp;
     const lldb::addr_t m_memory_addr;
+    std::auto_ptr<lldb_private::SectionList> m_sections_ap;
+    std::auto_ptr<lldb_private::Symtab> m_symtab_ap;
     
     //------------------------------------------------------------------
     /// Sets the architecture for a module.  At present the architecture

Modified: lldb/trunk/source/Core/Address.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Address.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Core/Address.cpp (original)
+++ lldb/trunk/source/Core/Address.cpp Mon Mar  4 15:46:16 2013
@@ -1015,29 +1015,6 @@ lldb_private::operator!= (const Address&
             a.GetOffset()  != rhs.GetOffset();
 }
 
-bool
-Address::IsLinkedAddress () const
-{
-    SectionSP section_sp (GetSection());
-    return section_sp && section_sp->GetLinkedSection();
-}
-
-
-void
-Address::ResolveLinkedAddress ()
-{
-    SectionSP section_sp (GetSection());
-    if (section_sp)
-    {
-        SectionSP linked_section_sp (section_sp->GetLinkedSection());
-        if (linked_section_sp)
-        {
-            m_offset += section_sp->GetLinkedOffset();
-            m_section_wp = linked_section_sp;
-        }
-    }
-}
-
 AddressClass
 Address::GetAddressClass () const
 {

Modified: lldb/trunk/source/Core/Section.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Section.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Core/Section.cpp (original)
+++ lldb/trunk/source/Core/Section.cpp Mon Mar  4 15:46:16 2013
@@ -21,8 +21,8 @@ Section::Section (const ModuleSP &module
                   SectionType sect_type,
                   addr_t file_addr,
                   addr_t byte_size,
-                  uint64_t file_offset,
-                  uint64_t file_size,
+                  lldb::offset_t file_offset,
+                  lldb::offset_t file_size,
                   uint32_t flags) :
     ModuleChild     (module_sp),
     UserID          (sect_id),
@@ -37,9 +37,7 @@ Section::Section (const ModuleSP &module
     m_children      (),
     m_fake          (false),
     m_encrypted     (false),
-    m_thread_specific (false),
-    m_linked_section_wp(),
-    m_linked_offset (0)
+    m_thread_specific (false)
 {
 //    printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s\n",
 //            this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, name.GetCString());
@@ -52,8 +50,8 @@ Section::Section (const lldb::SectionSP
                   SectionType sect_type,
                   addr_t file_addr,
                   addr_t byte_size,
-                  uint64_t file_offset,
-                  uint64_t file_size,
+                  lldb::offset_t file_offset,
+                  lldb::offset_t file_size,
                   uint32_t flags) :
     ModuleChild     (module_sp),
     UserID          (sect_id),
@@ -68,9 +66,7 @@ Section::Section (const lldb::SectionSP
     m_children      (),
     m_fake          (false),
     m_encrypted     (false),
-    m_thread_specific (false),
-    m_linked_section_wp(),
-    m_linked_offset (0)
+    m_thread_specific (false)
 {
 //    printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s.%s\n",
 //            this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, parent_section_sp->GetName().GetCString(), name.GetCString());
@@ -83,15 +79,6 @@ Section::~Section()
 //    printf ("Section::~Section(%p)\n", this);
 }
 
-const ConstString&
-Section::GetName() const
-{
-    SectionSP linked_section_sp (m_linked_section_wp.lock());
-    if (linked_section_sp)
-        return linked_section_sp->GetName();
-    return m_name;
-}
-
 addr_t
 Section::GetFileAddress () const
 {
@@ -119,43 +106,21 @@ Section::GetOffset () const
     return 0;
 }
 
-
-addr_t
-Section::GetLinkedFileAddress () const
-{
-    SectionSP linked_section_sp (m_linked_section_wp.lock());
-    if (linked_section_sp)
-        return linked_section_sp->GetFileAddress() + m_linked_offset;
-    return LLDB_INVALID_ADDRESS;
-}
-
-
 addr_t
 Section::GetLoadBaseAddress (Target *target) const
 {
     addr_t load_base_addr = LLDB_INVALID_ADDRESS;
-    SectionSP linked_section_sp (m_linked_section_wp.lock());
-    if (linked_section_sp)
+    SectionSP parent_sp (GetParent ());
+    if (parent_sp)
     {
-        load_base_addr = linked_section_sp->GetLoadBaseAddress(target);
+        load_base_addr = parent_sp->GetLoadBaseAddress (target);
         if (load_base_addr != LLDB_INVALID_ADDRESS)
-            load_base_addr += m_linked_offset;
+            load_base_addr += GetOffset();
     }
     else
     {
-        SectionSP parent_sp (GetParent ());
-        if (parent_sp)
-        {
-            load_base_addr = parent_sp->GetLoadBaseAddress (target);
-            if (load_base_addr != LLDB_INVALID_ADDRESS)
-                load_base_addr += GetOffset();
-        }
-        else
-        {
-            load_base_addr = target->GetSectionLoadList().GetSectionLoadAddress (const_cast<Section *>(this)->shared_from_this());
-        }
+        load_base_addr = target->GetSectionLoadList().GetSectionLoadAddress (const_cast<Section *>(this)->shared_from_this());
     }
-
     return load_base_addr;
 }
 
@@ -174,22 +139,13 @@ Section::ResolveContainedAddress (addr_t
                 return child_section->ResolveContainedAddress (offset - child_offset, so_addr);
         }
     }
-    SectionSP linked_section_sp (m_linked_section_wp.lock());
-    if (linked_section_sp)
-    {
-        so_addr.SetOffset(m_linked_offset + offset);
-        so_addr.SetSection(linked_section_sp);
-    }
-    else
-    {
-        so_addr.SetOffset(offset);
-        so_addr.SetSection(const_cast<Section *>(this)->shared_from_this());
-        
+    so_addr.SetOffset(offset);
+    so_addr.SetSection(const_cast<Section *>(this)->shared_from_this());
+    
 #ifdef LLDB_CONFIGURATION_DEBUG
-        // For debug builds, ensure that there are no orphaned (i.e., moduleless) sections.
-        assert(GetModule().get());
+    // For debug builds, ensure that there are no orphaned (i.e., moduleless) sections.
+    assert(GetModule().get());
 #endif
-    }
     return true;
 }
 
@@ -208,21 +164,6 @@ Section::ContainsFileAddress (addr_t vm_
     return false;
 }
 
-bool
-Section::ContainsLinkedFileAddress (addr_t vm_addr) const
-{
-    const addr_t linked_file_addr = GetLinkedFileAddress();
-    if (linked_file_addr != LLDB_INVALID_ADDRESS)
-    {
-        if (linked_file_addr <= vm_addr)
-        {
-            const addr_t offset = vm_addr - linked_file_addr;
-            return offset < GetByteSize();
-        }
-    }
-    return false;
-}
-
 int
 Section::Compare (const Section& a, const Section& b)
 {
@@ -261,12 +202,11 @@ Section::Dump (Stream *s, Target *target
     bool resolved = true;
     addr_t addr = LLDB_INVALID_ADDRESS;
 
-    SectionSP linked_section_sp (m_linked_section_wp.lock());
     if (GetByteSize() == 0)
         s->Printf("%39s", "");
     else
     {
-        if (target && linked_section_sp.get() == NULL)
+        if (target)
             addr = GetLoadBaseAddress (target);
 
         if (addr == LLDB_INVALID_ADDRESS)
@@ -286,35 +226,6 @@ Section::Dump (Stream *s, Target *target
 
     s->EOL();
 
-    if (linked_section_sp)
-    {
-        addr = LLDB_INVALID_ADDRESS;
-        resolved = true;
-        if (target)
-        {
-            addr = linked_section_sp->GetLoadBaseAddress(target);
-            if (addr != LLDB_INVALID_ADDRESS)
-                addr += m_linked_offset;
-        }
-
-        if (addr == LLDB_INVALID_ADDRESS)
-        {
-            if (target)
-                resolved = false;
-            addr = linked_section_sp->GetFileAddress() + m_linked_offset;
-        }
-
-        int indent = 28 + s->GetIndentLevel();
-        s->Printf("%*.*s", indent, indent, "");
-        VMRange linked_range(addr, addr + m_byte_size);
-        linked_range.Dump (s, 0);
-        indent = 3 * (sizeof(uint32_t) * 2 + 2 + 1) + 1;
-        s->Printf("%c%*.*s", resolved ? ' ' : '*', indent, indent, "");
-
-        linked_section_sp->DumpName(s);
-        s->Printf(" + 0x%" PRIx64 "\n", m_linked_offset);
-    }
-
     if (depth > 0)
         m_children.Dump(s, target, false, depth - 1);
 }
@@ -371,22 +282,10 @@ Section::Slide (addr_t slide_amount, boo
     return false;
 }
 
-void
-Section::SetLinkedLocation (const lldb::SectionSP &linked_section_sp, uint64_t linked_offset)
-{
-    if (linked_section_sp)
-        m_module_wp = linked_section_sp->GetModule();
-    m_linked_section_wp = linked_section_sp;
-    m_linked_offset  = linked_offset;
-}
-
 #pragma mark SectionList
 
 SectionList::SectionList () :
     m_sections()
-#ifdef LLDB_CONFIGURATION_DEBUG
-    , m_finalized(false)
-#endif
 {
 }
 
@@ -401,7 +300,6 @@ SectionList::AddSection (const lldb::Sec
     assert (section_sp.get());
     size_t section_index = m_sections.size();
     m_sections.push_back(section_sp);
-    InvalidateRangeCache();
     return section_index;
 }
 
@@ -441,7 +339,6 @@ SectionList::ReplaceSection (user_id_t s
         if ((*sect_iter)->GetID() == sect_id)
         {
             *sect_iter = sect_sp;
-            InvalidateRangeCache();
             return true;
         }
         else if (depth > 0)
@@ -575,71 +472,6 @@ SectionList::FindSectionContainingFileAd
     return sect_sp;
 }
 
-void
-SectionList::BuildRangeCache() const
-{
-    m_range_cache.Clear();
-    
-    for (collection::size_type idx = 0, last_idx = m_sections.size();
-         idx < last_idx;
-         ++idx)
-    {
-        Section *sect = m_sections[idx].get();
-        
-        addr_t linked_file_address = sect->GetLinkedFileAddress();
-        
-        if (linked_file_address != LLDB_INVALID_ADDRESS)
-            m_range_cache.Append(SectionRangeCache::Entry(linked_file_address, sect->GetByteSize(), idx));
-    }
-    
-    m_range_cache.Sort();
-    
-#ifdef LLDB_CONFIGURATION_DEBUG
-    m_finalized = true;
-#endif
-}
-
-void
-SectionList::InvalidateRangeCache() const
-{
-#ifdef LLDB_CONFIGURATION_DEBUG
-    assert(!m_finalized);
-#endif
-    m_range_cache.Clear();
-}
-
-SectionSP
-SectionList::FindSectionContainingLinkedFileAddress (addr_t vm_addr, uint32_t depth) const
-{
-    //if (m_range_cache.IsEmpty())
-    //    BuildRangeCache();
-#ifdef LLDB_CONFIGURATION_DEBUG
-    assert(m_finalized);
-#endif
-    
-    SectionRangeCache::Entry *entry = m_range_cache.FindEntryThatContains(vm_addr);
-    
-    if (entry)
-        return m_sections[entry->data];
-        
-    if (depth == 0)
-        return SectionSP();
-    
-    for (const_iterator si = m_sections.begin(), se = m_sections.end();
-         si != se;
-         ++si)
-    {
-        Section *sect = si->get();
-        
-        SectionSP sect_sp = sect->GetChildren().FindSectionContainingLinkedFileAddress(vm_addr, depth - 1);
-            
-        if (sect_sp)
-            return sect_sp;
-    }
-    
-    return SectionSP();
-}
-
 bool
 SectionList::ContainsSection(user_id_t sect_id) const
 {
@@ -681,15 +513,12 @@ SectionList::Slide (addr_t slide_amount,
         if ((*pos)->Slide(slide_amount, slide_children))
             ++count;
     }
-    InvalidateRangeCache();
     return count;
 }
 
 void
 SectionList::Finalize ()
 {
-    BuildRangeCache();
-    
     for (const_iterator si = m_sections.begin(), se = m_sections.end();
          si != se;
          ++si)

Modified: lldb/trunk/source/Expression/DWARFExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/DWARFExpression.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Expression/DWARFExpression.cpp (original)
+++ lldb/trunk/source/Expression/DWARFExpression.cpp Mon Mar  4 15:46:16 2013
@@ -1009,24 +1009,25 @@ GetOpcodeDataSize (const DataExtractor &
     return LLDB_INVALID_OFFSET;
 }
 
-bool
-DWARFExpression::LocationContains_DW_OP_addr (lldb::addr_t file_addr, bool &error) const
+lldb::addr_t
+DWARFExpression::GetLocation_DW_OP_addr (uint32_t op_addr_idx, bool &error) const
 {
     error = false;
     if (IsLocationList())
-        return false;
+        return LLDB_INVALID_ADDRESS;
     lldb::offset_t offset = 0;
+    uint32_t curr_op_addr_idx = 0;
     while (m_data.ValidOffset(offset))
     {
         const uint8_t op = m_data.GetU8(&offset);
         
         if (op == DW_OP_addr)
         {
-            if (file_addr == LLDB_INVALID_ADDRESS)
-                return true;
-            addr_t op_file_addr = m_data.GetAddress(&offset);
-            if (op_file_addr == file_addr)
-                return true;
+            const lldb::addr_t op_file_addr = m_data.GetAddress(&offset);
+            if (curr_op_addr_idx == op_addr_idx)
+                return op_file_addr;
+            else
+                ++curr_op_addr_idx;
         }
         else
         {
@@ -1039,7 +1040,7 @@ DWARFExpression::LocationContains_DW_OP_
             offset += op_arg_size;
         }
     }
-    return false;
+    return LLDB_INVALID_ADDRESS;
 }
 
 bool

Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Mon Mar  4 15:46:16 2013
@@ -254,8 +254,6 @@ ObjectFileELF::ObjectFileELF (const lldb
     m_header(),
     m_program_headers(),
     m_section_headers(),
-    m_sections_ap(),
-    m_symtab_ap(),
     m_filespec_ap(),
     m_shstr_data()
 {

Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h Mon Mar  4 15:46:16 2013
@@ -153,12 +153,6 @@ private:
     /// Collection of symbols from the dynamic table.
     DynamicSymbolColl m_dynamic_symbols;
 
-    /// List of sections present in this ELF object file.
-    mutable std::auto_ptr<lldb_private::SectionList> m_sections_ap;
-
-    /// Table of all non-dynamic symbols present in this object file.
-    mutable std::auto_ptr<lldb_private::Symtab> m_symtab_ap;
-
     /// List of file specifications corresponding to the modules (shared
     /// libraries) on which this object file depends.
     mutable std::auto_ptr<lldb_private::FileSpecList> m_filespec_ap;

Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Mon Mar  4 15:46:16 2013
@@ -501,8 +501,6 @@ ObjectFileMachO::ObjectFileMachO(const l
                                  lldb::offset_t file_offset,
                                  lldb::offset_t length) :
     ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
-    m_sections_ap(),
-    m_symtab_ap(),
     m_mach_segments(),
     m_mach_sections(),
     m_entry_point_address(),
@@ -518,8 +516,6 @@ ObjectFileMachO::ObjectFileMachO (const
                                   const lldb::ProcessSP &process_sp,
                                   lldb::addr_t header_addr) :
     ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
-    m_sections_ap(),
-    m_symtab_ap(),
     m_mach_segments(),
     m_mach_sections(),
     m_entry_point_address(),

Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h Mon Mar  4 15:46:16 2013
@@ -146,8 +146,6 @@ public:
 
 protected:
     llvm::MachO::mach_header m_header;
-    mutable std::auto_ptr<lldb_private::SectionList> m_sections_ap;
-    mutable std::auto_ptr<lldb_private::Symtab> m_symtab_ap;
     static const lldb_private::ConstString &GetSegmentNameTEXT();
     static const lldb_private::ConstString &GetSegmentNameDATA();
     static const lldb_private::ConstString &GetSegmentNameOBJC();
@@ -157,7 +155,7 @@ protected:
     llvm::MachO::dysymtab_command m_dysymtab;
     std::vector<llvm::MachO::segment_command_64> m_mach_segments;
     std::vector<llvm::MachO::section_64> m_mach_sections;
-    typedef lldb_private::RangeArray<uint32_t, uint32_t, 1> FileRangeArray;
+    typedef lldb_private::RangeVector<uint32_t, uint32_t> FileRangeArray;
     lldb_private::Address  m_entry_point_address;
     FileRangeArray m_thread_context_offsets;
     bool m_thread_context_offsets_valid;

Modified: lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h (original)
+++ lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h Mon Mar  4 15:46:16 2013
@@ -229,8 +229,6 @@ protected:
 	typedef SectionHeaderColl::iterator			SectionHeaderCollIter;
 	typedef SectionHeaderColl::const_iterator	SectionHeaderCollConstIter;
 private:
-    mutable std::auto_ptr<lldb_private::SectionList> m_sections_ap;
-    mutable std::auto_ptr<lldb_private::Symtab> m_symtab_ap;
 	dos_header_t		m_dos_header;
 	coff_header_t		m_coff_header;
 	coff_opt_header_t	m_coff_header_opt;

Modified: lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.h (original)
+++ lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.h Mon Mar  4 15:46:16 2013
@@ -130,7 +130,7 @@ private:
     // For ProcessMachCore only
     //------------------------------------------------------------------
     typedef lldb_private::Range<uint32_t, uint32_t> FileRange;
-    typedef lldb_private::RangeDataArray<lldb::addr_t, lldb::addr_t, FileRange, 1> VMRangeToFileOffset;
+    typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, FileRange> VMRangeToFileOffset;
 
     VMRangeToFileOffset m_core_aranges;
     lldb::ModuleSP m_core_module_sp;

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h Mon Mar  4 15:46:16 2013
@@ -7,8 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef SymbolFileDWARF_DWARFDebugLine_h_
-#define SymbolFileDWARF_DWARFDebugLine_h_
+#ifndef SymbolFileDWARF_DWARFDebugMacinfo_h_
+#define SymbolFileDWARF_DWARFDebugMacinfo_h_
 
 #include "SymbolFileDWARF.h"
 
@@ -26,4 +26,4 @@ public:
 };
 
 
-#endif  // SymbolFileDWARF_DWARFDebugLine_h_
+#endif  // SymbolFileDWARF_DWARFDebugMacinfo_h_

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp Mon Mar  4 15:46:16 2013
@@ -182,9 +182,9 @@ LogChannelDWARF::ListCategories (Stream
                   "  line - log the parsing if .debug_line\n"
                   "  pubnames - log the parsing if .debug_pubnames\n"
                   "  pubtypes - log the parsing if .debug_pubtypes\n"
-                  "  lookups - log any lookups that happen by name, regex, or address\n\n"
-                  "  completion - log struct/unions/class type completions\n\n"
-                  "  map - log insertions of object files into DWARF debug maps\n\n",
+                  "  lookups - log any lookups that happen by name, regex, or address\n"
+                  "  completion - log struct/unions/class type completions\n"
+                  "  map - log insertions of object files into DWARF debug maps\n",
                   SymbolFileDWARF::GetPluginNameStatic());
 }
 

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Mon Mar  4 15:46:16 2013
@@ -891,28 +891,40 @@ SymbolFileDWARF::ParseCompileUnitFunctio
 
             assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
 
-            func_range.GetBaseAddress().ResolveLinkedAddress();
-
-            const user_id_t func_user_id = MakeUserID(die->GetOffset());
-            func_sp.reset(new Function (sc.comp_unit,
-                                        func_user_id,       // UserID is the DIE offset
-                                        func_user_id,
-                                        func_name,
-                                        func_type,
-                                        func_range));           // first address range
-
-            if (func_sp.get() != NULL)
-            {
-                if (frame_base.IsValid())
-                    func_sp->GetFrameBaseExpression() = frame_base;
-                sc.comp_unit->AddFunction(func_sp);
-                return func_sp.get();
+            if (FixupAddress (func_range.GetBaseAddress()))
+            {
+                const user_id_t func_user_id = MakeUserID(die->GetOffset());
+                func_sp.reset(new Function (sc.comp_unit,
+                                            MakeUserID(func_user_id),       // UserID is the DIE offset
+                                            MakeUserID(func_user_id),
+                                            func_name,
+                                            func_type,
+                                            func_range));           // first address range
+
+                if (func_sp.get() != NULL)
+                {
+                    if (frame_base.IsValid())
+                        func_sp->GetFrameBaseExpression() = frame_base;
+                    sc.comp_unit->AddFunction(func_sp);
+                    return func_sp.get();
+                }
             }
         }
     }
     return NULL;
 }
 
+bool
+SymbolFileDWARF::FixupAddress (Address &addr)
+{
+    SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile ();
+    if (debug_map_symfile)
+    {
+        return debug_map_symfile->LinkOSOAddress(addr);
+    }
+    // This is a normal DWARF file, no address fixups need to happen
+    return true;
+}
 lldb::LanguageType
 SymbolFileDWARF::ParseCompileUnitLanguage (const SymbolContext& sc)
 {
@@ -983,15 +995,7 @@ SymbolFileDWARF::ParseCompileUnitSupport
 struct ParseDWARFLineTableCallbackInfo
 {
     LineTable* line_table;
-    const SectionList *section_list;
-    lldb::addr_t prev_sect_file_base_addr;
-    lldb::addr_t curr_sect_file_base_addr;
-    bool is_oso_for_debug_map;
-    bool prev_in_final_executable;
-    DWARFDebugLine::Row prev_row;
-    SectionSP prev_section_sp;
-    SectionSP curr_section_sp;
-    llvm::OwningPtr<LineSequence> curr_sequence_ap;
+    std::auto_ptr<LineSequence> sequence_ap;
 };
 
 //----------------------------------------------------------------------
@@ -1000,7 +1004,6 @@ struct ParseDWARFLineTableCallbackInfo
 static void
 ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
 {
-    LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
     if (state.row == DWARFDebugLine::State::StartParsingLineTable)
     {
         // Just started parsing the line table
@@ -1012,166 +1015,32 @@ ParseDWARFLineTableCallback(dw_offset_t
     else
     {
         ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
-        // We have a new row, lets append it
-
-        if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
-        {
-            info->prev_section_sp = info->curr_section_sp;
-            info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
-            // If this is an end sequence entry, then we subtract one from the
-            // address to make sure we get an address that is not the end of
-            // a section.
-            if (state.end_sequence && state.address != 0)
-                info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
-            else
-                info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
-
-            if (info->curr_section_sp.get())
-                info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
-            else
-                info->curr_sect_file_base_addr = 0;
-        }
-        if (info->curr_section_sp.get())
-        {
-            lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
-            // Check for the fancy section magic to determine if we
-
-            if (info->is_oso_for_debug_map)
-            {
-                // When this is a debug map object file that contains DWARF
-                // (referenced from an N_OSO debug map nlist entry) we will have
-                // a file address in the file range for our section from the
-                // original .o file, and a load address in the executable that
-                // contains the debug map.
-                //
-                // If the sections for the file range and load range are
-                // different, we have a remapped section for the function and
-                // this address is resolved. If they are the same, then the
-                // function for this address didn't make it into the final
-                // executable.
-                bool curr_in_final_executable = (bool) info->curr_section_sp->GetLinkedSection ();
-
-                // If we are doing DWARF with debug map, then we need to carefully
-                // add each line table entry as there may be gaps as functions
-                // get moved around or removed.
-                if (!info->prev_row.end_sequence && info->prev_section_sp.get())
-                {
-                    if (info->prev_in_final_executable)
-                    {
-                        bool terminate_previous_entry = false;
-                        if (!curr_in_final_executable)
-                        {
-                            // Check for the case where the previous line entry
-                            // in a function made it into the final executable,
-                            // yet the current line entry falls in a function
-                            // that didn't. The line table used to be contiguous
-                            // through this address range but now it isn't. We
-                            // need to terminate the previous line entry so
-                            // that we can reconstruct the line range correctly
-                            // for it and to keep the line table correct.
-                            terminate_previous_entry = true;
-                        }
-                        else if (info->curr_section_sp.get() != info->prev_section_sp.get())
-                        {
-                            // Check for cases where the line entries used to be
-                            // contiguous address ranges, but now they aren't.
-                            // This can happen when order files specify the
-                            // ordering of the functions.
-                            lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
-                            Section *curr_sect = info->curr_section_sp.get();
-                            Section *prev_sect = info->prev_section_sp.get();
-                            assert (curr_sect->GetLinkedSection());
-                            assert (prev_sect->GetLinkedSection());
-                            lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
-                            lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
-                            lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
-                            lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
-                            if (object_file_addr_delta != linked_file_addr_delta)
-                                terminate_previous_entry = true;
-                        }
-
-                        if (terminate_previous_entry)
-                        {
-                            line_table->InsertLineEntry (info->prev_section_sp,
-                                                         state.address - info->prev_sect_file_base_addr,
-                                                         info->prev_row.line,
-                                                         info->prev_row.column,
-                                                         info->prev_row.file,
-                                                         false,                 // is_stmt
-                                                         false,                 // basic_block
-                                                         false,                 // state.prologue_end
-                                                         false,                 // state.epilogue_begin
-                                                         true);                 // end_sequence);
-                        }
-                    }
-                }
-
-                if (curr_in_final_executable)
-                {
-                    line_table->InsertLineEntry (info->curr_section_sp,
-                                                 curr_line_section_offset,
-                                                 state.line,
-                                                 state.column,
-                                                 state.file,
-                                                 state.is_stmt,
-                                                 state.basic_block,
-                                                 state.prologue_end,
-                                                 state.epilogue_begin,
-                                                 state.end_sequence);
-                    info->prev_section_sp = info->curr_section_sp;
-                }
-                else
-                {
-                    // If the current address didn't make it into the final
-                    // executable, the current section will be the __text
-                    // segment in the .o file, so we need to clear this so
-                    // we can catch the next function that did make it into
-                    // the final executable.
-                    info->prev_section_sp.reset();
-                    info->curr_section_sp.reset();
-                }
+        LineTable* line_table = info->line_table;
 
-                info->prev_in_final_executable = curr_in_final_executable;
-            }
-            else
-            {
-                // We are not in an object file that contains DWARF for an
-                // N_OSO, this is just a normal DWARF file. The DWARF spec
-                // guarantees that the addresses will be in increasing order
-                // for a sequence, but the line table for a single compile unit
-                // may contain multiple sequences so we append entries to the
-                // current sequence until we find its end, then we merge the
-                // sequence into the main line table collection.
-
-                // If this is our first time here, we need to create a 
-                // sequence container.
-                if (!info->curr_sequence_ap)
-                {
-                    info->curr_sequence_ap.reset(line_table->CreateLineSequenceContainer());
-                    assert(info->curr_sequence_ap);
-                }
-                line_table->AppendLineEntryToSequence(info->curr_sequence_ap.get(),
-                                                      info->curr_section_sp,
-                                                      curr_line_section_offset,
-                                                      state.line,
-                                                      state.column,
-                                                      state.file,
-                                                      state.is_stmt,
-                                                      state.basic_block,
-                                                      state.prologue_end,
-                                                      state.epilogue_begin,
-                                                      state.end_sequence);
-                if (state.end_sequence)
-                {
-                    // First, put the current sequence into the line table.
-                    line_table->InsertSequence(info->curr_sequence_ap.get());
-                    // Then, empty it to prepare for the next sequence.
-                    info->curr_sequence_ap->Clear();
-                }
-            }
+        // If this is our first time here, we need to create a
+        // sequence container.
+        if (!info->sequence_ap.get())
+        {
+            info->sequence_ap.reset(line_table->CreateLineSequenceContainer());
+            assert(info->sequence_ap.get());
+        }
+        line_table->AppendLineEntryToSequence (info->sequence_ap.get(),
+                                               state.address,
+                                               state.line,
+                                               state.column,
+                                               state.file,
+                                               state.is_stmt,
+                                               state.basic_block,
+                                               state.prologue_end,
+                                               state.epilogue_begin,
+                                               state.end_sequence);
+        if (state.end_sequence)
+        {
+            // First, put the current sequence into the line table.
+            line_table->InsertSequence(info->sequence_ap.get());
+            // Then, empty it to prepare for the next sequence.
+            info->sequence_ap->Clear();
         }
-
-        info->prev_row = state;
     }
 }
 
@@ -1194,22 +1063,23 @@ SymbolFileDWARF::ParseCompileUnitLineTab
                 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
                 if (line_table_ap.get())
                 {
-                    ParseDWARFLineTableCallbackInfo info = { 
-                        line_table_ap.get(), 
-                        m_obj_file->GetSectionList(), 
-                        0, 
-                        0, 
-                        GetDebugMapSymfile () != NULL,
-                        false, 
-                        DWARFDebugLine::Row(), 
-                        SectionSP(), 
-                        SectionSP(),
-                        llvm::OwningPtr<LineSequence>()
-                    };
+                    ParseDWARFLineTableCallbackInfo info;
+                    info.line_table = line_table_ap.get();
                     lldb::offset_t offset = cu_line_offset;
                     DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
-                    sc.comp_unit->SetLineTable(line_table_ap.release());
-                    return true;
+                    if (m_debug_map_symfile)
+                    {
+                        // We have an object file that has a line table with addresses
+                        // that are not linked. We need to link the line table and convert
+                        // the addresses that are relative to the .o file into addresses
+                        // for the main executable.
+                        sc.comp_unit->SetLineTable (m_debug_map_symfile->LinkOSOLineTable (this, line_table_ap.get()));
+                    }
+                    else
+                    {
+                        sc.comp_unit->SetLineTable(line_table_ap.release());
+                        return true;
+                    }
                 }
             }
         }
@@ -2672,19 +2542,19 @@ SymbolFileDWARF::ResolveSymbolContext (c
                             LineTable *line_table = sc.comp_unit->GetLineTable();
                             if (line_table != NULL)
                             {
-                                if (so_addr.IsLinkedAddress())
+                                // And address that makes it into this function should be in terms
+                                // of this debug file if there is no debug map, or it will be an
+                                // address in the .o file which needs to be fixed up to be in terms
+                                // of the debug map executable. Either way, calling FixupAddress()
+                                // will work for us.
+                                Address exe_so_addr (so_addr);
+                                if (FixupAddress(exe_so_addr))
                                 {
-                                    Address linked_addr (so_addr);
-                                    linked_addr.ResolveLinkedAddress();
-                                    if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
+                                    if (line_table->FindLineEntryByAddress (exe_so_addr, sc.line_entry))
                                     {
                                         resolved |= eSymbolContextLineEntry;
                                     }
                                 }
-                                else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
-                                {
-                                    resolved |= eSymbolContextLineEntry;
-                                }
                             }
                         }
                         
@@ -6976,14 +6846,13 @@ SymbolFileDWARF::ParseVariablesForContex
         if (info == NULL)
             return 0;
         
-        uint32_t cu_idx = UINT32_MAX;
-        DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
-
-        if (dwarf_cu == NULL)
-            return 0;
-
         if (sc.function)
         {
+            DWARFCompileUnit* dwarf_cu = info->GetCompileUnitContainingDIE(sc.function->GetID()).get();
+            
+            if (dwarf_cu == NULL)
+                return 0;
+            
             const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
             
             dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
@@ -6998,6 +6867,11 @@ SymbolFileDWARF::ParseVariablesForContex
         }
         else if (sc.comp_unit)
         {
+            DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID()).get();
+
+            if (dwarf_cu == NULL)
+                return 0;
+
             uint32_t vars_added = 0;
             VariableListSP variables (sc.comp_unit->GetVariableList(false));
             
@@ -7232,10 +7106,10 @@ SymbolFileDWARF::ParseVariableDIE
                 {
                     bool op_error = false;
                     // Check if the location has a DW_OP_addr with any address value...
-                    addr_t location_has_op_addr = false;
+                    lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
                     if (!location_is_const_value_data)
                     {
-                        location_has_op_addr = location.LocationContains_DW_OP_addr (LLDB_INVALID_ADDRESS, op_error);
+                        location_DW_OP_addr = location.GetLocation_DW_OP_addr (0, op_error);
                         if (op_error)
                         {
                             StreamString strm;
@@ -7244,67 +7118,63 @@ SymbolFileDWARF::ParseVariableDIE
                         }
                     }
 
-                    if (location_has_op_addr)
+                    if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
                     {
                         if (is_external)
-                        {
                             scope = eValueTypeVariableGlobal;
-
-                            if (GetDebugMapSymfile ())
+                        else
+                            scope = eValueTypeVariableStatic;
+                        
+                        
+                        SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile ();
+                        
+                        if (debug_map_symfile)
+                        {
+                            // When leaving the DWARF in the .o files on darwin,
+                            // when we have a global variable that wasn't initialized,
+                            // the .o file might not have allocated a virtual
+                            // address for the global variable. In this case it will
+                            // have created a symbol for the global variable
+                            // that is undefined/data and external and the value will
+                            // be the byte size of the variable. When we do the
+                            // address map in SymbolFileDWARFDebugMap we rely on
+                            // having an address, we need to do some magic here
+                            // so we can get the correct address for our global
+                            // variable. The address for all of these entries
+                            // will be zero, and there will be an undefined symbol
+                            // in this object file, and the executable will have
+                            // a matching symbol with a good address. So here we
+                            // dig up the correct address and replace it in the
+                            // location for the variable, and set the variable's
+                            // symbol context scope to be that of the main executable
+                            // so the file address will resolve correctly.
+                            bool linked_oso_file_addr = false;
+                            if (is_external && location_DW_OP_addr == 0)
                             {
-                                // When leaving the DWARF in the .o files on darwin,
-                                // when we have a global variable that wasn't initialized,
-                                // the .o file might not have allocated a virtual
-                                // address for the global variable. In this case it will
-                                // have created a symbol for the global variable
-                                // that is undefined/data and external and the value will
-                                // be the byte size of the variable. When we do the
-                                // address map in SymbolFileDWARFDebugMap we rely on
-                                // having an address, we need to do some magic here
-                                // so we can get the correct address for our global 
-                                // variable. The address for all of these entries
-                                // will be zero, and there will be an undefined symbol
-                                // in this object file, and the executable will have
-                                // a matching symbol with a good address. So here we
-                                // dig up the correct address and replace it in the
-                                // location for the variable, and set the variable's
-                                // symbol context scope to be that of the main executable
-                                // so the file address will resolve correctly.
-                                if (location.LocationContains_DW_OP_addr (0, op_error))
+                                
+                                // we have a possible uninitialized extern global
+                                ConstString const_name(mangled ? mangled : name);
+                                ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile();
+                                if (debug_map_objfile)
                                 {
-                                    
-                                    // we have a possible uninitialized extern global
-                                    Symtab *symtab = m_obj_file->GetSymtab();
-                                    if (symtab)
+                                    Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
+                                    if (debug_map_symtab)
                                     {
-                                        ConstString const_name(mangled ? mangled : name);
-                                        Symbol *o_symbol = symtab->FindFirstSymbolWithNameAndType (const_name,
-                                                                                                   eSymbolTypeAny,
-                                                                                                   Symtab::eDebugNo,
-                                                                                                   Symtab::eVisibilityExtern);
-                                        
-                                        if (o_symbol)
+                                        Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
+                                                                                                               eSymbolTypeData,
+                                                                                                               Symtab::eDebugYes,
+                                                                                                               Symtab::eVisibilityExtern);
+                                        if (exe_symbol)
                                         {
-                                            ObjectFile *debug_map_objfile = m_debug_map_symfile->GetObjectFile();
-                                            if (debug_map_objfile)
+                                            if (exe_symbol->ValueIsAddress())
                                             {
-                                                Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
-                                                Symbol *defined_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
-                                                                                                                           eSymbolTypeData, 
-                                                                                                                           Symtab::eDebugYes, 
-                                                                                                                           Symtab::eVisibilityExtern);
-                                                if (defined_symbol)
+                                                const addr_t exe_file_addr = exe_symbol->GetAddress().GetFileAddress();
+                                                if (exe_file_addr != LLDB_INVALID_ADDRESS)
                                                 {
-                                                    if (defined_symbol->ValueIsAddress())
+                                                    if (location.Update_DW_OP_addr (exe_file_addr))
                                                     {
-                                                        const addr_t defined_addr = defined_symbol->GetAddress().GetFileAddress();
-                                                        if (defined_addr != LLDB_INVALID_ADDRESS)
-                                                        {
-                                                            if (location.Update_DW_OP_addr (defined_addr))
-                                                            {
-                                                                symbol_context_scope = defined_symbol;
-                                                            }
-                                                        }
+                                                        linked_oso_file_addr = true;
+                                                        symbol_context_scope = exe_symbol;
                                                     }
                                                 }
                                             }
@@ -7312,10 +7182,23 @@ SymbolFileDWARF::ParseVariableDIE
                                     }
                                 }
                             }
-                        }
-                        else  
-                        {
-                            scope = eValueTypeVariableStatic;
+
+                            if (!linked_oso_file_addr)
+                            {
+                                // The DW_OP_addr is not zero, but it contains a .o file address which
+                                // needs to be linked up correctly.
+                                const lldb::addr_t exe_file_addr = debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr);
+                                if (exe_file_addr != LLDB_INVALID_ADDRESS)
+                                {
+                                    // Update the file address for this variable
+                                    location.Update_DW_OP_addr (exe_file_addr);
+                                }
+                                else
+                                {
+                                    // Variable didn't make it into the final executable
+                                    return var_sp;
+                                }
+                            }
                         }
                     }
                     else

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Mon Mar  4 15:46:16 2013
@@ -541,6 +541,9 @@ protected:
                                 const DWARFDebugInfoEntry *dst_class_die,
                                 llvm::SmallVectorImpl <const DWARFDebugInfoEntry *> &failures);
 
+    bool
+    FixupAddress (lldb_private::Address &addr);
+
     lldb::ModuleWP                  m_debug_map_module_wp;
     SymbolFileDWARFDebugMap *       m_debug_map_symfile;
     clang::TranslationUnitDecl *    m_clang_tu_decl;

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp Mon Mar  4 15:46:16 2013
@@ -14,6 +14,8 @@
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/RegularExpression.h"
 #include "lldb/Core/Section.h"
+
+//#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT
 #if defined(DEBUG_OSO_DMAP)
 #include "lldb/Core/StreamFile.h"
 #endif
@@ -21,6 +23,7 @@
 
 #include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
 #include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/LineTable.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/SymbolVendor.h"
 #include "lldb/Symbol/VariableList.h"
@@ -35,207 +38,171 @@ using namespace lldb_private;
 // (so we can fixup the object file sections) and also for "Module::GetSymbolVendor()"
 // (so we can fixup the symbol file id.
 
-class DebugMapModule : public Module
+
+
+
+const SymbolFileDWARFDebugMap::FileRangeMap &
+SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile)
 {
-public:
-    DebugMapModule (const ModuleSP &exe_module_sp,
-                    uint32_t cu_idx,
-                    const FileSpec& file_spec,
-                    const ArchSpec& arch,
-                    const ConstString *object_name,
-                    off_t object_offset) :
-        Module (file_spec, arch, object_name, object_offset),
-        m_exe_module_wp (exe_module_sp),
-        m_cu_idx (cu_idx)
-    {
-        LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
-        if (log)
-            log->Printf("%p: DebugMapModule::DebugMapModule (exe_module=%p, cu_idx=%u, oso_path='%s/%s', object_name='%s')",
-                        this,
-                        exe_module_sp.get(),
-                        cu_idx,
-                        file_spec.GetDirectory().GetCString(),
-                        file_spec.GetFilename().GetCString(),
-                        object_name ? object_name->GetCString() : "");
-    }
+    if (file_range_map_valid)
+        return file_range_map;
 
-    virtual
-    ~DebugMapModule ()
+    file_range_map_valid = true;
+
+    Module *oso_module = exe_symfile->GetModuleByCompUnitInfo (this);
+    ObjectFile *oso_objfile = oso_module->GetObjectFile();
+    
+    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
+    if (log)
     {
-        LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
-        if (log)
-            log->Printf("%p: DebugMapModule::~DebugMapModule ()", this);
+        ConstString object_name (oso_module->GetObjectName());
+        log->Printf("%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s/%s%s%s%s')",
+                    this,
+                    oso_module->GetFileSpec().GetDirectory().GetCString(),
+                    oso_module->GetFileSpec().GetFilename().GetCString(),
+                    object_name ? "(" : "",
+                    object_name ? object_name.GetCString() : "",
+                    object_name ? ")" : "");
     }
+    
 
-    virtual ObjectFile *
-    GetObjectFile ()
+    std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
+    if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos))
     {
-        Mutex::Locker locker (m_mutex);
-        if (m_did_load_objfile == false)
+        for (auto comp_unit_info : cu_infos)
         {
-            ModuleSP exe_module_sp (m_exe_module_wp.lock());
-            if (exe_module_sp)
+            Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab();
+            ModuleSP oso_module_sp (oso_objfile->GetModule());
+            Symtab *oso_symtab = oso_objfile->GetSymtab();
+#if defined(DEBUG_OSO_DMAP)
+            StreamFile s(stdout, false);
+            s << "OSO symtab:\n";
+            oso_symtab->Dump(&s, NULL, eSortOrderNone);
+            s << "OSO sections before:\n";
+            oso_objfile->GetSectionList()->Dump(&s, NULL, true, UINT32_MAX);
+#endif
+            
+            ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
+            //SectionList *oso_sections = oso_objfile->Sections();
+            // Now we need to make sections that map from zero based object
+            // file addresses to where things eneded up in the main executable.
+            
+            assert (comp_unit_info->first_symbol_index != UINT32_MAX);
+            // End index is one past the last valid symbol index
+            const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
+            for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO
+                 idx < oso_end_idx;
+                 ++idx)
             {
-                ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
-                ObjectFile *oso_objfile = Module::GetObjectFile();
-                SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
-
-                if (exe_objfile && oso_objfile && exe_sym_vendor)
+                Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
+                if (exe_symbol)
                 {
-                    SymbolFileDWARFDebugMap *exe_symfile = (SymbolFileDWARFDebugMap *)exe_sym_vendor->GetSymbolFile();
-                    if (exe_symfile)
+                    if (exe_symbol->IsDebug() == false)
+                        continue;
+                    
+                    switch (exe_symbol->GetType())
                     {
-                        std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
-                        if (exe_symfile->GetCompUnitInfosForModule(this, cu_infos))
+                    default:
+                        break;
+                        
+                    case eSymbolTypeCode:
                         {
-                            for (auto comp_unit_info : cu_infos)
+                            // For each N_FUN, or function that we run into in the debug map
+                            // we make a new section that we add to the sections found in the
+                            // .o file. This new section has the file address set to what the
+                            // addresses are in the .o file, and the load address is adjusted
+                            // to match where it ended up in the final executable! We do this
+                            // before we parse any dwarf info so that when it goes get parsed
+                            // all section/offset addresses that get registered will resolve
+                            // correctly to the new addresses in the main executable.
+                            
+                            // First we find the original symbol in the .o file's symbol table
+                            Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(Mangled::ePreferMangled),
+                                                                                                 eSymbolTypeCode,
+                                                                                                 Symtab::eDebugNo,
+                                                                                                 Symtab::eVisibilityAny);
+                            if (oso_fun_symbol)
                             {
-                                // Set the ID of the symbol file DWARF to the index of the OSO
-                                // shifted left by 32 bits to provide a unique prefix for any
-                                // UserID's that get created in the symbol file.
-                                //comp_unit_info->exe_sections_sp.reset(new SectionList);
+                                // Add the inverse OSO file address to debug map entry mapping
+                                exe_symfile->AddOSOFileRange (this,
+                                                              exe_symbol->GetAddress().GetFileAddress(),
+                                                              oso_fun_symbol->GetAddress().GetFileAddress(),
+                                                              std::min<addr_t>(exe_symbol->GetByteSize(), oso_fun_symbol->GetByteSize()));
                                 
-                                Symtab *exe_symtab = exe_objfile->GetSymtab();
-                                ModuleSP oso_module_sp (oso_objfile->GetModule());
-                                Symtab *oso_symtab = oso_objfile->GetSymtab();
-                                //#define DEBUG_OSO_DMAP    // Do not check in with this defined...
-#if defined(DEBUG_OSO_DMAP)
-                                StreamFile s(stdout);
-                                s << "OSO symtab:\n";
-                                oso_symtab->Dump(&s, NULL);
-                                s << "OSO sections before:\n";
-                                oso_objfile->GetSectionList()->Dump(&s, NULL, true);
-#endif
-                    
-                                ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
-                                //SectionList *oso_sections = oso_objfile->Sections();
-                                // Now we need to make sections that map from zero based object
-                                // file addresses to where things eneded up in the main executable.
-
-                                assert (comp_unit_info->first_symbol_index != UINT32_MAX);
-                                // End index is one past the last valid symbol index
-                                const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
-                                uint32_t sect_id = 0x10000;
-                                for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO
-                                     idx < oso_end_idx;
-                                     ++idx)
-                                {
-                                    Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
-                                    if (exe_symbol)
-                                    {
-                                        if (exe_symbol->IsDebug() == false)
-                                            continue;
-                                        
-                                        switch (exe_symbol->GetType())
-                                        {
-                                            default:
-                                                break;
-                                                
-                                            case eSymbolTypeCode:
-                                            {
-                                                // For each N_FUN, or function that we run into in the debug map
-                                                // we make a new section that we add to the sections found in the
-                                                // .o file. This new section has the file address set to what the
-                                                // addresses are in the .o file, and the load address is adjusted
-                                                // to match where it ended up in the final executable! We do this
-                                                // before we parse any dwarf info so that when it goes get parsed
-                                                // all section/offset addresses that get registered will resolve
-                                                // correctly to the new addresses in the main executable.
-                                                
-                                                // First we find the original symbol in the .o file's symbol table
-                                                Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny);
-                                                if (oso_fun_symbol)
-                                                {
-                                                    // If we found the symbol, then we
-                                                    SectionSP exe_fun_section (exe_symbol->GetAddress().GetSection());
-                                                    SectionSP oso_fun_section (oso_fun_symbol->GetAddress().GetSection());
-                                                    if (oso_fun_section)
-                                                    {
-                                                        // Now we create a section that we will add as a child of the
-                                                        // section in which the .o symbol (the N_FUN) exists.
-                                                        
-                                                        // We use the exe_symbol size because the one in the .o file
-                                                        // will just be a symbol with no size, and the exe_symbol
-                                                        // size will reflect any size changes (ppc has been known to
-                                                        // shrink function sizes when it gets rid of jump islands that
-                                                        // aren't needed anymore).
-                                                        SectionSP oso_fun_section_sp (new Section (oso_fun_symbol->GetAddress().GetSection(),
-                                                                                                   oso_module_sp,                         // Module (the .o file)
-                                                                                                   sect_id++,                          // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs
-                                                                                                   exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated!
-                                                                                                   eSectionTypeDebug,
-                                                                                                   oso_fun_symbol->GetAddress().GetOffset(),  // File VM address offset in the current section
-                                                                                                   exe_symbol->GetByteSize(),          // File size (we need the size from the executable)
-                                                                                                   0, 0, 0));
-                                                        
-                                                        oso_fun_section_sp->SetLinkedLocation (exe_fun_section,
-                                                                                               exe_symbol->GetAddress().GetFileAddress() - exe_fun_section->GetFileAddress());
-                                                        oso_fun_section->GetChildren().AddSection(oso_fun_section_sp);
-                                                    }
-                                                }
-                                            }
-                                                break;
-                                                
-                                            case eSymbolTypeData:
-                                            {
-                                                // For each N_GSYM we remap the address for the global by making
-                                                // a new section that we add to the sections found in the .o file.
-                                                // This new section has the file address set to what the
-                                                // addresses are in the .o file, and the load address is adjusted
-                                                // to match where it ended up in the final executable! We do this
-                                                // before we parse any dwarf info so that when it goes get parsed
-                                                // all section/offset addresses that get registered will resolve
-                                                // correctly to the new addresses in the main executable. We
-                                                // initially set the section size to be 1 byte, but will need to
-                                                // fix up these addresses further after all globals have been
-                                                // parsed to span the gaps, or we can find the global variable
-                                                // sizes from the DWARF info as we are parsing.
-                                                
-                                                // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
-                                                Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(),
-                                                                                                                      eSymbolTypeData,
-                                                                                                                      Symtab::eDebugNo,
-                                                                                                                      Symtab::eVisibilityAny);
-                                                
-                                                if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() && oso_gsym_symbol->ValueIsAddress())
-                                                {
-                                                    // If we found the symbol, then we
-                                                    SectionSP exe_gsym_section (exe_symbol->GetAddress().GetSection());
-                                                    SectionSP oso_gsym_section (oso_gsym_symbol->GetAddress().GetSection());
-                                                    if (oso_gsym_section)
-                                                    {
-                                                        SectionSP oso_gsym_section_sp (new Section (oso_gsym_symbol->GetAddress().GetSection(),
-                                                                                                    oso_module_sp,                         // Module (the .o file)
-                                                                                                    sect_id++,                          // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs
-                                                                                                    exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated!
-                                                                                                    eSectionTypeDebug,
-                                                                                                    oso_gsym_symbol->GetAddress().GetOffset(),  // File VM address offset in the current section
-                                                                                                    1,                                   // We don't know the size of the global, just do the main address for now.
-                                                                                                    0, 0, 0));
-                                                        
-                                                        oso_gsym_section_sp->SetLinkedLocation (exe_gsym_section,
-                                                                                                exe_symbol->GetAddress().GetFileAddress() - exe_gsym_section->GetFileAddress());
-                                                        oso_gsym_section->GetChildren().AddSection(oso_gsym_section_sp);
-                                                    }
-                                                }
-                                            }
-                                                break;
-                                        }
-                                    }
-                                }
-                                oso_objfile->GetSectionList()->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
-    #if defined(DEBUG_OSO_DMAP)
-                                s << "OSO sections after:\n";
-                                oso_objfile->GetSectionList()->Dump(&s, NULL, true);
-    #endif
                             }
                         }
+                        break;
+                        
+                    case eSymbolTypeData:
+                        {
+                            // For each N_GSYM we remap the address for the global by making
+                            // a new section that we add to the sections found in the .o file.
+                            // This new section has the file address set to what the
+                            // addresses are in the .o file, and the load address is adjusted
+                            // to match where it ended up in the final executable! We do this
+                            // before we parse any dwarf info so that when it goes get parsed
+                            // all section/offset addresses that get registered will resolve
+                            // correctly to the new addresses in the main executable. We
+                            // initially set the section size to be 1 byte, but will need to
+                            // fix up these addresses further after all globals have been
+                            // parsed to span the gaps, or we can find the global variable
+                            // sizes from the DWARF info as we are parsing.
+                            
+                            // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
+                            Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(Mangled::ePreferMangled),
+                                                                                                  eSymbolTypeData,
+                                                                                                  Symtab::eDebugNo,
+                                                                                                  Symtab::eVisibilityAny);
+                            
+                            if (exe_symbol && oso_gsym_symbol &&
+                                exe_symbol->ValueIsAddress() &&
+                                oso_gsym_symbol->ValueIsAddress())
+                            {
+                                // Add the inverse OSO file address to debug map entry mapping
+                                exe_symfile->AddOSOFileRange (this,
+                                                              exe_symbol->GetAddress().GetFileAddress(),
+                                                              oso_gsym_symbol->GetAddress().GetFileAddress(),
+                                                              std::min<addr_t>(exe_symbol->GetByteSize(), oso_gsym_symbol->GetByteSize()));
+                            }
+                        }
+                        break;
                     }
                 }
             }
+            
+            exe_symfile->FinalizeOSOFileRanges (this);
+#if defined(DEBUG_OSO_DMAP)
+            s << "OSO sections after:\n";
+            oso_objfile->GetSectionList()->Dump(&s, NULL, true, UINT32_MAX);
+#endif
+            // We don't need the symbols anymore for the .o files
+            oso_objfile->ClearSymtab();
         }
-        return m_objfile_sp.get();
     }
+    return file_range_map;
+}
+
+
+class DebugMapModule : public Module
+{
+public:
+    DebugMapModule (const ModuleSP &exe_module_sp,
+                    uint32_t cu_idx,
+                    const FileSpec& file_spec,
+                    const ArchSpec& arch,
+                    const ConstString *object_name,
+                    off_t object_offset) :
+        Module (file_spec, arch, object_name, object_offset),
+        m_exe_module_wp (exe_module_sp),
+        m_cu_idx (cu_idx)
+    {
+    }
+
+    virtual
+    ~DebugMapModule ()
+    {
+    }
+
     
     virtual SymbolVendor*
     GetSymbolVendor(bool can_create = true, lldb_private::Stream *feedback_strm = NULL)
@@ -356,14 +323,12 @@ SymbolFileDWARFDebugMap::InitializeObjec
     GetClangASTContext().SetExternalSource (ast_source_ap);
 }
 
-
-
 void
 SymbolFileDWARFDebugMap::InitOSO()
 {
     if (m_flags.test(kHaveInitializedOSOs))
         return;
-
+    
     m_flags.set(kHaveInitializedOSOs);
     // In order to get the abilities of this plug-in, we look at the list of
     // N_OSO entries (object files) from the symbol table and make sure that
@@ -376,10 +341,6 @@ SymbolFileDWARFDebugMap::InitOSO()
         LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
 
         std::vector<uint32_t> oso_indexes;
-#if defined(DEBUG_OSO_DMAP)
-//      StreamFile s(stdout);
-//      symtab->Dump(&s, NULL, eSortOrderNone);
-#endif
         // When a mach-o symbol is encoded, the n_type field is encoded in bits
         // 23:16, and the n_desc field is encoded in bits 15:0.
         // 
@@ -399,7 +360,31 @@ SymbolFileDWARFDebugMap::InitOSO()
             symtab->SortSymbolIndexesByValue(m_func_indexes, true);
             symtab->SortSymbolIndexesByValue(m_glob_indexes, true);
 
+            for (uint32_t sym_idx : m_func_indexes)
+            {
+                const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
+                lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress();
+                lldb::addr_t byte_size = symbol->GetByteSize();
+                DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
+                m_debug_map.Append(debug_map_entry);
+            }
+            for (uint32_t sym_idx : m_glob_indexes)
+            {
+                const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
+                lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress();
+                lldb::addr_t byte_size = symbol->GetByteSize();
+                DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
+                m_debug_map.Append(debug_map_entry);
+            }
+            m_debug_map.Sort();
+
+#if defined(DEBUG_OSO_DMAP)
+            StreamFile s(stdout, false);
+            symtab->Dump(&s, NULL, m_func_indexes);
+            symtab->Dump(&s, NULL, m_glob_indexes);
+#endif
             m_compile_unit_infos.resize(oso_index_count);
+            
 //          s.Printf("%s N_OSO symbols:\n", __PRETTY_FUNCTION__);
 //          symtab->Dump(&s, oso_indexes);
 
@@ -643,34 +628,20 @@ SymbolFileDWARFDebugMap::ParseCompileUni
             FileSpec so_file_spec;
             if (GetFileSpecForSO (cu_idx, so_file_spec))
             {
-                Module *oso_module = GetModuleByOSOIndex (cu_idx);
-                if (oso_module)
-                {
-                     // User zero as the ID to match the compile unit at offset
-                     // zero in each .o file since each .o file can only have
-                     // one compile unit for now.
-                    lldb::user_id_t cu_id = 0;
-                    m_compile_unit_infos[cu_idx].compile_unit_sp.reset (new CompileUnit (oso_module->shared_from_this(),
-                                                                                             NULL,
-                                                                                             so_file_spec,
-                                                                                             cu_id,
-                                                                                             eLanguageTypeUnknown));
-                }
-
-                if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
-                {
-                    m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
-                                                                                            NULL,
-                                                                                            so_file_spec,
-                                                                                            cu_idx,
-                                                                                            eLanguageTypeUnknown));
-                }
+                // User zero as the ID to match the compile unit at offset
+                // zero in each .o file since each .o file can only have
+                // one compile unit for now.
+                lldb::user_id_t cu_id = 0;
+                m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
+                                                                                    NULL,
+                                                                                    so_file_spec,
+                                                                                    cu_id,
+                                                                                    eLanguageTypeUnknown));
             
                 if (m_compile_unit_infos[cu_idx].compile_unit_sp)
                 {
                     // Let our symbol vendor know about this compile unit
-                    m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx,
-                                                                                       m_compile_unit_infos[cu_idx].compile_unit_sp);
+                    m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp);
                 }
             }
         }
@@ -779,7 +750,7 @@ SymbolFileDWARFDebugMap::ResolveTypeUID(
     const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
     SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
     if (oso_dwarf)
-        oso_dwarf->ResolveTypeUID (type_uid);
+        return oso_dwarf->ResolveTypeUID (type_uid);
     return NULL;
 }
 
@@ -798,30 +769,30 @@ SymbolFileDWARFDebugMap::ResolveSymbolCo
     if (symtab)
     {
         const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
-        sc.symbol = symtab->FindSymbolContainingFileAddress (exe_file_addr, &m_func_indexes[0], m_func_indexes.size());
 
-        if (sc.symbol != NULL)
+        const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains (exe_file_addr);
+        if (debug_map_entry)
         {
-            resolved_flags |= eSymbolContextSymbol;
 
-            uint32_t oso_idx = 0;
-            CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx);
-            if (comp_unit_info)
-            {
-                SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
-                ObjectFile *oso_objfile = GetObjectFileByOSOIndex (oso_idx);
-                if (oso_dwarf && oso_objfile)
-                {
-                    SectionList *oso_section_list = oso_objfile->GetSectionList();
+            sc.symbol = symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());
 
-                    SectionSP oso_symbol_section_sp (oso_section_list->FindSectionContainingLinkedFileAddress (exe_file_addr, UINT32_MAX));
+            if (sc.symbol != NULL)
+            {
+                resolved_flags |= eSymbolContextSymbol;
 
-                    if (oso_symbol_section_sp)
+                uint32_t oso_idx = 0;
+                CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx);
+                if (comp_unit_info)
+                {
+                    Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
+                    if (oso_module)
                     {
-                        const addr_t linked_file_addr = oso_symbol_section_sp->GetLinkedFileAddress();
-                        Address oso_so_addr (oso_symbol_section_sp, exe_file_addr - linked_file_addr);
-                        if (oso_so_addr.IsSectionOffset())
-                            resolved_flags |= oso_dwarf->ResolveSymbolContext (oso_so_addr, resolve_scope, sc);
+                        lldb::addr_t oso_file_addr = exe_file_addr - debug_map_entry->GetRangeBase() + debug_map_entry->data.GetOSOFileAddress();
+                        Address oso_so_addr;
+                        if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr))
+                        {
+                            resolved_flags |= oso_module->GetSymbolVendor()->ResolveSymbolContext (oso_so_addr, resolve_scope, sc);
+                        }
                     }
                 }
             }
@@ -1307,6 +1278,24 @@ SymbolFileDWARFDebugMap::GetCompileUnit
     return lldb::CompUnitSP();
 }
 
+SymbolFileDWARFDebugMap::CompileUnitInfo *
+SymbolFileDWARFDebugMap::GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf)
+{
+    if (oso_dwarf)
+    {
+        const uint32_t cu_count = GetNumCompileUnits();
+        for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
+        {
+            SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
+            if (oso_symfile == oso_dwarf)
+            {
+                return &m_compile_unit_infos[cu_idx];
+            }
+        }
+    }
+    return NULL;
+}
+
 
 void
 SymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp)
@@ -1415,4 +1404,99 @@ SymbolFileDWARFDebugMap::GetClangDeclCon
     return NULL;
 }
 
+bool
+SymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info,
+                                          lldb::addr_t exe_file_addr,
+                                          lldb::addr_t oso_file_addr,
+                                          lldb::addr_t oso_byte_size)
+{
+    assert (cu_info);// REMOVE THIS PRIOR TO CHECKIN
+    const uint32_t debug_map_idx = m_debug_map.FindEntryIndexThatContains(exe_file_addr);
+    if (debug_map_idx != UINT32_MAX)
+    {
+        DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(exe_file_addr);
+        assert (debug_map_entry);// REMOVE THIS PRIOR TO CHECKIN
+        debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
+        cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, oso_byte_size, exe_file_addr));
+        return true;
+    }
+    return false;
+}
+
+void
+SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (CompileUnitInfo *cu_info)
+{
+    cu_info->file_range_map.Sort();
+#if defined(DEBUG_OSO_DMAP)
+    const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this);
+    const size_t n = oso_file_range_map.GetSize();
+    printf ("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p)\n", cu_info);
+    for (size_t i=0; i<n; ++i)
+    {
+        const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i);
+        printf ("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n",
+                entry.GetRangeBase(), entry.GetRangeEnd(),
+                entry.data, entry.data + entry.GetByteSize());
+    }
+#endif
+}
+
+lldb::addr_t
+SymbolFileDWARFDebugMap::LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr)
+{
+    CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_symfile);
+    if (cu_info)
+    {
+        const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
+        if (oso_range_entry)
+        {
+            const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
+            if (debug_map_entry)
+            {
+                const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
+                const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
+                return exe_file_addr;
+            }
+        }
+    }
+    return LLDB_INVALID_ADDRESS;
+}
+
+bool
+SymbolFileDWARFDebugMap::LinkOSOAddress (Address &addr)
+{
+    // Make sure this address hasn't been fixed already
+    Module *exe_module = GetObjectFile()->GetModule().get();
+    Module *addr_module = addr.GetModule().get();
+    if (addr_module == exe_module)
+        return true; // Address is already in terms of the main executable module
+
+    CompileUnitInfo *cu_info = GetCompileUnitInfo ((SymbolFileDWARF *)addr_module->GetSymbolVendor()->GetSymbolFile());
+    if (cu_info)
+    {
+        const lldb::addr_t oso_file_addr = addr.GetFileAddress();
+        const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
+        if (oso_range_entry)
+        {
+            const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
+            if (debug_map_entry)
+            {
+                const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
+                const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
+                return exe_module->ResolveFileAddress(exe_file_addr, addr);
+            }
+        }
+    }
+    return true;
+}
+
+LineTable *
+SymbolFileDWARFDebugMap::LinkOSOLineTable (SymbolFileDWARF *oso_dwarf, LineTable *line_table)
+{
+    CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_dwarf);
+    if (cu_info)
+        return line_table->LinkLineTable(cu_info->GetFileRangeMap(this));
+    return NULL;
+}
+
 

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h Mon Mar  4 15:46:16 2013
@@ -16,6 +16,7 @@
 
 #include "clang/AST/CharUnits.h"
 
+#include "lldb/Core/RangeMap.h"
 #include "lldb/Symbol/SymbolFile.h"
 
 #include "UniqueDWARFASTType.h"
@@ -143,6 +144,8 @@ protected:
     
     typedef STD_SHARED_PTR(OSOInfo) OSOInfoSP;
 
+    typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t> FileRangeMap;
+
     //------------------------------------------------------------------
     // Class specific types
     //------------------------------------------------------------------
@@ -156,6 +159,9 @@ protected:
         uint32_t last_symbol_index;
         uint32_t first_symbol_id;
         uint32_t last_symbol_id;
+        FileRangeMap file_range_map;
+        bool file_range_map_valid;
+        
 
         CompileUnitInfo() :
             so_file (),
@@ -165,9 +171,14 @@ protected:
             first_symbol_index (UINT32_MAX),
             last_symbol_index (UINT32_MAX),
             first_symbol_id (UINT32_MAX),
-            last_symbol_id (UINT32_MAX)
+            last_symbol_id (UINT32_MAX),
+            file_range_map (),
+            file_range_map_valid (false)
         {
         }
+        
+        const FileRangeMap &
+        GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile);
     };
 
     //------------------------------------------------------------------
@@ -240,6 +251,9 @@ protected:
 
     lldb::CompUnitSP
     GetCompileUnit (SymbolFileDWARF *oso_dwarf);
+    
+    CompileUnitInfo *
+    GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf);
 
     lldb::TypeSP
     FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx);    
@@ -258,6 +272,58 @@ protected:
     {
         return m_unique_ast_type_map;
     }
+    
+    
+    //------------------------------------------------------------------
+    // OSOEntry
+    //------------------------------------------------------------------
+    class OSOEntry
+    {
+    public:
+        
+        OSOEntry () :
+        m_exe_sym_idx (UINT32_MAX),
+        m_oso_file_addr (LLDB_INVALID_ADDRESS)
+        {
+        }
+        
+        OSOEntry (uint32_t exe_sym_idx,
+                  lldb::addr_t oso_file_addr) :
+        m_exe_sym_idx (exe_sym_idx),
+        m_oso_file_addr (oso_file_addr)
+        {
+        }
+        
+        uint32_t
+        GetExeSymbolIndex () const
+        {
+            return m_exe_sym_idx;
+        }
+        
+        bool
+        operator < (const OSOEntry &rhs) const
+        {
+            return m_exe_sym_idx < rhs.m_exe_sym_idx;
+        }
+        
+        lldb::addr_t
+        GetOSOFileAddress () const
+        {
+            return m_oso_file_addr;
+        }
+        
+        void
+        SetOSOFileAddress (lldb::addr_t oso_file_addr)
+        {
+            m_oso_file_addr = oso_file_addr;
+        }
+    protected:
+        uint32_t m_exe_sym_idx;
+        lldb::addr_t m_oso_file_addr;
+    };
+
+    typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, OSOEntry> DebugMap;
+
     //------------------------------------------------------------------
     // Member Variables
     //------------------------------------------------------------------
@@ -268,6 +334,77 @@ protected:
     std::map<lldb_private::ConstString, OSOInfoSP> m_oso_map;
     UniqueDWARFASTTypeMap m_unique_ast_type_map;
     lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
+    DebugMap m_debug_map;
+    
+    //------------------------------------------------------------------
+    // When an object file from the debug map gets parsed in
+    // SymbolFileDWARF, it needs to tell the debug map about the object
+    // files addresses by calling this function once for each N_FUN,
+    // N_GSYM and N_STSYM and after all entries in the debug map have
+    // been matched up, FinalizeOSOFileRanges() should be called.
+    //------------------------------------------------------------------
+    bool
+    AddOSOFileRange (CompileUnitInfo *cu_info,
+                     lldb::addr_t exe_file_addr,
+                     lldb::addr_t oso_file_addr,
+                     lldb::addr_t oso_byte_size);
+    
+    //------------------------------------------------------------------
+    // Called after calling AddOSOFileRange() for each object file debug
+    // map entry to finalize the info for the unlinked compile unit.
+    //------------------------------------------------------------------
+    void
+    FinalizeOSOFileRanges (CompileUnitInfo *cu_info);
+
+    //------------------------------------------------------------------
+    /// Convert \a addr from a .o file address, to an executable address.
+    ///
+    /// @param[in] addr
+    ///     A section offset address from a .o file
+    ///
+    /// @return
+    ///     Returns true if \a addr was converted to be an executable
+    ///     section/offset address, false otherwise.
+    //------------------------------------------------------------------
+    bool
+    LinkOSOAddress (lldb_private::Address &addr);
+    
+    //------------------------------------------------------------------
+    /// Convert a .o file "file address" to an executable "file address".
+    ///
+    /// @param[in] oso_symfile
+    ///     The DWARF symbol file that contains \a oso_file_addr
+    ///
+    /// @param[in] oso_file_addr
+    ///     A .o file "file address" to convert.
+    ///
+    /// @return
+    ///     LLDB_INVALID_ADDRESS if \a oso_file_addr is not in the
+    ///     linked executable, otherwise a valid "file address" from the
+    ///     linked executable that contains the debug map.
+    //------------------------------------------------------------------
+    lldb::addr_t
+    LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr);
+            
+    //------------------------------------------------------------------
+    /// Given a line table full of lines with "file adresses" that are
+    /// for a .o file represented by \a oso_symfile, link a new line table
+    /// and return it.
+    ///
+    /// @param[in] oso_symfile
+    ///     The DWARF symbol file that produced the \a line_table
+    ///
+    /// @param[in] addr
+    ///     A section offset address from a .o file
+    ///
+    /// @return
+    ///     Returns a valid line table full of linked addresses, or NULL
+    ///     if none of the line table adresses exist in the main
+    ///     executable.
+    //------------------------------------------------------------------
+    lldb_private::LineTable *
+    LinkOSOLineTable (SymbolFileDWARF *oso_symfile,
+                      lldb_private::LineTable *line_table);
 };
 
 #endif // #ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_

Modified: lldb/trunk/source/Symbol/Function.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Function.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Function.cpp (original)
+++ lldb/trunk/source/Symbol/Function.cpp Mon Mar  4 15:46:16 2013
@@ -392,13 +392,7 @@ Function::CalculateSymbolContextModule (
 {
     SectionSP section_sp (m_range.GetBaseAddress().GetSection());
     if (section_sp)
-    {
-        SectionSP linked_section_sp (section_sp->GetLinkedSection());
-        if (linked_section_sp)
-            return linked_section_sp->GetModule();
-        else
-            return section_sp->GetModule();
-    }
+        return section_sp->GetModule();
     
     return this->GetCompileUnit()->GetModule();
 }

Modified: lldb/trunk/source/Symbol/LineTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/LineTable.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/LineTable.cpp (original)
+++ lldb/trunk/source/Symbol/LineTable.cpp Mon Mar  4 15:46:16 2013
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/Core/Address.h"
+#include "lldb/Core/Module.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Core/Stream.h"
 #include "lldb/Symbol/CompileUnit.h"
@@ -22,7 +23,6 @@ using namespace lldb_private;
 //----------------------------------------------------------------------
 LineTable::LineTable(CompileUnit* comp_unit) :
     m_comp_unit(comp_unit),
-    m_section_list(),
     m_entries()
 {
 }
@@ -37,8 +37,7 @@ LineTable::~LineTable()
 void
 LineTable::InsertLineEntry
 (
-    const SectionSP& section_sp,
-    lldb::addr_t section_offset,
+    lldb::addr_t file_addr,
     uint32_t line,
     uint16_t column,
     uint16_t file_idx,
@@ -49,21 +48,7 @@ LineTable::InsertLineEntry
     bool is_terminal_entry
 )
 {
-    SectionSP line_section_sp;
-    SectionSP linked_section_sp (section_sp->GetLinkedSection());
-    if (linked_section_sp)
-    {
-        section_offset += section_sp->GetLinkedOffset();
-        line_section_sp = linked_section_sp;
-    }
-    else
-    {
-        line_section_sp = section_sp;
-    }
-    assert(line_section_sp.get());
-
-    uint32_t sect_idx = m_section_list.AddUniqueSection (line_section_sp);
-    Entry entry(sect_idx, section_offset, line, column, file_idx, is_start_of_statement, is_start_of_basic_block, is_prologue_end, is_epilogue_begin, is_terminal_entry);
+    Entry entry(file_addr, line, column, file_idx, is_start_of_statement, is_start_of_basic_block, is_prologue_end, is_epilogue_begin, is_terminal_entry);
 
     entry_collection::iterator begin_pos = m_entries.begin();
     entry_collection::iterator end_pos = m_entries.end();
@@ -85,7 +70,7 @@ LineSequence::LineSequence()
 void
 LineTable::LineSequenceImpl::Clear()
 { 
-    m_seq_entries.clear();
+    m_entries.clear();
 }
 
 LineSequence* LineTable::CreateLineSequenceContainer ()
@@ -97,8 +82,7 @@ void
 LineTable::AppendLineEntryToSequence
 (
     LineSequence* sequence,
-    const SectionSP& section_sp,
-    lldb::addr_t section_offset,
+    lldb::addr_t file_addr,
     uint32_t line,
     uint16_t column,
     uint16_t file_idx,
@@ -111,9 +95,8 @@ LineTable::AppendLineEntryToSequence
 {
     assert(sequence != NULL);
     LineSequenceImpl* seq = reinterpret_cast<LineSequenceImpl*>(sequence);
-    uint32_t sect_idx = m_section_list.AddUniqueSection (section_sp);
-    Entry entry(sect_idx, section_offset, line, column, file_idx, is_start_of_statement, is_start_of_basic_block, is_prologue_end, is_epilogue_begin, is_terminal_entry);
-    seq->m_seq_entries.push_back (entry);
+    Entry entry(file_addr, line, column, file_idx, is_start_of_statement, is_start_of_basic_block, is_prologue_end, is_epilogue_begin, is_terminal_entry);
+    seq->m_entries.push_back (entry);
 }
 
 void
@@ -121,17 +104,17 @@ LineTable::InsertSequence (LineSequence*
 {
     assert(sequence != NULL);
     LineSequenceImpl* seq = reinterpret_cast<LineSequenceImpl*>(sequence);
-    if (seq->m_seq_entries.empty())
+    if (seq->m_entries.empty())
         return;
-    Entry& entry = seq->m_seq_entries.front();
-
+    Entry& entry = seq->m_entries.front();
+    
     // If the first entry address in this sequence is greater than or equal to
     // the address of the last item in our entry collection, just append.
     if (m_entries.empty() || !Entry::EntryAddressLessThan(entry, m_entries.back()))
     {
         m_entries.insert(m_entries.end(),
-                         seq->m_seq_entries.begin(),
-                         seq->m_seq_entries.end());
+                         seq->m_entries.begin(),
+                         seq->m_entries.end());
         return;
     }
 
@@ -149,7 +132,7 @@ LineTable::InsertSequence (LineSequence*
         assert(prev_pos->is_terminal_entry);
     }
 #endif
-    m_entries.insert(pos, seq->m_seq_entries.begin(), seq->m_seq_entries.end());
+    m_entries.insert(pos, seq->m_entries.begin(), seq->m_entries.end());
 }
 
 //----------------------------------------------------------------------
@@ -161,37 +144,23 @@ LineTable::Entry::LessThanBinaryPredicat
 bool
 LineTable::Entry::LessThanBinaryPredicate::operator() (const LineTable::Entry& a, const LineTable::Entry& b) const
 {
-    if (a.sect_idx == b.sect_idx)
-    {
-        #define LT_COMPARE(a,b) if (a != b) return a < b
-        LT_COMPARE (a.sect_offset, b.sect_offset);
-        // b and a reversed on purpose below.
-        LT_COMPARE (b.is_terminal_entry, a.is_terminal_entry);
-        LT_COMPARE (a.line, b.line);
-        LT_COMPARE (a.column, b.column);
-        LT_COMPARE (a.is_start_of_statement, b.is_start_of_statement);
-        LT_COMPARE (a.is_start_of_basic_block, b.is_start_of_basic_block);
-        // b and a reversed on purpose below.
-        LT_COMPARE (b.is_prologue_end, a.is_prologue_end);
-        LT_COMPARE (a.is_epilogue_begin, b.is_epilogue_begin);
-        LT_COMPARE (a.file_idx, b.file_idx);
-        return false;
-        #undef LT_COMPARE
-    }
-
-    const Section *a_section = m_line_table->GetSectionForEntryIndex (a.sect_idx);
-    const Section *b_section = m_line_table->GetSectionForEntryIndex (b.sect_idx);
-    return Section::Compare(*a_section, *b_section) < 0;
+    #define LT_COMPARE(a,b) if (a != b) return a < b
+    LT_COMPARE (a.file_addr, b.file_addr);
+    // b and a reversed on purpose below.
+    LT_COMPARE (b.is_terminal_entry, a.is_terminal_entry);
+    LT_COMPARE (a.line, b.line);
+    LT_COMPARE (a.column, b.column);
+    LT_COMPARE (a.is_start_of_statement, b.is_start_of_statement);
+    LT_COMPARE (a.is_start_of_basic_block, b.is_start_of_basic_block);
+    // b and a reversed on purpose below.
+    LT_COMPARE (b.is_prologue_end, a.is_prologue_end);
+    LT_COMPARE (a.is_epilogue_begin, b.is_epilogue_begin);
+    LT_COMPARE (a.file_idx, b.file_idx);
+    return false;
+    #undef LT_COMPARE
 }
 
 
-Section *
-LineTable::GetSectionForEntryIndex (uint32_t idx)
-{
-    if (idx < m_section_list.GetSize())
-        return m_section_list.GetSectionAtIndex(idx).get();
-    return NULL;
-}
 
 uint32_t
 LineTable::GetSize() const
@@ -218,69 +187,69 @@ LineTable::FindLineEntryByAddress (const
         *index_ptr = UINT32_MAX;
 
     bool success = false;
-    uint32_t sect_idx = m_section_list.FindSectionIndex (so_addr.GetSection().get());
-    if (sect_idx != UINT32_MAX)
+
+    if (so_addr.GetModule().get() == m_comp_unit->GetModule().get())
     {
         Entry search_entry;
-        search_entry.sect_idx = sect_idx;
-        search_entry.sect_offset = so_addr.GetOffset();
-
-        entry_collection::const_iterator begin_pos = m_entries.begin();
-        entry_collection::const_iterator end_pos = m_entries.end();
-        entry_collection::const_iterator pos = lower_bound(begin_pos, end_pos, search_entry, Entry::EntryAddressLessThan);
-        if (pos != end_pos)
+        search_entry.file_addr = so_addr.GetFileAddress();
+        if (search_entry.file_addr != LLDB_INVALID_ADDRESS)
         {
-            if (pos != begin_pos)
+            entry_collection::const_iterator begin_pos = m_entries.begin();
+            entry_collection::const_iterator end_pos = m_entries.end();
+            entry_collection::const_iterator pos = lower_bound(begin_pos, end_pos, search_entry, Entry::EntryAddressLessThan);
+            if (pos != end_pos)
             {
-                if (pos->sect_offset != search_entry.sect_offset)
-                    --pos;
-                else if (pos->sect_offset == search_entry.sect_offset)
+                if (pos != begin_pos)
                 {
-                    // If this is a termination entry, it should't match since
-                    // entries with the "is_terminal_entry" member set to true 
-                    // are termination entries that define the range for the 
-                    // previous entry.
-                    if (pos->is_terminal_entry)
+                    if (pos->file_addr != search_entry.file_addr)
+                        --pos;
+                    else if (pos->file_addr == search_entry.file_addr)
                     {
-                        // The matching entry is a terminal entry, so we skip
-                        // ahead to the next entry to see if there is another
-                        // entry following this one whose section/offset matches.
-                        ++pos;
-                        if (pos != end_pos)
+                        // If this is a termination entry, it should't match since
+                        // entries with the "is_terminal_entry" member set to true 
+                        // are termination entries that define the range for the 
+                        // previous entry.
+                        if (pos->is_terminal_entry)
                         {
-                            if (pos->sect_offset != search_entry.sect_offset)
-                                pos = end_pos;
+                            // The matching entry is a terminal entry, so we skip
+                            // ahead to the next entry to see if there is another
+                            // entry following this one whose section/offset matches.
+                            ++pos;
+                            if (pos != end_pos)
+                            {
+                                if (pos->file_addr != search_entry.file_addr)
+                                    pos = end_pos;
+                            }
                         }
-                    }
-                    
-                    if (pos != end_pos)
-                    {
-                        // While in the same section/offset backup to find the first
-                        // line entry that matches the address in case there are 
-                        // multiple
-                        while (pos != begin_pos)
+                        
+                        if (pos != end_pos)
                         {
-                            entry_collection::const_iterator prev_pos = pos - 1;
-                            if (prev_pos->sect_idx    == search_entry.sect_idx &&
-                                prev_pos->sect_offset == search_entry.sect_offset &&
-                                prev_pos->is_terminal_entry == false)
-                                --pos;
-                            else
-                                break;
+                            // While in the same section/offset backup to find the first
+                            // line entry that matches the address in case there are 
+                            // multiple
+                            while (pos != begin_pos)
+                            {
+                                entry_collection::const_iterator prev_pos = pos - 1;
+                                if (prev_pos->file_addr == search_entry.file_addr &&
+                                    prev_pos->is_terminal_entry == false)
+                                    --pos;
+                                else
+                                    break;
+                            }
                         }
                     }
-                }
 
-            }
-            
-            // Make sure we have a valid match and that the match isn't a terminating
-            // entry for a previous line...
-            if (pos != end_pos && pos->is_terminal_entry == false)
-            {
-                uint32_t match_idx = std::distance (begin_pos, pos);
-                success = ConvertEntryAtIndexToLineEntry(match_idx, line_entry);
-                if (index_ptr != NULL && success)
-                    *index_ptr = match_idx;
+                }
+                
+                // Make sure we have a valid match and that the match isn't a terminating
+                // entry for a previous line...
+                if (pos != end_pos && pos->is_terminal_entry == false)
+                {
+                    uint32_t match_idx = std::distance (begin_pos, pos);
+                    success = ConvertEntryAtIndexToLineEntry(match_idx, line_entry);
+                    if (index_ptr != NULL && success)
+                        *index_ptr = match_idx;
+                }
             }
         }
     }
@@ -294,32 +263,24 @@ LineTable::ConvertEntryAtIndexToLineEntr
     if (idx < m_entries.size())
     {
         const Entry& entry = m_entries[idx];
-        line_entry.range.GetBaseAddress().SetSection(m_section_list.GetSectionAtIndex (entry.sect_idx));
-        line_entry.range.GetBaseAddress().SetOffset(entry.sect_offset);
-        if (!entry.is_terminal_entry && idx + 1 < m_entries.size())
+        ModuleSP module_sp (m_comp_unit->GetModule());
+        if (module_sp && module_sp->ResolveFileAddress(entry.file_addr, line_entry.range.GetBaseAddress()))
         {
-            const Entry& next_entry = m_entries[idx+1];
-            if (next_entry.sect_idx == entry.sect_idx)
-            {
-                line_entry.range.SetByteSize(next_entry.sect_offset - entry.sect_offset);
-            }
+            if (!entry.is_terminal_entry && idx + 1 < m_entries.size())
+                line_entry.range.SetByteSize(m_entries[idx+1].file_addr - entry.file_addr);
             else
-            {
-                Address next_line_addr(m_section_list.GetSectionAtIndex (next_entry.sect_idx), next_entry.sect_offset);
-                line_entry.range.SetByteSize(next_line_addr.GetFileAddress() - line_entry.range.GetBaseAddress().GetFileAddress());
-            }
+                line_entry.range.SetByteSize(0);
+
+            line_entry.file = m_comp_unit->GetSupportFiles().GetFileSpecAtIndex (entry.file_idx);
+            line_entry.line = entry.line;
+            line_entry.column = entry.column;
+            line_entry.is_start_of_statement = entry.is_start_of_statement;
+            line_entry.is_start_of_basic_block = entry.is_start_of_basic_block;
+            line_entry.is_prologue_end = entry.is_prologue_end;
+            line_entry.is_epilogue_begin = entry.is_epilogue_begin;
+            line_entry.is_terminal_entry = entry.is_terminal_entry;
+            return true;
         }
-        else
-            line_entry.range.SetByteSize(0);
-        line_entry.file = m_comp_unit->GetSupportFiles().GetFileSpecAtIndex (entry.file_idx);
-        line_entry.line = entry.line;
-        line_entry.column = entry.column;
-        line_entry.is_start_of_statement = entry.is_start_of_statement;
-        line_entry.is_start_of_basic_block = entry.is_start_of_basic_block;
-        line_entry.is_prologue_end = entry.is_prologue_end;
-        line_entry.is_epilogue_begin = entry.is_epilogue_begin;
-        line_entry.is_terminal_entry = entry.is_terminal_entry;
-        return true;
     }
     return false;
 }
@@ -503,7 +464,6 @@ LineTable::GetContiguousFileAddressRange
     
     const size_t count = m_entries.size();
     LineEntry line_entry;
-    std::vector<addr_t> section_base_file_addrs (m_section_list.GetSize(), LLDB_INVALID_ADDRESS);
     FileAddressRanges::Entry range (LLDB_INVALID_ADDRESS, 0);
     for (size_t idx = 0; idx < count; ++idx)
     {
@@ -513,23 +473,89 @@ LineTable::GetContiguousFileAddressRange
         {
             if (range.GetRangeBase() != LLDB_INVALID_ADDRESS)
             {
-                if (section_base_file_addrs[entry.sect_idx] == LLDB_INVALID_ADDRESS)
-                    section_base_file_addrs[entry.sect_idx] = m_section_list.GetSectionAtIndex (entry.sect_idx)->GetFileAddress();
-                range.SetRangeEnd(section_base_file_addrs[entry.sect_idx] + entry.sect_offset);
+                range.SetRangeEnd(entry.file_addr);
                 file_ranges.Append(range);
                 range.Clear(LLDB_INVALID_ADDRESS);
             }
         }
         else if (range.GetRangeBase() == LLDB_INVALID_ADDRESS)
         {
-            if (section_base_file_addrs[entry.sect_idx] == LLDB_INVALID_ADDRESS)
-                section_base_file_addrs[entry.sect_idx] = m_section_list.GetSectionAtIndex (entry.sect_idx)->GetFileAddress();
-            range.SetRangeBase(section_base_file_addrs[entry.sect_idx] + entry.sect_offset);
+            range.SetRangeBase(entry.file_addr);
         }
     }
     return file_ranges.GetSize() - initial_count;
 }
 
+LineTable *
+LineTable::LinkLineTable (const FileRangeMap &file_range_map)
+{
+    std::auto_ptr<LineTable> line_table_ap (new LineTable (m_comp_unit));
+    LineSequenceImpl sequence;
+    const size_t count = m_entries.size();
+    LineEntry line_entry;
+    const FileRangeMap::Entry *file_range_entry = NULL;
+    const FileRangeMap::Entry *prev_file_range_entry = NULL;
+    lldb::addr_t prev_file_addr = LLDB_INVALID_ADDRESS;
+    bool prev_entry_was_linked = false;
+    for (size_t idx = 0; idx < count; ++idx)
+    {
+        const Entry& entry = m_entries[idx];
+        
+        const bool end_sequence = entry.is_terminal_entry;
+        const lldb::addr_t lookup_file_addr = entry.file_addr - (end_sequence ? 1 : 0);
+        if (file_range_entry == NULL || !file_range_entry->Contains(lookup_file_addr))
+        {
+            prev_file_range_entry = file_range_entry;
+            file_range_entry = file_range_map.FindEntryThatContains(lookup_file_addr);
+        }
+        
+        if (file_range_entry)
+        {
+            // This entry has an address remapping and it needs to have its address relinked
+            sequence.m_entries.push_back(entry);
+            // Fix tha addresss
+            const lldb::addr_t linked_file_addr = entry.file_addr - file_range_entry->GetRangeBase() + file_range_entry->data;
+//            if (linked_file_addr == 0x000000000128b7d5)
+//                puts("remove this");
+            sequence.m_entries.back().file_addr = linked_file_addr;
+        }
+        else if (prev_entry_was_linked)
+        {
+            // This entry doesn't have a remapping and it needs to be removed.
+            // Watch out in case we need to terminate a previous entry needs to
+            // be terminated now that one line entry in a sequence is not longer valid.
+            if (!entry.is_terminal_entry &&
+                !sequence.m_entries.empty() &&
+                !sequence.m_entries.back().is_terminal_entry)
+            {
+                assert (prev_file_addr != LLDB_INVALID_ADDRESS);
+                sequence.m_entries.push_back(sequence.m_entries.back());
+                const lldb::addr_t linked_file_addr = std::min<lldb::addr_t>(entry.file_addr,prev_file_range_entry->GetRangeEnd()) - prev_file_range_entry->GetRangeBase() + prev_file_range_entry->data;
+                sequence.m_entries.back().file_addr = linked_file_addr;
+                sequence.m_entries.back().is_terminal_entry = true;
+            }
+        }
+        
+        // If we have items in the sequence and the last entry is a terminal entry,
+        // insert this sequence into our new line table.
+        if (!sequence.m_entries.empty() && sequence.m_entries.back().is_terminal_entry)
+        {
+            line_table_ap->InsertSequence (&sequence);
+            sequence.Clear();
+            prev_entry_was_linked = false;
+            prev_file_addr = LLDB_INVALID_ADDRESS;
+        }
+        else
+        {
+            prev_entry_was_linked = file_range_entry != NULL;
+            prev_file_addr = entry.file_addr;
+        }
+    }
+    if (line_table_ap->m_entries.empty())
+        return NULL;
+    return line_table_ap.release();
+}
+
 
 
 

Modified: lldb/trunk/source/Symbol/ObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ObjectFile.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ObjectFile.cpp (original)
+++ lldb/trunk/source/Symbol/ObjectFile.cpp Mon Mar  4 15:46:16 2013
@@ -200,8 +200,10 @@ ObjectFile::ObjectFile (const lldb::Modu
     m_data (),
     m_unwind_table (*this),
     m_process_wp(),
-    m_memory_addr (LLDB_INVALID_ADDRESS)
-{    
+    m_memory_addr (LLDB_INVALID_ADDRESS),
+    m_sections_ap (),
+    m_symtab_ap ()
+{
     if (file_spec_ptr)
         m_file = *file_spec_ptr;
     if (data_sp)
@@ -209,12 +211,16 @@ ObjectFile::ObjectFile (const lldb::Modu
     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
     if (log)
     {
+        const ConstString object_name (module_sp->GetObjectName());
         if (m_file)
         {
-            log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = %s/%s, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64 "\n",
+            log->Printf ("%p ObjectFile::ObjectFile() module = %p (%s%s%s%s), file = %s/%s, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64,
                          this,
-                         module_sp->GetFileSpec().GetDirectory().AsCString(),
+                         module_sp.get(),
                          module_sp->GetFileSpec().GetFilename().AsCString(),
+                         object_name ? "(" : "",
+                         object_name ? object_name.GetCString() : "",
+                         object_name ? ")" : "",
                          m_file.GetDirectory().AsCString(),
                          m_file.GetFilename().AsCString(),
                          m_file_offset,
@@ -222,10 +228,13 @@ ObjectFile::ObjectFile (const lldb::Modu
         }
         else
         {
-            log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = <NULL>, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64 "\n",
+            log->Printf ("%p ObjectFile::ObjectFile() module = %p (%s%s%s%s), file = <NULL>, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64,
                          this,
-                         module_sp->GetFileSpec().GetDirectory().AsCString(),
+                         module_sp.get(),
                          module_sp->GetFileSpec().GetFilename().AsCString(),
+                         object_name ? "(" : "",
+                         object_name ? object_name.GetCString() : "",
+                         object_name ? ")" : "",
                          m_file_offset,
                          m_length);
         }
@@ -246,17 +255,23 @@ ObjectFile::ObjectFile (const lldb::Modu
     m_data (),
     m_unwind_table (*this),
     m_process_wp (process_sp),
-    m_memory_addr (header_addr)
-{    
+    m_memory_addr (header_addr),
+    m_sections_ap (),
+    m_symtab_ap ()
+{
     if (header_data_sp)
         m_data.SetData (header_data_sp, 0, header_data_sp->GetByteSize());
     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
     if (log)
     {
-        log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, process = %p, header_addr = 0x%" PRIx64 "\n",
+        const ConstString object_name (module_sp->GetObjectName());
+        log->Printf ("%p ObjectFile::ObjectFile() module = %p (%s%s%s%s), process = %p, header_addr = 0x%" PRIx64,
                      this,
-                     module_sp->GetFileSpec().GetDirectory().AsCString(),
+                     module_sp.get(),
                      module_sp->GetFileSpec().GetFilename().AsCString(),
+                     object_name ? "(" : "",
+                     object_name ? object_name.GetCString() : "",
+                     object_name ? ")" : "",
                      process_sp.get(),
                      m_memory_addr);
     }
@@ -519,3 +534,20 @@ ObjectFile::SplitArchivePathWithObject (
     return false;
 }
 
+void
+ObjectFile::ClearSymtab ()
+{
+    ModuleSP module_sp(GetModule());
+    if (module_sp)
+    {
+        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+        if (log)
+        {
+            log->Printf ("%p ObjectFile::ClearSymtab () symtab = %p",
+                         this,
+                         m_symtab_ap.get());
+        }
+        m_symtab_ap.reset();
+    }
+}

Modified: lldb/trunk/source/Symbol/Symtab.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Symtab.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Symtab.cpp (original)
+++ lldb/trunk/source/Symbol/Symtab.cpp Mon Mar  4 15:46:16 2013
@@ -11,6 +11,7 @@
 
 #include "lldb/Core/Module.h"
 #include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/Section.h"
 #include "lldb/Core/Timer.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/SymbolContext.h"
@@ -882,13 +883,13 @@ Symtab::CalculateSymbolSize (Symbol *sym
         if (!m_addr_indexes_computed)
             InitAddressIndexes();
         const size_t num_addr_indexes = m_addr_indexes.size();
+        const lldb::addr_t symbol_file_addr = symbol->GetAddress().GetFileAddress();
         SymbolSearchInfo info = FindIndexPtrForSymbolContainingAddress (this,
-                                                                        symbol->GetAddress().GetFileAddress(),
+                                                                        symbol_file_addr,
                                                                         &m_addr_indexes.front(),
                                                                         num_addr_indexes);
         if (info.match_index_ptr != NULL)
         {
-            const lldb::addr_t curr_file_addr = symbol->GetAddress().GetFileAddress();
             // We can figure out the address range of all symbols except the
             // last one by taking the delta between the current symbol and
             // the next symbol
@@ -899,15 +900,32 @@ Symtab::CalculateSymbolSize (Symbol *sym
             {
                 Symbol *next_symbol = SymbolAtIndex(m_addr_indexes[addr_index]);
                 if (next_symbol == NULL)
-                    break;
-
-                const lldb::addr_t next_file_addr = next_symbol->GetAddress().GetFileAddress();
-                if (next_file_addr > curr_file_addr)
                 {
-                    byte_size = next_file_addr - curr_file_addr;
-                    symbol->SetByteSize(byte_size);
-                    symbol->SetSizeIsSynthesized(true);
-                    break;
+                    // No next symbol take the size to be the remaining bytes in the section
+                    // in which the symbol resides
+                    SectionSP section_sp (m_objfile->GetSectionList()->FindSectionContainingFileAddress (symbol_file_addr));
+                    if (section_sp)
+                    {
+                        const lldb::addr_t end_section_file_addr = section_sp->GetFileAddress() + section_sp->GetByteSize();
+                        if (end_section_file_addr > symbol_file_addr)
+                        {
+                            byte_size = end_section_file_addr - symbol_file_addr;
+                            symbol->SetByteSize(byte_size);
+                            symbol->SetSizeIsSynthesized(true);
+                            break;
+                        }
+                    }
+                }
+                else
+                {
+                    const lldb::addr_t next_file_addr = next_symbol->GetAddress().GetFileAddress();
+                    if (next_file_addr > symbol_file_addr)
+                    {
+                        byte_size = next_file_addr - symbol_file_addr;
+                        symbol->SetByteSize(byte_size);
+                        symbol->SetSizeIsSynthesized(true);
+                        break;
+                    }
                 }
             }
         }





More information about the lldb-commits mailing list