//===-- MinidumpFileBuilder.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 "MinidumpFileBuilder.h"

#include "Plugins/Process/minidump/RegisterContextMinidump_ARM64.h"
#include "Plugins/Process/minidump/RegisterContextMinidump_x86_64.h"

#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/Section.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/ThreadList.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RangeMap.h"
#include "lldb/Utility/RegisterValue.h"

#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Minidump.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/TargetParser/Triple.h"

#include "Plugins/Process/minidump/MinidumpTypes.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-types.h"

#include <algorithm>
#include <cinttypes>
#include <cstddef>
#include <cstdint>
#include <utility>

using namespace lldb;
using namespace lldb_private;
using namespace llvm::minidump;

Status MinidumpFileBuilder::AddHeaderAndCalculateDirectories() {
  // First set the offset on the file, and on the bytes saved
  m_saved_data_size = HEADER_SIZE;
  // We know we will have at least Misc, SystemInfo, Modules, and ThreadList
  // (corresponding memory list for stacks), an additional memory list for
  // non-stacks, and a stream to mark this minidump was generated by LLDB.
  lldb_private::Target &target = m_process_sp->GetTarget();
  m_expected_directories = 6;
  // Check if OS is linux and reserve directory space for all linux specific
  // breakpad extension directories.
  if (target.GetArchitecture().GetTriple().getOS() ==
      llvm::Triple::OSType::Linux)
    m_expected_directories += 9;

  // Go through all of the threads and check for exceptions.
  std::vector<lldb::ThreadSP> threads =
      m_process_sp->CalculateCoreFileThreadList(m_save_core_options);
  for (const ThreadSP &thread_sp : threads) {
    StopInfoSP stop_info_sp = thread_sp->GetStopInfo();
    if (stop_info_sp) {
      const StopReason &stop_reason = stop_info_sp->GetStopReason();
      if (stop_reason != lldb::eStopReasonInvalid)
        m_expected_directories++;
    }
  }

  // Add a generous buffer of directories, these are quite small
  // and forks may add new directories upstream LLDB hadn't accounted for
  // when we started pre-calculating directory size, so this should account for
  // that
  m_expected_directories += 100;

  m_saved_data_size +=
      m_expected_directories * sizeof(llvm::minidump::Directory);
  Status error;
  offset_t new_offset = m_core_file->SeekFromStart(m_saved_data_size);
  if (new_offset != m_saved_data_size)
    error = Status::FromErrorStringWithFormat(
        "Failed to fill in header and directory "
        "sections. Written / Expected (%" PRIx64 " / %" PRIx64 ")",
        new_offset, m_saved_data_size);

  if (error.Fail())
    return error;

  return AddLLDBGeneratedStream();
}

Status MinidumpFileBuilder::AddDirectory(StreamType type,
                                         uint64_t stream_size) {
  // We explicitly cast type, an 32b enum, to uint32_t to avoid warnings.
  Status error;
  if (GetCurrentDataEndOffset() > UINT32_MAX) {
    error = Status::FromErrorStringWithFormat(
        "Unable to add directory for stream type "
        "%x, offset is greater then 32 bit limit.",
        (uint32_t)type);
    return error;
  }

  if (m_directories.size() + 1 > m_expected_directories) {
    error = Status::FromErrorStringWithFormat(
        "Unable to add directory for stream type %x, exceeded expected number "
        "of directories %zu.",
        (uint32_t)type, m_expected_directories);
    return error;
  }

  LocationDescriptor loc;
  loc.DataSize = static_cast<llvm::support::ulittle32_t>(stream_size);
  // Stream will begin at the current end of data section
  loc.RVA = static_cast<llvm::support::ulittle32_t>(GetCurrentDataEndOffset());

  Directory dir;
  dir.Type = static_cast<llvm::support::little_t<StreamType>>(type);
  dir.Location = loc;

  m_directories.push_back(dir);
  return error;
}

Status MinidumpFileBuilder::AddLLDBGeneratedStream() {
  Status error;
  StreamType type = StreamType::LLDBGenerated;
  return AddDirectory(type, 0);
}

Status MinidumpFileBuilder::AddSystemInfo() {
  Status error;
  const llvm::Triple &target_triple =
      m_process_sp->GetTarget().GetArchitecture().GetTriple();
  error =
      AddDirectory(StreamType::SystemInfo, sizeof(llvm::minidump::SystemInfo));
  if (error.Fail())
    return error;

  llvm::minidump::ProcessorArchitecture arch;
  switch (target_triple.getArch()) {
  case llvm::Triple::ArchType::x86_64:
    arch = ProcessorArchitecture::AMD64;
    break;
  case llvm::Triple::ArchType::x86:
    arch = ProcessorArchitecture::X86;
    break;
  case llvm::Triple::ArchType::arm:
    arch = ProcessorArchitecture::ARM;
    break;
  case llvm::Triple::ArchType::aarch64:
    arch = ProcessorArchitecture::ARM64;
    break;
  case llvm::Triple::ArchType::mips64:
  case llvm::Triple::ArchType::mips64el:
  case llvm::Triple::ArchType::mips:
  case llvm::Triple::ArchType::mipsel:
    arch = ProcessorArchitecture::MIPS;
    break;
  case llvm::Triple::ArchType::ppc64:
  case llvm::Triple::ArchType::ppc:
  case llvm::Triple::ArchType::ppc64le:
    arch = ProcessorArchitecture::PPC;
    break;
  default:
    error = Status::FromErrorStringWithFormat(
        "Architecture %s not supported.",
        target_triple.getArchName().str().c_str());
    return error;
  };

  llvm::support::little_t<OSPlatform> platform_id;
  switch (target_triple.getOS()) {
  case llvm::Triple::OSType::Linux:
    if (target_triple.getEnvironment() ==
        llvm::Triple::EnvironmentType::Android)
      platform_id = OSPlatform::Android;
    else
      platform_id = OSPlatform::Linux;
    break;
  case llvm::Triple::OSType::Win32:
    platform_id = OSPlatform::Win32NT;
    break;
  case llvm::Triple::OSType::MacOSX:
    platform_id = OSPlatform::MacOSX;
    break;
  case llvm::Triple::OSType::IOS:
    platform_id = OSPlatform::IOS;
    break;
  default:
    error = Status::FromErrorStringWithFormat(
        "OS %s not supported.", target_triple.getOSName().str().c_str());
    return error;
  };

  llvm::minidump::SystemInfo sys_info{};
  sys_info.ProcessorArch =
      static_cast<llvm::support::little_t<ProcessorArchitecture>>(arch);
  // Global offset to beginning of a csd_string in a data section
  sys_info.CSDVersionRVA = static_cast<llvm::support::ulittle32_t>(
      GetCurrentDataEndOffset() + sizeof(llvm::minidump::SystemInfo));
  sys_info.PlatformId = platform_id;
  m_data.AppendData(&sys_info, sizeof(llvm::minidump::SystemInfo));

  std::string csd_string;

  error = WriteString(csd_string, &m_data);
  if (error.Fail()) {
    error =
        Status::FromErrorString("Unable to convert the csd string to UTF16.");
    return error;
  }

  return error;
}

