//===-- ObjectFileMachO.cpp -------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// C Includes
// C++ Includes
// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"

// Project includes
#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/ArchSpec.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/RangeMap.h"
#include "lldb/Core/RegisterValue.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/DataBufferLLVM.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
#include "lldb/Utility/UUID.h"

#include "lldb/Utility/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

#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 == NULL)
      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", NULL, 8, data);
      WriteRegister(reg_ctx, "rbx", NULL, 8, data);
      WriteRegister(reg_ctx, "rcx", NULL, 8, data);
      WriteRegister(reg_ctx, "rdx", NULL, 8, data);
      WriteRegister(reg_ctx, "rdi", NULL, 8, data);
      WriteRegister(reg_ctx, "rsi", NULL, 8, data);
      WriteRegister(reg_ctx, "rbp", NULL, 8, data);
      WriteRegister(reg_ctx, "rsp", NULL, 8, data);
      WriteRegister(reg_ctx, "r8", NULL, 8, data);
      WriteRegister(reg_ctx, "r9", NULL, 8, data);
      WriteRegister(reg_ctx, "r10", NULL, 8, data);
      WriteRegister(reg_ctx, "r11", NULL, 8, data);
      WriteRegister(reg_ctx, "r12", NULL, 8, data);
      WriteRegister(reg_ctx, "r13", NULL, 8, data);
      WriteRegister(reg_ctx, "r14", NULL, 8, data);
      WriteRegister(reg_ctx, "r15", NULL, 8, data);
      WriteRegister(reg_ctx, "rip", NULL, 8, data);
      WriteRegister(reg_ctx, "rflags", NULL, 8, data);
      WriteRegister(reg_ctx, "cs", NULL, 8, data);
      WriteRegister(reg_ctx, "fs", NULL, 8, data);
      WriteRegister(reg_ctx, "gs", NULL, 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", NULL, 4, data);
      WriteRegister(reg_ctx, "err", NULL, 4, data);
      WriteRegister(reg_ctx, "faultvaddr", NULL, 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 == NULL)
      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", NULL, 4, data);
      WriteRegister(reg_ctx, "ebx", NULL, 4, data);
      WriteRegister(reg_ctx, "ecx", NULL, 4, data);
      WriteRegister(reg_ctx, "edx", NULL, 4, data);
      WriteRegister(reg_ctx, "edi", NULL, 4, data);
      WriteRegister(reg_ctx, "esi", NULL, 4, data);
      WriteRegister(reg_ctx, "ebp", NULL, 4, data);
      WriteRegister(reg_ctx, "esp", NULL, 4, data);
      WriteRegister(reg_ctx, "ss", NULL, 4, data);
      WriteRegister(reg_ctx, "eflags", NULL, 4, data);
      WriteRegister(reg_ctx, "eip", NULL, 4, data);
      WriteRegister(reg_ctx, "cs", NULL, 4, data);
      WriteRegister(reg_ctx, "ds", NULL, 4, data);
      WriteRegister(reg_ctx, "es", NULL, 4, data);
      WriteRegister(reg_ctx, "fs", NULL, 4, data);
      WriteRegister(reg_ctx, "gs", NULL, 4, data);

      // Write out the EXC registers
      data.PutHex32(EXCRegSet);
      data.PutHex32(EXCWordCount);
      WriteRegister(reg_ctx, "trapno", NULL, 4, data);
      WriteRegister(reg_ctx, "err", NULL, 4, data);
      WriteRegister(reg_ctx, "faultvaddr", NULL, 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 == NULL)
      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", NULL, 4, data);
      WriteRegister(reg_ctx, "r1", NULL, 4, data);
      WriteRegister(reg_ctx, "r2", NULL, 4, data);
      WriteRegister(reg_ctx, "r3", NULL, 4, data);
      WriteRegister(reg_ctx, "r4", NULL, 4, data);
      WriteRegister(reg_ctx, "r5", NULL, 4, data);
      WriteRegister(reg_ctx, "r6", NULL, 4, data);
      WriteRegister(reg_ctx, "r7", NULL, 4, data);
      WriteRegister(reg_ctx, "r8", NULL, 4, data);
      WriteRegister(reg_ctx, "r9", NULL, 4, data);
      WriteRegister(reg_ctx, "r10", NULL, 4, data);
      WriteRegister(reg_ctx, "r11", NULL, 4, data);
      WriteRegister(reg_ctx, "r12", NULL, 4, data);
      WriteRegister(reg_ctx, "sp", NULL, 4, data);
      WriteRegister(reg_ctx, "lr", NULL, 4, data);
      WriteRegister(reg_ctx, "pc", NULL, 4, data);
      WriteRegister(reg_ctx, "cpsr", NULL, 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 &&
            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 == NULL)
      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", NULL, 8, data);
      WriteRegister(reg_ctx, "x1", NULL, 8, data);
      WriteRegister(reg_ctx, "x2", NULL, 8, data);
      WriteRegister(reg_ctx, "x3", NULL, 8, data);
      WriteRegister(reg_ctx, "x4", NULL, 8, data);
      WriteRegister(reg_ctx, "x5", NULL, 8, data);
      WriteRegister(reg_ctx, "x6", NULL, 8, data);
      WriteRegister(reg_ctx, "x7", NULL, 8, data);
      WriteRegister(reg_ctx, "x8", NULL, 8, data);
      WriteRegister(reg_ctx, "x9", NULL, 8, data);
      WriteRegister(reg_ctx, "x10", NULL, 8, data);
      WriteRegister(reg_ctx, "x11", NULL, 8, data);
      WriteRegister(reg_ctx, "x12", NULL, 8, data);
      WriteRegister(reg_ctx, "x13", NULL, 8, data);
      WriteRegister(reg_ctx, "x14", NULL, 8, data);
      WriteRegister(reg_ctx, "x15", NULL, 8, data);
      WriteRegister(reg_ctx, "x16", NULL, 8, data);
      WriteRegister(reg_ctx, "x17", NULL, 8, data);
      WriteRegister(reg_ctx, "x18", NULL, 8, data);
      WriteRegister(reg_ctx, "x19", NULL, 8, data);
      WriteRegister(reg_ctx, "x20", NULL, 8, data);
      WriteRegister(reg_ctx, "x21", NULL, 8, data);
      WriteRegister(reg_ctx, "x22", NULL, 8, data);
      WriteRegister(reg_ctx, "x23", NULL, 8, data);
      WriteRegister(reg_ctx, "x24", NULL, 8, data);
      WriteRegister(reg_ctx, "x25", NULL, 8, data);
      WriteRegister(reg_ctx, "x26", NULL, 8, data);
      WriteRegister(reg_ctx, "x27", NULL, 8, data);
      WriteRegister(reg_ctx, "x28", NULL, 8, data);
      WriteRegister(reg_ctx, "fp", NULL, 8, data);
      WriteRegister(reg_ctx, "lr", NULL, 8, data);
      WriteRegister(reg_ctx, "sp", NULL, 8, data);
      WriteRegister(reg_ctx, "pc", NULL, 8, data);
      WriteRegister(reg_ctx, "cpsr", NULL, 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 =
        DataBufferLLVM::CreateSliceFromPath(file->GetPath(), 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 =
        DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length, file_offset);
    if (!data_sp)
      return nullptr;
    data_offset = 0;
  }
  auto objfile_ap = llvm::make_unique<ObjectFileMachO>(
      module_sp, data_sp, data_offset, file, file_offset, length);
  if (!objfile_ap || !objfile_ap->ParseHeader())
    return nullptr;

  return objfile_ap.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_ap(
        new ObjectFileMachO(module_sp, data_sp, process_sp, header_addr));
    if (objfile_ap.get() && objfile_ap->ParseHeader())
      return objfile_ap.release();
  }
  return NULL;
}

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 = DataBufferLLVM::CreateSliceFromPath(
            file.GetPath(), 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);

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

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

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

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

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

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

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

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

      ArchSpec mach_arch;

      if (GetArchitecture(mach_arch)) {
        // 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 = DataBufferLLVM::CreateSliceFromPath(
                  m_file.GetPath(), 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 eAddressClassUnknown;

          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 eAddressClassCodeAlternateISA;
            }
            return eAddressClassCode;

          case eSectionTypeContainer:
            return eAddressClassUnknown;

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

          case eSectionTypeDebug:
          case eSectionTypeDWARFDebugAbbrev:
          case eSectionTypeDWARFDebugAddr:
          case eSectionTypeDWARFDebugAranges:
          case eSectionTypeDWARFDebugFrame:
          case eSectionTypeDWARFDebugInfo:
          case eSectionTypeDWARFDebugLine:
          case eSectionTypeDWARFDebugLoc:
          case eSectionTypeDWARFDebugMacInfo:
          case eSectionTypeDWARFDebugMacro:
          case eSectionTypeDWARFDebugPubNames:
          case eSectionTypeDWARFDebugPubTypes:
          case eSectionTypeDWARFDebugRanges:
          case eSectionTypeDWARFDebugStr:
          case eSectionTypeDWARFDebugStrOffsets:
          case eSectionTypeDWARFAppleNames:
          case eSectionTypeDWARFAppleTypes:
          case eSectionTypeDWARFAppleNamespaces:
          case eSectionTypeDWARFAppleObjC:
            return eAddressClassDebug;

          case eSectionTypeEHFrame:
          case eSectionTypeARMexidx:
          case eSectionTypeARMextab:
          case eSectionTypeCompactUnwind:
            return eAddressClassRuntime;

          case eSectionTypeAbsoluteAddress:
          case eSectionTypeELFSymbolTable:
          case eSectionTypeELFDynamicSymbols:
          case eSectionTypeELFRelocationEntries:
          case eSectionTypeELFDynamicLinkInfo:
          case eSectionTypeOther:
            return eAddressClassUnknown;
          }
        }
      }

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

      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 eAddressClassCodeAlternateISA;
        }
        return eAddressClassCode;

      case eSymbolTypeData:
        return eAddressClassData;
      case eSymbolTypeRuntime:
        return eAddressClassRuntime;
      case eSymbolTypeException:
        return eAddressClassRuntime;
      case eSymbolTypeSourceFile:
        return eAddressClassDebug;
      case eSymbolTypeHeaderFile:
        return eAddressClassDebug;
      case eSymbolTypeObjectFile:
        return eAddressClassDebug;
      case eSymbolTypeCommonBlock:
        return eAddressClassDebug;
      case eSymbolTypeBlock:
        return eAddressClassDebug;
      case eSymbolTypeLocal:
        return eAddressClassData;
      case eSymbolTypeParam:
        return eAddressClassData;
      case eSymbolTypeVariable:
        return eAddressClassData;
      case eSymbolTypeVariableType:
        return eAddressClassDebug;
      case eSymbolTypeLineEntry:
        return eAddressClassDebug;
      case eSymbolTypeLineHeader:
        return eAddressClassDebug;
      case eSymbolTypeScopeBegin:
        return eAddressClassDebug;
      case eSymbolTypeScopeEnd:
        return eAddressClassDebug;
      case eSymbolTypeAdditional:
        return eAddressClassUnknown;
      case eSymbolTypeCompiler:
        return eAddressClassDebug;
      case eSymbolTypeInstrumentation:
        return eAddressClassDebug;
      case eSymbolTypeUndefined:
        return eAddressClassUnknown;
      case eSymbolTypeObjCClass:
        return eAddressClassRuntime;
      case eSymbolTypeObjCMetaClass:
        return eAddressClassRuntime;
      case eSymbolTypeObjCIVar:
        return eAddressClassRuntime;
      case eSymbolTypeReExported:
        return eAddressClassRuntime;
      }
    }
  }
  return eAddressClassUnknown;
}

