This revision was automatically updated to reflect the committed changes.
Closed by commit rL326791: ObjectFileMachO: split CreateSections mega-function 
into more manageable chunks (authored by labath, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D44074?vs=136932&id=137178#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D44074

Files:
  lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
  lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h

Index: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
===================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -1349,25 +1349,12 @@
   return false;
 }
 
-void ObjectFileMachO::CreateSections(SectionList &unified_section_list) {
-  if (m_sections_ap)
-    return;
-
-  m_sections_ap.reset(new SectionList());
-
-  const bool is_dsym = (m_header.filetype == MH_DSYM);
-  lldb::user_id_t segID = 0;
-  lldb::user_id_t sectID = 0;
+ObjectFileMachO::EncryptedFileRanges ObjectFileMachO::GetEncryptedFileRanges() {
+  EncryptedFileRanges result;
   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) {
+  for (uint32_t 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;
@@ -1381,526 +1368,536 @@
           EncryptedFileRanges::Entry entry;
           entry.SetRangeBase(encryption_cmd.cryptoff);
           entry.SetByteSize(encryption_cmd.cryptsize);
-          encrypted_file_ranges.Append(entry);
+          result.Append(entry);
         }
       }
     }
     offset = load_cmd_offset + encryption_cmd.cmdsize;
   }
 
-  bool section_file_addresses_changed = false;
+  return result;
+}
 
-  offset = MachHeaderSizeFromMagic(m_header.magic);
+void ObjectFileMachO::SanitizeSegmentCommand(segment_command_64 &seg_cmd,
+                                             uint32_t cmd_idx) {
+  if (m_length == 0 || seg_cmd.filesize == 0)
+    return;
 
-  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 (seg_cmd.fileoff > m_length) {
+    // We have a load command that says it extends past the end of the file.
+    // This is likely a corrupt file.  We don't have any way to return an error
+    // condition here (this method was likely invoked from something like
+    // ObjectFile::GetSectionList()), so we just null out the section contents,
+    // and dump a message to stdout.  The most common case here is core file
+    // debugging with a truncated file.
+    const char *lc_segment_name =
+        seg_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
+    GetModule()->ReportWarning(
+        "load command %u %s has a fileoff (0x%" PRIx64
+        ") that extends beyond the end of the file (0x%" PRIx64
+        "), ignoring this section",
+        cmd_idx, lc_segment_name, seg_cmd.fileoff, m_length);
+
+    seg_cmd.fileoff = 0;
+    seg_cmd.filesize = 0;
+  }
+
+  if (seg_cmd.fileoff + seg_cmd.filesize > m_length) {
+    // We have a load command that says it extends past the end of the file.
+    // This is likely a corrupt file.  We don't have any way to return an error
+    // condition here (this method was likely invoked from something like
+    // ObjectFile::GetSectionList()), so we just null out the section contents,
+    // and dump a message to stdout.  The most common case here is core file
+    // debugging with a truncated file.
+    const char *lc_segment_name =
+        seg_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
+    GetModule()->ReportWarning(
+        "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 to match",
+        cmd_idx, lc_segment_name, seg_cmd.fileoff + seg_cmd.filesize, m_length);
+
+    // Truncate the length
+    seg_cmd.filesize = m_length - seg_cmd.fileoff;
+  }
+}
 
