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

#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/StringRef.h"

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

#include "lldb/Host/SafeMachO.h"

#include "llvm/ADT/DenseSet.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/MemoryBuffer.h"

#include "MachOTrie.h"
#include "ObjectFileMachO.h"

#if defined(__APPLE__)
#include <TargetConditionals.h>
// GetLLDBSharedCacheUUID() needs to call dlsym()
#include <dlfcn.h>
#include <mach/mach_init.h>
#include <mach/vm_map.h>
#include <lldb/Host/SafeMachO.h>
#endif

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

#include <bitset>
#include <memory>
#include <optional>

// Unfortunately the signpost header pulls in the system MachO header, too.
#ifdef CPU_TYPE_ARM
#undef CPU_TYPE_ARM
#endif
#ifdef CPU_TYPE_ARM64
#undef CPU_TYPE_ARM64
#endif
#ifdef CPU_TYPE_ARM64_32
#undef CPU_TYPE_ARM64_32
#endif
#ifdef CPU_TYPE_X86_64
#undef CPU_TYPE_X86_64
#endif
#ifdef MH_DYLINKER
#undef MH_DYLINKER
#endif
#ifdef MH_OBJECT
#undef MH_OBJECT
#endif
#ifdef LC_VERSION_MIN_MACOSX
#undef LC_VERSION_MIN_MACOSX
#endif
#ifdef LC_VERSION_MIN_IPHONEOS
#undef LC_VERSION_MIN_IPHONEOS
#endif
#ifdef LC_VERSION_MIN_TVOS
#undef LC_VERSION_MIN_TVOS
#endif
#ifdef LC_VERSION_MIN_WATCHOS
#undef LC_VERSION_MIN_WATCHOS
#endif
#ifdef LC_BUILD_VERSION
#undef LC_BUILD_VERSION
#endif
#ifdef PLATFORM_MACOS
#undef PLATFORM_MACOS
#endif
#ifdef PLATFORM_MACCATALYST
#undef PLATFORM_MACCATALYST
#endif
#ifdef PLATFORM_IOS
#undef PLATFORM_IOS
#endif
#ifdef PLATFORM_IOSSIMULATOR
#undef PLATFORM_IOSSIMULATOR
#endif
#ifdef PLATFORM_TVOS
#undef PLATFORM_TVOS
#endif
#ifdef PLATFORM_TVOSSIMULATOR
#undef PLATFORM_TVOSSIMULATOR
#endif
#ifdef PLATFORM_WATCHOS
#undef PLATFORM_WATCHOS
#endif
#ifdef PLATFORM_WATCHOSSIMULATOR
#undef PLATFORM_WATCHOSSIMULATOR
#endif

using namespace lldb;
using namespace lldb_private;
using namespace llvm::MachO;

static constexpr llvm::StringLiteral g_loader_path = "@loader_path";
static constexpr llvm::StringLiteral g_executable_path = "@executable_path";

LLDB_PLUGIN_DEFINE(ObjectFileMachO)

/// Read a Mach-O load-command header (cmd + cmdsize) from \p data at
/// \p offset into \p cmd, advancing \p offset by 8 bytes.  \p T may be
/// \c llvm::MachO::load_command or any of its richer variants
/// (\c thread_command, \c dylib_command, \c encryption_info_command, ...);
/// only the leading cmd/cmdsize fields are touched by this read.  Returns
/// false on EOF or on a cmdsize smaller than sizeof(load_command), in which
/// case callers should break out of their load-command loop to avoid spinning
/// on malformed input.
template <typename T>
static bool ReadMachOCommand(const DataExtractor &data, lldb::offset_t &offset,
                             T &cmd) {
  static_assert(offsetof(T, cmd) == 0, "T::cmd must be the first field");
  static_assert(offsetof(T, cmdsize) == sizeof(uint32_t),
                "T::cmdsize must immediately follow T::cmd");
  static_assert(std::is_same<decltype(T::cmd), uint32_t>::value,
                "T::cmd must be uint32_t");
  static_assert(std::is_same<decltype(T::cmdsize), uint32_t>::value,
                "T::cmdsize must be uint32_t");
  if (data.GetU32(&offset, &cmd, 2) == nullptr)
    return false;
  if (cmd.cmdsize < sizeof(load_command))
    return false;
  return true;
}

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

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

    while (offset < data.GetByteSize()) {
      int flavor = data.GetU32(&offset);
      if (flavor == 0)
        break;
      uint32_t count = data.GetU32(&offset);
      switch (flavor) {
      case GPRRegSet: {
        uint32_t *gpr_data = reinterpret_cast<uint32_t *>(&gpr.rax);
        for (uint32_t i = 0; i < count && offset < data.GetByteSize(); ++i)
          gpr_data[i] = data.GetU32(&offset);
        SetError(GPRRegSet, Read, 0);
      } break;
      case FPURegSet:
        // TODO: fill in FPU regs....
        SetError(FPURegSet, Read, -1);
        break;
      case EXCRegSet:
        exc.trapno = data.GetU32(&offset);
        exc.err = data.GetU32(&offset);
        exc.faultvaddr = data.GetU64(&offset);
        SetError(EXCRegSet, Read, 0);
        break;
      default:
        offset += count * 4;
        break;
      }
    }
  }

  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);
      PrintRegisterValue(reg_ctx, "rax", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "rbx", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "rcx", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "rdx", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "rdi", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "rsi", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "rbp", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "rsp", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "r8", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "r9", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "r10", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "r11", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "r12", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "r13", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "r14", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "r15", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "rip", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "rflags", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "cs", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "fs", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "gs", nullptr, 8, data);

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

      // Write out the EXC registers
      data.PutHex32(EXCRegSet);
      data.PutHex32(EXCWordCount);
      PrintRegisterValue(reg_ctx, "trapno", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "err", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "faultvaddr", nullptr, 8, 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 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);

    while (offset < data.GetByteSize()) {
      int flavor = data.GetU32(&offset);
      uint32_t count = data.GetU32(&offset);
      offset_t next_thread_state = offset + (count * 4);
      switch (flavor) {
      case GPRAltRegSet:
      case GPRRegSet: {
        // r0-r15, plus CPSR
        uint32_t gpr_buf_count = (sizeof(gpr.r) / sizeof(gpr.r[0])) + 1;
        if (count == gpr_buf_count) {
          for (uint32_t i = 0; i < (count - 1); ++i) {
            gpr.r[i] = data.GetU32(&offset);
          }
          gpr.cpsr = data.GetU32(&offset);

          SetError(GPRRegSet, Read, 0);
        }
      } break;

      case FPURegSet: {
        uint8_t *fpu_reg_buf = (uint8_t *)&fpu.floats;
        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);
        }
      } 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);
        }
        break;
      }
      offset = next_thread_state;
    }
  }

  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);
      PrintRegisterValue(reg_ctx, "r0", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "r1", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "r2", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "r3", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "r4", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "r5", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "r6", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "r7", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "r8", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "r9", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "r10", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "r11", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "r12", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "sp", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "lr", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "pc", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "cpsr", nullptr, 4, data);

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

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

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

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

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

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

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

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

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

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

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

  void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {
    lldb::offset_t offset = 0;
    SetError(GPRRegSet, Read, -1);
    SetError(FPURegSet, Read, -1);
    SetError(EXCRegSet, Read, -1);
    while (offset < data.GetByteSize()) {
      int flavor = data.GetU32(&offset);
      uint32_t count = data.GetU32(&offset);
      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);
        }
        break;
      case FPURegSet: {
        uint8_t *fpu_reg_buf = (uint8_t *)&fpu.v[0];
        const int fpu_reg_buf_size = sizeof(fpu);
        if (fpu_reg_buf_size == count * sizeof(uint32_t) &&
            data.ExtractBytes(offset, fpu_reg_buf_size, eByteOrderLittle,
                              fpu_reg_buf) == fpu_reg_buf_size) {
          SetError(FPURegSet, Read, 0);
        }
      } 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);
        }
        break;
      }
      offset = next_thread_state;
    }
  }

  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);
      PrintRegisterValue(reg_ctx, "x0", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x1", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x2", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x3", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x4", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x5", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x6", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x7", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x8", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x9", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x10", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x11", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x12", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x13", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x14", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x15", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x16", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x17", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x18", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x19", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x20", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x21", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x22", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x23", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x24", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x25", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x26", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x27", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "x28", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "fp", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "lr", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "sp", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "pc", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "cpsr", nullptr, 4, data);
      data.PutHex32(0); // uint32_t pad at the end

      // Write out the EXC registers
      data.PutHex32(EXCRegSet);
      data.PutHex32(EXCWordCount);
      PrintRegisterValue(reg_ctx, "far", nullptr, 8, data);
      PrintRegisterValue(reg_ctx, "esr", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "exception", nullptr, 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_riscv32_Mach
    : public RegisterContextDarwin_riscv32 {
public:
  RegisterContextDarwin_riscv32_Mach(lldb_private::Thread &thread,
                                     const DataExtractor &data)
      : RegisterContextDarwin_riscv32(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);
    SetError(CSRRegSet, Read, -1);
    while (offset < data.GetByteSize()) {
      int flavor = data.GetU32(&offset);
      uint32_t count = data.GetU32(&offset);
      offset_t next_thread_state = offset + (count * 4);
      switch (flavor) {
      case GPRRegSet:
        // x0-x31 + pc
        if (count >= 32) {
          for (uint32_t i = 0; i < 32; ++i)
            ((uint32_t *)&gpr.x0)[i] = data.GetU32(&offset);
          gpr.pc = data.GetU32(&offset);
          SetError(GPRRegSet, Read, 0);
        }
        break;
      case FPURegSet: {
        // f0-f31 + fcsr
        if (count >= 32) {
          for (uint32_t i = 0; i < 32; ++i)
            ((uint32_t *)&fpr.f0)[i] = data.GetU32(&offset);
          fpr.fcsr = data.GetU32(&offset);
          SetError(FPURegSet, Read, 0);
        }
      } 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);
        }
        break;
      }
      offset = next_thread_state;
    }
  }

  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);
      PrintRegisterValue(reg_ctx, "x0", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x1", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x2", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x3", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x4", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x5", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x6", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x7", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x8", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x9", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x10", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x11", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x12", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x13", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x14", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x15", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x16", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x17", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x18", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x19", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x20", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x21", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x22", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x23", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x24", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x25", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x26", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x27", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x28", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x29", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x30", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "x31", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "pc", nullptr, 4, data);
      data.PutHex32(0); // uint32_t pad at the end

      // Write out the EXC registers
      data.PutHex32(EXCRegSet);
      data.PutHex32(EXCWordCount);
      PrintRegisterValue(reg_ctx, "exception", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "fsr", nullptr, 4, data);
      PrintRegisterValue(reg_ctx, "far", nullptr, 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 DoReadCSR(lldb::tid_t tid, int flavor, CSR &csr) 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 DoWriteCSR(lldb::tid_t tid, int flavor, const CSR &csr) override {
    return 0;
  }
};

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

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

  default:
    break;
  }
  return 0;
}

#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008

char ObjectFileMachO::ID;

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

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

ObjectFile *ObjectFileMachO::CreateInstance(const lldb::ModuleSP &module_sp,
                                            DataExtractorSP extractor_sp,
                                            lldb::offset_t data_offset,
                                            const FileSpec *file,
                                            lldb::offset_t file_offset,
                                            lldb::offset_t length) {
  if (!extractor_sp || !extractor_sp->HasData()) {
    DataBufferSP data_sp = MapFileData(*file, length, file_offset);
    if (!data_sp)
      return nullptr;
    data_offset = 0;
    extractor_sp = std::make_shared<DataExtractor>(data_sp);
  }

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

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

  return objfile_up.release();
}

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

ModuleSpecList ObjectFileMachO::GetModuleSpecifications(
    const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp,
    lldb::offset_t file_offset, lldb::offset_t length) {
  if (!extractor_sp || !extractor_sp->HasData())
    return {};

  ModuleSpecList specs;
  if (ObjectFileMachO::MagicBytesMatch(extractor_sp, 0,
                                       extractor_sp->GetByteSize())) {
    llvm::MachO::mach_header header;
    offset_t data_offset = 0;
    if (ParseHeader(extractor_sp, &data_offset, header)) {
      size_t header_and_load_cmds =
          header.sizeofcmds + MachHeaderSizeFromMagic(header.magic);
      if (header_and_load_cmds >= extractor_sp->GetByteSize()) {
        DataBufferSP file_data_sp =
            MapFileData(file, header_and_load_cmds, file_offset);
        if (file_data_sp)
          extractor_sp->SetData(file_data_sp);
        data_offset = MachHeaderSizeFromMagic(header.magic);
      }
      if (extractor_sp && extractor_sp->HasData()) {
        ModuleSpec base_spec;
        base_spec.GetFileSpec() = file;
        base_spec.SetObjectOffset(file_offset);
        base_spec.SetObjectSize(length);
        GetAllArchSpecs(header, *extractor_sp, data_offset, base_spec, specs);
      }
    }
  }
  return specs;
}

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

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

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

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

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

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

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

ConstString ObjectFileMachO::GetSegmentNameLLVM_COV() {
  static ConstString g_section_name("__LLVM_COV");
  return g_section_name;
}

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

ConstString ObjectFileMachO::GetSectionNameLLDBNoNlist() {
  static ConstString g_section_name_lldb_no_nlist("__lldb_no_nlist");
  return g_section_name_lldb_no_nlist;
}