Symtab *ObjectFileMachO::GetSymtab() {
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
    if (m_symtab_ap.get() == NULL) {
      m_symtab_ap.reset(new Symtab(this));
      std::lock_guard<std::recursive_mutex> symtab_guard(
          m_symtab_ap->GetMutex());
      ParseSymtab();
      m_symtab_ap->Finalize();
    }
  }
  return m_symtab_ap.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) == NULL)
          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) ==
              NULL) {
            // Clear m_dysymtab if we were unable to read all items from the
            // load command
            ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));
          }
        }
        offset = load_cmd_offset + lc.cmdsize;
      }
    }
  }
  if (m_dysymtab.cmd)
    return m_dysymtab.nlocalsym <= 1;
  return false;
}

void ObjectFileMachO::CreateSections(SectionList &unified_section_list) {
  if (!m_sections_ap.get()) {
    m_sections_ap.reset(new SectionList());

    const bool is_dsym = (m_header.filetype == MH_DSYM);
    lldb::user_id_t segID = 0;
    lldb::user_id_t sectID = 0;
    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
    uint32_t i;
    const bool is_core = GetType() == eTypeCoreFile;
    // bool dump_sections = false;
    ModuleSP module_sp(GetModule());
    // First look up any LC_ENCRYPTION_INFO load commands
    typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
    EncryptedFileRanges encrypted_file_ranges;
    encryption_info_command encryption_cmd;
    for (i = 0; i < m_header.ncmds; ++i) {
      const lldb::offset_t load_cmd_offset = offset;
      if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
        break;

      // 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);
            encrypted_file_ranges.Append(entry);
          }
        }
      }
      offset = load_cmd_offset + encryption_cmd.cmdsize;
    }

    bool section_file_addresses_changed = false;

    offset = MachHeaderSizeFromMagic(m_header.magic);

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

      if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64) {
        if (m_data.GetU8(&offset, (uint8_t *)load_cmd.segname, 16)) {
          bool add_section = true;
          bool add_to_unified = true;
          ConstString const_segname(load_cmd.segname,
                                    std::min<size_t>(strlen(load_cmd.segname),
                                                     sizeof(load_cmd.segname)));

          SectionSP unified_section_sp(
              unified_section_list.FindSectionByName(const_segname));
          if (is_dsym && unified_section_sp) {
            if (const_segname == GetSegmentNameLINKEDIT()) {
              // We need to keep the __LINKEDIT segment private to this object
              // file only
              add_to_unified = false;
            } else {
              // This is the dSYM file and this section has already been created
              // by
              // the object file, no need to create it.
              add_section = false;
            }
          }
          load_cmd.vmaddr = m_data.GetAddress(&offset);
          load_cmd.vmsize = m_data.GetAddress(&offset);
          load_cmd.fileoff = m_data.GetAddress(&offset);
          load_cmd.filesize = m_data.GetAddress(&offset);
          if (m_length != 0 && load_cmd.filesize != 0) {
            if (load_cmd.fileoff > m_length) {
              // We have a load command that says it extends past the end of the
              // file.  This is likely
              // a corrupt file.  We don't have any way to return an error
              // condition here (this method
              // was likely invoked from something like
              // ObjectFile::GetSectionList()) -- all we can do
              // is null out the SectionList vector and if a process has been
              // set up, dump a message
              // to stdout.  The most common case here is core file debugging
              // with a truncated file.
              const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64
                                                ? "LC_SEGMENT_64"
                                                : "LC_SEGMENT";
              module_sp->ReportWarning(
                  "load command %u %s has a fileoff (0x%" PRIx64
                  ") that extends beyond the end of the file (0x%" PRIx64
                  "), ignoring this section",
                  i, lc_segment_name, load_cmd.fileoff, m_length);

              load_cmd.fileoff = 0;
              load_cmd.filesize = 0;
            }

            if (load_cmd.fileoff + load_cmd.filesize > m_length) {
              // We have a load command that says it extends past the end of the
              // file.  This is likely
              // a corrupt file.  We don't have any way to return an error
              // condition here (this method
              // was likely invoked from something like
              // ObjectFile::GetSectionList()) -- all we can do
              // is null out the SectionList vector and if a process has been
              // set up, dump a message
              // to stdout.  The most common case here is core file debugging
              // with a truncated file.
              const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64
                                                ? "LC_SEGMENT_64"
                                                : "LC_SEGMENT";
              GetModule()->ReportWarning(
                  "load command %u %s has a fileoff + filesize (0x%" PRIx64
                  ") that extends beyond the end of the file (0x%" PRIx64
                  "), the segment will be truncated to match",
                  i, lc_segment_name, load_cmd.fileoff + load_cmd.filesize,
                  m_length);

              // Tuncase the length
              load_cmd.filesize = m_length - load_cmd.fileoff;
            }
          }
          if (m_data.GetU32(&offset, &load_cmd.maxprot, 4)) {
            uint32_t segment_permissions = 0;
            if (load_cmd.initprot & VM_PROT_READ)
              segment_permissions |= ePermissionsReadable;
            if (load_cmd.initprot & VM_PROT_WRITE)
              segment_permissions |= ePermissionsWritable;
            if (load_cmd.initprot & VM_PROT_EXECUTE)
              segment_permissions |= ePermissionsExecutable;

            const bool segment_is_encrypted =
                (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;

            // Keep a list of mach segments around in case we need to
            // get at data that isn't stored in the abstracted Sections.
            m_mach_segments.push_back(load_cmd);

            // Use a segment ID of the segment index shifted left by 8 so they
            // never conflict with any of the sections.
            SectionSP segment_sp;
            if (add_section && (const_segname || is_core)) {
              segment_sp.reset(new Section(
                  module_sp,     // Module to which this section belongs
                  this,          // Object file to which this sections belongs
                  ++segID << 8,  // Section ID is the 1 based segment index
                                 // shifted right by 8 bits as not to collide
                                 // with any of the 256 section IDs that are
                                 // possible
                  const_segname, // Name of this section
                  eSectionTypeContainer, // This section is a container of other
                                         // sections.
                  load_cmd.vmaddr,   // File VM address == addresses as they are
                                     // found in the object file
                  load_cmd.vmsize,   // VM size in bytes of this section
                  load_cmd.fileoff,  // Offset to the data for this section in
                                     // the file
                  load_cmd.filesize, // Size in bytes of this section as found
                                     // in the file
                  0,                 // Segments have no alignment information
                  load_cmd.flags));  // Flags for this section

              segment_sp->SetIsEncrypted(segment_is_encrypted);
              m_sections_ap->AddSection(segment_sp);
              segment_sp->SetPermissions(segment_permissions);
              if (add_to_unified)
                unified_section_list.AddSection(segment_sp);
            } else if (unified_section_sp) {
              if (is_dsym &&
                  unified_section_sp->GetFileAddress() != load_cmd.vmaddr) {
                // Check to see if the module was read from memory?
                if (module_sp->GetObjectFile()->GetHeaderAddress().IsValid()) {
                  // We have a module that is in memory and needs to have its
                  // file address adjusted. We need to do this because when we
                  // load a file from memory, its addresses will be slid
                  // already,
                  // yet the addresses in the new symbol file will still be
                  // unslid.
                  // Since everything is stored as section offset, this
                  // shouldn't
                  // cause any problems.

                  // Make sure we've parsed the symbol table from the
                  // ObjectFile before we go around changing its Sections.
                  module_sp->GetObjectFile()->GetSymtab();
                  // eh_frame would present the same problems but we parse that
                  // on
                  // a per-function basis as-needed so it's more difficult to
                  // remove its use of the Sections.  Realistically, the
                  // environments
                  // where this code path will be taken will not have eh_frame
                  // sections.

                  unified_section_sp->SetFileAddress(load_cmd.vmaddr);

                  // Notify the module that the section addresses have been
                  // changed once
                  // we're done so any file-address caches can be updated.
                  section_file_addresses_changed = true;
                }
              }
              m_sections_ap->AddSection(unified_section_sp);
            }

            struct section_64 sect64;
            ::memset(&sect64, 0, sizeof(sect64));
            // Push a section into our mach sections for the section at
            // index zero (NO_SECT) if we don't have any mach sections yet...
            if (m_mach_sections.empty())
              m_mach_sections.push_back(sect64);
            uint32_t segment_sect_idx;
            const lldb::user_id_t first_segment_sectID = sectID + 1;

            const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
            for (segment_sect_idx = 0; segment_sect_idx < load_cmd.nsects;
                 ++segment_sect_idx) {
              if (m_data.GetU8(&offset, (uint8_t *)sect64.sectname,
                               sizeof(sect64.sectname)) == NULL)
                break;
              if (m_data.GetU8(&offset, (uint8_t *)sect64.segname,
                               sizeof(sect64.segname)) == NULL)
                break;
              sect64.addr = m_data.GetAddress(&offset);
              sect64.size = m_data.GetAddress(&offset);

              if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
                break;

              // Keep a list of mach sections around in case we need to
              // get at data that isn't stored in the abstracted Sections.
              m_mach_sections.push_back(sect64);

              if (add_section) {
                ConstString section_name(
                    sect64.sectname, std::min<size_t>(strlen(sect64.sectname),
                                                      sizeof(sect64.sectname)));
                if (!const_segname) {
                  // We have a segment with no name so we need to conjure up
                  // segments that correspond to the section's segname if there
                  // isn't already such a section. If there is such a section,
                  // we resize the section so that it spans all sections.
                  // We also mark these sections as fake so address matches
                  // don't
                  // hit if they land in the gaps between the child sections.
                  const_segname.SetTrimmedCStringWithLength(
                      sect64.segname, sizeof(sect64.segname));
                  segment_sp =
                      unified_section_list.FindSectionByName(const_segname);
                  if (segment_sp.get()) {
                    Section *segment = segment_sp.get();
                    // Grow the section size as needed.
                    const lldb::addr_t sect64_min_addr = sect64.addr;
                    const lldb::addr_t sect64_max_addr =
                        sect64_min_addr + sect64.size;
                    const lldb::addr_t curr_seg_byte_size =
                        segment->GetByteSize();
                    const lldb::addr_t curr_seg_min_addr =
                        segment->GetFileAddress();
                    const lldb::addr_t curr_seg_max_addr =
                        curr_seg_min_addr + curr_seg_byte_size;
                    if (sect64_min_addr >= curr_seg_min_addr) {
                      const lldb::addr_t new_seg_byte_size =
                          sect64_max_addr - curr_seg_min_addr;
                      // Only grow the section size if needed
                      if (new_seg_byte_size > curr_seg_byte_size)
                        segment->SetByteSize(new_seg_byte_size);
                    } else {
                      // We need to change the base address of the segment and
                      // adjust the child section offsets for all existing
                      // children.
                      const lldb::addr_t slide_amount =
                          sect64_min_addr - curr_seg_min_addr;
                      segment->Slide(slide_amount, false);
                      segment->GetChildren().Slide(-slide_amount, false);
                      segment->SetByteSize(curr_seg_max_addr - sect64_min_addr);
                    }

                    // Grow the section size as needed.
                    if (sect64.offset) {
                      const lldb::addr_t segment_min_file_offset =
                          segment->GetFileOffset();
                      const lldb::addr_t segment_max_file_offset =
                          segment_min_file_offset + segment->GetFileSize();

                      const lldb::addr_t section_min_file_offset =
                          sect64.offset;
                      const lldb::addr_t section_max_file_offset =
                          section_min_file_offset + sect64.size;
                      const lldb::addr_t new_file_offset = std::min(
                          section_min_file_offset, segment_min_file_offset);
                      const lldb::addr_t new_file_size =
                          std::max(section_max_file_offset,
                                   segment_max_file_offset) -
                          new_file_offset;
                      segment->SetFileOffset(new_file_offset);
                      segment->SetFileSize(new_file_size);
                    }
                  } else {
                    // Create a fake section for the section's named segment
                    segment_sp.reset(new Section(
                        segment_sp, // Parent section
                        module_sp,  // Module to which this section belongs
                        this,       // Object file to which this section belongs
                        ++segID << 8, // Section ID is the 1 based segment index
                                      // shifted right by 8 bits as not to
                                      // collide with any of the 256 section IDs
                                      // that are possible
                        const_segname,         // Name of this section
                        eSectionTypeContainer, // This section is a container of
                                               // other sections.
                        sect64.addr, // File VM address == addresses as they are
                                     // found in the object file
                        sect64.size, // VM size in bytes of this section
                        sect64.offset, // Offset to the data for this section in
                                       // the file
                        sect64.offset ? sect64.size : 0, // Size in bytes of
                                                         // this section as
                                                         // found in the file
                        sect64.align,
                        load_cmd.flags)); // Flags for this section
                    segment_sp->SetIsFake(true);
                    segment_sp->SetPermissions(segment_permissions);
                    m_sections_ap->AddSection(segment_sp);
                    if (add_to_unified)
                      unified_section_list.AddSection(segment_sp);
                    segment_sp->SetIsEncrypted(segment_is_encrypted);
                  }
                }
                assert(segment_sp.get());

                lldb::SectionType sect_type = eSectionTypeOther;

                if (sect64.flags &
                    (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
                  sect_type = eSectionTypeCode;
                else {
                  uint32_t mach_sect_type = sect64.flags & SECTION_TYPE;
                  static ConstString g_sect_name_objc_data("__objc_data");
                  static ConstString g_sect_name_objc_msgrefs("__objc_msgrefs");
                  static ConstString g_sect_name_objc_selrefs("__objc_selrefs");
                  static ConstString g_sect_name_objc_classrefs(
                      "__objc_classrefs");
                  static ConstString g_sect_name_objc_superrefs(
                      "__objc_superrefs");
                  static ConstString g_sect_name_objc_const("__objc_const");
                  static ConstString g_sect_name_objc_classlist(
                      "__objc_classlist");
                  static ConstString g_sect_name_cfstring("__cfstring");

                  static ConstString g_sect_name_dwarf_debug_abbrev(
                      "__debug_abbrev");
                  static ConstString g_sect_name_dwarf_debug_aranges(
                      "__debug_aranges");
                  static ConstString g_sect_name_dwarf_debug_frame(
                      "__debug_frame");
                  static ConstString g_sect_name_dwarf_debug_info(
                      "__debug_info");
                  static ConstString g_sect_name_dwarf_debug_line(
                      "__debug_line");
                  static ConstString g_sect_name_dwarf_debug_loc("__debug_loc");
                  static ConstString g_sect_name_dwarf_debug_macinfo(
                      "__debug_macinfo");
                  static ConstString g_sect_name_dwarf_debug_pubnames(
                      "__debug_pubnames");
                  static ConstString g_sect_name_dwarf_debug_pubtypes(
                      "__debug_pubtypes");
                  static ConstString g_sect_name_dwarf_debug_ranges(
                      "__debug_ranges");
                  static ConstString g_sect_name_dwarf_debug_str("__debug_str");
                  static ConstString g_sect_name_dwarf_apple_names(
                      "__apple_names");
                  static ConstString g_sect_name_dwarf_apple_types(
                      "__apple_types");
                  static ConstString g_sect_name_dwarf_apple_namespaces(
                      "__apple_namespac");
                  static ConstString g_sect_name_dwarf_apple_objc(
                      "__apple_objc");
                  static ConstString g_sect_name_eh_frame("__eh_frame");
                  static ConstString g_sect_name_compact_unwind(
                      "__unwind_info");
                  static ConstString g_sect_name_text("__text");
                  static ConstString g_sect_name_data("__data");
                  static ConstString g_sect_name_go_symtab("__gosymtab");

                  if (section_name == g_sect_name_dwarf_debug_abbrev)
                    sect_type = eSectionTypeDWARFDebugAbbrev;
                  else if (section_name == g_sect_name_dwarf_debug_aranges)
                    sect_type = eSectionTypeDWARFDebugAranges;
                  else if (section_name == g_sect_name_dwarf_debug_frame)
                    sect_type = eSectionTypeDWARFDebugFrame;
                  else if (section_name == g_sect_name_dwarf_debug_info)
                    sect_type = eSectionTypeDWARFDebugInfo;
                  else if (section_name == g_sect_name_dwarf_debug_line)
                    sect_type = eSectionTypeDWARFDebugLine;
                  else if (section_name == g_sect_name_dwarf_debug_loc)
                    sect_type = eSectionTypeDWARFDebugLoc;
                  else if (section_name == g_sect_name_dwarf_debug_macinfo)
                    sect_type = eSectionTypeDWARFDebugMacInfo;
                  else if (section_name == g_sect_name_dwarf_debug_pubnames)
                    sect_type = eSectionTypeDWARFDebugPubNames;
                  else if (section_name == g_sect_name_dwarf_debug_pubtypes)
                    sect_type = eSectionTypeDWARFDebugPubTypes;
                  else if (section_name == g_sect_name_dwarf_debug_ranges)
                    sect_type = eSectionTypeDWARFDebugRanges;
                  else if (section_name == g_sect_name_dwarf_debug_str)
                    sect_type = eSectionTypeDWARFDebugStr;
                  else if (section_name == g_sect_name_dwarf_apple_names)
                    sect_type = eSectionTypeDWARFAppleNames;
                  else if (section_name == g_sect_name_dwarf_apple_types)
                    sect_type = eSectionTypeDWARFAppleTypes;
                  else if (section_name == g_sect_name_dwarf_apple_namespaces)
                    sect_type = eSectionTypeDWARFAppleNamespaces;
                  else if (section_name == g_sect_name_dwarf_apple_objc)
                    sect_type = eSectionTypeDWARFAppleObjC;
                  else if (section_name == g_sect_name_objc_selrefs)
                    sect_type = eSectionTypeDataCStringPointers;
                  else if (section_name == g_sect_name_objc_msgrefs)
                    sect_type = eSectionTypeDataObjCMessageRefs;
                  else if (section_name == g_sect_name_eh_frame)
                    sect_type = eSectionTypeEHFrame;
                  else if (section_name == g_sect_name_compact_unwind)
                    sect_type = eSectionTypeCompactUnwind;
                  else if (section_name == g_sect_name_cfstring)
                    sect_type = eSectionTypeDataObjCCFStrings;
                  else if (section_name == g_sect_name_go_symtab)
                    sect_type = eSectionTypeGoSymtab;
                  else if (section_name == g_sect_name_objc_data ||
                           section_name == g_sect_name_objc_classrefs ||
                           section_name == g_sect_name_objc_superrefs ||
                           section_name == g_sect_name_objc_const ||
                           section_name == g_sect_name_objc_classlist) {
                    sect_type = eSectionTypeDataPointers;
                  }

                  if (sect_type == eSectionTypeOther) {
                    switch (mach_sect_type) {
                    // TODO: categorize sections by other flags for regular
                    // sections
                    case S_REGULAR:
                      if (section_name == g_sect_name_text)
                        sect_type = eSectionTypeCode;
                      else if (section_name == g_sect_name_data)
                        sect_type = eSectionTypeData;
                      else
                        sect_type = eSectionTypeOther;
                      break;
                    case S_ZEROFILL:
                      sect_type = eSectionTypeZeroFill;
                      break;
                    case S_CSTRING_LITERALS:
                      sect_type = eSectionTypeDataCString;
                      break; // section with only literal C strings
                    case S_4BYTE_LITERALS:
                      sect_type = eSectionTypeData4;
                      break; // section with only 4 byte literals
                    case S_8BYTE_LITERALS:
                      sect_type = eSectionTypeData8;
                      break; // section with only 8 byte literals
                    case S_LITERAL_POINTERS:
                      sect_type = eSectionTypeDataPointers;
                      break; // section with only pointers to literals
                    case S_NON_LAZY_SYMBOL_POINTERS:
                      sect_type = eSectionTypeDataPointers;
                      break; // section with only non-lazy symbol pointers
                    case S_LAZY_SYMBOL_POINTERS:
                      sect_type = eSectionTypeDataPointers;
                      break; // section with only lazy symbol pointers
                    case S_SYMBOL_STUBS:
                      sect_type = eSectionTypeCode;
                      break; // section with only symbol stubs, byte size of
                             // stub in the reserved2 field
                    case S_MOD_INIT_FUNC_POINTERS:
                      sect_type = eSectionTypeDataPointers;
                      break; // section with only function pointers for
                             // initialization
                    case S_MOD_TERM_FUNC_POINTERS:
                      sect_type = eSectionTypeDataPointers;
                      break; // section with only function pointers for
                             // termination
                    case S_COALESCED:
                      sect_type = eSectionTypeOther;
                      break;
                    case S_GB_ZEROFILL:
                      sect_type = eSectionTypeZeroFill;
                      break;
                    case S_INTERPOSING:
                      sect_type = eSectionTypeCode;
                      break; // section with only pairs of function pointers for
                             // interposing
                    case S_16BYTE_LITERALS:
                      sect_type = eSectionTypeData16;
                      break; // section with only 16 byte literals
                    case S_DTRACE_DOF:
                      sect_type = eSectionTypeDebug;
                      break;
                    case S_LAZY_DYLIB_SYMBOL_POINTERS:
                      sect_type = eSectionTypeDataPointers;
                      break;
                    default:
                      break;
                    }
                  }
                }

                SectionSP section_sp(new Section(
                    segment_sp, module_sp, this, ++sectID, section_name,
                    sect_type, sect64.addr - segment_sp->GetFileAddress(),
                    sect64.size, sect64.offset,
                    sect64.offset == 0 ? 0 : sect64.size, sect64.align,
                    sect64.flags));
                // Set the section to be encrypted to match the segment

                bool section_is_encrypted = false;
                if (!segment_is_encrypted && load_cmd.filesize != 0)
                  section_is_encrypted =
                      encrypted_file_ranges.FindEntryThatContains(
                          sect64.offset) != NULL;

                section_sp->SetIsEncrypted(segment_is_encrypted ||
                                           section_is_encrypted);
                section_sp->SetPermissions(segment_permissions);
                segment_sp->GetChildren().AddSection(section_sp);

                if (segment_sp->IsFake()) {
                  segment_sp.reset();
                  const_segname.Clear();
                }
              }
            }
            if (segment_sp && is_dsym) {
              if (first_segment_sectID <= sectID) {
                lldb::user_id_t sect_uid;
                for (sect_uid = first_segment_sectID; sect_uid <= sectID;
                     ++sect_uid) {
                  SectionSP curr_section_sp(
                      segment_sp->GetChildren().FindSectionByID(sect_uid));
                  SectionSP next_section_sp;
                  if (sect_uid + 1 <= sectID)
                    next_section_sp =
                        segment_sp->GetChildren().FindSectionByID(sect_uid + 1);

                  if (curr_section_sp.get()) {
                    if (curr_section_sp->GetByteSize() == 0) {
                      if (next_section_sp.get() != NULL)
                        curr_section_sp->SetByteSize(
                            next_section_sp->GetFileAddress() -
                            curr_section_sp->GetFileAddress());
                      else
                        curr_section_sp->SetByteSize(load_cmd.vmsize);
                    }
                  }
                }
              }
            }
          }
        }
      } else if (load_cmd.cmd == LC_DYSYMTAB) {
        m_dysymtab.cmd = load_cmd.cmd;
        m_dysymtab.cmdsize = load_cmd.cmdsize;
        m_data.GetU32(&offset, &m_dysymtab.ilocalsym,
                      (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
      }

      offset = load_cmd_offset + load_cmd.cmdsize;
    }

    if (section_file_addresses_changed && module_sp.get()) {
      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 = NULL;
    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 = DataBufferLLVM::CreateSliceFromPath(
      dyld_shared_cache.GetPath(),
      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);
    uint8_t uuid_bytes[sizeof(uuid_t)];
    memcpy(uuid_bytes, dsc_header_data.GetData(&offset, sizeof(uuid_t)),
           sizeof(uuid_t));
    dsc_uuid.SetBytes(uuid_bytes);
  }
  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) == NULL)
      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) ==
          0) // 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, false);
        // 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) ==
          NULL) // 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_ap.get();
    SectionList *section_list = GetSectionList();
    if (section_list == NULL)
      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(NULL, 0, byte_order, addr_byte_size);
    DataExtractor strtab_data(NULL, 0, byte_order, addr_byte_size);
    DataExtractor function_starts_data(NULL, 0, byte_order, addr_byte_size);
    DataExtractor indirect_symbol_index_data(NULL, 0, byte_order,
                                             addr_byte_size);
    DataExtractor dyld_trie_data(NULL, 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(GetLLDBSharedCacheUUID());
          UUID process_shared_cache(GetProcessSharedCacheUUID(process));
          bool use_lldb_cache = true;
          if (lldb_shared_cache.IsValid() && process_shared_cache.IsValid() &&
              lldb_shared_cache != process_shared_cache) {
            use_lldb_cache = false;
            ModuleSP module_sp(GetModule());
            if (module_sp)
              module_sp->ReportWarning("shared cache in process does not match "
                                       "lldb's own shared cache, startup will "
                                       "be slow.");
          }

          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());
            // Load strings individually from memory when loading from memory
            // since shared cache
            // string tables contain strings for all symbols from all shared
            // cached libraries
            // 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 (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());
            }
          } else 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;
      }
    }

    const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
    const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
    const ConstString &g_segment_name_DATA_DIRTY = GetSegmentNameDATA_DIRTY();
    const ConstString &g_segment_name_DATA_CONST = GetSegmentNameDATA_CONST();
    const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
    const 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 = NULL;

    uint32_t sym_idx = 0;
    Symbol *sym = NULL;
    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;

      if (process) {
        process_shared_cache_uuid = GetProcessSharedCacheUUID(process);
      }

      // 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 (dsc_development_filespec.Exists()) {
          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() && dsc_nondevelopment_filespec.Exists()) {
          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 (!dsc_filespec.Exists()) {
        if (dsc_development_filespec.Exists()) {
          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 = DataBufferLLVM::CreateSliceFromPath(
          dsc_filespec.GetPath(), 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 =
              DataBufferLLVM::CreateSliceFromPath(
                  dsc_filespec.GetPath(),
                  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 =
                DataBufferLLVM::CreateSliceFromPath(dsc_filespec.GetPath(),
                                               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 (!so_dir.Exists()) {
                                    so_dir.SetFile(
                                        &full_so_path[double_slash_pos + 1],
                                        false);
                                    if (so_dir.Exists()) {
                                      // 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 == NULL) {
        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 = NULL;

        if (have_strtab_data) {
          symbol_name = strtab_data.PeekCStr(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: 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 = NULL;
        } 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 = NULL;

        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 == 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 (!so_dir.Exists()) {
                      so_dir.SetFile(&full_so_path[double_slash_pos + 1],
                                     false);
                      if (so_dir.Exists()) {
                        // 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 = NULL;
                }
              }
              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 == 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 {
                // 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 (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 == false)
          ++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 == false) {
            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 = NULL;
                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 = NULL; // 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(header_arch);

    *s << ", file = '" << m_file
       << "', arch = " << header_arch.GetArchitectureName() << "\n";

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

    if (m_symtab_ap.get())
      m_symtab_ap->Dump(s, NULL, eSortOrderNone);
  }
}

bool ObjectFileMachO::GetUUID(const llvm::MachO::mach_header &header,
                              const lldb_private::DataExtractor &data,
                              lldb::offset_t lc_offset,
                              lldb_private::UUID &uuid) {
  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) == NULL)
      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 false;

        uuid.SetBytes(uuid_bytes);
        return true;
      }
      return false;
    }
    offset = cmd_offset + load_cmd.cmdsize;
  }
  return false;
}

bool 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 true;
    } else {
      struct load_command load_cmd;

      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) == NULL)
          break;

        switch (load_cmd.cmd) {
        case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
          triple.setOS(llvm::Triple::IOS);
          return true;

        case llvm::MachO::LC_VERSION_MIN_MACOSX:
          triple.setOS(llvm::Triple::MacOSX);
          return true;

        case llvm::MachO::LC_VERSION_MIN_TVOS:
          triple.setOS(llvm::Triple::TvOS);
          return true;

        case llvm::MachO::LC_VERSION_MIN_WATCHOS:
          triple.setOS(llvm::Triple::WatchOS);
          return true;

        default:
          break;
        }

        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.IsValid();
}