-    if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64) {
-      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)));
-
-        SectionSP unified_section_sp(
-            unified_section_list.FindSectionByName(const_segname));
-        if (is_dsym && unified_section_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;
-          }
-        }
-        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 (load_cmd.fileoff > m_length) {
-            // We have a load command that says it extends past the end of the
-            // file.  This is likely a corrupt file.  We don't have any way to
-            // return an error condition here (this method was likely invoked
-            // 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 == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
-            module_sp->ReportWarning(
-                "load command %u %s has a fileoff (0x%" PRIx64
-                ") that extends beyond the end of the file (0x%" PRIx64
-                "), ignoring this section",
-                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 the
-            // file.  This is likely a corrupt file.  We don't have any way to
-            // return an error condition here (this method was likely invoked
-            // 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 == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
-            GetModule()->ReportWarning(
-                "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 to match",
-                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)) {
-          uint32_t segment_permissions = 0;
-          if (load_cmd.initprot & VM_PROT_READ)
-            segment_permissions |= ePermissionsReadable;
-          if (load_cmd.initprot & VM_PROT_WRITE)
-            segment_permissions |= ePermissionsWritable;
-          if (load_cmd.initprot & VM_PROT_EXECUTE)
-            segment_permissions |= ePermissionsExecutable;
-
-          const bool segment_is_encrypted =
-              (load_cmd.flags & SG_PROTECTED_VERSION_1) != 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);
-
-          // 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)) {
-            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 file
-                0,                 // Segments have no alignment information
-                load_cmd.flags));  // Flags for this section
-
-            segment_sp->SetIsEncrypted(segment_is_encrypted);
-            m_sections_ap->AddSection(segment_sp);
-            segment_sp->SetPermissions(segment_permissions);
-            if (add_to_unified)
-              unified_section_list.AddSection(segment_sp);
-          } else if (unified_section_sp) {
-            if (is_dsym &&
-                unified_section_sp->GetFileAddress() != load_cmd.vmaddr) {
-              // Check to see if the module was read from memory?
-              if (module_sp->GetObjectFile()->GetHeaderAddress().IsValid()) {
-                // We have a module that is in memory and needs to have its
-                // file address adjusted. We need to do this because when we
-                // load a file from memory, its addresses will be slid already,
-                // yet the addresses in the new symbol file will still be
-                // unslid.  Since everything is stored as section offset, this
-                // shouldn't cause any problems.
-
-                // Make sure we've parsed the symbol table from the
-                // ObjectFile before we go around changing its Sections.
-                module_sp->GetObjectFile()->GetSymtab();
-                // eh_frame would present the same problems but we parse that
-                // on a per-function basis as-needed so it's more difficult to
-                // remove its use of the Sections.  Realistically, the
-                // environments where this code path will be taken will not
-                // have eh_frame sections.
-
-                unified_section_sp->SetFileAddress(load_cmd.vmaddr);
-
-                // Notify the module that the section addresses have been
-                // changed once we're done so any file-address caches can be
-                // updated.
-                section_file_addresses_changed = true;
-              }
-            }
-            m_sections_ap->AddSection(unified_section_sp);
-          }
+static uint32_t GetSegmentPermissions(const segment_command_64 &seg_cmd) {
+  uint32_t result = 0;
+  if (seg_cmd.initprot & VM_PROT_READ)
+    result |= ePermissionsReadable;
+  if (seg_cmd.initprot & VM_PROT_WRITE)
+    result |= ePermissionsWritable;
+  if (seg_cmd.initprot & VM_PROT_EXECUTE)
+    result |= ePermissionsExecutable;
+  return result;
+}
 