Status WriteString(const std::string &to_write,
                   lldb_private::DataBufferHeap *buffer) {
  Status error;
  // let the StringRef eat also null termination char
  llvm::StringRef to_write_ref(to_write.c_str(), to_write.size() + 1);
  llvm::SmallVector<llvm::UTF16, 128> to_write_utf16;

  bool converted = convertUTF8ToUTF16String(to_write_ref, to_write_utf16);
  if (!converted) {
    error = Status::FromErrorStringWithFormat(
        "Unable to convert the string to UTF16. Failed to convert %s",
        to_write.c_str());
    return error;
  }

  // size of the UTF16 string should be written without the null termination
  // character that is stored in 2 bytes
  llvm::support::ulittle32_t to_write_size(to_write_utf16.size_in_bytes() - 2);

  buffer->AppendData(&to_write_size, sizeof(llvm::support::ulittle32_t));
  buffer->AppendData(to_write_utf16.data(), to_write_utf16.size_in_bytes());

  return error;
}

llvm::Expected<uint64_t> getModuleFileSize(Target &target,
                                           const ModuleSP &mod) {
  // JIT module has the same vm and file size.
  uint64_t SizeOfImage = 0;
  if (mod->GetObjectFile()->CalculateType() == ObjectFile::Type::eTypeJIT) {
    for (const auto &section : *mod->GetObjectFile()->GetSectionList()) {
      SizeOfImage += section->GetByteSize();
    }
    return SizeOfImage;
  }
  SectionSP sect_sp = mod->GetObjectFile()->GetBaseAddress().GetSection();

  if (!sect_sp) {
    return llvm::createStringError(std::errc::operation_not_supported,
                                   "Couldn't obtain the section information.");
  }
  lldb::addr_t sect_addr = sect_sp->GetLoadBaseAddress(&target);
  // Use memory size since zero fill sections, like ".bss", will be smaller on
  // disk.
  lldb::addr_t sect_size = sect_sp->GetByteSize();
  // This will usually be zero, but make sure to calculate the BaseOfImage
  // offset.
  const lldb::addr_t base_sect_offset =
      mod->GetObjectFile()->GetBaseAddress().GetLoadAddress(&target) -
      sect_addr;
  SizeOfImage = sect_size - base_sect_offset;
  lldb::addr_t next_sect_addr = sect_addr + sect_size;
  Address sect_so_addr;
  target.ResolveLoadAddress(next_sect_addr, sect_so_addr);
  lldb::SectionSP next_sect_sp = sect_so_addr.GetSection();
  while (next_sect_sp &&
         next_sect_sp->GetLoadBaseAddress(&target) == next_sect_addr) {
    sect_size = sect_sp->GetByteSize();
    SizeOfImage += sect_size;
    next_sect_addr += sect_size;
    target.ResolveLoadAddress(next_sect_addr, sect_so_addr);
    next_sect_sp = sect_so_addr.GetSection();
  }

  return SizeOfImage;
}

// ModuleList stream consists of a number of modules, followed by an array
// of llvm::minidump::Module's structures. Every structure informs about a
// single module. Additional data of variable length, such as module's names,
// are stored just after the ModuleList stream. The llvm::minidump::Module
// structures point to this helper data by global offset.
Status MinidumpFileBuilder::AddModuleList() {
  constexpr size_t minidump_module_size = sizeof(llvm::minidump::Module);
  Status error;

  lldb_private::Target &target = m_process_sp->GetTarget();
  const ModuleList &modules = target.GetImages();
  llvm::support::ulittle32_t modules_count =
      static_cast<llvm::support::ulittle32_t>(modules.GetSize());

  // This helps us with getting the correct global offset in minidump
  // file later, when we will be setting up offsets from the
  // the llvm::minidump::Module's structures into helper data
  size_t size_before = GetCurrentDataEndOffset();

  // Temporary storage for the helper data (of variable length)
  // as these cannot be dumped to m_data before dumping entire
  // array of module structures.
  DataBufferHeap helper_data;

  // Vector to store modules that pass validation.
  std::vector<std::pair<ModuleSP, uint64_t>> valid_modules;

  for (size_t i = 0; i < modules_count; ++i) {
    ModuleSP mod = modules.GetModuleAtIndex(i);
    std::string module_name = mod->GetSpecificationDescription();
    auto maybe_mod_size = getModuleFileSize(target, mod);
    if (!maybe_mod_size) {
      llvm::Error mod_size_err = maybe_mod_size.takeError();
      Log *log = GetLog(LLDBLog::Object);
      llvm::handleAllErrors(
          std::move(mod_size_err), [&](const llvm::ErrorInfoBase &E) {
            if (log) {
              LLDB_LOGF(log, "Unable to get the size of module %s: %s",
                        module_name.c_str(), E.message().c_str());
            }
          });
      continue;
    }
    valid_modules.emplace_back(mod, *maybe_mod_size);
  }

  size_t module_stream_size = sizeof(llvm::support::ulittle32_t) +
                              valid_modules.size() * minidump_module_size;

  error = AddDirectory(StreamType::ModuleList, module_stream_size);
  if (error.Fail())
    return error;

  // Setting the header with the number of modules.
  llvm::support::ulittle32_t count =
      static_cast<llvm::support::ulittle32_t>(valid_modules.size());
  m_data.AppendData(&count, sizeof(llvm::support::ulittle32_t));

  for (const auto &valid_module : valid_modules) {
    ModuleSP mod = valid_module.first;
    uint64_t module_size = valid_module.second;
    std::string module_name = mod->GetSpecificationDescription();

    llvm::support::ulittle32_t signature =
        static_cast<llvm::support::ulittle32_t>(
            static_cast<uint32_t>(minidump::CvSignature::ElfBuildId));
    auto uuid = mod->GetUUID().GetBytes();

    VSFixedFileInfo info;
    info.Signature = static_cast<llvm::support::ulittle32_t>(0u);
    info.StructVersion = static_cast<llvm::support::ulittle32_t>(0u);
    info.FileVersionHigh = static_cast<llvm::support::ulittle32_t>(0u);
    info.FileVersionLow = static_cast<llvm::support::ulittle32_t>(0u);
    info.ProductVersionHigh = static_cast<llvm::support::ulittle32_t>(0u);
    info.ProductVersionLow = static_cast<llvm::support::ulittle32_t>(0u);
    info.FileFlagsMask = static_cast<llvm::support::ulittle32_t>(0u);
    info.FileFlags = static_cast<llvm::support::ulittle32_t>(0u);
    info.FileOS = static_cast<llvm::support::ulittle32_t>(0u);
    info.FileType = static_cast<llvm::support::ulittle32_t>(0u);
    info.FileSubtype = static_cast<llvm::support::ulittle32_t>(0u);
    info.FileDateHigh = static_cast<llvm::support::ulittle32_t>(0u);
    info.FileDateLow = static_cast<llvm::support::ulittle32_t>(0u);

    LocationDescriptor ld;
    ld.DataSize = static_cast<llvm::support::ulittle32_t>(0u);
    ld.RVA = static_cast<llvm::support::ulittle32_t>(0u);

    // Setting up LocationDescriptor for uuid string. The global offset into
    // minidump file is calculated.
    LocationDescriptor ld_cv;
    ld_cv.DataSize = static_cast<llvm::support::ulittle32_t>(
        sizeof(llvm::support::ulittle32_t) + uuid.size());
    ld_cv.RVA = static_cast<llvm::support::ulittle32_t>(
        size_before + module_stream_size + helper_data.GetByteSize());

    helper_data.AppendData(&signature, sizeof(llvm::support::ulittle32_t));
    helper_data.AppendData(uuid.begin(), uuid.size());

    llvm::minidump::Module m{};
    m.BaseOfImage = static_cast<llvm::support::ulittle64_t>(
        mod->GetObjectFile()->GetBaseAddress().GetLoadAddress(&target));
    m.SizeOfImage = static_cast<llvm::support::ulittle32_t>(module_size);
    m.Checksum = static_cast<llvm::support::ulittle32_t>(0);
    m.TimeDateStamp =
        static_cast<llvm::support::ulittle32_t>(std::time(nullptr));
    m.ModuleNameRVA = static_cast<llvm::support::ulittle32_t>(
        size_before + module_stream_size + helper_data.GetByteSize());
    m.VersionInfo = info;
    m.CvRecord = ld_cv;
    m.MiscRecord = ld;

    error = WriteString(module_name, &helper_data);

    if (error.Fail())
      return error;

    m_data.AppendData(&m, sizeof(llvm::minidump::Module));
  }

  m_data.AppendData(helper_data.GetBytes(), helper_data.GetByteSize());
  return error;
}