bool ObjectFileMachO::GetUUID(lldb_private::UUID *uuid) {
  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, *uuid);
  }
  return false;
}

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;
    const bool resolve_path = false; // Don't resolve the dependent file paths
                                     // since they may not reside on this system
    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) == NULL)
        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, resolve_path);
              if (files.AppendIfUnique(file_spec))
                count++;
            }
          }
        }
      } break;

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

    FileSpec this_file_spec(m_file);
    this_file_spec.ResolvePath();
    
    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, true);
          // Remove any redundant parts of the path (like "../foo") since
          // LC_RPATH values often contain "..".
          file_spec = file_spec.GetNormalizedPath();
          if (file_spec.Exists() && 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);
        file_spec = file_spec.GetNormalizedPath();
        if (file_spec.Exists() && files.AppendIfUnique(file_spec)) {
          count++;
          break;
        }
      }
    }
  }
  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) == NULL)
        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::GetHeaderAddress() {
  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) == NULL)
          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) == NULL)
          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) == NULL)
        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) == NULL)
          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.SetBytes (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.reset(new RegisterContextDarwin_arm64_Mach(thread, data));
        break;

      case llvm::MachO::CPU_TYPE_ARM:
        reg_ctx_sp.reset(new RegisterContextDarwin_arm_Mach(thread, data));
        break;

      case llvm::MachO::CPU_TYPE_I386:
        reg_ctx_sp.reset(new RegisterContextDarwin_i386_Mach(thread, data));
        break;

      case llvm::MachO::CPU_TYPE_X86_64:
        reg_ctx_sp.reset(new 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.
      UUID uuid;
      if (GetUUID(&uuid)) {
        // 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.
    UUID uuid;
    if (GetUUID(&uuid)) {
      // 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;
}

uint32_t ObjectFileMachO::GetVersion(uint32_t *versions,
                                     uint32_t num_versions) {
  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) == NULL)
        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) == NULL)
            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) {
      if (versions != NULL && num_versions > 0) {
        if (num_versions > 0)
          versions[0] = (version & 0xFFFF0000ull) >> 16;
        if (num_versions > 1)
          versions[1] = (version & 0x0000FF00ull) >> 8;
        if (num_versions > 2)
          versions[2] = (version & 0x000000FFull);
        // Fill in an remaining version numbers with invalid values
        for (i = 3; i < num_versions; ++i)
          versions[i] = UINT32_MAX;
      }
      // The LC_ID_DYLIB load command has a version with 3 version numbers
      // in it, so always return 3
      return 3;
    }
  }
  return false;
}