-          struct section_64 sect64;
-          ::memset(&sect64, 0, sizeof(sect64));
-          // Push a section into our mach sections for the section at
-          // index zero (NO_SECT) 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 == LC_SEGMENT ? 7 : 8;
-          for (segment_sect_idx = 0; segment_sect_idx < load_cmd.nsects;
-               ++segment_sect_idx) {
-            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);
+static lldb::SectionType GetSectionType(uint32_t flags,
+                                        ConstString section_name) {
 
-            if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
-              break;
+  if (flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
+    return eSectionTypeCode;
 
-            // 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);
-                  }
+  uint32_t mach_sect_type = flags & SECTION_TYPE;
+  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_compact_unwind("__unwind_info");
+  static ConstString g_sect_name_text("__text");
+  static ConstString g_sect_name_data("__data");
+  static ConstString g_sect_name_go_symtab("__gosymtab");
+
+  if (section_name == g_sect_name_dwarf_debug_abbrev)
+    return eSectionTypeDWARFDebugAbbrev;
+  if (section_name == g_sect_name_dwarf_debug_aranges)
+    return eSectionTypeDWARFDebugAranges;
+  if (section_name == g_sect_name_dwarf_debug_frame)
+    return eSectionTypeDWARFDebugFrame;
+  if (section_name == g_sect_name_dwarf_debug_info)
+    return eSectionTypeDWARFDebugInfo;
+  if (section_name == g_sect_name_dwarf_debug_line)
+    return eSectionTypeDWARFDebugLine;
+  if (section_name == g_sect_name_dwarf_debug_loc)
+    return eSectionTypeDWARFDebugLoc;
+  if (section_name == g_sect_name_dwarf_debug_macinfo)
+    return eSectionTypeDWARFDebugMacInfo;
+  if (section_name == g_sect_name_dwarf_debug_pubnames)
+    return eSectionTypeDWARFDebugPubNames;
+  if (section_name == g_sect_name_dwarf_debug_pubtypes)
+    return eSectionTypeDWARFDebugPubTypes;
+  if (section_name == g_sect_name_dwarf_debug_ranges)
+    return eSectionTypeDWARFDebugRanges;
+  if (section_name == g_sect_name_dwarf_debug_str)
+    return eSectionTypeDWARFDebugStr;
+  if (section_name == g_sect_name_dwarf_apple_names)
+    return eSectionTypeDWARFAppleNames;
+  if (section_name == g_sect_name_dwarf_apple_types)
+    return eSectionTypeDWARFAppleTypes;
+  if (section_name == g_sect_name_dwarf_apple_namespaces)
+    return eSectionTypeDWARFAppleNamespaces;
+  if (section_name == g_sect_name_dwarf_apple_objc)
+    return eSectionTypeDWARFAppleObjC;
+  if (section_name == g_sect_name_objc_selrefs)
+    return eSectionTypeDataCStringPointers;
+  if (section_name == g_sect_name_objc_msgrefs)
+    return eSectionTypeDataObjCMessageRefs;
+  if (section_name == g_sect_name_eh_frame)
+    return eSectionTypeEHFrame;
+  if (section_name == g_sect_name_compact_unwind)
+    return eSectionTypeCompactUnwind;
+  if (section_name == g_sect_name_cfstring)
+    return eSectionTypeDataObjCCFStrings;
+  if (section_name == g_sect_name_go_symtab)
+    return eSectionTypeGoSymtab;
+  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) {
+    return eSectionTypeDataPointers;
+  }
+
+  switch (mach_sect_type) {
+  // TODO: categorize sections by other flags for regular sections
+  case S_REGULAR:
+    if (section_name == g_sect_name_text)
+      return eSectionTypeCode;
+    if (section_name == g_sect_name_data)
+      return eSectionTypeData;
+    return eSectionTypeOther;
+  case S_ZEROFILL:
+    return eSectionTypeZeroFill;
+  case S_CSTRING_LITERALS: // section with only literal C strings
+    return eSectionTypeDataCString;
+  case S_4BYTE_LITERALS: // section with only 4 byte literals
+    return eSectionTypeData4;
+  case S_8BYTE_LITERALS: // section with only 8 byte literals
+    return eSectionTypeData8;
+  case S_LITERAL_POINTERS: // section with only pointers to literals
+    return eSectionTypeDataPointers;
+  case S_NON_LAZY_SYMBOL_POINTERS: // section with only non-lazy symbol pointers
+    return eSectionTypeDataPointers;
+  case S_LAZY_SYMBOL_POINTERS: // section with only lazy symbol pointers
+    return eSectionTypeDataPointers;
+  case S_SYMBOL_STUBS: // section with only symbol stubs, byte size of stub in
+                       // the reserved2 field
+    return eSectionTypeCode;
+  case S_MOD_INIT_FUNC_POINTERS: // section with only function pointers for
+                                 // initialization
+    return eSectionTypeDataPointers;
+  case S_MOD_TERM_FUNC_POINTERS: // section with only function pointers for
+                                 // termination
+    return eSectionTypeDataPointers;
+  case S_COALESCED:
+    return eSectionTypeOther;
+  case S_GB_ZEROFILL:
+    return eSectionTypeZeroFill;
+  case S_INTERPOSING: // section with only pairs of function pointers for
+                      // interposing
+    return eSectionTypeCode;
+  case S_16BYTE_LITERALS: // section with only 16 byte literals
+    return eSectionTypeData16;
+  case S_DTRACE_DOF:
+    return eSectionTypeDebug;
+  case S_LAZY_DYLIB_SYMBOL_POINTERS:
+    return eSectionTypeDataPointers;
+  default:
+    return eSectionTypeOther;
+  }
+}
 
