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

#include "ThreadMinidump.h"

#include "lldb/Core/DumpDataExtractor.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionGroupBoolean.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/JITLoaderList.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/State.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Support/MemoryBuffer.h"

#include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
#include "Plugins/ObjectFile/Placeholder/ObjectFilePlaceholder.h"
#include "Plugins/Process/Utility/StopInfoMachException.h"

#include <memory>
#include <optional>

using namespace lldb;
using namespace lldb_private;
using namespace minidump;

LLDB_PLUGIN_DEFINE(ProcessMinidump)

namespace {

/// Duplicate the HashElfTextSection() from the breakpad sources.
///
/// Breakpad, a Google crash log reporting tool suite, creates minidump files
/// for many different architectures. When using Breakpad to create ELF
/// minidumps, it will check for a GNU build ID when creating a minidump file
/// and if one doesn't exist in the file, it will say the UUID of the file is a
/// checksum of up to the first 4096 bytes of the .text section. Facebook also
/// uses breakpad and modified this hash to avoid collisions so we can
/// calculate and check for this as well.
///
/// The breakpad code might end up hashing up to 15 bytes that immediately
/// follow the .text section in the file, so this code must do exactly what it
/// does so we can get an exact match for the UUID.
///
/// \param[in] module_sp The module to grab the .text section from.
///
/// \param[in,out] breakpad_uuid A vector that will receive the calculated
///                breakpad .text hash.
///
/// \param[in,out] facebook_uuid A vector that will receive the calculated
///                facebook .text hash.
///
void HashElfTextSection(ModuleSP module_sp, std::vector<uint8_t> &breakpad_uuid,
                        std::vector<uint8_t> &facebook_uuid) {
  SectionList *sect_list = module_sp->GetSectionList();
  if (sect_list == nullptr)
    return;
  SectionSP sect_sp = sect_list->FindSectionByName(".text");
  if (!sect_sp)
    return;
  constexpr size_t kMDGUIDSize = 16;
  constexpr size_t kBreakpadPageSize = 4096;
  // The breakpad code has a bug where it might access beyond the end of a
  // .text section by up to 15 bytes, so we must ensure we round up to the
  // next kMDGUIDSize byte boundary.
  DataExtractorSP extractor_sp;
  const size_t text_size = sect_sp->GetFileSize();
  const size_t read_size = std::min<size_t>(
      llvm::alignTo(text_size, kMDGUIDSize), kBreakpadPageSize);
  sect_sp->GetObjectFile()->GetData(sect_sp->GetFileOffset(), read_size,
                                    extractor_sp);

  breakpad_uuid.assign(kMDGUIDSize, 0);
  facebook_uuid.assign(kMDGUIDSize, 0);

  // The only difference between the breakpad hash and the facebook hash is the
  // hashing of the text section size into the hash prior to hashing the .text
  // contents.
  for (size_t i = 0; i < kMDGUIDSize; i++)
    facebook_uuid[i] ^= text_size % 255;

  // This code carefully duplicates how the hash was created in Breakpad
  // sources, including the error where it might has an extra 15 bytes past the
  // end of the .text section if the .text section is less than a page size in
  // length.
  const uint8_t *ptr = extractor_sp->GetDataStart();
  const uint8_t *ptr_end = extractor_sp->GetDataEnd();
  while (ptr < ptr_end) {
    for (unsigned i = 0; i < kMDGUIDSize; i++) {
      breakpad_uuid[i] ^= ptr[i];
      facebook_uuid[i] ^= ptr[i];
    }
    ptr += kMDGUIDSize;
  }
}

} // namespace

llvm::StringRef ProcessMinidump::GetPluginDescriptionStatic() {
  return "Minidump plug-in.";
}

lldb::ProcessSP ProcessMinidump::CreateInstance(lldb::TargetSP target_sp,
                                                lldb::ListenerSP listener_sp,
                                                const FileSpec *crash_file,
                                                bool can_connect) {
  if (!crash_file || can_connect)
    return nullptr;

  lldb::ProcessSP process_sp;
  // Read enough data for the Minidump header
  constexpr size_t header_size = sizeof(Header);
  auto DataPtr = FileSystem::Instance().CreateDataBuffer(crash_file->GetPath(),
                                                         header_size, 0);
  if (!DataPtr)
    return nullptr;

  lldbassert(DataPtr->GetByteSize() == header_size);
  if (identify_magic(toStringRef(DataPtr->GetData())) != llvm::file_magic::minidump)
    return nullptr;

  auto AllData =
      FileSystem::Instance().CreateDataBuffer(crash_file->GetPath(), -1, 0);
  if (!AllData)
    return nullptr;

  return std::make_shared<ProcessMinidump>(target_sp, listener_sp, *crash_file,
                                           std::move(AllData));
}

bool ProcessMinidump::CanDebug(lldb::TargetSP target_sp,
                               bool plugin_specified_by_name) {
  return true;
}

ProcessMinidump::ProcessMinidump(lldb::TargetSP target_sp,
                                 lldb::ListenerSP listener_sp,
                                 const FileSpec &core_file,
                                 DataBufferSP core_data)
    : PostMortemProcess(target_sp, listener_sp, core_file),
      m_core_data(std::move(core_data)), m_is_wow64(false) {}

