Cleanup on the unified section list changes. Main changes are:
- ObjectFile::GetSymtab() and ObjectFile::ClearSymtab() no longer takes any flags
- Module coordinates with the object files and contain a unified section list so that object file and symbol file can share sections when they need to, yet contain their own sections.

Other cleanups:
- Fixed Symbol::GetByteSize() to not have the symbol table compute the byte sizes on the fly
- Modified the ObjectFileMachO class to compute symbol sizes all at once efficiently
- Modified the Symtab class to store a file address lookup table for more efficient lookups
- Removed Section::Finalize() and SectionList::Finalize() as they did nothing
- Improved performance of the detection of symbol files that have debug maps by excluding stripped files and core files, debug files, object files and stubs
- Added the ability to tell if an ObjectFile has been stripped with ObjectFile::IsStripped() (used this for the above performance improvement)

llvm-svn: 185990
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 1045332..fde83fb 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -513,22 +513,6 @@
     return num_specs;
 }
 
-user_id_t
-ObjectFileELF::GetSectionIndexByType(unsigned type)
-{
-    if (!ParseSectionHeaders())
-        return 0;
-
-    for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
-         sh_pos != m_section_headers.end(); ++sh_pos) 
-    {
-        if (sh_pos->sh_type == type)
-            return SectionIndex(sh_pos);
-    }
-
-    return 0;
-}
-
 Address
 ObjectFileELF::GetImageInfoAddress()
 {
@@ -539,28 +523,27 @@
     if (!section_list)
         return Address();
 
-    user_id_t dynsym_id = GetSectionIndexByType(SHT_DYNAMIC);
-    if (!dynsym_id)
+    // Find the SHT_DYNAMIC (.dynamic) section.
+    SectionSP dynsym_section_sp (section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true));
+    if (!dynsym_section_sp)
         return Address();
+    assert (dynsym_section_sp->GetObjectFile() == this);
 
+    user_id_t dynsym_id = dynsym_section_sp->GetID();
     const ELFSectionHeaderInfo *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id);
     if (!dynsym_hdr)
         return Address();
 
-    SectionSP dynsym_section_sp (section_list->FindSectionByID(dynsym_id));
-    if (dynsym_section_sp)
+    for (size_t i = 0; i < m_dynamic_symbols.size(); ++i)
     {
-        for (size_t i = 0; i < m_dynamic_symbols.size(); ++i)
-        {
-            ELFDynamic &symbol = m_dynamic_symbols[i];
+        ELFDynamic &symbol = m_dynamic_symbols[i];
 
-            if (symbol.d_tag == DT_DEBUG)
-            {
-                // Compute the offset as the number of previous entries plus the
-                // size of d_tag.
-                addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
-                return Address(dynsym_section_sp, offset);
-            }
+        if (symbol.d_tag == DT_DEBUG)
+        {
+            // Compute the offset as the number of previous entries plus the
+            // size of d_tag.
+            addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
+            return Address(dynsym_section_sp, offset);
         }
     }
 
@@ -570,26 +553,19 @@
 lldb_private::Address
 ObjectFileELF::GetEntryPointAddress () 
 {
-    SectionList *sections;
-    addr_t offset;
-
     if (m_entry_point_address.IsValid())
         return m_entry_point_address;
 
     if (!ParseHeader() || !IsExecutable())
         return m_entry_point_address;
 
-    sections = GetSectionList();
-    offset = m_header.e_entry;
+    SectionList *section_list = GetSectionList();
+    addr_t offset = m_header.e_entry;
 
-    if (!sections) 
-    {
+    if (!section_list) 
         m_entry_point_address.SetOffset(offset);
-        return m_entry_point_address;
-    }
-
-    m_entry_point_address.ResolveAddressUsingFileSections(offset, sections);
-
+    else
+        m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list);
     return m_entry_point_address;
 }
 
@@ -607,32 +583,22 @@
     if (!ParseSectionHeaders())
         return 0;
 
-    // Locate the dynamic table.
-    user_id_t dynsym_id = 0;
-    user_id_t dynstr_id = 0;
-    for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
-         sh_pos != m_section_headers.end(); ++sh_pos)
-    {
-        if (sh_pos->sh_type == SHT_DYNAMIC)
-        {
-            dynsym_id = SectionIndex(sh_pos);
-            dynstr_id = sh_pos->sh_link + 1; // Section ID's are 1 based.
-            break;
-        }
-    }
-
-    if (!(dynsym_id && dynstr_id))
-        return 0;
-
     SectionList *section_list = GetSectionList();
     if (!section_list)
         return 0;
 
-    // Resolve and load the dynamic table entries and corresponding string
-    // table.
-    Section *dynsym = section_list->FindSectionByID(dynsym_id).get();
-    Section *dynstr = section_list->FindSectionByID(dynstr_id).get();
-    if (!(dynsym && dynstr))
+    // Find the SHT_DYNAMIC section.
+    Section *dynsym = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
+    if (!dynsym)
+        return 0;
+    assert (dynsym->GetObjectFile() == this);
+
+    const ELFSectionHeaderInfo *header = GetSectionHeaderByIndex (dynsym->GetID());
+    if (!header)
+        return 0;
+    // sh_link: section header index of string table used by entries in the section.
+    Section *dynstr = section_list->FindSectionByID (header->sh_link + 1).get();
+    if (!dynstr)
         return 0;
 
     DataExtractor dynsym_data;
@@ -844,30 +810,6 @@
     return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc);
 }
 
-lldb::user_id_t
-ObjectFileELF::GetSectionIndexByName(const char *name)
-{
-    if (!ParseSectionHeaders())
-        return 0;
-
-    // Search the collection of section headers for one with a matching name.
-    for (SectionHeaderCollIter I = m_section_headers.begin();
-         I != m_section_headers.end(); ++I)
-    {
-        const char *sectionName = I->section_name.AsCString();
-
-        if (!sectionName)
-            return 0;
-
-        if (strcmp(name, sectionName) != 0)
-            continue;
-
-        return SectionIndex(I);
-    }
-
-    return 0;
-}
-
 const ObjectFileELF::ELFSectionHeaderInfo *
 ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id)
 {
@@ -880,14 +822,10 @@
     return NULL;
 }
 
-
-SectionList *
-ObjectFileELF::GetSectionList()
+void
+ObjectFileELF::CreateSections(SectionList &unified_section_list)
 {
-    if (m_sections_ap.get())
-        return m_sections_ap.get();
-
-    if (ParseSectionHeaders())
+    if (!m_sections_ap.get() && ParseSectionHeaders())
     {
         m_sections_ap.reset(new SectionList());
 
@@ -982,40 +920,75 @@
                     break;
             }
 
-            SectionSP section_sp(new Section(
-                GetModule(),        // Module to which this section belongs.
-                this,               // ObjectFile to which this section belongs and should read section data from.
-                SectionIndex(I),    // Section ID.
-                name,               // Section name.
-                sect_type,          // Section type.
-                header.sh_addr,     // VM address.
-                vm_size,            // VM size in bytes of this section.
-                header.sh_offset,   // Offset of this section in the file.
-                file_size,          // Size of the section as found in the file.
-                header.sh_flags));  // Flags for this section.
+            SectionSP section_sp (new Section(GetModule(),        // Module to which this section belongs.
+                                              this,               // ObjectFile to which this section belongs and should read section data from.
+                                              SectionIndex(I),    // Section ID.
+                                              name,               // Section name.
+                                              sect_type,          // Section type.
+                                              header.sh_addr,     // VM address.
+                                              vm_size,            // VM size in bytes of this section.
+                                              header.sh_offset,   // Offset of this section in the file.
+                                              file_size,          // Size of the section as found in the file.
+                                              header.sh_flags));  // Flags for this section.
 
             if (is_thread_specific)
                 section_sp->SetIsThreadSpecific (is_thread_specific);
             m_sections_ap->AddSection(section_sp);
         }
-
-        m_sections_ap->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
     }
 
-    return m_sections_ap.get();
+    if (m_sections_ap.get())
+    {
+        if (GetType() == eTypeDebugInfo)
+        {
+            static const SectionType g_sections[] =
+            {
+                eSectionTypeDWARFDebugAranges,
+                eSectionTypeDWARFDebugInfo,
+                eSectionTypeDWARFDebugAbbrev,
+                eSectionTypeDWARFDebugFrame,
+                eSectionTypeDWARFDebugLine,
+                eSectionTypeDWARFDebugStr,
+                eSectionTypeDWARFDebugLoc,
+                eSectionTypeDWARFDebugMacInfo,
+                eSectionTypeDWARFDebugPubNames,
+                eSectionTypeDWARFDebugPubTypes,
+                eSectionTypeDWARFDebugRanges,
+                eSectionTypeELFSymbolTable,
+            };
+            SectionList *elf_section_list = m_sections_ap.get();
+            for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]); ++idx)
+            {
+                SectionType section_type = g_sections[idx];
+                SectionSP section_sp (elf_section_list->FindSectionByType (section_type, true));
+                if (section_sp)
+                {
+                    SectionSP module_section_sp (unified_section_list.FindSectionByType (section_type, true));
+                    if (module_section_sp)
+                        unified_section_list.ReplaceSection (module_section_sp->GetID(), section_sp);
+                    else
+                        unified_section_list.AddSection (section_sp);
+                }
+            }
+        }
+        else
+        {
+            unified_section_list = *m_sections_ap;
+        }
+    }
 }
 
+// private
 unsigned