-                  // 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 file
-                      sect64.align,
-                      load_cmd.flags)); // Flags for this section
-                  segment_sp->SetIsFake(true);
-                  segment_sp->SetPermissions(segment_permissions);
-                  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());
+struct ObjectFileMachO::SegmentParsingContext {
+  const EncryptedFileRanges EncryptedRanges;
+  lldb_private::SectionList &UnifiedList;
+  uint32_t NextSegmentIdx = 0;
+  uint32_t NextSectionIdx = 0;
+  bool FileAddressesChanged = false;
 
-              lldb::SectionType sect_type = eSectionTypeOther;
+  SegmentParsingContext(EncryptedFileRanges EncryptedRanges,
+                        lldb_private::SectionList &UnifiedList)
+      : EncryptedRanges(std::move(EncryptedRanges)), UnifiedList(UnifiedList) {}
+};
 
-              if (sect64.flags &
-                  (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
-                sect_type = eSectionTypeCode;
-              else {
-                uint32_t mach_sect_type = sect64.flags & SECTION_TYPE;
-                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_compact_unwind("__unwind_info");
-                static ConstString g_sect_name_text("__text");
-                static ConstString g_sect_name_data("__data");
-                static ConstString g_sect_name_go_symtab("__gosymtab");
-
-                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_compact_unwind)
-                  sect_type = eSectionTypeCompactUnwind;
-                else if (section_name == g_sect_name_cfstring)
-                  sect_type = eSectionTypeDataObjCCFStrings;
-                else if (section_name == g_sect_name_go_symtab)
-                  sect_type = eSectionTypeGoSymtab;
-                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;
-                }
+void ObjectFileMachO::ProcessSegmentCommand(const load_command &load_cmd_,
+                                            lldb::offset_t offset,
+                                            uint32_t cmd_idx,
+                                            SegmentParsingContext &context) {
+  segment_command_64 load_cmd;
+  memcpy(&load_cmd, &load_cmd_, sizeof(load_cmd_));
 
-                if (sect_type == eSectionTypeOther) {
-                  switch (mach_sect_type) {
-                  // TODO: categorize sections by other flags for regular
-                  // sections
-                  case S_REGULAR:
-                    if (section_name == g_sect_name_text)
-                      sect_type = eSectionTypeCode;
-                    else if (section_name == g_sect_name_data)
-                      sect_type = eSectionTypeData;
-                    else
-                      sect_type = eSectionTypeOther;
-                    break;
-                  case S_ZEROFILL:
-                    sect_type = eSectionTypeZeroFill;
-                    break;
-                  case S_CSTRING_LITERALS:
-                    sect_type = eSectionTypeDataCString;
-                    break; // section with only literal C strings
-                  case S_4BYTE_LITERALS:
-                    sect_type = eSectionTypeData4;
-                    break; // section with only 4 byte literals
-                  case S_8BYTE_LITERALS:
-                    sect_type = eSectionTypeData8;
-                    break; // section with only 8 byte literals
-                  case S_LITERAL_POINTERS:
-                    sect_type = eSectionTypeDataPointers;
-                    break; // section with only pointers to literals
-                  case S_NON_LAZY_SYMBOL_POINTERS:
-                    sect_type = eSectionTypeDataPointers;
-                    break; // section with only non-lazy symbol pointers
-                  case S_LAZY_SYMBOL_POINTERS:
-                    sect_type = eSectionTypeDataPointers;
-                    break; // section with only lazy symbol pointers
-                  case S_SYMBOL_STUBS:
-                    sect_type = eSectionTypeCode;
-                    break; // section with only symbol stubs, byte size of
-                           // stub in the reserved2 field
-                  case S_MOD_INIT_FUNC_POINTERS:
-                    sect_type = eSectionTypeDataPointers;
-                    break; // section with only function pointers for
-                           // initialization
-                  case S_MOD_TERM_FUNC_POINTERS:
-                    sect_type = eSectionTypeDataPointers;
-                    break; // section with only function pointers for
-                           // termination
-                  case S_COALESCED:
-                    sect_type = eSectionTypeOther;
-                    break;
-                  case S_GB_ZEROFILL:
-                    sect_type = eSectionTypeZeroFill;
-                    break;
-                  case S_INTERPOSING:
-                    sect_type = eSectionTypeCode;
-                    break; // section with only pairs of function pointers for
-                           // interposing
-                  case S_16BYTE_LITERALS:
-                    sect_type = eSectionTypeData16;
-                    break; // section with only 16 byte literals
-                  case S_DTRACE_DOF:
-                    sect_type = eSectionTypeDebug;
-                    break;
-                  case S_LAZY_DYLIB_SYMBOL_POINTERS:
-                    sect_type = eSectionTypeDataPointers;
-                    break;
-                  default:
-                    break;
-                  }
-                }
-              }
+  if (!m_data.GetU8(&offset, (uint8_t *)load_cmd.segname, 16))
+    return;
 
-              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.align,
-                  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);
-              section_sp->SetPermissions(segment_permissions);
-              segment_sp->GetChildren().AddSection(section_sp);
-
-              if (segment_sp->IsFake()) {
-                segment_sp.reset();
-                const_segname.Clear();
-              }
-            }
+  ModuleSP module_sp = GetModule();
+  const bool is_core = GetType() == eTypeCoreFile;
+  const bool is_dsym = (m_header.filetype == MH_DSYM);
+  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)));
+
+  SectionSP unified_section_sp(
+      context.UnifiedList.FindSectionByName(const_segname));
+  if (is_dsym && unified_section_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;
+    }
+  }
+  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_data.GetU32(&offset, &load_cmd.maxprot, 4))
+    return;
+
+  SanitizeSegmentCommand(load_cmd, cmd_idx);
+
+  const uint32_t segment_permissions = GetSegmentPermissions(load_cmd);
+  const bool segment_is_encrypted =
+      (load_cmd.flags & SG_PROTECTED_VERSION_1) != 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);
+
+  // 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)) {
+    segment_sp.reset(new Section(
+        module_sp, // Module to which this section belongs
+        this,      // Object file to which this sections belongs
+        ++context.NextSegmentIdx
+            << 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 file
+        0,                // Segments have no alignment information
+        load_cmd.flags)); // Flags for this section
+
+    segment_sp->SetIsEncrypted(segment_is_encrypted);
+    m_sections_ap->AddSection(segment_sp);
+    segment_sp->SetPermissions(segment_permissions);
+    if (add_to_unified)
+      context.UnifiedList.AddSection(segment_sp);
+  } else if (unified_section_sp) {
+    if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr) {
+      // Check to see if the module was read from memory?
+      if (module_sp->GetObjectFile()->GetHeaderAddress().IsValid()) {
+        // We have a module that is in memory and needs to have its
+        // file address adjusted. We need to do this because when we
+        // load a file from memory, its addresses will be slid already,
+        // yet the addresses in the new symbol file will still be
+        // unslid.  Since everything is stored as section offset, this
+        // shouldn't cause any problems.
+
+        // Make sure we've parsed the symbol table from the
+        // ObjectFile before we go around changing its Sections.
+        module_sp->GetObjectFile()->GetSymtab();
+        // eh_frame would present the same problems but we parse that
+        // on a per-function basis as-needed so it's more difficult to
+        // remove its use of the Sections.  Realistically, the
+        // environments where this code path will be taken will not
+        // have eh_frame sections.
+
+        unified_section_sp->SetFileAddress(load_cmd.vmaddr);
+
+        // Notify the module that the section addresses have been
+        // changed once we're done so any file-address caches can be
+        // updated.
+        context.FileAddressesChanged = true;
+      }
+    }
+    m_sections_ap->AddSection(unified_section_sp);
+  }
+
+  struct section_64 sect64;
+  ::memset(&sect64, 0, sizeof(sect64));
+  // Push a section into our mach sections for the section at
+  // index zero (NO_SECT) 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 = context.NextSectionIdx + 1;
+
+  const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
+  for (segment_sect_idx = 0; segment_sect_idx < load_cmd.nsects;
+       ++segment_sect_idx) {
+    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 (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 = context.UnifiedList.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);
           }