bool ObjectFileMachO::MagicBytesMatch(DataExtractorSP extractor_sp,
                                      lldb::addr_t data_offset,
                                      lldb::addr_t data_length) {
  lldb::offset_t offset = data_offset;
  uint32_t magic = extractor_sp->GetU32(&offset);

  offset += 4; // cputype
  offset += 4; // cpusubtype
  uint32_t filetype = extractor_sp->GetU32(&offset);

  // A fileset has a Mach-O header but is not an
  // individual file and must be handled via an
  // ObjectContainer plugin.
  if (filetype == llvm::MachO::MH_FILESET)
    return false;

  return MachHeaderSizeFromMagic(magic) != 0;
}

ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
                                 DataExtractorSP extractor_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, extractor_sp,
                 data_offset),
      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::WritableDataBufferSP header_data_sp,
                                 const lldb::ProcessSP &process_sp,
                                 lldb::addr_t header_addr)
    : ObjectFile(module_sp, process_sp, header_addr,
                 std::make_shared<DataExtractor>(header_data_sp)),
      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(DataExtractorSP &extractor_sp,
                                  lldb::offset_t *data_offset_ptr,
                                  llvm::MachO::mach_header &header) {
  extractor_sp->SetByteOrder(endian::InlHostByteOrder());
  // Leave magic in the original byte order
  header.magic = extractor_sp->GetU32(data_offset_ptr);
  bool can_parse = false;
  bool is_64_bit = false;
  switch (header.magic) {
  case MH_MAGIC:
    extractor_sp->SetByteOrder(endian::InlHostByteOrder());
    extractor_sp->SetAddressByteSize(4);
    can_parse = true;
    break;

  case MH_MAGIC_64:
    extractor_sp->SetByteOrder(endian::InlHostByteOrder());
    extractor_sp->SetAddressByteSize(8);
    can_parse = true;
    is_64_bit = true;
    break;

  case MH_CIGAM:
    extractor_sp->SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
                                   ? eByteOrderLittle
                                   : eByteOrderBig);
    extractor_sp->SetAddressByteSize(4);
    can_parse = true;
    break;

  case MH_CIGAM_64:
    extractor_sp->SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
                                   ? eByteOrderLittle
                                   : eByteOrderBig);
    extractor_sp->SetAddressByteSize(8);
    is_64_bit = true;
    can_parse = true;
    break;

  default:
    break;
  }

  if (can_parse) {
    extractor_sp->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)
    return false;

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

  case MH_MAGIC_64:
    m_data_nsp->SetByteOrder(endian::InlHostByteOrder());
    m_data_nsp->SetAddressByteSize(8);
    can_parse = true;
    break;

  case MH_CIGAM:
    m_data_nsp->SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
                                 ? eByteOrderLittle
                                 : eByteOrderBig);
    m_data_nsp->SetAddressByteSize(4);
    can_parse = true;
    break;

  case MH_CIGAM_64:
    m_data_nsp->SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
                                 ? eByteOrderLittle
                                 : eByteOrderBig);
    m_data_nsp->SetAddressByteSize(8);
    can_parse = true;
    break;

  default:
    break;
  }

  if (can_parse) {
    m_data_nsp->GetU32(&offset, &m_header.cputype, 6);

    ModuleSpecList all_specs;
    ModuleSpec base_spec;
    GetAllArchSpecs(m_header, *m_data_nsp,
                    MachHeaderSizeFromMagic(m_header.magic), base_spec,
                    all_specs);

    for (unsigned i = 0, e = all_specs.GetSize(); i != e; ++i) {
      ArchSpec mach_arch =
          all_specs.GetModuleSpecRefAtIndex(i).GetArchitecture();

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

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

ByteOrder ObjectFileMachO::GetByteOrder() const {
  return m_data_nsp->GetByteOrder();
}

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

bool ObjectFileMachO::IsDynamicLoader() const {
  return m_header.filetype == MH_DYLINKER;
}

bool ObjectFileMachO::IsSharedCacheBinary() const {
  return m_header.flags & MH_DYLIB_IN_CACHE;
}

bool ObjectFileMachO::IsKext() const {
  return m_header.filetype == MH_KEXT_BUNDLE;
}

uint32_t ObjectFileMachO::GetAddressByteSize() const {
  return m_data_nsp->GetAddressByteSize();
}

AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) {
  Symtab *symtab = GetSymtab();
  if (!symtab)
    return AddressClass::eUnknown;

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

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

        case eSectionTypeContainer:
          return AddressClass::eUnknown;

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

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

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

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

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

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

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

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;

        llvm::MachO::load_command lc = {};
        if (!ReadMachOCommand(*m_data_nsp, offset, lc))
          break;
        if (lc.cmd == LC_DYSYMTAB) {
          m_dysymtab.cmd = lc.cmd;
          m_dysymtab.cmdsize = lc.cmdsize;
          if (m_data_nsp->GetU32(&offset, &m_dysymtab.ilocalsym,
                                 (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2) ==
              nullptr) {
            // Clear m_dysymtab if we were unable to read all items from the
            // load command
            ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));
          }
        }
        offset = load_cmd_offset + lc.cmdsize;
      }
    }
  }
  if (m_dysymtab.cmd)
    return m_dysymtab.nlocalsym <= 1;
  return false;
}

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

  llvm::MachO::encryption_info_command encryption_cmd;
  for (uint32_t i = 0; i < m_header.ncmds; ++i) {
    const lldb::offset_t load_cmd_offset = offset;
    if (!ReadMachOCommand(*m_data_nsp, offset, encryption_cmd))
      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_nsp->GetU32(&offset, &encryption_cmd.cryptoff, 3)) {
        if (encryption_cmd.cryptid != 0) {
          EncryptedFileRanges::Entry entry;
          entry.SetRangeBase(encryption_cmd.cryptoff);
          entry.SetByteSize(encryption_cmd.cryptsize);
          result.Append(entry);
        }
      }
    }
    offset = load_cmd_offset + encryption_cmd.cmdsize;
  }

  return result;
}

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

  if (IsSharedCacheBinary() && !IsInMemory()) {
    // In shared cache images, the load commands are relative to the
    // shared cache file, and not the specific image we are
    // examining. Let's fix this up so that it looks like a normal
    // image.
    if (strncmp(seg_cmd.segname, GetSegmentNameTEXT().GetCString(),
                sizeof(seg_cmd.segname)) == 0)
      m_text_address = seg_cmd.vmaddr;
    if (strncmp(seg_cmd.segname, GetSegmentNameLINKEDIT().GetCString(),
                sizeof(seg_cmd.segname)) == 0)
      m_linkedit_original_offset = seg_cmd.fileoff;

    seg_cmd.fileoff = seg_cmd.vmaddr - m_text_address;
  }

  if (seg_cmd.fileoff > m_length) {
    // We have a load command that says it extends past the end of the file.
    // This is likely a corrupt file.  We don't have any way to return an error
    // condition here (this method was likely invoked from something like
    // ObjectFile::GetSectionList()), so we just null out the section contents,
    // and dump a message to stdout.  The most common case here is core file
    // debugging with a truncated file.
    const char *lc_segment_name =
        seg_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
    GetModule()->ReportWarning(
        "load command {0} {1} has a fileoff ({2:x16}) that extends beyond "
        "the end of the file ({3:x16}), ignoring this section",
        cmd_idx, lc_segment_name, seg_cmd.fileoff, m_length);

    seg_cmd.fileoff = 0;
    seg_cmd.filesize = 0;
  }

  if (seg_cmd.fileoff + seg_cmd.filesize > m_length) {
    // We have a load command that says it extends past the end of the file.
    // This is likely a corrupt file.  We don't have any way to return an error
    // condition here (this method was likely invoked from something like
    // ObjectFile::GetSectionList()), so we just null out the section contents,
    // and dump a message to stdout.  The most common case here is core file
    // debugging with a truncated file.
    const char *lc_segment_name =
        seg_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
    GetModule()->ReportWarning(
        "load command {0} {1} has a fileoff + filesize ({2:x16}) that "
        "extends beyond the end of the file ({3:x16}), the segment will be "
        "truncated to match",
        cmd_idx, lc_segment_name, seg_cmd.fileoff + seg_cmd.filesize, m_length);

    // Truncate the length
    seg_cmd.filesize = m_length - seg_cmd.fileoff;
  }
}

static uint32_t
GetSegmentPermissions(const llvm::MachO::segment_command_64 &seg_cmd) {
  uint32_t result = 0;
  if (seg_cmd.initprot & VM_PROT_READ)
    result |= ePermissionsReadable;
  if (seg_cmd.initprot & VM_PROT_WRITE)
    result |= ePermissionsWritable;
  if (seg_cmd.initprot & VM_PROT_EXECUTE)
    result |= ePermissionsExecutable;
  return result;
}

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

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

  uint32_t mach_sect_type = flags & SECTION_TYPE;
  static ConstString g_sect_name_objc_data("__objc_data");
  static ConstString g_sect_name_objc_msgrefs("__objc_msgrefs");
  static ConstString g_sect_name_objc_selrefs("__objc_selrefs");
  static ConstString g_sect_name_objc_classrefs("__objc_classrefs");
  static ConstString g_sect_name_objc_superrefs("__objc_superrefs");
  static ConstString g_sect_name_objc_const("__objc_const");
  static ConstString g_sect_name_objc_classlist("__objc_classlist");
  static ConstString g_sect_name_cfstring("__cfstring");

  static ConstString g_sect_name_dwarf_debug_str_offs("__debug_str_offs");
  static ConstString g_sect_name_dwarf_debug_str_offs_dwo("__debug_str_offs.dwo");
  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");
  static ConstString g_sect_name_ctf("__ctf");
  static ConstString g_sect_name_lldb_summaries("__lldbsummaries");
  static ConstString g_sect_name_lldb_formatters("__lldbformatters");
  static ConstString g_sect_name_swift_ast("__swift_ast");

  if (section_name == g_sect_name_dwarf_debug_str_offs)
    return eSectionTypeDWARFDebugStrOffsets;
  if (section_name == g_sect_name_dwarf_debug_str_offs_dwo)
    return eSectionTypeDWARFDebugStrOffsetsDwo;

  llvm::StringRef stripped_name = section_name.GetStringRef();
  if (stripped_name.consume_front("__debug_"))
    return ObjectFile::GetDWARFSectionTypeFromName(stripped_name);

  if (section_name == g_sect_name_dwarf_apple_names)
    return eSectionTypeDWARFAppleNames;
  if (section_name == g_sect_name_dwarf_apple_types)
    return eSectionTypeDWARFAppleTypes;
  if (section_name == g_sect_name_dwarf_apple_namespaces)
    return eSectionTypeDWARFAppleNamespaces;
  if (section_name == g_sect_name_dwarf_apple_objc)
    return eSectionTypeDWARFAppleObjC;
  if (section_name == g_sect_name_objc_selrefs)
    return eSectionTypeDataCStringPointers;
  if (section_name == g_sect_name_objc_msgrefs)
    return eSectionTypeDataObjCMessageRefs;
  if (section_name == g_sect_name_eh_frame)
    return eSectionTypeEHFrame;
  if (section_name == g_sect_name_compact_unwind)
    return eSectionTypeCompactUnwind;
  if (section_name == g_sect_name_cfstring)
    return eSectionTypeDataObjCCFStrings;
  if (section_name == g_sect_name_go_symtab)
    return eSectionTypeGoSymtab;
  if (section_name == g_sect_name_ctf)
    return eSectionTypeCTF;
  if (section_name == g_sect_name_lldb_summaries)
    return lldb::eSectionTypeLLDBTypeSummaries;
  if (section_name == g_sect_name_lldb_formatters)
    return lldb::eSectionTypeLLDBFormatters;
  if (section_name == g_sect_name_swift_ast)
    return eSectionTypeSwiftModules;
  if (section_name == g_sect_name_objc_data ||
      section_name == g_sect_name_objc_classrefs ||
      section_name == g_sect_name_objc_superrefs ||
      section_name == g_sect_name_objc_const ||
      section_name == g_sect_name_objc_classlist) {
    return eSectionTypeDataPointers;
  }

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

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

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

void ObjectFileMachO::ProcessSegmentCommand(
    const llvm::MachO::load_command &load_cmd_, lldb::offset_t offset,
    uint32_t cmd_idx, SegmentParsingContext &context) {
  llvm::MachO::segment_command_64 load_cmd;
  memcpy(&load_cmd, &load_cmd_, sizeof(load_cmd_));

  if (!m_data_nsp->GetU8(&offset, (uint8_t *)load_cmd.segname, 16))
    return;

  ModuleSP module_sp = GetModule();
  const bool is_core = GetType() == eTypeCoreFile;
  const bool is_dsym = (m_header.filetype == MH_DSYM);
  bool add_section = true;
  bool add_to_unified = true;
  ConstString const_segname(
      load_cmd.segname, strnlen(load_cmd.segname, sizeof(load_cmd.segname)));

  SectionSP unified_section_sp(
      context.UnifiedList.FindSectionByName(const_segname));
  if (is_dsym && unified_section_sp) {
    if (const_segname == GetSegmentNameLINKEDIT()) {
      // We need to keep the __LINKEDIT segment private to this object file
      // only
      add_to_unified = false;
    } else {
      // This is the dSYM file and this section has already been created by the
      // object file, no need to create it.
      add_section = false;
    }
  }
  load_cmd.vmaddr = m_data_nsp->GetAddress(&offset);
  load_cmd.vmsize = m_data_nsp->GetAddress(&offset);
  load_cmd.fileoff = m_data_nsp->GetAddress(&offset);
  load_cmd.filesize = m_data_nsp->GetAddress(&offset);
  if (!m_data_nsp->GetU32(&offset, &load_cmd.maxprot, 4))
    return;

  SanitizeSegmentCommand(load_cmd, cmd_idx);

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

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

    segment_sp->SetIsEncrypted(segment_is_encrypted);
    m_sections_up->AddSection(segment_sp);
    segment_sp->SetPermissions(segment_permissions);
    if (add_to_unified)
      context.UnifiedList.AddSection(segment_sp);
  } else if (unified_section_sp) {
    // If this is a dSYM and the file addresses in the dSYM differ from the
    // file addresses in the ObjectFile, we must use the file base address for
    // the Section from the dSYM for the DWARF to resolve correctly.
    // This only happens with binaries in the shared cache in practice;
    // normally a mismatch like this would give a binary & dSYM that do not
    // match UUIDs. When a binary is included in the shared cache, its
    // segments are rearranged to optimize the shared cache, so its file
    // addresses will differ from what the ObjectFile had originally,
    // and what the dSYM has.
    if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr) {
      LLDB_LOG(GetLog(LLDBLog::Symbols),
               "Installing dSYM's {0} segment file address over ObjectFile's "
               "so symbol table/debug info resolves correctly for {1}",
               const_segname.AsCString(""),
               module_sp->GetFileSpec().GetFilename());

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

      unified_section_sp->SetFileAddress(load_cmd.vmaddr);

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

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

  // 64 bit mach-o files have sections with 32 bit file offsets. If any section
  // data end will exceed UINT32_MAX, then we need to do some bookkeeping to
  // ensure we can access this data correctly.
  uint64_t section_offset_adjust = 0;
  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_nsp->GetU8(&offset, (uint8_t *)sect64.sectname,
                          sizeof(sect64.sectname)) == nullptr)
      break;
    if (m_data_nsp->GetU8(&offset, (uint8_t *)sect64.segname,
                          sizeof(sect64.segname)) == nullptr)
      break;
    sect64.addr = m_data_nsp->GetAddress(&offset);
    sect64.size = m_data_nsp->GetAddress(&offset);

    if (m_data_nsp->GetU32(&offset, &sect64.offset, num_u32s) == nullptr)
      break;

    if (IsSharedCacheBinary() && !IsInMemory()) {
      sect64.offset = sect64.addr - m_text_address;
    }

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

    // Make sure we can load sections in mach-o files where some sections cross
    // a 4GB boundary. llvm::MachO::section_64 have only 32 bit file offsets
    // for the file offset of the section contents, so we need to track and
    // sections that overflow and adjust the offsets accordingly.
    const uint64_t section_file_offset =
        (uint64_t)sect64.offset + section_offset_adjust;
    const uint64_t end_section_offset = (uint64_t)sect64.offset + sect64.size;
    if (end_section_offset >= UINT32_MAX)
      section_offset_adjust += end_section_offset & 0xFFFFFFFF00000000ull;

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

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

      lldb::SectionType sect_type = GetSectionType(sect64.flags, section_name);

      SectionSP section_sp = std::make_shared<Section>(
          segment_sp, module_sp, this, ++context.NextSectionIdx, section_name,
          sect_type, sect64.addr - segment_sp->GetFileAddress(), sect64.size,
          section_file_offset, section_file_offset == 0 ? 0 : sect64.size,
          sect64.align, sect64.flags);
      // Set the section to be encrypted to match the segment

      bool section_is_encrypted = false;
      if (!segment_is_encrypted && load_cmd.filesize != 0)
        section_is_encrypted = context.EncryptedRanges.FindEntryThatContains(
                                   section_file_offset) != nullptr;

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

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

        if (curr_section_sp.get()) {
          if (curr_section_sp->GetByteSize() == 0) {
            if (next_section_sp.get() != nullptr)
              curr_section_sp->SetByteSize(next_section_sp->GetFileAddress() -
                                           curr_section_sp->GetFileAddress());
            else
              curr_section_sp->SetByteSize(load_cmd.vmsize);
          }
        }
      }
    }
  }
}

