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

#include "FormatUtil.h"
#include "SystemInitializerTest.h"

#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Expression/IRMemoryMap.h"
#include "lldb/Initialization/SystemLifetimeManager.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"

#include "llvm/ADT/IntervalMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/WithColor.h"
#include <cstdio>
#include <thread>

using namespace lldb;
using namespace lldb_private;
using namespace llvm;

namespace opts {
static cl::SubCommand BreakpointSubcommand("breakpoints",
                                           "Test breakpoint resolution");
cl::SubCommand ObjectFileSubcommand("object-file",
                                    "Display LLDB object file information");
cl::SubCommand SymbolsSubcommand("symbols", "Dump symbols for an object file");
cl::SubCommand IRMemoryMapSubcommand("ir-memory-map", "Test IRMemoryMap");

cl::opt<std::string> Log("log", cl::desc("Path to a log file"), cl::init(""),
                         cl::sub(BreakpointSubcommand),
                         cl::sub(ObjectFileSubcommand),
                         cl::sub(SymbolsSubcommand),
                         cl::sub(IRMemoryMapSubcommand));

/// Create a target using the file pointed to by \p Filename, or abort.
TargetSP createTarget(Debugger &Dbg, const std::string &Filename);

/// Read \p Filename into a null-terminated buffer, or abort.
std::unique_ptr<MemoryBuffer> openFile(const std::string &Filename);

namespace breakpoint {
static cl::opt<std::string> Target(cl::Positional, cl::desc("<target>"),
                                   cl::Required, cl::sub(BreakpointSubcommand));
static cl::opt<std::string> CommandFile(cl::Positional,
                                        cl::desc("<command-file>"),
                                        cl::init("-"),
                                        cl::sub(BreakpointSubcommand));
static cl::opt<bool> Persistent(
    "persistent",
    cl::desc("Don't automatically remove all breakpoints before each command"),
    cl::sub(BreakpointSubcommand));

static llvm::StringRef plural(uintmax_t value) { return value == 1 ? "" : "s"; }
static void dumpState(const BreakpointList &List, LinePrinter &P);
static std::string substitute(StringRef Cmd);
static int evaluateBreakpoints(Debugger &Dbg);
} // namespace breakpoint

namespace object {
cl::opt<bool> SectionContents("contents",
                              cl::desc("Dump each section's contents"),
                              cl::sub(ObjectFileSubcommand));
cl::opt<bool> SectionDependentModules("dep-modules",
                                      cl::desc("Dump each dependent module"),
                                      cl::sub(ObjectFileSubcommand));
cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<input files>"),
                                     cl::OneOrMore,
                                     cl::sub(ObjectFileSubcommand));
} // namespace object

namespace symbols {
static cl::opt<std::string> InputFile(cl::Positional, cl::desc("<input file>"),
                                      cl::Required, cl::sub(SymbolsSubcommand));

static cl::opt<std::string>
    SymbolPath("symbol-file",
               cl::desc("The file from which to fetch symbol information."),
               cl::value_desc("file"), cl::sub(SymbolsSubcommand));

enum class FindType {
  None,
  Function,
  Block,
  Namespace,
  Type,
  Variable,
};
static cl::opt<FindType> Find(
    "find", cl::desc("Choose search type:"),
    cl::values(
        clEnumValN(FindType::None, "none", "No search, just dump the module."),
        clEnumValN(FindType::Function, "function", "Find functions."),
        clEnumValN(FindType::Block, "block", "Find blocks."),
        clEnumValN(FindType::Namespace, "namespace", "Find namespaces."),
        clEnumValN(FindType::Type, "type", "Find types."),
        clEnumValN(FindType::Variable, "variable", "Find global variables.")),
    cl::sub(SymbolsSubcommand));

static cl::opt<std::string> Name("name", cl::desc("Name to find."),
                                 cl::sub(SymbolsSubcommand));
static cl::opt<bool>
    Regex("regex",
          cl::desc("Search using regular expressions (avaliable for variables "
                   "and functions only)."),
          cl::sub(SymbolsSubcommand));
static cl::opt<std::string>
    Context("context",
            cl::desc("Restrict search to the context of the given variable."),
            cl::value_desc("variable"), cl::sub(SymbolsSubcommand));

static cl::list<FunctionNameType> FunctionNameFlags(
    "function-flags", cl::desc("Function search flags:"),
    cl::values(clEnumValN(eFunctionNameTypeAuto, "auto",
                          "Automatically deduce flags based on name."),
               clEnumValN(eFunctionNameTypeFull, "full", "Full function name."),
               clEnumValN(eFunctionNameTypeBase, "base", "Base name."),
               clEnumValN(eFunctionNameTypeMethod, "method", "Method name."),
               clEnumValN(eFunctionNameTypeSelector, "selector",
                          "Selector name.")),
    cl::sub(SymbolsSubcommand));
static FunctionNameType getFunctionNameFlags() {
  FunctionNameType Result = FunctionNameType(0);
  for (FunctionNameType Flag : FunctionNameFlags)
    Result = FunctionNameType(Result | Flag);
  return Result;
}

static cl::opt<bool> DumpAST("dump-ast",
                             cl::desc("Dump AST restored from symbols."),
                             cl::sub(SymbolsSubcommand));

static cl::opt<bool> Verify("verify", cl::desc("Verify symbol information."),
                            cl::sub(SymbolsSubcommand));

static cl::opt<std::string> File("file",
                                 cl::desc("File (compile unit) to search."),
                                 cl::sub(SymbolsSubcommand));
static cl::opt<int> Line("line", cl::desc("Line to search."),
                         cl::sub(SymbolsSubcommand));

static Expected<CompilerDeclContext> getDeclContext(SymbolVendor &Vendor);

static Error findFunctions(lldb_private::Module &Module);
static Error findBlocks(lldb_private::Module &Module);
static Error findNamespaces(lldb_private::Module &Module);
static Error findTypes(lldb_private::Module &Module);
static Error findVariables(lldb_private::Module &Module);
static Error dumpModule(lldb_private::Module &Module);
static Error dumpAST(lldb_private::Module &Module);
static Error verify(lldb_private::Module &Module);

static Expected<Error (*)(lldb_private::Module &)> getAction();
static int dumpSymbols(Debugger &Dbg);
} // namespace symbols