-ObjectFileELF::ParseSymbols(Symtab *symtab, 
-             user_id_t start_id,
-             SectionList *section_list,
-             const ELFSectionHeaderInfo *symtab_shdr,
-             const DataExtractor &symtab_data,
-             const DataExtractor &strtab_data)
+ObjectFileELF::ParseSymbols (Symtab *symtab,
+                             user_id_t start_id,
+                             SectionList *section_list,
+                             const size_t num_symbols,
+                             const DataExtractor &symtab_data,
+                             const DataExtractor &strtab_data)
 {
     ELFSymbol symbol;
     lldb::offset_t offset = 0;
-    const size_t num_symbols = symtab_data.GetByteSize() / symtab_shdr->sh_entsize;
 
     static ConstString text_section_name(".text");
     static ConstString init_section_name(".init");
@@ -1128,21 +1101,18 @@
             }
         }
 
-        // If the symbol section we've found has no data (SHT_NOBITS), then check the module
-        // for the main object file and use the section there if it has data. This can happen
-        // if we're parsing the debug file and the it has no .text section, for example.
+        // If the symbol section we've found has no data (SHT_NOBITS), then check the module section
+        // list. This can happen if we're parsing the debug file and it has no .text section, for example.
         if (symbol_section_sp && (symbol_section_sp->GetFileSize() == 0))
         {
             ModuleSP module_sp(GetModule());
             if (module_sp)
             {
-                ObjectFile *obj_file = module_sp->GetObjectFile();
-                // Check if we've got a different object file than ourselves.
-                if (obj_file && (obj_file != this))
+                SectionList *module_section_list = module_sp->GetSectionList();
+                if (module_section_list && module_section_list != section_list)
                 {
                     const ConstString &sect_name = symbol_section_sp->GetName();
-                    SectionList *obj_file_section_list = obj_file->GetSectionList();
-                    lldb::SectionSP section_sp (obj_file_section_list->FindSectionByName (sect_name));
+                    lldb::SectionSP section_sp (module_section_list->FindSectionByName (sect_name));
                     if (section_sp && section_sp->GetFileSize())
                     {
                         symbol_section_sp = section_sp;
@@ -1178,32 +1148,46 @@
 }
 
 unsigned
-ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id, user_id_t symtab_id)
+ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id, lldb_private::Section *symtab)
 {
-    // Parse in the section list if needed.
-    SectionList *section_list = GetSectionList();
+    if (symtab->GetObjectFile() != this)
+    {
+        // If the symbol table section is owned by a different object file, have it do the
+        // parsing.
+        ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(symtab->GetObjectFile());
+        return obj_file_elf->ParseSymbolTable (symbol_table, start_id, symtab);
+    }
+
+    // Get section list for this object file.
+    SectionList *section_list = m_sections_ap.get();
     if (!section_list)
         return 0;
 
-    const ELFSectionHeaderInfo *symtab_hdr = &m_section_headers[symtab_id - 1];
+    user_id_t symtab_id = symtab->GetID();
+    const ELFSectionHeaderInfo *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
     assert(symtab_hdr->sh_type == SHT_SYMTAB || 
            symtab_hdr->sh_type == SHT_DYNSYM);
 
+    // sh_link: section header index of associated string table.
     // Section ID's are ones based.
     user_id_t strtab_id = symtab_hdr->sh_link + 1;
-
-    Section *symtab = section_list->FindSectionByID(symtab_id).get();
     Section *strtab = section_list->FindSectionByID(strtab_id).get();
+
     unsigned num_symbols = 0;
     if (symtab && strtab)
     {
+        assert (symtab->GetObjectFile() == this);
+        assert (strtab->GetObjectFile() == this);
+
         DataExtractor symtab_data;
         DataExtractor strtab_data;
         if (ReadSectionData(symtab, symtab_data) &&
             ReadSectionData(strtab, strtab_data))
         {
+            size_t num_symbols = symtab_data.GetByteSize() / symtab_hdr->sh_entsize;
+
             num_symbols = ParseSymbols(symbol_table, start_id, 
-                                       section_list, symtab_hdr,
+                                       section_list, num_symbols,
                                        symtab_data, strtab_data);
         }
     }
@@ -1217,17 +1201,15 @@
     if (m_dynamic_symbols.size())
         return m_dynamic_symbols.size();
 
-    user_id_t dyn_id = GetSectionIndexByType(SHT_DYNAMIC);
-    if (!dyn_id)
-        return 0;
-
     SectionList *section_list = GetSectionList();
     if (!section_list)
         return 0;
 
-    Section *dynsym = section_list->FindSectionByID(dyn_id).get();
+    // Find the SHT_DYNAMIC section.
+    Section *dynsym = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
     if (!dynsym)
         return 0;
+    assert (dynsym->GetObjectFile() == this);
 
     ELFDynamic symbol;
     DataExtractor dynsym_data;
@@ -1360,7 +1342,7 @@
 {
     assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
 
-    // The link field points to the associated symbol table.  The info field
+    // The link field points to the associated symbol table. The info field
     // points to the section holding the plt.
     user_id_t symtab_id = rel_hdr->sh_link;
     user_id_t plt_id = rel_hdr->sh_info;
@@ -1380,7 +1362,7 @@
     if (!sym_hdr)
         return 0;
 
-    SectionList *section_list = GetSectionList();
+    SectionList *section_list = m_sections_ap.get();
     if (!section_list)
         return 0;
 
@@ -1396,6 +1378,7 @@
     if (!symtab)
         return 0;
 
+    // sh_link points to associated string table.
     Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get();
     if (!strtab)
         return 0;
@@ -1430,82 +1413,68 @@
 }
 
 Symtab *
-ObjectFileELF::GetSymtab(uint32_t flags)
+ObjectFileELF::GetSymtab()
 {
     ModuleSP module_sp(GetModule());
-    if (module_sp)
-    {
-        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+    if (!module_sp)
+        return NULL;
 
-        bool from_unified_section_list = !!(flags & eSymtabFromUnifiedSectionList);
-        SectionList *section_list = from_unified_section_list ? module_sp->GetUnifiedSectionList() : GetSectionList();
+    // We always want to use the main object file so we (hopefully) only have one cached copy
+    // of our symtab, dynamic sections, etc.
+    ObjectFile *module_obj_file = module_sp->GetObjectFile();
+    if (module_obj_file && module_obj_file != this)
+        return module_obj_file->GetSymtab();
+
+    if (m_symtab_ap.get() == NULL)
+    {
+        SectionList *section_list = GetSectionList();
         if (!section_list)
             return NULL;
 
-        // If we're doing the unified section list and it has been modified, then clear our
-        // cache and reload the symbols. If needed, we could check on only the sections that
-        // we use to create the symbol table...
-        std::unique_ptr<lldb_private::Symtab> &symtab_ap = from_unified_section_list ? m_symtab_unified_ap : m_symtab_ap;
-        if (from_unified_section_list && (m_symtab_unified_revisionid != section_list->GetRevisionID()))
-        {
-            symtab_ap.reset();
-            m_symtab_unified_revisionid = section_list->GetRevisionID();
-        }
-        else if (symtab_ap.get())
-        {
-            return symtab_ap.get();
-        }
+        uint64_t symbol_id = 0;
+        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
 
-        Symtab *symbol_table = new Symtab(this);
-        symtab_ap.reset(symbol_table);
+        m_symtab_ap.reset(new Symtab(this));
 
         // Sharable objects and dynamic executables usually have 2 distinct symbol
         // tables, one named ".symtab", and the other ".dynsym". The dynsym is a smaller
         // version of the symtab that only contains global symbols. The information found
         // in the dynsym is therefore also found in the symtab, while the reverse is not
         // necessarily true.
-        Section *section_sym = section_list->FindSectionByType (eSectionTypeELFSymbolTable, true).get();
-        if (!section_sym)
+        Section *symtab = section_list->FindSectionByType (eSectionTypeELFSymbolTable, true).get();
+        if (!symtab)
         {
             // The symtab section is non-allocable and can be stripped, so if it doesn't exist
             // then use the dynsym section which should always be there.
-            section_sym = section_list->FindSectionByType (eSectionTypeELFDynamicSymbols, true).get();
+            symtab = section_list->FindSectionByType (eSectionTypeELFDynamicSymbols, true).get();
         }
+        if (symtab)
+            symbol_id += ParseSymbolTable (m_symtab_ap.get(), symbol_id, symtab);
 
-        uint64_t symbol_id = 0;
-        if (section_sym)
+        // Synthesize trampoline symbols to help navigate the PLT.
+        const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
+        if (symbol)
         {
-            user_id_t section_id = section_sym->GetID();
-            ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(section_sym->GetObjectFile());
-
-            symbol_id += obj_file_elf->ParseSymbolTable (symbol_table, symbol_id, section_id);
-        }
-
-        Section *section = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
-        if (section)
-        {
-            ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(section->GetObjectFile());
-
-            // Synthesize trampoline symbols to help navigate the PLT.
-            const ELFDynamic *symbol = obj_file_elf->FindDynamicSymbol(DT_JMPREL);
-            if (symbol)
+            addr_t addr = symbol->d_ptr;
+            Section *reloc_section = section_list->FindSectionContainingFileAddress(addr).get();
+            if (reloc_section) 
             {
-                addr_t addr = symbol->d_ptr;
-                Section *reloc_section = section_list->FindSectionContainingFileAddress(addr).get();
-                if (reloc_section) 
-                {
-                    user_id_t reloc_id = reloc_section->GetID();
-                    const ELFSectionHeaderInfo *reloc_header = obj_file_elf->GetSectionHeaderByIndex(reloc_id);
-                    assert(reloc_header);
+                user_id_t reloc_id = reloc_section->GetID();
+                const ELFSectionHeaderInfo *reloc_header = GetSectionHeaderByIndex(reloc_id);
+                assert(reloc_header);
 
-                    obj_file_elf->ParseTrampolineSymbols(symbol_table, symbol_id, reloc_header, reloc_id);
-                }
+                ParseTrampolineSymbols (m_symtab_ap.get(), symbol_id, reloc_header, reloc_id);
             }
         }
-
-        return symbol_table;
     }
-    return NULL;
+    return m_symtab_ap.get();
+}
+
+bool
+ObjectFileELF::IsStripped ()
+{
+    // TODO: determine this for ELF
+    return false;
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index a6e3cbb..e186fc3 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -100,10 +100,13 @@
     GetAddressByteSize() const;
 
     virtual lldb_private::Symtab *
-    GetSymtab(uint32_t flags = 0);
+    GetSymtab();
 
-    virtual lldb_private::SectionList *
-    GetSectionList();
+    virtual bool
+    IsStripped ();
+
+    virtual void
+    CreateSections (lldb_private::SectionList &unified_section_list);
 
     virtual void
     Dump(lldb_private::Stream *s);
@@ -232,14 +235,14 @@
     unsigned
     ParseSymbolTable(lldb_private::Symtab *symbol_table,
                      lldb::user_id_t start_id,
-                     lldb::user_id_t symtab_id);
+                     lldb_private::Section *symtab);
 
     /// Helper routine for ParseSymbolTable().
     unsigned
     ParseSymbols(lldb_private::Symtab *symbol_table, 
                  lldb::user_id_t start_id,
                  lldb_private::SectionList *section_list,
-                 const ELFSectionHeaderInfo *symtab_shdr,
+                 const size_t num_symbols,
                  const lldb_private::DataExtractor &symtab_data,
                  const lldb_private::DataExtractor &strtab_data);
 
@@ -252,17 +255,6 @@
                            const ELFSectionHeaderInfo *rela_hdr,
                            lldb::user_id_t section_id);
 
-    /// Utility method for looking up a section given its name.  Returns the
-    /// index of the corresponding section or zero if no section with the given
-    /// name can be found (note that section indices are always 1 based, and so
-    /// section index 0 is never valid).
-    lldb::user_id_t
-    GetSectionIndexByName(const char *name);
-
-    // Returns the ID of the first section that has the given type.
-    lldb::user_id_t
-    GetSectionIndexByType(unsigned type);
-
     /// Returns the section header with the given id or NULL.
     const ELFSectionHeaderInfo *
     GetSectionHeaderByIndex(lldb::user_id_t id);
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index c59da7b..bbe2aac 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -895,7 +895,7 @@
 }
 
 Symtab *
-ObjectFileMachO::GetSymtab(uint32_t flags)
+ObjectFileMachO::GetSymtab()
 {
     ModuleSP module_sp(GetModule());
     if (module_sp)
@@ -905,409 +905,462 @@
         {
             m_symtab_ap.reset(new Symtab(this));
             Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
-            ParseSymtab (true);
+            ParseSymtab ();
             m_symtab_ap->Finalize ();
         }
     }
     return m_symtab_ap.get();
 }
 
