//===-- ObjectFileMachO.cpp -------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/StringRef.h"

#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h"
#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/FileSpecList.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Host/Host.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadList.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RangeMap.h"
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
#include "lldb/Utility/UUID.h"

#include "lldb/Host/SafeMachO.h"

#include "llvm/Support/MemoryBuffer.h"

#include "ObjectFileMachO.h"

#if defined(__APPLE__) &&                                                      \
    (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
// GetLLDBSharedCacheUUID() needs to call dlsym()
#include <dlfcn.h>
#endif

#ifndef __APPLE__
#include "Utility/UuidCompatibility.h"
#else
#include <uuid/uuid.h>
#endif

#include <memory>

#define THUMB_ADDRESS_BIT_MASK 0xfffffffffffffffeull
using namespace lldb;
using namespace lldb_private;
using namespace llvm::MachO;

// Some structure definitions needed for parsing the dyld shared cache files
// found on iOS devices.

struct lldb_copy_dyld_cache_header_v1 {
  char magic[16];         // e.g. "dyld_v0    i386", "dyld_v1   armv7", etc.
  uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info
  uint32_t mappingCount;  // number of dyld_cache_mapping_info entries
  uint32_t imagesOffset;
  uint32_t imagesCount;
  uint64_t dyldBaseAddress;
  uint64_t codeSignatureOffset;
  uint64_t codeSignatureSize;
  uint64_t slideInfoOffset;
  uint64_t slideInfoSize;
  uint64_t localSymbolsOffset;
  uint64_t localSymbolsSize;
  uint8_t uuid[16]; // v1 and above, also recorded in dyld_all_image_infos v13
                    // and later
};

struct lldb_copy_dyld_cache_mapping_info {
  uint64_t address;
  uint64_t size;
  uint64_t fileOffset;
  uint32_t maxProt;
  uint32_t initProt;
};

struct lldb_copy_dyld_cache_local_symbols_info {
  uint32_t nlistOffset;
  uint32_t nlistCount;
  uint32_t stringsOffset;
  uint32_t stringsSize;
  uint32_t entriesOffset;
  uint32_t entriesCount;
};
struct lldb_copy_dyld_cache_local_symbols_entry {
  uint32_t dylibOffset;
  uint32_t nlistStartIndex;
  uint32_t nlistCount;
};

class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64 {
public:
  RegisterContextDarwin_x86_64_Mach(lldb_private::Thread &thread,
                                    const DataExtractor &data)
      : RegisterContextDarwin_x86_64(thread, 0) {
    SetRegisterDataFrom_LC_THREAD(data);
  }

  void InvalidateAllRegisters() override {
    // Do nothing... registers are always valid...
  }

  void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {
    lldb::offset_t offset = 0;
    SetError(GPRRegSet, Read, -1);
    SetError(FPURegSet, Read, -1);
    SetError(EXCRegSet, Read, -1);
    bool done = false;

    while (!done) {
      int flavor = data.GetU32(&offset);
      if (flavor == 0)
        done = true;
      else {
        uint32_t i;
        uint32_t count = data.GetU32(&offset);
        switch (flavor) {
        case GPRRegSet:
          for (i = 0; i < count; ++i)
            (&gpr.rax)[i] = data.GetU64(&offset);
          SetError(GPRRegSet, Read, 0);
          done = true;

          break;
        case FPURegSet:
          // TODO: fill in FPU regs....
          // SetError (FPURegSet, Read, -1);
          done = true;

          break;
        case EXCRegSet:
          exc.trapno = data.GetU32(&offset);
          exc.err = data.GetU32(&offset);
          exc.faultvaddr = data.GetU64(&offset);
          SetError(EXCRegSet, Read, 0);
          done = true;
          break;
        case 7:
        case 8:
        case 9:
          // fancy flavors that encapsulate of the above flavors...
          break;

        default:
          done = true;
          break;
        }
      }
    }
  }

  static size_t WriteRegister(RegisterContext *reg_ctx, const char *name,
                              const char *alt_name, size_t reg_byte_size,
                              Stream &data) {
    const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
    if (reg_info == nullptr)
      reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
    if (reg_info) {
      lldb_private::RegisterValue reg_value;
      if (reg_ctx->ReadRegister(reg_info, reg_value)) {
        if (reg_info->byte_size >= reg_byte_size)
          data.Write(reg_value.GetBytes(), reg_byte_size);
        else {
          data.Write(reg_value.GetBytes(), reg_info->byte_size);
          for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n;
               ++i)
            data.PutChar(0);
        }
        return reg_byte_size;
      }
    }
    // Just write zeros if all else fails
    for (size_t i = 0; i < reg_byte_size; ++i)
      data.PutChar(0);
    return reg_byte_size;
  }

  static bool Create_LC_THREAD(Thread *thread, Stream &data) {
    RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());
    if (reg_ctx_sp) {
      RegisterContext *reg_ctx = reg_ctx_sp.get();

      data.PutHex32(GPRRegSet); // Flavor
      data.PutHex32(GPRWordCount);
      WriteRegister(reg_ctx, "rax", nullptr, 8, data);
      WriteRegister(reg_ctx, "rbx", nullptr, 8, data);
      WriteRegister(reg_ctx, "rcx", nullptr, 8, data);
      WriteRegister(reg_ctx, "rdx", nullptr, 8, data);
      WriteRegister(reg_ctx, "rdi", nullptr, 8, data);
      WriteRegister(reg_ctx, "rsi", nullptr, 8, data);
      WriteRegister(reg_ctx, "rbp", nullptr, 8, data);
      WriteRegister(reg_ctx, "rsp", nullptr, 8, data);
      WriteRegister(reg_ctx, "r8", nullptr, 8, data);
      WriteRegister(reg_ctx, "r9", nullptr, 8, data);
      WriteRegister(reg_ctx, "r10", nullptr, 8, data);
      WriteRegister(reg_ctx, "r11", nullptr, 8, data);
      WriteRegister(reg_ctx, "r12", nullptr, 8, data);
      WriteRegister(reg_ctx, "r13", nullptr, 8, data);
      WriteRegister(reg_ctx, "r14", nullptr, 8, data);
      WriteRegister(reg_ctx, "r15", nullptr, 8, data);
      WriteRegister(reg_ctx, "rip", nullptr, 8, data);
      WriteRegister(reg_ctx, "rflags", nullptr, 8, data);
      WriteRegister(reg_ctx, "cs", nullptr, 8, data);
      WriteRegister(reg_ctx, "fs", nullptr, 8, data);
      WriteRegister(reg_ctx, "gs", nullptr, 8, data);

      //            // Write out the FPU registers
      //            const size_t fpu_byte_size = sizeof(FPU);
      //            size_t bytes_written = 0;
      //            data.PutHex32 (FPURegSet);
      //            data.PutHex32 (fpu_byte_size/sizeof(uint64_t));
      //            bytes_written += data.PutHex32(0); // uint32_t pad[0]
      //            bytes_written += data.PutHex32(0); // uint32_t pad[1]
      //            bytes_written += WriteRegister (reg_ctx, "fcw", "fctrl", 2,
      //            data);   // uint16_t    fcw;    // "fctrl"
      //            bytes_written += WriteRegister (reg_ctx, "fsw" , "fstat", 2,
      //            data);  // uint16_t    fsw;    // "fstat"
      //            bytes_written += WriteRegister (reg_ctx, "ftw" , "ftag", 1,
      //            data);   // uint8_t     ftw;    // "ftag"
      //            bytes_written += data.PutHex8  (0); // uint8_t pad1;
      //            bytes_written += WriteRegister (reg_ctx, "fop" , NULL, 2,
      //            data);     // uint16_t    fop;    // "fop"
      //            bytes_written += WriteRegister (reg_ctx, "fioff", "ip", 4,
      //            data);    // uint32_t    ip;     // "fioff"
      //            bytes_written += WriteRegister (reg_ctx, "fiseg", NULL, 2,
      //            data);    // uint16_t    cs;     // "fiseg"
      //            bytes_written += data.PutHex16 (0); // uint16_t    pad2;
      //            bytes_written += WriteRegister (reg_ctx, "dp", "fooff" , 4,
      //            data);   // uint32_t    dp;     // "fooff"
      //            bytes_written += WriteRegister (reg_ctx, "foseg", NULL, 2,
      //            data);    // uint16_t    ds;     // "foseg"
      //            bytes_written += data.PutHex16 (0); // uint16_t    pad3;
      //            bytes_written += WriteRegister (reg_ctx, "mxcsr", NULL, 4,
      //            data);    // uint32_t    mxcsr;
      //            bytes_written += WriteRegister (reg_ctx, "mxcsrmask", NULL,
      //            4, data);// uint32_t    mxcsrmask;
      //            bytes_written += WriteRegister (reg_ctx, "stmm0", NULL,
      //            sizeof(MMSReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "stmm1", NULL,
      //            sizeof(MMSReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "stmm2", NULL,
      //            sizeof(MMSReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "stmm3", NULL,
      //            sizeof(MMSReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "stmm4", NULL,
      //            sizeof(MMSReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "stmm5", NULL,
      //            sizeof(MMSReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "stmm6", NULL,
      //            sizeof(MMSReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "stmm7", NULL,
      //            sizeof(MMSReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "xmm0" , NULL,
      //            sizeof(XMMReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "xmm1" , NULL,
      //            sizeof(XMMReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "xmm2" , NULL,
      //            sizeof(XMMReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "xmm3" , NULL,
      //            sizeof(XMMReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "xmm4" , NULL,
      //            sizeof(XMMReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "xmm5" , NULL,
      //            sizeof(XMMReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "xmm6" , NULL,
      //            sizeof(XMMReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "xmm7" , NULL,
      //            sizeof(XMMReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "xmm8" , NULL,
      //            sizeof(XMMReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "xmm9" , NULL,
      //            sizeof(XMMReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "xmm10", NULL,
      //            sizeof(XMMReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "xmm11", NULL,
      //            sizeof(XMMReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "xmm12", NULL,
      //            sizeof(XMMReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "xmm13", NULL,
      //            sizeof(XMMReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "xmm14", NULL,
      //            sizeof(XMMReg), data);
      //            bytes_written += WriteRegister (reg_ctx, "xmm15", NULL,
      //            sizeof(XMMReg), data);
      //
      //            // Fill rest with zeros
      //            for (size_t i=0, n = fpu_byte_size - bytes_written; i<n; ++
      //            i)
      //                data.PutChar(0);

      // Write out the EXC registers
      data.PutHex32(EXCRegSet);
      data.PutHex32(EXCWordCount);
      WriteRegister(reg_ctx, "trapno", nullptr, 4, data);
      WriteRegister(reg_ctx, "err", nullptr, 4, data);
      WriteRegister(reg_ctx, "faultvaddr", nullptr, 8, data);
      return true;
    }
    return false;
  }

protected:
  int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return 0; }

  int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return 0; }

  int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return 0; }

  int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
    return 0;
  }

  int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {
    return 0;
  }

  int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {
    return 0;
  }
};

class RegisterContextDarwin_i386_Mach : public RegisterContextDarwin_i386 {
public:
  RegisterContextDarwin_i386_Mach(lldb_private::Thread &thread,
                                  const DataExtractor &data)
      : RegisterContextDarwin_i386(thread, 0) {
    SetRegisterDataFrom_LC_THREAD(data);
  }

  void InvalidateAllRegisters() override {
    // Do nothing... registers are always valid...
  }

  void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {
    lldb::offset_t offset = 0;
    SetError(GPRRegSet, Read, -1);
    SetError(FPURegSet, Read, -1);
    SetError(EXCRegSet, Read, -1);
    bool done = false;

    while (!done) {
      int flavor = data.GetU32(&offset);
      if (flavor == 0)
        done = true;
      else {
        uint32_t i;
        uint32_t count = data.GetU32(&offset);
        switch (flavor) {
        case GPRRegSet:
          for (i = 0; i < count; ++i)
            (&gpr.eax)[i] = data.GetU32(&offset);
          SetError(GPRRegSet, Read, 0);
          done = true;

          break;
        case FPURegSet:
          // TODO: fill in FPU regs....
          // SetError (FPURegSet, Read, -1);
          done = true;

          break;
        case EXCRegSet:
          exc.trapno = data.GetU32(&offset);
          exc.err = data.GetU32(&offset);
          exc.faultvaddr = data.GetU32(&offset);
          SetError(EXCRegSet, Read, 0);
          done = true;
          break;
        case 7:
        case 8:
        case 9:
          // fancy flavors that encapsulate of the above flavors...
          break;

        default:
          done = true;
          break;
        }
      }
    }
  }

  static size_t WriteRegister(RegisterContext *reg_ctx, const char *name,
                              const char *alt_name, size_t reg_byte_size,
                              Stream &data) {
    const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
    if (reg_info == nullptr)
      reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
    if (reg_info) {
      lldb_private::RegisterValue reg_value;
      if (reg_ctx->ReadRegister(reg_info, reg_value)) {
        if (reg_info->byte_size >= reg_byte_size)
          data.Write(reg_value.GetBytes(), reg_byte_size);
        else {
          data.Write(reg_value.GetBytes(), reg_info->byte_size);
          for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n;
               ++i)
            data.PutChar(0);
        }
        return reg_byte_size;
      }
    }
    // Just write zeros if all else fails
    for (size_t i = 0; i < reg_byte_size; ++i)
      data.PutChar(0);
    return reg_byte_size;
  }

  static bool Create_LC_THREAD(Thread *thread, Stream &data) {
    RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());
    if (reg_ctx_sp) {
      RegisterContext *reg_ctx = reg_ctx_sp.get();

      data.PutHex32(GPRRegSet); // Flavor
      data.PutHex32(GPRWordCount);
      WriteRegister(reg_ctx, "eax", nullptr, 4, data);
      WriteRegister(reg_ctx, "ebx", nullptr, 4, data);
      WriteRegister(reg_ctx, "ecx", nullptr, 4, data);
      WriteRegister(reg_ctx, "edx", nullptr, 4, data);
      WriteRegister(reg_ctx, "edi", nullptr, 4, data);
      WriteRegister(reg_ctx, "esi", nullptr, 4, data);
      WriteRegister(reg_ctx, "ebp", nullptr, 4, data);
      WriteRegister(reg_ctx, "esp", nullptr, 4, data);
      WriteRegister(reg_ctx, "ss", nullptr, 4, data);
      WriteRegister(reg_ctx, "eflags", nullptr, 4, data);
      WriteRegister(reg_ctx, "eip", nullptr, 4, data);
      WriteRegister(reg_ctx, "cs", nullptr, 4, data);
      WriteRegister(reg_ctx, "ds", nullptr, 4, data);
      WriteRegister(reg_ctx, "es", nullptr, 4, data);
      WriteRegister(reg_ctx, "fs", nullptr, 4, data);
      WriteRegister(reg_ctx, "gs", nullptr, 4, data);

      // Write out the EXC registers
      data.PutHex32(EXCRegSet);
      data.PutHex32(EXCWordCount);
      WriteRegister(reg_ctx, "trapno", nullptr, 4, data);
      WriteRegister(reg_ctx, "err", nullptr, 4, data);
      WriteRegister(reg_ctx, "faultvaddr", nullptr, 4, data);
      return true;
    }
    return false;
  }

protected:
  int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return 0; }

  int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return 0; }

  int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return 0; }

  int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
    return 0;
  }

  int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {
    return 0;
  }

  int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {
    return 0;
  }
};

class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm {
public:
  RegisterContextDarwin_arm_Mach(lldb_private::Thread &thread,
                                 const DataExtractor &data)
      : RegisterContextDarwin_arm(thread, 0) {
    SetRegisterDataFrom_LC_THREAD(data);
  }

  void InvalidateAllRegisters() override {
    // Do nothing... registers are always valid...
  }

  void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {
    lldb::offset_t offset = 0;
    SetError(GPRRegSet, Read, -1);
    SetError(FPURegSet, Read, -1);
    SetError(EXCRegSet, Read, -1);
    bool done = false;

    while (!done) {
      int flavor = data.GetU32(&offset);
      uint32_t count = data.GetU32(&offset);
      lldb::offset_t next_thread_state = offset + (count * 4);
      switch (flavor) {
      case GPRAltRegSet:
      case GPRRegSet:
        for (uint32_t i = 0; i < count; ++i) {
          gpr.r[i] = data.GetU32(&offset);
        }

        // Note that gpr.cpsr is also copied by the above loop; this loop
        // technically extends one element past the end of the gpr.r[] array.

        SetError(GPRRegSet, Read, 0);
        offset = next_thread_state;
        break;

      case FPURegSet: {
        uint8_t *fpu_reg_buf = (uint8_t *)&fpu.floats.s[0];
        const int fpu_reg_buf_size = sizeof(fpu.floats);
        if (data.ExtractBytes(offset, fpu_reg_buf_size, eByteOrderLittle,
                              fpu_reg_buf) == fpu_reg_buf_size) {
          offset += fpu_reg_buf_size;
          fpu.fpscr = data.GetU32(&offset);
          SetError(FPURegSet, Read, 0);
        } else {
          done = true;
        }
      }
        offset = next_thread_state;
        break;

      case EXCRegSet:
        if (count == 3) {
          exc.exception = data.GetU32(&offset);
          exc.fsr = data.GetU32(&offset);
          exc.far = data.GetU32(&offset);
          SetError(EXCRegSet, Read, 0);
        }
        done = true;
        offset = next_thread_state;
        break;

      // Unknown register set flavor, stop trying to parse.
      default:
        done = true;
      }
    }
  }

  static size_t WriteRegister(RegisterContext *reg_ctx, const char *name,
                              const char *alt_name, size_t reg_byte_size,
                              Stream &data) {
    const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
    if (reg_info == nullptr)
      reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
    if (reg_info) {
      lldb_private::RegisterValue reg_value;
      if (reg_ctx->ReadRegister(reg_info, reg_value)) {
        if (reg_info->byte_size >= reg_byte_size)
          data.Write(reg_value.GetBytes(), reg_byte_size);
        else {
          data.Write(reg_value.GetBytes(), reg_info->byte_size);
          for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n;
               ++i)
            data.PutChar(0);
        }
        return reg_byte_size;
      }
    }
    // Just write zeros if all else fails
    for (size_t i = 0; i < reg_byte_size; ++i)
      data.PutChar(0);
    return reg_byte_size;
  }

  static bool Create_LC_THREAD(Thread *thread, Stream &data) {
    RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());
    if (reg_ctx_sp) {
      RegisterContext *reg_ctx = reg_ctx_sp.get();

      data.PutHex32(GPRRegSet); // Flavor
      data.PutHex32(GPRWordCount);
      WriteRegister(reg_ctx, "r0", nullptr, 4, data);
      WriteRegister(reg_ctx, "r1", nullptr, 4, data);
      WriteRegister(reg_ctx, "r2", nullptr, 4, data);
      WriteRegister(reg_ctx, "r3", nullptr, 4, data);
      WriteRegister(reg_ctx, "r4", nullptr, 4, data);
      WriteRegister(reg_ctx, "r5", nullptr, 4, data);
      WriteRegister(reg_ctx, "r6", nullptr, 4, data);
      WriteRegister(reg_ctx, "r7", nullptr, 4, data);
      WriteRegister(reg_ctx, "r8", nullptr, 4, data);
      WriteRegister(reg_ctx, "r9", nullptr, 4, data);
      WriteRegister(reg_ctx, "r10", nullptr, 4, data);
      WriteRegister(reg_ctx, "r11", nullptr, 4, data);
      WriteRegister(reg_ctx, "r12", nullptr, 4, data);
      WriteRegister(reg_ctx, "sp", nullptr, 4, data);
      WriteRegister(reg_ctx, "lr", nullptr, 4, data);
      WriteRegister(reg_ctx, "pc", nullptr, 4, data);
      WriteRegister(reg_ctx, "cpsr", nullptr, 4, data);

      // Write out the EXC registers
      //            data.PutHex32 (EXCRegSet);
      //            data.PutHex32 (EXCWordCount);
      //            WriteRegister (reg_ctx, "exception", NULL, 4, data);
      //            WriteRegister (reg_ctx, "fsr", NULL, 4, data);
      //            WriteRegister (reg_ctx, "far", NULL, 4, data);
      return true;
    }
    return false;
  }

protected:
  int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; }

  int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; }

  int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; }

  int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override { return -1; }

  int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
    return 0;
  }

  int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {
    return 0;
  }

  int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {
    return 0;
  }

  int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override {
    return -1;
  }
};

class RegisterContextDarwin_arm64_Mach : public RegisterContextDarwin_arm64 {
public:
  RegisterContextDarwin_arm64_Mach(lldb_private::Thread &thread,
                                   const DataExtractor &data)
      : RegisterContextDarwin_arm64(thread, 0) {
    SetRegisterDataFrom_LC_THREAD(data);
  }

  void InvalidateAllRegisters() override {
    // Do nothing... registers are always valid...
  }

  void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {
    lldb::offset_t offset = 0;
    SetError(GPRRegSet, Read, -1);
    SetError(FPURegSet, Read, -1);
    SetError(EXCRegSet, Read, -1);
    bool done = false;
    while (!done) {
      int flavor = data.GetU32(&offset);
      uint32_t count = data.GetU32(&offset);
      lldb::offset_t next_thread_state = offset + (count * 4);
      switch (flavor) {
      case GPRRegSet:
        // x0-x29 + fp + lr + sp + pc (== 33 64-bit registers) plus cpsr (1
        // 32-bit register)
        if (count >= (33 * 2) + 1) {
          for (uint32_t i = 0; i < 29; ++i)
            gpr.x[i] = data.GetU64(&offset);
          gpr.fp = data.GetU64(&offset);
          gpr.lr = data.GetU64(&offset);
          gpr.sp = data.GetU64(&offset);
          gpr.pc = data.GetU64(&offset);
          gpr.cpsr = data.GetU32(&offset);
          SetError(GPRRegSet, Read, 0);
        }
        offset = next_thread_state;
        break;
      case FPURegSet: {
        uint8_t *fpu_reg_buf = (uint8_t *)&fpu.v[0];
        const int fpu_reg_buf_size = sizeof(fpu);
        if (fpu_reg_buf_size == count * sizeof(uint32_t) &&
            data.ExtractBytes(offset, fpu_reg_buf_size, eByteOrderLittle,
                              fpu_reg_buf) == fpu_reg_buf_size) {
          SetError(FPURegSet, Read, 0);
        } else {
          done = true;
        }
      }
        offset = next_thread_state;
        break;
      case EXCRegSet:
        if (count == 4) {
          exc.far = data.GetU64(&offset);
          exc.esr = data.GetU32(&offset);
          exc.exception = data.GetU32(&offset);
          SetError(EXCRegSet, Read, 0);
        }
        offset = next_thread_state;
        break;
      default:
        done = true;
        break;
      }
    }
  }

  static size_t WriteRegister(RegisterContext *reg_ctx, const char *name,
                              const char *alt_name, size_t reg_byte_size,
                              Stream &data) {
    const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
    if (reg_info == nullptr)
      reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
    if (reg_info) {
      lldb_private::RegisterValue reg_value;
      if (reg_ctx->ReadRegister(reg_info, reg_value)) {
        if (reg_info->byte_size >= reg_byte_size)
          data.Write(reg_value.GetBytes(), reg_byte_size);
        else {
          data.Write(reg_value.GetBytes(), reg_info->byte_size);
          for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n;
               ++i)
            data.PutChar(0);
        }
        return reg_byte_size;
      }
    }
    // Just write zeros if all else fails
    for (size_t i = 0; i < reg_byte_size; ++i)
      data.PutChar(0);
    return reg_byte_size;
  }

  static bool Create_LC_THREAD(Thread *thread, Stream &data) {
    RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());
    if (reg_ctx_sp) {
      RegisterContext *reg_ctx = reg_ctx_sp.get();

      data.PutHex32(GPRRegSet); // Flavor
      data.PutHex32(GPRWordCount);
      WriteRegister(reg_ctx, "x0", nullptr, 8, data);
      WriteRegister(reg_ctx, "x1", nullptr, 8, data);
      WriteRegister(reg_ctx, "x2", nullptr, 8, data);
      WriteRegister(reg_ctx, "x3", nullptr, 8, data);
      WriteRegister(reg_ctx, "x4", nullptr, 8, data);
      WriteRegister(reg_ctx, "x5", nullptr, 8, data);
      WriteRegister(reg_ctx, "x6", nullptr, 8, data);
      WriteRegister(reg_ctx, "x7", nullptr, 8, data);
      WriteRegister(reg_ctx, "x8", nullptr, 8, data);
      WriteRegister(reg_ctx, "x9", nullptr, 8, data);
      WriteRegister(reg_ctx, "x10", nullptr, 8, data);
      WriteRegister(reg_ctx, "x11", nullptr, 8, data);
      WriteRegister(reg_ctx, "x12", nullptr, 8, data);
      WriteRegister(reg_ctx, "x13", nullptr, 8, data);
      WriteRegister(reg_ctx, "x14", nullptr, 8, data);
      WriteRegister(reg_ctx, "x15", nullptr, 8, data);
      WriteRegister(reg_ctx, "x16", nullptr, 8, data);
      WriteRegister(reg_ctx, "x17", nullptr, 8, data);
      WriteRegister(reg_ctx, "x18", nullptr, 8, data);
      WriteRegister(reg_ctx, "x19", nullptr, 8, data);
      WriteRegister(reg_ctx, "x20", nullptr, 8, data);
      WriteRegister(reg_ctx, "x21", nullptr, 8, data);
      WriteRegister(reg_ctx, "x22", nullptr, 8, data);
      WriteRegister(reg_ctx, "x23", nullptr, 8, data);
      WriteRegister(reg_ctx, "x24", nullptr, 8, data);
      WriteRegister(reg_ctx, "x25", nullptr, 8, data);
      WriteRegister(reg_ctx, "x26", nullptr, 8, data);
      WriteRegister(reg_ctx, "x27", nullptr, 8, data);
      WriteRegister(reg_ctx, "x28", nullptr, 8, data);
      WriteRegister(reg_ctx, "fp", nullptr, 8, data);
      WriteRegister(reg_ctx, "lr", nullptr, 8, data);
      WriteRegister(reg_ctx, "sp", nullptr, 8, data);
      WriteRegister(reg_ctx, "pc", nullptr, 8, data);
      WriteRegister(reg_ctx, "cpsr", nullptr, 4, data);

      // Write out the EXC registers
      //            data.PutHex32 (EXCRegSet);
      //            data.PutHex32 (EXCWordCount);
      //            WriteRegister (reg_ctx, "far", NULL, 8, data);
      //            WriteRegister (reg_ctx, "esr", NULL, 4, data);
      //            WriteRegister (reg_ctx, "exception", NULL, 4, data);
      return true;
    }
    return false;
  }