namespace irmemorymap {
static cl::opt<std::string> Target(cl::Positional, cl::desc("<target>"),
                                   cl::Required,
                                   cl::sub(IRMemoryMapSubcommand));
static cl::opt<std::string> CommandFile(cl::Positional,
                                        cl::desc("<command-file>"),
                                        cl::init("-"),
                                        cl::sub(IRMemoryMapSubcommand));
static cl::opt<bool> UseHostOnlyAllocationPolicy(
    "host-only", cl::desc("Use the host-only allocation policy"),
    cl::init(false), cl::sub(IRMemoryMapSubcommand));

using AllocationT = std::pair<addr_t, addr_t>;
using AddrIntervalMap =
    IntervalMap<addr_t, unsigned, 8, IntervalMapHalfOpenInfo<addr_t>>;

struct IRMemoryMapTestState {
  TargetSP Target;
  IRMemoryMap Map;

  AddrIntervalMap::Allocator IntervalMapAllocator;
  AddrIntervalMap Allocations;

  StringMap<addr_t> Label2AddrMap;

  IRMemoryMapTestState(TargetSP Target)
      : Target(Target), Map(Target), Allocations(IntervalMapAllocator) {}
};

bool evalMalloc(StringRef Line, IRMemoryMapTestState &State);
bool evalFree(StringRef Line, IRMemoryMapTestState &State);
int evaluateMemoryMapCommands(Debugger &Dbg);
} // namespace irmemorymap

} // namespace opts

template <typename... Args>
static Error make_string_error(const char *Format, Args &&... args) {
  return llvm::make_error<llvm::StringError>(
      llvm::formatv(Format, std::forward<Args>(args)...).str(),
      llvm::inconvertibleErrorCode());
}

TargetSP opts::createTarget(Debugger &Dbg, const std::string &Filename) {
  TargetSP Target;
  Status ST = Dbg.GetTargetList().CreateTarget(
      Dbg, Filename, /*triple*/ "", eLoadDependentsNo,
      /*platform_options*/ nullptr, Target);
  if (ST.Fail()) {
    errs() << formatv("Failed to create target '{0}: {1}\n", Filename, ST);
    exit(1);
  }
  return Target;
}

std::unique_ptr<MemoryBuffer> opts::openFile(const std::string &Filename) {
  auto MB = MemoryBuffer::getFileOrSTDIN(Filename);
  if (!MB) {
    errs() << formatv("Could not open file '{0}: {1}\n", Filename,
                      MB.getError().message());
    exit(1);
  }
  return std::move(*MB);
}