-
-SectionList *
-ObjectFileMachO::GetSectionList()
+bool
+ObjectFileMachO::IsStripped ()
 {
-    ModuleSP module_sp(GetModule());
-    if (module_sp)
+    if (m_dysymtab.cmd == 0)
     {
-        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
-        if (m_sections_ap.get() == NULL)
+        ModuleSP module_sp(GetModule());
+        if (module_sp)
         {
-            m_sections_ap.reset(new SectionList());
-            ParseSections();
-        }
-    }
-    return m_sections_ap.get();
-}
-
-
-size_t
-ObjectFileMachO::ParseSections ()
-{
-    lldb::user_id_t segID = 0;
-    lldb::user_id_t sectID = 0;
-    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
-    uint32_t i;
-    const bool is_core = GetType() == eTypeCoreFile;
-    //bool dump_sections = false;
-    ModuleSP module_sp (GetModule());
-    // First look up any LC_ENCRYPTION_INFO load commands
-    typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
-    EncryptedFileRanges encrypted_file_ranges;
-    encryption_info_command encryption_cmd;
-    for (i=0; i<m_header.ncmds; ++i)
-    {
-        const lldb::offset_t load_cmd_offset = offset;
-        if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
-            break;
-
-        if (encryption_cmd.cmd == LoadCommandEncryptionInfo)
-        {
-            if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3))
+            lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
+            for (uint32_t i=0; i<m_header.ncmds; ++i)
             {
-                if (encryption_cmd.cryptid != 0)
+                const lldb::offset_t load_cmd_offset = offset;
+                
+                load_command lc;
+                if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
+                    break;
+                if (lc.cmd == LoadCommandDynamicSymtabInfo)
                 {
-                    EncryptedFileRanges::Entry entry;
-                    entry.SetRangeBase(encryption_cmd.cryptoff);
-                    entry.SetByteSize(encryption_cmd.cryptsize);
-                    encrypted_file_ranges.Append(entry);
+                    m_dysymtab.cmd = lc.cmd;
+                    m_dysymtab.cmdsize = lc.cmdsize;
+                    if (m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2) == NULL)
+                    {
+                        // Clear m_dysymtab if we were unable to read all items from the load command
+                        ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
+                    }
                 }
+                offset = load_cmd_offset + lc.cmdsize;
             }
         }
-        offset = load_cmd_offset + encryption_cmd.cmdsize;
     }
+    if (m_dysymtab.cmd)
+        return m_dysymtab.nlocalsym == 0;
+    return false;
+}
 
-    offset = MachHeaderSizeFromMagic(m_header.magic);
-
-    struct segment_command_64 load_cmd;
-    for (i=0; i<m_header.ncmds; ++i)
+void
+ObjectFileMachO::CreateSections (SectionList &unified_section_list)
+{
+    if (!m_sections_ap.get())
     {
-        const lldb::offset_t load_cmd_offset = offset;
-        if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
-            break;
-
-        if (load_cmd.cmd == LoadCommandSegment32 || load_cmd.cmd == LoadCommandSegment64)
+        m_sections_ap.reset(new SectionList());
+        
+        const bool is_dsym = (m_header.filetype == HeaderFileTypeDSYM);
+        lldb::user_id_t segID = 0;
+        lldb::user_id_t sectID = 0;
+        lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
+        uint32_t i;
+        const bool is_core = GetType() == eTypeCoreFile;
+        //bool dump_sections = false;
+        ModuleSP module_sp (GetModule());
+        // First look up any LC_ENCRYPTION_INFO load commands
+        typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
+        EncryptedFileRanges encrypted_file_ranges;
+        encryption_info_command encryption_cmd;
+        for (i=0; i<m_header.ncmds; ++i)
         {
-            if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16))
+            const lldb::offset_t load_cmd_offset = offset;
+            if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
+                break;
+
+            if (encryption_cmd.cmd == LoadCommandEncryptionInfo)
             {
-                load_cmd.vmaddr = m_data.GetAddress(&offset);
-                load_cmd.vmsize = m_data.GetAddress(&offset);
-                load_cmd.fileoff = m_data.GetAddress(&offset);
-                load_cmd.filesize = m_data.GetAddress(&offset);
-                if (m_length != 0 && load_cmd.filesize != 0)
+                if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3))
                 {
-                    if (load_cmd.fileoff > m_length)
+                    if (encryption_cmd.cryptid != 0)
                     {
-                        // We have a load command that says it extends past the end of hte file.  This is likely
-                        // a corrupt file.  We don't have any way to return an error condition here (this method
-                        // was likely invokved from something like ObjectFile::GetSectionList()) -- all we can do
-                        // is null out the SectionList vector and if a process has been set up, dump a message
-                        // to stdout.  The most common case here is core file debugging with a truncated file.
-                        const char *lc_segment_name = load_cmd.cmd == LoadCommandSegment64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
-                        GetModule()->ReportError("is a corrupt mach-o file: load command %u %s has a fileoff (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 ")",
-                                                 i,
-                                                 lc_segment_name,
-                                                 load_cmd.fileoff,
-                                                 m_length);
-                        
-                        load_cmd.fileoff = 0;
-                        load_cmd.filesize = 0;
-                    }
-                    
-                    if (load_cmd.fileoff + load_cmd.filesize > m_length)
-                    {
-                        // We have a load command that says it extends past the end of hte file.  This is likely
-                        // a corrupt file.  We don't have any way to return an error condition here (this method
-                        // was likely invokved from something like ObjectFile::GetSectionList()) -- all we can do
-                        // is null out the SectionList vector and if a process has been set up, dump a message
-                        // to stdout.  The most common case here is core file debugging with a truncated file.
-                        const char *lc_segment_name = load_cmd.cmd == LoadCommandSegment64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
-                        GetModule()->ReportError("is a corrupt mach-o file: load command %u %s has a fileoff + filesize (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 "), the segment will be truncated",
-                                                 i,
-                                                 lc_segment_name,
-                                                 load_cmd.fileoff + load_cmd.filesize,
-                                                 m_length);
-                        
-                        // Tuncase the length
-                        load_cmd.filesize = m_length - load_cmd.fileoff;
+                        EncryptedFileRanges::Entry entry;
+                        entry.SetRangeBase(encryption_cmd.cryptoff);
+                        entry.SetByteSize(encryption_cmd.cryptsize);
+                        encrypted_file_ranges.Append(entry);
                     }
                 }