uint16_t read_register_u16_raw(RegisterContext *reg_ctx,
                               llvm::StringRef reg_name) {
  const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
  if (!reg_info)
    return 0;
  lldb_private::RegisterValue reg_value;
  bool success = reg_ctx->ReadRegister(reg_info, reg_value);
  if (!success)
    return 0;
  return reg_value.GetAsUInt16();
}

uint32_t read_register_u32_raw(RegisterContext *reg_ctx,
                               llvm::StringRef reg_name) {
  const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
  if (!reg_info)
    return 0;
  lldb_private::RegisterValue reg_value;
  bool success = reg_ctx->ReadRegister(reg_info, reg_value);
  if (!success)
    return 0;
  return reg_value.GetAsUInt32();
}

uint64_t read_register_u64_raw(RegisterContext *reg_ctx,
                               llvm::StringRef reg_name) {
  const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
  if (!reg_info)
    return 0;
  lldb_private::RegisterValue reg_value;
  bool success = reg_ctx->ReadRegister(reg_info, reg_value);
  if (!success)
    return 0;
  return reg_value.GetAsUInt64();
}

llvm::support::ulittle16_t read_register_u16(RegisterContext *reg_ctx,
                                             llvm::StringRef reg_name) {
  return static_cast<llvm::support::ulittle16_t>(
      read_register_u16_raw(reg_ctx, reg_name));
}

llvm::support::ulittle32_t read_register_u32(RegisterContext *reg_ctx,
                                             llvm::StringRef reg_name) {
  return static_cast<llvm::support::ulittle32_t>(
      read_register_u32_raw(reg_ctx, reg_name));
}

llvm::support::ulittle64_t read_register_u64(RegisterContext *reg_ctx,
                                             llvm::StringRef reg_name) {
  return static_cast<llvm::support::ulittle64_t>(
      read_register_u64_raw(reg_ctx, reg_name));
}

void read_register_u128(RegisterContext *reg_ctx, llvm::StringRef reg_name,
                        uint8_t *dst) {
  const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
  if (reg_info) {
    lldb_private::RegisterValue reg_value;
    if (reg_ctx->ReadRegister(reg_info, reg_value)) {
      Status error;
      uint32_t bytes_copied = reg_value.GetAsMemoryData(
          *reg_info, dst, 16, lldb::ByteOrder::eByteOrderLittle, error);
      if (bytes_copied == 16)
        return;
    }
  }
  // If anything goes wrong, then zero out the register value.
  memset(dst, 0, 16);
}