void opts::breakpoint::dumpState(const BreakpointList &List, LinePrinter &P) {
  P.formatLine("{0} breakpoint{1}", List.GetSize(), plural(List.GetSize()));
  if (List.GetSize() > 0)
    P.formatLine("At least one breakpoint.");
  for (size_t i = 0, e = List.GetSize(); i < e; ++i) {
    BreakpointSP BP = List.GetBreakpointAtIndex(i);
    P.formatLine("Breakpoint ID {0}:", BP->GetID());
    AutoIndent Indent(P, 2);
    P.formatLine("{0} location{1}.", BP->GetNumLocations(),
                 plural(BP->GetNumLocations()));
    if (BP->GetNumLocations() > 0)
      P.formatLine("At least one location.");
    P.formatLine("{0} resolved location{1}.", BP->GetNumResolvedLocations(),
                 plural(BP->GetNumResolvedLocations()));
    if (BP->GetNumResolvedLocations() > 0)
      P.formatLine("At least one resolved location.");
    for (size_t l = 0, le = BP->GetNumLocations(); l < le; ++l) {
      BreakpointLocationSP Loc = BP->GetLocationAtIndex(l);
      P.formatLine("Location ID {0}:", Loc->GetID());
      AutoIndent Indent(P, 2);
      P.formatLine("Enabled: {0}", Loc->IsEnabled());
      P.formatLine("Resolved: {0}", Loc->IsResolved());
      SymbolContext sc;
      Loc->GetAddress().CalculateSymbolContext(&sc);
      lldb_private::StreamString S;
      sc.DumpStopContext(&S, BP->GetTarget().GetProcessSP().get(),
                         Loc->GetAddress(), false, true, false, true, true);
      P.formatLine("Address: {0}", S.GetString());
    }
  }
  P.NewLine();
}

std::string opts::breakpoint::substitute(StringRef Cmd) {
  std::string Result;
  raw_string_ostream OS(Result);
  while (!Cmd.empty()) {
    switch (Cmd[0]) {
    case '%':
      if (Cmd.consume_front("%p") && (Cmd.empty() || !isalnum(Cmd[0]))) {
        OS << sys::path::parent_path(breakpoint::CommandFile);
        break;
      }
      LLVM_FALLTHROUGH;
    default:
      size_t pos = Cmd.find('%');
      OS << Cmd.substr(0, pos);
      Cmd = Cmd.substr(pos);
      break;
    }
  }
  return std::move(OS.str());
}

int opts::breakpoint::evaluateBreakpoints(Debugger &Dbg) {
  TargetSP Target = opts::createTarget(Dbg, breakpoint::Target);
  std::unique_ptr<MemoryBuffer> MB = opts::openFile(breakpoint::CommandFile);

  LinePrinter P(4, outs());
  StringRef Rest = MB->getBuffer();
  int HadErrors = 0;
  while (!Rest.empty()) {
    StringRef Line;
    std::tie(Line, Rest) = Rest.split('\n');
    Line = Line.ltrim();
    if (Line.empty() || Line[0] == '#')
      continue;

    if (!Persistent)
      Target->RemoveAllBreakpoints(/*internal_also*/ true);

    std::string Command = substitute(Line);
    P.formatLine("Command: {0}", Command);
    CommandReturnObject Result;
    if (!Dbg.GetCommandInterpreter().HandleCommand(
            Command.c_str(), /*add_to_history*/ eLazyBoolNo, Result)) {
      P.formatLine("Failed: {0}", Result.GetErrorData());
      HadErrors = 1;
      continue;
    }

    dumpState(Target->GetBreakpointList(/*internal*/ false), P);
  }
  return HadErrors;
}

Expected<CompilerDeclContext>
opts::symbols::getDeclContext(SymbolVendor &Vendor) {
  if (Context.empty())
    return CompilerDeclContext();
  VariableList List;
  Vendor.FindGlobalVariables(ConstString(Context), nullptr, UINT32_MAX, List);
  if (List.Empty())
    return make_string_error("Context search didn't find a match.");
  if (List.GetSize() > 1)
    return make_string_error("Context search found multiple matches.");
  return List.GetVariableAtIndex(0)->GetDeclContext();
}