-                if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
+            }
+            offset = load_cmd_offset + encryption_cmd.cmdsize;
+        }
+
+        offset = MachHeaderSizeFromMagic(m_header.magic);
+
+        struct segment_command_64 load_cmd;
+        for (i=0; i<m_header.ncmds; ++i)
+        {
+            const lldb::offset_t load_cmd_offset = offset;
+            if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
+                break;
+
+            if (load_cmd.cmd == LoadCommandSegment32 || load_cmd.cmd == LoadCommandSegment64)
+            {
+                if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16))
                 {
+                    bool add_section = true;
+                    bool add_to_unified = true;
+                    ConstString const_segname (load_cmd.segname, std::min<size_t>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
 
-                    const bool segment_is_encrypted = (load_cmd.flags & SegmentCommandFlagBitProtectedVersion1) != 0;
-
-                    // Keep a list of mach segments around in case we need to
-                    // get at data that isn't stored in the abstracted Sections.
-                    m_mach_segments.push_back (load_cmd);
-
-                    ConstString segment_name (load_cmd.segname, std::min<size_t>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
-                    // Use a segment ID of the segment index shifted left by 8 so they
-                    // never conflict with any of the sections.
-                    SectionSP segment_sp;
-                    if (segment_name || is_core)
+                    SectionSP unified_section_sp(unified_section_list.FindSectionByName(const_segname));
+                    if (is_dsym && unified_section_sp)
                     {
-                        segment_sp.reset(new Section (module_sp,              // Module to which this section belongs
-                                                      this,                   // Object file to which this sections belongs
-                                                      ++segID << 8,           // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible
-                                                      segment_name,           // Name of this section
-                                                      eSectionTypeContainer,  // This section is a container of other sections.
-                                                      load_cmd.vmaddr,        // File VM address == addresses as they are found in the object file
-                                                      load_cmd.vmsize,        // VM size in bytes of this section
-                                                      load_cmd.fileoff,       // Offset to the data for this section in the file
-                                                      load_cmd.filesize,      // Size in bytes of this section as found in the the file
-                                                      load_cmd.flags));       // Flags for this section
-
-                        segment_sp->SetIsEncrypted (segment_is_encrypted);
-                        m_sections_ap->AddSection(segment_sp);
+                        if (const_segname == GetSegmentNameLINKEDIT())
+                        {
+                            // We need to keep the __LINKEDIT segment private to this object file only
+                            add_to_unified = false;
+                        }
+                        else
+                        {
+                            // This is the dSYM file and this section has already been created by
+                            // the object file, no need to create it.
+                            add_section = false;
+                        }
                     }
-
-                    struct section_64 sect64;
-                    ::memset (&sect64, 0, sizeof(sect64));
-                    // Push a section into our mach sections for the section at
-                    // index zero (NListSectionNoSection) if we don't have any
-                    // mach sections yet...
-                    if (m_mach_sections.empty())
-                        m_mach_sections.push_back(sect64);
-                    uint32_t segment_sect_idx;
-                    const lldb::user_id_t first_segment_sectID = sectID + 1;
-
-
-                    const uint32_t num_u32s = load_cmd.cmd == LoadCommandSegment32 ? 7 : 8;
-                    for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx)
+                    load_cmd.vmaddr = m_data.GetAddress(&offset);
+                    load_cmd.vmsize = m_data.GetAddress(&offset);
+                    load_cmd.fileoff = m_data.GetAddress(&offset);
+                    load_cmd.filesize = m_data.GetAddress(&offset);
+                    if (m_length != 0 && load_cmd.filesize != 0)
                     {
-                        if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL)
-                            break;
-                        if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL)
-                            break;
-                        sect64.addr = m_data.GetAddress(&offset);
-                        sect64.size = m_data.GetAddress(&offset);
+                        if (load_cmd.fileoff > m_length)
+                        {
+                            // We have a load command that says it extends past the end of hte file.  This is likely
+                            // a corrupt file.  We don't have any way to return an error condition here (this method
+                            // was likely invokved from something like ObjectFile::GetSectionList()) -- all we can do
+                            // is null out the SectionList vector and if a process has been set up, dump a message
+                            // to stdout.  The most common case here is core file debugging with a truncated file.
+                            const char *lc_segment_name = load_cmd.cmd == LoadCommandSegment64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
+                            GetModule()->ReportError("is a corrupt mach-o file: load command %u %s has a fileoff (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 ")",
+                                                     i,
+                                                     lc_segment_name,
+                                                     load_cmd.fileoff,
+                                                     m_length);
+                            
+                            load_cmd.fileoff = 0;
+                            load_cmd.filesize = 0;
+                        }
+                        
+                        if (load_cmd.fileoff + load_cmd.filesize > m_length)
+                        {
+                            // We have a load command that says it extends past the end of hte file.  This is likely
+                            // a corrupt file.  We don't have any way to return an error condition here (this method
+                            // was likely invokved from something like ObjectFile::GetSectionList()) -- all we can do
+                            // is null out the SectionList vector and if a process has been set up, dump a message
+                            // to stdout.  The most common case here is core file debugging with a truncated file.
+                            const char *lc_segment_name = load_cmd.cmd == LoadCommandSegment64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
+                            GetModule()->ReportError("is a corrupt mach-o file: load command %u %s has a fileoff + filesize (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 "), the segment will be truncated",
+                                                     i,
+                                                     lc_segment_name,
+                                                     load_cmd.fileoff + load_cmd.filesize,
+                                                     m_length);
+                            
+                            // Tuncase the length
+                            load_cmd.filesize = m_length - load_cmd.fileoff;
+                        }
+                    }
+                    if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
+                    {
 
-                        if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
-                            break;
+                        const bool segment_is_encrypted = (load_cmd.flags & SegmentCommandFlagBitProtectedVersion1) != 0;
 
-                        // Keep a list of mach sections around in case we need to
+                        // Keep a list of mach segments around in case we need to
                         // get at data that isn't stored in the abstracted Sections.
-                        m_mach_sections.push_back (sect64);
+                        m_mach_segments.push_back (load_cmd);
 
-                        ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
-                        if (!segment_name)
+                        // Use a segment ID of the segment index shifted left by 8 so they
+                        // never conflict with any of the sections.
+                        SectionSP segment_sp;
+                        if (add_section && (const_segname || is_core))
                         {
-                            // We have a segment with no name so we need to conjure up
-                            // segments that correspond to the section's segname if there
-                            // isn't already such a section. If there is such a section,
-                            // we resize the section so that it spans all sections.
-                            // We also mark these sections as fake so address matches don't
-                            // hit if they land in the gaps between the child sections.
-                            segment_name.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname));
-                            segment_sp = m_sections_ap->FindSectionByName (segment_name);
-                            if (segment_sp.get())
-                            {
-                                Section *segment = segment_sp.get();
-                                // Grow the section size as needed.
-                                const lldb::addr_t sect64_min_addr = sect64.addr;
-                                const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
-                                const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
-                                const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
-                                const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size;
-                                if (sect64_min_addr >= curr_seg_min_addr)
-                                {
-                                    const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr;
-                                    // Only grow the section size if needed
-                                    if (new_seg_byte_size > curr_seg_byte_size)
-                                        segment->SetByteSize (new_seg_byte_size);
-                                }
-                                else
-                                {
-                                    // We need to change the base address of the segment and
-                                    // adjust the child section offsets for all existing children.
-                                    const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
-                                    segment->Slide(slide_amount, false);
-                                    segment->GetChildren().Slide(-slide_amount, false);
-                                    segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
-                                }
+                            segment_sp.reset(new Section (module_sp,              // Module to which this section belongs
+                                                          this,                   // Object file to which this sections belongs
+                                                          ++segID << 8,           // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible
+                                                          const_segname,          // Name of this section
+                                                          eSectionTypeContainer,  // This section is a container of other sections.
+                                                          load_cmd.vmaddr,        // File VM address == addresses as they are found in the object file
+                                                          load_cmd.vmsize,        // VM size in bytes of this section
+                                                          load_cmd.fileoff,       // Offset to the data for this section in the file
+                                                          load_cmd.filesize,      // Size in bytes of this section as found in the the file
+                                                          load_cmd.flags));       // Flags for this section
 
-                                // Grow the section size as needed.
-                                if (sect64.offset)
-                                {
-                                    const lldb::addr_t segment_min_file_offset = segment->GetFileOffset();
-                                    const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize();
-
-                                    const lldb::addr_t section_min_file_offset = sect64.offset;
-                                    const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size;
-                                    const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset);
-                                    const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset;
-                                    segment->SetFileOffset (new_file_offset);
-                                    segment->SetFileSize (new_file_size);
-                                }
-                            }
-                            else
-                            {
-                                // Create a fake section for the section's named segment
-                                segment_sp.reset(new Section (segment_sp,            // Parent section
-                                                              module_sp,             // Module to which this section belongs
-                                                              this,                  // Object file to which this section belongs
-                                                              ++segID << 8,          // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible
-                                                              segment_name,          // Name of this section
-                                                              eSectionTypeContainer, // This section is a container of other sections.
-                                                              sect64.addr,           // File VM address == addresses as they are found in the object file
-                                                              sect64.size,           // VM size in bytes of this section
-                                                              sect64.offset,         // Offset to the data for this section in the file
-                                                              sect64.offset ? sect64.size : 0,        // Size in bytes of this section as found in the the file
-                                                              load_cmd.flags));      // Flags for this section
-                                segment_sp->SetIsFake(true);
-                                m_sections_ap->AddSection(segment_sp);
-                                segment_sp->SetIsEncrypted (segment_is_encrypted);
-                            }
+                            segment_sp->SetIsEncrypted (segment_is_encrypted);
+                            m_sections_ap->AddSection(segment_sp);
+                            if (add_to_unified)
+                                unified_section_list.AddSection(segment_sp);
                         }