bool ObjectFileMachO::GetArchitecture(ArchSpec &arch) {
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
    return GetArchitecture(m_header, m_data,
                           MachHeaderSizeFromMagic(m_header.magic), arch);
  }
  return false;
}

UUID ObjectFileMachO::GetProcessSharedCacheUUID(Process *process) {
  UUID uuid;
  if (process && process->GetDynamicLoader()) {
    DynamicLoader *dl = process->GetDynamicLoader();
    addr_t load_address;
    LazyBool using_shared_cache;
    LazyBool private_shared_cache;
    dl->GetSharedCacheInformation(load_address, uuid, using_shared_cache,
                                  private_shared_cache);
  }
  return uuid;
}

UUID ObjectFileMachO::GetLLDBSharedCacheUUID() {
  UUID uuid;
#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>
        } else {
          sharedCacheUUID_address =
              (uuid_t *)((uint8_t *)dyld_all_image_infos_address +
                         84); // sharedCacheUUID <mach-o/dyld_images.h>
        }
        uuid.SetBytes(sharedCacheUUID_address);
      }
    }
  }
#endif
  return uuid;
}

uint32_t ObjectFileMachO::GetMinimumOSVersion(uint32_t *versions,
                                              uint32_t num_versions) {
  if (m_min_os_versions.empty()) {
    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
    bool success = false;
    for (uint32_t i = 0; success == false && 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) == NULL)
        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_versions.push_back(xxxx);
            m_min_os_versions.push_back(yy);
            m_min_os_versions.push_back(zz);
          }
          success = true;
        }
      }
      offset = load_cmd_offset + lc.cmdsize;
    }

    if (success == false) {
      // Push an invalid value so we don't keep trying to
      m_min_os_versions.push_back(UINT32_MAX);
    }
  }

  if (m_min_os_versions.size() > 1 || m_min_os_versions[0] != UINT32_MAX) {
    if (versions != NULL && num_versions > 0) {
      for (size_t i = 0; i < num_versions; ++i) {
        if (i < m_min_os_versions.size())
          versions[i] = m_min_os_versions[i];
        else
          versions[i] = 0;
      }
    }
    return m_min_os_versions.size();
  }
  // Call the superclasses version that will empty out the data
  return ObjectFile::GetMinimumOSVersion(versions, num_versions);
}