protected:
  int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; }

  int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; }

  int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; }

  int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override { return -1; }

  int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
    return 0;
  }

  int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {
    return 0;
  }

  int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {
    return 0;
  }

  int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override {
    return -1;
  }
};

static uint32_t MachHeaderSizeFromMagic(uint32_t magic) {
  switch (magic) {
  case MH_MAGIC:
  case MH_CIGAM:
    return sizeof(struct mach_header);

  case MH_MAGIC_64:
  case MH_CIGAM_64:
    return sizeof(struct mach_header_64);
    break;

  default:
    break;
  }
  return 0;
}

#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008

void ObjectFileMachO::Initialize() {
  PluginManager::RegisterPlugin(
      GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
      CreateMemoryInstance, GetModuleSpecifications, SaveCore);
}

void ObjectFileMachO::Terminate() {
  PluginManager::UnregisterPlugin(CreateInstance);
}

lldb_private::ConstString ObjectFileMachO::GetPluginNameStatic() {
  static ConstString g_name("mach-o");
  return g_name;
}

const char *ObjectFileMachO::GetPluginDescriptionStatic() {
  return "Mach-o object file reader (32 and 64 bit)";
}

ObjectFile *ObjectFileMachO::CreateInstance(const lldb::ModuleSP &module_sp,
                                            DataBufferSP &data_sp,
                                            lldb::offset_t data_offset,
                                            const FileSpec *file,
                                            lldb::offset_t file_offset,
                                            lldb::offset_t length) {
  if (!data_sp) {
    data_sp = MapFileData(*file, length, file_offset);
    if (!data_sp)
      return nullptr;
    data_offset = 0;
  }

  if (!ObjectFileMachO::MagicBytesMatch(data_sp, data_offset, length))
    return nullptr;

  // Update the data to contain the entire file if it doesn't already
  if (data_sp->GetByteSize() < length) {
    data_sp = MapFileData(*file, length, file_offset);
    if (!data_sp)
      return nullptr;
    data_offset = 0;
  }
  auto objfile_up = llvm::make_unique<ObjectFileMachO>(
      module_sp, data_sp, data_offset, file, file_offset, length);
  if (!objfile_up || !objfile_up->ParseHeader())
    return nullptr;

  return objfile_up.release();
}

ObjectFile *ObjectFileMachO::CreateMemoryInstance(
    const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
    const ProcessSP &process_sp, lldb::addr_t header_addr) {
  if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {
    std::unique_ptr<ObjectFile> objfile_up(
        new ObjectFileMachO(module_sp, data_sp, process_sp, header_addr));
    if (objfile_up.get() && objfile_up->ParseHeader())
      return objfile_up.release();
  }
  return nullptr;
}

size_t ObjectFileMachO::GetModuleSpecifications(
    const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
    lldb::offset_t data_offset, lldb::offset_t file_offset,
    lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
  const size_t initial_count = specs.GetSize();

  if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {
    DataExtractor data;
    data.SetData(data_sp);
    llvm::MachO::mach_header header;
    if (ParseHeader(data, &data_offset, header)) {
      size_t header_and_load_cmds =
          header.sizeofcmds + MachHeaderSizeFromMagic(header.magic);
      if (header_and_load_cmds >= data_sp->GetByteSize()) {
        data_sp = MapFileData(file, header_and_load_cmds, file_offset);
        data.SetData(data_sp);
        data_offset = MachHeaderSizeFromMagic(header.magic);
      }
      if (data_sp) {
        ModuleSpec spec;
        spec.GetFileSpec() = file;
        spec.SetObjectOffset(file_offset);
        spec.SetObjectSize(length);

        spec.GetArchitecture() = GetArchitecture(header, data, data_offset);
        if (spec.GetArchitecture().IsValid()) {
          spec.GetUUID() = GetUUID(header, data, data_offset);
          specs.Append(spec);
        }
      }
    }
  }
  return specs.GetSize() - initial_count;
}

ConstString ObjectFileMachO::GetSegmentNameTEXT() {
  static ConstString g_segment_name_TEXT("__TEXT");
  return g_segment_name_TEXT;
}

ConstString ObjectFileMachO::GetSegmentNameDATA() {
  static ConstString g_segment_name_DATA("__DATA");
  return g_segment_name_DATA;
}

ConstString ObjectFileMachO::GetSegmentNameDATA_DIRTY() {
  static ConstString g_segment_name("__DATA_DIRTY");
  return g_segment_name;
}

ConstString ObjectFileMachO::GetSegmentNameDATA_CONST() {
  static ConstString g_segment_name("__DATA_CONST");
  return g_segment_name;
}

ConstString ObjectFileMachO::GetSegmentNameOBJC() {
  static ConstString g_segment_name_OBJC("__OBJC");
  return g_segment_name_OBJC;
}

ConstString ObjectFileMachO::GetSegmentNameLINKEDIT() {
  static ConstString g_section_name_LINKEDIT("__LINKEDIT");
  return g_section_name_LINKEDIT;
}

ConstString ObjectFileMachO::GetSegmentNameDWARF() {
  static ConstString g_section_name("__DWARF");
  return g_section_name;
}

ConstString ObjectFileMachO::GetSectionNameEHFrame() {
  static ConstString g_section_name_eh_frame("__eh_frame");
  return g_section_name_eh_frame;
}

bool ObjectFileMachO::MagicBytesMatch(DataBufferSP &data_sp,
                                      lldb::addr_t data_offset,
                                      lldb::addr_t data_length) {
  DataExtractor data;
  data.SetData(data_sp, data_offset, data_length);
  lldb::offset_t offset = 0;
  uint32_t magic = data.GetU32(&offset);
  return MachHeaderSizeFromMagic(magic) != 0;
}

ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
                                 DataBufferSP &data_sp,
                                 lldb::offset_t data_offset,
                                 const FileSpec *file,
                                 lldb::offset_t file_offset,
                                 lldb::offset_t length)
    : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
      m_mach_segments(), m_mach_sections(), m_entry_point_address(),
      m_thread_context_offsets(), m_thread_context_offsets_valid(false),
      m_reexported_dylibs(), m_allow_assembly_emulation_unwind_plans(true) {
  ::memset(&m_header, 0, sizeof(m_header));
  ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));
}

ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
                                 lldb::DataBufferSP &header_data_sp,
                                 const lldb::ProcessSP &process_sp,
                                 lldb::addr_t header_addr)
    : ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
      m_mach_segments(), m_mach_sections(), m_entry_point_address(),
      m_thread_context_offsets(), m_thread_context_offsets_valid(false),
      m_reexported_dylibs(), m_allow_assembly_emulation_unwind_plans(true) {
  ::memset(&m_header, 0, sizeof(m_header));
  ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));
}

bool ObjectFileMachO::ParseHeader(DataExtractor &data,
                                  lldb::offset_t *data_offset_ptr,
                                  llvm::MachO::mach_header &header) {
  data.SetByteOrder(endian::InlHostByteOrder());
  // Leave magic in the original byte order
  header.magic = data.GetU32(data_offset_ptr);
  bool can_parse = false;
  bool is_64_bit = false;
  switch (header.magic) {
  case MH_MAGIC:
    data.SetByteOrder(endian::InlHostByteOrder());
    data.SetAddressByteSize(4);
    can_parse = true;
    break;

  case MH_MAGIC_64:
    data.SetByteOrder(endian::InlHostByteOrder());
    data.SetAddressByteSize(8);
    can_parse = true;
    is_64_bit = true;
    break;

  case MH_CIGAM:
    data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
                          ? eByteOrderLittle
                          : eByteOrderBig);
    data.SetAddressByteSize(4);
    can_parse = true;
    break;

  case MH_CIGAM_64:
    data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
                          ? eByteOrderLittle
                          : eByteOrderBig);
    data.SetAddressByteSize(8);
    is_64_bit = true;
    can_parse = true;
    break;

  default:
    break;
  }

  if (can_parse) {
    data.GetU32(data_offset_ptr, &header.cputype, 6);
    if (is_64_bit)
      *data_offset_ptr += 4;
    return true;
  } else {
    memset(&header, 0, sizeof(header));
  }
  return false;
}

bool ObjectFileMachO::ParseHeader() {
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
    bool can_parse = false;
    lldb::offset_t offset = 0;
    m_data.SetByteOrder(endian::InlHostByteOrder());
    // Leave magic in the original byte order
    m_header.magic = m_data.GetU32(&offset);
    switch (m_header.magic) {
    case MH_MAGIC:
      m_data.SetByteOrder(endian::InlHostByteOrder());
      m_data.SetAddressByteSize(4);
      can_parse = true;
      break;

    case MH_MAGIC_64:
      m_data.SetByteOrder(endian::InlHostByteOrder());
      m_data.SetAddressByteSize(8);
      can_parse = true;
      break;

    case MH_CIGAM:
      m_data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
                              ? eByteOrderLittle
                              : eByteOrderBig);
      m_data.SetAddressByteSize(4);
      can_parse = true;
      break;

    case MH_CIGAM_64:
      m_data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
                              ? eByteOrderLittle
                              : eByteOrderBig);
      m_data.SetAddressByteSize(8);
      can_parse = true;
      break;

    default:
      break;
    }

    if (can_parse) {
      m_data.GetU32(&offset, &m_header.cputype, 6);

      if (ArchSpec mach_arch = GetArchitecture()) {
        // Check if the module has a required architecture
        const ArchSpec &module_arch = module_sp->GetArchitecture();
        if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch))
          return false;

        if (SetModulesArchitecture(mach_arch)) {
          const size_t header_and_lc_size =
              m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
          if (m_data.GetByteSize() < header_and_lc_size) {
            DataBufferSP data_sp;
            ProcessSP process_sp(m_process_wp.lock());
            if (process_sp) {
              data_sp =
                  ReadMemory(process_sp, m_memory_addr, header_and_lc_size);
            } else {
              // Read in all only the load command data from the file on disk
              data_sp = MapFileData(m_file, header_and_lc_size, m_file_offset);
              if (data_sp->GetByteSize() != header_and_lc_size)
                return false;
            }
            if (data_sp)
              m_data.SetData(data_sp);
          }
        }
        return true;
      }
    } else {
      memset(&m_header, 0, sizeof(struct mach_header));
    }
  }
  return false;
}

ByteOrder ObjectFileMachO::GetByteOrder() const {
  return m_data.GetByteOrder();
}

bool ObjectFileMachO::IsExecutable() const {
  return m_header.filetype == MH_EXECUTE;
}

uint32_t ObjectFileMachO::GetAddressByteSize() const {
  return m_data.GetAddressByteSize();
}

AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) {
  Symtab *symtab = GetSymtab();
  if (symtab) {
    Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
    if (symbol) {
      if (symbol->ValueIsAddress()) {
        SectionSP section_sp(symbol->GetAddressRef().GetSection());
        if (section_sp) {
          const lldb::SectionType section_type = section_sp->GetType();
          switch (section_type) {
          case eSectionTypeInvalid:
            return AddressClass::eUnknown;

          case eSectionTypeCode:
            if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
              // For ARM we have a bit in the n_desc field of the symbol that
              // tells us ARM/Thumb which is bit 0x0008.
              if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
                return AddressClass::eCodeAlternateISA;
            }
            return AddressClass::eCode;

          case eSectionTypeContainer:
            return AddressClass::eUnknown;

          case eSectionTypeData:
          case eSectionTypeDataCString:
          case eSectionTypeDataCStringPointers:
          case eSectionTypeDataSymbolAddress:
          case eSectionTypeData4:
          case eSectionTypeData8:
          case eSectionTypeData16:
          case eSectionTypeDataPointers:
          case eSectionTypeZeroFill:
          case eSectionTypeDataObjCMessageRefs:
          case eSectionTypeDataObjCCFStrings:
          case eSectionTypeGoSymtab:
            return AddressClass::eData;

          case eSectionTypeDebug:
          case eSectionTypeDWARFDebugAbbrev:
          case eSectionTypeDWARFDebugAbbrevDwo:
          case eSectionTypeDWARFDebugAddr:
          case eSectionTypeDWARFDebugAranges:
          case eSectionTypeDWARFDebugCuIndex:
          case eSectionTypeDWARFDebugFrame:
          case eSectionTypeDWARFDebugInfo:
          case eSectionTypeDWARFDebugInfoDwo:
          case eSectionTypeDWARFDebugLine:
          case eSectionTypeDWARFDebugLineStr:
          case eSectionTypeDWARFDebugLoc:
          case eSectionTypeDWARFDebugLocLists:
          case eSectionTypeDWARFDebugMacInfo:
          case eSectionTypeDWARFDebugMacro:
          case eSectionTypeDWARFDebugNames:
          case eSectionTypeDWARFDebugPubNames:
          case eSectionTypeDWARFDebugPubTypes:
          case eSectionTypeDWARFDebugRanges:
          case eSectionTypeDWARFDebugRngLists:
          case eSectionTypeDWARFDebugStr:
          case eSectionTypeDWARFDebugStrDwo:
          case eSectionTypeDWARFDebugStrOffsets:
          case eSectionTypeDWARFDebugStrOffsetsDwo:
          case eSectionTypeDWARFDebugTypes:
          case eSectionTypeDWARFDebugTypesDwo:
          case eSectionTypeDWARFAppleNames:
          case eSectionTypeDWARFAppleTypes:
          case eSectionTypeDWARFAppleNamespaces:
          case eSectionTypeDWARFAppleObjC:
          case eSectionTypeDWARFGNUDebugAltLink:
            return AddressClass::eDebug;

          case eSectionTypeEHFrame:
          case eSectionTypeARMexidx:
          case eSectionTypeARMextab:
          case eSectionTypeCompactUnwind:
            return AddressClass::eRuntime;

          case eSectionTypeAbsoluteAddress:
          case eSectionTypeELFSymbolTable:
          case eSectionTypeELFDynamicSymbols:
          case eSectionTypeELFRelocationEntries:
          case eSectionTypeELFDynamicLinkInfo:
          case eSectionTypeOther:
            return AddressClass::eUnknown;
          }
        }
      }

      const SymbolType symbol_type = symbol->GetType();
      switch (symbol_type) {
      case eSymbolTypeAny:
        return AddressClass::eUnknown;
      case eSymbolTypeAbsolute:
        return AddressClass::eUnknown;

      case eSymbolTypeCode:
      case eSymbolTypeTrampoline:
      case eSymbolTypeResolver:
        if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
          // For ARM we have a bit in the n_desc field of the symbol that tells
          // us ARM/Thumb which is bit 0x0008.
          if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
            return AddressClass::eCodeAlternateISA;
        }
        return AddressClass::eCode;

      case eSymbolTypeData:
        return AddressClass::eData;
      case eSymbolTypeRuntime:
        return AddressClass::eRuntime;
      case eSymbolTypeException:
        return AddressClass::eRuntime;
      case eSymbolTypeSourceFile:
        return AddressClass::eDebug;
      case eSymbolTypeHeaderFile:
        return AddressClass::eDebug;
      case eSymbolTypeObjectFile:
        return AddressClass::eDebug;
      case eSymbolTypeCommonBlock:
        return AddressClass::eDebug;
      case eSymbolTypeBlock:
        return AddressClass::eDebug;
      case eSymbolTypeLocal:
        return AddressClass::eData;
      case eSymbolTypeParam:
        return AddressClass::eData;
      case eSymbolTypeVariable:
        return AddressClass::eData;
      case eSymbolTypeVariableType:
        return AddressClass::eDebug;
      case eSymbolTypeLineEntry:
        return AddressClass::eDebug;
      case eSymbolTypeLineHeader:
        return AddressClass::eDebug;
      case eSymbolTypeScopeBegin:
        return AddressClass::eDebug;
      case eSymbolTypeScopeEnd:
        return AddressClass::eDebug;
      case eSymbolTypeAdditional:
        return AddressClass::eUnknown;
      case eSymbolTypeCompiler:
        return AddressClass::eDebug;
      case eSymbolTypeInstrumentation:
        return AddressClass::eDebug;
      case eSymbolTypeUndefined:
        return AddressClass::eUnknown;
      case eSymbolTypeObjCClass:
        return AddressClass::eRuntime;
      case eSymbolTypeObjCMetaClass:
        return AddressClass::eRuntime;
      case eSymbolTypeObjCIVar:
        return AddressClass::eRuntime;
      case eSymbolTypeReExported:
        return AddressClass::eRuntime;
      }
    }
  }
  return AddressClass::eUnknown;
}

Symtab *ObjectFileMachO::GetSymtab() {
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
    if (m_symtab_up == nullptr) {
      m_symtab_up.reset(new Symtab(this));
      std::lock_guard<std::recursive_mutex> symtab_guard(
          m_symtab_up->GetMutex());
      ParseSymtab();
      m_symtab_up->Finalize();
    }
  }
  return m_symtab_up.get();
}

bool ObjectFileMachO::IsStripped() {
  if (m_dysymtab.cmd == 0) {
    ModuleSP module_sp(GetModule());
    if (module_sp) {
      lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
      for (uint32_t i = 0; i < m_header.ncmds; ++i) {
        const lldb::offset_t load_cmd_offset = offset;

        load_command lc;
        if (m_data.GetU32(&offset, &lc.cmd, 2) == nullptr)
          break;
        if (lc.cmd == LC_DYSYMTAB) {
          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) ==
              nullptr) {
            // 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;
      }
    }
  }
  if (m_dysymtab.cmd)
    return m_dysymtab.nlocalsym <= 1;
  return false;
}

ObjectFileMachO::EncryptedFileRanges ObjectFileMachO::GetEncryptedFileRanges() {
  EncryptedFileRanges result;
  lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);

  encryption_info_command encryption_cmd;
  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) == nullptr)
      break;

    // LC_ENCRYPTION_INFO and LC_ENCRYPTION_INFO_64 have the same sizes for the
    // 3 fields we care about, so treat them the same.
    if (encryption_cmd.cmd == LC_ENCRYPTION_INFO ||
        encryption_cmd.cmd == LC_ENCRYPTION_INFO_64) {
      if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3)) {
        if (encryption_cmd.cryptid != 0) {
          EncryptedFileRanges::Entry entry;
          entry.SetRangeBase(encryption_cmd.cryptoff);
          entry.SetByteSize(encryption_cmd.cryptsize);
          result.Append(entry);
        }
      }
    }
    offset = load_cmd_offset + encryption_cmd.cmdsize;
  }

  return result;
}

void ObjectFileMachO::SanitizeSegmentCommand(segment_command_64 &seg_cmd,
                                             uint32_t cmd_idx) {
  if (m_length == 0 || seg_cmd.filesize == 0)
    return;

  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;
  }
}

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;
}

static lldb::SectionType GetSectionType(uint32_t flags,
                                        ConstString section_name) {

  if (flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
    return eSectionTypeCode;

  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_loclists("__debug_loclists");
  static ConstString g_sect_name_dwarf_debug_macinfo("__debug_macinfo");
  static ConstString g_sect_name_dwarf_debug_names("__debug_names");
  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_debug_types("__debug_types");
  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_loclists)
    return eSectionTypeDWARFDebugLocLists;
  if (section_name == g_sect_name_dwarf_debug_macinfo)
    return eSectionTypeDWARFDebugMacInfo;
  if (section_name == g_sect_name_dwarf_debug_names)
    return eSectionTypeDWARFDebugNames;
  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_debug_types)
    return eSectionTypeDWARFDebugTypes;
  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;
  }
}

struct ObjectFileMachO::SegmentParsingContext {
  const EncryptedFileRanges EncryptedRanges;
  lldb_private::SectionList &UnifiedList;
  uint32_t NextSegmentIdx = 0;
  uint32_t NextSectionIdx = 0;
  bool FileAddressesChanged = false;

  SegmentParsingContext(EncryptedFileRanges EncryptedRanges,
                        lldb_private::SectionList &UnifiedList)
      : EncryptedRanges(std::move(EncryptedRanges)), UnifiedList(UnifiedList) {}
};

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 (!m_data.GetU8(&offset, (uint8_t *)load_cmd.segname, 16))
    return;

  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, strnlen(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 = std::make_shared<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_up->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()->GetBaseAddress().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_up->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)) == nullptr)
      break;
    if (m_data.GetU8(&offset, (uint8_t *)sect64.segname,
                     sizeof(sect64.segname)) == nullptr)
      break;
    sect64.addr = m_data.GetAddress(&offset);
    sect64.size = m_data.GetAddress(&offset);

    if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == nullptr)
      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, strnlen(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);
          }
        } else {
          // Create a fake section for the section's named segment
          segment_sp = std::make_shared<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_up->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) != nullptr;

      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() != nullptr)
              curr_section_sp->SetByteSize(next_section_sp->GetFileAddress() -
                                           curr_section_sp->GetFileAddress());
            else
              curr_section_sp->SetByteSize(load_cmd.vmsize);
          }
        }
      }
    }
  }
}

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_up)
    return;

  m_sections_up.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) == nullptr)
      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 (context.FileAddressesChanged && module_sp)
    module_sp->SectionFileAddressesChanged();
}

class MachSymtabSectionInfo {
public:
  MachSymtabSectionInfo(SectionList *section_list)
      : m_section_list(section_list), m_section_infos() {
    // Get the number of sections down to a depth of 1 to include all segments
    // and their sections, but no other sections that may be added for debug
    // map or
    m_section_infos.resize(section_list->GetNumSections(1));
  }

  SectionSP GetSection(uint8_t n_sect, addr_t file_addr) {
    if (n_sect == 0)
      return SectionSP();
    if (n_sect < m_section_infos.size()) {
      if (!m_section_infos[n_sect].section_sp) {
        SectionSP section_sp(m_section_list->FindSectionByID(n_sect));
        m_section_infos[n_sect].section_sp = section_sp;
        if (section_sp) {
          m_section_infos[n_sect].vm_range.SetBaseAddress(
              section_sp->GetFileAddress());
          m_section_infos[n_sect].vm_range.SetByteSize(
              section_sp->GetByteSize());
        } else {
          Host::SystemLog(Host::eSystemLogError,
                          "error: unable to find section for section %u\n",
                          n_sect);
        }
      }
      if (m_section_infos[n_sect].vm_range.Contains(file_addr)) {
        // Symbol is in section.
        return m_section_infos[n_sect].section_sp;
      } else if (m_section_infos[n_sect].vm_range.GetByteSize() == 0 &&
                 m_section_infos[n_sect].vm_range.GetBaseAddress() ==
                     file_addr) {
        // Symbol is in section with zero size, but has the same start address
        // as the section. This can happen with linker symbols (symbols that
        // start with the letter 'l' or 'L'.
        return m_section_infos[n_sect].section_sp;
      }
    }
    return m_section_list->FindSectionContainingFileAddress(file_addr);
  }

protected:
  struct SectionInfo {
    SectionInfo() : vm_range(), section_sp() {}

    VMRange vm_range;
    SectionSP section_sp;
  };
  SectionList *m_section_list;
  std::vector<SectionInfo> m_section_infos;
};

struct TrieEntry {
  TrieEntry()
      : name(), address(LLDB_INVALID_ADDRESS), flags(0), other(0),
        import_name() {}

  void Clear() {
    name.Clear();
    address = LLDB_INVALID_ADDRESS;
    flags = 0;
    other = 0;
    import_name.Clear();
  }

  void Dump() const {
    printf("0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"",
           static_cast<unsigned long long>(address),
           static_cast<unsigned long long>(flags),
           static_cast<unsigned long long>(other), name.GetCString());
    if (import_name)
      printf(" -> \"%s\"\n", import_name.GetCString());
    else
      printf("\n");
  }
  ConstString name;
  uint64_t address;
  uint64_t flags;
  uint64_t other;
  ConstString import_name;
};

struct TrieEntryWithOffset {
  lldb::offset_t nodeOffset;
  TrieEntry entry;

  TrieEntryWithOffset(lldb::offset_t offset) : nodeOffset(offset), entry() {}