ProcessMinidump::~ProcessMinidump() {
  Clear();
  // We need to call finalize on the process before destroying ourselves to
  // make sure all of the broadcaster cleanup goes as planned. If we destruct
  // this class, then Process::~Process() might have problems trying to fully
  // destroy the broadcaster.
  Finalize(true /* destructing */);
}

void ProcessMinidump::Initialize() {
  PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                GetPluginDescriptionStatic(),
                                ProcessMinidump::CreateInstance);
}

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

Status ProcessMinidump::DoLoadCore() {
  auto expected_parser = MinidumpParser::Create(m_core_data);
  if (!expected_parser)
    return Status::FromError(expected_parser.takeError());
  m_minidump_parser = std::move(*expected_parser);

  Status error;

  // Do we support the minidump's architecture?
  ArchSpec arch = GetArchitecture();
  switch (arch.GetMachine()) {
  case llvm::Triple::x86:
  case llvm::Triple::x86_64:
  case llvm::Triple::arm:
  case llvm::Triple::aarch64:
    // Any supported architectures must be listed here and also supported in
    // ThreadMinidump::CreateRegisterContextForFrame().
    break;
  default:
    error = Status::FromErrorStringWithFormat(
        "unsupported minidump architecture: %s", arch.GetArchitectureName());
    return error;
  }
  GetTarget().SetArchitecture(arch, true /*set_platform*/);

  m_thread_list = m_minidump_parser->GetThreads();
  auto exception_stream_it = m_minidump_parser->GetExceptionStreams();
  for (auto exception_stream_or_err : exception_stream_it) {
    // If we can't read an exception stream skip it
    // We should probably serve a warning
    if (!exception_stream_or_err) {
      LLDB_LOG_ERROR(GetLog(LLDBLog::Process),
                     exception_stream_or_err.takeError(),
                     "failed to read exception stream: {0}");
      continue;
    }
    const llvm::minidump::ExceptionStream &exception_stream =
        *exception_stream_or_err;

    if (!m_exceptions_by_tid
             .try_emplace(exception_stream.ThreadId, exception_stream)
             .second) {
      return Status::FromErrorStringWithFormatv(
          "Duplicate exception stream for tid {0}", exception_stream.ThreadId);
    }
  }

  SetUnixSignals(UnixSignals::Create(GetArchitecture()));

  ReadModuleList();
  if (ModuleSP module = GetTarget().GetExecutableModule())
    GetTarget().MergeArchitecture(module->GetArchitecture());
  std::optional<lldb::pid_t> pid = m_minidump_parser->GetPid();
  if (!pid) {
    Debugger::ReportWarning("unable to retrieve process ID from minidump file, "
                            "setting process ID to 1",
                            GetTarget().GetDebugger().GetID());
    pid = 1;
  }
  SetID(*pid);

  return error;
}

Status ProcessMinidump::DoDestroy() { return Status(); }

void ProcessMinidump::RefreshStateAfterStop() {

  for (const auto &[_, exception_stream] : m_exceptions_by_tid) {
    constexpr uint32_t BreakpadDumpRequested = 0xFFFFFFFF;
    if (exception_stream.ExceptionRecord.ExceptionCode ==
        BreakpadDumpRequested) {
      // This "ExceptionCode" value is a sentinel that is sometimes used
      // when generating a dump for a process that hasn't crashed.

      // TODO: The definition and use of this "dump requested" constant
      // in Breakpad are actually Linux-specific, and for similar use
      // cases on Mac/Windows it defines different constants, referring
      // to them as "simulated" exceptions; consider moving this check
      // down to the OS-specific paths and checking each OS for its own
      // constant.
      return;
    }

    lldb::StopInfoSP stop_info;
    lldb::ThreadSP stop_thread;

    Process::m_thread_list.SetSelectedThreadByID(exception_stream.ThreadId);
    stop_thread = Process::m_thread_list.GetSelectedThread();
    ArchSpec arch = GetArchitecture();

    if (arch.GetTriple().getOS() == llvm::Triple::Linux) {
      uint32_t signo = exception_stream.ExceptionRecord.ExceptionCode;
      if (signo == 0) {
        // No stop.
        return;
      }
      const char *description = nullptr;
      if (exception_stream.ExceptionRecord.ExceptionFlags ==
          llvm::minidump::Exception::LLDB_FLAG)
        description = reinterpret_cast<const char *>(
            exception_stream.ExceptionRecord.ExceptionInformation);

      llvm::StringRef description_str(description,
                                      Exception::MaxParameterBytes);
      stop_info = StopInfo::CreateStopReasonWithSignal(
          *stop_thread, signo, description_str.str().c_str());
    } else if (arch.GetTriple().getVendor() == llvm::Triple::Apple) {
      stop_info = StopInfoMachException::CreateStopReasonWithMachException(
          *stop_thread, exception_stream.ExceptionRecord.ExceptionCode, 2,
          exception_stream.ExceptionRecord.ExceptionFlags,
          exception_stream.ExceptionRecord.ExceptionAddress, 0);
    } else {
      std::string desc;
      llvm::raw_string_ostream desc_stream(desc);
      desc_stream << "Exception "
                  << llvm::format_hex(
                         exception_stream.ExceptionRecord.ExceptionCode, 8)
                  << " encountered at address "
                  << llvm::format_hex(
                         exception_stream.ExceptionRecord.ExceptionAddress, 8);
      stop_info =
          StopInfo::CreateStopReasonWithException(*stop_thread, desc.c_str());
    }

    stop_thread->SetStopInfo(stop_info);
  }
}