void ObjectFileMachO::ProcessDysymtabCommand(
    const llvm::MachO::load_command &load_cmd, lldb::offset_t offset) {
  m_dysymtab.cmd = load_cmd.cmd;
  m_dysymtab.cmdsize = load_cmd.cmdsize;
  m_data_nsp->GetU32(&offset, &m_dysymtab.ilocalsym,
                     (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
}

void ObjectFileMachO::CreateSections(SectionList &unified_section_list) {
  if (m_sections_up)
    return;

  m_sections_up = std::make_unique<SectionList>();

  lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
  // bool dump_sections = false;
  ModuleSP module_sp(GetModule());

  offset = MachHeaderSizeFromMagic(m_header.magic);

  SegmentParsingContext context(GetEncryptedFileRanges(), unified_section_list);
  llvm::MachO::load_command load_cmd;
  for (uint32_t i = 0; i < m_header.ncmds; ++i) {
    const lldb::offset_t load_cmd_offset = offset;
    if (!ReadMachOCommand(*m_data_nsp, offset, load_cmd))
      break;

    if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)
      ProcessSegmentCommand(load_cmd, offset, i, context);
    else if (load_cmd.cmd == LC_DYSYMTAB)
      ProcessDysymtabCommand(load_cmd, offset);

    offset = load_cmd_offset + load_cmd.cmdsize;
  }

  if (context.FileAddressesChanged && module_sp)
    module_sp->SectionFileAddressesChanged();
}

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

  SectionSP GetSection(uint8_t n_sect, addr_t file_addr) {
    if (n_sect == 0)
      return SectionSP();
    if (n_sect < m_section_infos.size()) {
      if (!m_section_infos[n_sect].section_sp) {
        SectionSP section_sp(m_section_list->FindSectionByID(n_sect));
        m_section_infos[n_sect].section_sp = section_sp;
        if (section_sp) {
          m_section_infos[n_sect].vm_range.SetRangeBase(
              section_sp->GetFileAddress());
          m_section_infos[n_sect].vm_range.SetByteSize(
              section_sp->GetByteSize());
        } else {
          std::string filename = "<unknown>";
          SectionSP first_section_sp(m_section_list->GetSectionAtIndex(0));
          if (first_section_sp)
            filename = first_section_sp->GetObjectFile()->GetFileSpec().GetPath();

          Debugger::ReportError(
              llvm::formatv("unable to find section {0} for a symbol in "
                            "{1}, corrupt file?",
                            n_sect, filename));
        }
      }
      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.GetRangeBase() == 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() {}

    Range<addr_t, addr_t> vm_range;
    SectionSP section_sp;
  };
  SectionList *m_section_list;
  std::vector<SectionInfo> m_section_infos;
};

static bool
TryParseV2ObjCMetadataSymbol(const char *&symbol_name,
                             const char *&symbol_name_non_abi_mangled,
                             SymbolType &type) {
  static constexpr llvm::StringLiteral g_objc_v2_prefix_class("_OBJC_CLASS_$_");
  static constexpr llvm::StringLiteral g_objc_v2_prefix_metaclass(
      "_OBJC_METACLASS_$_");
  static constexpr llvm::StringLiteral g_objc_v2_prefix_ivar("_OBJC_IVAR_$_");

  llvm::StringRef symbol_name_ref(symbol_name);
  if (symbol_name_ref.empty())
    return false;

  if (symbol_name_ref.starts_with(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;
    return true;
  }

  if (symbol_name_ref.starts_with(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;
    return true;
  }

  if (symbol_name_ref.starts_with(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;
    return true;
  }

  return false;
}

static SymbolType GetSymbolType(const char *&symbol_name,
                                bool &demangled_is_synthesized,
                                const SectionSP &text_section_sp,
                                const SectionSP &data_section_sp,
                                const SectionSP &data_dirty_section_sp,
                                const SectionSP &data_const_section_sp,
                                const SectionSP &symbol_section) {
  SymbolType type = eSymbolTypeInvalid;

  llvm::StringRef symbol_sect_name = symbol_section->GetName();
  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.starts_with("__objc")) {
      type = eSymbolTypeRuntime;

      if (symbol_name) {
        llvm::StringRef symbol_name_ref(symbol_name);
        if (symbol_name_ref.starts_with("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.starts_with(g_objc_v2_prefix_class)) {
            symbol_name = symbol_name + g_objc_v2_prefix_class.size();
            type = eSymbolTypeObjCClass;
            demangled_is_synthesized = true;
          } else if (symbol_name_ref.starts_with(g_objc_v2_prefix_metaclass)) {
            symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
            type = eSymbolTypeObjCMetaClass;
            demangled_is_synthesized = true;
          } else if (symbol_name_ref.starts_with(g_objc_v2_prefix_ivar)) {
            symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
            type = eSymbolTypeObjCIVar;
            demangled_is_synthesized = true;
          }
        }
      }
    } else if (symbol_sect_name.starts_with("__gcc_except_tab")) {
      type = eSymbolTypeException;
    } else {
      type = eSymbolTypeData;
    }
  } else if (symbol_sect_name.starts_with("__IMPORT")) {
    type = eSymbolTypeTrampoline;
  }
  return type;
}

static std::optional<struct nlist_64>
ParseNList(DataExtractor &nlist_data, lldb::offset_t &nlist_data_offset,
           size_t nlist_byte_size) {
  struct nlist_64 nlist;
  if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
    return {};
  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);
  return nlist;
}

enum { DebugSymbols = true, NonDebugSymbols = false };

void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
  ModuleSP module_sp(GetModule());
  if (!module_sp)
    return;

  Log *log = GetLog(LLDBLog::Symbols);

  const FileSpec &file = m_file ? m_file : module_sp->GetFileSpec();
  llvm::StringRef file_name = file.GetFilename().nonEmptyOr("<Unknown>");
  LLDB_SCOPED_TIMERF("ObjectFileMachO::ParseSymtab () module = %s",
                     file_name.str().c_str());
  LLDB_LOG(log, "Parsing symbol table for {0}", file_name);
  Progress progress("Parsing symbol table", file_name.str());

  LinkeditDataCommandLargeOffsets function_starts_load_command;
  LinkeditDataCommandLargeOffsets exports_trie_load_command;
  DyldInfoCommandLargeOffsets dyld_info;
  DysymtabCommandLargeOffsets dysymtab(m_dysymtab);
  SymtabCommandLargeOffsets symtab_load_command;
  // The data element of type bool indicates that this entry is thumb
  // code.
  typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;

  // Record the address of every function/data that we add to the symtab.
  // We add symbols to the table in the order of most information (nlist
  // records) to least (function starts), and avoid duplicating symbols
  // via this set.
  llvm::DenseSet<addr_t> symbols_added;

  // We are using a llvm::DenseSet for "symbols_added" so we must be sure we
  // do not add the empty key to the set.
  auto add_symbol_addr = [&symbols_added](lldb::addr_t file_addr) {
    // Don't add the empty key.
    if (file_addr == UINT64_MAX)
      return;
    symbols_added.insert(file_addr);
  };
  FunctionStarts function_starts;
  lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
  uint32_t i;
  FileSpecList dylib_files;
  UUID image_uuid;

  for (i = 0; i < m_header.ncmds; ++i) {
    const lldb::offset_t cmd_offset = offset;
    // Read in the load command and load command size
    llvm::MachO::load_command lc;
    if (!ReadMachOCommand(*m_data_nsp, offset, lc))
      break;
    // Watch for the symbol table load command
    switch (lc.cmd) {
    case LC_SYMTAB: {
      llvm::MachO::symtab_command lc_obj;
      if (m_data_nsp->GetU32(&offset, &lc_obj.symoff, 4)) {
        lc_obj.cmd = lc.cmd;
        lc_obj.cmdsize = lc.cmdsize;
        symtab_load_command = lc_obj;
      }
    } break;

    case LC_DYLD_INFO:
    case LC_DYLD_INFO_ONLY: {
      llvm::MachO::dyld_info_command lc_obj;
      if (m_data_nsp->GetU32(&offset, &lc_obj.rebase_off, 10)) {
        lc_obj.cmd = lc.cmd;
        lc_obj.cmdsize = lc.cmdsize;
        dyld_info = lc_obj;
      }
    } 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_nsp->GetU32(&offset);
      const char *path = m_data_nsp->PeekCStr(name_offset);
      if (path) {
        FileSpec file_spec(path);
        // Strip the path if there is @rpath, @executable, etc so we just use
        // the basename
        if (path[0] == '@')
          file_spec.ClearDirectory();

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

        dylib_files.Append(file_spec);
      }
    } break;

    case LC_DYLD_EXPORTS_TRIE: {
      llvm::MachO::linkedit_data_command lc_obj;
      lc_obj.cmd = lc.cmd;
      lc_obj.cmdsize = lc.cmdsize;
      if (m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
        exports_trie_load_command = lc_obj;
    } break;
    case LC_FUNCTION_STARTS: {
      llvm::MachO::linkedit_data_command lc_obj;
      lc_obj.cmd = lc.cmd;
      lc_obj.cmdsize = lc.cmdsize;
      if (m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
        function_starts_load_command = lc_obj;
    } break;

    case LC_UUID: {
      const uint8_t *uuid_bytes = m_data_nsp->PeekData(offset, 16);

      if (uuid_bytes)
        image_uuid = UUID(uuid_bytes, 16);
      break;
    }

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

  if (!symtab_load_command.cmd)
    return;

  SectionList *section_list = GetSectionList();
  if (section_list == nullptr)
    return;

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

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

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

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

  uint32_t memory_module_load_level = eMemoryModuleLoadLevelComplete;
  bool is_shared_cache_image = IsSharedCacheBinary();
  bool is_local_shared_cache_image = is_shared_cache_image && !IsInMemory();

  ConstString g_segment_name_TEXT = GetSegmentNameTEXT();
  ConstString g_segment_name_DATA = GetSegmentNameDATA();
  ConstString g_segment_name_DATA_DIRTY = GetSegmentNameDATA_DIRTY();
  ConstString g_segment_name_DATA_CONST = GetSegmentNameDATA_CONST();
  ConstString g_segment_name_OBJC = GetSegmentNameOBJC();
  ConstString g_section_name_eh_frame = GetSectionNameEHFrame();
  ConstString g_section_name_lldb_no_nlist = GetSectionNameLLDBNoNlist();
  SectionSP text_section_sp(
      section_list->FindSectionByName(g_segment_name_TEXT));
  SectionSP data_section_sp(
      section_list->FindSectionByName(g_segment_name_DATA));
  SectionSP linkedit_section_sp(
      section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
  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;
  SectionSP lldb_no_nlist_section_sp;
  if (text_section_sp.get()) {
    eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
        g_section_name_eh_frame);
    lldb_no_nlist_section_sp = text_section_sp->GetChildren().FindSectionByName(
        g_section_name_lldb_no_nlist);
  } else {
    eh_frame_section_sp =
        section_list->FindSectionByName(g_section_name_eh_frame);
    lldb_no_nlist_section_sp =
        section_list->FindSectionByName(g_section_name_lldb_no_nlist);
  }

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

    memory_module_load_level = target.GetMemoryModuleLoadLevel();

    // If __TEXT,__lldb_no_nlist section is present in this binary,
    // and we're reading it out of memory, do not read any of the
    // nlist entries.  They are not needed in lldb and it may be
    // expensive to load these.  This is to handle a dylib consisting
    // of only metadata, no code, but it has many nlist entries.
    if (lldb_no_nlist_section_sp)
      memory_module_load_level = eMemoryModuleLoadLevelMinimal;

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

      // Always load dyld - the dynamic linker - from memory if we didn't
      // find a binary anywhere else. lldb will not register
      // dylib/framework/bundle loads/unloads if we don't have the dyld
      // symbols, we force dyld to load from memory despite the user's
      // target.memory-module-load-level setting.
      if (memory_module_load_level == eMemoryModuleLoadLevelComplete ||
          m_header.filetype == llvm::MachO::MH_DYLINKER) {
        DataBufferSP nlist_data_sp(
            ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
        if (nlist_data_sp)
          nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
        if (dysymtab.nindirectsyms != 0) {
          const addr_t indirect_syms_addr = linkedit_load_addr +
                                            dysymtab.indirectsymoff -
                                            linkedit_file_offset;
          DataBufferSP indirect_syms_data_sp(ReadMemory(
              process_sp, indirect_syms_addr, dysymtab.nindirectsyms * 4));
          if (indirect_syms_data_sp)
            indirect_symbol_index_data.SetData(
                indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
          // If this binary is outside the shared cache,
          // cache the string table.
          // Binaries in the shared cache all share a giant string table,
          // and we can't share the string tables across multiple
          // ObjectFileMachO's, so we'd end up re-reading this mega-strtab
          // for every binary in the shared cache - it would be a big perf
          // problem. For binaries outside the shared cache, it's faster to
          // read the entire strtab at once instead of piece-by-piece as we
          // process the nlist records.
          if (!is_shared_cache_image) {
            DataBufferSP strtab_data_sp(
                ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
            if (strtab_data_sp) {
              strtab_data.SetData(strtab_data_sp, 0,
                                  strtab_data_sp->GetByteSize());
            }
          }
        }
        if (memory_module_load_level >= eMemoryModuleLoadLevelPartial) {
          if (function_starts_load_command.cmd) {
            const addr_t func_start_addr =
                linkedit_load_addr + function_starts_load_command.dataoff -
                linkedit_file_offset;
            DataBufferSP func_start_data_sp(
                ReadMemory(process_sp, func_start_addr,
                           function_starts_load_command.datasize));
            if (func_start_data_sp)
              function_starts_data.SetData(func_start_data_sp, 0,
                                           func_start_data_sp->GetByteSize());
          }
        }
      }
    }
  } else {
    if (is_local_shared_cache_image && linkedit_section_sp) {
      // The load commands in shared cache images are relative to the
      // beginning of the shared cache, not the library image. The
      // data we get handed when creating the ObjectFileMachO starts
      // at the beginning of a specific library and spans to the end
      // of the cache to be able to reach the shared LINKEDIT
      // segments. We need to convert the load command offsets to be
      // relative to the beginning of our specific image.
      lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
      lldb::offset_t linkedit_slide =
          linkedit_offset - m_linkedit_original_offset;
      symtab_load_command.symoff += linkedit_slide;
      symtab_load_command.stroff += linkedit_slide;
      dyld_info.export_off += linkedit_slide;
      dysymtab.indirectsymoff += linkedit_slide;
      function_starts_load_command.dataoff += linkedit_slide;
      exports_trie_load_command.dataoff += linkedit_slide;
    }

    nlist_data = *m_data_nsp->GetSubsetExtractorSP(symtab_load_command.symoff,
                                                   nlist_data_byte_size);
    strtab_data = *m_data_nsp->GetSubsetExtractorSP(symtab_load_command.stroff,
                                                    strtab_data_byte_size);

    // We shouldn't have exports data from both the LC_DYLD_INFO command
    // AND the LC_DYLD_EXPORTS_TRIE command in the same binary:
    lldbassert(!((dyld_info.export_size > 0)
                 && (exports_trie_load_command.datasize > 0)));
    if (dyld_info.export_size > 0) {
      dyld_trie_data = *m_data_nsp->GetSubsetExtractorSP(dyld_info.export_off,
                                                         dyld_info.export_size);
    } else if (exports_trie_load_command.datasize > 0) {
      dyld_trie_data =
          *m_data_nsp->GetSubsetExtractorSP(exports_trie_load_command.dataoff,
                                            exports_trie_load_command.datasize);
    }

    if (dysymtab.nindirectsyms != 0) {
      indirect_symbol_index_data = *m_data_nsp->GetSubsetExtractorSP(
          dysymtab.indirectsymoff, dysymtab.nindirectsyms * 4);
    }
    if (function_starts_load_command.cmd) {
      function_starts_data = *m_data_nsp->GetSubsetExtractorSP(
          function_starts_load_command.dataoff,
          function_starts_load_command.datasize);
    }
  }

  const bool have_strtab_data = strtab_data.GetByteSize() > 0;

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

  // 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;
      if (is_arm) {
        if (function_start_entry.addr & 1) {
          function_start_entry.addr &= THUMB_ADDRESS_BIT_MASK;
          function_start_entry.data = true;
        } else if (always_thumb) {
          function_start_entry.data = true;
        }
      }
      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;
          if (is_arm) {
            if (function_start_entry.addr & 1) {
              function_start_entry.addr &= THUMB_ADDRESS_BIT_MASK;
              function_start_entry.data = true;
            } else if (always_thumb) {
              function_start_entry.data = true;
            }
          }
          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(GetLog(LLDBLog::Symbols | LLDBLog::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);

  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 llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
  typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
  ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
  ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
  ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
  // Any symbols that get merged into another will get an entry in this map
  // so we know
  NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
  uint32_t nlist_idx = 0;
  Symbol *symbol_ptr = nullptr;

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

  std::vector<TrieEntryWithOffset> reexport_trie_entries;
  std::vector<TrieEntryWithOffset> external_sym_trie_entries;
  std::set<lldb::addr_t> resolver_addresses;

  const size_t dyld_trie_data_size = dyld_trie_data.GetByteSize();
  if (dyld_trie_data_size > 0) {
    LLDB_LOG(log, "Parsing {0} bytes of dyld trie data", dyld_trie_data_size);
    SectionSP text_segment_sp =
        GetSectionList()->FindSectionByName(GetSegmentNameTEXT());
    lldb::addr_t text_segment_file_addr = LLDB_INVALID_ADDRESS;
    if (text_segment_sp)
      text_segment_file_addr = text_segment_sp->GetFileAddress();
    ParseTrieEntries(dyld_trie_data, is_arm, text_segment_file_addr,
                     resolver_addresses, reexport_trie_entries,
                     external_sym_trie_entries);
  }

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

#if TARGET_OS_IPHONE

  // 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 (IsSharedCacheBinary()) {
    // 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();

    UUID dsc_uuid;
    UUID process_shared_cache_uuid;
    addr_t process_shared_cache_base_addr;

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

    __block bool found_image = false;
    __block void *nlist_buffer = nullptr;
    __block unsigned nlist_count = 0;
    __block char *string_table = nullptr;
    __block vm_offset_t vm_nlist_memory = 0;
    __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
    __block vm_offset_t vm_string_memory = 0;
    __block mach_msg_type_number_t vm_string_bytes_read = 0;

    llvm::scope_exit _(^{
      if (vm_nlist_memory)
        vm_deallocate(mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
      if (vm_string_memory)
        vm_deallocate(mach_task_self(), vm_string_memory, vm_string_bytes_read);
    });

    typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
    typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
    UndefinedNameToDescMap undefined_name_to_desc;
    SymbolIndexToName reexport_shlib_needs_fixup;

    dyld_for_each_installed_shared_cache(^(dyld_shared_cache_t shared_cache) {
      uuid_t cache_uuid;
      dyld_shared_cache_copy_uuid(shared_cache, &cache_uuid);
      if (found_image)
        return;

        if (process_shared_cache_uuid.IsValid() &&
          process_shared_cache_uuid != UUID(&cache_uuid, 16))
        return;

      dyld_shared_cache_for_each_image(shared_cache, ^(dyld_image_t image) {
        uuid_t dsc_image_uuid;
        if (found_image)
          return;

        dyld_image_copy_uuid(image, &dsc_image_uuid);
        if (image_uuid != UUID(dsc_image_uuid, 16))
          return;

        found_image = true;

        // Compute the size of the string table. We need to ask dyld for a
        // new SPI to avoid this step.
        dyld_image_local_nlist_content_4Symbolication(
            image, ^(const void *nlistStart, uint64_t nlistCount,
                     const char *stringTable) {
              if (!nlistStart || !nlistCount)
                return;

              // The buffers passed here are valid only inside the block.
              // Use vm_read to make a cheap copy of them available for our
              // processing later.
              kern_return_t ret =
                  vm_read(mach_task_self(), (vm_address_t)nlistStart,
                          nlist_byte_size * nlistCount, &vm_nlist_memory,
                          &vm_nlist_bytes_read);
              if (ret != KERN_SUCCESS)
                return;
              assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);

              // We don't know the size of the string table. It's cheaper
              // to map the whole VM region than to determine the size by
              // parsing all the nlist entries.
              vm_address_t string_address = (vm_address_t)stringTable;
              vm_size_t region_size;
              mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
              vm_region_basic_info_data_t info;
              memory_object_name_t object;
              ret = vm_region_64(mach_task_self(), &string_address,
                                 &region_size, VM_REGION_BASIC_INFO_64,
                                 (vm_region_info_t)&info, &info_count, &object);
              if (ret != KERN_SUCCESS)
                return;

              ret = vm_read(mach_task_self(), (vm_address_t)stringTable,
                            region_size -
                                ((vm_address_t)stringTable - string_address),
                            &vm_string_memory, &vm_string_bytes_read);
              if (ret != KERN_SUCCESS)
                return;

              nlist_buffer = (void *)vm_nlist_memory;
              string_table = (char *)vm_string_memory;
              nlist_count = nlistCount;
            });
      });
    });
    if (nlist_buffer) {
      DataExtractor dsc_local_symbols_data(nlist_buffer,
                                           nlist_count * nlist_byte_size,
                                           byte_order, addr_byte_size);
      unmapped_local_symbols_found = nlist_count;

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

      lldb::offset_t nlist_data_offset = 0;

                for (uint32_t nlist_index = 0;
                     nlist_index < nlist_count;
                     nlist_index++) {
                  /////////////////////////////
                  {
                    std::optional<struct nlist_64> nlist_maybe =
                        ParseNList(dsc_local_symbols_data, nlist_data_offset,
                                   nlist_byte_size);
                    if (!nlist_maybe)
                      break;
                    struct nlist_64 nlist = *nlist_maybe;

                    SymbolType type = eSymbolTypeInvalid;
          const char *symbol_name = string_table + 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
                      Debugger::ReportError(llvm::formatv(
                          "DSC unmapped local symbol[{0}] has invalid "
                          "string table offset {1:x} in {2}, ignoring symbol",
                          nlist_index, nlist.n_strx,
                          module_sp->GetFileSpec().GetPath()));
                      continue;
                    }
                    if (symbol_name[0] == '\0')
                      symbol_name = NULL;

                    const char *symbol_name_non_abi_mangled = NULL;

                    SectionSP symbol_section;
                    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 (TryParseV2ObjCMetadataSymbol(
                                symbol_name, symbol_name_non_abi_mangled,
                                type)) {
                          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));
                              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()
                                                      .AsCString();
                            if (so_path && so_path[0]) {
                              std::string full_so_path(so_path);
                              const size_t double_slash_pos =
                                  full_so_path.find("//");
                              if (double_slash_pos != std::string::npos) {
                                // The linker has been generating bad N_SO
                                // entries with doubled up paths
                                // in the format "%s%s" where the first
                                // string in the DW_AT_comp_dir, and the
                                // second is the directory for the source
                                // file so you end up with a path that looks
                                // like "/tmp/src//tmp/src/"
                                FileSpec so_dir(so_path);
                                if (!FileSystem::Instance().Exists(so_dir)) {
                                  so_dir.SetFile(
                                      &full_so_path[double_slash_pos + 1],
                                      FileSpec::Style::native);
                                  if (FileSystem::Instance().Exists(so_dir)) {
                                    // Trim off the incorrect path
                                    full_so_path.erase(0, double_slash_pos + 1);
                                  }
                                }
                              }
                              if (*full_so_path.rbegin() != '/')
                                full_so_path += '/';
                              full_so_path += symbol_name;
                              sym[sym_idx - 1].GetMangled().SetValue(
                                  ConstString(full_so_path.c_str()));
                              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) {
                            llvm::StringRef symbol_sect_name =
                                symbol_section->GetName();
                            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.starts_with("__objc")) {
                                type = eSymbolTypeRuntime;

                                if (TryParseV2ObjCMetadataSymbol(
                                        symbol_name,
                                        symbol_name_non_abi_mangled, type))
                                  demangled_is_synthesized = true;
                              } else if (symbol_sect_name.starts_with("__gcc_except_tab")) {
                                type = eSymbolTypeException;
                              } else {
                                type = eSymbolTypeData;
                              }
                            } else if (symbol_sect_name.starts_with("__IMPORT")) 
                              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);
                                llvm::StringRef
                                    g_objc_v1_prefix_class(".objc_class_name_");
                                if (symbol_name_ref.starts_with(
                                        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 {
                        if (symbol_name && symbol_name[0] == '_') {
                          symbol_name++; // Skip the leading underscore
                        }

                        if (symbol_name) {
                          ConstString const_symbol_name(symbol_name);
                          sym[sym_idx].GetMangled().SetValue(const_symbol_name);
                          if (is_gsym && is_debug) {
                            const char *gsym_name =
                                sym[sym_idx]
                                    .GetMangled()
                                    .GetName(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();
                        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
                          auto range =
                              N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
                          if (range.first != range.second) {
                            bool found_it = false;
                            for (auto pos = range.first; pos != range.second;
                                 ++pos) {
                              if (sym[sym_idx].GetMangled().GetName(
                                      Mangled::ePreferMangled) ==
                                  sym[pos->second].GetMangled().GetName(
                                      Mangled::ePreferMangled)) {
                                m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
                                // We just need the flags from the linker
                                // symbol, so put these flags
                                // 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
                          auto range = N_STSYM_addr_to_sym_idx.equal_range(
                              nlist.n_value);
                          if (range.first != range.second) {
                            bool found_it = false;
                            for (auto pos = range.first; pos != range.second;
                                 ++pos) {
                              if (sym[sym_idx].GetMangled().GetName(
                                      Mangled::ePreferMangled) ==
                                  sym[pos->second].GetMangled().GetName(
                                      Mangled::ePreferMangled)) {
                                m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
                                // We just need the flags from the linker
                                // symbol, so put these flags
                                // 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(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() =
                                    Address(symbol_section, symbol_value);
                                add_symbol_addr(sym[GSYM_sym_idx]
                                                    .GetAddress()
                                                    .GetFileAddress());
                                // 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() =
                            Address(symbol_section, symbol_value);
                        add_symbol_addr(
                            sym[sym_idx].GetAddress().GetFileAddress());
                      }
                      sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);

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

#endif
  lldb::offset_t nlist_data_offset = 0;

  if (nlist_data.GetByteSize() > 0) {

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

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

    typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
    typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
    UndefinedNameToDescMap undefined_name_to_desc;
    SymbolIndexToName reexport_shlib_needs_fixup;

    // Symtab parsing is a huge mess. Everything is entangled and the code
    // requires access to a ridiculous amount of variables. LLDB depends
    // heavily on the proper merging of symbols and to get that right we need
    // to make sure we have parsed all the debug symbols first. Therefore we
    // invoke the lambda twice, once to parse only the debug symbols and then
    // once more to parse the remaining symbols.
    auto ParseSymbolLambda = [&](struct nlist_64 &nlist, uint32_t nlist_idx,
                                 bool debug_only) {
      const bool is_debug = ((nlist.n_type & N_STAB) != 0);
      if (is_debug != debug_only)
        return true;

      const char *symbol_name_non_abi_mangled = nullptr;
      const char *symbol_name = nullptr;

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

        if (symbol_name == nullptr) {
          // No symbol should be NULL, even the symbols with no string values
          // should have an offset zero which points to an empty C-string
          Debugger::ReportError(llvm::formatv(
              "symbol[{0}] has invalid string table offset {1:x} in {2}, "
              "ignoring symbol",
              nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
          return true;
        }
        if (symbol_name[0] == '\0')
          symbol_name = nullptr;
      } else {
        const addr_t str_addr = strtab_addr + nlist.n_strx;
        Status str_error;
        if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
                                           str_error))
          symbol_name = memory_symbol_name.c_str();
      }

      SymbolType type = eSymbolTypeInvalid;
      SectionSP symbol_section;
      bool add_nlist = true;
      bool is_gsym = false;
      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 (TryParseV2ObjCMetadataSymbol(symbol_name,
                                           symbol_name_non_abi_mangled, type)) {
            demangled_is_synthesized = true;
          } else {
            if (nlist.n_value != 0)
              symbol_section =
                  section_info.GetSection(nlist.n_sect, nlist.n_value);

            type = eSymbolTypeData;
          }
        } break;

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

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

            N_FUN_addr_to_sym_idx.insert(
                std::make_pair(nlist.n_value, sym_idx));
            // We use the current number of symbols in the symbol table in
            // lieu of using nlist_idx in case we ever start trimming entries
            // out
            N_FUN_indexes.push_back(sym_idx);
          } else {
            type = eSymbolTypeCompiler;

            if (!N_FUN_indexes.empty()) {
              // Copy the size of the function into the original STAB entry
              // so we don't have to hunt for it later
              symtab.SymbolAtIndex(N_FUN_indexes.back())
                  ->SetByteSize(nlist.n_value);
              N_FUN_indexes.pop_back();
              // We don't really need the end function STAB as it contains
              // the size which we already placed with the original symbol,
              // so don't add it if we want a minimal symbol table
              add_nlist = false;
            }
          }
          break;

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

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

        case N_BNSYM:
          // We use the current number of symbols in the symbol table in lieu
          // of using nlist_idx in case we ever start trimming entries out
          // Skip these if we want minimal symbol tables
          add_nlist = false;
          break;

        case N_ENSYM:
          // Set the size of the N_BNSYM to the terminating index of this
          // N_ENSYM so that we can always skip the entire symbol if we need
          // to navigate more quickly at the source level when parsing STABS
          // Skip these if we want minimal symbol tables
          add_nlist = false;
          break;

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

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

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

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

        case N_SO:
          // source file name
          type = eSymbolTypeSourceFile;
          if (symbol_name == nullptr) {
            add_nlist = false;
            if (N_SO_index != UINT32_MAX) {
              // Set the size of the N_SO to the terminating index of this
              // N_SO so that we can always skip the entire N_SO if we need
              // to navigate more quickly at the source level when parsing
              // STABS
              symbol_ptr = symtab.SymbolAtIndex(N_SO_index);
              symbol_ptr->SetByteSize(sym_idx);
              symbol_ptr->SetSizeIsSibling(true);
            }
            N_NSYM_indexes.clear();
            N_INCL_indexes.clear();
            N_BRAC_indexes.clear();
            N_COMM_indexes.clear();
            N_FUN_indexes.clear();
            N_SO_index = UINT32_MAX;
          } else {
            // We use the current number of symbols in the symbol table in
            // lieu of using nlist_idx in case we ever start trimming entries
            // out
            const bool N_SO_has_full_path = symbol_name[0] == '/';
            if (N_SO_has_full_path) {
              if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
                // We have two consecutive N_SO entries where the first
                // contains a directory and the second contains a full path.
                sym[sym_idx - 1].GetMangled().SetValue(
                    ConstString(symbol_name));
                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
              llvm::StringRef so_path = sym[sym_idx - 1]
                                            .GetMangled()
                                            .GetDemangledName()
                                            .GetStringRef();
              if (!so_path.empty()) {
                std::string full_so_path(so_path);
                const size_t double_slash_pos = full_so_path.find("//");
                if (double_slash_pos != std::string::npos) {
                  // The linker has been generating bad N_SO entries with
                  // doubled up paths in the format "%s%s" where the first
                  // string in the DW_AT_comp_dir, and the second is the
                  // directory for the source file so you end up with a path
                  // that looks like "/tmp/src//tmp/src/"
                  FileSpec so_dir(so_path);
                  if (!FileSystem::Instance().Exists(so_dir)) {
                    so_dir.SetFile(&full_so_path[double_slash_pos + 1],
                                   FileSpec::Style::native);
                    if (FileSystem::Instance().Exists(so_dir)) {
                      // Trim off the incorrect path
                      full_so_path.erase(0, double_slash_pos + 1);
                    }
                  }
                }
                if (*full_so_path.rbegin() != '/')
                  full_so_path += '/';
                full_so_path += symbol_name;
                sym[sym_idx - 1].GetMangled().SetValue(
                    ConstString(full_so_path.c_str()));
                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);
          [[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_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] && symbol_name) {
            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;
          }
          [[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) {
              llvm::StringRef symbol_sect_name = symbol_section->GetName();
              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.starts_with("__objc")) {
                  type = eSymbolTypeRuntime;

                  if (TryParseV2ObjCMetadataSymbol(
                          symbol_name, symbol_name_non_abi_mangled, type))
                    demangled_is_synthesized = true;
                } else if (symbol_sect_name.starts_with("__gcc_except_tab")) {
                  type = eSymbolTypeException;
                } else {
                  type = eSymbolTypeData;
                }
              } else if (symbol_sect_name.starts_with("__IMPORT")) {
                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);
                  llvm::StringRef g_objc_v1_prefix_class(
                      ".objc_class_name_");
                  if (symbol_name_ref.starts_with(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) {
        sym[sym_idx].Clear();
        return true;
      }

      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 {

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

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

      if (is_gsym) {
        const char *gsym_name = sym[sym_idx]
                                    .GetMangled()
                                    .GetName(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();
        symbol_value -= section_file_addr;
      }

      if (!is_debug) {
        if (type == eSymbolTypeCode) {
          // See if we can find a N_FUN entry for any code symbols. If we do
          // find a match, and the name matches, then we can merge the two into
          // just the function symbol to avoid duplicate entries in the symbol
          // table.
          std::pair<ValueToSymbolIndexMap::const_iterator,
                    ValueToSymbolIndexMap::const_iterator>
              range;
          range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
          if (range.first != range.second) {
            for (ValueToSymbolIndexMap::const_iterator pos = range.first;
                 pos != range.second; ++pos) {
              if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) ==
                  sym[pos->second].GetMangled().GetName(
                      Mangled::ePreferMangled)) {
                m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
                // We just need the flags from the linker symbol, so put these
                // flags 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();
                return true;
              }
            }
          } 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) {
            for (ValueToSymbolIndexMap::const_iterator pos = range.first;
                 pos != range.second; ++pos) {
              if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) ==
                  sym[pos->second].GetMangled().GetName(
                      Mangled::ePreferMangled)) {
                m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
                // We just need the flags from the linker symbol, so put these
                // flags 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();
                return true;
              }
            }
          } else {
            // Combine N_GSYM stab entries with the non stab symbol.
            const char *gsym_name = sym[sym_idx]
                                        .GetMangled()
                                        .GetName(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() =
                    Address(symbol_section, symbol_value);
                add_symbol_addr(
                    sym[GSYM_sym_idx].GetAddress().GetFileAddress());
                // 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();
                return true;
              }
            }
          }
        }
      }

      sym[sym_idx].SetID(nlist_idx);
      sym[sym_idx].SetType(type);
      if (set_value) {
        sym[sym_idx].GetAddressRef() = Address(symbol_section, symbol_value);
        if (symbol_section)
          add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
      }
      sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
      if (nlist.n_desc & N_WEAK_REF)
        sym[sym_idx].SetIsWeak(true);

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

      ++sym_idx;
      return true;
    };

    // First parse all the nlists but don't process them yet. See the next
    // comment for an explanation why.
    std::vector<struct nlist_64> nlists;
    nlists.reserve(symtab_load_command.nsyms);
    for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) {
      if (auto nlist =
              ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
        nlists.push_back(*nlist);
      else
        break;
    }

    // Now parse all the debug symbols. This is needed to merge non-debug
    // symbols in the next step. Non-debug symbols are always coalesced into
    // the debug symbol. Doing this in one step would mean that some symbols
    // won't be merged.
    nlist_idx = 0;
    for (auto &nlist : nlists) {
      if (!ParseSymbolLambda(nlist, nlist_idx++, DebugSymbols))
        break;
    }

    // Finally parse all the non debug symbols.
    nlist_idx = 0;
    for (auto &nlist : nlists) {
      if (!ParseSymbolLambda(nlist, nlist_idx++, NonDebugSymbols))
        break;
    }

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

  // Count how many trie symbols we'll add to the symbol table
  int trie_symbol_table_augment_count = 0;
  for (auto &e : external_sym_trie_entries) {
    if (!symbols_added.contains(e.entry.address))
      trie_symbol_table_augment_count++;
  }

  if (num_syms < sym_idx + trie_symbol_table_augment_count) {
    num_syms = sym_idx + trie_symbol_table_augment_count;
    sym = symtab.Resize(num_syms);
  }
  uint32_t synthetic_sym_id = symtab_load_command.nsyms;

  // Add symbols from the trie to the symbol table.
  for (auto &e : external_sym_trie_entries) {
    if (symbols_added.contains(e.entry.address))
      continue;

    // Find the section that this trie address is in, use that to annotate
    // symbol type as we add the trie address and name to the symbol table.
    Address symbol_addr;
    if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
      SectionSP symbol_section(symbol_addr.GetSection());
      const char *symbol_name = e.entry.name.GetCString();
      bool demangled_is_synthesized = false;
      SymbolType type =
          GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
                        data_section_sp, data_dirty_section_sp,
                        data_const_section_sp, symbol_section);

      sym[sym_idx].SetType(type);
      if (symbol_section) {
        sym[sym_idx].SetID(synthetic_sym_id++);
        sym[sym_idx].GetMangled().SetMangledName(ConstString(symbol_name));
        if (demangled_is_synthesized)
          sym[sym_idx].SetDemangledNameIsSynthesized(true);
        sym[sym_idx].SetIsSynthetic(true);
        sym[sym_idx].SetExternal(true);
        sym[sym_idx].GetAddressRef() = symbol_addr;
        add_symbol_addr(symbol_addr.GetFileAddress());
        if (e.entry.flags & TRIE_SYMBOL_IS_THUMB)
          sym[sym_idx].SetFlags(MACHO_NLIST_ARM_SYMBOL_IS_THUMB);
        ++sym_idx;
      }
    }
  }

  if (function_starts_count > 0) {
    uint32_t num_synthetic_function_symbols = 0;
    for (i = 0; i < function_starts_count; ++i) {
      if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
        ++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 (!symbols_added.contains(func_start_entry->addr)) {
          addr_t symbol_file_addr = func_start_entry->addr;
          uint32_t symbol_flags = 0;
          if (func_start_entry->data)
            symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
          Address symbol_addr;
          if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
            SectionSP symbol_section(symbol_addr.GetSection());
            if (symbol_section) {
              sym[sym_idx].SetID(synthetic_sym_id++);
              // Don't set the name for any synthetic symbols, the Symbol
              // object will generate one if needed when the name is accessed
              // via accessors.
              sym[sym_idx].GetMangled().SetDemangledName(ConstString());
              sym[sym_idx].SetType(eSymbolTypeCode);
              sym[sym_idx].SetIsSynthetic(true);
              sym[sym_idx].GetAddressRef() = symbol_addr;
              add_symbol_addr(symbol_addr.GetFileAddress());
              if (symbol_flags)
                sym[sym_idx].SetFlags(symbol_flags);
              ++sym_idx;
            }
          }
        }
      }
    }
  }

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

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

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

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

          if (num_symbol_stubs == 0)
            continue;

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

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

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

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

  if (!reexport_trie_entries.empty()) {
    for (const auto &e : reexport_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;
        }
      }
    }
  }
}

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

    *s << ", file = '" << m_file;
    ModuleSpecList all_specs;
    ModuleSpec base_spec;
    GetAllArchSpecs(m_header, *m_data_nsp,
                    MachHeaderSizeFromMagic(m_header.magic), base_spec,
                    all_specs);
    for (unsigned i = 0, e = all_specs.GetSize(); i != e; ++i) {
      *s << "', triple";
      if (e)
        s->Printf("[%d]", i);
      *s << " = ";
      *s << all_specs.GetModuleSpecRefAtIndex(i)
                .GetArchitecture()
                .GetTriple()
                .getTriple();
    }
    *s << "\n";
    SectionList *sections = GetSectionList();
    if (sections)
      sections->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true,
                     UINT32_MAX);

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

UUID ObjectFileMachO::GetUUID(const llvm::MachO::mach_header &header,
                              const lldb_private::DataExtractor &data,
                              lldb::offset_t lc_offset) {
  uint32_t i;
  llvm::MachO::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 (!ReadMachOCommand(data, offset, load_cmd))
      break;

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

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

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

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

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

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

namespace {
struct OSEnv {
  llvm::StringRef os_type;
  llvm::StringRef environment;
  OSEnv(uint32_t cmd) {
    switch (cmd) {
    case llvm::MachO::PLATFORM_MACOS:
      os_type = llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
      return;
    case llvm::MachO::PLATFORM_IOS:
      os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
      return;
    case llvm::MachO::PLATFORM_TVOS:
      os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
      return;
    case llvm::MachO::PLATFORM_WATCHOS:
      os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
      return;
    case llvm::MachO::PLATFORM_BRIDGEOS:
      os_type = llvm::Triple::getOSTypeName(llvm::Triple::BridgeOS);
      return;
    case llvm::MachO::PLATFORM_DRIVERKIT:
      os_type = llvm::Triple::getOSTypeName(llvm::Triple::DriverKit);
      return;
    case llvm::MachO::PLATFORM_MACCATALYST:
      os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
      environment = llvm::Triple::getEnvironmentTypeName(llvm::Triple::MacABI);
      return;
    case llvm::MachO::PLATFORM_IOSSIMULATOR:
      os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
      environment =
          llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
      return;
    case llvm::MachO::PLATFORM_TVOSSIMULATOR:
      os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
      environment =
          llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
      return;
    case llvm::MachO::PLATFORM_WATCHOSSIMULATOR:
      os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
      environment =
          llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
      return;
    case llvm::MachO::PLATFORM_XROS:
      os_type = llvm::Triple::getOSTypeName(llvm::Triple::XROS);
      return;
    case llvm::MachO::PLATFORM_XROS_SIMULATOR:
      os_type = llvm::Triple::getOSTypeName(llvm::Triple::XROS);
      environment =
          llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
      return;
    default: {
      Log *log(GetLog(LLDBLog::Symbols | LLDBLog::Process));
      LLDB_LOGF(log, "unsupported platform in LC_BUILD_VERSION");
    }
    }
  }
};

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

void ObjectFileMachO::GetAllArchSpecs(const llvm::MachO::mach_header &header,
                                      const lldb_private::DataExtractor &data,
                                      lldb::offset_t lc_offset,
                                      ModuleSpec &base_spec,
                                      lldb_private::ModuleSpecList &all_specs) {
  auto &base_arch = base_spec.GetArchitecture();
  base_arch.SetArchitecture(eArchTypeMachO, header.cputype, header.cpusubtype);
  if (!base_arch.IsValid())
    return;

  bool found_any = false;
  auto add_triple = [&](const llvm::Triple &triple) {
    auto spec = base_spec;
    spec.GetArchitecture().GetTriple() = triple;
    if (spec.GetArchitecture().IsValid()) {
      spec.GetUUID() = ObjectFileMachO::GetUUID(header, data, lc_offset);
      all_specs.Append(spec);
      found_any = true;
    }
  };

  // Set OS to an unspecified unknown or a "*" so it can match any OS
  llvm::Triple base_triple = base_arch.GetTriple();
  base_triple.setOS(llvm::Triple::UnknownOS);
  base_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.
      base_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
      base_triple.setVendor(llvm::Triple::UnknownVendor);
      base_triple.setVendorName(llvm::StringRef());
    }
    return add_triple(base_triple);
  }

  llvm::MachO::load_command load_cmd;

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

    llvm::MachO::version_min_command version_min;
    switch (load_cmd.cmd) {
    case llvm::MachO::LC_VERSION_MIN_MACOSX:
    case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
    case llvm::MachO::LC_VERSION_MIN_TVOS:
    case llvm::MachO::LC_VERSION_MIN_WATCHOS: {
      if (load_cmd.cmdsize != sizeof(version_min))
        break;
      if (data.ExtractBytes(cmd_offset, sizeof(version_min),
                            data.GetByteOrder(), &version_min) == 0)
        break;
      MinOS min_os(version_min.version);
      llvm::SmallString<32> os_name;
      llvm::raw_svector_ostream os(os_name);
      os << GetOSName(load_cmd.cmd) << min_os.major_version << '.'
         << min_os.minor_version << '.' << min_os.patch_version;

      auto triple = base_triple;
      triple.setOSName(os.str());

      // Disambiguate legacy simulator platforms.
      if (load_cmd.cmd != llvm::MachO::LC_VERSION_MIN_MACOSX &&
          (base_triple.getArch() == llvm::Triple::x86_64 ||
           base_triple.getArch() == llvm::Triple::x86)) {
        // The combination of legacy LC_VERSION_MIN load command and
        // x86 architecture always indicates a simulator environment.
        // The combination of LC_VERSION_MIN and arm architecture only
        // appears for native binaries. Back-deploying simulator
        // binaries on Apple Silicon Macs use the modern unambigous
        // LC_BUILD_VERSION load commands; no special handling required.
        triple.setEnvironment(llvm::Triple::Simulator);
      }
      add_triple(triple);
      break;
    }
    default:
      break;
    }

    offset = cmd_offset + load_cmd.cmdsize;
  }

  // See if there are LC_BUILD_VERSION load commands that can give
  // us the OS type.
  offset = lc_offset;
  for (uint32_t i = 0; i < header.ncmds; ++i) {
    const lldb::offset_t cmd_offset = offset;
    if (!ReadMachOCommand(data, offset, load_cmd))
      break;

    do {
      if (load_cmd.cmd == llvm::MachO::LC_BUILD_VERSION) {
        llvm::MachO::build_version_command build_version;
        if (load_cmd.cmdsize < sizeof(build_version)) {
          // Malformed load command.
          break;
        }
        if (data.ExtractBytes(cmd_offset, sizeof(build_version),
                              data.GetByteOrder(), &build_version) == 0)
          break;
        MinOS min_os(build_version.minos);
        OSEnv os_env(build_version.platform);
        llvm::SmallString<16> os_name;
        llvm::raw_svector_ostream os(os_name);
        os << os_env.os_type << min_os.major_version << '.'
           << min_os.minor_version << '.' << min_os.patch_version;
        auto triple = base_triple;
        triple.setOSName(os.str());
        os_name.clear();
        if (!os_env.environment.empty())
          triple.setEnvironmentName(os_env.environment);
        add_triple(triple);
      }
    } while (false);
    offset = cmd_offset + load_cmd.cmdsize;
  }

  if (!found_any) {
    add_triple(base_triple);
  }
}

ArchSpec ObjectFileMachO::GetArchitecture(
    ModuleSP module_sp, const llvm::MachO::mach_header &header,
    const lldb_private::DataExtractor &data, lldb::offset_t lc_offset) {
  ModuleSpecList all_specs;
  ModuleSpec base_spec;
  GetAllArchSpecs(header, data, MachHeaderSizeFromMagic(header.magic),
                  base_spec, all_specs);

  // If the object file offers multiple alternative load commands,
  // pick the one that matches the module.
  if (module_sp) {
    const ArchSpec &module_arch = module_sp->GetArchitecture();
    for (unsigned i = 0, e = all_specs.GetSize(); i != e; ++i) {
      ArchSpec mach_arch =
          all_specs.GetModuleSpecRefAtIndex(i).GetArchitecture();
      if (module_arch.IsCompatibleMatch(mach_arch))
        return mach_arch;
    }
  }

  // Return the first arch we found.
  if (all_specs.GetSize() == 0)
    return {};
  return all_specs.GetModuleSpecRefAtIndex(0).GetArchitecture();
}

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

uint32_t ObjectFileMachO::GetDependentModules(FileSpecList &files) {
  ModuleSP module_sp = GetModule();
  if (!module_sp)
    return 0;

  uint32_t count = 0;
  std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
  llvm::MachO::load_command load_cmd;
  lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
  std::vector<std::string> rpath_paths;
  std::vector<std::string> rpath_relative_paths;
  std::vector<std::string> at_exec_relative_paths;
  uint32_t i;
  for (i = 0; i < m_header.ncmds; ++i) {
    const uint32_t cmd_offset = offset;
    if (!ReadMachOCommand(*m_data_nsp, offset, load_cmd))
      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_nsp->GetU32(&offset);
      // For LC_LOAD_DYLIB there is an alternate encoding
      // which adds a uint32_t `flags` field for `DYLD_USE_*`
      // flags.  This can be detected by a timestamp field with
      // the `DYLIB_USE_MARKER` constant value.
      bool is_delayed_init = false;
      uint32_t use_command_marker = m_data_nsp->GetU32(&offset);
      if (use_command_marker == 0x1a741800 /* DYLIB_USE_MARKER */) {
        offset += 4; /* uint32_t current_version */
        offset += 4; /* uint32_t compat_version */
        uint32_t flags = m_data_nsp->GetU32(&offset);
        // If this LC_LOAD_DYLIB is marked delay-init,
        // don't report it as a dependent library -- it
        // may be loaded in the process at some point,
        // but will most likely not be load at launch.
        if (flags & 0x08 /* DYLIB_USE_DELAYED_INIT */)
          is_delayed_init = true;
      }
      const char *path = m_data_nsp->PeekCStr(name_offset);
      if (path && !is_delayed_init) {
        if (load_cmd.cmd == LC_RPATH)
          rpath_paths.push_back(path);
        else {
          if (path[0] == '@') {
            if (strncmp(path, "@rpath", strlen("@rpath")) == 0)
              rpath_relative_paths.push_back(path + strlen("@rpath"));
            else if (strncmp(path, "@executable_path",
                             strlen("@executable_path")) == 0)
              at_exec_relative_paths.push_back(path +
                                               strlen("@executable_path"));
          } else {
            FileSpec file_spec(path);
            if (files.AppendIfUnique(file_spec))
              count++;
          }
        }
      }
    } break;

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

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

  if (!rpath_paths.empty()) {
    // Fixup all LC_RPATH values to be absolute paths.
    const std::string this_directory = this_file_spec.GetDirectory().str();
    for (auto &rpath : rpath_paths) {
      if (llvm::StringRef(rpath).starts_with(g_loader_path))
        rpath = this_directory + rpath.substr(g_loader_path.size());
      else if (llvm::StringRef(rpath).starts_with(g_executable_path))
        rpath = this_directory + rpath.substr(g_executable_path.size());
    }

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

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

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

  if ((!IsExecutable() && !IsDynamicLoader()) ||
      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());
    llvm::MachO::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 (!ReadMachOCommand(*m_data_nsp, offset, load_cmd))
        break;

      switch (load_cmd.cmd) {
      case LC_UNIXTHREAD:
      case LC_THREAD: {
        while (offset < cmd_offset + load_cmd.cmdsize) {
          uint32_t flavor = m_data_nsp->GetU32(&offset);
          uint32_t count = m_data_nsp->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_nsp->GetU32(&offset);
              done = true;
            }
            break;
          case llvm::MachO::CPU_TYPE_ARM64:
          case llvm::MachO::CPU_TYPE_ARM64_32:
            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_nsp->GetU64(&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_nsp->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: {
        uint64_t entryoffset = m_data_nsp->GetU64(&offset);
        SectionSP text_segment_sp =
            GetSectionList()->FindSectionByName(GetSegmentNameTEXT());
        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 && IsDynamicLoader()) {
      if (GetSymtab()) {
        const Symbol *dyld_start_sym =
            GetSymtab()->FindFirstSymbolWithNameAndType(
                ConstString("_dyld_start"), SymbolType::eSymbolTypeCode,
                Symtab::eDebugAny, Symtab::eVisibilityAny);
        if (dyld_start_sym && dyld_start_sym->GetAddress().IsValid()) {
          start_address = dyld_start_sym->GetAddress().GetFileAddress();
        }
      }
    }

    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;
        module_sp->FindSymbolsWithNameAndType(ConstString("start"),
                                              eSymbolTypeCode, contexts);
        if (contexts.GetSize()) {
          if (contexts.GetContextAtIndex(0, context))
            m_entry_point_address = context.symbol->GetAddress();
        }
      }
    }
  }

  return m_entry_point_address;
}

lldb_private::Address ObjectFileMachO::GetBaseAddress() {
  lldb_private::Address header_addr;
  SectionList *section_list = GetSectionList();
  if (section_list) {
    SectionSP text_segment_sp(
        section_list->FindSectionByName(GetSegmentNameTEXT()));
    if (text_segment_sp)
      header_addr = Address(text_segment_sp, /*offset=*/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;
      llvm::MachO::thread_command thread_cmd;
      for (uint32_t i = 0; i < m_header.ncmds; ++i) {
        const uint32_t cmd_offset = offset;
        if (!ReadMachOCommand(*m_data_nsp, offset, thread_cmd))
          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::vector<std::tuple<offset_t, offset_t>>
ObjectFileMachO::FindLC_NOTEByName(std::string name) {
  std::vector<std::tuple<offset_t, offset_t>> results;
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());

    offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
    for (uint32_t i = 0; i < m_header.ncmds; ++i) {
      const uint32_t cmd_offset = offset;
      llvm::MachO::load_command lc = {};
      if (!ReadMachOCommand(*m_data_nsp, offset, lc))
        break;
      if (lc.cmd == LC_NOTE) {
        char data_owner[17];
        m_data_nsp->CopyData(offset, 16, data_owner);
        data_owner[16] = '\0';
        offset += 16;

        if (name == data_owner) {
          offset_t payload_offset = m_data_nsp->GetU64_unchecked(&offset);
          offset_t payload_size = m_data_nsp->GetU64_unchecked(&offset);
          results.push_back({payload_offset, payload_size});
        }
      }
      offset = cmd_offset + lc.cmdsize;
    }
  }
  return results;
}

std::string ObjectFileMachO::GetIdentifierString() {
  Log *log(
      GetLog(LLDBLog::Symbols | LLDBLog::Process | LLDBLog::DynamicLoader));
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());

    auto lc_notes = FindLC_NOTEByName("kern ver str");
    for (auto lc_note : lc_notes) {
      offset_t payload_offset = std::get<0>(lc_note);
      offset_t payload_size = std::get<1>(lc_note);
      uint32_t version;
      if (m_data_nsp->GetU32(&payload_offset, &version, 1) != nullptr) {
        if (version == 1) {
          uint32_t strsize = payload_size - sizeof(uint32_t);
          std::string result(strsize, '\0');
          m_data_nsp->CopyData(payload_offset, strsize, result.data());
          LLDB_LOGF(log, "LC_NOTE 'kern ver str' found with text '%s'",
                    result.c_str());
          return result;
        }
      }
    }

    // Second, make a pass over the load commands looking for an obsolete
    // LC_IDENT load command.
    offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
    for (uint32_t i = 0; i < m_header.ncmds; ++i) {
      const uint32_t cmd_offset = offset;
      llvm::MachO::ident_command ident_command;
      if (!ReadMachOCommand(*m_data_nsp, offset, ident_command))
        break;
      if (ident_command.cmd == LC_IDENT && ident_command.cmdsize != 0) {
        std::string result(ident_command.cmdsize, '\0');
        if (m_data_nsp->CopyData(offset, ident_command.cmdsize,
                                 result.data()) == ident_command.cmdsize) {
          LLDB_LOGF(log, "LC_IDENT found with text '%s'", result.c_str());
          return result;
        }
      }
      offset = cmd_offset + ident_command.cmdsize;
    }
  }
  return {};
}

AddressableBits ObjectFileMachO::GetAddressableBits() {
  AddressableBits addressable_bits;

  Log *log(GetLog(LLDBLog::Process));
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
    auto lc_notes = FindLC_NOTEByName("addrable bits");
    for (auto lc_note : lc_notes) {
      offset_t payload_offset = std::get<0>(lc_note);
      uint32_t version;
      if (m_data_nsp->GetU32(&payload_offset, &version, 1) != nullptr) {
        if (version == 3) {
          uint32_t num_addr_bits =
              m_data_nsp->GetU32_unchecked(&payload_offset);
          addressable_bits.SetAddressableBits(num_addr_bits);
          LLDB_LOGF(log,
                    "LC_NOTE 'addrable bits' v3 found, value %d "
                    "bits",
                    num_addr_bits);
        }
        if (version == 4) {
          uint32_t lo_addr_bits = m_data_nsp->GetU32_unchecked(&payload_offset);
          uint32_t hi_addr_bits = m_data_nsp->GetU32_unchecked(&payload_offset);

          if (lo_addr_bits == hi_addr_bits)
            addressable_bits.SetAddressableBits(lo_addr_bits);
          else
            addressable_bits.SetAddressableBits(lo_addr_bits, hi_addr_bits);
          LLDB_LOGF(log, "LC_NOTE 'addrable bits' v4 found, value %d & %d bits",
                    lo_addr_bits, hi_addr_bits);
        }
      }
    }
  }
  return addressable_bits;
}

bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &value,
                                                bool &value_is_offset,
                                                UUID &uuid,
                                                ObjectFile::BinaryType &type) {
  Log *log(
      GetLog(LLDBLog::Symbols | LLDBLog::Process | LLDBLog::DynamicLoader));
  value = LLDB_INVALID_ADDRESS;
  value_is_offset = false;
  uuid.Clear();
  uint32_t log2_pagesize = 0; // not currently passed up to caller
  uint32_t platform = 0;      // not currently passed up to caller
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());

    auto lc_notes = FindLC_NOTEByName("main bin spec");
    for (auto lc_note : lc_notes) {
      offset_t payload_offset = std::get<0>(lc_note);

      // struct main_bin_spec
      // {
      //     uint32_t version;       // currently 2
      //     uint32_t type;          // 0 == unspecified,
      //                             // 1 == kernel
      //                             // 2 == user process,
      //                                     dyld mach-o binary addr
      //                             // 3 == standalone binary
      //                             // 4 == user process,
      //                             //      dyld_all_image_infos addr
      //     uint64_t address;       // UINT64_MAX if address not specified
      //     uint64_t slide;         // slide, UINT64_MAX if unspecified
      //                             // 0 if no slide needs to be applied to
      //                             // file address
      //     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
      //     uint32_t platform;      // The Mach-O platform for this corefile.
      //                             // 0 for unspecified.
      //                             // The values are defined in
      //                             // <mach-o/loader.h>, PLATFORM_*.
      // } __attribute((packed));

      // "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, 3 == firmware ]
      //    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 ]
      //    uint32_t unused        [ for alignment ]

      uint32_t version;
      if (m_data_nsp->GetU32(&payload_offset, &version, 1) != nullptr &&
          version <= 2) {
        uint32_t binspec_type = 0;
        uuid_t raw_uuid;
        memset(raw_uuid, 0, sizeof(uuid_t));

        if (!m_data_nsp->GetU32(&payload_offset, &binspec_type, 1))
          return false;
        if (!m_data_nsp->GetU64(&payload_offset, &value, 1))
          return false;
        uint64_t slide = LLDB_INVALID_ADDRESS;
        if (version > 1 && !m_data_nsp->GetU64(&payload_offset, &slide, 1))
          return false;
        if (value == LLDB_INVALID_ADDRESS && slide != LLDB_INVALID_ADDRESS) {
          value = slide;
          value_is_offset = true;
        }

        if (m_data_nsp->CopyData(payload_offset, sizeof(uuid_t), raw_uuid) !=
            0) {
          uuid = UUID(raw_uuid, sizeof(uuid_t));
          // convert the "main bin spec" type into our
          // ObjectFile::BinaryType enum
          const char *typestr = "unrecognized type";
          type = eBinaryTypeInvalid;
          switch (binspec_type) {
          case 0:
            type = eBinaryTypeUnknown;
            typestr = "uknown";
            break;
          case 1:
            type = eBinaryTypeKernel;
            typestr = "xnu kernel";
            break;
          case 2:
            type = eBinaryTypeUser;
            typestr = "userland dyld";
            break;
          case 3:
            type = eBinaryTypeStandalone;
            typestr = "standalone";
            break;
          case 4:
            type = eBinaryTypeUserAllImageInfos;
            typestr = "userland dyld_all_image_infos";
            break;
          }
          LLDB_LOGF(log,
                    "LC_NOTE 'main bin spec' found, version %d type %d "
                    "(%s), value 0x%" PRIx64 " value-is-slide==%s uuid %s",
                    version, type, typestr, value,
                    value_is_offset ? "true" : "false",
                    uuid.GetAsString().c_str());
          if (!m_data_nsp->GetU32(&payload_offset, &log2_pagesize, 1))
            return false;
          if (version > 1 && !m_data_nsp->GetU32(&payload_offset, &platform, 1))
            return false;
          return true;
        }
      }
    }
  }
  return false;
}