  void Dump(uint32_t idx) const {
    printf("[%3u] 0x%16.16llx: ", idx,
           static_cast<unsigned long long>(nodeOffset));
    entry.Dump();
  }

  bool operator<(const TrieEntryWithOffset &other) const {
    return (nodeOffset < other.nodeOffset);
  }
};

static bool ParseTrieEntries(DataExtractor &data, lldb::offset_t offset,
                             const bool is_arm,
                             std::vector<llvm::StringRef> &nameSlices,
                             std::set<lldb::addr_t> &resolver_addresses,
                             std::vector<TrieEntryWithOffset> &output) {
  if (!data.ValidOffset(offset))
    return true;

  const uint64_t terminalSize = data.GetULEB128(&offset);
  lldb::offset_t children_offset = offset + terminalSize;
  if (terminalSize != 0) {
    TrieEntryWithOffset e(offset);
    e.entry.flags = data.GetULEB128(&offset);
    const char *import_name = nullptr;
    if (e.entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT) {
      e.entry.address = 0;
      e.entry.other = data.GetULEB128(&offset); // dylib ordinal
      import_name = data.GetCStr(&offset);
    } else {
      e.entry.address = data.GetULEB128(&offset);
      if (e.entry.flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) {
        e.entry.other = data.GetULEB128(&offset);
        uint64_t resolver_addr = e.entry.other;
        if (is_arm)
          resolver_addr &= THUMB_ADDRESS_BIT_MASK;
        resolver_addresses.insert(resolver_addr);
      } else
        e.entry.other = 0;
    }
    // Only add symbols that are reexport symbols with a valid import name
    if (EXPORT_SYMBOL_FLAGS_REEXPORT & e.entry.flags && import_name &&
        import_name[0]) {
      std::string name;
      if (!nameSlices.empty()) {
        for (auto name_slice : nameSlices)
          name.append(name_slice.data(), name_slice.size());
      }
      if (name.size() > 1) {
        // Skip the leading '_'
        e.entry.name.SetCStringWithLength(name.c_str() + 1, name.size() - 1);
      }
      if (import_name) {
        // Skip the leading '_'
        e.entry.import_name.SetCString(import_name + 1);
      }
      output.push_back(e);
    }
  }

  const uint8_t childrenCount = data.GetU8(&children_offset);
  for (uint8_t i = 0; i < childrenCount; ++i) {
    const char *cstr = data.GetCStr(&children_offset);
    if (cstr)
      nameSlices.push_back(llvm::StringRef(cstr));
    else
      return false; // Corrupt data
    lldb::offset_t childNodeOffset = data.GetULEB128(&children_offset);
    if (childNodeOffset) {
      if (!ParseTrieEntries(data, childNodeOffset, is_arm, nameSlices,
                            resolver_addresses, output)) {
        return false;
      }
    }
    nameSlices.pop_back();
  }
  return true;
}

// Read the UUID out of a dyld_shared_cache file on-disk.
UUID ObjectFileMachO::GetSharedCacheUUID(FileSpec dyld_shared_cache,
                                         const ByteOrder byte_order,
                                         const uint32_t addr_byte_size) {
  UUID dsc_uuid;
  DataBufferSP DscData = MapFileData(
      dyld_shared_cache, sizeof(struct lldb_copy_dyld_cache_header_v1), 0);
  if (!DscData)
    return dsc_uuid;
  DataExtractor dsc_header_data(DscData, byte_order, addr_byte_size);

  char version_str[7];
  lldb::offset_t offset = 0;
  memcpy(version_str, dsc_header_data.GetData(&offset, 6), 6);
  version_str[6] = '\0';
  if (strcmp(version_str, "dyld_v") == 0) {
    offset = offsetof(struct lldb_copy_dyld_cache_header_v1, uuid);
    dsc_uuid = UUID::fromOptionalData(
        dsc_header_data.GetData(&offset, sizeof(uuid_t)), sizeof(uuid_t));
  }
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));
  if (log && dsc_uuid.IsValid()) {
    log->Printf("Shared cache %s has UUID %s", dyld_shared_cache.GetPath().c_str(), 
                dsc_uuid.GetAsString().c_str());
  }
  return dsc_uuid;
}