bool ProcessMinidump::IsAlive() { return true; }

bool ProcessMinidump::WarnBeforeDetach() const { return false; }

size_t ProcessMinidump::ReadMemory(const ProcessAddress &process_addr,
                                   void *buf, size_t size, Status &error) {
  lldb::addr_t addr = process_addr.GetValue();
  // Don't allow the caching that lldb_private::Process::ReadMemory does since
  // we have it all cached in our dump file anyway.
  return DoReadMemory(addr, buf, size, error);
}

size_t ProcessMinidump::DoReadMemory(const ProcessAddress &process_addr,
                                     void *buf, size_t size, Status &error) {
  lldb::addr_t addr = process_addr.GetValue();

  llvm::Expected<llvm::ArrayRef<uint8_t>> mem_maybe =
      m_minidump_parser->GetMemory(addr, size);
  if (!mem_maybe) {
    error = Status::FromError(mem_maybe.takeError());
    return 0;
  }

  llvm::ArrayRef<uint8_t> mem = *mem_maybe;

  std::memcpy(buf, mem.data(), mem.size());
  return mem.size();
}

ArchSpec ProcessMinidump::GetArchitecture() {
  if (!m_is_wow64) {
    return m_minidump_parser->GetArchitecture();
  }

  llvm::Triple triple;
  triple.setVendor(llvm::Triple::VendorType::UnknownVendor);
  triple.setArch(llvm::Triple::ArchType::x86);
  triple.setOS(llvm::Triple::OSType::Win32);
  return ArchSpec(triple);
}

DataExtractor ProcessMinidump::GetAuxvData() {
  std::optional<llvm::ArrayRef<uint8_t>> auxv =
      m_minidump_parser->GetStream(StreamType::LinuxAuxv);
  if (!auxv)
    return DataExtractor();

  return DataExtractor(auxv->data(), auxv->size(), GetByteOrder(),
                       GetAddressByteSize());
}

bool ProcessMinidump::IsLLDBMinidump() {
  std::optional<llvm::ArrayRef<uint8_t>> lldb_generated_section =
      m_minidump_parser->GetRawStream(StreamType::LLDBGenerated);
  return lldb_generated_section.has_value();
}

DynamicLoader *ProcessMinidump::GetDynamicLoader() {
  // This is a workaround for the dynamic loader not playing nice in issue
  // #119598. The specific reason we use the dynamic loader is to get the TLS
  // info sections, which we can assume are not being written to the minidump
  // unless it's an LLDB generate minidump.
  if (IsLLDBMinidump())
    return PostMortemProcess::GetDynamicLoader();
  return nullptr;
}

void ProcessMinidump::BuildMemoryRegions() {
  if (m_memory_regions)
    return;
  m_memory_regions.emplace();
  bool is_complete;
  std::tie(*m_memory_regions, is_complete) =
      m_minidump_parser->BuildMemoryRegions();

  if (is_complete)
    return;

  MemoryRegionInfos to_add;
  ModuleList &modules = GetTarget().GetImages();
  Target &target = GetTarget();
  modules.ForEach([&](const ModuleSP &module_sp) {
    SectionList *sections = module_sp->GetSectionList();
    for (size_t i = 0; i < sections->GetSize(); ++i) {
      SectionSP section_sp = sections->GetSectionAtIndex(i);
      addr_t load_addr = target.GetSectionLoadAddress(section_sp);
      if (load_addr == LLDB_INVALID_ADDRESS)
        continue;
      MemoryRegionInfo::RangeType section_range(load_addr,
                                                section_sp->GetByteSize());
      MemoryRegionInfo region =
          MinidumpParser::GetMemoryRegionInfo(*m_memory_regions, load_addr);
      if (region.GetMapped() != eLazyBoolYes &&
          region.GetRange().GetRangeBase() <= section_range.GetRangeBase() &&
          section_range.GetRangeEnd() <= region.GetRange().GetRangeEnd()) {
        to_add.emplace_back();
        to_add.back().GetRange() = section_range;
        to_add.back().SetLLDBPermissions(section_sp->GetPermissions());
        to_add.back().SetMapped(eLazyBoolYes);
        to_add.back().SetName(module_sp->GetFileSpec().GetPath().c_str());
      }
    }
    return IterationAction::Continue;
  });
  m_memory_regions->insert(m_memory_regions->end(), to_add.begin(),
                           to_add.end());
  llvm::sort(*m_memory_regions);
}

Status ProcessMinidump::DoGetMemoryRegionInfo(lldb::addr_t load_addr,
                                              MemoryRegionInfo &region) {
  BuildMemoryRegions();
  region = MinidumpParser::GetMemoryRegionInfo(*m_memory_regions, load_addr);
  return Status();
}

Status ProcessMinidump::GetMemoryRegions(MemoryRegionInfos &region_list) {
  BuildMemoryRegions();
  region_list = *m_memory_regions;
  return Status();
}

void ProcessMinidump::Clear() { Process::m_thread_list.Clear(); }