-          if (segment_sp && is_dsym) {
-            if (first_segment_sectID <= sectID) {
-              lldb::user_id_t sect_uid;
-              for (sect_uid = first_segment_sectID; sect_uid <= sectID;
-                   ++sect_uid) {
-                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 (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);
-                  }
-                }
-              }
-            }
+        } 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
+              ++context.NextSegmentIdx
+                  << 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 file
+              sect64.align,
+              load_cmd.flags)); // Flags for this section
+          segment_sp->SetIsFake(true);
+          segment_sp->SetPermissions(segment_permissions);
+          m_sections_ap->AddSection(segment_sp);
+          if (add_to_unified)
+            context.UnifiedList.AddSection(segment_sp);
+          segment_sp->SetIsEncrypted(segment_is_encrypted);
+        }
+      }
+      assert(segment_sp.get());
+
+      lldb::SectionType sect_type = GetSectionType(sect64.flags, section_name);
+
+      SectionSP section_sp(new Section(
+          segment_sp, module_sp, this, ++context.NextSectionIdx, section_name,
+          sect_type, sect64.addr - segment_sp->GetFileAddress(), sect64.size,
+          sect64.offset, sect64.offset == 0 ? 0 : sect64.size, sect64.align,
+          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 = context.EncryptedRanges.FindEntryThatContains(
+                                   sect64.offset) != NULL;
+
+      section_sp->SetIsEncrypted(segment_is_encrypted || section_is_encrypted);
+      section_sp->SetPermissions(segment_permissions);
+      segment_sp->GetChildren().AddSection(section_sp);
+
+      if (segment_sp->IsFake()) {
+        segment_sp.reset();
+        const_segname.Clear();
+      }
+    }
+  }
+  if (segment_sp && is_dsym) {
+    if (first_segment_sectID <= context.NextSectionIdx) {
+      lldb::user_id_t sect_uid;
+      for (sect_uid = first_segment_sectID; sect_uid <= context.NextSectionIdx;
+           ++sect_uid) {
+        SectionSP curr_section_sp(
+            segment_sp->GetChildren().FindSectionByID(sect_uid));
+        SectionSP next_section_sp;
+        if (sect_uid + 1 <= context.NextSectionIdx)
+          next_section_sp =
+              segment_sp->GetChildren().FindSectionByID(sect_uid + 1);
+
+        if (curr_section_sp.get()) {
+          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);
           }
         }
       }