size_t ObjectFileMachO::ParseSymtab() {
  static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
  Timer scoped_timer(func_cat, "ObjectFileMachO::ParseSymtab () module = %s",
                     m_file.GetFilename().AsCString(""));
  ModuleSP module_sp(GetModule());
  if (!module_sp)
    return 0;

  struct symtab_command symtab_load_command = {0, 0, 0, 0, 0, 0};
  struct linkedit_data_command function_starts_load_command = {0, 0, 0, 0};
  struct dyld_info_command dyld_info = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
  FunctionStarts function_starts;
  lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
  uint32_t i;
  FileSpecList dylib_files;
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));
  static const llvm::StringRef g_objc_v2_prefix_class("_OBJC_CLASS_$_");
  static const llvm::StringRef g_objc_v2_prefix_metaclass("_OBJC_METACLASS_$_");
  static const llvm::StringRef g_objc_v2_prefix_ivar("_OBJC_IVAR_$_");

  for (i = 0; i < m_header.ncmds; ++i) {
    const lldb::offset_t cmd_offset = offset;
    // Read in the load command and load command size
    struct load_command lc;
    if (m_data.GetU32(&offset, &lc, 2) == nullptr)
      break;
    // Watch for the symbol table load command
    switch (lc.cmd) {
    case LC_SYMTAB:
      symtab_load_command.cmd = lc.cmd;
      symtab_load_command.cmdsize = lc.cmdsize;
      // Read in the rest of the symtab load command
      if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) ==
          nullptr) // fill in symoff, nsyms, stroff, strsize fields
        return 0;
      if (symtab_load_command.symoff == 0) {
        if (log)
          module_sp->LogMessage(log, "LC_SYMTAB.symoff == 0");
        return 0;
      }

      if (symtab_load_command.stroff == 0) {
        if (log)
          module_sp->LogMessage(log, "LC_SYMTAB.stroff == 0");
        return 0;
      }

      if (symtab_load_command.nsyms == 0) {
        if (log)
          module_sp->LogMessage(log, "LC_SYMTAB.nsyms == 0");
        return 0;
      }

      if (symtab_load_command.strsize == 0) {
        if (log)
          module_sp->LogMessage(log, "LC_SYMTAB.strsize == 0");
        return 0;
      }
      break;

    case LC_DYLD_INFO:
    case LC_DYLD_INFO_ONLY:
      if (m_data.GetU32(&offset, &dyld_info.rebase_off, 10)) {
        dyld_info.cmd = lc.cmd;
        dyld_info.cmdsize = lc.cmdsize;
      } else {
        memset(&dyld_info, 0, sizeof(dyld_info));
      }
      break;

    case LC_LOAD_DYLIB:
    case LC_LOAD_WEAK_DYLIB:
    case LC_REEXPORT_DYLIB:
    case LC_LOADFVMLIB:
    case LC_LOAD_UPWARD_DYLIB: {
      uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
      const char *path = m_data.PeekCStr(name_offset);
      if (path) {
        FileSpec file_spec(path);
        // Strip the path if there is @rpath, @executable, etc so we just use
        // the basename
        if (path[0] == '@')
          file_spec.GetDirectory().Clear();

        if (lc.cmd == LC_REEXPORT_DYLIB) {
          m_reexported_dylibs.AppendIfUnique(file_spec);
        }

        dylib_files.Append(file_spec);
      }
    } break;

    case LC_FUNCTION_STARTS:
      function_starts_load_command.cmd = lc.cmd;
      function_starts_load_command.cmdsize = lc.cmdsize;
      if (m_data.GetU32(&offset, &function_starts_load_command.dataoff, 2) ==
          nullptr) // fill in symoff, nsyms, stroff, strsize fields
        memset(&function_starts_load_command, 0,
               sizeof(function_starts_load_command));
      break;

    default:
      break;
    }
    offset = cmd_offset + lc.cmdsize;
  }

  if (symtab_load_command.cmd) {
    Symtab *symtab = m_symtab_up.get();
    SectionList *section_list = GetSectionList();
    if (section_list == nullptr)
      return 0;

    const uint32_t addr_byte_size = m_data.GetAddressByteSize();
    const ByteOrder byte_order = m_data.GetByteOrder();
    bool bit_width_32 = addr_byte_size == 4;
    const size_t nlist_byte_size =
        bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);

    DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
    DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
    DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
    DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
                                             addr_byte_size);
    DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);

    const addr_t nlist_data_byte_size =
        symtab_load_command.nsyms * nlist_byte_size;
    const addr_t strtab_data_byte_size = symtab_load_command.strsize;
    addr_t strtab_addr = LLDB_INVALID_ADDRESS;

    ProcessSP process_sp(m_process_wp.lock());
    Process *process = process_sp.get();

    uint32_t memory_module_load_level = eMemoryModuleLoadLevelComplete;

    if (process && m_header.filetype != llvm::MachO::MH_OBJECT) {
      Target &target = process->GetTarget();

      memory_module_load_level = target.GetMemoryModuleLoadLevel();

      SectionSP linkedit_section_sp(
          section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
      // Reading mach file from memory in a process or core file...

      if (linkedit_section_sp) {
        addr_t linkedit_load_addr =
            linkedit_section_sp->GetLoadBaseAddress(&target);
        if (linkedit_load_addr == LLDB_INVALID_ADDRESS) {
          // We might be trying to access the symbol table before the
          // __LINKEDIT's load address has been set in the target. We can't
          // fail to read the symbol table, so calculate the right address
          // manually
          linkedit_load_addr = CalculateSectionLoadAddressForMemoryImage(
              m_memory_addr, GetMachHeaderSection(), linkedit_section_sp.get());
        }

        const addr_t linkedit_file_offset =
            linkedit_section_sp->GetFileOffset();
        const addr_t symoff_addr = linkedit_load_addr +
                                   symtab_load_command.symoff -
                                   linkedit_file_offset;
        strtab_addr = linkedit_load_addr + symtab_load_command.stroff -
                      linkedit_file_offset;

        bool data_was_read = false;

#if defined(__APPLE__) &&                                                      \
    (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
        if (m_header.flags & 0x80000000u &&
            process->GetAddressByteSize() == sizeof(void *)) {
          // This mach-o memory file is in the dyld shared cache. If this
          // program is not remote and this is iOS, then this process will
          // share the same shared cache as the process we are debugging and we
          // can read the entire __LINKEDIT from the address space in this
          // process. This is a needed optimization that is used for local iOS
          // debugging only since all shared libraries in the shared cache do
          // not have corresponding files that exist in the file system of the
          // device. They have been combined into a single file. This means we
          // always have to load these files from memory. All of the symbol and
          // string tables from all of the __LINKEDIT sections from the shared
          // libraries in the shared cache have been merged into a single large
          // symbol and string table. Reading all of this symbol and string
          // table data across can slow down debug launch times, so we optimize
          // this by reading the memory for the __LINKEDIT section from this
          // process.

          UUID lldb_shared_cache;
          addr_t lldb_shared_cache_addr;
          GetLLDBSharedCacheUUID (lldb_shared_cache_addr, lldb_shared_cache);
          UUID process_shared_cache;
          addr_t process_shared_cache_addr;
          GetProcessSharedCacheUUID(process, process_shared_cache_addr, process_shared_cache);
          bool use_lldb_cache = true;
          if (lldb_shared_cache.IsValid() && process_shared_cache.IsValid() &&
              (lldb_shared_cache != process_shared_cache
               || process_shared_cache_addr != lldb_shared_cache_addr)) {
            use_lldb_cache = false;
          }

          PlatformSP platform_sp(target.GetPlatform());
          if (platform_sp && platform_sp->IsHost() && use_lldb_cache) {
            data_was_read = true;
            nlist_data.SetData((void *)symoff_addr, nlist_data_byte_size,
                               eByteOrderLittle);
            strtab_data.SetData((void *)strtab_addr, strtab_data_byte_size,
                                eByteOrderLittle);
            if (function_starts_load_command.cmd) {
              const addr_t func_start_addr =
                  linkedit_load_addr + function_starts_load_command.dataoff -
                  linkedit_file_offset;
              function_starts_data.SetData(
                  (void *)func_start_addr,
                  function_starts_load_command.datasize, eByteOrderLittle);
            }
          }
        }
#endif

        if (!data_was_read) {
          // Always load dyld - the dynamic linker - from memory if we didn't
          // find a binary anywhere else. lldb will not register
          // dylib/framework/bundle loads/unloads if we don't have the dyld
          // symbols, we force dyld to load from memory despite the user's
          // target.memory-module-load-level setting.
          if (memory_module_load_level == eMemoryModuleLoadLevelComplete ||
              m_header.filetype == llvm::MachO::MH_DYLINKER) {
            DataBufferSP nlist_data_sp(
                ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
            if (nlist_data_sp)
              nlist_data.SetData(nlist_data_sp, 0,
                                 nlist_data_sp->GetByteSize());
            if (m_dysymtab.nindirectsyms != 0) {
              const addr_t indirect_syms_addr = linkedit_load_addr +
                                                m_dysymtab.indirectsymoff -
                                                linkedit_file_offset;
              DataBufferSP indirect_syms_data_sp(
                  ReadMemory(process_sp, indirect_syms_addr,
                             m_dysymtab.nindirectsyms * 4));
              if (indirect_syms_data_sp)
                indirect_symbol_index_data.SetData(
                    indirect_syms_data_sp, 0,
                    indirect_syms_data_sp->GetByteSize());
              // If this binary is outside the shared cache, 
              // cache the string table.
              // Binaries in the shared cache all share a giant string table, and
              // we can't share the string tables across multiple ObjectFileMachO's,
              // so we'd end up re-reading this mega-strtab for every binary
              // in the shared cache - it would be a big perf problem.
              // For binaries outside the shared cache, it's faster to read the
              // entire strtab at once instead of piece-by-piece as we process
              // the nlist records.
              if ((m_header.flags & 0x80000000u) == 0) {
                DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr, 
                      strtab_data_byte_size));
                if (strtab_data_sp) {
                  strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
                }
              }
            }
          }
          if (memory_module_load_level >=
                     eMemoryModuleLoadLevelPartial) {
            if (function_starts_load_command.cmd) {
              const addr_t func_start_addr =
                  linkedit_load_addr + function_starts_load_command.dataoff -
                  linkedit_file_offset;
              DataBufferSP func_start_data_sp(
                  ReadMemory(process_sp, func_start_addr,
                             function_starts_load_command.datasize));
              if (func_start_data_sp)
                function_starts_data.SetData(func_start_data_sp, 0,
                                             func_start_data_sp->GetByteSize());
            }
          }
        }
      }
    } else {
      nlist_data.SetData(m_data, symtab_load_command.symoff,
                         nlist_data_byte_size);
      strtab_data.SetData(m_data, symtab_load_command.stroff,
                          strtab_data_byte_size);

      if (dyld_info.export_size > 0) {
        dyld_trie_data.SetData(m_data, dyld_info.export_off,
                               dyld_info.export_size);
      }

      if (m_dysymtab.nindirectsyms != 0) {
        indirect_symbol_index_data.SetData(m_data, m_dysymtab.indirectsymoff,
                                           m_dysymtab.nindirectsyms * 4);
      }
      if (function_starts_load_command.cmd) {
        function_starts_data.SetData(m_data,
                                     function_starts_load_command.dataoff,
                                     function_starts_load_command.datasize);
      }
    }

    if (nlist_data.GetByteSize() == 0 &&
        memory_module_load_level == eMemoryModuleLoadLevelComplete) {
      if (log)
        module_sp->LogMessage(log, "failed to read nlist data");
      return 0;
    }

    const bool have_strtab_data = strtab_data.GetByteSize() > 0;
    if (!have_strtab_data) {
      if (process) {
        if (strtab_addr == LLDB_INVALID_ADDRESS) {
          if (log)
            module_sp->LogMessage(log, "failed to locate the strtab in memory");
          return 0;
        }
      } else {
        if (log)
          module_sp->LogMessage(log, "failed to read strtab data");
        return 0;
      }
    }

    ConstString g_segment_name_TEXT = GetSegmentNameTEXT();
    ConstString g_segment_name_DATA = GetSegmentNameDATA();
    ConstString g_segment_name_DATA_DIRTY = GetSegmentNameDATA_DIRTY();
    ConstString g_segment_name_DATA_CONST = GetSegmentNameDATA_CONST();
    ConstString g_segment_name_OBJC = GetSegmentNameOBJC();
    ConstString g_section_name_eh_frame = GetSectionNameEHFrame();
    SectionSP text_section_sp(
        section_list->FindSectionByName(g_segment_name_TEXT));
    SectionSP data_section_sp(
        section_list->FindSectionByName(g_segment_name_DATA));
    SectionSP data_dirty_section_sp(
        section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
    SectionSP data_const_section_sp(
        section_list->FindSectionByName(g_segment_name_DATA_CONST));
    SectionSP objc_section_sp(
        section_list->FindSectionByName(g_segment_name_OBJC));
    SectionSP eh_frame_section_sp;
    if (text_section_sp.get())
      eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
          g_section_name_eh_frame);
    else
      eh_frame_section_sp =
          section_list->FindSectionByName(g_section_name_eh_frame);

    const bool is_arm = (m_header.cputype == llvm::MachO::CPU_TYPE_ARM);

    // lldb works best if it knows the start address of all functions in a
    // module. Linker symbols or debug info are normally the best source of
    // information for start addr / size but they may be stripped in a released
    // binary. Two additional sources of information exist in Mach-O binaries:
    //    LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each
    //    function's start address in the
    //                         binary, relative to the text section.
    //    eh_frame           - the eh_frame FDEs have the start addr & size of
    //    each function
    //  LC_FUNCTION_STARTS is the fastest source to read in, and is present on
    //  all modern binaries.
    //  Binaries built to run on older releases may need to use eh_frame
    //  information.

    if (text_section_sp && function_starts_data.GetByteSize()) {
      FunctionStarts::Entry function_start_entry;
      function_start_entry.data = false;
      lldb::offset_t function_start_offset = 0;
      function_start_entry.addr = text_section_sp->GetFileAddress();
      uint64_t delta;
      while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
             0) {
        // Now append the current entry
        function_start_entry.addr += delta;
        function_starts.Append(function_start_entry);
      }
    } else {
      // If m_type is eTypeDebugInfo, then this is a dSYM - it will have the
      // load command claiming an eh_frame but it doesn't actually have the
      // eh_frame content.  And if we have a dSYM, we don't need to do any of
      // this fill-in-the-missing-symbols works anyway - the debug info should
      // give us all the functions in the module.
      if (text_section_sp.get() && eh_frame_section_sp.get() &&
          m_type != eTypeDebugInfo) {
        DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp,
                                    DWARFCallFrameInfo::EH);
        DWARFCallFrameInfo::FunctionAddressAndSizeVector functions;
        eh_frame.GetFunctionAddressAndSizeVector(functions);
        addr_t text_base_addr = text_section_sp->GetFileAddress();
        size_t count = functions.GetSize();
        for (size_t i = 0; i < count; ++i) {
          const DWARFCallFrameInfo::FunctionAddressAndSizeVector::Entry *func =
              functions.GetEntryAtIndex(i);
          if (func) {
            FunctionStarts::Entry function_start_entry;
            function_start_entry.addr = func->base - text_base_addr;
            function_starts.Append(function_start_entry);
          }
        }
      }
    }

    const size_t function_starts_count = function_starts.GetSize();

    // For user process binaries (executables, dylibs, frameworks, bundles), if
    // we don't have LC_FUNCTION_STARTS/eh_frame section in this binary, we're
    // going to assume the binary has been stripped.  Don't allow assembly
    // language instruction emulation because we don't know proper function
    // start boundaries.
    //
    // For all other types of binaries (kernels, stand-alone bare board
    // binaries, kexts), they may not have LC_FUNCTION_STARTS / eh_frame
    // sections - we should not make any assumptions about them based on that.
    if (function_starts_count == 0 && CalculateStrata() == eStrataUser) {
      m_allow_assembly_emulation_unwind_plans = false;
      Log *unwind_or_symbol_log(lldb_private::GetLogIfAnyCategoriesSet(
          LIBLLDB_LOG_SYMBOLS | LIBLLDB_LOG_UNWIND));

      if (unwind_or_symbol_log)
        module_sp->LogMessage(
            unwind_or_symbol_log,
            "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
    }

    const user_id_t TEXT_eh_frame_sectID =
        eh_frame_section_sp.get() ? eh_frame_section_sp->GetID()
                                  : static_cast<user_id_t>(NO_SECT);

    lldb::offset_t nlist_data_offset = 0;

    uint32_t N_SO_index = UINT32_MAX;

    MachSymtabSectionInfo section_info(section_list);
    std::vector<uint32_t> N_FUN_indexes;
    std::vector<uint32_t> N_NSYM_indexes;
    std::vector<uint32_t> N_INCL_indexes;
    std::vector<uint32_t> N_BRAC_indexes;
    std::vector<uint32_t> N_COMM_indexes;
    typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
    typedef std::map<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
    typedef std::map<const char *, uint32_t> ConstNameToSymbolIndexMap;
    ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
    ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
    ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
    // Any symbols that get merged into another will get an entry in this map
    // so we know
    NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
    uint32_t nlist_idx = 0;
    Symbol *symbol_ptr = nullptr;

    uint32_t sym_idx = 0;
    Symbol *sym = nullptr;
    size_t num_syms = 0;
    std::string memory_symbol_name;
    uint32_t unmapped_local_symbols_found = 0;

    std::vector<TrieEntryWithOffset> trie_entries;
    std::set<lldb::addr_t> resolver_addresses;

    if (dyld_trie_data.GetByteSize() > 0) {
      std::vector<llvm::StringRef> nameSlices;
      ParseTrieEntries(dyld_trie_data, 0, is_arm, nameSlices,
                       resolver_addresses, trie_entries);

      ConstString text_segment_name("__TEXT");
      SectionSP text_segment_sp =
          GetSectionList()->FindSectionByName(text_segment_name);
      if (text_segment_sp) {
        const lldb::addr_t text_segment_file_addr =
            text_segment_sp->GetFileAddress();
        if (text_segment_file_addr != LLDB_INVALID_ADDRESS) {
          for (auto &e : trie_entries)
            e.entry.address += text_segment_file_addr;
        }
      }
    }

    typedef std::set<ConstString> IndirectSymbols;
    IndirectSymbols indirect_symbol_names;

#if defined(__APPLE__) &&                                                      \
    (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))

    // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been
    // optimized by moving LOCAL symbols out of the memory mapped portion of
    // the DSC. The symbol information has all been retained, but it isn't
    // available in the normal nlist data. However, there *are* duplicate
    // entries of *some*
    // LOCAL symbols in the normal nlist data. To handle this situation
    // correctly, we must first attempt
    // to parse any DSC unmapped symbol information. If we find any, we set a
    // flag that tells the normal nlist parser to ignore all LOCAL symbols.

    if (m_header.flags & 0x80000000u) {
      // Before we can start mapping the DSC, we need to make certain the
      // target process is actually using the cache we can find.

      // Next we need to determine the correct path for the dyld shared cache.

      ArchSpec header_arch;
      GetArchitecture(header_arch);
      char dsc_path[PATH_MAX];
      char dsc_path_development[PATH_MAX];

      snprintf(
          dsc_path, sizeof(dsc_path), "%s%s%s",
          "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR
                                                       */
          "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
          header_arch.GetArchitectureName());

      snprintf(
          dsc_path_development, sizeof(dsc_path), "%s%s%s%s",
          "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR
                                                       */
          "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
          header_arch.GetArchitectureName(), ".development");

      FileSpec dsc_nondevelopment_filespec(dsc_path, false);
      FileSpec dsc_development_filespec(dsc_path_development, false);
      FileSpec dsc_filespec;

      UUID dsc_uuid;
      UUID process_shared_cache_uuid;
      addr_t process_shared_cache_base_addr;

      if (process) {
        GetProcessSharedCacheUUID(process, process_shared_cache_base_addr, process_shared_cache_uuid);
      }

      // First see if we can find an exact match for the inferior process
      // shared cache UUID in the development or non-development shared caches
      // on disk.
      if (process_shared_cache_uuid.IsValid()) {
        if (FileSystem::Instance().Exists(dsc_development_filespec)) {
          UUID dsc_development_uuid = GetSharedCacheUUID(
              dsc_development_filespec, byte_order, addr_byte_size);
          if (dsc_development_uuid.IsValid() &&
              dsc_development_uuid == process_shared_cache_uuid) {
            dsc_filespec = dsc_development_filespec;
            dsc_uuid = dsc_development_uuid;
          }
        }
        if (!dsc_uuid.IsValid() &&
            FileSystem::Instance().Exists(dsc_nondevelopment_filespec)) {
          UUID dsc_nondevelopment_uuid = GetSharedCacheUUID(
              dsc_nondevelopment_filespec, byte_order, addr_byte_size);
          if (dsc_nondevelopment_uuid.IsValid() &&
              dsc_nondevelopment_uuid == process_shared_cache_uuid) {
            dsc_filespec = dsc_nondevelopment_filespec;
            dsc_uuid = dsc_nondevelopment_uuid;
          }
        }
      }

      // Failing a UUID match, prefer the development dyld_shared cache if both
      // are present.
      if (!FileSystem::Instance().Exists(dsc_filespec)) {
        if (FileSystem::Instance().Exists(dsc_development_filespec)) {
          dsc_filespec = dsc_development_filespec;
        } else {
          dsc_filespec = dsc_nondevelopment_filespec;
        }
      }

      /* The dyld_cache_header has a pointer to the
         dyld_cache_local_symbols_info structure (localSymbolsOffset).
         The dyld_cache_local_symbols_info structure gives us three things:
           1. The start and count of the nlist records in the dyld_shared_cache
         file
           2. The start and size of the strings for these nlist records
           3. The start and count of dyld_cache_local_symbols_entry entries

         There is one dyld_cache_local_symbols_entry per dylib/framework in the
         dyld shared cache.
         The "dylibOffset" field is the Mach-O header of this dylib/framework in
         the dyld shared cache.
         The dyld_cache_local_symbols_entry also lists the start of this
         dylib/framework's nlist records
         and the count of how many nlist records there are for this
         dylib/framework.
      */

      // Process the dyld shared cache header to find the unmapped symbols

      DataBufferSP dsc_data_sp = MapFileData(
          dsc_filespec, sizeof(struct lldb_copy_dyld_cache_header_v1), 0);
      if (!dsc_uuid.IsValid()) {
        dsc_uuid = GetSharedCacheUUID(dsc_filespec, byte_order, addr_byte_size);
      }
      if (dsc_data_sp) {
        DataExtractor dsc_header_data(dsc_data_sp, byte_order, addr_byte_size);

        bool uuid_match = true;
        if (dsc_uuid.IsValid() && process) {
          if (process_shared_cache_uuid.IsValid() &&
              dsc_uuid != process_shared_cache_uuid) {
            // The on-disk dyld_shared_cache file is not the same as the one in
            // this process' memory, don't use it.
            uuid_match = false;
            ModuleSP module_sp(GetModule());
            if (module_sp)
              module_sp->ReportWarning("process shared cache does not match "
                                       "on-disk dyld_shared_cache file, some "
                                       "symbol names will be missing.");
          }
        }

        offset = offsetof(struct lldb_copy_dyld_cache_header_v1, mappingOffset);

        uint32_t mappingOffset = dsc_header_data.GetU32(&offset);

        // If the mappingOffset points to a location inside the header, we've
        // opened an old dyld shared cache, and should not proceed further.
        if (uuid_match &&
            mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v1)) {

          DataBufferSP dsc_mapping_info_data_sp = MapFileData(
              dsc_filespec, sizeof(struct lldb_copy_dyld_cache_mapping_info),
              mappingOffset);

          DataExtractor dsc_mapping_info_data(dsc_mapping_info_data_sp,
                                              byte_order, addr_byte_size);
          offset = 0;

          // The File addresses (from the in-memory Mach-O load commands) for
          // the shared libraries in the shared library cache need to be
          // adjusted by an offset to match up with the dylibOffset identifying
          // field in the dyld_cache_local_symbol_entry's.  This offset is
          // recorded in mapping_offset_value.
          const uint64_t mapping_offset_value =
              dsc_mapping_info_data.GetU64(&offset);

          offset = offsetof(struct lldb_copy_dyld_cache_header_v1,
                            localSymbolsOffset);
          uint64_t localSymbolsOffset = dsc_header_data.GetU64(&offset);
          uint64_t localSymbolsSize = dsc_header_data.GetU64(&offset);

          if (localSymbolsOffset && localSymbolsSize) {
            // Map the local symbols
            DataBufferSP dsc_local_symbols_data_sp =
                MapFileData(dsc_filespec, localSymbolsSize, localSymbolsOffset);

            if (dsc_local_symbols_data_sp) {
              DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp,
                                                   byte_order, addr_byte_size);

              offset = 0;

              typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
              typedef std::map<uint32_t, ConstString> SymbolIndexToName;
              UndefinedNameToDescMap undefined_name_to_desc;
              SymbolIndexToName reexport_shlib_needs_fixup;

              // Read the local_symbols_infos struct in one shot
              struct lldb_copy_dyld_cache_local_symbols_info local_symbols_info;
              dsc_local_symbols_data.GetU32(&offset,
                                            &local_symbols_info.nlistOffset, 6);

              SectionSP text_section_sp(
                  section_list->FindSectionByName(GetSegmentNameTEXT()));

              uint32_t header_file_offset =
                  (text_section_sp->GetFileAddress() - mapping_offset_value);

              offset = local_symbols_info.entriesOffset;
              for (uint32_t entry_index = 0;
                   entry_index < local_symbols_info.entriesCount;
                   entry_index++) {
                struct lldb_copy_dyld_cache_local_symbols_entry
                    local_symbols_entry;
                local_symbols_entry.dylibOffset =
                    dsc_local_symbols_data.GetU32(&offset);
                local_symbols_entry.nlistStartIndex =
                    dsc_local_symbols_data.GetU32(&offset);
                local_symbols_entry.nlistCount =
                    dsc_local_symbols_data.GetU32(&offset);

                if (header_file_offset == local_symbols_entry.dylibOffset) {
                  unmapped_local_symbols_found = local_symbols_entry.nlistCount;

                  // The normal nlist code cannot correctly size the Symbols
                  // array, we need to allocate it here.
                  sym = symtab->Resize(
                      symtab_load_command.nsyms + m_dysymtab.nindirectsyms +
                      unmapped_local_symbols_found - m_dysymtab.nlocalsym);
                  num_syms = symtab->GetNumSymbols();

                  nlist_data_offset =
                      local_symbols_info.nlistOffset +
                      (nlist_byte_size * local_symbols_entry.nlistStartIndex);
                  uint32_t string_table_offset =
                      local_symbols_info.stringsOffset;

                  for (uint32_t nlist_index = 0;
                       nlist_index < local_symbols_entry.nlistCount;
                       nlist_index++) {
                    /////////////////////////////
                    {
                      struct nlist_64 nlist;
                      if (!dsc_local_symbols_data.ValidOffsetForDataOfSize(
                              nlist_data_offset, nlist_byte_size))
                        break;

                      nlist.n_strx = dsc_local_symbols_data.GetU32_unchecked(
                          &nlist_data_offset);
                      nlist.n_type = dsc_local_symbols_data.GetU8_unchecked(
                          &nlist_data_offset);
                      nlist.n_sect = dsc_local_symbols_data.GetU8_unchecked(
                          &nlist_data_offset);
                      nlist.n_desc = dsc_local_symbols_data.GetU16_unchecked(
                          &nlist_data_offset);
                      nlist.n_value =
                          dsc_local_symbols_data.GetAddress_unchecked(
                              &nlist_data_offset);

                      SymbolType type = eSymbolTypeInvalid;
                      const char *symbol_name = dsc_local_symbols_data.PeekCStr(
                          string_table_offset + nlist.n_strx);

                      if (symbol_name == NULL) {
                        // No symbol should be NULL, even the symbols with no
                        // string values should have an offset zero which
                        // points to an empty C-string
                        Host::SystemLog(
                            Host::eSystemLogError,
                            "error: DSC unmapped local symbol[%u] has invalid "
                            "string table offset 0x%x in %s, ignoring symbol\n",
                            entry_index, nlist.n_strx,
                            module_sp->GetFileSpec().GetPath().c_str());
                        continue;
                      }
                      if (symbol_name[0] == '\0')
                        symbol_name = NULL;

                      const char *symbol_name_non_abi_mangled = NULL;

                      SectionSP symbol_section;
                      uint32_t symbol_byte_size = 0;
                      bool add_nlist = true;
                      bool is_debug = ((nlist.n_type & N_STAB) != 0);
                      bool demangled_is_synthesized = false;
                      bool is_gsym = false;
                      bool set_value = true;

                      assert(sym_idx < num_syms);

                      sym[sym_idx].SetDebug(is_debug);

                      if (is_debug) {
                        switch (nlist.n_type) {
                        case N_GSYM:
                          // global symbol: name,,NO_SECT,type,0
                          // Sometimes the N_GSYM value contains the address.

                          // FIXME: In the .o files, we have a GSYM and a debug
                          // symbol for all the ObjC data.  They
                          // have the same address, but we want to ensure that
                          // we always find only the real symbol, 'cause we
                          // don't currently correctly attribute the
                          // GSYM one to the ObjCClass/Ivar/MetaClass
                          // symbol type.  This is a temporary hack to make
                          // sure the ObjectiveC symbols get treated correctly.
                          // To do this right, we should coalesce all the GSYM
                          // & global symbols that have the same address.

                          is_gsym = true;
                          sym[sym_idx].SetExternal(true);

                          if (symbol_name && symbol_name[0] == '_' &&
                              symbol_name[1] == 'O') {
                            llvm::StringRef symbol_name_ref(symbol_name);
                            if (symbol_name_ref.startswith(
                                    g_objc_v2_prefix_class)) {
                              symbol_name_non_abi_mangled = symbol_name + 1;
                              symbol_name =
                                  symbol_name + g_objc_v2_prefix_class.size();
                              type = eSymbolTypeObjCClass;
                              demangled_is_synthesized = true;

                            } else if (symbol_name_ref.startswith(
                                           g_objc_v2_prefix_metaclass)) {
                              symbol_name_non_abi_mangled = symbol_name + 1;
                              symbol_name = symbol_name +
                                            g_objc_v2_prefix_metaclass.size();
                              type = eSymbolTypeObjCMetaClass;
                              demangled_is_synthesized = true;
                            } else if (symbol_name_ref.startswith(
                                           g_objc_v2_prefix_ivar)) {
                              symbol_name_non_abi_mangled = symbol_name + 1;
                              symbol_name =
                                  symbol_name + g_objc_v2_prefix_ivar.size();
                              type = eSymbolTypeObjCIVar;
                              demangled_is_synthesized = true;
                            }
                          } else {
                            if (nlist.n_value != 0)
                              symbol_section = section_info.GetSection(
                                  nlist.n_sect, nlist.n_value);
                            type = eSymbolTypeData;
                          }
                          break;

                        case N_FNAME:
                          // procedure name (f77 kludge): name,,NO_SECT,0,0
                          type = eSymbolTypeCompiler;
                          break;

                        case N_FUN:
                          // procedure: name,,n_sect,linenumber,address
                          if (symbol_name) {
                            type = eSymbolTypeCode;
                            symbol_section = section_info.GetSection(
                                nlist.n_sect, nlist.n_value);

                            N_FUN_addr_to_sym_idx.insert(
                                std::make_pair(nlist.n_value, sym_idx));
                            // 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
                            N_FUN_indexes.push_back(sym_idx);
                          } else {
                            type = eSymbolTypeCompiler;

                            if (!N_FUN_indexes.empty()) {
                              // Copy the size of the function into the
                              // original
                              // STAB entry so we don't have
                              // to hunt for it later
                              symtab->SymbolAtIndex(N_FUN_indexes.back())
                                  ->SetByteSize(nlist.n_value);
                              N_FUN_indexes.pop_back();
                              // 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
                              add_nlist = false;
                            }
                          }
                          break;

                        case N_STSYM:
                          // static symbol: name,,n_sect,type,address
                          N_STSYM_addr_to_sym_idx.insert(
                              std::make_pair(nlist.n_value, sym_idx));
                          symbol_section = section_info.GetSection(
                              nlist.n_sect, nlist.n_value);
                          if (symbol_name && symbol_name[0]) {
                            type = ObjectFile::GetSymbolTypeFromName(
                                symbol_name + 1, eSymbolTypeData);
                          }
                          break;

                        case N_LCSYM:
                          // .lcomm symbol: name,,n_sect,type,address
                          symbol_section = section_info.GetSection(
                              nlist.n_sect, nlist.n_value);
                          type = eSymbolTypeCommonBlock;
                          break;

                        case 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 Skip these if we want
                          // minimal symbol tables
                          add_nlist = false;
                          break;

                        case N_ENSYM:
                          // 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
                          // Skip these if we want minimal symbol tables
                          add_nlist = false;
                          break;

                        case N_OPT:
                          // emitted with gcc2_compiled and in gcc source
                          type = eSymbolTypeCompiler;
                          break;

                        case N_RSYM:
                          // register sym: name,,NO_SECT,type,register
                          type = eSymbolTypeVariable;
                          break;

                        case N_SLINE:
                          // src line: 0,,n_sect,linenumber,address
                          symbol_section = section_info.GetSection(
                              nlist.n_sect, nlist.n_value);
                          type = eSymbolTypeLineEntry;
                          break;

                        case N_SSYM:
                          // structure elt: name,,NO_SECT,type,struct_offset
                          type = eSymbolTypeVariableType;
                          break;

                        case N_SO:
                          // source file name
                          type = eSymbolTypeSourceFile;
                          if (symbol_name == NULL) {
                            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);
                              symbol_ptr->SetSizeIsSibling(true);
                            }
                            N_NSYM_indexes.clear();
                            N_INCL_indexes.clear();
                            N_BRAC_indexes.clear();
                            N_COMM_indexes.clear();
                            N_FUN_indexes.clear();
                            N_SO_index = UINT32_MAX;
                          } else {
                            // 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
                            const bool N_SO_has_full_path =
                                symbol_name[0] == '/';
                            if (N_SO_has_full_path) {
                              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.
                                sym[sym_idx - 1].GetMangled().SetValue(
                                    ConstString(symbol_name), false);
                                m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
                                add_nlist = false;
                              } else {
                                // This is the first entry in a N_SO that
                                // contains a directory or
                                // a full path to the source file
                                N_SO_index = sym_idx;
                              }
                            } 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
                              const char *so_path =
                                  sym[sym_idx - 1]
                                      .GetMangled()
                                      .GetDemangledName(
                                          lldb::eLanguageTypeUnknown)
                                      .AsCString();
                              if (so_path && so_path[0]) {
                                std::string full_so_path(so_path);
                                const size_t double_slash_pos =
                                    full_so_path.find("//");
                                if (double_slash_pos != std::string::npos) {
                                  // The linker has been generating bad N_SO
                                  // entries with doubled up paths
                                  // in the format "%s%s" where the first
                                  // string in the DW_AT_comp_dir, and the
                                  // second is the directory for the source
                                  // file so you end up with a path that looks
                                  // like "/tmp/src//tmp/src/"
                                  FileSpec so_dir(so_path, false);
                                  if (!FileSystem::Instance().Exists(so_dir)) {
                                    so_dir.SetFile(
                                        &full_so_path[double_slash_pos + 1],
                                        false);
                                    if (FileSystem::Instance().Exists(so_dir)) {
                                      // Trim off the incorrect path
                                      full_so_path.erase(0,
                                                         double_slash_pos + 1);
                                    }
                                  }
                                }
                                if (*full_so_path.rbegin() != '/')
                                  full_so_path += '/';
                                full_so_path += symbol_name;
                                sym[sym_idx - 1].GetMangled().SetValue(
                                    ConstString(full_so_path.c_str()), false);
                                add_nlist = false;
                                m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
                              }
                            } else {
                              // This could be a relative path to a N_SO
                              N_SO_index = sym_idx;
                            }
                          }
                          break;

                        case N_OSO:
                          // object file name: name,,0,0,st_mtime
                          type = eSymbolTypeObjectFile;
                          break;

                        case N_LSYM:
                          // local sym: name,,NO_SECT,type,offset
                          type = eSymbolTypeLocal;
                          break;

                        // INCL scopes
                        case N_BINCL:
                          // include file beginning: name,,NO_SECT,0,sum 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
                          N_INCL_indexes.push_back(sym_idx);
                          type = eSymbolTypeScopeBegin;
                          break;

                        case N_EINCL:
                          // include file end: name,,NO_SECT,0,0
                          // Set the size of the N_BINCL to the terminating
                          // index of this N_EINCL so that we can always skip
                          // the entire symbol if we need to navigate more
                          // quickly at the source level when parsing STABS
                          if (!N_INCL_indexes.empty()) {
                            symbol_ptr =
                                symtab->SymbolAtIndex(N_INCL_indexes.back());
                            symbol_ptr->SetByteSize(sym_idx + 1);
                            symbol_ptr->SetSizeIsSibling(true);
                            N_INCL_indexes.pop_back();
                          }
                          type = eSymbolTypeScopeEnd;
                          break;

                        case N_SOL:
                          // #included file name: name,,n_sect,0,address
                          type = eSymbolTypeHeaderFile;

                          // We currently don't use the header files on darwin
                          add_nlist = false;
                          break;

                        case N_PARAMS:
                          // compiler parameters: name,,NO_SECT,0,0
                          type = eSymbolTypeCompiler;
                          break;

                        case N_VERSION:
                          // compiler version: name,,NO_SECT,0,0
                          type = eSymbolTypeCompiler;
                          break;

                        case N_OLEVEL:
                          // compiler -O level: name,,NO_SECT,0,0
                          type = eSymbolTypeCompiler;
                          break;

                        case N_PSYM:
                          // parameter: name,,NO_SECT,type,offset
                          type = eSymbolTypeVariable;
                          break;

                        case N_ENTRY:
                          // alternate entry: name,,n_sect,linenumber,address
                          symbol_section = section_info.GetSection(
                              nlist.n_sect, nlist.n_value);
                          type = eSymbolTypeLineEntry;
                          break;

                        // Left and Right Braces
                        case N_LBRAC:
                          // left bracket: 0,,NO_SECT,nesting level,address 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
                          symbol_section = section_info.GetSection(
                              nlist.n_sect, nlist.n_value);
                          N_BRAC_indexes.push_back(sym_idx);
                          type = eSymbolTypeScopeBegin;
                          break;

                        case N_RBRAC:
                          // right bracket: 0,,NO_SECT,nesting level,address
                          // Set the size of the N_LBRAC to the terminating
                          // index of this N_RBRAC so that we can always skip
                          // the entire symbol if we need to navigate more
                          // quickly at the source level when parsing STABS
                          symbol_section = section_info.GetSection(
                              nlist.n_sect, nlist.n_value);
                          if (!N_BRAC_indexes.empty()) {
                            symbol_ptr =
                                symtab->SymbolAtIndex(N_BRAC_indexes.back());
                            symbol_ptr->SetByteSize(sym_idx + 1);
                            symbol_ptr->SetSizeIsSibling(true);
                            N_BRAC_indexes.pop_back();
                          }
                          type = eSymbolTypeScopeEnd;
                          break;

                        case N_EXCL:
                          // deleted include file: name,,NO_SECT,0,sum
                          type = eSymbolTypeHeaderFile;
                          break;

                        // COMM scopes
                        case N_BCOMM:
                          // begin common: name,,NO_SECT,0,0
                          // 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
                          type = eSymbolTypeScopeBegin;
                          N_COMM_indexes.push_back(sym_idx);
                          break;

                        case N_ECOML:
                          // end common (local name): 0,,n_sect,0,address
                          symbol_section = section_info.GetSection(
                              nlist.n_sect, nlist.n_value);
                        // Fall through

                        case N_ECOMM:
                          // end common: name,,n_sect,0,0
                          // Set the size of the N_BCOMM to the terminating
                          // index of this N_ECOMM/N_ECOML so that we can
                          // always skip the entire symbol if we need to
                          // navigate more quickly at the source level when
                          // parsing STABS
                          if (!N_COMM_indexes.empty()) {
                            symbol_ptr =
                                symtab->SymbolAtIndex(N_COMM_indexes.back());
                            symbol_ptr->SetByteSize(sym_idx + 1);
                            symbol_ptr->SetSizeIsSibling(true);
                            N_COMM_indexes.pop_back();
                          }
                          type = eSymbolTypeScopeEnd;
                          break;

                        case N_LENG:
                          // second stab entry with length information
                          type = eSymbolTypeAdditional;
                          break;

                        default:
                          break;
                        }
                      } else {
                        // uint8_t n_pext    = N_PEXT & nlist.n_type;
                        uint8_t n_type = N_TYPE & nlist.n_type;
                        sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);

                        switch (n_type) {
                        case N_INDR: {
                          const char *reexport_name_cstr =
                              strtab_data.PeekCStr(nlist.n_value);
                          if (reexport_name_cstr && reexport_name_cstr[0]) {
                            type = eSymbolTypeReExported;
                            ConstString reexport_name(
                                reexport_name_cstr +
                                ((reexport_name_cstr[0] == '_') ? 1 : 0));
                            sym[sym_idx].SetReExportedSymbolName(reexport_name);
                            set_value = false;
                            reexport_shlib_needs_fixup[sym_idx] = reexport_name;
                            indirect_symbol_names.insert(
                                ConstString(symbol_name +
                                            ((symbol_name[0] == '_') ? 1 : 0)));
                          } else
                            type = eSymbolTypeUndefined;
                        } break;

                        case N_UNDF:
                          if (symbol_name && symbol_name[0]) {
                            ConstString undefined_name(
                                symbol_name +
                                ((symbol_name[0] == '_') ? 1 : 0));
                            undefined_name_to_desc[undefined_name] =
                                nlist.n_desc;
                          }
                        // Fall through
                        case N_PBUD:
                          type = eSymbolTypeUndefined;
                          break;

                        case N_ABS:
                          type = eSymbolTypeAbsolute;
                          break;

                        case N_SECT: {
                          symbol_section = section_info.GetSection(
                              nlist.n_sect, nlist.n_value);

                          if (symbol_section == NULL) {
                            // TODO: warn about this?
                            add_nlist = false;
                            break;
                          }

                          if (TEXT_eh_frame_sectID == nlist.n_sect) {
                            type = eSymbolTypeException;
                          } else {
                            uint32_t section_type =
                                symbol_section->Get() & SECTION_TYPE;

                            switch (section_type) {
                            case S_CSTRING_LITERALS:
                              type = eSymbolTypeData;
                              break; // section with only literal C strings
                            case S_4BYTE_LITERALS:
                              type = eSymbolTypeData;
                              break; // section with only 4 byte literals
                            case S_8BYTE_LITERALS:
                              type = eSymbolTypeData;
                              break; // section with only 8 byte literals
                            case S_LITERAL_POINTERS:
                              type = eSymbolTypeTrampoline;
                              break; // section with only pointers to literals
                            case S_NON_LAZY_SYMBOL_POINTERS:
                              type = eSymbolTypeTrampoline;
                              break; // section with only non-lazy symbol
                                     // pointers
                            case S_LAZY_SYMBOL_POINTERS:
                              type = eSymbolTypeTrampoline;
                              break; // section with only lazy symbol pointers
                            case S_SYMBOL_STUBS:
                              type = eSymbolTypeTrampoline;
                              break; // section with only symbol stubs, byte
                                     // size of stub in the reserved2 field
                            case S_MOD_INIT_FUNC_POINTERS:
                              type = eSymbolTypeCode;
                              break; // section with only function pointers for
                                     // initialization
                            case S_MOD_TERM_FUNC_POINTERS:
                              type = eSymbolTypeCode;
                              break; // section with only function pointers for
                                     // termination
                            case S_INTERPOSING:
                              type = eSymbolTypeTrampoline;
                              break; // section with only pairs of function
                                     // pointers for interposing
                            case S_16BYTE_LITERALS:
                              type = eSymbolTypeData;
                              break; // section with only 16 byte literals
                            case S_DTRACE_DOF:
                              type = eSymbolTypeInstrumentation;
                              break;
                            case S_LAZY_DYLIB_SYMBOL_POINTERS:
                              type = eSymbolTypeTrampoline;
                              break;
                            default:
                              switch (symbol_section->GetType()) {
                              case lldb::eSectionTypeCode:
                                type = eSymbolTypeCode;
                                break;
                              case eSectionTypeData:
                              case eSectionTypeDataCString: // Inlined C string
                                                            // data
                              case eSectionTypeDataCStringPointers: // Pointers
                                                                    // to C
                                                                    // string
                                                                    // data
                              case eSectionTypeDataSymbolAddress: // Address of
                                                                  // a symbol in
                                                                  // the symbol
                                                                  // table
                              case eSectionTypeData4:
                              case eSectionTypeData8:
                              case eSectionTypeData16:
                                type = eSymbolTypeData;
                                break;
                              default:
                                break;
                              }
                              break;
                            }

                            if (type == eSymbolTypeInvalid) {
                              const char *symbol_sect_name =
                                  symbol_section->GetName().AsCString();
                              if (symbol_section->IsDescendant(
                                      text_section_sp.get())) {
                                if (symbol_section->IsClear(
                                        S_ATTR_PURE_INSTRUCTIONS |
                                        S_ATTR_SELF_MODIFYING_CODE |
                                        S_ATTR_SOME_INSTRUCTIONS))
                                  type = eSymbolTypeData;
                                else
                                  type = eSymbolTypeCode;
                              } else if (symbol_section->IsDescendant(
                                             data_section_sp.get()) ||
                                         symbol_section->IsDescendant(
                                             data_dirty_section_sp.get()) ||
                                         symbol_section->IsDescendant(
                                             data_const_section_sp.get())) {
                                if (symbol_sect_name &&
                                    ::strstr(symbol_sect_name, "__objc") ==
                                        symbol_sect_name) {
                                  type = eSymbolTypeRuntime;

                                  if (symbol_name) {
                                    llvm::StringRef symbol_name_ref(
                                        symbol_name);
                                    if (symbol_name_ref.startswith("_OBJC_")) {
                                      static const llvm::StringRef
                                          g_objc_v2_prefix_class(
                                              "_OBJC_CLASS_$_");
                                      static const llvm::StringRef
                                          g_objc_v2_prefix_metaclass(
                                              "_OBJC_METACLASS_$_");
                                      static const llvm::StringRef
                                          g_objc_v2_prefix_ivar(
                                              "_OBJC_IVAR_$_");
                                      if (symbol_name_ref.startswith(
                                              g_objc_v2_prefix_class)) {
                                        symbol_name_non_abi_mangled =
                                            symbol_name + 1;
                                        symbol_name =
                                            symbol_name +
                                            g_objc_v2_prefix_class.size();
                                        type = eSymbolTypeObjCClass;
                                        demangled_is_synthesized = true;
                                      } else if (
                                          symbol_name_ref.startswith(
                                              g_objc_v2_prefix_metaclass)) {
                                        symbol_name_non_abi_mangled =
                                            symbol_name + 1;
                                        symbol_name =
                                            symbol_name +
                                            g_objc_v2_prefix_metaclass.size();
                                        type = eSymbolTypeObjCMetaClass;
                                        demangled_is_synthesized = true;
                                      } else if (symbol_name_ref.startswith(
                                                     g_objc_v2_prefix_ivar)) {
                                        symbol_name_non_abi_mangled =
                                            symbol_name + 1;
                                        symbol_name =
                                            symbol_name +
                                            g_objc_v2_prefix_ivar.size();
                                        type = eSymbolTypeObjCIVar;
                                        demangled_is_synthesized = true;
                                      }
                                    }
                                  }
                                } else if (symbol_sect_name &&
                                           ::strstr(symbol_sect_name,
                                                    "__gcc_except_tab") ==
                                               symbol_sect_name) {
                                  type = eSymbolTypeException;
                                } else {
                                  type = eSymbolTypeData;
                                }
                              } else if (symbol_sect_name &&
                                         ::strstr(symbol_sect_name,
                                                  "__IMPORT") ==
                                             symbol_sect_name) {
                                type = eSymbolTypeTrampoline;
                              } else if (symbol_section->IsDescendant(
                                             objc_section_sp.get())) {
                                type = eSymbolTypeRuntime;
                                if (symbol_name && symbol_name[0] == '.') {
                                  llvm::StringRef symbol_name_ref(symbol_name);
                                  static const llvm::StringRef
                                      g_objc_v1_prefix_class(
                                          ".objc_class_name_");
                                  if (symbol_name_ref.startswith(
                                          g_objc_v1_prefix_class)) {
                                    symbol_name_non_abi_mangled = symbol_name;
                                    symbol_name = symbol_name +
                                                  g_objc_v1_prefix_class.size();
                                    type = eSymbolTypeObjCClass;
                                    demangled_is_synthesized = true;
                                  }
                                }
                              }
                            }
                          }
                        } break;
                        }
                      }

                      if (add_nlist) {
                        uint64_t symbol_value = nlist.n_value;
                        if (symbol_name_non_abi_mangled) {
                          sym[sym_idx].GetMangled().SetMangledName(
                              ConstString(symbol_name_non_abi_mangled));
                          sym[sym_idx].GetMangled().SetDemangledName(
                              ConstString(symbol_name));
                        } else {
                          bool symbol_name_is_mangled = false;

                          if (symbol_name && symbol_name[0] == '_') {
                            symbol_name_is_mangled = symbol_name[1] == '_';
                            symbol_name++; // Skip the leading underscore
                          }

                          if (symbol_name) {
                            ConstString const_symbol_name(symbol_name);
                            sym[sym_idx].GetMangled().SetValue(
                                const_symbol_name, symbol_name_is_mangled);
                            if (is_gsym && is_debug) {
                              const char *gsym_name =
                                  sym[sym_idx]
                                      .GetMangled()
                                      .GetName(lldb::eLanguageTypeUnknown,
                                               Mangled::ePreferMangled)
                                      .GetCString();
                              if (gsym_name)
                                N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
                            }
                          }
                        }
                        if (symbol_section) {
                          const addr_t section_file_addr =
                              symbol_section->GetFileAddress();
                          if (symbol_byte_size == 0 &&
                              function_starts_count > 0) {
                            addr_t symbol_lookup_file_addr = nlist.n_value;
                            // Do an exact address match for non-ARM addresses,
                            // else get the closest since the symbol might be a
                            // thumb symbol which has an address with bit zero
                            // set
                            FunctionStarts::Entry *func_start_entry =
                                function_starts.FindEntry(
                                    symbol_lookup_file_addr, !is_arm);
                            if (is_arm && func_start_entry) {
                              // Verify that the function start address is the
                              // symbol address (ARM) or the symbol address + 1
                              // (thumb)
                              if (func_start_entry->addr !=
                                      symbol_lookup_file_addr &&
                                  func_start_entry->addr !=
                                      (symbol_lookup_file_addr + 1)) {
                                // Not the right entry, NULL it out...
                                func_start_entry = NULL;
                              }
                            }
                            if (func_start_entry) {
                              func_start_entry->data = true;

                              addr_t symbol_file_addr = func_start_entry->addr;
                              uint32_t symbol_flags = 0;
                              if (is_arm) {
                                if (symbol_file_addr & 1)
                                  symbol_flags =
                                      MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
                                symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
                              }

                              const FunctionStarts::Entry
                                  *next_func_start_entry =
                                      function_starts.FindNextEntry(
                                          func_start_entry);
                              const addr_t section_end_file_addr =
                                  section_file_addr +
                                  symbol_section->GetByteSize();
                              if (next_func_start_entry) {
                                addr_t next_symbol_file_addr =
                                    next_func_start_entry->addr;
                                // Be sure the clear the Thumb address bit when
                                // we calculate the size from the current and
                                // next address
                                if (is_arm)
                                  next_symbol_file_addr &=
                                      THUMB_ADDRESS_BIT_MASK;
                                symbol_byte_size = std::min<lldb::addr_t>(
                                    next_symbol_file_addr - symbol_file_addr,
                                    section_end_file_addr - symbol_file_addr);
                              } else {
                                symbol_byte_size =
                                    section_end_file_addr - symbol_file_addr;
                              }
                            }
                          }
                          symbol_value -= section_file_addr;
                        }

                        if (is_debug == false) {
                          if (type == eSymbolTypeCode) {
                            // See if we can find a N_FUN entry for any code
                            // symbols. If we do find a match, and the name
                            // matches, then we can merge the two into just the
                            // function symbol to avoid duplicate entries in
                            // the symbol table
                            std::pair<ValueToSymbolIndexMap::const_iterator,
                                      ValueToSymbolIndexMap::const_iterator>
                                range;
                            range = N_FUN_addr_to_sym_idx.equal_range(
                                nlist.n_value);
                            if (range.first != range.second) {
                              bool found_it = false;
                              for (ValueToSymbolIndexMap::const_iterator pos =
                                       range.first;
                                   pos != range.second; ++pos) {
                                if (sym[sym_idx].GetMangled().GetName(
                                        lldb::eLanguageTypeUnknown,
                                        Mangled::ePreferMangled) ==
                                    sym[pos->second].GetMangled().GetName(
                                        lldb::eLanguageTypeUnknown,
                                        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
                                  // into the N_FUN flags to avoid duplicate
                                  // symbols in the symbol table
                                  sym[pos->second].SetExternal(
                                      sym[sym_idx].IsExternal());
                                  sym[pos->second].SetFlags(nlist.n_type << 16 |
                                                            nlist.n_desc);
                                  if (resolver_addresses.find(nlist.n_value) !=
                                      resolver_addresses.end())
                                    sym[pos->second].SetType(
                                        eSymbolTypeResolver);
                                  sym[sym_idx].Clear();
                                  found_it = true;
                                  break;
                                }
                              }
                              if (found_it)
                                continue;
                            } else {
                              if (resolver_addresses.find(nlist.n_value) !=
                                  resolver_addresses.end())
                                type = eSymbolTypeResolver;
                            }
                          } else if (type == eSymbolTypeData ||
                                     type == eSymbolTypeObjCClass ||
                                     type == eSymbolTypeObjCMetaClass ||
                                     type == eSymbolTypeObjCIVar) {
                            // See if we can find a N_STSYM entry for any data
                            // symbols. If we do find a match, and the name
                            // matches, then we can merge the two into just the
                            // Static symbol to avoid duplicate entries in the
                            // symbol table
                            std::pair<ValueToSymbolIndexMap::const_iterator,
                                      ValueToSymbolIndexMap::const_iterator>
                                range;
                            range = N_STSYM_addr_to_sym_idx.equal_range(
                                nlist.n_value);
                            if (range.first != range.second) {
                              bool found_it = false;
                              for (ValueToSymbolIndexMap::const_iterator pos =
                                       range.first;
                                   pos != range.second; ++pos) {
                                if (sym[sym_idx].GetMangled().GetName(
                                        lldb::eLanguageTypeUnknown,
                                        Mangled::ePreferMangled) ==
                                    sym[pos->second].GetMangled().GetName(
                                        lldb::eLanguageTypeUnknown,
                                        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
                                  // into the N_STSYM flags to avoid duplicate
                                  // symbols in the symbol table
                                  sym[pos->second].SetExternal(
                                      sym[sym_idx].IsExternal());
                                  sym[pos->second].SetFlags(nlist.n_type << 16 |
                                                            nlist.n_desc);
                                  sym[sym_idx].Clear();
                                  found_it = true;
                                  break;
                                }
                              }
                              if (found_it)
                                continue;
                            } else {
                              const char *gsym_name =
                                  sym[sym_idx]
                                      .GetMangled()
                                      .GetName(lldb::eLanguageTypeUnknown,
                                               Mangled::ePreferMangled)
                                      .GetCString();
                              if (gsym_name) {
                                // Combine N_GSYM stab entries with the non
                                // stab symbol
                                ConstNameToSymbolIndexMap::const_iterator pos =
                                    N_GSYM_name_to_sym_idx.find(gsym_name);
                                if (pos != N_GSYM_name_to_sym_idx.end()) {
                                  const uint32_t GSYM_sym_idx = pos->second;
                                  m_nlist_idx_to_sym_idx[nlist_idx] =
                                      GSYM_sym_idx;
                                  // Copy the address, because often the N_GSYM
                                  // address has an invalid address of zero
                                  // when the global is a common symbol
                                  sym[GSYM_sym_idx].GetAddressRef().SetSection(
                                      symbol_section);
                                  sym[GSYM_sym_idx].GetAddressRef().SetOffset(
                                      symbol_value);
                                  // We just need the flags from the linker
                                  // symbol, so put these flags
                                  // into the N_GSYM flags to avoid duplicate
                                  // symbols in the symbol table
                                  sym[GSYM_sym_idx].SetFlags(
                                      nlist.n_type << 16 | nlist.n_desc);
                                  sym[sym_idx].Clear();
                                  continue;
                                }
                              }
                            }
                          }
                        }

                        sym[sym_idx].SetID(nlist_idx);
                        sym[sym_idx].SetType(type);
                        if (set_value) {
                          sym[sym_idx].GetAddressRef().SetSection(
                              symbol_section);
                          sym[sym_idx].GetAddressRef().SetOffset(symbol_value);
                        }
                        sym[sym_idx].SetFlags(nlist.n_type << 16 |
                                              nlist.n_desc);

                        if (symbol_byte_size > 0)
                          sym[sym_idx].SetByteSize(symbol_byte_size);

                        if (demangled_is_synthesized)
                          sym[sym_idx].SetDemangledNameIsSynthesized(true);
                        ++sym_idx;
                      } else {
                        sym[sym_idx].Clear();
                      }
                    }
                    /////////////////////////////
                  }
                  break; // No more entries to consider
                }
              }

              for (const auto &pos : reexport_shlib_needs_fixup) {
                const auto undef_pos = undefined_name_to_desc.find(pos.second);
                if (undef_pos != undefined_name_to_desc.end()) {
                  const uint8_t dylib_ordinal =
                      llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
                  if (dylib_ordinal > 0 &&
                      dylib_ordinal < dylib_files.GetSize())
                    sym[pos.first].SetReExportedSymbolSharedLibrary(
                        dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
                }
              }
            }
          }
        }
      }
    }

    // Must reset this in case it was mutated above!
    nlist_data_offset = 0;
