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/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);