lldb_private::minidump::MinidumpContext_x86_64
GetThreadContext_x86_64(RegisterContext *reg_ctx) {
  lldb_private::minidump::MinidumpContext_x86_64 thread_context = {};
  thread_context.p1_home = {};
  thread_context.context_flags = static_cast<uint32_t>(
      lldb_private::minidump::MinidumpContext_x86_64_Flags::x86_64_Flag |
      lldb_private::minidump::MinidumpContext_x86_64_Flags::Control |
      lldb_private::minidump::MinidumpContext_x86_64_Flags::Segments |
      lldb_private::minidump::MinidumpContext_x86_64_Flags::Integer |
      lldb_private::minidump::MinidumpContext_x86_64_Flags::LLDBSpecific);
  thread_context.rax = read_register_u64(reg_ctx, "rax");
  thread_context.rbx = read_register_u64(reg_ctx, "rbx");
  thread_context.rcx = read_register_u64(reg_ctx, "rcx");
  thread_context.rdx = read_register_u64(reg_ctx, "rdx");
  thread_context.rdi = read_register_u64(reg_ctx, "rdi");
  thread_context.rsi = read_register_u64(reg_ctx, "rsi");
  thread_context.rbp = read_register_u64(reg_ctx, "rbp");
  thread_context.rsp = read_register_u64(reg_ctx, "rsp");
  thread_context.r8 = read_register_u64(reg_ctx, "r8");
  thread_context.r9 = read_register_u64(reg_ctx, "r9");
  thread_context.r10 = read_register_u64(reg_ctx, "r10");
  thread_context.r11 = read_register_u64(reg_ctx, "r11");
  thread_context.r12 = read_register_u64(reg_ctx, "r12");
  thread_context.r13 = read_register_u64(reg_ctx, "r13");
  thread_context.r14 = read_register_u64(reg_ctx, "r14");
  thread_context.r15 = read_register_u64(reg_ctx, "r15");
  thread_context.rip = read_register_u64(reg_ctx, "rip");
  // To make our code agnostic to whatever type the register value identifies
  // itself as, we read as a u64 and truncate to u32/u16 ourselves.
  thread_context.eflags = read_register_u64(reg_ctx, "rflags");
  thread_context.cs = read_register_u64(reg_ctx, "cs");
  thread_context.fs = read_register_u64(reg_ctx, "fs");
  thread_context.gs = read_register_u64(reg_ctx, "gs");
  thread_context.ss = read_register_u64(reg_ctx, "ss");
  thread_context.ds = read_register_u64(reg_ctx, "ds");
  thread_context.fs_base = read_register_u64(reg_ctx, "fs_base");
  thread_context.gs_base = read_register_u64(reg_ctx, "gs_base");
  return thread_context;
}

minidump::RegisterContextMinidump_ARM64::Context
GetThreadContext_ARM64(RegisterContext *reg_ctx) {
  minidump::RegisterContextMinidump_ARM64::Context thread_context = {};
  thread_context.context_flags = static_cast<uint32_t>(
      minidump::RegisterContextMinidump_ARM64::Flags::ARM64_Flag |
      minidump::RegisterContextMinidump_ARM64::Flags::Integer |
      minidump::RegisterContextMinidump_ARM64::Flags::FloatingPoint);
  char reg_name[16];
  for (uint32_t i = 0; i < 31; ++i) {
    snprintf(reg_name, sizeof(reg_name), "x%u", i);
    thread_context.x[i] = read_register_u64(reg_ctx, reg_name);
  }
  // Work around a bug in debugserver where "sp" on arm64 doesn't have the alt
  // name set to "x31"
  thread_context.x[31] = read_register_u64(reg_ctx, "sp");
  thread_context.pc = read_register_u64(reg_ctx, "pc");
  thread_context.cpsr = read_register_u32(reg_ctx, "cpsr");
  thread_context.fpsr = read_register_u32(reg_ctx, "fpsr");
  thread_context.fpcr = read_register_u32(reg_ctx, "fpcr");
  for (uint32_t i = 0; i < 32; ++i) {
    snprintf(reg_name, sizeof(reg_name), "v%u", i);
    read_register_u128(reg_ctx, reg_name, &thread_context.v[i * 16]);
  }
  return thread_context;
}

class ArchThreadContexts {
  llvm::Triple::ArchType m_arch;
  union {
    lldb_private::minidump::MinidumpContext_x86_64 x86_64;
    lldb_private::minidump::RegisterContextMinidump_ARM64::Context arm64;
  };

public:
  ArchThreadContexts(llvm::Triple::ArchType arch) : m_arch(arch) {}

  bool prepareRegisterContext(RegisterContext *reg_ctx) {
    switch (m_arch) {
    case llvm::Triple::ArchType::x86_64:
      x86_64 = GetThreadContext_x86_64(reg_ctx);
      return true;
    case llvm::Triple::ArchType::aarch64:
      arm64 = GetThreadContext_ARM64(reg_ctx);
      return true;
    default:
      break;
    }
    return false;
  }

  const void *data() const { return &x86_64; }

  size_t size() const {
    switch (m_arch) {
    case llvm::Triple::ArchType::x86_64:
      return sizeof(x86_64);
    case llvm::Triple::ArchType::aarch64:
      return sizeof(arm64);
    default:
      break;
    }
    return 0;
  }
};

Status MinidumpFileBuilder::FixThreadStacks() {
  Status error;
  // If we have anything in the heap flush it.
  FlushBufferToDisk();
  m_core_file->SeekFromStart(m_thread_list_start);
  for (auto &pair : m_thread_by_range_end) {
    // The thread objects will get a new memory descriptor added
    // When we are emitting the memory list and then we write it here
    const llvm::minidump::Thread &thread = pair.second;
    size_t bytes_to_write = sizeof(llvm::minidump::Thread);
    size_t bytes_written = bytes_to_write;
    error = m_core_file->Write(&thread, bytes_written);
    if (error.Fail() || bytes_to_write != bytes_written) {
      error = Status::FromErrorStringWithFormat(
          "Wrote incorrect number of bytes to minidump file. (written %zd/%zd)",
          bytes_written, bytes_to_write);
      return error;
    }
  }

  return error;
}