-    } else if (load_cmd.cmd == LC_DYSYMTAB) {
-      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);
     }
+  }
+}
+
+void ObjectFileMachO::ProcessDysymtabCommand(const load_command &load_cmd,
+                                             lldb::offset_t offset) {
+  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);
+}
+
+void ObjectFileMachO::CreateSections(SectionList &unified_section_list) {
+  if (m_sections_ap)
+    return;
+
+  m_sections_ap.reset(new SectionList());
+
+  lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
+  // bool dump_sections = false;
+  ModuleSP module_sp(GetModule());
+
+  offset = MachHeaderSizeFromMagic(m_header.magic);
+
+  SegmentParsingContext context(GetEncryptedFileRanges(), unified_section_list);
+  struct load_command load_cmd;
+  for (uint32_t 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 == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)
+      ProcessSegmentCommand(load_cmd, offset, i, context);
+    else if (load_cmd.cmd == LC_DYSYMTAB)
+      ProcessDysymtabCommand(load_cmd, offset);
 
     offset = load_cmd_offset + load_cmd.cmdsize;
   }
 
-  if (section_file_addresses_changed && module_sp.get()) {
+  if (context.FileAddressesChanged && module_sp)
     module_sp->SectionFileAddressesChanged();
-  }
 }
 
 class MachSymtabSectionInfo {
Index: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
===================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
@@ -185,6 +185,18 @@
 
   size_t ParseSymtab();
 
+  typedef lldb_private::RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
+  EncryptedFileRanges GetEncryptedFileRanges();
+
+  struct SegmentParsingContext;
+  void ProcessDysymtabCommand(const llvm::MachO::load_command &load_cmd,
+                              lldb::offset_t offset);
+  void ProcessSegmentCommand(const llvm::MachO::load_command &load_cmd,
+                             lldb::offset_t offset, uint32_t cmd_idx,
+                             SegmentParsingContext &context);
+  void SanitizeSegmentCommand(llvm::MachO::segment_command_64 &seg_cmd,
+                              uint32_t cmd_idx);
+
   llvm::MachO::mach_header m_header;
   static const lldb_private::ConstString &GetSegmentNameTEXT();
   static const lldb_private::ConstString &GetSegmentNameDATA();
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to