#endif

    if (nlist_data.GetByteSize() > 0) {

      // If the sym array was not created while parsing the DSC unmapped
      // symbols, create it now.
      if (sym == nullptr) {
        sym = symtab->Resize(symtab_load_command.nsyms +
                             m_dysymtab.nindirectsyms);
        num_syms = symtab->GetNumSymbols();
      }

      if (unmapped_local_symbols_found) {
        assert(m_dysymtab.ilocalsym == 0);
        nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
        nlist_idx = m_dysymtab.nlocalsym;
      } else {
        nlist_idx = 0;
      }

      typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
      typedef std::map<uint32_t, ConstString> SymbolIndexToName;
      UndefinedNameToDescMap undefined_name_to_desc;
      SymbolIndexToName reexport_shlib_needs_fixup;
      for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) {
        struct nlist_64 nlist;
        if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset,
                                                 nlist_byte_size))
          break;

        nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
        nlist.n_type = nlist_data.GetU8_unchecked(&nlist_data_offset);
        nlist.n_sect = nlist_data.GetU8_unchecked(&nlist_data_offset);
        nlist.n_desc = nlist_data.GetU16_unchecked(&nlist_data_offset);
        nlist.n_value = nlist_data.GetAddress_unchecked(&nlist_data_offset);

        SymbolType type = eSymbolTypeInvalid;
        const char *symbol_name = nullptr;

        if (have_strtab_data) {
          symbol_name = strtab_data.PeekCStr(nlist.n_strx);

          if (symbol_name == nullptr) {
            // No symbol should be NULL, even the symbols with no string values
            // should have an offset zero which points to an empty C-string
            Host::SystemLog(Host::eSystemLogError,
                            "error: symbol[%u] has invalid string table offset "
                            "0x%x in %s, ignoring symbol\n",
                            nlist_idx, nlist.n_strx,
                            module_sp->GetFileSpec().GetPath().c_str());
            continue;
          }
          if (symbol_name[0] == '\0')
            symbol_name = nullptr;
        } else {
          const addr_t str_addr = strtab_addr + nlist.n_strx;
          Status str_error;
          if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
                                             str_error))
            symbol_name = memory_symbol_name.c_str();
        }
        const char *symbol_name_non_abi_mangled = nullptr;

        SectionSP symbol_section;
        lldb::addr_t symbol_byte_size = 0;
        bool add_nlist = true;
        bool is_gsym = false;
        bool is_debug = ((nlist.n_type & N_STAB) != 0);
        bool demangled_is_synthesized = false;
        bool set_value = true;
        assert(sym_idx < num_syms);

        sym[sym_idx].SetDebug(is_debug);

        if (is_debug) {
          switch (nlist.n_type) {
          case N_GSYM:
            // global symbol: name,,NO_SECT,type,0
            // Sometimes the N_GSYM value contains the address.

            // FIXME: In the .o files, we have a GSYM and a debug symbol for all
            // the ObjC data.  They
            // have the same address, but we want to ensure that we always find
            // only the real symbol, 'cause we don't currently correctly
            // attribute the GSYM one to the ObjCClass/Ivar/MetaClass symbol
            // type.  This is a temporary hack to make sure the ObjectiveC
            // symbols get treated correctly.  To do this right, we should
            // coalesce all the GSYM & global symbols that have the same
            // address.
            is_gsym = true;
            sym[sym_idx].SetExternal(true);

            if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O') {
              llvm::StringRef symbol_name_ref(symbol_name);
              if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) {
                symbol_name_non_abi_mangled = symbol_name + 1;
                symbol_name = symbol_name + g_objc_v2_prefix_class.size();
                type = eSymbolTypeObjCClass;
                demangled_is_synthesized = true;

              } else if (symbol_name_ref.startswith(
                             g_objc_v2_prefix_metaclass)) {
                symbol_name_non_abi_mangled = symbol_name + 1;
                symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
                type = eSymbolTypeObjCMetaClass;
                demangled_is_synthesized = true;
              } else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar)) {
                symbol_name_non_abi_mangled = symbol_name + 1;
                symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
                type = eSymbolTypeObjCIVar;
                demangled_is_synthesized = true;
              }
            } else {
              if (nlist.n_value != 0)
                symbol_section =
                    section_info.GetSection(nlist.n_sect, nlist.n_value);
              type = eSymbolTypeData;
            }
            break;

          case N_FNAME:
            // procedure name (f77 kludge): name,,NO_SECT,0,0
            type = eSymbolTypeCompiler;
            break;

          case N_FUN:
            // procedure: name,,n_sect,linenumber,address
            if (symbol_name) {
              type = eSymbolTypeCode;
              symbol_section =
                  section_info.GetSection(nlist.n_sect, nlist.n_value);

              N_FUN_addr_to_sym_idx.insert(
                  std::make_pair(nlist.n_value, sym_idx));
              // 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
              N_FUN_indexes.push_back(sym_idx);
            } else {
              type = eSymbolTypeCompiler;

              if (!N_FUN_indexes.empty()) {
                // Copy the size of the function into the original STAB entry
                // so we don't have to hunt for it later
                symtab->SymbolAtIndex(N_FUN_indexes.back())
                    ->SetByteSize(nlist.n_value);
                N_FUN_indexes.pop_back();
                // 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
                add_nlist = false;
              }
            }
            break;

          case N_STSYM:
            // static symbol: name,,n_sect,type,address
            N_STSYM_addr_to_sym_idx.insert(
                std::make_pair(nlist.n_value, sym_idx));
            symbol_section =
                section_info.GetSection(nlist.n_sect, nlist.n_value);
            if (symbol_name && symbol_name[0]) {
              type = ObjectFile::GetSymbolTypeFromName(symbol_name + 1,
                                                       eSymbolTypeData);
            }
            break;

          case N_LCSYM:
            // .lcomm symbol: name,,n_sect,type,address
            symbol_section =
                section_info.GetSection(nlist.n_sect, nlist.n_value);
            type = eSymbolTypeCommonBlock;
            break;

          case 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
            // Skip these if we want minimal symbol tables
            add_nlist = false;
            break;

          case N_ENSYM:
            // 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
            // Skip these if we want minimal symbol tables
            add_nlist = false;
            break;

          case N_OPT:
            // emitted with gcc2_compiled and in gcc source
            type = eSymbolTypeCompiler;
            break;

          case N_RSYM:
            // register sym: name,,NO_SECT,type,register
            type = eSymbolTypeVariable;
            break;

          case N_SLINE:
            // src line: 0,,n_sect,linenumber,address
            symbol_section =
                section_info.GetSection(nlist.n_sect, nlist.n_value);
            type = eSymbolTypeLineEntry;
            break;

          case N_SSYM:
            // structure elt: name,,NO_SECT,type,struct_offset
            type = eSymbolTypeVariableType;
            break;

          case N_SO:
            // source file name
            type = eSymbolTypeSourceFile;
            if (symbol_name == nullptr) {
              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);
                symbol_ptr->SetSizeIsSibling(true);
              }
              N_NSYM_indexes.clear();
              N_INCL_indexes.clear();
              N_BRAC_indexes.clear();
              N_COMM_indexes.clear();
              N_FUN_indexes.clear();
              N_SO_index = UINT32_MAX;
            } else {
              // 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
              const bool N_SO_has_full_path = symbol_name[0] == '/';
              if (N_SO_has_full_path) {
                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.
                  sym[sym_idx - 1].GetMangled().SetValue(
                      ConstString(symbol_name), false);
                  m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
                  add_nlist = false;
                } else {
                  // This is the first entry in a N_SO that contains a
                  // directory or a full path to the source file
                  N_SO_index = sym_idx;
                }
              } 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
                const char *so_path =
                    sym[sym_idx - 1]
                        .GetMangled()
                        .GetDemangledName(lldb::eLanguageTypeUnknown)
                        .AsCString();
                if (so_path && so_path[0]) {
                  std::string full_so_path(so_path);
                  const size_t double_slash_pos = full_so_path.find("//");
                  if (double_slash_pos != std::string::npos) {
                    // The linker has been generating bad N_SO entries with
                    // doubled up paths in the format "%s%s" where the first
                    // string in the DW_AT_comp_dir, and the second is the
                    // directory for the source file so you end up with a path
                    // that looks like "/tmp/src//tmp/src/"
                    FileSpec so_dir(so_path);
                    if (!FileSystem::Instance().Exists(so_dir)) {
                      so_dir.SetFile(&full_so_path[double_slash_pos + 1],
                                     FileSpec::Style::native);
                      if (FileSystem::Instance().Exists(so_dir)) {
                        // Trim off the incorrect path
                        full_so_path.erase(0, double_slash_pos + 1);
                      }
                    }
                  }
                  if (*full_so_path.rbegin() != '/')
                    full_so_path += '/';
                  full_so_path += symbol_name;
                  sym[sym_idx - 1].GetMangled().SetValue(
                      ConstString(full_so_path.c_str()), false);
                  add_nlist = false;
                  m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
                }
              } else {
                // This could be a relative path to a N_SO
                N_SO_index = sym_idx;
              }
            }
            break;

          case N_OSO:
            // object file name: name,,0,0,st_mtime
            type = eSymbolTypeObjectFile;
            break;

          case N_LSYM:
            // local sym: name,,NO_SECT,type,offset
            type = eSymbolTypeLocal;
            break;

          // INCL scopes
          case N_BINCL:
            // include file beginning: name,,NO_SECT,0,sum 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
            N_INCL_indexes.push_back(sym_idx);
            type = eSymbolTypeScopeBegin;
            break;

          case N_EINCL:
            // include file end: name,,NO_SECT,0,0
            // Set the size of the N_BINCL to the terminating index of this
            // N_EINCL so that we can always skip the entire symbol if we need
            // to navigate more quickly at the source level when parsing STABS
            if (!N_INCL_indexes.empty()) {
              symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
              symbol_ptr->SetByteSize(sym_idx + 1);
              symbol_ptr->SetSizeIsSibling(true);
              N_INCL_indexes.pop_back();
            }
            type = eSymbolTypeScopeEnd;
            break;

          case N_SOL:
            // #included file name: name,,n_sect,0,address
            type = eSymbolTypeHeaderFile;

            // We currently don't use the header files on darwin
            add_nlist = false;
            break;

          case N_PARAMS:
            // compiler parameters: name,,NO_SECT,0,0
            type = eSymbolTypeCompiler;
            break;

          case N_VERSION:
            // compiler version: name,,NO_SECT,0,0
            type = eSymbolTypeCompiler;
            break;

          case N_OLEVEL:
            // compiler -O level: name,,NO_SECT,0,0
            type = eSymbolTypeCompiler;
            break;

          case N_PSYM:
            // parameter: name,,NO_SECT,type,offset
            type = eSymbolTypeVariable;
            break;

          case N_ENTRY:
            // alternate entry: name,,n_sect,linenumber,address
            symbol_section =
                section_info.GetSection(nlist.n_sect, nlist.n_value);
            type = eSymbolTypeLineEntry;
            break;

          // Left and Right Braces
          case N_LBRAC:
            // left bracket: 0,,NO_SECT,nesting level,address 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
            symbol_section =
                section_info.GetSection(nlist.n_sect, nlist.n_value);
            N_BRAC_indexes.push_back(sym_idx);
            type = eSymbolTypeScopeBegin;
            break;

          case N_RBRAC:
            // right bracket: 0,,NO_SECT,nesting level,address Set the size of
            // the N_LBRAC to the terminating index of this N_RBRAC so that we
            // can always skip the entire symbol if we need to navigate more
            // quickly at the source level when parsing STABS
            symbol_section =
                section_info.GetSection(nlist.n_sect, nlist.n_value);
            if (!N_BRAC_indexes.empty()) {
              symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
              symbol_ptr->SetByteSize(sym_idx + 1);
              symbol_ptr->SetSizeIsSibling(true);
              N_BRAC_indexes.pop_back();
            }
            type = eSymbolTypeScopeEnd;
            break;

          case N_EXCL:
            // deleted include file: name,,NO_SECT,0,sum
            type = eSymbolTypeHeaderFile;
            break;

          // COMM scopes
          case N_BCOMM:
            // begin common: name,,NO_SECT,0,0
            // 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
            type = eSymbolTypeScopeBegin;
            N_COMM_indexes.push_back(sym_idx);
            break;

          case N_ECOML:
            // end common (local name): 0,,n_sect,0,address
            symbol_section =
                section_info.GetSection(nlist.n_sect, nlist.n_value);
            LLVM_FALLTHROUGH;

          case N_ECOMM:
            // end common: name,,n_sect,0,0
            // Set the size of the N_BCOMM to the terminating index of this
            // N_ECOMM/N_ECOML so that we can always skip the entire symbol if
            // we need to navigate more quickly at the source level when
            // parsing STABS
            if (!N_COMM_indexes.empty()) {
              symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
              symbol_ptr->SetByteSize(sym_idx + 1);
              symbol_ptr->SetSizeIsSibling(true);
              N_COMM_indexes.pop_back();
            }
            type = eSymbolTypeScopeEnd;
            break;

          case N_LENG:
            // second stab entry with length information
            type = eSymbolTypeAdditional;
            break;

          default:
            break;
          }
        } else {
          // uint8_t n_pext    = N_PEXT & nlist.n_type;
          uint8_t n_type = N_TYPE & nlist.n_type;
          sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);

          switch (n_type) {
          case N_INDR: {
            const char *reexport_name_cstr =
                strtab_data.PeekCStr(nlist.n_value);
            if (reexport_name_cstr && reexport_name_cstr[0]) {
              type = eSymbolTypeReExported;
              ConstString reexport_name(
                  reexport_name_cstr +
                  ((reexport_name_cstr[0] == '_') ? 1 : 0));
              sym[sym_idx].SetReExportedSymbolName(reexport_name);
              set_value = false;
              reexport_shlib_needs_fixup[sym_idx] = reexport_name;
              indirect_symbol_names.insert(
                  ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
            } else
              type = eSymbolTypeUndefined;
          } break;

          case N_UNDF:
            if (symbol_name && symbol_name[0]) {
              ConstString undefined_name(symbol_name +
                                         ((symbol_name[0] == '_') ? 1 : 0));
              undefined_name_to_desc[undefined_name] = nlist.n_desc;
            }
            LLVM_FALLTHROUGH;

          case N_PBUD:
            type = eSymbolTypeUndefined;
            break;

          case N_ABS:
            type = eSymbolTypeAbsolute;
            break;

          case N_SECT: {
            symbol_section =
                section_info.GetSection(nlist.n_sect, nlist.n_value);

            if (!symbol_section) {
              // TODO: warn about this?
              add_nlist = false;
              break;
            }

            if (TEXT_eh_frame_sectID == nlist.n_sect) {
              type = eSymbolTypeException;
            } else {
              uint32_t section_type = symbol_section->Get() & SECTION_TYPE;

              switch (section_type) {
              case S_CSTRING_LITERALS:
                type = eSymbolTypeData;
                break; // section with only literal C strings
              case S_4BYTE_LITERALS:
                type = eSymbolTypeData;
                break; // section with only 4 byte literals
              case S_8BYTE_LITERALS:
                type = eSymbolTypeData;
                break; // section with only 8 byte literals
              case S_LITERAL_POINTERS:
                type = eSymbolTypeTrampoline;
                break; // section with only pointers to literals
              case S_NON_LAZY_SYMBOL_POINTERS:
                type = eSymbolTypeTrampoline;
                break; // section with only non-lazy symbol pointers
              case S_LAZY_SYMBOL_POINTERS:
                type = eSymbolTypeTrampoline;
                break; // section with only lazy symbol pointers
              case S_SYMBOL_STUBS:
                type = eSymbolTypeTrampoline;
                break; // section with only symbol stubs, byte size of stub in
                       // the reserved2 field
              case S_MOD_INIT_FUNC_POINTERS:
                type = eSymbolTypeCode;
                break; // section with only function pointers for initialization
              case S_MOD_TERM_FUNC_POINTERS:
                type = eSymbolTypeCode;
                break; // section with only function pointers for termination
              case S_INTERPOSING:
                type = eSymbolTypeTrampoline;
                break; // section with only pairs of function pointers for
                       // interposing
              case S_16BYTE_LITERALS:
                type = eSymbolTypeData;
                break; // section with only 16 byte literals
              case S_DTRACE_DOF:
                type = eSymbolTypeInstrumentation;
                break;
              case S_LAZY_DYLIB_SYMBOL_POINTERS:
                type = eSymbolTypeTrampoline;
                break;
              default:
                switch (symbol_section->GetType()) {
                case lldb::eSectionTypeCode:
                  type = eSymbolTypeCode;
                  break;
                case eSectionTypeData:
                case eSectionTypeDataCString:         // Inlined C string data
                case eSectionTypeDataCStringPointers: // Pointers to C string
                                                      // data
                case eSectionTypeDataSymbolAddress:   // Address of a symbol in
                                                      // the symbol table
                case eSectionTypeData4:
                case eSectionTypeData8:
                case eSectionTypeData16:
                  type = eSymbolTypeData;
                  break;
                default:
                  break;
                }
                break;
              }

              if (type == eSymbolTypeInvalid) {
                const char *symbol_sect_name =
                    symbol_section->GetName().AsCString();
                if (symbol_section->IsDescendant(text_section_sp.get())) {
                  if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
                                              S_ATTR_SELF_MODIFYING_CODE |
                                              S_ATTR_SOME_INSTRUCTIONS))
                    type = eSymbolTypeData;
                  else
                    type = eSymbolTypeCode;
                } else if (symbol_section->IsDescendant(
                               data_section_sp.get()) ||
                           symbol_section->IsDescendant(
                               data_dirty_section_sp.get()) ||
                           symbol_section->IsDescendant(
                               data_const_section_sp.get())) {
                  if (symbol_sect_name &&
                      ::strstr(symbol_sect_name, "__objc") ==
                          symbol_sect_name) {
                    type = eSymbolTypeRuntime;

                    if (symbol_name) {
                      llvm::StringRef symbol_name_ref(symbol_name);
                      if (symbol_name_ref.startswith("_OBJC_")) {
                        static const llvm::StringRef g_objc_v2_prefix_class(
                            "_OBJC_CLASS_$_");
                        static const llvm::StringRef g_objc_v2_prefix_metaclass(
                            "_OBJC_METACLASS_$_");
                        static const llvm::StringRef g_objc_v2_prefix_ivar(
                            "_OBJC_IVAR_$_");
                        if (symbol_name_ref.startswith(
                                g_objc_v2_prefix_class)) {
                          symbol_name_non_abi_mangled = symbol_name + 1;
                          symbol_name =
                              symbol_name + g_objc_v2_prefix_class.size();
                          type = eSymbolTypeObjCClass;
                          demangled_is_synthesized = true;
                        } else if (symbol_name_ref.startswith(
                                       g_objc_v2_prefix_metaclass)) {
                          symbol_name_non_abi_mangled = symbol_name + 1;
                          symbol_name =
                              symbol_name + g_objc_v2_prefix_metaclass.size();
                          type = eSymbolTypeObjCMetaClass;
                          demangled_is_synthesized = true;
                        } else if (symbol_name_ref.startswith(
                                       g_objc_v2_prefix_ivar)) {
                          symbol_name_non_abi_mangled = symbol_name + 1;
                          symbol_name =
                              symbol_name + g_objc_v2_prefix_ivar.size();
                          type = eSymbolTypeObjCIVar;
                          demangled_is_synthesized = true;
                        }
                      }
                    }
                  } else if (symbol_sect_name &&
                             ::strstr(symbol_sect_name, "__gcc_except_tab") ==
                                 symbol_sect_name) {
                    type = eSymbolTypeException;
                  } else {
                    type = eSymbolTypeData;
                  }
                } else if (symbol_sect_name &&
                           ::strstr(symbol_sect_name, "__IMPORT") ==
                               symbol_sect_name) {
                  type = eSymbolTypeTrampoline;
                } else if (symbol_section->IsDescendant(
                               objc_section_sp.get())) {
                  type = eSymbolTypeRuntime;
                  if (symbol_name && symbol_name[0] == '.') {
                    llvm::StringRef symbol_name_ref(symbol_name);
                    static const llvm::StringRef g_objc_v1_prefix_class(
                        ".objc_class_name_");
                    if (symbol_name_ref.startswith(g_objc_v1_prefix_class)) {
                      symbol_name_non_abi_mangled = symbol_name;
                      symbol_name = symbol_name + g_objc_v1_prefix_class.size();
                      type = eSymbolTypeObjCClass;
                      demangled_is_synthesized = true;
                    }
                  }
                }
              }
            }
          } break;
          }
        }

        if (add_nlist) {
          uint64_t symbol_value = nlist.n_value;

          if (symbol_name_non_abi_mangled) {
            sym[sym_idx].GetMangled().SetMangledName(
                ConstString(symbol_name_non_abi_mangled));
            sym[sym_idx].GetMangled().SetDemangledName(
                ConstString(symbol_name));
          } else {
            bool symbol_name_is_mangled = false;

            if (symbol_name && symbol_name[0] == '_') {
              symbol_name_is_mangled = symbol_name[1] == '_';
              symbol_name++; // Skip the leading underscore
            }

            if (symbol_name) {
              ConstString const_symbol_name(symbol_name);
              sym[sym_idx].GetMangled().SetValue(const_symbol_name,
                                                 symbol_name_is_mangled);
            }
          }

          if (is_gsym) {
            const char *gsym_name = sym[sym_idx]
                                        .GetMangled()
                                        .GetName(lldb::eLanguageTypeUnknown,
                                                 Mangled::ePreferMangled)
                                        .GetCString();
            if (gsym_name)
              N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
          }

          if (symbol_section) {
            const addr_t section_file_addr = symbol_section->GetFileAddress();
            if (symbol_byte_size == 0 && function_starts_count > 0) {
              addr_t symbol_lookup_file_addr = nlist.n_value;
              // Do an exact address match for non-ARM addresses, else get the
              // closest since the symbol might be a thumb symbol which has an
              // address with bit zero set
              FunctionStarts::Entry *func_start_entry =
                  function_starts.FindEntry(symbol_lookup_file_addr, !is_arm);
              if (is_arm && func_start_entry) {
                // Verify that the function start address is the symbol address
                // (ARM) or the symbol address + 1 (thumb)
                if (func_start_entry->addr != symbol_lookup_file_addr &&
                    func_start_entry->addr != (symbol_lookup_file_addr + 1)) {
                  // Not the right entry, NULL it out...
                  func_start_entry = nullptr;
                }
              }
              if (func_start_entry) {
                func_start_entry->data = true;

                addr_t symbol_file_addr = func_start_entry->addr;
                if (is_arm)
                  symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;

                const FunctionStarts::Entry *next_func_start_entry =
                    function_starts.FindNextEntry(func_start_entry);
                const addr_t section_end_file_addr =
                    section_file_addr + symbol_section->GetByteSize();
                if (next_func_start_entry) {
                  addr_t next_symbol_file_addr = next_func_start_entry->addr;
                  // Be sure the clear the Thumb address bit when we calculate
                  // the size from the current and next address
                  if (is_arm)
                    next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
                  symbol_byte_size = std::min<lldb::addr_t>(
                      next_symbol_file_addr - symbol_file_addr,
                      section_end_file_addr - symbol_file_addr);
                } else {
                  symbol_byte_size = section_end_file_addr - symbol_file_addr;
                }
              }
            }
            symbol_value -= section_file_addr;
          }

          if (!is_debug) {
            if (type == eSymbolTypeCode) {
              // See if we can find a N_FUN entry for any code symbols. If we
              // do find a match, and the name matches, then we can merge the
              // two into just the function symbol to avoid duplicate entries
              // in the symbol table
              std::pair<ValueToSymbolIndexMap::const_iterator,
                        ValueToSymbolIndexMap::const_iterator>
                  range;
              range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
              if (range.first != range.second) {
                bool found_it = false;
                for (ValueToSymbolIndexMap::const_iterator pos = range.first;
                     pos != range.second; ++pos) {
                  if (sym[sym_idx].GetMangled().GetName(
                          lldb::eLanguageTypeUnknown,
                          Mangled::ePreferMangled) ==
                      sym[pos->second].GetMangled().GetName(
                          lldb::eLanguageTypeUnknown,
                          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 into the N_FUN flags to avoid duplicate
                    // symbols in the symbol table
                    sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
                    sym[pos->second].SetFlags(nlist.n_type << 16 |
                                              nlist.n_desc);
                    if (resolver_addresses.find(nlist.n_value) !=
                        resolver_addresses.end())
                      sym[pos->second].SetType(eSymbolTypeResolver);
                    sym[sym_idx].Clear();
                    found_it = true;
                    break;
                  }
                }
                if (found_it)
                  continue;
              } else {
                if (resolver_addresses.find(nlist.n_value) !=
                    resolver_addresses.end())
                  type = eSymbolTypeResolver;
              }
            } else if (type == eSymbolTypeData ||
                       type == eSymbolTypeObjCClass ||
                       type == eSymbolTypeObjCMetaClass ||
                       type == eSymbolTypeObjCIVar) {
              // See if we can find a N_STSYM entry for any data symbols. If we
              // do find a match, and the name matches, then we can merge the
              // two into just the Static symbol to avoid duplicate entries in
              // the symbol table
              std::pair<ValueToSymbolIndexMap::const_iterator,
                        ValueToSymbolIndexMap::const_iterator>
                  range;
              range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
              if (range.first != range.second) {
                bool found_it = false;
                for (ValueToSymbolIndexMap::const_iterator pos = range.first;
                     pos != range.second; ++pos) {
                  if (sym[sym_idx].GetMangled().GetName(
                          lldb::eLanguageTypeUnknown,
                          Mangled::ePreferMangled) ==
                      sym[pos->second].GetMangled().GetName(
                          lldb::eLanguageTypeUnknown,
                          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 into the N_STSYM flags to avoid duplicate
                    // symbols in the symbol table
                    sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
                    sym[pos->second].SetFlags(nlist.n_type << 16 |
                                              nlist.n_desc);
                    sym[sym_idx].Clear();
                    found_it = true;
                    break;
                  }
                }
                if (found_it)
                  continue;
              } else {
                // Combine N_GSYM stab entries with the non stab symbol
                const char *gsym_name = sym[sym_idx]
                                            .GetMangled()
                                            .GetName(lldb::eLanguageTypeUnknown,
                                                     Mangled::ePreferMangled)
                                            .GetCString();
                if (gsym_name) {
                  ConstNameToSymbolIndexMap::const_iterator pos =
                      N_GSYM_name_to_sym_idx.find(gsym_name);
                  if (pos != N_GSYM_name_to_sym_idx.end()) {
                    const uint32_t GSYM_sym_idx = pos->second;
                    m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
                    // Copy the address, because often the N_GSYM address has
                    // an invalid address of zero when the global is a common
                    // symbol
                    sym[GSYM_sym_idx].GetAddressRef().SetSection(
                        symbol_section);
                    sym[GSYM_sym_idx].GetAddressRef().SetOffset(symbol_value);
                    // We just need the flags from the linker symbol, so put
                    // these flags into the N_GSYM flags to avoid duplicate
                    // symbols in the symbol table
                    sym[GSYM_sym_idx].SetFlags(nlist.n_type << 16 |
                                               nlist.n_desc);
                    sym[sym_idx].Clear();
                    continue;
                  }
                }
              }
            }
          }

          sym[sym_idx].SetID(nlist_idx);
          sym[sym_idx].SetType(type);
          if (set_value) {
            sym[sym_idx].GetAddressRef().SetSection(symbol_section);
            sym[sym_idx].GetAddressRef().SetOffset(symbol_value);
          }
          sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
          if (nlist.n_desc & N_WEAK_REF)
            sym[sym_idx].SetIsWeak(true);

          if (symbol_byte_size > 0)
            sym[sym_idx].SetByteSize(symbol_byte_size);

          if (demangled_is_synthesized)
            sym[sym_idx].SetDemangledNameIsSynthesized(true);

          ++sym_idx;
        } else {
          sym[sym_idx].Clear();
        }
      }

      for (const auto &pos : reexport_shlib_needs_fixup) {
        const auto undef_pos = undefined_name_to_desc.find(pos.second);
        if (undef_pos != undefined_name_to_desc.end()) {
          const uint8_t dylib_ordinal =
              llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
          if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
            sym[pos.first].SetReExportedSymbolSharedLibrary(
                dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
        }
      }
    }

    uint32_t synthetic_sym_id = symtab_load_command.nsyms;

    if (function_starts_count > 0) {
      uint32_t num_synthetic_function_symbols = 0;
      for (i = 0; i < function_starts_count; ++i) {
        if (!function_starts.GetEntryRef(i).data)
          ++num_synthetic_function_symbols;
      }

      if (num_synthetic_function_symbols > 0) {
        if (num_syms < sym_idx + num_synthetic_function_symbols) {
          num_syms = sym_idx + num_synthetic_function_symbols;
          sym = symtab->Resize(num_syms);
        }
        for (i = 0; i < function_starts_count; ++i) {
          const FunctionStarts::Entry *func_start_entry =
              function_starts.GetEntryAtIndex(i);
          if (!func_start_entry->data) {
            addr_t symbol_file_addr = func_start_entry->addr;
            uint32_t symbol_flags = 0;
            if (is_arm) {
              if (symbol_file_addr & 1)
                symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
              symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
            }
            Address symbol_addr;
            if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
              SectionSP symbol_section(symbol_addr.GetSection());
              uint32_t symbol_byte_size = 0;
              if (symbol_section) {
                const addr_t section_file_addr =
                    symbol_section->GetFileAddress();
                const FunctionStarts::Entry *next_func_start_entry =
                    function_starts.FindNextEntry(func_start_entry);
                const addr_t section_end_file_addr =
                    section_file_addr + symbol_section->GetByteSize();
                if (next_func_start_entry) {
                  addr_t next_symbol_file_addr = next_func_start_entry->addr;
                  if (is_arm)
                    next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
                  symbol_byte_size = std::min<lldb::addr_t>(
                      next_symbol_file_addr - symbol_file_addr,
                      section_end_file_addr - symbol_file_addr);
                } else {
                  symbol_byte_size = section_end_file_addr - symbol_file_addr;
                }
                sym[sym_idx].SetID(synthetic_sym_id++);
                sym[sym_idx].GetMangled().SetDemangledName(
                    GetNextSyntheticSymbolName());
                sym[sym_idx].SetType(eSymbolTypeCode);
                sym[sym_idx].SetIsSynthetic(true);
                sym[sym_idx].GetAddressRef() = symbol_addr;
                if (symbol_flags)
                  sym[sym_idx].SetFlags(symbol_flags);
                if (symbol_byte_size)
                  sym[sym_idx].SetByteSize(symbol_byte_size);
                ++sym_idx;
              }
            }
          }
        }
      }
    }

    // Trim our symbols down to just what we ended up with after removing any
    // symbols.
    if (sym_idx < num_syms) {
      num_syms = sym_idx;
      sym = symtab->Resize(num_syms);
    }

    // Now synthesize indirect symbols
    if (m_dysymtab.nindirectsyms != 0) {
      if (indirect_symbol_index_data.GetByteSize()) {
        NListIndexToSymbolIndexMap::const_iterator end_index_pos =
            m_nlist_idx_to_sym_idx.end();

        for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size();
             ++sect_idx) {
          if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) ==
              S_SYMBOL_STUBS) {
            uint32_t symbol_stub_byte_size =
                m_mach_sections[sect_idx].reserved2;
            if (symbol_stub_byte_size == 0)
              continue;

            const uint32_t num_symbol_stubs =
                m_mach_sections[sect_idx].size / symbol_stub_byte_size;

            if (num_symbol_stubs == 0)
              continue;

            const uint32_t symbol_stub_index_offset =
                m_mach_sections[sect_idx].reserved1;
            for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs;
                 ++stub_idx) {
              const uint32_t symbol_stub_index =
                  symbol_stub_index_offset + stub_idx;
              const lldb::addr_t symbol_stub_addr =
                  m_mach_sections[sect_idx].addr +
                  (stub_idx * symbol_stub_byte_size);
              lldb::offset_t symbol_stub_offset = symbol_stub_index * 4;
              if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
                      symbol_stub_offset, 4)) {
                const uint32_t stub_sym_id =
                    indirect_symbol_index_data.GetU32(&symbol_stub_offset);
                if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
                  continue;

                NListIndexToSymbolIndexMap::const_iterator index_pos =
                    m_nlist_idx_to_sym_idx.find(stub_sym_id);
                Symbol *stub_symbol = nullptr;
                if (index_pos != end_index_pos) {
                  // We have a remapping from the original nlist index to a
                  // current symbol index, so just look this up by index
                  stub_symbol = symtab->SymbolAtIndex(index_pos->second);
                } else {
                  // We need to lookup a symbol using the original nlist symbol
                  // index since this index is coming from the S_SYMBOL_STUBS
                  stub_symbol = symtab->FindSymbolByID(stub_sym_id);
                }

                if (stub_symbol) {
                  Address so_addr(symbol_stub_addr, section_list);

                  if (stub_symbol->GetType() == eSymbolTypeUndefined) {
                    // Change the external symbol into a trampoline that makes
                    // sense These symbols were N_UNDF N_EXT, and are useless
                    // to us, so we can re-use them so we don't have to make up
                    // a synthetic symbol for no good reason.
                    if (resolver_addresses.find(symbol_stub_addr) ==
                        resolver_addresses.end())
                      stub_symbol->SetType(eSymbolTypeTrampoline);
                    else
                      stub_symbol->SetType(eSymbolTypeResolver);
                    stub_symbol->SetExternal(false);
                    stub_symbol->GetAddressRef() = so_addr;
                    stub_symbol->SetByteSize(symbol_stub_byte_size);
                  } else {
                    // Make a synthetic symbol to describe the trampoline stub
                    Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
                    if (sym_idx >= num_syms) {
                      sym = symtab->Resize(++num_syms);
                      stub_symbol = nullptr; // this pointer no longer valid
                    }
                    sym[sym_idx].SetID(synthetic_sym_id++);
                    sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
                    if (resolver_addresses.find(symbol_stub_addr) ==
                        resolver_addresses.end())
                      sym[sym_idx].SetType(eSymbolTypeTrampoline);
                    else
                      sym[sym_idx].SetType(eSymbolTypeResolver);
                    sym[sym_idx].SetIsSynthetic(true);
                    sym[sym_idx].GetAddressRef() = so_addr;
                    sym[sym_idx].SetByteSize(symbol_stub_byte_size);
                    ++sym_idx;
                  }
                } else {
                  if (log)
                    log->Warning("symbol stub referencing symbol table symbol "
                                 "%u that isn't in our minimal symbol table, "
                                 "fix this!!!",
                                 stub_sym_id);
                }
              }
            }
          }
        }
      }
    }

    if (!trie_entries.empty()) {
      for (const auto &e : trie_entries) {
        if (e.entry.import_name) {
          // Only add indirect symbols from the Trie entries if we didn't have
          // a N_INDR nlist entry for this already
          if (indirect_symbol_names.find(e.entry.name) ==
              indirect_symbol_names.end()) {
            // Make a synthetic symbol to describe re-exported symbol.
            if (sym_idx >= num_syms)
              sym = symtab->Resize(++num_syms);
            sym[sym_idx].SetID(synthetic_sym_id++);
            sym[sym_idx].GetMangled() = Mangled(e.entry.name);
            sym[sym_idx].SetType(eSymbolTypeReExported);
            sym[sym_idx].SetIsSynthetic(true);
            sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
            if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize()) {
              sym[sym_idx].SetReExportedSymbolSharedLibrary(
                  dylib_files.GetFileSpecAtIndex(e.entry.other - 1));
            }
            ++sym_idx;
          }
        }
      }
    }

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