Status MinidumpFileBuilder::AddThreadList() {
  constexpr size_t minidump_thread_size = sizeof(llvm::minidump::Thread);
  std::vector<ThreadSP> thread_list =
      m_process_sp->CalculateCoreFileThreadList(m_save_core_options);

  // size of the entire thread stream consists of:
  // number of threads and threads array
  size_t thread_stream_size = sizeof(llvm::support::ulittle32_t) +
                              thread_list.size() * minidump_thread_size;
  // save for the ability to set up RVA
  size_t size_before = GetCurrentDataEndOffset();
  Status error;
  error = AddDirectory(StreamType::ThreadList, thread_stream_size);
  if (error.Fail())
    return error;

  llvm::support::ulittle32_t thread_count =
      static_cast<llvm::support::ulittle32_t>(thread_list.size());
  m_data.AppendData(&thread_count, sizeof(llvm::support::ulittle32_t));

  // Take the offset after the thread count.
  m_thread_list_start = GetCurrentDataEndOffset();
  DataBufferHeap helper_data;

  Log *log = GetLog(LLDBLog::Object);
  for (const ThreadSP &thread_sp : thread_list) {
    RegisterContextSP reg_ctx_sp(thread_sp->GetRegisterContext());

    if (!reg_ctx_sp) {
      error = Status::FromErrorString("Unable to get the register context.");
      return error;
    }
    RegisterContext *reg_ctx = reg_ctx_sp.get();
    Target &target = m_process_sp->GetTarget();
    const ArchSpec &arch = target.GetArchitecture();
    ArchThreadContexts thread_context(arch.GetMachine());
    if (!thread_context.prepareRegisterContext(reg_ctx)) {
      error = Status::FromErrorStringWithFormat(
          "architecture %s not supported.",
          arch.GetTriple().getArchName().str().c_str());
      return error;
    }

    uint64_t sp = reg_ctx->GetSP();
    MemoryRegionInfo sp_region;
    m_process_sp->GetMemoryRegionInfo(sp, sp_region);

    // Emit a blank descriptor
    MemoryDescriptor stack;
    LocationDescriptor empty_label;
    empty_label.DataSize = 0;
    empty_label.RVA = 0;
    stack.Memory = empty_label;
    stack.StartOfMemoryRange = 0;
    LocationDescriptor thread_context_memory_locator;
    thread_context_memory_locator.DataSize =
        static_cast<llvm::support::ulittle32_t>(thread_context.size());
    thread_context_memory_locator.RVA = static_cast<llvm::support::ulittle32_t>(
        size_before + thread_stream_size + helper_data.GetByteSize());
    // Cache thie thread context memory so we can reuse for exceptions.
    m_tid_to_reg_ctx[thread_sp->GetID()] = thread_context_memory_locator;

    LLDB_LOGF(log, "AddThreadList for thread %d: thread_context %zu bytes",
              thread_sp->GetIndexID(), thread_context.size());
    helper_data.AppendData(thread_context.data(), thread_context.size());

    llvm::minidump::Thread t;
    t.ThreadId = static_cast<llvm::support::ulittle32_t>(thread_sp->GetID());
    t.SuspendCount = static_cast<llvm::support::ulittle32_t>(
        (thread_sp->GetState() == StateType::eStateSuspended) ? 1 : 0);
    t.PriorityClass = static_cast<llvm::support::ulittle32_t>(0);
    t.Priority = static_cast<llvm::support::ulittle32_t>(0);
    t.EnvironmentBlock = static_cast<llvm::support::ulittle64_t>(0);
    t.Stack = stack, t.Context = thread_context_memory_locator;

    // We save off the stack object so we can circle back and clean it up.
    m_thread_by_range_end[sp_region.GetRange().GetRangeEnd()] = t;
    m_data.AppendData(&t, sizeof(llvm::minidump::Thread));
  }

  LLDB_LOGF(log, "AddThreadList(): total helper_data %" PRIx64 " bytes",
            helper_data.GetByteSize());
  m_data.AppendData(helper_data.GetBytes(), helper_data.GetByteSize());
  return Status();
}

Status MinidumpFileBuilder::AddExceptions() {
  std::vector<ThreadSP> thread_list =
      m_process_sp->CalculateCoreFileThreadList(m_save_core_options);
  Status error;
  for (const ThreadSP &thread_sp : thread_list) {
    StopInfoSP stop_info_sp = thread_sp->GetStopInfo();
    // If we don't have a stop info, or if it's invalid, skip.
    if (!stop_info_sp ||
        stop_info_sp->GetStopReason() == lldb::eStopReasonInvalid)
      continue;

    constexpr size_t minidump_exception_size =
        sizeof(llvm::minidump::ExceptionStream);
    error = AddDirectory(StreamType::Exception, minidump_exception_size);
    if (error.Fail())
      return error;

    RegisterContextSP reg_ctx_sp(thread_sp->GetRegisterContext());
    Exception exp_record = {};
    exp_record.ExceptionCode =
        static_cast<llvm::support::ulittle32_t>(stop_info_sp->GetValue());
    exp_record.ExceptionFlags =
        static_cast<llvm::support::ulittle32_t>(Exception::LLDB_FLAG);
    exp_record.ExceptionRecord = static_cast<llvm::support::ulittle64_t>(0);
    exp_record.ExceptionAddress = reg_ctx_sp->GetPC();
    exp_record.NumberParameters = static_cast<llvm::support::ulittle32_t>(1);
    std::string description = stop_info_sp->GetDescription();
    // We have 120 bytes to work with and it's unlikely description will
    // overflow, but we gotta check.
    memcpy(&exp_record.ExceptionInformation, description.c_str(),
           std::min(description.size(), Exception::MaxParameterBytes));
    exp_record.UnusedAlignment = static_cast<llvm::support::ulittle32_t>(0);
    ExceptionStream exp_stream;
    exp_stream.ThreadId =
        static_cast<llvm::support::ulittle32_t>(thread_sp->GetID());
    exp_stream.UnusedAlignment = static_cast<llvm::support::ulittle32_t>(0);
    exp_stream.ExceptionRecord = exp_record;
    auto Iter = m_tid_to_reg_ctx.find(thread_sp->GetID());
    if (Iter != m_tid_to_reg_ctx.end()) {
      exp_stream.ThreadContext = Iter->second;
    } else {
      exp_stream.ThreadContext.DataSize = 0;
      exp_stream.ThreadContext.RVA = 0;
    }
    m_data.AppendData(&exp_stream, minidump_exception_size);
  }

  return error;
}

lldb_private::Status MinidumpFileBuilder::AddMiscInfo() {
  Status error;
  error = AddDirectory(StreamType::MiscInfo,
                       sizeof(lldb_private::minidump::MinidumpMiscInfo));
  if (error.Fail())
    return error;

  lldb_private::minidump::MinidumpMiscInfo misc_info{};
  misc_info.size = static_cast<llvm::support::ulittle32_t>(
      sizeof(lldb_private::minidump::MinidumpMiscInfo));
  // Default set flags1 to 0, in case that we will not be able to
  // get any information
  misc_info.flags1 = static_cast<llvm::support::ulittle32_t>(0);

  lldb_private::ProcessInstanceInfo process_info;
  m_process_sp->GetProcessInfo(process_info);
  if (process_info.ProcessIDIsValid()) {
    // Set flags1 to reflect that PID is filled in
    misc_info.flags1 =
        static_cast<llvm::support::ulittle32_t>(static_cast<uint32_t>(
            lldb_private::minidump::MinidumpMiscInfoFlags::ProcessID));
    misc_info.process_id =
        static_cast<llvm::support::ulittle32_t>(process_info.GetProcessID());
  }

  m_data.AppendData(&misc_info,
                    sizeof(lldb_private::minidump::MinidumpMiscInfo));
  return error;
}

std::unique_ptr<llvm::MemoryBuffer>
getFileStreamHelper(const std::string &path) {
  auto maybe_stream = llvm::MemoryBuffer::getFileAsStream(path);
  if (!maybe_stream)
    return nullptr;
  return std::move(maybe_stream.get());
}