Error opts::symbols::findFunctions(lldb_private::Module &Module) {
  SymbolVendor &Vendor = *Module.GetSymbolVendor();
  SymbolContextList List;
  if (!File.empty()) {
    assert(Line != 0);

    FileSpec src_file(File);
    size_t cu_count = Module.GetNumCompileUnits();
    for (size_t i = 0; i < cu_count; i++) {
      lldb::CompUnitSP cu_sp = Module.GetCompileUnitAtIndex(i);
      if (!cu_sp)
        continue;

      LineEntry le;
      cu_sp->FindLineEntry(0, Line, &src_file, false, &le);
      if (!le.IsValid())
        continue;

      auto addr = le.GetSameLineContiguousAddressRange().GetBaseAddress();
      if (!addr.IsValid())
        continue;

      SymbolContext sc;
      uint32_t resolved =
          addr.CalculateSymbolContext(&sc, eSymbolContextFunction);
      if (resolved & eSymbolContextFunction)
        List.Append(sc);
    }
  } else if (Regex) {
    RegularExpression RE(Name);
    assert(RE.IsValid());
    Vendor.FindFunctions(RE, true, false, List);
  } else {
    Expected<CompilerDeclContext> ContextOr = getDeclContext(Vendor);
    if (!ContextOr)
      return ContextOr.takeError();
    CompilerDeclContext *ContextPtr =
        ContextOr->IsValid() ? &*ContextOr : nullptr;

    Vendor.FindFunctions(ConstString(Name), ContextPtr, getFunctionNameFlags(),
                         true, false, List);
  }
  outs() << formatv("Found {0} functions:\n", List.GetSize());
  StreamString Stream;
  List.Dump(&Stream, nullptr);
  outs() << Stream.GetData() << "\n";
  return Error::success();
}

Error opts::symbols::findBlocks(lldb_private::Module &Module) {
  assert(!Regex);
  assert(!File.empty());
  assert(Line != 0);

  SymbolContextList List;

  FileSpec src_file(File);
  size_t cu_count = Module.GetNumCompileUnits();
  for (size_t i = 0; i < cu_count; i++) {
    lldb::CompUnitSP cu_sp = Module.GetCompileUnitAtIndex(i);
    if (!cu_sp)
      continue;

    LineEntry le;
    cu_sp->FindLineEntry(0, Line, &src_file, false, &le);
    if (!le.IsValid())
      continue;

    auto addr = le.GetSameLineContiguousAddressRange().GetBaseAddress();
    if (!addr.IsValid())
      continue;

    SymbolContext sc;
    uint32_t resolved = addr.CalculateSymbolContext(&sc, eSymbolContextBlock);
    if (resolved & eSymbolContextBlock)
      List.Append(sc);
  }

  outs() << formatv("Found {0} blocks:\n", List.GetSize());
  StreamString Stream;
  List.Dump(&Stream, nullptr);
  outs() << Stream.GetData() << "\n";
  return Error::success();
}

Error opts::symbols::findNamespaces(lldb_private::Module &Module) {
  SymbolVendor &Vendor = *Module.GetSymbolVendor();
  Expected<CompilerDeclContext> ContextOr = getDeclContext(Vendor);
  if (!ContextOr)
    return ContextOr.takeError();
  CompilerDeclContext *ContextPtr =
      ContextOr->IsValid() ? &*ContextOr : nullptr;

  CompilerDeclContext Result =
      Vendor.FindNamespace(ConstString(Name), ContextPtr);
  if (Result)
    outs() << "Found namespace: "
           << Result.GetScopeQualifiedName().GetStringRef() << "\n";
  else
    outs() << "Namespace not found.\n";
  return Error::success();
}

Error opts::symbols::findTypes(lldb_private::Module &Module) {
  SymbolVendor &Vendor = *Module.GetSymbolVendor();
  Expected<CompilerDeclContext> ContextOr = getDeclContext(Vendor);
  if (!ContextOr)
    return ContextOr.takeError();
  CompilerDeclContext *ContextPtr =
      ContextOr->IsValid() ? &*ContextOr : nullptr;

  DenseSet<SymbolFile *> SearchedFiles;
  TypeMap Map;
  Vendor.FindTypes(ConstString(Name), ContextPtr, true, UINT32_MAX,
                   SearchedFiles, Map);

  outs() << formatv("Found {0} types:\n", Map.GetSize());
  StreamString Stream;
  Map.Dump(&Stream, false);
  outs() << Stream.GetData() << "\n";
  return Error::success();
}