uint32_t ObjectFileMachO::GetSDKVersion(uint32_t *versions,
                                        uint32_t num_versions) {
  if (m_sdk_versions.empty()) {
    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
    bool success = false;
    for (uint32_t i = 0; success == false && 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) == NULL)
        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.push_back(xxxx);
            m_sdk_versions.push_back(yy);
            m_sdk_versions.push_back(zz);
          }
          success = true;
        }
      }
      offset = load_cmd_offset + lc.cmdsize;
    }

    if (success == false) {
      // Push an invalid value so we don't keep trying to
      m_sdk_versions.push_back(UINT32_MAX);
    }
  }

  if (m_sdk_versions.size() > 1 || m_sdk_versions[0] != UINT32_MAX) {
    if (versions != NULL && num_versions > 0) {
      for (size_t i = 0; i < num_versions; ++i) {
        if (i < m_sdk_versions.size())
          versions[i] = m_sdk_versions[i];
        else
          versions[i] = 0;
      }
    }
    return m_sdk_versions.size();
  }
  // Call the superclasses version that will empty out the data
  return ObjectFile::GetSDKVersion(versions, num_versions);
}

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) {
    SectionList *section_list = GetSectionList();
    if (section_list) {
      lldb::addr_t mach_base_file_addr = LLDB_INVALID_ADDRESS;
      const size_t num_sections = section_list->GetSize();

      for (size_t sect_idx = 0; sect_idx < num_sections &&
                                mach_base_file_addr == LLDB_INVALID_ADDRESS;
           ++sect_idx) {
        Section *section = section_list->GetSectionAtIndex(sect_idx).get();
        if (section && section->GetFileSize() > 0 &&
            section->GetFileOffset() == 0 &&
            section->IsThreadSpecific() == false &&
            module_sp.get() == section->GetModule().get()) {
          return section;
        }
      }
    }
  }
  return nullptr;
}