Status MinidumpFileBuilder::AddLinuxFileStreams() {
  Status error;
  // No-op if we are not on linux.
  if (m_process_sp->GetTarget().GetArchitecture().GetTriple().getOS() !=
      llvm::Triple::Linux)
    return error;

  std::vector<std::pair<StreamType, std::string>> files_with_stream_types = {
      {StreamType::LinuxCPUInfo, "/proc/cpuinfo"},
      {StreamType::LinuxLSBRelease, "/etc/lsb-release"},
  };

  lldb_private::ProcessInstanceInfo process_info;
  m_process_sp->GetProcessInfo(process_info);
  if (process_info.ProcessIDIsValid()) {
    lldb::pid_t pid = process_info.GetProcessID();
    std::string pid_str = std::to_string(pid);
    files_with_stream_types.push_back(
        {StreamType::LinuxProcStatus, "/proc/" + pid_str + "/status"});
    files_with_stream_types.push_back(
        {StreamType::LinuxCMDLine, "/proc/" + pid_str + "/cmdline"});
    files_with_stream_types.push_back(
        {StreamType::LinuxEnviron, "/proc/" + pid_str + "/environ"});
    files_with_stream_types.push_back(
        {StreamType::LinuxAuxv, "/proc/" + pid_str + "/auxv"});
    files_with_stream_types.push_back(
        {StreamType::LinuxMaps, "/proc/" + pid_str + "/maps"});
    files_with_stream_types.push_back(
        {StreamType::LinuxProcStat, "/proc/" + pid_str + "/stat"});
    files_with_stream_types.push_back(
        {StreamType::LinuxProcFD, "/proc/" + pid_str + "/fd"});
  }

  for (const auto &entry : files_with_stream_types) {
    StreamType stream = entry.first;
    std::string path = entry.second;
    auto memory_buffer = getFileStreamHelper(path);

    if (memory_buffer) {
      size_t size = memory_buffer->getBufferSize();
      if (size == 0)
        continue;
      error = AddDirectory(stream, size);
      if (error.Fail())
        return error;
      m_data.AppendData(memory_buffer->getBufferStart(), size);
    }
  }

  return error;
}

Status MinidumpFileBuilder::AddMemoryList() {
  Status error;

  // We first save the thread stacks to ensure they fit in the first UINT32_MAX
  // bytes of the core file. Thread structures in minidump files can only use
  // 32 bit memory descriptiors, so we emit them first to ensure the memory is
  // in accessible with a 32 bit offset.
  std::vector<CoreFileMemoryRange> ranges_32;
  llvm::Expected<CoreFileMemoryRanges> all_core_memory_ranges_maybe =
      m_save_core_options.GetMemoryRegionsToSave();
  if (!all_core_memory_ranges_maybe)
    return Status::FromError(all_core_memory_ranges_maybe.takeError());

  const CoreFileMemoryRanges &all_core_memory_ranges =
      *all_core_memory_ranges_maybe;

  lldb_private::Progress progress("Saving Minidump File", "",
                                  all_core_memory_ranges.GetSize());
  std::vector<CoreFileMemoryRange> all_core_memory_vec;
  // Extract all the data into just a vector of data. So we can mutate this in
  // place.
  for (const auto &core_range : all_core_memory_ranges)
    all_core_memory_vec.push_back(core_range.data);

  // Start by saving all of the stacks and ensuring they fit under the 32b
  // limit.
  uint64_t total_size = GetCurrentDataEndOffset();
  auto iterator = all_core_memory_vec.begin();
  while (iterator != all_core_memory_vec.end()) {
    if (m_thread_by_range_end.count(iterator->range.end()) > 0) {
      // We don't save stacks twice.
      ranges_32.push_back(*iterator);
      total_size +=
          iterator->range.size() + sizeof(llvm::minidump::MemoryDescriptor);
      iterator = all_core_memory_vec.erase(iterator);
    } else {
      iterator++;
    }
  }

  // The header has to be in 32b memory, as it needs to be addressable by a 32b
  // RVA. Everything else can be 64b.
  total_size += sizeof(llvm::minidump::MemoryListHeader);

  if (total_size >= UINT32_MAX) {
    error = Status::FromErrorStringWithFormat(
        "Unable to write minidump. Stack memory "
        "exceeds 32b limit. (Num Stacks %zu)",
        ranges_32.size());
    return error;
  }

  // Save only the thread stacks to the 32b memory list. Everything else will
  // get put in Memory64, this simplifies tracking
  error = AddMemoryList_32(ranges_32, progress);
  if (error.Fail())
    return error;

  // Add the remaining memory as a 64b range.
  if (!all_core_memory_ranges.IsEmpty()) {
    error = AddMemoryList_64(all_core_memory_vec, progress);
    if (error.Fail())
      return error;
  }

  return FixThreadStacks();
}

Status MinidumpFileBuilder::DumpHeader() const {
  // write header
  llvm::minidump::Header header;
  header.Signature = static_cast<llvm::support::ulittle32_t>(
      llvm::minidump::Header::MagicSignature);
  header.Version = static_cast<llvm::support::ulittle32_t>(
      llvm::minidump::Header::MagicVersion);
  header.NumberOfStreams =
      static_cast<llvm::support::ulittle32_t>(m_directories.size());
  // We write the directories right after the header.
  header.StreamDirectoryRVA =
      static_cast<llvm::support::ulittle32_t>(HEADER_SIZE);
  header.Checksum = static_cast<llvm::support::ulittle32_t>(
      0u); // not used in most of the writers
  header.TimeDateStamp =
      static_cast<llvm::support::ulittle32_t>(std::time(nullptr));
  header.Flags =
      static_cast<llvm::support::ulittle64_t>(0u); // minidump normal flag

  Status error;
  size_t bytes_written;

  m_core_file->SeekFromStart(0);
  bytes_written = HEADER_SIZE;
  error = m_core_file->Write(&header, bytes_written);
  if (error.Fail() || bytes_written != HEADER_SIZE) {
    if (bytes_written != HEADER_SIZE)
      error = Status::FromErrorStringWithFormat(
          "Unable to write the minidump header (written %zd/%zd)",
          bytes_written, HEADER_SIZE);
    return error;
  }
  return error;
}

offset_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
  return m_data.GetByteSize() + m_saved_data_size;
}