Error opts::symbols::findVariables(lldb_private::Module &Module) {
  SymbolVendor &Vendor = *Module.GetSymbolVendor();
  VariableList List;
  if (Regex) {
    RegularExpression RE(Name);
    assert(RE.IsValid());
    Vendor.FindGlobalVariables(RE, UINT32_MAX, List);
  } else if (!File.empty()) {
    CompUnitSP CU;
    for (size_t Ind = 0; !CU && Ind < Module.GetNumCompileUnits(); ++Ind) {
      CompUnitSP Candidate = Module.GetCompileUnitAtIndex(Ind);
      if (!Candidate || Candidate->GetFilename().GetStringRef() != File)
        continue;
      if (CU)
        return make_string_error("Multiple compile units for file `{0}` found.",
                                 File);
      CU = std::move(Candidate);
    }

    if (!CU)
      return make_string_error("Compile unit `{0}` not found.", File);

    List.AddVariables(CU->GetVariableList(true).get());
  } else {
    Expected<CompilerDeclContext> ContextOr = getDeclContext(Vendor);
    if (!ContextOr)
      return ContextOr.takeError();
    CompilerDeclContext *ContextPtr =
        ContextOr->IsValid() ? &*ContextOr : nullptr;

    Vendor.FindGlobalVariables(ConstString(Name), ContextPtr, UINT32_MAX, List);
  }
  outs() << formatv("Found {0} variables:\n", List.GetSize());
  StreamString Stream;
  List.Dump(&Stream, false);
  outs() << Stream.GetData() << "\n";
  return Error::success();
}

Error opts::symbols::dumpModule(lldb_private::Module &Module) {
  StreamString Stream;
  Module.ParseAllDebugSymbols();
  Module.Dump(&Stream);
  outs() << Stream.GetData() << "\n";
  return Error::success();
}

Error opts::symbols::dumpAST(lldb_private::Module &Module) {
  SymbolVendor &plugin = *Module.GetSymbolVendor();
   Module.ParseAllDebugSymbols();

  auto symfile = plugin.GetSymbolFile();
  if (!symfile)
    return make_string_error("Module has no symbol file.");

  auto clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
      symfile->GetTypeSystemForLanguage(eLanguageTypeC_plus_plus));
  if (!clang_ast_ctx)
    return make_string_error("Can't retrieve Clang AST context.");

  auto ast_ctx = clang_ast_ctx->getASTContext();
  if (!ast_ctx)
    return make_string_error("Can't retrieve AST context.");

  auto tu = ast_ctx->getTranslationUnitDecl();
  if (!tu)
    return make_string_error("Can't retrieve translation unit declaration.");

  tu->print(outs());

  return Error::success();
}

Error opts::symbols::verify(lldb_private::Module &Module) {
  SymbolVendor &plugin = *Module.GetSymbolVendor();

  SymbolFile *symfile = plugin.GetSymbolFile();
  if (!symfile)
    return make_string_error("Module has no symbol file.");

  uint32_t comp_units_count = symfile->GetNumCompileUnits();

  outs() << "Found " << comp_units_count << " compile units.\n";

  for (uint32_t i = 0; i < comp_units_count; i++) {
    lldb::CompUnitSP comp_unit = symfile->ParseCompileUnitAtIndex(i);
    if (!comp_unit)
      return make_string_error("Connot parse compile unit {0}.", i);

    outs() << "Processing '" << comp_unit->GetFilename().AsCString()
           << "' compile unit.\n";

    LineTable *lt = comp_unit->GetLineTable();
    if (!lt)
      return make_string_error("Can't get a line table of a compile unit.");

    uint32_t count = lt->GetSize();

    outs() << "The line table contains " << count << " entries.\n";

    if (count == 0)
      continue;

    LineEntry le;
    if (!lt->GetLineEntryAtIndex(0, le))
      return make_string_error("Can't get a line entry of a compile unit.");

    for (uint32_t i = 1; i < count; i++) {
      lldb::addr_t curr_end =
          le.range.GetBaseAddress().GetFileAddress() + le.range.GetByteSize();

      if (!lt->GetLineEntryAtIndex(i, le))
        return make_string_error("Can't get a line entry of a compile unit");

      if (curr_end > le.range.GetBaseAddress().GetFileAddress())
        return make_string_error(
            "Line table of a compile unit is inconsistent.");
    }
  }

  outs() << "The symbol information is verified.\n";

  return Error::success();
}