-                        assert (segment_sp.get());
-
-                        uint32_t mach_sect_type = sect64.flags & SectionFlagMaskSectionType;
-                        static ConstString g_sect_name_objc_data ("__objc_data");
-                        static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs");
-                        static ConstString g_sect_name_objc_selrefs ("__objc_selrefs");
-                        static ConstString g_sect_name_objc_classrefs ("__objc_classrefs");
-                        static ConstString g_sect_name_objc_superrefs ("__objc_superrefs");
-                        static ConstString g_sect_name_objc_const ("__objc_const");
-                        static ConstString g_sect_name_objc_classlist ("__objc_classlist");
-                        static ConstString g_sect_name_cfstring ("__cfstring");
-
-                        static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev");
-                        static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges");
-                        static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame");
-                        static ConstString g_sect_name_dwarf_debug_info ("__debug_info");
-                        static ConstString g_sect_name_dwarf_debug_line ("__debug_line");
-                        static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc");
-                        static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo");
-                        static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames");
-                        static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes");
-                        static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges");
-                        static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
-                        static ConstString g_sect_name_dwarf_apple_names ("__apple_names");
-                        static ConstString g_sect_name_dwarf_apple_types ("__apple_types");
-                        static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac");
-                        static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc");
-                        static ConstString g_sect_name_eh_frame ("__eh_frame");
-                        static ConstString g_sect_name_DATA ("__DATA");
-                        static ConstString g_sect_name_TEXT ("__TEXT");
-
-                        SectionType sect_type = eSectionTypeOther;
-
-                        if (section_name == g_sect_name_dwarf_debug_abbrev)
-                            sect_type = eSectionTypeDWARFDebugAbbrev;
-                        else if (section_name == g_sect_name_dwarf_debug_aranges)
-                            sect_type = eSectionTypeDWARFDebugAranges;
-                        else if (section_name == g_sect_name_dwarf_debug_frame)
-                            sect_type = eSectionTypeDWARFDebugFrame;
-                        else if (section_name == g_sect_name_dwarf_debug_info)
-                            sect_type = eSectionTypeDWARFDebugInfo;
-                        else if (section_name == g_sect_name_dwarf_debug_line)
-                            sect_type = eSectionTypeDWARFDebugLine;
-                        else if (section_name == g_sect_name_dwarf_debug_loc)
-                            sect_type = eSectionTypeDWARFDebugLoc;
-                        else if (section_name == g_sect_name_dwarf_debug_macinfo)
-                            sect_type = eSectionTypeDWARFDebugMacInfo;
-                        else if (section_name == g_sect_name_dwarf_debug_pubnames)
-                            sect_type = eSectionTypeDWARFDebugPubNames;
-                        else if (section_name == g_sect_name_dwarf_debug_pubtypes)
-                            sect_type = eSectionTypeDWARFDebugPubTypes;
-                        else if (section_name == g_sect_name_dwarf_debug_ranges)
-                            sect_type = eSectionTypeDWARFDebugRanges;
-                        else if (section_name == g_sect_name_dwarf_debug_str)
-                            sect_type = eSectionTypeDWARFDebugStr;
-                        else if (section_name == g_sect_name_dwarf_apple_names)
-                            sect_type = eSectionTypeDWARFAppleNames;
-                        else if (section_name == g_sect_name_dwarf_apple_types)
-                            sect_type = eSectionTypeDWARFAppleTypes;
-                        else if (section_name == g_sect_name_dwarf_apple_namespaces)
-                            sect_type = eSectionTypeDWARFAppleNamespaces;
-                        else if (section_name == g_sect_name_dwarf_apple_objc)
-                            sect_type = eSectionTypeDWARFAppleObjC;
-                        else if (section_name == g_sect_name_objc_selrefs)
-                            sect_type = eSectionTypeDataCStringPointers;
-                        else if (section_name == g_sect_name_objc_msgrefs)
-                            sect_type = eSectionTypeDataObjCMessageRefs;
-                        else if (section_name == g_sect_name_eh_frame)
-                            sect_type = eSectionTypeEHFrame;
-                        else if (section_name == g_sect_name_cfstring)
-                            sect_type = eSectionTypeDataObjCCFStrings;
-                        else if (section_name == g_sect_name_objc_data ||
-                                 section_name == g_sect_name_objc_classrefs ||
-                                 section_name == g_sect_name_objc_superrefs ||
-                                 section_name == g_sect_name_objc_const ||
-                                 section_name == g_sect_name_objc_classlist)
+                        else if (unified_section_sp)
                         {
-                            sect_type = eSectionTypeDataPointers;
+                            m_sections_ap->AddSection(unified_section_sp);
                         }
 