void ObjectFileMachO::Dump(Stream *s) {
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
    s->Printf("%p: ", static_cast<void *>(this));
    s->Indent();
    if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64)
      s->PutCString("ObjectFileMachO64");
    else
      s->PutCString("ObjectFileMachO32");

    ArchSpec header_arch = GetArchitecture();

    *s << ", file = '" << m_file
       << "', triple = " << header_arch.GetTriple().getTriple() << "\n";

    SectionList *sections = GetSectionList();
    if (sections)
      sections->Dump(s, nullptr, true, UINT32_MAX);

    if (m_symtab_up)
      m_symtab_up->Dump(s, nullptr, eSortOrderNone);
  }
}

UUID ObjectFileMachO::GetUUID(const llvm::MachO::mach_header &header,
                              const lldb_private::DataExtractor &data,
                              lldb::offset_t lc_offset) {
  uint32_t i;
  struct uuid_command load_cmd;

  lldb::offset_t offset = lc_offset;
  for (i = 0; i < header.ncmds; ++i) {
    const lldb::offset_t cmd_offset = offset;
    if (data.GetU32(&offset, &load_cmd, 2) == nullptr)
      break;

    if (load_cmd.cmd == LC_UUID) {
      const uint8_t *uuid_bytes = data.PeekData(offset, 16);

      if (uuid_bytes) {
        // OpenCL on Mac OS X uses the same UUID for each of its object files.
        // We pretend these object files have no UUID to prevent crashing.

        const uint8_t opencl_uuid[] = {0x8c, 0x8e, 0xb3, 0x9b, 0x3b, 0xa8,
                                       0x4b, 0x16, 0xb6, 0xa4, 0x27, 0x63,
                                       0xbb, 0x14, 0xf0, 0x0d};

        if (!memcmp(uuid_bytes, opencl_uuid, 16))
          return UUID();

        return UUID::fromOptionalData(uuid_bytes, 16);
      }
      return UUID();
    }
    offset = cmd_offset + load_cmd.cmdsize;
  }
  return UUID();
}

static llvm::StringRef GetOSName(uint32_t cmd) {
  switch (cmd) {
  case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
    return llvm::Triple::getOSTypeName(llvm::Triple::IOS);
  case llvm::MachO::LC_VERSION_MIN_MACOSX:
    return llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
  case llvm::MachO::LC_VERSION_MIN_TVOS:
    return llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
  case llvm::MachO::LC_VERSION_MIN_WATCHOS:
    return llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
  default:
    llvm_unreachable("unexpected LC_VERSION load command");
  }
}