Expected<Error (*)(lldb_private::Module &)> opts::symbols::getAction() {
  if (Verify && DumpAST)
    return make_string_error(
        "Cannot both verify symbol information and dump AST.");

  if (Verify) {
    if (Find != FindType::None)
      return make_string_error(
          "Cannot both search and verify symbol information.");
    if (Regex || !Context.empty() || !Name.empty() || !File.empty() ||
        Line != 0)
      return make_string_error(
          "-regex, -context, -name, -file and -line options are not "
          "applicable for symbol verification.");
    return verify;
  }

  if (DumpAST) {
    if (Find != FindType::None)
      return make_string_error("Cannot both search and dump AST.");
    if (Regex || !Context.empty() || !Name.empty() || !File.empty() ||
        Line != 0)
      return make_string_error(
          "-regex, -context, -name, -file and -line options are not "
          "applicable for dumping AST.");
    return dumpAST;
  }

  if (Regex && !Context.empty())
    return make_string_error(
        "Cannot search using both regular expressions and context.");

  if (Regex && !RegularExpression(Name).IsValid())
    return make_string_error("`{0}` is not a valid regular expression.", Name);

  if (Regex + !Context.empty() + !File.empty() >= 2)
    return make_string_error(
        "Only one of -regex, -context and -file may be used simultaneously.");
  if (Regex && Name.empty())
    return make_string_error("-regex used without a -name");

  switch (Find) {
  case FindType::None:
    if (!Context.empty() || !Name.empty() || !File.empty() || Line != 0)
      return make_string_error(
          "Specify search type (-find) to use search options.");
    return dumpModule;

  case FindType::Function:
    if (!File.empty() + (Line != 0) == 1)
      return make_string_error("Both file name and line number must be "
                               "specified when searching a function "
                               "by file position.");
    if (Regex + (getFunctionNameFlags() != 0) + !File.empty() >= 2)
      return make_string_error("Only one of regular expression, function-flags "
                               "and file position may be used simultaneously "
                               "when searching a function.");
    return findFunctions;

  case FindType::Block:
    if (File.empty() || Line == 0)
      return make_string_error("Both file name and line number must be "
                               "specified when searching a block.");
    if (Regex || getFunctionNameFlags() != 0)
      return make_string_error("Cannot use regular expression or "
                               "function-flags for searching a block.");
    return findBlocks;

  case FindType::Namespace:
    if (Regex || !File.empty() || Line != 0)
      return make_string_error("Cannot search for namespaces using regular "
                               "expressions, file names or line numbers.");
    return findNamespaces;

  case FindType::Type:
    if (Regex || !File.empty() || Line != 0)
      return make_string_error("Cannot search for types using regular "
                               "expressions, file names or line numbers.");
    return findTypes;

  case FindType::Variable:
    if (Line != 0)
      return make_string_error("Cannot search for variables "
                               "using line numbers.");
    return findVariables;
  }

  llvm_unreachable("Unsupported symbol action.");
}

int opts::symbols::dumpSymbols(Debugger &Dbg) {
  auto ActionOr = getAction();
  if (!ActionOr) {
    logAllUnhandledErrors(ActionOr.takeError(), WithColor::error(), "");
    return 1;
  }
  auto Action = *ActionOr;

  outs() << "Module: " << InputFile << "\n";
  ModuleSpec Spec{FileSpec(InputFile)};
  StringRef Symbols = SymbolPath.empty() ? InputFile : SymbolPath;
  Spec.GetSymbolFileSpec().SetFile(Symbols, FileSpec::Style::native);

  auto ModulePtr = std::make_shared<lldb_private::Module>(Spec);
  SymbolVendor *Vendor = ModulePtr->GetSymbolVendor();
  if (!Vendor) {
    WithColor::error() << "Module has no symbol vendor.\n";
    return 1;
  }

  if (Error E = Action(*ModulePtr)) {
    WithColor::error() << toString(std::move(E)) << "\n";
    return 1;
  }

  return 0;
}

static void dumpSectionList(LinePrinter &Printer, const SectionList &List, bool is_subsection) {
  size_t Count = List.GetNumSections(0);
  if (Count == 0) {
    Printer.formatLine("There are no {0}sections", is_subsection ? "sub" : "");
    return;
  }
  Printer.formatLine("Showing {0} {1}sections", Count,
                     is_subsection ? "sub" : "");
  for (size_t I = 0; I < Count; ++I) {
    auto S = List.GetSectionAtIndex(I);
    assert(S);
    AutoIndent Indent(Printer, 2);
    Printer.formatLine("Index: {0}", I);
    Printer.formatLine("ID: {0:x}", S->GetID());
    Printer.formatLine("Name: {0}", S->GetName().GetStringRef());
    Printer.formatLine("Type: {0}", S->GetTypeAsCString());
    Printer.formatLine("Permissions: {0}", GetPermissionsAsCString(S->GetPermissions()));
    Printer.formatLine("Thread specific: {0:y}", S->IsThreadSpecific());
    Printer.formatLine("VM address: {0:x}", S->GetFileAddress());
    Printer.formatLine("VM size: {0}", S->GetByteSize());
    Printer.formatLine("File size: {0}", S->GetFileSize());

    if (opts::object::SectionContents) {
      DataExtractor Data;
      S->GetSectionData(Data);
      ArrayRef<uint8_t> Bytes = {Data.GetDataStart(), Data.GetDataEnd()};
      Printer.formatBinary("Data: ", Bytes, 0);
    }

    if (S->GetType() == eSectionTypeContainer)
      dumpSectionList(Printer, S->GetChildren(), true);
    Printer.NewLine();
  }
}