-                        if (sect_type == eSectionTypeOther)
+                        struct section_64 sect64;
+                        ::memset (&sect64, 0, sizeof(sect64));
+                        // Push a section into our mach sections for the section at
+                        // index zero (NListSectionNoSection) if we don't have any
+                        // mach sections yet...
+                        if (m_mach_sections.empty())
+                            m_mach_sections.push_back(sect64);
+                        uint32_t segment_sect_idx;
+                        const lldb::user_id_t first_segment_sectID = sectID + 1;
+
+
+                        const uint32_t num_u32s = load_cmd.cmd == LoadCommandSegment32 ? 7 : 8;
+                        for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx)
                         {
-                            switch (mach_sect_type)
-                            {
-                            // TODO: categorize sections by other flags for regular sections
-                            case SectionTypeRegular:
-                                if (segment_sp->GetName() == g_sect_name_TEXT)
-                                    sect_type = eSectionTypeCode;
-                                else if (segment_sp->GetName() == g_sect_name_DATA)
-                                    sect_type = eSectionTypeData;
-                                else
-                                    sect_type = eSectionTypeOther;
+                            if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL)
                                 break;
-                            case SectionTypeZeroFill:                   sect_type = eSectionTypeZeroFill; break;
-                            case SectionTypeCStringLiterals:            sect_type = eSectionTypeDataCString;    break; // section with only literal C strings
-                            case SectionType4ByteLiterals:              sect_type = eSectionTypeData4;    break; // section with only 4 byte literals
-                            case SectionType8ByteLiterals:              sect_type = eSectionTypeData8;    break; // section with only 8 byte literals
-                            case SectionTypeLiteralPointers:            sect_type = eSectionTypeDataPointers;  break; // section with only pointers to literals
-                            case SectionTypeNonLazySymbolPointers:      sect_type = eSectionTypeDataPointers;  break; // section with only non-lazy symbol pointers
-                            case SectionTypeLazySymbolPointers:         sect_type = eSectionTypeDataPointers;  break; // section with only lazy symbol pointers
-                            case SectionTypeSymbolStubs:                sect_type = eSectionTypeCode;  break; // section with only symbol stubs, byte size of stub in the reserved2 field
-                            case SectionTypeModuleInitFunctionPointers: sect_type = eSectionTypeDataPointers;    break; // section with only function pointers for initialization
-                            case SectionTypeModuleTermFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination
-                            case SectionTypeCoalesced:                  sect_type = eSectionTypeOther; break;
-                            case SectionTypeZeroFillLarge:              sect_type = eSectionTypeZeroFill; break;
-                            case SectionTypeInterposing:                sect_type = eSectionTypeCode;  break; // section with only pairs of function pointers for interposing
-                            case SectionType16ByteLiterals:             sect_type = eSectionTypeData16; break; // section with only 16 byte literals
-                            case SectionTypeDTraceObjectFormat:         sect_type = eSectionTypeDebug; break;
-                            case SectionTypeLazyDylibSymbolPointers:    sect_type = eSectionTypeDataPointers;  break;
-                            default: break;
+                            if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL)
+                                break;
+                            sect64.addr = m_data.GetAddress(&offset);
+                            sect64.size = m_data.GetAddress(&offset);
+
+                            if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
+                                break;
+
+                            // Keep a list of mach sections around in case we need to
+                            // get at data that isn't stored in the abstracted Sections.
+                            m_mach_sections.push_back (sect64);
+
+                            if (add_section)
+                            {
+                                ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
+                                if (!const_segname)
+                                {
+                                    // We have a segment with no name so we need to conjure up
+                                    // segments that correspond to the section's segname if there
+                                    // isn't already such a section. If there is such a section,
+                                    // we resize the section so that it spans all sections.
+                                    // We also mark these sections as fake so address matches don't
+                                    // hit if they land in the gaps between the child sections.
+                                    const_segname.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname));
+                                    segment_sp = unified_section_list.FindSectionByName (const_segname);
+                                    if (segment_sp.get())
+                                    {
+                                        Section *segment = segment_sp.get();
+                                        // Grow the section size as needed.
+                                        const lldb::addr_t sect64_min_addr = sect64.addr;
+                                        const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
+                                        const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
+                                        const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
+                                        const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size;
+                                        if (sect64_min_addr >= curr_seg_min_addr)
+                                        {
+                                            const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr;
+                                            // Only grow the section size if needed
+                                            if (new_seg_byte_size > curr_seg_byte_size)
+                                                segment->SetByteSize (new_seg_byte_size);
+                                        }
+                                        else
+                                        {
+                                            // We need to change the base address of the segment and
+                                            // adjust the child section offsets for all existing children.
+                                            const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
+                                            segment->Slide(slide_amount, false);
+                                            segment->GetChildren().Slide(-slide_amount, false);
+                                            segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
+                                        }
+
+                                        // Grow the section size as needed.
+                                        if (sect64.offset)
+                                        {
+                                            const lldb::addr_t segment_min_file_offset = segment->GetFileOffset();
+                                            const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize();
+
+                                            const lldb::addr_t section_min_file_offset = sect64.offset;
+                                            const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size;
+                                            const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset);
+                                            const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset;
+                                            segment->SetFileOffset (new_file_offset);
+                                            segment->SetFileSize (new_file_size);
+                                        }
+                                    }
+                                    else
+                                    {
+                                        // Create a fake section for the section's named segment
+                                        segment_sp.reset(new Section (segment_sp,            // Parent section
+                                                                      module_sp,             // Module to which this section belongs
+                                                                      this,                  // Object file to which this section belongs
+                                                                      ++segID << 8,          // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible
+                                                                      const_segname,         // Name of this section
+                                                                      eSectionTypeContainer, // This section is a container of other sections.
+                                                                      sect64.addr,           // File VM address == addresses as they are found in the object file
+                                                                      sect64.size,           // VM size in bytes of this section
+                                                                      sect64.offset,         // Offset to the data for this section in the file
+                                                                      sect64.offset ? sect64.size : 0,        // Size in bytes of this section as found in the the file
+                                                                      load_cmd.flags));      // Flags for this section
+                                        segment_sp->SetIsFake(true);
+                                        
+                                        m_sections_ap->AddSection(segment_sp);
+                                        if (add_to_unified)
+                                            unified_section_list.AddSection(segment_sp);
+                                        segment_sp->SetIsEncrypted (segment_is_encrypted);
+                                    }
+                                }
+                                assert (segment_sp.get());
+
+                                uint32_t mach_sect_type = sect64.flags & SectionFlagMaskSectionType;
+                                static ConstString g_sect_name_objc_data ("__objc_data");
+                                static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs");
+                                static ConstString g_sect_name_objc_selrefs ("__objc_selrefs");
+                                static ConstString g_sect_name_objc_classrefs ("__objc_classrefs");
+                                static ConstString g_sect_name_objc_superrefs ("__objc_superrefs");
+                                static ConstString g_sect_name_objc_const ("__objc_const");
+                                static ConstString g_sect_name_objc_classlist ("__objc_classlist");
+                                static ConstString g_sect_name_cfstring ("__cfstring");
+
+                                static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev");
+                                static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges");
+                                static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame");
+                                static ConstString g_sect_name_dwarf_debug_info ("__debug_info");
+                                static ConstString g_sect_name_dwarf_debug_line ("__debug_line");
+                                static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc");
+                                static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo");
+                                static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames");
+                                static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes");
+                                static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges");
+                                static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
+                                static ConstString g_sect_name_dwarf_apple_names ("__apple_names");
+                                static ConstString g_sect_name_dwarf_apple_types ("__apple_types");
+                                static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac");
+                                static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc");
+                                static ConstString g_sect_name_eh_frame ("__eh_frame");
+                                static ConstString g_sect_name_DATA ("__DATA");
+                                static ConstString g_sect_name_TEXT ("__TEXT");
+
+                                SectionType sect_type = eSectionTypeOther;
+
+                                if (section_name == g_sect_name_dwarf_debug_abbrev)
+                                    sect_type = eSectionTypeDWARFDebugAbbrev;
+                                else if (section_name == g_sect_name_dwarf_debug_aranges)
+                                    sect_type = eSectionTypeDWARFDebugAranges;
+                                else if (section_name == g_sect_name_dwarf_debug_frame)
+                                    sect_type = eSectionTypeDWARFDebugFrame;
+                                else if (section_name == g_sect_name_dwarf_debug_info)
+                                    sect_type = eSectionTypeDWARFDebugInfo;
+                                else if (section_name == g_sect_name_dwarf_debug_line)
+                                    sect_type = eSectionTypeDWARFDebugLine;
+                                else if (section_name == g_sect_name_dwarf_debug_loc)
+                                    sect_type = eSectionTypeDWARFDebugLoc;
+                                else if (section_name == g_sect_name_dwarf_debug_macinfo)
+                                    sect_type = eSectionTypeDWARFDebugMacInfo;
+                                else if (section_name == g_sect_name_dwarf_debug_pubnames)
+                                    sect_type = eSectionTypeDWARFDebugPubNames;
+                                else if (section_name == g_sect_name_dwarf_debug_pubtypes)
+                                    sect_type = eSectionTypeDWARFDebugPubTypes;
+                                else if (section_name == g_sect_name_dwarf_debug_ranges)
+                                    sect_type = eSectionTypeDWARFDebugRanges;
+                                else if (section_name == g_sect_name_dwarf_debug_str)
+                                    sect_type = eSectionTypeDWARFDebugStr;
+                                else if (section_name == g_sect_name_dwarf_apple_names)
+                                    sect_type = eSectionTypeDWARFAppleNames;
+                                else if (section_name == g_sect_name_dwarf_apple_types)
+                                    sect_type = eSectionTypeDWARFAppleTypes;
+                                else if (section_name == g_sect_name_dwarf_apple_namespaces)
+                                    sect_type = eSectionTypeDWARFAppleNamespaces;
+                                else if (section_name == g_sect_name_dwarf_apple_objc)
+                                    sect_type = eSectionTypeDWARFAppleObjC;
+                                else if (section_name == g_sect_name_objc_selrefs)
+                                    sect_type = eSectionTypeDataCStringPointers;
+                                else if (section_name == g_sect_name_objc_msgrefs)
+                                    sect_type = eSectionTypeDataObjCMessageRefs;
+                                else if (section_name == g_sect_name_eh_frame)
+                                    sect_type = eSectionTypeEHFrame;
+                                else if (section_name == g_sect_name_cfstring)
+                                    sect_type = eSectionTypeDataObjCCFStrings;
+                                else if (section_name == g_sect_name_objc_data ||
+                                         section_name == g_sect_name_objc_classrefs ||
+                                         section_name == g_sect_name_objc_superrefs ||
+                                         section_name == g_sect_name_objc_const ||
+                                         section_name == g_sect_name_objc_classlist)
+                                {
+                                    sect_type = eSectionTypeDataPointers;
+                                }
+
+                                if (sect_type == eSectionTypeOther)
+                                {
+                                    switch (mach_sect_type)
+                                    {
+                                    // TODO: categorize sections by other flags for regular sections
+                                    case SectionTypeRegular:
+                                        if (segment_sp->GetName() == g_sect_name_TEXT)
+                                            sect_type = eSectionTypeCode;
+                                        else if (segment_sp->GetName() == g_sect_name_DATA)
+                                            sect_type = eSectionTypeData;
+                                        else
+                                            sect_type = eSectionTypeOther;
+                                        break;
+                                    case SectionTypeZeroFill:                   sect_type = eSectionTypeZeroFill; break;
+                                    case SectionTypeCStringLiterals:            sect_type = eSectionTypeDataCString;    break; // section with only literal C strings
+                                    case SectionType4ByteLiterals:              sect_type = eSectionTypeData4;    break; // section with only 4 byte literals
+                                    case SectionType8ByteLiterals:              sect_type = eSectionTypeData8;    break; // section with only 8 byte literals
+                                    case SectionTypeLiteralPointers:            sect_type = eSectionTypeDataPointers;  break; // section with only pointers to literals
+                                    case SectionTypeNonLazySymbolPointers:      sect_type = eSectionTypeDataPointers;  break; // section with only non-lazy symbol pointers
+                                    case SectionTypeLazySymbolPointers:         sect_type = eSectionTypeDataPointers;  break; // section with only lazy symbol pointers
+                                    case SectionTypeSymbolStubs:                sect_type = eSectionTypeCode;  break; // section with only symbol stubs, byte size of stub in the reserved2 field
+                                    case SectionTypeModuleInitFunctionPointers: sect_type = eSectionTypeDataPointers;    break; // section with only function pointers for initialization
+                                    case SectionTypeModuleTermFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination
+                                    case SectionTypeCoalesced:                  sect_type = eSectionTypeOther; break;
+                                    case SectionTypeZeroFillLarge:              sect_type = eSectionTypeZeroFill; break;
+                                    case SectionTypeInterposing:                sect_type = eSectionTypeCode;  break; // section with only pairs of function pointers for interposing
+                                    case SectionType16ByteLiterals:             sect_type = eSectionTypeData16; break; // section with only 16 byte literals
+                                    case SectionTypeDTraceObjectFormat:         sect_type = eSectionTypeDebug; break;
+                                    case SectionTypeLazyDylibSymbolPointers:    sect_type = eSectionTypeDataPointers;  break;
+                                    default: break;
+                                    }
+                                }
+
+                                SectionSP section_sp(new Section (segment_sp,
+                                                                  module_sp,
+                                                                  this,
+                                                                  ++sectID,
+                                                                  section_name,
+                                                                  sect_type,
+                                                                  sect64.addr - segment_sp->GetFileAddress(),
+                                                                  sect64.size,
+                                                                  sect64.offset,
+                                                                  sect64.offset == 0 ? 0 : sect64.size,
+                                                                  sect64.flags));
+                                // Set the section to be encrypted to match the segment
+
+                                bool section_is_encrypted = false;
+                                if (!segment_is_encrypted && load_cmd.filesize != 0)
+                                    section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL;
+
+                                section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted);
+                                segment_sp->GetChildren().AddSection(section_sp);
+
+                                if (segment_sp->IsFake())
+                                {
+                                    segment_sp.reset();
+                                    const_segname.Clear();
+                                }
                             }
                         }