bool ObjectFileMachO::GetCorefileThreadExtraInfos(
    std::vector<lldb::tid_t> &tids) {
  tids.clear();
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());

    Log *log(GetLog(LLDBLog::Object | LLDBLog::Process | LLDBLog::Thread));
    if (StructuredData::ObjectSP object_sp = GetCorefileProcessMetadata()) {
      StructuredData::Dictionary *dict = object_sp->GetAsDictionary();
      StructuredData::Array *threads;
      if (!dict->GetValueForKeyAsArray("threads", threads) || !threads) {
        LLDB_LOGF(log,
                  "'process metadata' LC_NOTE does not have a 'threads' key");
        return false;
      }
      if (threads->GetSize() != GetNumThreadContexts()) {
        LLDB_LOGF(log, "Unable to read 'process metadata' LC_NOTE, number of "
                       "threads does not match number of LC_THREADS.");
        return false;
      }
      const size_t num_threads = threads->GetSize();
      for (size_t i = 0; i < num_threads; i++) {
        std::optional<StructuredData::Dictionary *> maybe_thread =
            threads->GetItemAtIndexAsDictionary(i);
        if (!maybe_thread) {
          LLDB_LOGF(log,
                    "Unable to read 'process metadata' LC_NOTE, threads "
                    "array does not have a dictionary at index %zu.",
                    i);
          return false;
        }
        StructuredData::Dictionary *thread = *maybe_thread;
        lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
        if (thread->GetValueForKeyAsInteger<lldb::tid_t>("thread_id", tid))
          if (tid == 0)
            tid = LLDB_INVALID_THREAD_ID;
        tids.push_back(tid);
      }

      if (log) {
        StreamString logmsg;
        logmsg.Printf("LC_NOTE 'process metadata' found: ");
        dict->Dump(logmsg, /* pretty_print */ false);
        LLDB_LOGF(log, "%s", logmsg.GetData());
      }
      return true;
    }
  }
  return false;
}