static int dumpObjectFiles(Debugger &Dbg) {
  LinePrinter Printer(4, llvm::outs());

  int HadErrors = 0;
  for (const auto &File : opts::object::InputFilenames) {
    ModuleSpec Spec{FileSpec(File)};

    auto ModulePtr = std::make_shared<lldb_private::Module>(Spec);

    ObjectFile *ObjectPtr = ModulePtr->GetObjectFile();
    if (!ObjectPtr) {
      WithColor::error() << File << " not recognised as an object file\n";
      HadErrors = 1;
      continue;
    }

    // Fetch symbol vendor before we get the section list to give the symbol
    // vendor a chance to populate it.
    ModulePtr->GetSymbolVendor();
    SectionList *Sections = ModulePtr->GetSectionList();
    if (!Sections) {
      llvm::errs() << "Could not load sections for module " << File << "\n";
      HadErrors = 1;
      continue;
    }

    Printer.formatLine("Plugin name: {0}", ObjectPtr->GetPluginName());
    Printer.formatLine("Architecture: {0}",
                       ModulePtr->GetArchitecture().GetTriple().getTriple());
    Printer.formatLine("UUID: {0}", ModulePtr->GetUUID().GetAsString());
    Printer.formatLine("Executable: {0}", ObjectPtr->IsExecutable());
    Printer.formatLine("Stripped: {0}", ObjectPtr->IsStripped());
    Printer.formatLine("Type: {0}", ObjectPtr->GetType());
    Printer.formatLine("Strata: {0}", ObjectPtr->GetStrata());
    Printer.formatLine("Base VM address: {0:x}",
                       ObjectPtr->GetBaseAddress().GetFileAddress());

    dumpSectionList(Printer, *Sections, /*is_subsection*/ false);

    if (opts::object::SectionDependentModules) {
      // A non-empty section list ensures a valid object file.
      auto Obj = ModulePtr->GetObjectFile();
      FileSpecList Files;
      auto Count = Obj->GetDependentModules(Files);
      Printer.formatLine("Showing {0} dependent module(s)", Count);
      for (size_t I = 0; I < Files.GetSize(); ++I) {
        AutoIndent Indent(Printer, 2);
        Printer.formatLine("Name: {0}",
                           Files.GetFileSpecAtIndex(I).GetCString());
      }
      Printer.NewLine();
    }
  }
  return HadErrors;
}

bool opts::irmemorymap::evalMalloc(StringRef Line,
                                   IRMemoryMapTestState &State) {
  // ::= <label> = malloc <size> <alignment>
  StringRef Label;
  std::tie(Label, Line) = Line.split('=');
  if (Line.empty())
    return false;
  Label = Label.trim();
  Line = Line.trim();
  size_t Size;
  uint8_t Alignment;
  int Matches = sscanf(Line.data(), "malloc %zu %hhu", &Size, &Alignment);
  if (Matches != 2)
    return false;

  outs() << formatv("Command: {0} = malloc(size={1}, alignment={2})\n", Label,
                    Size, Alignment);
  if (!isPowerOf2_32(Alignment)) {
    outs() << "Malloc error: alignment is not a power of 2\n";
    exit(1);
  }

  IRMemoryMap::AllocationPolicy AP =
      UseHostOnlyAllocationPolicy ? IRMemoryMap::eAllocationPolicyHostOnly
                                  : IRMemoryMap::eAllocationPolicyProcessOnly;

  // Issue the malloc in the target process with "-rw" permissions.
  const uint32_t Permissions = 0x3;
  const bool ZeroMemory = false;
  Status ST;
  addr_t Addr =
      State.Map.Malloc(Size, Alignment, Permissions, AP, ZeroMemory, ST);
  if (ST.Fail()) {
    outs() << formatv("Malloc error: {0}\n", ST);
    return true;
  }

  // Print the result of the allocation before checking its validity.
  outs() << formatv("Malloc: address = {0:x}\n", Addr);

  // Check that the allocation is aligned.
  if (!Addr || Addr % Alignment != 0) {
    outs() << "Malloc error: zero or unaligned allocation detected\n";
    exit(1);
  }

  // In case of Size == 0, we still expect the returned address to be unique and
  // non-overlapping.
  addr_t EndOfRegion = Addr + std::max<size_t>(Size, 1);
  if (State.Allocations.overlaps(Addr, EndOfRegion)) {
    auto I = State.Allocations.find(Addr);
    outs() << "Malloc error: overlapping allocation detected"
           << formatv(", previous allocation at [{0:x}, {1:x})\n", I.start(),
                      I.stop());
    exit(1);
  }

  // Insert the new allocation into the interval map. Use unique allocation
  // IDs to inhibit interval coalescing.
  static unsigned AllocationID = 0;
  State.Allocations.insert(Addr, EndOfRegion, AllocationID++);

  // Store the label -> address mapping.
  State.Label2AddrMap[Label] = Addr;

  return true;
}