-
-                        SectionSP section_sp(new Section (segment_sp,
-                                                          module_sp,
-                                                          this,
-                                                          ++sectID,
-                                                          section_name,
-                                                          sect_type,
-                                                          sect64.addr - segment_sp->GetFileAddress(),
-                                                          sect64.size,
-                                                          sect64.offset,
-                                                          sect64.offset == 0 ? 0 : sect64.size,
-                                                          sect64.flags));
-                        // Set the section to be encrypted to match the segment
-
-                        bool section_is_encrypted = false;
-                        if (!segment_is_encrypted && load_cmd.filesize != 0)
-                            section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL;
-
-                        section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted);
-                        segment_sp->GetChildren().AddSection(section_sp);
-
-                        if (segment_sp->IsFake())
+                        if (segment_sp && is_dsym)
                         {
-                            segment_sp.reset();
-                            segment_name.Clear();
-                        }
-                    }
-                    if (segment_sp && m_header.filetype == HeaderFileTypeDSYM)
-                    {
-                        if (first_segment_sectID <= sectID)
-                        {
-                            lldb::user_id_t sect_uid;
-                            for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid)
+                            if (first_segment_sectID <= sectID)
                             {
-                                SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid));
-                                SectionSP next_section_sp;
-                                if (sect_uid + 1 <= sectID)
-                                    next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1);
-
-                                if (curr_section_sp.get())
+                                lldb::user_id_t sect_uid;
+                                for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid)
                                 {
-                                    if (curr_section_sp->GetByteSize() == 0)
+                                    SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid));
+                                    SectionSP next_section_sp;
+                                    if (sect_uid + 1 <= sectID)
+                                        next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1);
+
+                                    if (curr_section_sp.get())
                                     {
-                                        if (next_section_sp.get() != NULL)
-                                            curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() );
-                                        else
-                                            curr_section_sp->SetByteSize ( load_cmd.vmsize );
+                                        if (curr_section_sp->GetByteSize() == 0)
+                                        {
+                                            if (next_section_sp.get() != NULL)
+                                                curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() );
+                                            else
+                                                curr_section_sp->SetByteSize ( load_cmd.vmsize );
+                                        }
                                     }
                                 }
                             }
@@ -1315,22 +1368,20 @@
                     }
                 }
             }
-        }
-        else if (load_cmd.cmd == LoadCommandDynamicSymtabInfo)
-        {
-            m_dysymtab.cmd = load_cmd.cmd;
-            m_dysymtab.cmdsize = load_cmd.cmdsize;
-            m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
-        }
+            else if (load_cmd.cmd == LoadCommandDynamicSymtabInfo)
+            {
+                m_dysymtab.cmd = load_cmd.cmd;
+                m_dysymtab.cmdsize = load_cmd.cmdsize;
+                m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
+            }
 
-        offset = load_cmd_offset + load_cmd.cmdsize;
+            offset = load_cmd_offset + load_cmd.cmdsize;
+        }
+        
+//        StreamFile s(stdout, false);                    // REMOVE THIS LINE
+//        s.Printf ("Sections for %s:\n", m_file.GetPath().c_str());// REMOVE THIS LINE
+//        m_sections_ap->Dump(&s, NULL, true, UINT32_MAX);// REMOVE THIS LINE
     }
-//    if (dump_sections)
-//    {
-//        StreamFile s(stdout);
-//        m_sections_ap->Dump(&s, true);
-//    }
-    return sectID;  // Return the number of sections we registered with the module
 }
 
 class MachSymtabSectionInfo
@@ -1403,7 +1454,7 @@
 };
 
 size_t
-ObjectFileMachO::ParseSymtab (bool minimize)
+ObjectFileMachO::ParseSymtab ()
 {
     Timer scoped_timer(__PRETTY_FUNCTION__,
                        "ObjectFileMachO::ParseSymtab () module = %s",
@@ -2044,8 +2095,7 @@
                                                                 // We don't really need the end function STAB as it contains the size which
                                                                 // we already placed with the original symbol, so don't add it if we want a
                                                                 // minimal symbol table
-                                                                if (minimize)
-                                                                    add_nlist = false;
+                                                                add_nlist = false;
                                                             }
                                                         }
                                                         break;
@@ -2067,17 +2117,8 @@
                                                         // N_BNSYM
                                                         // We use the current number of symbols in the symbol table in lieu of
                                                         // using nlist_idx in case we ever start trimming entries out
-                                                        if (minimize)
-                                                        {
-                                                            // Skip these if we want minimal symbol tables
-                                                            add_nlist = false;
-                                                        }
-                                                        else
-                                                        {
-                                                            symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
-                                                            N_NSYM_indexes.push_back(sym_idx);
-                                                            type = eSymbolTypeScopeBegin;
-                                                        }
+                                                        // Skip these if we want minimal symbol tables
+                                                        add_nlist = false;
                                                         break;
 
                                                     case StabEndSymbol:
@@ -2085,22 +2126,8 @@
                                                         // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
                                                         // so that we can always skip the entire symbol if we need to navigate
                                                         // more quickly at the source level when parsing STABS
-                                                        if (minimize)
-                                                        {
-                                                            // Skip these if we want minimal symbol tables
-                                                            add_nlist = false;
-                                                        }
-                                                        else
-                                                        {
-                                                            if ( !N_NSYM_indexes.empty() )
-                                                            {
-                                                                symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back());
-                                                                symbol_ptr->SetByteSize(sym_idx + 1);
-                                                                symbol_ptr->SetSizeIsSibling(true);
-                                                                N_NSYM_indexes.pop_back();
-                                                            }
-                                                            type = eSymbolTypeScopeEnd;
-                                                        }
+                                                        // Skip these if we want minimal symbol tables
+                                                        add_nlist = false;
                                                         break;
 
 