StructuredData::ObjectSP ObjectFileMachO::GetCorefileProcessMetadata() {
  ModuleSP module_sp(GetModule());
  if (!module_sp)
    return {};

  Log *log(GetLog(LLDBLog::Object | LLDBLog::Process | LLDBLog::Thread));
  std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
  auto lc_notes = FindLC_NOTEByName("process metadata");
  if (lc_notes.size() == 0)
    return {};

  if (lc_notes.size() > 1)
    LLDB_LOGF(
        log,
        "Multiple 'process metadata' LC_NOTEs found, only using the first.");

  auto [payload_offset, strsize] = lc_notes[0];
  std::string buf(strsize, '\0');
  if (m_data_nsp->CopyData(payload_offset, strsize, buf.data()) != strsize) {
    LLDB_LOGF(log,
              "Unable to read %" PRIu64
              " bytes of 'process metadata' LC_NOTE JSON contents",
              strsize);
    return {};
  }
  while (buf.back() == '\0')
    buf.resize(buf.size() - 1);
  StructuredData::ObjectSP object_sp = StructuredData::ParseJSON(buf);
  if (!object_sp) {
    LLDB_LOGF(log, "Unable to read 'process metadata' LC_NOTE, did not "
                   "parse as valid JSON.");
    return {};
  }
  StructuredData::Dictionary *dict = object_sp->GetAsDictionary();
  if (!dict) {
    LLDB_LOGF(log, "Unable to read 'process metadata' LC_NOTE, did not "
                   "get a dictionary.");
    return {};
  }

  return object_sp;
}

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_nsp, thread_context_file_range->GetRangeBase(),
                         thread_context_file_range->GetByteSize());

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

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

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

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

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

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

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

      return eStrataKernel;
    }
  }
    return eStrataUnknown;

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

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