namespace {
  struct OSEnv {
    llvm::StringRef os_type;
    llvm::StringRef environment;
    OSEnv(uint32_t cmd) {
      switch (cmd) {
      case PLATFORM_MACOS:
        os_type = llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
        return;
      case PLATFORM_IOS:
        os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
        return;
      case PLATFORM_TVOS:
        os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
        return;
      case PLATFORM_WATCHOS:
        os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
        return;
// NEED_BRIDGEOS_TRIPLE      case PLATFORM_BRIDGEOS:
// NEED_BRIDGEOS_TRIPLE        os_type = llvm::Triple::getOSTypeName(llvm::Triple::BridgeOS);
// NEED_BRIDGEOS_TRIPLE        return;
#if defined (PLATFORM_IOSSIMULATOR) && defined (PLATFORM_TVOSSIMULATOR) && defined (PLATFORM_WATCHOSSIMULATOR)
      case PLATFORM_IOSSIMULATOR:
        os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
        environment =
            llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
        return;
      case PLATFORM_TVOSSIMULATOR:
        os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
        environment =
            llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
        return;
      case PLATFORM_WATCHOSSIMULATOR:
        os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
        environment =
            llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
        return;
#endif
      default: {
        Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS |
                                                        LIBLLDB_LOG_PROCESS));
        if (log)
          log->Printf("unsupported platform in LC_BUILD_VERSION");
      }
      }
    }
  };

  struct MinOS {
    uint32_t major_version, minor_version, patch_version;
    MinOS(uint32_t version)
        : major_version(version >> 16),
          minor_version((version >> 8) & 0xffu),
          patch_version(version & 0xffu) {}
  };
} // namespace

ArchSpec
ObjectFileMachO::GetArchitecture(const llvm::MachO::mach_header &header,
                                 const lldb_private::DataExtractor &data,
                                 lldb::offset_t lc_offset) {
  ArchSpec arch;
  arch.SetArchitecture(eArchTypeMachO, header.cputype, header.cpusubtype);

  if (arch.IsValid()) {
    llvm::Triple &triple = arch.GetTriple();

    // Set OS to an unspecified unknown or a "*" so it can match any OS
    triple.setOS(llvm::Triple::UnknownOS);
    triple.setOSName(llvm::StringRef());

    if (header.filetype == MH_PRELOAD) {
      if (header.cputype == CPU_TYPE_ARM) {
        // If this is a 32-bit arm binary, and it's a standalone binary, force
        // the Vendor to Apple so we don't accidentally pick up the generic
        // armv7 ABI at runtime.  Apple's armv7 ABI always uses r7 for the
        // frame pointer register; most other armv7 ABIs use a combination of
        // r7 and r11.
        triple.setVendor(llvm::Triple::Apple);
      } else {
        // Set vendor to an unspecified unknown or a "*" so it can match any
        // vendor This is required for correct behavior of EFI debugging on
        // x86_64
        triple.setVendor(llvm::Triple::UnknownVendor);
        triple.setVendorName(llvm::StringRef());
      }
      return arch;
    } else {
      struct load_command load_cmd;
      llvm::SmallString<16> os_name;
      llvm::raw_svector_ostream os(os_name);

      // See if there is an LC_VERSION_MIN_* load command that can give
      // us the OS type.
      lldb::offset_t offset = lc_offset;
      for (uint32_t i = 0; i < header.ncmds; ++i) {
        const lldb::offset_t cmd_offset = offset;
        if (data.GetU32(&offset, &load_cmd, 2) == nullptr)
          break;

        struct version_min_command version_min;
        switch (load_cmd.cmd) {
        case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
        case llvm::MachO::LC_VERSION_MIN_MACOSX:
        case llvm::MachO::LC_VERSION_MIN_TVOS:
        case llvm::MachO::LC_VERSION_MIN_WATCHOS: {
          if (load_cmd.cmdsize != sizeof(version_min))
            break;
          if (data.ExtractBytes(cmd_offset, sizeof(version_min),
                                data.GetByteOrder(), &version_min) == 0)
            break;
          MinOS min_os(version_min.version);
          os << GetOSName(load_cmd.cmd) << min_os.major_version << '.'
             << min_os.minor_version << '.' << min_os.patch_version;
          triple.setOSName(os.str());
          return arch;
        }
        default:
          break;
        }

        offset = cmd_offset + load_cmd.cmdsize;
      }

      // See if there is an LC_BUILD_VERSION load command that can give
      // us the OS type.

      offset = lc_offset;
      for (uint32_t i = 0; i < header.ncmds; ++i) {
        const lldb::offset_t cmd_offset = offset;
        if (data.GetU32(&offset, &load_cmd, 2) == nullptr)
          break;
        do {
          if (load_cmd.cmd == llvm::MachO::LC_BUILD_VERSION) {
            struct build_version_command build_version;
            if (load_cmd.cmdsize < sizeof(build_version)) {
              // Malformed load command.
              break;
            }
            if (data.ExtractBytes(cmd_offset, sizeof(build_version),
                                  data.GetByteOrder(), &build_version) == 0)
              break;
            MinOS min_os(build_version.minos);
            OSEnv os_env(build_version.platform);
            if (os_env.os_type.empty())
              break;
            os << os_env.os_type << min_os.major_version << '.'
               << min_os.minor_version << '.' << min_os.patch_version;
            triple.setOSName(os.str());
            if (!os_env.environment.empty())
              triple.setEnvironmentName(os_env.environment);
            return arch;
          }
        } while (false);
        offset = cmd_offset + load_cmd.cmdsize;
      }

      if (header.filetype != MH_KEXT_BUNDLE) {
        // We didn't find a LC_VERSION_MIN load command and this isn't a KEXT
        // so lets not say our Vendor is Apple, leave it as an unspecified
        // unknown
        triple.setVendor(llvm::Triple::UnknownVendor);
        triple.setVendorName(llvm::StringRef());
      }
    }
  }
  return arch;
}

UUID ObjectFileMachO::GetUUID() {
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
    return GetUUID(m_header, m_data, offset);
  }
  return UUID();
}

uint32_t ObjectFileMachO::GetDependentModules(FileSpecList &files) {
  uint32_t count = 0;
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
    struct load_command load_cmd;
    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
    std::vector<std::string> rpath_paths;
    std::vector<std::string> rpath_relative_paths;
    std::vector<std::string> at_exec_relative_paths;
    uint32_t i;
    for (i = 0; i < m_header.ncmds; ++i) {
      const uint32_t cmd_offset = offset;
      if (m_data.GetU32(&offset, &load_cmd, 2) == nullptr)
        break;

      switch (load_cmd.cmd) {
      case LC_RPATH:
      case LC_LOAD_DYLIB:
      case LC_LOAD_WEAK_DYLIB:
      case LC_REEXPORT_DYLIB:
      case LC_LOAD_DYLINKER:
      case LC_LOADFVMLIB:
      case LC_LOAD_UPWARD_DYLIB: {
        uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
        const char *path = m_data.PeekCStr(name_offset);
        if (path) {
          if (load_cmd.cmd == LC_RPATH)
            rpath_paths.push_back(path);
          else {
            if (path[0] == '@') {
              if (strncmp(path, "@rpath", strlen("@rpath")) == 0)
                rpath_relative_paths.push_back(path + strlen("@rpath"));
              else if (strncmp(path, "@executable_path", 
                       strlen("@executable_path")) == 0)
                at_exec_relative_paths.push_back(path 
                                                 + strlen("@executable_path"));
            } else {
              FileSpec file_spec(path);
              if (files.AppendIfUnique(file_spec))
                count++;
            }
          }
        }
      } break;

      default:
        break;
      }
      offset = cmd_offset + load_cmd.cmdsize;
    }

    FileSpec this_file_spec(m_file);
    FileSystem::Instance().Resolve(this_file_spec);

    if (!rpath_paths.empty()) {
      // Fixup all LC_RPATH values to be absolute paths
      std::string loader_path("@loader_path");
      std::string executable_path("@executable_path");
      for (auto &rpath : rpath_paths) {
        if (rpath.find(loader_path) == 0) {
          rpath.erase(0, loader_path.size());
          rpath.insert(0, this_file_spec.GetDirectory().GetCString());
        } else if (rpath.find(executable_path) == 0) {
          rpath.erase(0, executable_path.size());
          rpath.insert(0, this_file_spec.GetDirectory().GetCString());
        }
      }

      for (const auto &rpath_relative_path : rpath_relative_paths) {
        for (const auto &rpath : rpath_paths) {
          std::string path = rpath;
          path += rpath_relative_path;
          // It is OK to resolve this path because we must find a file on disk
          // for us to accept it anyway if it is rpath relative.
          FileSpec file_spec(path);
          FileSystem::Instance().Resolve(file_spec);
          if (FileSystem::Instance().Exists(file_spec) &&
              files.AppendIfUnique(file_spec)) {
            count++;
            break;
          }
        }
      }
    }

    // We may have @executable_paths but no RPATHS.  Figure those out here.
    // Only do this if this object file is the executable.  We have no way to
    // get back to the actual executable otherwise, so we won't get the right
    // path.
    if (!at_exec_relative_paths.empty() && CalculateType() == eTypeExecutable) {
      FileSpec exec_dir = this_file_spec.CopyByRemovingLastPathComponent();
      for (const auto &at_exec_relative_path : at_exec_relative_paths) {
        FileSpec file_spec = 
            exec_dir.CopyByAppendingPathComponent(at_exec_relative_path);
        if (FileSystem::Instance().Exists(file_spec) &&
            files.AppendIfUnique(file_spec))
          count++;
      }
    }
  }
  return count;
}

lldb_private::Address ObjectFileMachO::GetEntryPointAddress() {
  // If the object file is not an executable it can't hold the entry point.
  // m_entry_point_address is initialized to an invalid address, so we can just
  // return that. If m_entry_point_address is valid it means we've found it
  // already, so return the cached value.

  if (!IsExecutable() || m_entry_point_address.IsValid())
    return m_entry_point_address;

  // Otherwise, look for the UnixThread or Thread command.  The data for the
  // Thread command is given in /usr/include/mach-o.h, but it is basically:
  //
  //  uint32_t flavor  - this is the flavor argument you would pass to
  //  thread_get_state
  //  uint32_t count   - this is the count of longs in the thread state data
  //  struct XXX_thread_state state - this is the structure from
  //  <machine/thread_status.h> corresponding to the flavor.
  //  <repeat this trio>
  //
  // So we just keep reading the various register flavors till we find the GPR
  // one, then read the PC out of there.
  // FIXME: We will need to have a "RegisterContext data provider" class at some
  // point that can get all the registers
  // out of data in this form & attach them to a given thread.  That should
  // underlie the MacOS X User process plugin, and we'll also need it for the
  // MacOS X Core File process plugin.  When we have that we can also use it
  // here.
  //
  // For now we hard-code the offsets and flavors we need:
  //
  //

  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
    struct load_command load_cmd;
    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
    uint32_t i;
    lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
    bool done = false;

    for (i = 0; i < m_header.ncmds; ++i) {
      const lldb::offset_t cmd_offset = offset;
      if (m_data.GetU32(&offset, &load_cmd, 2) == nullptr)
        break;

      switch (load_cmd.cmd) {
      case LC_UNIXTHREAD:
      case LC_THREAD: {
        while (offset < cmd_offset + load_cmd.cmdsize) {
          uint32_t flavor = m_data.GetU32(&offset);
          uint32_t count = m_data.GetU32(&offset);
          if (count == 0) {
            // We've gotten off somehow, log and exit;
            return m_entry_point_address;
          }

          switch (m_header.cputype) {
          case llvm::MachO::CPU_TYPE_ARM:
            if (flavor == 1 ||
                flavor == 9) // ARM_THREAD_STATE/ARM_THREAD_STATE32 from
                             // mach/arm/thread_status.h
            {
              offset += 60; // This is the offset of pc in the GPR thread state
                            // data structure.
              start_address = m_data.GetU32(&offset);
              done = true;
            }
            break;
          case llvm::MachO::CPU_TYPE_ARM64:
            if (flavor == 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h
            {
              offset += 256; // This is the offset of pc in the GPR thread state
                             // data structure.
              start_address = m_data.GetU64(&offset);
              done = true;
            }
            break;
          case llvm::MachO::CPU_TYPE_I386:
            if (flavor ==
                1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
            {
              offset += 40; // This is the offset of eip in the GPR thread state
                            // data structure.
              start_address = m_data.GetU32(&offset);
              done = true;
            }
            break;
          case llvm::MachO::CPU_TYPE_X86_64:
            if (flavor ==
                4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
            {
              offset += 16 * 8; // This is the offset of rip in the GPR thread
                                // state data structure.
              start_address = m_data.GetU64(&offset);
              done = true;
            }
            break;
          default:
            return m_entry_point_address;
          }
          // Haven't found the GPR flavor yet, skip over the data for this
          // flavor:
          if (done)
            break;
          offset += count * 4;
        }
      } break;
      case LC_MAIN: {
        ConstString text_segment_name("__TEXT");
        uint64_t entryoffset = m_data.GetU64(&offset);
        SectionSP text_segment_sp =
            GetSectionList()->FindSectionByName(text_segment_name);
        if (text_segment_sp) {
          done = true;
          start_address = text_segment_sp->GetFileAddress() + entryoffset;
        }
      } break;

      default:
        break;
      }
      if (done)
        break;

      // Go to the next load command:
      offset = cmd_offset + load_cmd.cmdsize;
    }

    if (start_address != LLDB_INVALID_ADDRESS) {
      // We got the start address from the load commands, so now resolve that
      // address in the sections of this ObjectFile:
      if (!m_entry_point_address.ResolveAddressUsingFileSections(
              start_address, GetSectionList())) {
        m_entry_point_address.Clear();
      }
    } else {
      // We couldn't read the UnixThread load command - maybe it wasn't there.
      // As a fallback look for the "start" symbol in the main executable.

      ModuleSP module_sp(GetModule());

      if (module_sp) {
        SymbolContextList contexts;
        SymbolContext context;
        if (module_sp->FindSymbolsWithNameAndType(ConstString("start"),
                                                  eSymbolTypeCode, contexts)) {
          if (contexts.GetContextAtIndex(0, context))
            m_entry_point_address = context.symbol->GetAddress();
        }
      }
    }
  }

  return m_entry_point_address;
}

lldb_private::Address ObjectFileMachO::GetBaseAddress() {
  lldb_private::Address header_addr;
  SectionList *section_list = GetSectionList();
  if (section_list) {
    SectionSP text_segment_sp(
        section_list->FindSectionByName(GetSegmentNameTEXT()));
    if (text_segment_sp) {
      header_addr.SetSection(text_segment_sp);
      header_addr.SetOffset(0);
    }
  }
  return header_addr;
}

uint32_t ObjectFileMachO::GetNumThreadContexts() {
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
    if (!m_thread_context_offsets_valid) {
      m_thread_context_offsets_valid = true;
      lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
      FileRangeArray::Entry file_range;
      thread_command thread_cmd;
      for (uint32_t i = 0; i < m_header.ncmds; ++i) {
        const uint32_t cmd_offset = offset;
        if (m_data.GetU32(&offset, &thread_cmd, 2) == nullptr)
          break;

        if (thread_cmd.cmd == LC_THREAD) {
          file_range.SetRangeBase(offset);
          file_range.SetByteSize(thread_cmd.cmdsize - 8);
          m_thread_context_offsets.Append(file_range);
        }
        offset = cmd_offset + thread_cmd.cmdsize;
      }
    }
  }
  return m_thread_context_offsets.GetSize();
}

std::string ObjectFileMachO::GetIdentifierString() {
  std::string result;
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());

    // First, look over the load commands for an LC_NOTE load command with
    // data_owner string "kern ver str" & use that if found.
    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
    for (uint32_t i = 0; i < m_header.ncmds; ++i) {
      const uint32_t cmd_offset = offset;
      load_command lc;
      if (m_data.GetU32(&offset, &lc.cmd, 2) == nullptr)
        break;
      if (lc.cmd == LC_NOTE)
      {
          char data_owner[17];
          m_data.CopyData (offset, 16, data_owner);
          data_owner[16] = '\0';
          offset += 16;
          uint64_t fileoff = m_data.GetU64_unchecked (&offset);
          uint64_t size = m_data.GetU64_unchecked (&offset);

          // "kern ver str" has a uint32_t version and then a nul terminated
          // c-string.
          if (strcmp ("kern ver str", data_owner) == 0)
          {
              offset = fileoff;
              uint32_t version;
              if (m_data.GetU32 (&offset, &version, 1) != nullptr)
              {
                  if (version == 1)
                  {
                      uint32_t strsize = size - sizeof (uint32_t);
                      char *buf = (char*) malloc (strsize);
                      if (buf)
                      {
                          m_data.CopyData (offset, strsize, buf);
                          buf[strsize - 1] = '\0';
                          result = buf;
                          if (buf)
                              free (buf);
                          return result;
                      }
                  }
              }
          }
      }
      offset = cmd_offset + lc.cmdsize;
    }

    // Second, make a pass over the load commands looking for an obsolete
    // LC_IDENT load command.
    offset = MachHeaderSizeFromMagic(m_header.magic);
    for (uint32_t i = 0; i < m_header.ncmds; ++i) {
      const uint32_t cmd_offset = offset;
      struct ident_command ident_command;
      if (m_data.GetU32(&offset, &ident_command, 2) == nullptr)
        break;
      if (ident_command.cmd == LC_IDENT && ident_command.cmdsize != 0) {
        char *buf = (char *) malloc (ident_command.cmdsize);
        if (buf != nullptr 
            && m_data.CopyData (offset, ident_command.cmdsize, buf) == ident_command.cmdsize) {
          buf[ident_command.cmdsize - 1] = '\0';
          result = buf;
        }
        if (buf)
          free (buf);
      }
      offset = cmd_offset + ident_command.cmdsize;
    }

  }
  return result;
}

bool ObjectFileMachO::GetCorefileMainBinaryInfo (addr_t &address, UUID &uuid) {
  address = LLDB_INVALID_ADDRESS;
  uuid.Clear();
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
    for (uint32_t i = 0; i < m_header.ncmds; ++i) {
      const uint32_t cmd_offset = offset;
      load_command lc;
      if (m_data.GetU32(&offset, &lc.cmd, 2) == nullptr)
        break;
      if (lc.cmd == LC_NOTE)
      {
          char data_owner[17];
          memset (data_owner, 0, sizeof (data_owner));
          m_data.CopyData (offset, 16, data_owner);
          offset += 16;
          uint64_t fileoff = m_data.GetU64_unchecked (&offset);
          uint64_t size = m_data.GetU64_unchecked (&offset);

          // "main bin spec" (main binary specification) data payload is
          // formatted:
          //    uint32_t version       [currently 1]
          //    uint32_t type          [0 == unspecified, 1 == kernel, 2 == user process]
          //    uint64_t address       [ UINT64_MAX if address not specified ]
          //    uuid_t   uuid          [ all zero's if uuid not specified ]
          //    uint32_t log2_pagesize [ process page size in log base 2, e.g. 4k pages are 12.  0 for unspecified ]

          if (strcmp ("main bin spec", data_owner) == 0 && size >= 32)
          {
              offset = fileoff;
              uint32_t version;
              if (m_data.GetU32 (&offset, &version, 1) != nullptr && version == 1)
              {
                  uint32_t type = 0;
                  uuid_t raw_uuid;
                  memset (raw_uuid, 0, sizeof (uuid_t));

                  if (m_data.GetU32(&offset, &type, 1) &&
                      m_data.GetU64(&offset, &address, 1) &&
                      m_data.CopyData(offset, sizeof(uuid_t), raw_uuid) != 0) {
                    uuid = UUID::fromOptionalData(raw_uuid, sizeof(uuid_t));
                    return true;
                  }
              }
          }
      }
      offset = cmd_offset + lc.cmdsize;
    }
  }
  return false;
}

lldb::RegisterContextSP
ObjectFileMachO::GetThreadContextAtIndex(uint32_t idx,
                                         lldb_private::Thread &thread) {
  lldb::RegisterContextSP reg_ctx_sp;

  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
    if (!m_thread_context_offsets_valid)
      GetNumThreadContexts();

    const FileRangeArray::Entry *thread_context_file_range =
        m_thread_context_offsets.GetEntryAtIndex(idx);
    if (thread_context_file_range) {

      DataExtractor data(m_data, thread_context_file_range->GetRangeBase(),
                         thread_context_file_range->GetByteSize());

      switch (m_header.cputype) {
      case llvm::MachO::CPU_TYPE_ARM64:
        reg_ctx_sp =
            std::make_shared<RegisterContextDarwin_arm64_Mach>(thread, data);
        break;

      case llvm::MachO::CPU_TYPE_ARM:
        reg_ctx_sp =
            std::make_shared<RegisterContextDarwin_arm_Mach>(thread, data);
        break;

      case llvm::MachO::CPU_TYPE_I386:
        reg_ctx_sp =
            std::make_shared<RegisterContextDarwin_i386_Mach>(thread, data);
        break;

      case llvm::MachO::CPU_TYPE_X86_64:
        reg_ctx_sp =
            std::make_shared<RegisterContextDarwin_x86_64_Mach>(thread, data);
        break;
      }
    }
  }
  return reg_ctx_sp;
}

ObjectFile::Type ObjectFileMachO::CalculateType() {
  switch (m_header.filetype) {
  case MH_OBJECT: // 0x1u
    if (GetAddressByteSize() == 4) {
      // 32 bit kexts are just object files, but they do have a valid
      // UUID load command.
      if (GetUUID()) {
        // this checking for the UUID load command is not enough we could
        // eventually look for the symbol named "OSKextGetCurrentIdentifier" as
        // this is required of kexts
        if (m_strata == eStrataInvalid)
          m_strata = eStrataKernel;
        return eTypeSharedLibrary;
      }
    }
    return eTypeObjectFile;

  case MH_EXECUTE:
    return eTypeExecutable; // 0x2u
  case MH_FVMLIB:
    return eTypeSharedLibrary; // 0x3u
  case MH_CORE:
    return eTypeCoreFile; // 0x4u
  case MH_PRELOAD:
    return eTypeSharedLibrary; // 0x5u
  case MH_DYLIB:
    return eTypeSharedLibrary; // 0x6u
  case MH_DYLINKER:
    return eTypeDynamicLinker; // 0x7u
  case MH_BUNDLE:
    return eTypeSharedLibrary; // 0x8u
  case MH_DYLIB_STUB:
    return eTypeStubLibrary; // 0x9u
  case MH_DSYM:
    return eTypeDebugInfo; // 0xAu
  case MH_KEXT_BUNDLE:
    return eTypeSharedLibrary; // 0xBu
  default:
    break;
  }
  return eTypeUnknown;
}

ObjectFile::Strata ObjectFileMachO::CalculateStrata() {
  switch (m_header.filetype) {
  case MH_OBJECT: // 0x1u
  {
    // 32 bit kexts are just object files, but they do have a valid
    // UUID load command.
    if (GetUUID()) {
      // this checking for the UUID load command is not enough we could
      // eventually look for the symbol named "OSKextGetCurrentIdentifier" as
      // this is required of kexts
      if (m_type == eTypeInvalid)
        m_type = eTypeSharedLibrary;

      return eStrataKernel;
    }
  }
    return eStrataUnknown;

  case MH_EXECUTE: // 0x2u
    // Check for the MH_DYLDLINK bit in the flags
    if (m_header.flags & MH_DYLDLINK) {
      return eStrataUser;
    } else {
      SectionList *section_list = GetSectionList();
      if (section_list) {
        static ConstString g_kld_section_name("__KLD");
        if (section_list->FindSectionByName(g_kld_section_name))
          return eStrataKernel;
      }
    }
    return eStrataRawImage;

  case MH_FVMLIB:
    return eStrataUser; // 0x3u
  case MH_CORE:
    return eStrataUnknown; // 0x4u
  case MH_PRELOAD:
    return eStrataRawImage; // 0x5u
  case MH_DYLIB:
    return eStrataUser; // 0x6u
  case MH_DYLINKER:
    return eStrataUser; // 0x7u
  case MH_BUNDLE:
    return eStrataUser; // 0x8u
  case MH_DYLIB_STUB:
    return eStrataUser; // 0x9u
  case MH_DSYM:
    return eStrataUnknown; // 0xAu
  case MH_KEXT_BUNDLE:
    return eStrataKernel; // 0xBu
  default:
    break;
  }
  return eStrataUnknown;
}

llvm::VersionTuple ObjectFileMachO::GetVersion() {
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
    struct dylib_command load_cmd;
    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
    uint32_t version_cmd = 0;
    uint64_t version = 0;
    uint32_t i;
    for (i = 0; i < m_header.ncmds; ++i) {
      const lldb::offset_t cmd_offset = offset;
      if (m_data.GetU32(&offset, &load_cmd, 2) == nullptr)
        break;

      if (load_cmd.cmd == LC_ID_DYLIB) {
        if (version_cmd == 0) {
          version_cmd = load_cmd.cmd;
          if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == nullptr)
            break;
          version = load_cmd.dylib.current_version;
        }
        break; // Break for now unless there is another more complete version
               // number load command in the future.
      }
      offset = cmd_offset + load_cmd.cmdsize;
    }

    if (version_cmd == LC_ID_DYLIB) {
      unsigned major = (version & 0xFFFF0000ull) >> 16;
      unsigned minor = (version & 0x0000FF00ull) >> 8;
      unsigned subminor = (version & 0x000000FFull);
      return llvm::VersionTuple(major, minor, subminor);
    }
  }
  return llvm::VersionTuple();
}

ArchSpec ObjectFileMachO::GetArchitecture() {
  ModuleSP module_sp(GetModule());
  ArchSpec arch;
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());

    return GetArchitecture(m_header, m_data,
                           MachHeaderSizeFromMagic(m_header.magic));
  }
  return arch;
}