@@ -2130,15 +2157,14 @@
                                                         type = eSymbolTypeSourceFile;
                                                         if (symbol_name == NULL)
                                                         {
-                                                            if (minimize)
-                                                                add_nlist = false;
+                                                            add_nlist = false;
                                                             if (N_SO_index != UINT32_MAX)
                                                             {
                                                                 // Set the size of the N_SO to the terminating index of this N_SO
                                                                 // so that we can always skip the entire N_SO if we need to navigate
                                                                 // more quickly at the source level when parsing STABS
                                                                 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
-                                                                symbol_ptr->SetByteSize(sym_idx + (minimize ? 0 : 1));
+                                                                symbol_ptr->SetByteSize(sym_idx);
                                                                 symbol_ptr->SetSizeIsSibling(true);
                                                             }
                                                             N_NSYM_indexes.clear();
@@ -2155,7 +2181,7 @@
                                                             const bool N_SO_has_full_path = symbol_name[0] == '/';
                                                             if (N_SO_has_full_path)
                                                             {
-                                                                if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
+                                                                if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
                                                                 {
                                                                     // We have two consecutive N_SO entries where the first contains a directory
                                                                     // and the second contains a full path.
@@ -2170,7 +2196,7 @@
                                                                     N_SO_index = sym_idx;
                                                                 }
                                                             }
-                                                            else if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
+                                                            else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
                                                             {
                                                                 // This is usually the second N_SO entry that contains just the filename,
                                                                 // so here we combine it with the first one if we are minimizing the symbol table
@@ -2253,8 +2279,7 @@
                                                         type = eSymbolTypeHeaderFile;
 
                                                         // We currently don't use the header files on darwin
-                                                        if (minimize)
-                                                            add_nlist = false;
+                                                        add_nlist = false;
                                                         break;
 
                                                     case StabCompilerParameters:
@@ -2503,8 +2528,6 @@
                                             if (add_nlist)
                                             {
                                                 uint64_t symbol_value = nlist.n_value;
-                                                bool symbol_name_is_mangled = false;
-
                                                 if (symbol_name_non_abi_mangled)
                                                 {
                                                     sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
@@ -2512,6 +2535,8 @@
                                                 }
                                                 else
                                                 {
+                                                    bool symbol_name_is_mangled = false;
+                                                    
                                                     if (symbol_name && symbol_name[0] == '_')
                                                     {
                                                         symbol_name_is_mangled = symbol_name[1] == '_';
@@ -2521,9 +2546,9 @@
                                                     if (symbol_name)
                                                     {
                                                         ConstString const_symbol_name(symbol_name);
-                                                        if (is_gsym)
-                                                            N_GSYM_name_to_sym_idx[const_symbol_name.GetCString()] = sym_idx;
                                                         sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
+                                                        if (is_gsym && is_debug)
+                                                            N_GSYM_name_to_sym_idx[sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString()] = sym_idx;
                                                     }
                                                 }
                                                 if (symbol_section)
@@ -2590,8 +2615,7 @@
                                                         ValueToSymbolIndexMap::const_iterator pos = N_FUN_addr_to_sym_idx.find (nlist.n_value);
                                                         if (pos != N_FUN_addr_to_sym_idx.end())
                                                         {
-                                                            if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
-                                                                (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
+                                                            if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
                                                             {
                                                                 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
                                                                 // We just need the flags from the linker symbol, so put these flags
@@ -2611,8 +2635,7 @@
                                                         ValueToSymbolIndexMap::const_iterator pos = N_STSYM_addr_to_sym_idx.find (nlist.n_value);
                                                         if (pos != N_STSYM_addr_to_sym_idx.end())
                                                         {
-                                                            if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
-                                                                (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
+                                                            if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
                                                             {
                                                                 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
                                                                 // We just need the flags from the linker symbol, so put these flags
@@ -2625,7 +2648,7 @@
                                                         else
                                                         {
                                                             // Combine N_GSYM stab entries with the non stab symbol
-                                                            ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(sym[sym_idx].GetMangled().GetMangledName().GetCString());
+                                                            ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString());
                                                             if (pos != N_GSYM_name_to_sym_idx.end())
                                                             {
                                                                 const uint32_t GSYM_sym_idx = pos->second;
@@ -2811,8 +2834,7 @@
                             // We don't really need the end function STAB as it contains the size which
                             // we already placed with the original symbol, so don't add it if we want a
                             // minimal symbol table
-                            if (minimize)
-                                add_nlist = false;
+                            add_nlist = false;
                         }
                     }
                     break;
@@ -2834,17 +2856,8 @@
                     // N_BNSYM
                     // We use the current number of symbols in the symbol table in lieu of
                     // using nlist_idx in case we ever start trimming entries out
-                    if (minimize)
-                    {
-                        // Skip these if we want minimal symbol tables
-                        add_nlist = false;
-                    }
-                    else
-                    {
-                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
-                        N_NSYM_indexes.push_back(sym_idx);
-                        type = eSymbolTypeScopeBegin;
-                    }
+                    // Skip these if we want minimal symbol tables
+                    add_nlist = false;
                     break;
 
                 case StabEndSymbol:
@@ -2852,22 +2865,8 @@
                     // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
                     // so that we can always skip the entire symbol if we need to navigate
                     // more quickly at the source level when parsing STABS
-                    if (minimize)
-                    {
-                        // Skip these if we want minimal symbol tables
-                        add_nlist = false;
-                    }
-                    else
-                    {
-                        if ( !N_NSYM_indexes.empty() )
-                        {
-                            symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back());
-                            symbol_ptr->SetByteSize(sym_idx + 1);
-                            symbol_ptr->SetSizeIsSibling(true);
-                            N_NSYM_indexes.pop_back();
-                        }
-                        type = eSymbolTypeScopeEnd;
-                    }
+                    // Skip these if we want minimal symbol tables
+                    add_nlist = false;
                     break;
 
 
@@ -2897,15 +2896,14 @@
                     type = eSymbolTypeSourceFile;
                     if (symbol_name == NULL)
                     {
-                        if (minimize)
-                            add_nlist = false;
+                        add_nlist = false;
                         if (N_SO_index != UINT32_MAX)
                         {
                             // Set the size of the N_SO to the terminating index of this N_SO
                             // so that we can always skip the entire N_SO if we need to navigate
                             // more quickly at the source level when parsing STABS
                             symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
-                            symbol_ptr->SetByteSize(sym_idx + (minimize ? 0 : 1));
+                            symbol_ptr->SetByteSize(sym_idx);
                             symbol_ptr->SetSizeIsSibling(true);
                         }
                         N_NSYM_indexes.clear();
@@ -2922,7 +2920,7 @@
                         const bool N_SO_has_full_path = symbol_name[0] == '/';
                         if (N_SO_has_full_path)
                         {
-                            if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
+                            if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
                             {
                                 // We have two consecutive N_SO entries where the first contains a directory
                                 // and the second contains a full path.
@@ -2937,7 +2935,7 @@
                                 N_SO_index = sym_idx;
                             }
                         }
-                        else if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
+                        else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
                         {
                             // This is usually the second N_SO entry that contains just the filename,
                             // so here we combine it with the first one if we are minimizing the symbol table
@@ -3021,8 +3019,7 @@
                     type = eSymbolTypeHeaderFile;
 
                     // We currently don't use the header files on darwin
-                    if (minimize)
-                        add_nlist = false;
+                    add_nlist = false;
                     break;
 
                 case StabCompilerParameters:
@@ -3275,7 +3272,6 @@
             if (add_nlist)
             {
                 uint64_t symbol_value = nlist.n_value;
-                bool symbol_name_is_mangled = false;
 
                 if (symbol_name_non_abi_mangled)
                 {
@@ -3284,6 +3280,8 @@
                 }
                 else
                 {
+                    bool symbol_name_is_mangled = false;
+
                     if (symbol_name && symbol_name[0] == '_')
                     {
                         symbol_name_is_mangled = symbol_name[1] == '_';
@@ -3293,9 +3291,11 @@
                     if (symbol_name)
                     {
                         ConstString const_symbol_name(symbol_name);
-                        if (is_gsym)
-                            N_GSYM_name_to_sym_idx[const_symbol_name.GetCString()] = sym_idx;
                         sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
+                        if (is_gsym && is_debug)
+                        {
+                            N_GSYM_name_to_sym_idx[sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString()] = sym_idx;
+                        }
                     }
                 }
                 if (symbol_section)
@@ -3357,8 +3357,7 @@
                         ValueToSymbolIndexMap::const_iterator pos = N_FUN_addr_to_sym_idx.find (nlist.n_value);
                         if (pos != N_FUN_addr_to_sym_idx.end())
                         {
-                            if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
-                                (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
+                            if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
                             {
                                 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
                                 // We just need the flags from the linker symbol, so put these flags
@@ -3378,8 +3377,7 @@
                         ValueToSymbolIndexMap::const_iterator pos = N_STSYM_addr_to_sym_idx.find (nlist.n_value);
                         if (pos != N_STSYM_addr_to_sym_idx.end())
                         {
-                            if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
-                                (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
+                            if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
                             {
                                 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
                                 // We just need the flags from the linker symbol, so put these flags
@@ -3392,7 +3390,7 @@
                         else
                         {
                             // Combine N_GSYM stab entries with the non stab symbol
-                            ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(sym[sym_idx].GetMangled().GetMangledName().GetCString());
+                            ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString());
                             if (pos != N_GSYM_name_to_sym_idx.end())
                             {
                                 const uint32_t GSYM_sym_idx = pos->second;
@@ -3639,6 +3637,16 @@
                 }
             }
         }
+        
+//        StreamFile s(stdout, false);
+//        s.Printf ("Symbol table before CalculateSymbolSizes():\n");
+//        symtab->Dump(&s, NULL, eSortOrderNone);
+        // Set symbol byte sizes correctly since mach-o nlist entries don't have sizes
+        symtab->CalculateSymbolSizes();
+
+//        s.Printf ("Symbol table after CalculateSymbolSizes():\n");
+//        symtab->Dump(&s, NULL, eSortOrderNone);
+
         return symtab->GetNumSymbols();
     }
     return 0;
@@ -3663,8 +3671,9 @@
 
         *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
 
-        if (m_sections_ap.get())
-            m_sections_ap->Dump(s, NULL, true, UINT32_MAX);
+        SectionList *sections = GetSectionList();
+        if (sections)
+            sections->Dump(s, NULL, true, UINT32_MAX);
 
         if (m_symtab_ap.get())
             m_symtab_ap->Dump(s, NULL, eSortOrderNone);
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
index 6587453..1c0d2ce 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
@@ -102,10 +102,13 @@
     GetAddressClass (lldb::addr_t file_addr);
 
     virtual lldb_private::Symtab *
-    GetSymtab(uint32_t flags = 0);
+    GetSymtab();
 
-    virtual lldb_private::SectionList *
-    GetSectionList();
+    virtual bool
+    IsStripped ();
+    
+    virtual void
+    CreateSections (lldb_private::SectionList &unified_section_list);
 
     virtual void
     Dump (lldb_private::Stream *s);
@@ -195,10 +198,7 @@
     bool m_thread_context_offsets_valid;
 
     size_t
-    ParseSections ();
-
-    size_t
-    ParseSymtab (bool minimize);
+    ParseSymtab ();
 
 };
 
diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
index ec1aef7..7afcd6f 100644
--- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -511,7 +511,7 @@
 // GetNListSymtab
 //----------------------------------------------------------------------
 Symtab *
-ObjectFilePECOFF::GetSymtab(uint32_t flags)
+ObjectFilePECOFF::GetSymtab()
 {
     ModuleSP module_sp(GetModule());
     if (module_sp)
@@ -597,16 +597,26 @@
 
 }
 
-SectionList *
-ObjectFilePECOFF::GetSectionList()
+bool
+ObjectFilePECOFF::IsStripped ()
 {
-    ModuleSP module_sp(GetModule());
-    if (module_sp)
+    // TODO: determine this for COFF
+    return false;
+}
+
+
+
+void
+ObjectFilePECOFF::CreateSections (SectionList &unified_section_list)
+{
+    if (!m_sections_ap.get())
     {
-        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
-        if (m_sections_ap.get() == NULL)
+        m_sections_ap.reset(new SectionList());
+
+        ModuleSP module_sp(GetModule());
+        if (module_sp)
         {
-            m_sections_ap.reset(new SectionList());
+            lldb_private::Mutex::Locker locker(module_sp->GetMutex());
             const uint32_t nsects = m_sect_headers.size();
             ModuleSP module_sp (GetModule());
             for (uint32_t idx = 0; idx<nsects; ++idx)
@@ -710,13 +720,11 @@
 
                 //section_sp->SetIsEncrypted (segment_is_encrypted);
 
-                m_sections_ap->AddSection(section_sp);
+                unified_section_list.AddSection(section_sp);
+                m_sections_ap->AddSection (section_sp);
             }
-            
-            m_sections_ap->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
         }
     }
-    return m_sections_ap.get();
 }
 
 bool
@@ -754,8 +762,9 @@
         
         *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
         
-        if (m_sections_ap.get())
-            m_sections_ap->Dump(s, NULL, true, UINT32_MAX);
+        SectionList *sections = GetSectionList();
+        if (sections)
+            sections->Dump(s, NULL, true, UINT32_MAX);
         
         if (m_symtab_ap.get())
             m_symtab_ap->Dump(s, NULL, eSortOrderNone);
diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
index c12c7b9..4a41ba8 100644
--- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
+++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
@@ -86,10 +86,13 @@
 //    GetAddressClass (lldb::addr_t file_addr);
 //    
     virtual lldb_private::Symtab *
-    GetSymtab(uint32_t flags = 0);
+    GetSymtab ();
     
-    virtual lldb_private::SectionList *
-    GetSectionList();
+    virtual bool
+    IsStripped ();
+
+    virtual void
+    CreateSections (lldb_private::SectionList &unified_section_list);
     
     virtual void
     Dump (lldb_private::Stream *s);