llvm::VersionTuple ObjectFileMachO::GetVersion() {
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
    llvm::MachO::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 (!ReadMachOCommand(*m_data_nsp, offset, load_cmd))
        break;

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

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

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

    return GetArchitecture(module_sp, m_header, *m_data_nsp,
                           MachHeaderSizeFromMagic(m_header.magic));
  }
  return arch;
}

void ObjectFileMachO::GetProcessSharedCacheUUID(Process *process,
                                                addr_t &base_addr, UUID &uuid) {
  uuid.Clear();
  base_addr = LLDB_INVALID_ADDRESS;
  if (process && process->GetDynamicLoader()) {
    DynamicLoader *dl = process->GetDynamicLoader();
    LazyBool using_shared_cache;
    LazyBool private_shared_cache;
    FileSpec sc_filepath;
    std::optional<uint64_t> size;
    dl->GetSharedCacheInformation(base_addr, uuid, using_shared_cache,
                                  private_shared_cache, sc_filepath, size);
  }
  Log *log(GetLog(LLDBLog::Symbols | LLDBLog::Process));
  LLDB_LOGF(
      log,
      "inferior process shared cache has a UUID of %s, base address 0x%" PRIx64,
      uuid.GetAsString().c_str(), base_addr);
}

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

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

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

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

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

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

static llvm::VersionTuple FindMinimumVersionInfo(DataExtractor &data,
                                                 lldb::offset_t offset,
                                                 size_t ncmds) {
  for (size_t i = 0; i < ncmds; i++) {
    const lldb::offset_t load_cmd_offset = offset;
    llvm::MachO::load_command lc = {};
    if (!ReadMachOCommand(data, offset, lc))
      break;

    uint32_t version = 0;
    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) {
      // struct version_min_command {
      //   uint32_t cmd; // LC_VERSION_MIN_*
      //   uint32_t cmdsize;
      //   uint32_t version; // X.Y.Z encoded in nibbles xxxx.yy.zz
      //   uint32_t sdk;
      // };
      // We want to read version.
      version = data.GetU32(&offset);
    } else if (lc.cmd == llvm::MachO::LC_BUILD_VERSION) {
      // struct build_version_command {
      //   uint32_t cmd; // LC_BUILD_VERSION
      //   uint32_t cmdsize;
      //   uint32_t platform;
      //   uint32_t minos; // X.Y.Z encoded in nibbles xxxx.yy.zz
      //   uint32_t sdk;
      //   uint32_t ntools;
      // };
      // We want to read minos.
      offset += sizeof(uint32_t);     // Skip over platform
      version = data.GetU32(&offset); // Extract minos
    }

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

llvm::VersionTuple ObjectFileMachO::GetMinimumOSVersion() {
  if (!m_min_os_version)
    m_min_os_version = FindMinimumVersionInfo(
        *m_data_nsp, MachHeaderSizeFromMagic(m_header.magic), m_header.ncmds);
  return *m_min_os_version;
}

llvm::VersionTuple ObjectFileMachO::GetSDKVersion() {
  if (!m_sdk_versions)
    m_sdk_versions = FindMinimumVersionInfo(
        *m_data_nsp, MachHeaderSizeFromMagic(m_header.magic), m_header.ncmds);
  return *m_sdk_versions;
}

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

bool ObjectFileMachO::CanTrustAddressRanges() {
  // Dsymutil guarantees that the .debug_aranges accelerator is complete and can
  // be trusted by LLDB.
  return m_header.filetype == llvm::MachO::MH_DSYM;
}

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

Section *ObjectFileMachO::GetMachHeaderSection() {
  // Find the first address of the mach header which is the first non-zero file
  // sized section whose file offset is zero. This is the base file address of
  // the mach-o file which can be subtracted from the vmaddr of the other
  // segments found in memory and added to the load address
  ModuleSP module_sp = GetModule();
  if (!module_sp)
    return nullptr;
  SectionList *section_list = GetSectionList();
  if (!section_list)
    return nullptr;

  // Some binaries can have a TEXT segment with a non-zero file offset.
  // Binaries in the shared cache are one example.  Some hand-generated
  // binaries may not be laid out in the normal TEXT,DATA,LC_SYMTAB order
  // in the file, even though they're laid out correctly in vmaddr terms.
  SectionSP text_segment_sp =
      section_list->FindSectionByName(GetSegmentNameTEXT());
  if (text_segment_sp.get() && SectionIsLoadable(text_segment_sp.get()))
    return text_segment_sp.get();

  const size_t num_sections = section_list->GetSize();
  for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
    Section *section = section_list->GetSectionAtIndex(sect_idx).get();
    if (section->GetFileOffset() == 0 && SectionIsLoadable(section))
      return section;
  }

  return nullptr;
}