void ObjectFileMachO::GetProcessSharedCacheUUID(Process *process, addr_t &base_addr, UUID &uuid) {
  uuid.Clear();
  base_addr = LLDB_INVALID_ADDRESS;
  if (process && process->GetDynamicLoader()) {
    DynamicLoader *dl = process->GetDynamicLoader();
    LazyBool using_shared_cache;
    LazyBool private_shared_cache;
    dl->GetSharedCacheInformation(base_addr, uuid, using_shared_cache,
                                  private_shared_cache);
  }
  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS | LIBLLDB_LOG_PROCESS));
  if (log)
    log->Printf("inferior process shared cache has a UUID of %s, base address 0x%" PRIx64 , uuid.GetAsString().c_str(), base_addr);
}

// From dyld SPI header dyld_process_info.h
typedef void *dyld_process_info;
struct lldb_copy__dyld_process_cache_info {
  uuid_t cacheUUID;          // UUID of cache used by process
  uint64_t cacheBaseAddress; // load address of dyld shared cache
  bool noCache;              // process is running without a dyld cache
  bool privateCache; // process is using a private copy of its dyld cache
};

// #including mach/mach.h pulls in machine.h & CPU_TYPE_ARM etc conflicts with llvm
// enum definitions llvm::MachO::CPU_TYPE_ARM turning them into compile errors.
// So we need to use the actual underlying types of task_t and kern_return_t
// below.
extern "C" unsigned int /*task_t*/ mach_task_self(); 

void ObjectFileMachO::GetLLDBSharedCacheUUID(addr_t &base_addr, UUID &uuid) {
  uuid.Clear();
  base_addr = LLDB_INVALID_ADDRESS;

#if defined(__APPLE__) &&                                                      \
    (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
  uint8_t *(*dyld_get_all_image_infos)(void);
  dyld_get_all_image_infos =
      (uint8_t * (*)())dlsym(RTLD_DEFAULT, "_dyld_get_all_image_infos");
  if (dyld_get_all_image_infos) {
    uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos();
    if (dyld_all_image_infos_address) {
      uint32_t *version = (uint32_t *)
          dyld_all_image_infos_address; // version <mach-o/dyld_images.h>
      if (*version >= 13) {
        uuid_t *sharedCacheUUID_address = 0;
        int wordsize = sizeof(uint8_t *);
        if (wordsize == 8) {
          sharedCacheUUID_address =
              (uuid_t *)((uint8_t *)dyld_all_image_infos_address +
                         160); // sharedCacheUUID <mach-o/dyld_images.h>
          if (*version >= 15)
            base_addr = *(uint64_t *) ((uint8_t *) dyld_all_image_infos_address 
                          + 176); // sharedCacheBaseAddress <mach-o/dyld_images.h>
        } else {
          sharedCacheUUID_address =
              (uuid_t *)((uint8_t *)dyld_all_image_infos_address +
                         84); // sharedCacheUUID <mach-o/dyld_images.h>
          if (*version >= 15) {
            base_addr = 0;
            base_addr = *(uint32_t *) ((uint8_t *) dyld_all_image_infos_address 
                          + 100); // sharedCacheBaseAddress <mach-o/dyld_images.h>
          }
        }
        uuid = UUID::fromOptionalData(sharedCacheUUID_address, sizeof(uuid_t));
      }
    }
  } else {
    // Exists in macOS 10.12 and later, iOS 10.0 and later - dyld SPI
    dyld_process_info (*dyld_process_info_create)(unsigned int /* task_t */ task, uint64_t timestamp, unsigned int /*kern_return_t*/ *kernelError);
    void (*dyld_process_info_get_cache)(void *info, void *cacheInfo);
    void (*dyld_process_info_release)(dyld_process_info info);

    dyld_process_info_create = (void *(*)(unsigned int /* task_t */, uint64_t, unsigned int /*kern_return_t*/ *))
               dlsym (RTLD_DEFAULT, "_dyld_process_info_create");
    dyld_process_info_get_cache = (void (*)(void *, void *))
               dlsym (RTLD_DEFAULT, "_dyld_process_info_get_cache");
    dyld_process_info_release = (void (*)(void *))
               dlsym (RTLD_DEFAULT, "_dyld_process_info_release");

    if (dyld_process_info_create && dyld_process_info_get_cache) {
      unsigned int /*kern_return_t */ kern_ret;
		  dyld_process_info process_info = dyld_process_info_create(::mach_task_self(), 0, &kern_ret);
      if (process_info) {
        struct lldb_copy__dyld_process_cache_info sc_info;
        memset (&sc_info, 0, sizeof (struct lldb_copy__dyld_process_cache_info));
        dyld_process_info_get_cache (process_info, &sc_info);
        if (sc_info.cacheBaseAddress != 0) {
          base_addr = sc_info.cacheBaseAddress;
          uuid = UUID::fromOptionalData(sc_info.cacheUUID, sizeof(uuid_t));
        }
        dyld_process_info_release (process_info);
      }
    }
  }
  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS | LIBLLDB_LOG_PROCESS));
  if (log && uuid.IsValid())
    log->Printf("lldb's in-memory shared cache has a UUID of %s base address of 0x%" PRIx64, uuid.GetAsString().c_str(), base_addr);
#endif
}

llvm::VersionTuple ObjectFileMachO::GetMinimumOSVersion() {
  if (!m_min_os_version) {
    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
    for (uint32_t i = 0; i < m_header.ncmds; ++i) {
      const lldb::offset_t load_cmd_offset = offset;

      version_min_command lc;
      if (m_data.GetU32(&offset, &lc.cmd, 2) == nullptr)
        break;
      if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX ||
          lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS ||
          lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS ||
          lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) {
        if (m_data.GetU32(&offset, &lc.version,
                          (sizeof(lc) / sizeof(uint32_t)) - 2)) {
          const uint32_t xxxx = lc.version >> 16;
          const uint32_t yy = (lc.version >> 8) & 0xffu;
          const uint32_t zz = lc.version & 0xffu;
          if (xxxx) {
            m_min_os_version = llvm::VersionTuple(xxxx, yy, zz);
            break;
          }
        } 
      } else if (lc.cmd == llvm::MachO::LC_BUILD_VERSION) {
        // struct build_version_command {
        //     uint32_t    cmd;            /* LC_BUILD_VERSION */
        //     uint32_t    cmdsize;        /* sizeof(struct build_version_command) plus */
        //                                 /* ntools * sizeof(struct build_tool_version) */
        //     uint32_t    platform;       /* platform */
        //     uint32_t    minos;          /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
        //     uint32_t    sdk;            /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
        //     uint32_t    ntools;         /* number of tool entries following this */
        // };

        offset += 4;  // skip platform
        uint32_t minos = m_data.GetU32(&offset);

        const uint32_t xxxx = minos >> 16;
        const uint32_t yy = (minos >> 8) & 0xffu;
        const uint32_t zz = minos & 0xffu;
        if (xxxx) {
            m_min_os_version = llvm::VersionTuple(xxxx, yy, zz);
            break;
        }
      }

      offset = load_cmd_offset + lc.cmdsize;
    }

    if (!m_min_os_version) {
      // Set version to an empty value so we don't keep trying to
      m_min_os_version = llvm::VersionTuple();
    }
  }

  return *m_min_os_version;
}

llvm::VersionTuple ObjectFileMachO::GetSDKVersion() {
  if (!m_sdk_versions.hasValue()) {
    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
    for (uint32_t i = 0; i < m_header.ncmds; ++i) {
      const lldb::offset_t load_cmd_offset = offset;

      version_min_command lc;
      if (m_data.GetU32(&offset, &lc.cmd, 2) == nullptr)
        break;
      if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX ||
          lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS ||
          lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS ||
          lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) {
        if (m_data.GetU32(&offset, &lc.version,
                          (sizeof(lc) / sizeof(uint32_t)) - 2)) {
          const uint32_t xxxx = lc.sdk >> 16;
          const uint32_t yy = (lc.sdk >> 8) & 0xffu;
          const uint32_t zz = lc.sdk & 0xffu;
          if (xxxx) {
            m_sdk_versions = llvm::VersionTuple(xxxx, yy, zz);
            break;
          } else {
            GetModule()->ReportWarning(
                "minimum OS version load command with invalid (0) version found.");
          }
        }
      }
      offset = load_cmd_offset + lc.cmdsize;
    }

    if (!m_sdk_versions.hasValue()) {
      offset = MachHeaderSizeFromMagic(m_header.magic);
      for (uint32_t i = 0; i < m_header.ncmds; ++i) {
        const lldb::offset_t load_cmd_offset = offset;

        version_min_command lc;
        if (m_data.GetU32(&offset, &lc.cmd, 2) == nullptr)
          break;
        if (lc.cmd == llvm::MachO::LC_BUILD_VERSION) {
          // struct build_version_command {
          //     uint32_t    cmd;            /* LC_BUILD_VERSION */
          //     uint32_t    cmdsize;        /* sizeof(struct
          //     build_version_command) plus */
          //                                 /* ntools * sizeof(struct
          //                                 build_tool_version) */
          //     uint32_t    platform;       /* platform */
          //     uint32_t    minos;          /* X.Y.Z is encoded in nibbles
          //     xxxx.yy.zz */ uint32_t    sdk;            /* X.Y.Z is encoded
          //     in nibbles xxxx.yy.zz */ uint32_t    ntools;         /* number
          //     of tool entries following this */
          // };

          offset += 4; // skip platform
          uint32_t minos = m_data.GetU32(&offset);

          const uint32_t xxxx = minos >> 16;
          const uint32_t yy = (minos >> 8) & 0xffu;
          const uint32_t zz = minos & 0xffu;
          if (xxxx) {
            m_sdk_versions = llvm::VersionTuple(xxxx, yy, zz);
            break;
          }
        }
        offset = load_cmd_offset + lc.cmdsize;
      }
    }

    if (!m_sdk_versions.hasValue())
      m_sdk_versions = llvm::VersionTuple();
  }

  return m_sdk_versions.getValue();
}

bool ObjectFileMachO::GetIsDynamicLinkEditor() {
  return m_header.filetype == llvm::MachO::MH_DYLINKER;
}

bool ObjectFileMachO::AllowAssemblyEmulationUnwindPlans() {
  return m_allow_assembly_emulation_unwind_plans;
}

// PluginInterface protocol
lldb_private::ConstString ObjectFileMachO::GetPluginName() {
  return GetPluginNameStatic();
}

uint32_t ObjectFileMachO::GetPluginVersion() { return 1; }

Section *ObjectFileMachO::GetMachHeaderSection() {
  // Find the first address of the mach header which is the first non-zero file
  // sized section whose file offset is zero. This is the base file address of
  // the mach-o file which can be subtracted from the vmaddr of the other
  // segments found in memory and added to the load address
  ModuleSP module_sp = GetModule();
  if (!module_sp)
    return nullptr;
  SectionList *section_list = GetSectionList();
  if (!section_list)
    return nullptr;
  const size_t num_sections = section_list->GetSize();
  for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
    Section *section = section_list->GetSectionAtIndex(sect_idx).get();
    if (section->GetFileOffset() == 0 && SectionIsLoadable(section))
      return section;
  }
  return nullptr;
}

bool ObjectFileMachO::SectionIsLoadable(const Section *section) {
  if (!section)
    return false;
  const bool is_dsym = (m_header.filetype == MH_DSYM);
  if (section->GetFileSize() == 0 && !is_dsym)
    return false;
  if (section->IsThreadSpecific())
    return false;
  if (GetModule().get() != section->GetModule().get())
    return false;
  // Be careful with __LINKEDIT and __DWARF segments
  if (section->GetName() == GetSegmentNameLINKEDIT() ||
      section->GetName() == GetSegmentNameDWARF()) {
    // Only map __LINKEDIT and __DWARF if we have an in memory image and
    // this isn't a kernel binary like a kext or mach_kernel.
    const bool is_memory_image = (bool)m_process_wp.lock();
    const Strata strata = GetStrata();
    if (is_memory_image == false || strata == eStrataKernel)
      return false;
  }
  return true;
}

lldb::addr_t ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage(
    lldb::addr_t header_load_address, const Section *header_section,
    const Section *section) {
  ModuleSP module_sp = GetModule();
  if (module_sp && header_section && section &&
      header_load_address != LLDB_INVALID_ADDRESS) {
    lldb::addr_t file_addr = header_section->GetFileAddress();
    if (file_addr != LLDB_INVALID_ADDRESS && SectionIsLoadable(section))
      return section->GetFileAddress() - file_addr + header_load_address;
  }
  return LLDB_INVALID_ADDRESS;
}

bool ObjectFileMachO::SetLoadAddress(Target &target, lldb::addr_t value,
                                     bool value_is_offset) {
  ModuleSP module_sp = GetModule();
  if (module_sp) {
    size_t num_loaded_sections = 0;
    SectionList *section_list = GetSectionList();
    if (section_list) {
      const size_t num_sections = section_list->GetSize();

      if (value_is_offset) {
        // "value" is an offset to apply to each top level segment
        for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
          // Iterate through the object file sections to find all of the
          // sections that size on disk (to avoid __PAGEZERO) and load them
          SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
          if (SectionIsLoadable(section_sp.get()))
            if (target.GetSectionLoadList().SetSectionLoadAddress(
                    section_sp, section_sp->GetFileAddress() + value))
              ++num_loaded_sections;
        }
      } else {
        // "value" is the new base address of the mach_header, adjust each
        // section accordingly

        Section *mach_header_section = GetMachHeaderSection();
        if (mach_header_section) {
          for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
            SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));

            lldb::addr_t section_load_addr =
                CalculateSectionLoadAddressForMemoryImage(
                    value, mach_header_section, section_sp.get());
            if (section_load_addr != LLDB_INVALID_ADDRESS) {
              if (target.GetSectionLoadList().SetSectionLoadAddress(
                      section_sp, section_load_addr))
                ++num_loaded_sections;
            }
          }
        }
      }
    }
    return num_loaded_sections > 0;
  }
  return false;
}

bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
                               const FileSpec &outfile, Status &error) {
  if (process_sp) {
    Target &target = process_sp->GetTarget();
    const ArchSpec target_arch = target.GetArchitecture();
    const llvm::Triple &target_triple = target_arch.GetTriple();
    if (target_triple.getVendor() == llvm::Triple::Apple &&
        (target_triple.getOS() == llvm::Triple::MacOSX ||
         target_triple.getOS() == llvm::Triple::IOS ||
         target_triple.getOS() == llvm::Triple::WatchOS ||
         target_triple.getOS() == llvm::Triple::TvOS)) {
         // NEED_BRIDGEOS_TRIPLE target_triple.getOS() == llvm::Triple::BridgeOS)) {
      bool make_core = false;
      switch (target_arch.GetMachine()) {
      case llvm::Triple::aarch64:
      case llvm::Triple::arm:
      case llvm::Triple::thumb:
      case llvm::Triple::x86:
      case llvm::Triple::x86_64:
        make_core = true;
        break;
      default:
        error.SetErrorStringWithFormat("unsupported core architecture: %s",
                                       target_triple.str().c_str());
        break;
      }

      if (make_core) {
        std::vector<segment_command_64> segment_load_commands;
        //                uint32_t range_info_idx = 0;
        MemoryRegionInfo range_info;
        Status range_error = process_sp->GetMemoryRegionInfo(0, range_info);
        const uint32_t addr_byte_size = target_arch.GetAddressByteSize();
        const ByteOrder byte_order = target_arch.GetByteOrder();
        if (range_error.Success()) {
          while (range_info.GetRange().GetRangeBase() != LLDB_INVALID_ADDRESS) {
            const addr_t addr = range_info.GetRange().GetRangeBase();
            const addr_t size = range_info.GetRange().GetByteSize();

            if (size == 0)
              break;

            // Calculate correct protections
            uint32_t prot = 0;
            if (range_info.GetReadable() == MemoryRegionInfo::eYes)
              prot |= VM_PROT_READ;
            if (range_info.GetWritable() == MemoryRegionInfo::eYes)
              prot |= VM_PROT_WRITE;
            if (range_info.GetExecutable() == MemoryRegionInfo::eYes)
              prot |= VM_PROT_EXECUTE;

            if (prot != 0) {
              uint32_t cmd_type = LC_SEGMENT_64;
              uint32_t segment_size = sizeof(segment_command_64);
              if (addr_byte_size == 4) {
                cmd_type = LC_SEGMENT;
                segment_size = sizeof(segment_command);
              }
              segment_command_64 segment = {
                  cmd_type,     // uint32_t cmd;
                  segment_size, // uint32_t cmdsize;
                  {0},          // char segname[16];
                  addr, // uint64_t vmaddr;    // uint32_t for 32-bit Mach-O
                  size, // uint64_t vmsize;    // uint32_t for 32-bit Mach-O
                  0,    // uint64_t fileoff;   // uint32_t for 32-bit Mach-O
                  size, // uint64_t filesize;  // uint32_t for 32-bit Mach-O
                  prot, // uint32_t maxprot;
                  prot, // uint32_t initprot;
                  0,    // uint32_t nsects;
                  0};   // uint32_t flags;
              segment_load_commands.push_back(segment);
            } else {
              // No protections and a size of 1 used to be returned from old
              // debugservers when we asked about a region that was past the
              // last memory region and it indicates the end...
              if (size == 1)
                break;
            }

            range_error = process_sp->GetMemoryRegionInfo(
                range_info.GetRange().GetRangeEnd(), range_info);
            if (range_error.Fail())
              break;
          }

          StreamString buffer(Stream::eBinary, addr_byte_size, byte_order);

          mach_header_64 mach_header;
          if (addr_byte_size == 8) {
            mach_header.magic = MH_MAGIC_64;
          } else {
            mach_header.magic = MH_MAGIC;
          }
          mach_header.cputype = target_arch.GetMachOCPUType();
          mach_header.cpusubtype = target_arch.GetMachOCPUSubType();
          mach_header.filetype = MH_CORE;
          mach_header.ncmds = segment_load_commands.size();
          mach_header.flags = 0;
          mach_header.reserved = 0;
          ThreadList &thread_list = process_sp->GetThreadList();
          const uint32_t num_threads = thread_list.GetSize();

          // Make an array of LC_THREAD data items. Each one contains the
          // contents of the LC_THREAD load command. The data doesn't contain
          // the load command + load command size, we will add the load command
          // and load command size as we emit the data.
          std::vector<StreamString> LC_THREAD_datas(num_threads);
          for (auto &LC_THREAD_data : LC_THREAD_datas) {
            LC_THREAD_data.GetFlags().Set(Stream::eBinary);
            LC_THREAD_data.SetAddressByteSize(addr_byte_size);
            LC_THREAD_data.SetByteOrder(byte_order);
          }
          for (uint32_t thread_idx = 0; thread_idx < num_threads;
               ++thread_idx) {
            ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx));
            if (thread_sp) {
              switch (mach_header.cputype) {
              case llvm::MachO::CPU_TYPE_ARM64:
                RegisterContextDarwin_arm64_Mach::Create_LC_THREAD(
                    thread_sp.get(), LC_THREAD_datas[thread_idx]);
                break;

              case llvm::MachO::CPU_TYPE_ARM:
                RegisterContextDarwin_arm_Mach::Create_LC_THREAD(
                    thread_sp.get(), LC_THREAD_datas[thread_idx]);
                break;

              case llvm::MachO::CPU_TYPE_I386:
                RegisterContextDarwin_i386_Mach::Create_LC_THREAD(
                    thread_sp.get(), LC_THREAD_datas[thread_idx]);
                break;

              case llvm::MachO::CPU_TYPE_X86_64:
                RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD(
                    thread_sp.get(), LC_THREAD_datas[thread_idx]);
                break;
              }
            }
          }

          // The size of the load command is the size of the segments...
          if (addr_byte_size == 8) {
            mach_header.sizeofcmds = segment_load_commands.size() *
                                     sizeof(struct segment_command_64);
          } else {
            mach_header.sizeofcmds =
                segment_load_commands.size() * sizeof(struct segment_command);
          }

          // and the size of all LC_THREAD load command
          for (const auto &LC_THREAD_data : LC_THREAD_datas) {
            ++mach_header.ncmds;
            mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
          }

          // Write the mach header
          buffer.PutHex32(mach_header.magic);
          buffer.PutHex32(mach_header.cputype);
          buffer.PutHex32(mach_header.cpusubtype);
          buffer.PutHex32(mach_header.filetype);
          buffer.PutHex32(mach_header.ncmds);
          buffer.PutHex32(mach_header.sizeofcmds);
          buffer.PutHex32(mach_header.flags);
          if (addr_byte_size == 8) {
            buffer.PutHex32(mach_header.reserved);
          }

          // Skip the mach header and all load commands and align to the next
          // 0x1000 byte boundary
          addr_t file_offset = buffer.GetSize() + mach_header.sizeofcmds;
          if (file_offset & 0x00000fff) {
            file_offset += 0x00001000ull;
            file_offset &= (~0x00001000ull + 1);
          }

          for (auto &segment : segment_load_commands) {
            segment.fileoff = file_offset;
            file_offset += segment.filesize;
          }

          // Write out all of the LC_THREAD load commands
          for (const auto &LC_THREAD_data : LC_THREAD_datas) {
            const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
            buffer.PutHex32(LC_THREAD);
            buffer.PutHex32(8 + LC_THREAD_data_size); // cmd + cmdsize + data
            buffer.Write(LC_THREAD_data.GetString().data(),
                         LC_THREAD_data_size);
          }

          // Write out all of the segment load commands
          for (const auto &segment : segment_load_commands) {
            printf("0x%8.8x 0x%8.8x [0x%16.16" PRIx64 " - 0x%16.16" PRIx64
                   ") [0x%16.16" PRIx64 " 0x%16.16" PRIx64
                   ") 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x]\n",
                   segment.cmd, segment.cmdsize, segment.vmaddr,
                   segment.vmaddr + segment.vmsize, segment.fileoff,
                   segment.filesize, segment.maxprot, segment.initprot,
                   segment.nsects, segment.flags);

            buffer.PutHex32(segment.cmd);
            buffer.PutHex32(segment.cmdsize);
            buffer.PutRawBytes(segment.segname, sizeof(segment.segname));
            if (addr_byte_size == 8) {
              buffer.PutHex64(segment.vmaddr);
              buffer.PutHex64(segment.vmsize);
              buffer.PutHex64(segment.fileoff);
              buffer.PutHex64(segment.filesize);
            } else {
              buffer.PutHex32(static_cast<uint32_t>(segment.vmaddr));
              buffer.PutHex32(static_cast<uint32_t>(segment.vmsize));
              buffer.PutHex32(static_cast<uint32_t>(segment.fileoff));
              buffer.PutHex32(static_cast<uint32_t>(segment.filesize));
            }
            buffer.PutHex32(segment.maxprot);
            buffer.PutHex32(segment.initprot);
            buffer.PutHex32(segment.nsects);
            buffer.PutHex32(segment.flags);
          }

          File core_file;
          std::string core_file_path(outfile.GetPath());
          error = FileSystem::Instance().Open(core_file, outfile,
                                              File::eOpenOptionWrite |
                                                  File::eOpenOptionTruncate |
                                                  File::eOpenOptionCanCreate);
          if (error.Success()) {
            // Read 1 page at a time
            uint8_t bytes[0x1000];
            // Write the mach header and load commands out to the core file
            size_t bytes_written = buffer.GetString().size();
            error = core_file.Write(buffer.GetString().data(), bytes_written);
            if (error.Success()) {
              // Now write the file data for all memory segments in the process
              for (const auto &segment : segment_load_commands) {
                if (core_file.SeekFromStart(segment.fileoff) == -1) {
                  error.SetErrorStringWithFormat(
                      "unable to seek to offset 0x%" PRIx64 " in '%s'",
                      segment.fileoff, core_file_path.c_str());
                  break;
                }

                printf("Saving %" PRId64
                       " bytes of data for memory region at 0x%" PRIx64 "\n",
                       segment.vmsize, segment.vmaddr);
                addr_t bytes_left = segment.vmsize;
                addr_t addr = segment.vmaddr;
                Status memory_read_error;
                while (bytes_left > 0 && error.Success()) {
                  const size_t bytes_to_read =
                      bytes_left > sizeof(bytes) ? sizeof(bytes) : bytes_left;

                  // In a savecore setting, we don't really care about caching,
                  // as the data is dumped and very likely never read again,
                  // so we call ReadMemoryFromInferior to bypass it.
                  const size_t bytes_read = process_sp->ReadMemoryFromInferior(
                      addr, bytes, bytes_to_read, memory_read_error);

                  if (bytes_read == bytes_to_read) {
                    size_t bytes_written = bytes_read;
                    error = core_file.Write(bytes, bytes_written);
                    bytes_left -= bytes_read;
                    addr += bytes_read;
                  } else {
                    // Some pages within regions are not readable, those should
                    // be zero filled
                    memset(bytes, 0, bytes_to_read);
                    size_t bytes_written = bytes_to_read;
                    error = core_file.Write(bytes, bytes_written);
                    bytes_left -= bytes_to_read;
                    addr += bytes_to_read;
                  }
                }
              }
            }
          }
        } else {
          error.SetErrorString(
              "process doesn't support getting memory region info");
        }
      }
      return true; // This is the right plug to handle saving core files for
                   // this process
    }
  }
  return false;
}