bool ProcessMinidump::DoUpdateThreadList(ThreadList &old_thread_list,
                                         ThreadList &new_thread_list) {
  for (const minidump::Thread &thread : m_thread_list) {
    LocationDescriptor context_location = thread.Context;

    // If the minidump contains an exception context, use it
    if (auto it = m_exceptions_by_tid.find(thread.ThreadId);
        it != m_exceptions_by_tid.end())
      context_location = it->second.ThreadContext;

    llvm::ArrayRef<uint8_t> context;
    if (!m_is_wow64)
      context = m_minidump_parser->GetThreadContext(context_location);
    else
      context = m_minidump_parser->GetThreadContextWow64(thread);

    lldb::ThreadSP thread_sp(new ThreadMinidump(*this, thread, context));
    new_thread_list.AddThread(thread_sp);
  }
  return new_thread_list.GetSize(false) > 0;
}

ModuleSP ProcessMinidump::GetOrCreateModule(UUID minidump_uuid,
                                            llvm::StringRef name,
                                            ModuleSpec module_spec) {
  Log *log = GetLog(LLDBLog::DynamicLoader);
  Status error;

  ModuleSP module_sp =
      GetTarget().GetOrCreateModule(module_spec, true /* notify */, &error);
  if (!module_sp)
    return module_sp;
  // We consider the module to be a match if the minidump UUID is a
  // prefix of the actual UUID, or if either of the UUIDs are empty.
  const auto dmp_bytes = minidump_uuid.GetBytes();
  const auto mod_bytes = module_sp->GetUUID().GetBytes();
  const bool match = dmp_bytes.empty() || mod_bytes.empty() ||
                     mod_bytes.take_front(dmp_bytes.size()) == dmp_bytes;
  if (match) {
    LLDB_LOG(log, "Partial uuid match for {0}.", name);
    return module_sp;
  }

  // Breakpad generates minindump files, and if there is no GNU build
  // ID in the binary, it will calculate a UUID by hashing first 4096
  // bytes of the .text section and using that as the UUID for a module
  // in the minidump. Facebook uses a modified breakpad client that
  // uses a slightly modified this hash to avoid collisions. Check for
  // UUIDs from the minindump that match these cases and accept the
  // module we find if they do match.
  std::vector<uint8_t> breakpad_uuid;
  std::vector<uint8_t> facebook_uuid;
  HashElfTextSection(module_sp, breakpad_uuid, facebook_uuid);
  if (dmp_bytes == llvm::ArrayRef<uint8_t>(breakpad_uuid)) {
    LLDB_LOG(log, "Breakpad .text hash match for {0}.", name);
    return module_sp;
  }
  if (dmp_bytes == llvm::ArrayRef<uint8_t>(facebook_uuid)) {
    LLDB_LOG(log, "Facebook .text hash match for {0}.", name);
    return module_sp;
  }
  // The UUID wasn't a partial match and didn't match the .text hash
  // so remove the module from the target, we will need to create a
  // placeholder object file.
  GetTarget().GetImages().Remove(module_sp);
  module_sp.reset();
  return module_sp;
}

void ProcessMinidump::ReadModuleList() {
  std::vector<const minidump::Module *> filtered_modules =
      m_minidump_parser->GetFilteredModuleList();

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

  for (auto module : filtered_modules) {
    std::string name = cantFail(m_minidump_parser->GetMinidumpFile().getString(
        module->ModuleNameRVA));
    const uint64_t load_addr = module->BaseOfImage;
    const uint64_t load_size = module->SizeOfImage;
    LLDB_LOG(log, "found module: name: {0} {1:x10}-{2:x10} size: {3}", name,
             load_addr, load_addr + load_size, load_size);

    // check if the process is wow64 - a 32 bit windows process running on a
    // 64 bit windows
    if (llvm::StringRef(name).ends_with_insensitive("wow64.dll")) {
      m_is_wow64 = true;
    }

    const auto uuid = m_minidump_parser->GetModuleUUID(module);
    auto file_spec = FileSpec(name, GetArchitecture().GetTriple());
    ModuleSpec module_spec(file_spec, uuid);
    module_spec.GetArchitecture() = GetArchitecture();
    Status error;
    // Try and find a module with a full UUID that matches. This function will
    // add the module to the target if it finds one.
    lldb::ModuleSP module_sp = GetTarget().GetOrCreateModule(module_spec,
                                                     true /* notify */, &error);
    if (module_sp) {
      LLDB_LOG(log, "Full uuid match for {0}.", name);
    } else {
      // We couldn't find a module with an exactly-matching UUID.  Sometimes
      // a minidump UUID is only a partial match or is a hash.  So try again
      // without specifying the UUID, then again without specifying the
      // directory if that fails.  This will allow us to find modules with
      // partial matches or hash UUIDs in user-provided sysroots or search
      // directories (target.exec-search-paths).
      ModuleSpec partial_module_spec = module_spec;
      partial_module_spec.GetUUID().Clear();
      module_sp = GetOrCreateModule(uuid, name, partial_module_spec);
      if (!module_sp) {
        partial_module_spec.GetFileSpec().ClearDirectory();
        module_sp = GetOrCreateModule(uuid, name, partial_module_spec);
      }
    }
    if (module_sp) {
      // Watch out for place holder modules that have different paths, but the
      // same UUID. If the base address is different, create a new module. If
      // we don't then we will end up setting the load address of a different
      // ObjectFilePlaceholder and an assertion will fire.
      auto *objfile = module_sp->GetObjectFile();
      if (objfile &&
          objfile->GetPluginName() ==
              ObjectFilePlaceholder::GetPluginNameStatic()) {
        if (((ObjectFilePlaceholder *)objfile)->GetBaseImageAddress() !=
            load_addr)
          module_sp.reset();
      }
    }
    if (!module_sp) {
      // We failed to locate a matching local object file. Fortunately, the
      // minidump format encodes enough information about each module's memory
      // range to allow us to create placeholder modules.
      //
      // This enables most LLDB functionality involving address-to-module
      // translations (ex. identifing the module for a stack frame PC) and
      // modules/sections commands (ex. target modules list, ...)
      LLDB_LOG(log,
               "Unable to locate the matching object file, creating a "
               "placeholder module for: {0}",
               name);

      module_sp = Module::CreateModuleFromObjectFile<ObjectFilePlaceholder>(
          module_spec, load_addr, load_size);
      // If we haven't loaded a main executable yet, set the first module to be
      // main executable
      if (!GetTarget().GetExecutableModule())
        GetTarget().SetExecutableModule(module_sp);
      else
        GetTarget().GetImages().Append(module_sp, true /* notify */);
    }

    bool load_addr_changed = false;
    module_sp->SetLoadAddress(GetTarget(), load_addr, false,
                              load_addr_changed);
  }
}