Status MinidumpFileBuilder::DumpDirectories() const {
  Status error;
  size_t bytes_written;
  m_core_file->SeekFromStart(HEADER_SIZE);
  for (const Directory &dir : m_directories) {
    bytes_written = DIRECTORY_SIZE;
    error = m_core_file->Write(&dir, bytes_written);
    if (error.Fail() || bytes_written != DIRECTORY_SIZE) {
      if (bytes_written != DIRECTORY_SIZE)
        error = Status::FromErrorStringWithFormat(
            "unable to write the directory (written %zd/%zd)", bytes_written,
            DIRECTORY_SIZE);
      return error;
    }
  }

  return error;
}

Status MinidumpFileBuilder::ReadWriteMemoryInChunks(
    lldb_private::DataBufferHeap &data_buffer,
    const lldb_private::CoreFileMemoryRange &range, uint64_t &bytes_read) {

  const lldb::addr_t addr = range.range.start();
  const lldb::addr_t size = range.range.size();
  Log *log = GetLog(LLDBLog::Object);
  uint64_t total_bytes_read = 0;
  Status addDataError;
  Process::ReadMemoryChunkCallback callback =
      [&](Status &error, lldb::addr_t current_addr, const void *buf,
          uint64_t bytes_read) -> lldb_private::IterationAction {
    if (error.Fail() || bytes_read == 0) {
      LLDB_LOGF(log,
                "Failed to read memory region at: 0x%" PRIx64
                ". Bytes read: 0x%" PRIx64 ", error: %s",
                current_addr, bytes_read, error.AsCString());

      // If we failed in a memory read, we would normally want to skip
      // this entire region. If we had already written to the minidump
      // file, we can't easily rewind that state.
      //
      // So if we do encounter an error while reading, we return
      // immediately, any prior bytes read will still be included but
      // any bytes partially read before the error are ignored.
      return lldb_private::IterationAction::Stop;
    }

    if (current_addr != addr + total_bytes_read) {
      LLDB_LOGF(log,
                "Current addr is at unexpected address, 0x%" PRIx64
                ", expected at 0x%" PRIx64,
                current_addr, addr + total_bytes_read);

      // Something went wrong and the address is not where it should be
      // we'll error out of this Minidump generation.
      addDataError = Status::FromErrorStringWithFormat(
          "Unexpected address encounterd when reading memory in chunks "
          "0x%" PRIx64 " expected 0x%" PRIx64,
          current_addr, addr + total_bytes_read);
      return lldb_private::IterationAction::Stop;
    }

    // Write to the minidump file with the chunk potentially flushing to
    // disk.
    // This error will be captured by the outer scope and is considered fatal.
    // If we get an error writing to disk we can't easily guarauntee that we
    // won't corrupt the minidump.
    addDataError = AddData(buf, bytes_read);
    if (addDataError.Fail())
      return lldb_private::IterationAction::Stop;

    total_bytes_read += bytes_read;
    // If we have a partial read, report it, but only if the partial read
    // didn't finish reading the entire region.
    if (bytes_read != data_buffer.GetByteSize() && total_bytes_read != size) {
      LLDB_LOGF(log,
                "Memory region at: 0x%" PRIx64 " partial read 0x%" PRIx64
                " bytes out of 0x%" PRIx64 " bytes.",
                current_addr, bytes_read,
                data_buffer.GetByteSize() - bytes_read);

      // If we've read some bytes, we stop trying to read more and return
      // this best effort attempt
      return lldb_private::IterationAction::Stop;
    }

    // No problems, keep going!
    return lldb_private::IterationAction::Continue;
  };

  bytes_read = m_process_sp->ReadMemoryInChunks(
      addr, data_buffer.GetBytes(), data_buffer.GetByteSize(), size, callback);
  return addDataError;
}

static uint64_t
GetLargestRangeSize(const std::vector<CoreFileMemoryRange> &ranges) {
  uint64_t max_size = 0;
  for (const auto &core_range : ranges)
    max_size = std::max(max_size, core_range.range.size());
  return max_size;
}

Status
MinidumpFileBuilder::AddMemoryList_32(std::vector<CoreFileMemoryRange> &ranges,
                                      Progress &progress) {
  std::vector<MemoryDescriptor> descriptors;
  Status error;
  if (ranges.size() == 0)
    return error;

  Log *log = GetLog(LLDBLog::Object);
  size_t region_index = 0;
  lldb_private::DataBufferHeap data_buffer(
      std::min(GetLargestRangeSize(ranges), MAX_WRITE_CHUNK_SIZE), 0);
  for (const auto &core_range : ranges) {
    // Take the offset before we write.
    const offset_t offset_for_data = GetCurrentDataEndOffset();
    const addr_t addr = core_range.range.start();
    const addr_t size = core_range.range.size();
    const addr_t end = core_range.range.end();

    LLDB_LOGF(log,
              "AddMemoryList %zu/%zu reading memory for region "
              "(0x%" PRIx64 " bytes) [0x%" PRIx64 ", 0x%" PRIx64 ")",
              region_index, ranges.size(), size, addr, addr + size);
    ++region_index;

    progress.Increment(1, "Adding Memory Range " + core_range.Dump());
    uint64_t bytes_read = 0;
    error = ReadWriteMemoryInChunks(data_buffer, core_range, bytes_read);
    if (error.Fail())
      return error;

    // If we completely failed to read this range
    // we can drop the memory range
    if (bytes_read == 0)
      continue;

    MemoryDescriptor descriptor;
    descriptor.StartOfMemoryRange =
        static_cast<llvm::support::ulittle64_t>(addr);
    descriptor.Memory.DataSize =
        static_cast<llvm::support::ulittle32_t>(bytes_read);
    descriptor.Memory.RVA =
        static_cast<llvm::support::ulittle32_t>(offset_for_data);
    descriptors.push_back(descriptor);
    if (m_thread_by_range_end.count(end) > 0)
      m_thread_by_range_end[end].Stack = descriptor;
  }

  // Add a directory that references this list
  // With a size of the number of ranges as a 32 bit num
  // And then the size of all the ranges
  error = AddDirectory(StreamType::MemoryList,
                       sizeof(llvm::minidump::MemoryListHeader) +
                           descriptors.size() *
                               sizeof(llvm::minidump::MemoryDescriptor));
  if (error.Fail())
    return error;

  llvm::minidump::MemoryListHeader list_header;
  llvm::support::ulittle32_t memory_ranges_num =
      static_cast<llvm::support::ulittle32_t>(descriptors.size());
  list_header.NumberOfMemoryRanges = memory_ranges_num;
  m_data.AppendData(&list_header, sizeof(llvm::minidump::MemoryListHeader));
  // For 32b we can get away with writing off the descriptors after the data.
  // This means no cleanup loop needed.
  m_data.AppendData(descriptors.data(),
                    descriptors.size() * sizeof(MemoryDescriptor));

  return error;
}