bool ObjectFileMachO::IsGOTSection(const lldb_private::Section &section) const {
  assert(section.GetObjectFile() == this && "Wrong object file!");
  SectionSP segment = section.GetParent();
  if (!segment)
    return false;

  const bool is_data_const_got =
      segment->GetName() == "__DATA_CONST" && section.GetName() == "__got";
  const bool is_auth_const_ptr =
      segment->GetName() == "__AUTH_CONST" &&
      (section.GetName() == "__auth_got" || section.GetName() == "__auth_ptr");
  return is_data_const_got || is_auth_const_ptr;
}

bool ObjectFileMachO::SectionIsLoadable(const Section *section) {
  if (!section)
    return false;
  if (section->IsThreadSpecific())
    return false;
  if (GetModule().get() != section->GetModule().get())
    return false;
  // firmware style binaries with llvm gcov segment do
  // not have that segment mapped into memory.
  if (section->GetName() == GetSegmentNameLLVM_COV()) {
    const Strata strata = GetStrata();
    if (strata == eStrataKernel || strata == eStrataRawImage)
      return false;
  }
  // Be careful with __LINKEDIT and __DWARF segments
  if (section->GetName() == GetSegmentNameLINKEDIT() ||
      section->GetName() == GetSegmentNameDWARF()) {
    // Only map __LINKEDIT and __DWARF if we have an in memory image and
    // this isn't a kernel binary like a kext or mach_kernel.
    const bool is_memory_image = (bool)m_process_wp.lock();
    const Strata strata = GetStrata();
    if (is_memory_image == false || strata == eStrataKernel)
      return false;
  }
  return true;
}

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

bool ObjectFileMachO::SetLoadAddress(Target &target, lldb::addr_t value,
                                     bool value_is_offset) {
  Log *log(GetLog(LLDBLog::DynamicLoader));
  ModuleSP module_sp = GetModule();
  if (!module_sp)
    return false;

  SectionList *section_list = GetSectionList();
  if (!section_list)
    return false;

  size_t num_loaded_sections = 0;
  const size_t num_sections = section_list->GetSize();

  // Warn if some top-level segments map to the same address. The binary may be
  // malformed.
  const bool warn_multiple = true;

  if (log) {
    StreamString logmsg;
    logmsg << "ObjectFileMachO::SetLoadAddress ";
    if (GetFileSpec())
      logmsg << "path='" << GetFileSpec().GetPath() << "' ";
    if (GetUUID()) {
      logmsg << "uuid=" << GetUUID().GetAsString();
    }
    LLDB_LOGF(log, "%s", logmsg.GetData());
  }
  if (value_is_offset) {
    // "value" is an offset to apply to each top level segment
    for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
      // Iterate through the object file sections to find all of the
      // sections that size on disk (to avoid __PAGEZERO) and load them
      SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
      if (SectionIsLoadable(section_sp.get())) {
        LLDB_LOG(
            log,
            "ObjectFileMachO::SetLoadAddress segment '{0}' load addr is {1:x}",
            section_sp->GetName(), section_sp->GetFileAddress() + value);
        if (target.SetSectionLoadAddress(section_sp,
                                         section_sp->GetFileAddress() + value,
                                         warn_multiple))
          ++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) {
          LLDB_LOG(log,
                   "ObjectFileMachO::SetLoadAddress segment '{0}' load addr is "
                   "{1:x}",
                   section_sp->GetName(), section_load_addr);
          if (target.SetSectionLoadAddress(section_sp, section_load_addr,
                                           warn_multiple))
            ++num_loaded_sections;
        }
      }
    }
  }
  return num_loaded_sections > 0;
}

struct all_image_infos_header {
  uint32_t version;         // currently 1
  uint32_t imgcount;        // number of binary images
  uint64_t entries_fileoff; // file offset in the corefile of where the array of
                            // struct entry's begin.
  uint32_t entries_size;    // size of 'struct entry'.
  uint32_t unused;
};

struct image_entry {
  uint64_t filepath_offset;  // offset in corefile to c-string of the file path,
                             // UINT64_MAX if unavailable.
  uuid_t uuid;               // uint8_t[16].  should be set to all zeroes if
                             // uuid is unknown.
  uint64_t load_address;     // UINT64_MAX if unknown.
  uint64_t seg_addrs_offset; // offset to the array of struct segment_vmaddr's.
  uint32_t segment_count;    // The number of segments for this binary.
  uint32_t unused;

  image_entry() {
    filepath_offset = UINT64_MAX;
    memset(&uuid, 0, sizeof(uuid_t));
    segment_count = 0;
    load_address = UINT64_MAX;
    seg_addrs_offset = UINT64_MAX;
    unused = 0;
  }
  image_entry(const image_entry &rhs) {
    filepath_offset = rhs.filepath_offset;
    memcpy(&uuid, &rhs.uuid, sizeof(uuid_t));
    segment_count = rhs.segment_count;
    seg_addrs_offset = rhs.seg_addrs_offset;
    load_address = rhs.load_address;
    unused = rhs.unused;
  }
};

struct segment_vmaddr {
  char segname[16];
  uint64_t vmaddr;
  uint64_t unused;

  segment_vmaddr() {
    memset(&segname, 0, 16);
    vmaddr = UINT64_MAX;
    unused = 0;
  }
  segment_vmaddr(const segment_vmaddr &rhs) {
    memcpy(&segname, &rhs.segname, 16);
    vmaddr = rhs.vmaddr;
    unused = rhs.unused;
  }
};

// Write the payload for the "all image infos" LC_NOTE into
// the supplied all_image_infos_payload, assuming that this
// will be written into the corefile starting at
// initial_file_offset.
//
// The placement of this payload is a little tricky.  We're
// laying this out as
//
// 1. header (struct all_image_info_header)
// 2. Array of fixed-size (struct image_entry)'s, one
//    per binary image present in the process.
// 3. Arrays of (struct segment_vmaddr)'s, a varying number
//    for each binary image.
// 4. Variable length c-strings of binary image filepaths,
//    one per binary.
//
// To compute where everything will be laid out in the
// payload, we need to iterate over the images and calculate
// how many segment_vmaddr structures each image will need,
// and how long each image's filepath c-string is. There
// are some multiple passes over the image list while calculating
// everything.

static offset_t
CreateAllImageInfosPayload(const lldb::ProcessSP &process_sp,
                           offset_t initial_file_offset,
                           StreamString &all_image_infos_payload,
                           lldb_private::SaveCoreOptions &options) {
  Target &target = process_sp->GetTarget();
  ModuleList modules = target.GetImages();

  // stack-only corefiles have no reason to include binaries that
  // are not executing; we're trying to make the smallest corefile
  // we can, so leave the rest out.
  if (options.GetStyle() == SaveCoreStyle::eSaveCoreStackOnly)
    modules.Clear();

  std::set<std::string> executing_uuids;
  std::vector<ThreadSP> thread_list =
      process_sp->CalculateCoreFileThreadList(options);
  for (const ThreadSP &thread_sp : thread_list) {
    uint32_t stack_frame_count = thread_sp->GetStackFrameCount();
    for (uint32_t j = 0; j < stack_frame_count; j++) {
      StackFrameSP stack_frame_sp = thread_sp->GetStackFrameAtIndex(j);
      Address pc = stack_frame_sp->GetFrameCodeAddress();
      ModuleSP module_sp = pc.GetModule();
      if (module_sp) {
        UUID uuid = module_sp->GetUUID();
        if (uuid.IsValid()) {
          executing_uuids.insert(uuid.GetAsString());
          modules.AppendIfNeeded(module_sp);
        }
      }
    }
  }
  size_t modules_count = modules.GetSize();

  struct all_image_infos_header infos;
  infos.version = 1;
  infos.imgcount = modules_count;
  infos.entries_size = sizeof(image_entry);
  infos.entries_fileoff = initial_file_offset + sizeof(all_image_infos_header);
  infos.unused = 0;

  all_image_infos_payload.PutHex32(infos.version);
  all_image_infos_payload.PutHex32(infos.imgcount);
  all_image_infos_payload.PutHex64(infos.entries_fileoff);
  all_image_infos_payload.PutHex32(infos.entries_size);
  all_image_infos_payload.PutHex32(infos.unused);

  // First create the structures for all of the segment name+vmaddr vectors
  // for each module, so we will know the size of them as we add the
  // module entries.
  std::vector<std::vector<segment_vmaddr>> modules_segment_vmaddrs;
  for (size_t i = 0; i < modules_count; i++) {
    ModuleSP module = modules.GetModuleAtIndex(i);

    SectionList *sections = module->GetSectionList();
    size_t sections_count = sections->GetSize();
    std::vector<segment_vmaddr> segment_vmaddrs;
    for (size_t j = 0; j < sections_count; j++) {
      SectionSP section = sections->GetSectionAtIndex(j);
      if (!section->GetParent().get()) {
        addr_t vmaddr = section->GetLoadBaseAddress(&target);
        if (vmaddr == LLDB_INVALID_ADDRESS)
          continue;
        llvm::StringRef name = section->GetName();
        segment_vmaddr seg_vmaddr;
        // This is the uncommon case where strncpy is exactly
        // the right one, doesn't need to be nul terminated.
        // The segment name in a Mach-O LC_SEGMENT/LC_SEGMENT_64 is char[16] and
        // is not guaranteed to be nul-terminated if all 16 characters are
        // used.
        // coverity[buffer_size_warning]
        strncpy(seg_vmaddr.segname, name.data(),
                std::min(name.size(), sizeof(seg_vmaddr.segname)));
        seg_vmaddr.vmaddr = vmaddr;
        seg_vmaddr.unused = 0;
        segment_vmaddrs.push_back(seg_vmaddr);
      }
    }
    modules_segment_vmaddrs.push_back(segment_vmaddrs);
  }

  offset_t size_of_vmaddr_structs = 0;
  for (size_t i = 0; i < modules_segment_vmaddrs.size(); i++) {
    size_of_vmaddr_structs +=
        modules_segment_vmaddrs[i].size() * sizeof(segment_vmaddr);
  }

  offset_t size_of_filepath_cstrings = 0;
  for (size_t i = 0; i < modules_count; i++) {
    ModuleSP module_sp = modules.GetModuleAtIndex(i);
    size_of_filepath_cstrings += module_sp->GetFileSpec().GetPath().size() + 1;
  }

  // Calculate the file offsets of our "all image infos" payload in the
  // corefile. initial_file_offset the original value passed in to this method.

  offset_t start_of_entries =
      initial_file_offset + sizeof(all_image_infos_header);
  offset_t start_of_seg_vmaddrs =
      start_of_entries + sizeof(image_entry) * modules_count;
  offset_t start_of_filenames = start_of_seg_vmaddrs + size_of_vmaddr_structs;

  offset_t final_file_offset = start_of_filenames + size_of_filepath_cstrings;

  // Now write the one-per-module 'struct image_entry' into the
  // StringStream; keep track of where the struct segment_vmaddr
  // entries for each module will end up in the corefile.

  offset_t current_string_offset = start_of_filenames;
  offset_t current_segaddrs_offset = start_of_seg_vmaddrs;
  for (size_t i = 0; i < modules_count; i++) {
    ModuleSP module_sp = modules.GetModuleAtIndex(i);

    struct image_entry ent;
    memcpy(&ent.uuid, module_sp->GetUUID().GetBytes().data(), sizeof(ent.uuid));
    if (modules_segment_vmaddrs[i].size() > 0) {
      ent.segment_count = modules_segment_vmaddrs[i].size();
      ent.seg_addrs_offset = current_segaddrs_offset;
    }
    ent.filepath_offset = current_string_offset;
    ObjectFile *objfile = module_sp->GetObjectFile();
    if (objfile) {
      Address base_addr(objfile->GetBaseAddress());
      if (base_addr.IsValid()) {
        ent.load_address = base_addr.GetLoadAddress(&target);
      }
    }

    all_image_infos_payload.PutHex64(ent.filepath_offset);
    all_image_infos_payload.PutRawBytes(ent.uuid, sizeof(ent.uuid));
    all_image_infos_payload.PutHex64(ent.load_address);
    all_image_infos_payload.PutHex64(ent.seg_addrs_offset);
    all_image_infos_payload.PutHex32(ent.segment_count);

    if (executing_uuids.find(module_sp->GetUUID().GetAsString()) !=
        executing_uuids.end())
      all_image_infos_payload.PutHex32(1);
    else
      all_image_infos_payload.PutHex32(0);

    current_segaddrs_offset += ent.segment_count * sizeof(segment_vmaddr);
    current_string_offset += module_sp->GetFileSpec().GetPath().size() + 1;
  }

  // Now write the struct segment_vmaddr entries into the StringStream.

  for (size_t i = 0; i < modules_segment_vmaddrs.size(); i++) {
    if (modules_segment_vmaddrs[i].size() == 0)
      continue;
    for (struct segment_vmaddr segvm : modules_segment_vmaddrs[i]) {
      all_image_infos_payload.PutRawBytes(segvm.segname, sizeof(segvm.segname));
      all_image_infos_payload.PutHex64(segvm.vmaddr);
      all_image_infos_payload.PutHex64(segvm.unused);
    }
  }

  for (size_t i = 0; i < modules_count; i++) {
    ModuleSP module_sp = modules.GetModuleAtIndex(i);
    std::string filepath = module_sp->GetFileSpec().GetPath();
    all_image_infos_payload.PutRawBytes(filepath.data(), filepath.size() + 1);
  }

  return final_file_offset;
}

// Temp struct used to combine contiguous memory regions with
// identical permissions.
struct page_object {
  addr_t addr;
  addr_t size;
  uint32_t prot;
};

bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
                               lldb_private::SaveCoreOptions &options,
                               Status &error) {
  // The FileSpec and Process are already checked in PluginManager::SaveCore.
  assert(options.GetOutputFile().has_value());
  assert(process_sp);
  const FileSpec outfile = options.GetOutputFile().value();

  // MachO defaults to dirty pages
  if (options.GetStyle() == SaveCoreStyle::eSaveCoreUnspecified)
    options.SetStyle(eSaveCoreDirtyOnly);

  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 ||
       target_triple.getOS() == llvm::Triple::BridgeOS ||
       target_triple.getOS() == llvm::Triple::XROS)) {
    bool make_core = false;
    switch (target_arch.GetMachine()) {
    case llvm::Triple::aarch64:
    case llvm::Triple::aarch64_32:
    case llvm::Triple::arm:
    case llvm::Triple::thumb:
    case llvm::Triple::x86:
    case llvm::Triple::x86_64:
      make_core = true;
      break;
    default:
      error = Status::FromErrorStringWithFormat(
          "unsupported core architecture: %s", target_triple.str().c_str());
      break;
    }

    if (make_core) {
      CoreFileMemoryRanges core_ranges;
      error = process_sp->CalculateCoreFileSaveRanges(options, core_ranges);
      if (error.Success()) {
        const uint32_t addr_byte_size = target_arch.GetAddressByteSize();
        const ByteOrder byte_order = target_arch.GetByteOrder();
        std::vector<llvm::MachO::segment_command_64> segment_load_commands;
        for (const auto &core_range_info : core_ranges) {
          // TODO: Refactor RangeDataVector to have a data iterator.
          const auto &core_range = core_range_info.data;
          uint32_t cmd_type = LC_SEGMENT_64;
          uint32_t segment_size = sizeof(llvm::MachO::segment_command_64);
          if (addr_byte_size == 4) {
            cmd_type = LC_SEGMENT;
            segment_size = sizeof(llvm::MachO::segment_command);
          }
          // Skip any ranges with no read/write/execute permissions and empty
          // ranges.
          if (core_range.lldb_permissions == 0 || core_range.range.size() == 0)
            continue;
          uint32_t vm_prot = 0;
          if (core_range.lldb_permissions & ePermissionsReadable)
            vm_prot |= VM_PROT_READ;
          if (core_range.lldb_permissions & ePermissionsWritable)
            vm_prot |= VM_PROT_WRITE;
          if (core_range.lldb_permissions & ePermissionsExecutable)
            vm_prot |= VM_PROT_EXECUTE;
          const addr_t vm_addr = core_range.range.start();
          const addr_t vm_size = core_range.range.size();
          llvm::MachO::segment_command_64 segment = {
              cmd_type,     // uint32_t cmd;
              segment_size, // uint32_t cmdsize;
              {0},          // char segname[16];
              vm_addr,      // uint64_t vmaddr;   // uint32_t for 32-bit Mach-O
              vm_size,      // uint64_t vmsize;   // uint32_t for 32-bit Mach-O
              0,            // uint64_t fileoff;  // uint32_t for 32-bit Mach-O
              vm_size,      // uint64_t filesize; // uint32_t for 32-bit Mach-O
              vm_prot,      // uint32_t maxprot;
              vm_prot,      // uint32_t initprot;
              0,            // uint32_t nsects;
              0};           // uint32_t flags;
          segment_load_commands.push_back(segment);
        }

        StreamString buffer(Stream::eBinary, byte_order);

        llvm::MachO::mach_header_64 mach_header;
        mach_header.magic = addr_byte_size == 8 ? MH_MAGIC_64 : 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.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:
            case llvm::MachO::CPU_TYPE_ARM64_32:
              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_X86_64:
              RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD(
                  thread_sp.get(), LC_THREAD_datas[thread_idx]);
              break;

            case llvm::MachO::CPU_TYPE_RISCV:
              RegisterContextDarwin_riscv32_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(llvm::MachO::segment_command_64);
        } else {
          mach_header.sizeofcmds = segment_load_commands.size() *
                                   sizeof(llvm::MachO::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();
        }

        // Bits will be set to indicate which bits are NOT used in
        // addressing in this process or 0 for unknown.
        uint64_t address_mask = process_sp->GetCodeAddressMask();
        if (address_mask != LLDB_INVALID_ADDRESS_MASK) {
          // LC_NOTE "addrable bits"
          mach_header.ncmds++;
          mach_header.sizeofcmds += sizeof(llvm::MachO::note_command);
        }

        // LC_NOTE "process metadata"
        mach_header.ncmds++;
        mach_header.sizeofcmds += sizeof(llvm::MachO::note_command);

        // LC_NOTE "all image infos"
        mach_header.ncmds++;
        mach_header.sizeofcmds += sizeof(llvm::MachO::note_command);

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

        file_offset = llvm::alignTo(file_offset, 16);
        std::vector<std::unique_ptr<LCNoteEntry>> lc_notes;

        // Add "addrable bits" LC_NOTE when an address mask is available
        if (address_mask != LLDB_INVALID_ADDRESS_MASK) {
          std::unique_ptr<LCNoteEntry> addrable_bits_lcnote_up(
              new LCNoteEntry(byte_order));
          addrable_bits_lcnote_up->name = "addrable bits";
          addrable_bits_lcnote_up->payload_file_offset = file_offset;
          int bits = std::bitset<64>(~address_mask).count();
          addrable_bits_lcnote_up->payload.PutHex32(4); // version
          addrable_bits_lcnote_up->payload.PutHex32(
              bits); // # of bits used for low addresses
          addrable_bits_lcnote_up->payload.PutHex32(
              bits); // # of bits used for high addresses
          addrable_bits_lcnote_up->payload.PutHex32(0); // reserved

          file_offset += addrable_bits_lcnote_up->payload.GetSize();

          lc_notes.push_back(std::move(addrable_bits_lcnote_up));
        }

        // Add "process metadata" LC_NOTE
        std::unique_ptr<LCNoteEntry> thread_extrainfo_lcnote_up(
            new LCNoteEntry(byte_order));
        thread_extrainfo_lcnote_up->name = "process metadata";
        thread_extrainfo_lcnote_up->payload_file_offset = file_offset;

        StructuredData::DictionarySP dict(
            std::make_shared<StructuredData::Dictionary>());
        StructuredData::ArraySP threads(
            std::make_shared<StructuredData::Array>());
        for (const ThreadSP &thread_sp :
             process_sp->CalculateCoreFileThreadList(options)) {
          StructuredData::DictionarySP thread(
              std::make_shared<StructuredData::Dictionary>());
          thread->AddIntegerItem("thread_id", thread_sp->GetID());
          threads->AddItem(thread);
        }
        dict->AddItem("threads", threads);
        StreamString strm;
        dict->Dump(strm, /* pretty */ false);
        thread_extrainfo_lcnote_up->payload.PutRawBytes(strm.GetData(),
                                                        strm.GetSize());

        file_offset += thread_extrainfo_lcnote_up->payload.GetSize();
        file_offset = llvm::alignTo(file_offset, 16);
        lc_notes.push_back(std::move(thread_extrainfo_lcnote_up));

        // Add "all image infos" LC_NOTE
        std::unique_ptr<LCNoteEntry> all_image_infos_lcnote_up(
            new LCNoteEntry(byte_order));
        all_image_infos_lcnote_up->name = "all image infos";
        all_image_infos_lcnote_up->payload_file_offset = file_offset;
        file_offset = CreateAllImageInfosPayload(
            process_sp, file_offset, all_image_infos_lcnote_up->payload,
            options);
        lc_notes.push_back(std::move(all_image_infos_lcnote_up));

        // Add LC_NOTE load commands
        for (auto &lcnote : lc_notes) {
          // Add the LC_NOTE load command to the file.
          buffer.PutHex32(LC_NOTE);
          buffer.PutHex32(sizeof(llvm::MachO::note_command));
          char namebuf[16];
          memset(namebuf, 0, sizeof(namebuf));
          // This is the uncommon case where strncpy is exactly
          // the right one, doesn't need to be nul terminated.
          // LC_NOTE name field is char[16] and is not guaranteed to be
          // nul-terminated.
          // coverity[buffer_size_warning]
          strncpy(namebuf, lcnote->name.c_str(), sizeof(namebuf));
          buffer.PutRawBytes(namebuf, sizeof(namebuf));
          buffer.PutHex64(lcnote->payload_file_offset);
          buffer.PutHex64(lcnote->payload.GetSize());
        }

        // Align to 4096-byte page boundary for the LC_SEGMENTs.
        file_offset = llvm::alignTo(file_offset, 4096);

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

        std::string core_file_path(outfile.GetPath());
        auto core_file = FileSystem::Instance().Open(
            outfile, File::eOpenOptionWriteOnly | File::eOpenOptionTruncate |
                         File::eOpenOptionCanCreate);
        if (!core_file) {
          error = Status::FromError(core_file.takeError());
        } else {
          // 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.get()->Write(buffer.GetString().data(), bytes_written);
          if (error.Success()) {

            for (auto &lcnote : lc_notes) {
              if (core_file.get()->SeekFromStart(lcnote->payload_file_offset) ==
                  -1) {
                error = Status::FromErrorStringWithFormat(
                    "Unable to seek to corefile pos "
                    "to write '%s' LC_NOTE payload",
                    lcnote->name.c_str());
                return false;
              }
              bytes_written = lcnote->payload.GetSize();
              error = core_file.get()->Write(lcnote->payload.GetData(),
                                             bytes_written);
              if (!error.Success())
                return false;
            }

            // Now write the file data for all memory segments in the process
            for (const auto &segment : segment_load_commands) {
              if (core_file.get()->SeekFromStart(segment.fileoff) == -1) {
                error = Status::FromErrorStringWithFormat(
                    "unable to seek to offset 0x%" PRIx64 " in '%s'",
                    segment.fileoff, core_file_path.c_str());
                break;
              }

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

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

                if (bytes_read == bytes_to_read) {
                  size_t bytes_written = bytes_read;
                  error = core_file.get()->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.get()->Write(bytes, bytes_written);
                  bytes_left -= bytes_to_read;
                  addr += bytes_to_read;
                }
              }
            }
          }
        }
      }
    }
    return true; // This is the right plug to handle saving core files for
                 // this process
  }
  return false;
}

ObjectFileMachO::MachOCorefileAllImageInfos
ObjectFileMachO::GetCorefileAllImageInfos() {
  MachOCorefileAllImageInfos image_infos;
  Log *log(GetLog(LLDBLog::Object | LLDBLog::Symbols | LLDBLog::Process |
                  LLDBLog::DynamicLoader));

  auto lc_notes = FindLC_NOTEByName("all image infos");
  for (auto lc_note : lc_notes) {
    offset_t payload_offset = std::get<0>(lc_note);
    // Read the struct all_image_infos_header.
    uint32_t version = m_data_nsp->GetU32(&payload_offset);
    if (version != 1) {
      return image_infos;
    }
    uint32_t imgcount = m_data_nsp->GetU32(&payload_offset);
    uint64_t entries_fileoff = m_data_nsp->GetU64(&payload_offset);
    // 'entries_size' is not used, nor is the 'unused' entry.
    //  offset += 4; // uint32_t entries_size;
    //  offset += 4; // uint32_t unused;

    LLDB_LOGF(log, "LC_NOTE 'all image infos' found version %d with %d images",
              version, imgcount);
    payload_offset = entries_fileoff;
    for (uint32_t i = 0; i < imgcount; i++) {
      // Read the struct image_entry.
      offset_t filepath_offset = m_data_nsp->GetU64(&payload_offset);
      uuid_t uuid;
      memcpy(&uuid, m_data_nsp->GetData(&payload_offset, sizeof(uuid_t)),
             sizeof(uuid_t));
      uint64_t load_address = m_data_nsp->GetU64(&payload_offset);
      offset_t seg_addrs_offset = m_data_nsp->GetU64(&payload_offset);
      uint32_t segment_count = m_data_nsp->GetU32(&payload_offset);
      uint32_t currently_executing = m_data_nsp->GetU32(&payload_offset);

      MachOCorefileImageEntry image_entry;
      image_entry.filename =
          (const char *)m_data_nsp->GetCStr(&filepath_offset);
      image_entry.uuid = UUID(uuid, sizeof(uuid_t));
      image_entry.load_address = load_address;
      image_entry.currently_executing = currently_executing;

      offset_t seg_vmaddrs_offset = seg_addrs_offset;
      for (uint32_t j = 0; j < segment_count; j++) {
        char segname[17];
        m_data_nsp->CopyData(seg_vmaddrs_offset, 16, segname);
        segname[16] = '\0';
        seg_vmaddrs_offset += 16;
        uint64_t vmaddr = m_data_nsp->GetU64(&seg_vmaddrs_offset);
        seg_vmaddrs_offset += 8; /* unused */

        std::tuple<ConstString, addr_t> new_seg{ConstString(segname), vmaddr};
        image_entry.segment_load_addresses.push_back(new_seg);
      }
      LLDB_LOGF(log, "  image entry: %s %s 0x%" PRIx64 " %s",
                image_entry.filename.c_str(),
                image_entry.uuid.GetAsString().c_str(),
                image_entry.load_address,
                image_entry.currently_executing ? "currently executing"
                                                : "not currently executing");
      image_infos.all_image_infos.push_back(image_entry);
    }
  }

  lc_notes = FindLC_NOTEByName("load binary");
  for (auto lc_note : lc_notes) {
    offset_t payload_offset = std::get<0>(lc_note);
    uint32_t version = m_data_nsp->GetU32(&payload_offset);
    if (version == 1) {
      uuid_t uuid;
      memcpy(&uuid, m_data_nsp->GetData(&payload_offset, sizeof(uuid_t)),
             sizeof(uuid_t));
      uint64_t load_address = m_data_nsp->GetU64(&payload_offset);
      uint64_t slide = m_data_nsp->GetU64(&payload_offset);
      std::string filename = m_data_nsp->GetCStr(&payload_offset);

      MachOCorefileImageEntry image_entry;
      image_entry.filename = filename;
      image_entry.uuid = UUID(uuid, sizeof(uuid_t));
      image_entry.load_address = load_address;
      image_entry.slide = slide;
      image_entry.currently_executing = true;
      image_infos.all_image_infos.push_back(image_entry);
      LLDB_LOGF(log,
                "LC_NOTE 'load binary' found, filename %s uuid %s load "
                "address 0x%" PRIx64 " slide 0x%" PRIx64,
                filename.c_str(),
                image_entry.uuid.IsValid()
                    ? image_entry.uuid.GetAsString().c_str()
                    : "00000000-0000-0000-0000-000000000000",
                load_address, slide);
    }
  }

  return image_infos;
}

bool ObjectFileMachO::LoadCoreFileImages(lldb_private::Process &process) {
  MachOCorefileAllImageInfos image_infos = GetCorefileAllImageInfos();
  Log *log = GetLog(LLDBLog::Object | LLDBLog::DynamicLoader);

  bool found_platform_binary = false;
  ModuleList added_modules;

  llvm::SmallVector<const MachOCorefileImageEntry *> pending_images;
  std::vector<DynamicLoader::BinarySpec> pending_specs;

  for (MachOCorefileImageEntry &image : image_infos.all_image_infos) {
    // If this is a platform binary, it has been loaded (or registered with
    // the DynamicLoader to be loaded), we don't need to do any further
    // processing.  We're not going to call ModulesDidLoad on this in this
    // method, so notify==true.
    //
    // Setting up a platform binary can replace the Target's platform and
    // dynamic loader, so no image is searched for until this loop has run to
    // the end.
    if (process.GetTarget()
            .GetDebugger()
            .GetPlatformList()
            .LoadPlatformBinaryAndSetup(&process, image.load_address,
                                        true /* notify */)) {
      LLDB_LOGF(log,
                "ObjectFileMachO::%s binary at 0x%" PRIx64
                " is a platform binary, has been handled by a Platform plugin.",
                __FUNCTION__, image.load_address);
      found_platform_binary = true;
      continue;
    }

    bool value_is_offset = image.load_address == LLDB_INVALID_ADDRESS;
    uint64_t value = value_is_offset ? image.slide : image.load_address;
    if (value_is_offset && value == LLDB_INVALID_ADDRESS) {
      // We have neither address nor slide; so we will find the binary
      // by UUID and load it at slide/offset 0.
      value = 0;
    }

    // We have either a UUID, or we have a load address which
    // and can try to read load commands and find a UUID.
    if (!image.uuid.IsValid() &&
        (value_is_offset || value == LLDB_INVALID_ADDRESS))
      continue;

    DynamicLoader::BinarySpec bin_spec;
    bin_spec.name = image.filename;
    bin_spec.uuid = image.uuid;
    bin_spec.value = value;
    bin_spec.value_is_offset = value_is_offset;
    bin_spec.force_symbol_search = image.currently_executing;
    bin_spec.notify = false;
    // Userland Darwin binaries will have segment load addresses via
    // the `all image infos` LC_NOTE.
    bin_spec.set_address_in_target = image.segment_load_addresses.empty();
    bin_spec.allow_memory_image_last_resort =
        !image.segment_load_addresses.empty();

    pending_images.push_back(&image);
    pending_specs.push_back(std::move(bin_spec));
  }

  DynamicLoader::LocateBinaries(&process, pending_specs);

  for (auto [image, bin_spec] :
       llvm::zip_equal(pending_images, pending_specs)) {
    ModuleSP module_sp;
    if (llvm::Expected<ModuleSP> loaded =
            DynamicLoader::LoadBinaryInTarget(&process, bin_spec)) {
      module_sp = *loaded;
    } else if (bin_spec.force_symbol_search) {
      *process.GetTarget().GetDebugger().GetAsyncErrorStream()
          << llvm::toString(loaded.takeError()) << "\n";
    } else {
      // A corefile image that isn't on this machine is routine, and has
      // already been logged.
      llvm::consumeError(loaded.takeError());
    }

    if (!module_sp)
      continue;

    added_modules.Append(module_sp, false /* notify */);

    // We have a list of segment load address
    if (image->segment_load_addresses.size() > 0) {
      if (log) {
        std::string uuidstr = image->uuid.GetAsString();
        log->Printf("ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
                    "UUID %s with section load addresses",
                    module_sp->GetFileSpec().GetPath().c_str(),
                    uuidstr.c_str());
      }
      ObjectFile *objfile = module_sp->GetObjectFile();
      SectionList *sectlist = objfile ? objfile->GetSectionList() : nullptr;
      for (auto name_vmaddr_tuple : image->segment_load_addresses) {
        if (sectlist) {
          SectionSP sect_sp =
              sectlist->FindSectionByName(std::get<0>(name_vmaddr_tuple));
          if (sect_sp) {
            process.GetTarget().SetSectionLoadAddress(
                sect_sp, std::get<1>(name_vmaddr_tuple));
          }
        }
      }
    } else {
      if (log) {
        std::string uuidstr = image->uuid.GetAsString();
        log->Printf("ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
                    "UUID %s with %s 0x%" PRIx64,
                    module_sp->GetFileSpec().GetPath().c_str(), uuidstr.c_str(),
                    bin_spec.value_is_offset ? "slide" : "load address",
                    bin_spec.value);
      }
      bool changed;
      module_sp->SetLoadAddress(process.GetTarget(), bin_spec.value,
                                bin_spec.value_is_offset, changed);
    }
  }

  if (added_modules.GetSize() > 0) {
    process.GetTarget().ModulesDidLoad(added_modules);
    process.Flush();
    return true;
  }
  // Return true if the only binary we found was the platform binary,
  // and it was loaded outside the scope of this method.
  if (found_platform_binary)
    return true;

  // No binaries.
  return false;
}