bool ProcessMinidump::GetProcessInfo(ProcessInstanceInfo &info) {
  info.Clear();
  info.SetProcessID(GetID());
  info.SetArchitecture(GetArchitecture());
  lldb::ModuleSP module_sp = GetTarget().GetExecutableModule();
  if (module_sp) {
    const bool add_exe_file_as_first_arg = false;
    info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
                           add_exe_file_as_first_arg);
  }
  return true;
}

// For minidumps there's no runtime generated code so we don't need JITLoader(s)
// Avoiding them will also speed up minidump loading since JITLoaders normally
// try to set up symbolic breakpoints, which in turn may force loading more
// debug information than needed.
JITLoaderList &ProcessMinidump::GetJITLoaders() {
  if (!m_jit_loaders_up) {
    m_jit_loaders_up = std::make_unique<JITLoaderList>();
  }
  return *m_jit_loaders_up;
}

#define INIT_BOOL(VAR, LONG, SHORT, DESC) \
    VAR(LLDB_OPT_SET_1, false, LONG, SHORT, DESC, false, true)
#define APPEND_OPT(VAR) \
    m_option_group.Append(&VAR, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1)

class CommandObjectProcessMinidumpDump : public CommandObjectParsed {
private:
  OptionGroupOptions m_option_group;
  OptionGroupBoolean m_dump_all;
  OptionGroupBoolean m_dump_directory;
  OptionGroupBoolean m_dump_linux_cpuinfo;
  OptionGroupBoolean m_dump_linux_proc_status;
  OptionGroupBoolean m_dump_linux_lsb_release;
  OptionGroupBoolean m_dump_linux_cmdline;
  OptionGroupBoolean m_dump_linux_environ;
  OptionGroupBoolean m_dump_linux_auxv;
  OptionGroupBoolean m_dump_linux_maps;
  OptionGroupBoolean m_dump_linux_proc_stat;
  OptionGroupBoolean m_dump_linux_proc_uptime;
  OptionGroupBoolean m_dump_linux_proc_fd;
  OptionGroupBoolean m_dump_linux_all;
  OptionGroupBoolean m_fb_app_data;
  OptionGroupBoolean m_fb_build_id;
  OptionGroupBoolean m_fb_version;
  OptionGroupBoolean m_fb_java_stack;
  OptionGroupBoolean m_fb_dalvik;
  OptionGroupBoolean m_fb_unwind;
  OptionGroupBoolean m_fb_error_log;
  OptionGroupBoolean m_fb_app_state;
  OptionGroupBoolean m_fb_abort;
  OptionGroupBoolean m_fb_thread;
  OptionGroupBoolean m_fb_logcat;
  OptionGroupBoolean m_fb_all;