Status
MinidumpFileBuilder::AddMemoryList_64(std::vector<CoreFileMemoryRange> &ranges,
                                      Progress &progress) {
  Status error;
  if (ranges.empty())
    return error;

  error = AddDirectory(StreamType::Memory64List,
                       (sizeof(llvm::minidump::Memory64ListHeader)) +
                           ranges.size() *
                               sizeof(llvm::minidump::MemoryDescriptor_64));
  if (error.Fail())
    return error;

  llvm::minidump::Memory64ListHeader list_header;
  llvm::support::ulittle64_t memory_ranges_num =
      static_cast<llvm::support::ulittle64_t>(ranges.size());
  list_header.NumberOfMemoryRanges = memory_ranges_num;
  // Capture the starting offset for all the descriptors so we can clean them up
  // if needed.
  offset_t starting_offset =
      GetCurrentDataEndOffset() + sizeof(llvm::minidump::Memory64ListHeader);
  // The base_rva needs to start after the directories, which is right after
  // the descriptors + the size of the header.
  offset_t base_rva =
      starting_offset +
      (ranges.size() * sizeof(llvm::minidump::MemoryDescriptor_64));
  llvm::support::ulittle64_t memory_ranges_base_rva =
      static_cast<llvm::support::ulittle64_t>(base_rva);
  list_header.BaseRVA = memory_ranges_base_rva;
  m_data.AppendData(&list_header, sizeof(llvm::minidump::Memory64ListHeader));

  lldb_private::DataBufferHeap data_buffer(
      std::min(GetLargestRangeSize(ranges), MAX_WRITE_CHUNK_SIZE), 0);
  bool cleanup_required = false;
  std::vector<MemoryDescriptor_64> descriptors;
  // Enumerate the ranges and create the memory descriptors so we can append
  // them first
  for (const auto core_range : ranges) {
    // Add the space required to store the memory descriptor
    MemoryDescriptor_64 memory_desc;
    memory_desc.StartOfMemoryRange =
        static_cast<llvm::support::ulittle64_t>(core_range.range.start());
    memory_desc.DataSize =
        static_cast<llvm::support::ulittle64_t>(core_range.range.size());
    descriptors.push_back(memory_desc);
    // Now write this memory descriptor to the buffer.
    m_data.AppendData(&memory_desc, sizeof(MemoryDescriptor_64));
  }

  Log *log = GetLog(LLDBLog::Object);
  size_t region_index = 0;
  for (const auto &core_range : ranges) {
    const addr_t addr = core_range.range.start();
    const addr_t size = core_range.range.size();

    LLDB_LOGF(log,
              "AddMemoryList_64 %zu/%zu reading memory for region "
              "(%" PRIx64 "bytes) "
              "[%" PRIx64 ", %" PRIx64 ")",
              region_index, ranges.size(), size, addr, addr + size);

    progress.Increment(1, "Adding Memory Range " + core_range.Dump());
    uint64_t bytes_read = 0;
    error = ReadWriteMemoryInChunks(data_buffer, core_range, bytes_read);
    if (error.Fail())
      return error;

    if (bytes_read == 0) {
      cleanup_required = true;
      descriptors[region_index].DataSize = 0;
    }
    if (bytes_read != size) {
      cleanup_required = true;
      descriptors[region_index].DataSize = bytes_read;
    }

    ++region_index;
  }

  // Early return if there is no cleanup needed.
  if (!cleanup_required) {
    return error;
  } else {
    // Flush to disk we can make the fixes in place.
    FlushBufferToDisk();
    // Fixup the descriptors that were not read correctly.
    m_core_file->SeekFromStart(starting_offset);
    size_t bytes_written = sizeof(MemoryDescriptor_64) * descriptors.size();
    error = m_core_file->Write(descriptors.data(), bytes_written);
    if (error.Fail() ||
        bytes_written != sizeof(MemoryDescriptor_64) * descriptors.size()) {
      error = Status::FromErrorStringWithFormat(
          "unable to write the memory descriptors (written %zd/%zd)",
          bytes_written, sizeof(MemoryDescriptor_64) * descriptors.size());
    }

    return error;
  }
}

Status MinidumpFileBuilder::AddData(const void *data, uint64_t size) {
  // Append the data to the buffer, if the buffer spills over, flush it to disk
  m_data.AppendData(data, size);
  if (m_data.GetByteSize() > MAX_WRITE_CHUNK_SIZE)
    return FlushBufferToDisk();

  return Status();
}

Status MinidumpFileBuilder::FlushBufferToDisk() {
  Status error;
  // Set the stream to it's end.
  m_core_file->SeekFromStart(m_saved_data_size);
  addr_t starting_size = m_data.GetByteSize();
  addr_t remaining_bytes = starting_size;
  offset_t offset = 0;

  while (remaining_bytes > 0) {
    size_t bytes_written = remaining_bytes;
    // We don't care how many bytes we wrote unless we got an error
    // so just decrement the remaining bytes.
    error = m_core_file->Write(m_data.GetBytes() + offset, bytes_written);
    if (error.Fail()) {
      error = Status::FromErrorStringWithFormat(
          "Wrote incorrect number of bytes to minidump file. (written %" PRIx64
          "/%" PRIx64 ")",
          starting_size - remaining_bytes, starting_size);
      return error;
    }

    offset += bytes_written;
    remaining_bytes -= bytes_written;
  }

  m_saved_data_size += starting_size;
  m_data.Clear();
  return error;
}

Status MinidumpFileBuilder::DumpFile() {
  Status error;
  // If anything is left unsaved, dump it.
  error = FlushBufferToDisk();
  if (error.Fail())
    return error;

  // Overwrite the header which we filled in earlier.
  error = DumpHeader();
  if (error.Fail())
    return error;

  // Overwrite the space saved for directories
  error = DumpDirectories();
  if (error.Fail())
    return error;

  return error;
}

void MinidumpFileBuilder::DeleteFile() noexcept {
  Log *log = GetLog(LLDBLog::Object);

  if (m_core_file) {
    Status error = m_core_file->Close();
    if (error.Fail())
      LLDB_LOGF(log, "Failed to close minidump file: %s", error.AsCString());

    m_core_file.reset();
  }
}