bool opts::irmemorymap::evalFree(StringRef Line, IRMemoryMapTestState &State) {
  // ::= free <label>
  if (!Line.consume_front("free"))
    return false;
  StringRef Label = Line.trim();

  outs() << formatv("Command: free({0})\n", Label);
  auto LabelIt = State.Label2AddrMap.find(Label);
  if (LabelIt == State.Label2AddrMap.end()) {
    outs() << "Free error: Invalid allocation label\n";
    exit(1);
  }

  Status ST;
  addr_t Addr = LabelIt->getValue();
  State.Map.Free(Addr, ST);
  if (ST.Fail()) {
    outs() << formatv("Free error: {0}\n", ST);
    exit(1);
  }

  // Erase the allocation from the live interval map.
  auto Interval = State.Allocations.find(Addr);
  if (Interval != State.Allocations.end()) {
    outs() << formatv("Free: [{0:x}, {1:x})\n", Interval.start(),
                      Interval.stop());
    Interval.erase();
  }

  return true;
}

int opts::irmemorymap::evaluateMemoryMapCommands(Debugger &Dbg) {
  // Set up a Target.
  TargetSP Target = opts::createTarget(Dbg, irmemorymap::Target);

  // Set up a Process. In order to allocate memory within a target, this
  // process must be alive and must support JIT'ing.
  CommandReturnObject Result;
  Dbg.SetAsyncExecution(false);
  CommandInterpreter &CI = Dbg.GetCommandInterpreter();
  auto IssueCmd = [&](const char *Cmd) -> bool {
    return CI.HandleCommand(Cmd, eLazyBoolNo, Result);
  };
  if (!IssueCmd("b main") || !IssueCmd("run")) {
    outs() << formatv("Failed: {0}\n", Result.GetErrorData());
    exit(1);
  }

  ProcessSP Process = Target->GetProcessSP();
  if (!Process || !Process->IsAlive() || !Process->CanJIT()) {
    outs() << "Cannot use process to test IRMemoryMap\n";
    exit(1);
  }

  // Set up an IRMemoryMap and associated testing state.
  IRMemoryMapTestState State(Target);

  // Parse and apply commands from the command file.
  std::unique_ptr<MemoryBuffer> MB = opts::openFile(irmemorymap::CommandFile);
  StringRef Rest = MB->getBuffer();
  while (!Rest.empty()) {
    StringRef Line;
    std::tie(Line, Rest) = Rest.split('\n');
    Line = Line.ltrim();

    if (Line.empty() || Line[0] == '#')
      continue;

    if (evalMalloc(Line, State))
      continue;

    if (evalFree(Line, State))
      continue;

    errs() << "Could not parse line: " << Line << "\n";
    exit(1);
  }
  return 0;
}

int main(int argc, const char *argv[]) {
  StringRef ToolName = argv[0];
  sys::PrintStackTraceOnErrorSignal(ToolName);
  PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj Y;

  cl::ParseCommandLineOptions(argc, argv, "LLDB Testing Utility\n");

  SystemLifetimeManager DebuggerLifetime;
  if (auto e = DebuggerLifetime.Initialize(
          llvm::make_unique<SystemInitializerTest>(), {}, nullptr)) {
    WithColor::error() << "initialization failed: " << toString(std::move(e))
                       << '\n';
    return 1;
  }

  CleanUp TerminateDebugger([&] { DebuggerLifetime.Terminate(); });

  auto Dbg = lldb_private::Debugger::CreateInstance();

  if (!opts::Log.empty())
    Dbg->EnableLog("lldb", {"all"}, opts::Log, 0, errs());

  if (opts::BreakpointSubcommand)
    return opts::breakpoint::evaluateBreakpoints(*Dbg);
  if (opts::ObjectFileSubcommand)
    return dumpObjectFiles(*Dbg);
  if (opts::SymbolsSubcommand)
    return opts::symbols::dumpSymbols(*Dbg);
  if (opts::IRMemoryMapSubcommand)
    return opts::irmemorymap::evaluateMemoryMapCommands(*Dbg);

  WithColor::error() << "No command specified.\n";
  return 1;
}