  void SetDefaultOptionsIfNoneAreSet() {
    if (m_dump_all.GetOptionValue().GetCurrentValue() ||
        m_dump_linux_all.GetOptionValue().GetCurrentValue() ||
        m_fb_all.GetOptionValue().GetCurrentValue() ||
        m_dump_directory.GetOptionValue().GetCurrentValue() ||
        m_dump_linux_cpuinfo.GetOptionValue().GetCurrentValue() ||
        m_dump_linux_proc_status.GetOptionValue().GetCurrentValue() ||
        m_dump_linux_lsb_release.GetOptionValue().GetCurrentValue() ||
        m_dump_linux_cmdline.GetOptionValue().GetCurrentValue() ||
        m_dump_linux_environ.GetOptionValue().GetCurrentValue() ||
        m_dump_linux_auxv.GetOptionValue().GetCurrentValue() ||
        m_dump_linux_maps.GetOptionValue().GetCurrentValue() ||
        m_dump_linux_proc_stat.GetOptionValue().GetCurrentValue() ||
        m_dump_linux_proc_uptime.GetOptionValue().GetCurrentValue() ||
        m_dump_linux_proc_fd.GetOptionValue().GetCurrentValue() ||
        m_fb_app_data.GetOptionValue().GetCurrentValue() ||
        m_fb_build_id.GetOptionValue().GetCurrentValue() ||
        m_fb_version.GetOptionValue().GetCurrentValue() ||
        m_fb_java_stack.GetOptionValue().GetCurrentValue() ||
        m_fb_dalvik.GetOptionValue().GetCurrentValue() ||
        m_fb_unwind.GetOptionValue().GetCurrentValue() ||
        m_fb_error_log.GetOptionValue().GetCurrentValue() ||
        m_fb_app_state.GetOptionValue().GetCurrentValue() ||
        m_fb_abort.GetOptionValue().GetCurrentValue() ||
        m_fb_thread.GetOptionValue().GetCurrentValue() ||
        m_fb_logcat.GetOptionValue().GetCurrentValue())
      return;
    // If no options were set, then dump everything
    m_dump_all.GetOptionValue().SetCurrentValue(true);
  }
  bool DumpAll() const {
    return m_dump_all.GetOptionValue().GetCurrentValue();
  }
  bool DumpDirectory() const {
    return DumpAll() ||
        m_dump_directory.GetOptionValue().GetCurrentValue();
  }
  bool DumpLinux() const {
    return DumpAll() || m_dump_linux_all.GetOptionValue().GetCurrentValue();
  }
  bool DumpLinuxCPUInfo() const {
    return DumpLinux() ||
        m_dump_linux_cpuinfo.GetOptionValue().GetCurrentValue();
  }
  bool DumpLinuxProcStatus() const {
    return DumpLinux() ||
        m_dump_linux_proc_status.GetOptionValue().GetCurrentValue();
  }
  bool DumpLinuxProcStat() const {
    return DumpLinux() ||
        m_dump_linux_proc_stat.GetOptionValue().GetCurrentValue();
  }
  bool DumpLinuxLSBRelease() const {
    return DumpLinux() ||
        m_dump_linux_lsb_release.GetOptionValue().GetCurrentValue();
  }
  bool DumpLinuxCMDLine() const {
    return DumpLinux() ||
        m_dump_linux_cmdline.GetOptionValue().GetCurrentValue();
  }
  bool DumpLinuxEnviron() const {
    return DumpLinux() ||
        m_dump_linux_environ.GetOptionValue().GetCurrentValue();
  }
  bool DumpLinuxAuxv() const {
    return DumpLinux() ||
        m_dump_linux_auxv.GetOptionValue().GetCurrentValue();
  }
  bool DumpLinuxMaps() const {
    return DumpLinux() ||
        m_dump_linux_maps.GetOptionValue().GetCurrentValue();
  }
  bool DumpLinuxProcUptime() const {
    return DumpLinux() ||
        m_dump_linux_proc_uptime.GetOptionValue().GetCurrentValue();
  }
  bool DumpLinuxProcFD() const {
    return DumpLinux() ||
        m_dump_linux_proc_fd.GetOptionValue().GetCurrentValue();
  }
  bool DumpFacebook() const {
    return DumpAll() || m_fb_all.GetOptionValue().GetCurrentValue();
  }
  bool DumpFacebookAppData() const {
    return DumpFacebook() || m_fb_app_data.GetOptionValue().GetCurrentValue();
  }
  bool DumpFacebookBuildID() const {
    return DumpFacebook() || m_fb_build_id.GetOptionValue().GetCurrentValue();
  }
  bool DumpFacebookVersionName() const {
    return DumpFacebook() || m_fb_version.GetOptionValue().GetCurrentValue();
  }
  bool DumpFacebookJavaStack() const {
    return DumpFacebook() || m_fb_java_stack.GetOptionValue().GetCurrentValue();
  }
  bool DumpFacebookDalvikInfo() const {
    return DumpFacebook() || m_fb_dalvik.GetOptionValue().GetCurrentValue();
  }
  bool DumpFacebookUnwindSymbols() const {
    return DumpFacebook() || m_fb_unwind.GetOptionValue().GetCurrentValue();
  }
  bool DumpFacebookErrorLog() const {
    return DumpFacebook() || m_fb_error_log.GetOptionValue().GetCurrentValue();
  }
  bool DumpFacebookAppStateLog() const {
    return DumpFacebook() || m_fb_app_state.GetOptionValue().GetCurrentValue();
  }
  bool DumpFacebookAbortReason() const {
    return DumpFacebook() || m_fb_abort.GetOptionValue().GetCurrentValue();
  }
  bool DumpFacebookThreadName() const {
    return DumpFacebook() || m_fb_thread.GetOptionValue().GetCurrentValue();
  }
  bool DumpFacebookLogcat() const {
    return DumpFacebook() || m_fb_logcat.GetOptionValue().GetCurrentValue();
  }
public:
  CommandObjectProcessMinidumpDump(CommandInterpreter &interpreter)
  : CommandObjectParsed(interpreter, "process plugin dump",
      "Dump information from the minidump file.", nullptr),
    m_option_group(),
    INIT_BOOL(m_dump_all, "all", 'a',
              "Dump the everything in the minidump."),
    INIT_BOOL(m_dump_directory, "directory", 'd',
              "Dump the minidump directory map."),
    INIT_BOOL(m_dump_linux_cpuinfo, "cpuinfo", 'C',
              "Dump linux /proc/cpuinfo."),
    INIT_BOOL(m_dump_linux_proc_status, "status", 's',
              "Dump linux /proc/<pid>/status."),
    INIT_BOOL(m_dump_linux_lsb_release, "lsb-release", 'r',
              "Dump linux /etc/lsb-release."),
    INIT_BOOL(m_dump_linux_cmdline, "cmdline", 'c',
              "Dump linux /proc/<pid>/cmdline."),
    INIT_BOOL(m_dump_linux_environ, "environ", 'e',
              "Dump linux /proc/<pid>/environ."),
    INIT_BOOL(m_dump_linux_auxv, "auxv", 'x',
              "Dump linux /proc/<pid>/auxv."),
    INIT_BOOL(m_dump_linux_maps, "maps", 'm',
              "Dump linux /proc/<pid>/maps."),
    INIT_BOOL(m_dump_linux_proc_stat, "stat", 'S',
              "Dump linux /proc/<pid>/stat."),
    INIT_BOOL(m_dump_linux_proc_uptime, "uptime", 'u',
              "Dump linux process uptime."),
    INIT_BOOL(m_dump_linux_proc_fd, "fd", 'f',
              "Dump linux /proc/<pid>/fd."),
    INIT_BOOL(m_dump_linux_all, "linux", 'l',
              "Dump all linux streams."),
    INIT_BOOL(m_fb_app_data, "fb-app-data", 1,
              "Dump Facebook application custom data."),
    INIT_BOOL(m_fb_build_id, "fb-build-id", 2,
              "Dump the Facebook build ID."),
    INIT_BOOL(m_fb_version, "fb-version", 3,
              "Dump Facebook application version string."),
    INIT_BOOL(m_fb_java_stack, "fb-java-stack", 4,
              "Dump Facebook java stack."),
    INIT_BOOL(m_fb_dalvik, "fb-dalvik-info", 5,
              "Dump Facebook Dalvik info."),
    INIT_BOOL(m_fb_unwind, "fb-unwind-symbols", 6,
              "Dump Facebook unwind symbols."),
    INIT_BOOL(m_fb_error_log, "fb-error-log", 7,
              "Dump Facebook error log."),
    INIT_BOOL(m_fb_app_state, "fb-app-state-log", 8,
              "Dump Facebook java stack."),
    INIT_BOOL(m_fb_abort, "fb-abort-reason", 9,
              "Dump Facebook abort reason."),
    INIT_BOOL(m_fb_thread, "fb-thread-name", 10,
              "Dump Facebook thread name."),
    INIT_BOOL(m_fb_logcat, "fb-logcat", 11,
              "Dump Facebook logcat."),
    INIT_BOOL(m_fb_all, "facebook", 12, "Dump all Facebook streams.") {
    APPEND_OPT(m_dump_all);
    APPEND_OPT(m_dump_directory);
    APPEND_OPT(m_dump_linux_cpuinfo);
    APPEND_OPT(m_dump_linux_proc_status);
    APPEND_OPT(m_dump_linux_lsb_release);
    APPEND_OPT(m_dump_linux_cmdline);
    APPEND_OPT(m_dump_linux_environ);
    APPEND_OPT(m_dump_linux_auxv);
    APPEND_OPT(m_dump_linux_maps);
    APPEND_OPT(m_dump_linux_proc_stat);
    APPEND_OPT(m_dump_linux_proc_uptime);
    APPEND_OPT(m_dump_linux_proc_fd);
    APPEND_OPT(m_dump_linux_all);
    APPEND_OPT(m_fb_app_data);
    APPEND_OPT(m_fb_build_id);
    APPEND_OPT(m_fb_version);
    APPEND_OPT(m_fb_java_stack);
    APPEND_OPT(m_fb_dalvik);
    APPEND_OPT(m_fb_unwind);
    APPEND_OPT(m_fb_error_log);
    APPEND_OPT(m_fb_app_state);
    APPEND_OPT(m_fb_abort);
    APPEND_OPT(m_fb_thread);
    APPEND_OPT(m_fb_logcat);
    APPEND_OPT(m_fb_all);
    m_option_group.Finalize();
  }