lldb::addr_t ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage(
    lldb::addr_t mach_header_load_address, const Section *mach_header_section,
    const Section *section) {
  ModuleSP module_sp = GetModule();
  if (module_sp && mach_header_section && section &&
      mach_header_load_address != LLDB_INVALID_ADDRESS) {
    lldb::addr_t mach_header_file_addr = mach_header_section->GetFileAddress();
    if (mach_header_file_addr != LLDB_INVALID_ADDRESS) {
      if (section && section->GetFileSize() > 0 &&
          section->IsThreadSpecific() == false &&
          module_sp.get() == section->GetModule().get()) {
        // Ignore __LINKEDIT and __DWARF segments
        if (section->GetName() == GetSegmentNameLINKEDIT()) {
          // Only map __LINKEDIT 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 LLDB_INVALID_ADDRESS;
        }
        return section->GetFileAddress() - mach_header_file_addr +
               mach_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 (section_sp && section_sp->GetFileSize() > 0 &&
              section_sp->IsThreadSpecific() == false &&
              module_sp.get() == section_sp->GetModule().get()) {
            // Ignore __LINKEDIT and __DWARF segments
            if (section_sp->GetName() == GetSegmentNameLINKEDIT()) {
              // Only map __LINKEDIT 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)
                continue;
            }
            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)) {
      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;

            //                        printf ("[%3u] [0x%16.16" PRIx64 " -
            //                        0x%16.16" PRIx64 ") %c%c%c\n",
            //                                range_info_idx,
            //                                addr,
            //                                size,
            //                                (prot & VM_PROT_READ   ) ? 'r' :
            //                                '-',
            //                                (prot & VM_PROT_WRITE  ) ? 'w' :
            //                                '-',
            //                                (prot & VM_PROT_EXECUTE) ? 'x' :
            //                                '-');

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

          printf("mach_header: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x "
                 "0x%8.8x 0x%8.8x\n",
                 mach_header.magic, mach_header.cputype, mach_header.cpusubtype,
                 mach_header.filetype, mach_header.ncmds,
                 mach_header.sizeofcmds, mach_header.flags,
                 mach_header.reserved);

          // 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 = core_file.Open(core_file_path.c_str(),
                                 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;
                  const size_t bytes_read = process_sp->ReadMemory(
                      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;
}