  ~CommandObjectProcessMinidumpDump() override = default;

  Options *GetOptions() override { return &m_option_group; }

  void DoExecute(Args &command, CommandReturnObject &result) override {
    const size_t argc = command.GetArgumentCount();
    if (argc > 0) {
      result.AppendErrorWithFormat("'%s' take no arguments, only options",
                                   m_cmd_name.c_str());
      return;
    }
    SetDefaultOptionsIfNoneAreSet();

    ProcessMinidump *process = static_cast<ProcessMinidump *>(
        m_interpreter.GetExecutionContext().GetProcessPtr());
    result.SetStatus(eReturnStatusSuccessFinishResult);
    Stream &s = result.GetOutputStream();
    MinidumpParser &minidump = *process->m_minidump_parser;
    if (DumpDirectory()) {
      s.Printf("RVA        SIZE       TYPE       StreamType\n");
      s.Printf("---------- ---------- ---------- --------------------------\n");
      for (const auto &stream_desc : minidump.GetMinidumpFile().streams())
        s.Printf(
            "0x%8.8x 0x%8.8x 0x%8.8x %s\n", (uint32_t)stream_desc.Location.RVA,
            (uint32_t)stream_desc.Location.DataSize,
            (unsigned)(StreamType)stream_desc.Type,
            MinidumpParser::GetStreamTypeAsString(stream_desc.Type).data());
      s.Printf("\n");
    }
    auto DumpTextStream = [&](StreamType stream_type,
                              llvm::StringRef label) -> void {
      auto bytes = minidump.GetStream(stream_type);
      if (!bytes.empty()) {
        if (label.empty())
          label = MinidumpParser::GetStreamTypeAsString(stream_type);
        s.Printf("%s:\n%s\n\n", label.data(), bytes.data());
      }
    };
    auto DumpBinaryStream = [&](StreamType stream_type,
                                llvm::StringRef label) -> void {
      auto bytes = minidump.GetStream(stream_type);
      if (!bytes.empty()) {
        if (label.empty())
          label = MinidumpParser::GetStreamTypeAsString(stream_type);
        s.Printf("%s:\n", label.data());
        DataExtractor data(bytes.data(), bytes.size(), eByteOrderLittle,
                           process->GetAddressByteSize());
        DumpDataExtractor(data, &s, 0, lldb::eFormatBytesWithASCII, 1,
                          bytes.size(), 16, 0, 0, 0);
        s.Printf("\n\n");
      }
    };

    if (DumpLinuxCPUInfo())
      DumpTextStream(StreamType::LinuxCPUInfo, "/proc/cpuinfo");
    if (DumpLinuxProcStatus())
      DumpTextStream(StreamType::LinuxProcStatus, "/proc/PID/status");
    if (DumpLinuxLSBRelease())
      DumpTextStream(StreamType::LinuxLSBRelease, "/etc/lsb-release");
    if (DumpLinuxCMDLine())
      DumpTextStream(StreamType::LinuxCMDLine, "/proc/PID/cmdline");
    if (DumpLinuxEnviron())
      DumpTextStream(StreamType::LinuxEnviron, "/proc/PID/environ");
    if (DumpLinuxAuxv())
      DumpBinaryStream(StreamType::LinuxAuxv, "/proc/PID/auxv");
    if (DumpLinuxMaps())
      DumpTextStream(StreamType::LinuxMaps, "/proc/PID/maps");
    if (DumpLinuxProcStat())
      DumpTextStream(StreamType::LinuxProcStat, "/proc/PID/stat");
    if (DumpLinuxProcUptime())
      DumpTextStream(StreamType::LinuxProcUptime, "uptime");
    if (DumpLinuxProcFD())
      DumpTextStream(StreamType::LinuxProcFD, "/proc/PID/fd");
    if (DumpFacebookAppData())
      DumpTextStream(StreamType::FacebookAppCustomData,
                     "Facebook App Data");
    if (DumpFacebookBuildID()) {
      auto bytes = minidump.GetStream(StreamType::FacebookBuildID);
      if (bytes.size() >= 4) {
        DataExtractor data(bytes.data(), bytes.size(), eByteOrderLittle,
                           process->GetAddressByteSize());
        lldb::offset_t offset = 0;
        uint32_t build_id = data.GetU32(&offset);
        s.Printf("Facebook Build ID:\n");
        s.Printf("%u\n", build_id);
        s.Printf("\n");
      }
    }
    if (DumpFacebookVersionName())
      DumpTextStream(StreamType::FacebookAppVersionName,
                     "Facebook Version String");
    if (DumpFacebookJavaStack())
      DumpTextStream(StreamType::FacebookJavaStack,
                     "Facebook Java Stack");
    if (DumpFacebookDalvikInfo())
      DumpTextStream(StreamType::FacebookDalvikInfo,
                     "Facebook Dalvik Info");
    if (DumpFacebookUnwindSymbols())
      DumpBinaryStream(StreamType::FacebookUnwindSymbols,
                       "Facebook Unwind Symbols Bytes");
    if (DumpFacebookErrorLog())
      DumpTextStream(StreamType::FacebookDumpErrorLog,
                     "Facebook Error Log");
    if (DumpFacebookAppStateLog())
      DumpTextStream(StreamType::FacebookAppStateLog,
                     "Faceook Application State Log");
    if (DumpFacebookAbortReason())
      DumpTextStream(StreamType::FacebookAbortReason,
                     "Facebook Abort Reason");
    if (DumpFacebookThreadName())
      DumpTextStream(StreamType::FacebookThreadName,
                     "Facebook Thread Name");
    if (DumpFacebookLogcat())
      DumpTextStream(StreamType::FacebookLogcat, "Facebook Logcat");
  }
};

class CommandObjectMultiwordProcessMinidump : public CommandObjectMultiword {
public:
  CommandObjectMultiwordProcessMinidump(CommandInterpreter &interpreter)
    : CommandObjectMultiword(interpreter, "process plugin",
          "Commands for operating on a ProcessMinidump process.",
          "process plugin <subcommand> [<subcommand-options>]") {
    LoadSubCommand("dump",
        CommandObjectSP(new CommandObjectProcessMinidumpDump(interpreter)));
  }

  ~CommandObjectMultiwordProcessMinidump() override = default;
};

CommandObject *ProcessMinidump::GetPluginCommandObject() {
  if (!m_command_sp)
    m_command_sp = std::make_shared<CommandObjectMultiwordProcessMinidump>(
        GetTarget().GetDebugger().GetCommandInterpreter());
  return m_command_sp.get();
}
