brintos

brintos / llvm-project-archived public Read only

0
0
Text · 45.4 KiB · 3f198d9 Raw
1291 lines · cpp
1//===- lldb-test.cpp ------------------------------------------ *- C++ --*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "FormatUtil.h"10#include "SystemInitializerTest.h"11 12#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"13#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"14#include "lldb/Breakpoint/BreakpointLocation.h"15#include "lldb/Core/Debugger.h"16#include "lldb/Core/Mangled.h"17#include "lldb/Core/Module.h"18#include "lldb/Core/Section.h"19#include "lldb/Expression/IRMemoryMap.h"20#include "lldb/Initialization/SystemLifetimeManager.h"21#include "lldb/Interpreter/CommandInterpreter.h"22#include "lldb/Interpreter/CommandReturnObject.h"23#include "lldb/Symbol/CompileUnit.h"24#include "lldb/Symbol/LineTable.h"25#include "lldb/Symbol/SymbolFile.h"26#include "lldb/Symbol/Symtab.h"27#include "lldb/Symbol/Type.h"28#include "lldb/Symbol/TypeList.h"29#include "lldb/Symbol/TypeMap.h"30#include "lldb/Symbol/VariableList.h"31#include "lldb/Target/Language.h"32#include "lldb/Target/Process.h"33#include "lldb/Target/Target.h"34#include "lldb/Utility/DataExtractor.h"35#include "lldb/Utility/LLDBAssert.h"36#include "lldb/Utility/State.h"37#include "lldb/Utility/StreamString.h"38 39#include "llvm/ADT/IntervalMap.h"40#include "llvm/ADT/ScopeExit.h"41#include "llvm/ADT/StringRef.h"42#include "llvm/Support/CommandLine.h"43#include "llvm/Support/ManagedStatic.h"44#include "llvm/Support/MathExtras.h"45#include "llvm/Support/Path.h"46#include "llvm/Support/PrettyStackTrace.h"47#include "llvm/Support/Signals.h"48#include "llvm/Support/WithColor.h"49 50#include <cstdio>51#include <optional>52#include <thread>53 54using namespace lldb;55using namespace lldb_private;56using namespace llvm;57 58namespace opts {59static cl::SubCommand BreakpointSubcommand("breakpoints",60                                           "Test breakpoint resolution");61cl::SubCommand ObjectFileSubcommand("object-file",62                                    "Display LLDB object file information");63cl::SubCommand SymbolsSubcommand("symbols", "Dump symbols for an object file");64cl::SubCommand SymTabSubcommand("symtab",65                                "Test symbol table functionality");66cl::SubCommand IRMemoryMapSubcommand("ir-memory-map", "Test IRMemoryMap");67cl::SubCommand AssertSubcommand("assert", "Test assert handling");68 69cl::opt<std::string> Log("log", cl::desc("Path to a log file"), cl::init(""),70                         cl::sub(BreakpointSubcommand),71                         cl::sub(ObjectFileSubcommand),72                         cl::sub(SymbolsSubcommand),73                         cl::sub(SymTabSubcommand),74                         cl::sub(IRMemoryMapSubcommand));75 76/// Create a target using the file pointed to by \p Filename, or abort.77TargetSP createTarget(Debugger &Dbg, const std::string &Filename);78 79/// Read \p Filename into a null-terminated buffer, or abort.80std::unique_ptr<MemoryBuffer> openFile(const std::string &Filename);81 82namespace breakpoint {83static cl::opt<std::string> Target(cl::Positional, cl::desc("<target>"),84                                   cl::Required, cl::sub(BreakpointSubcommand));85static cl::opt<std::string> CommandFile(cl::Positional,86                                        cl::desc("<command-file>"),87                                        cl::init("-"),88                                        cl::sub(BreakpointSubcommand));89static cl::opt<bool> Persistent(90    "persistent",91    cl::desc("Don't automatically remove all breakpoints before each command"),92    cl::sub(BreakpointSubcommand));93 94static llvm::StringRef plural(uintmax_t value) { return value == 1 ? "" : "s"; }95static void dumpState(const BreakpointList &List, LinePrinter &P);96static std::string substitute(StringRef Cmd);97static int evaluateBreakpoints(Debugger &Dbg);98} // namespace breakpoint99 100namespace object {101cl::opt<bool> SectionContents("contents",102                              cl::desc("Dump each section's contents"),103                              cl::sub(ObjectFileSubcommand));104cl::opt<bool> SectionDependentModules("dep-modules",105                                      cl::desc("Dump each dependent module"),106                                      cl::sub(ObjectFileSubcommand));107cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<input files>"),108                                     cl::OneOrMore,109                                     cl::sub(ObjectFileSubcommand));110} // namespace object111 112namespace symtab {113 114/// The same enum as Mangled::NamePreference but with a default115/// 'None' case. This is needed to disambiguate wheter "ManglingPreference" was116/// explicitly set or not.117enum class ManglingPreference {118  None,119  Mangled,120  Demangled,121  MangledWithoutArguments,122};123 124static cl::opt<std::string> FindSymbolsByRegex(125    "find-symbols-by-regex",126    cl::desc(127        "Dump symbols found in the symbol table matching the specified regex."),128    cl::sub(SymTabSubcommand));129 130static cl::opt<ManglingPreference> ManglingPreference(131    "mangling-preference",132    cl::desc("Preference on mangling scheme the regex should match against and "133             "dumped."),134    cl::values(135        clEnumValN(ManglingPreference::Mangled, "mangled", "Prefer mangled"),136        clEnumValN(ManglingPreference::Demangled, "demangled",137                   "Prefer demangled"),138        clEnumValN(ManglingPreference::MangledWithoutArguments,139                   "demangled-without-args", "Prefer mangled without args")),140    cl::sub(SymTabSubcommand));141 142static cl::opt<std::string> InputFile(cl::Positional, cl::desc("<input file>"),143                                      cl::Required, cl::sub(SymTabSubcommand));144 145/// Validate that the options passed make sense.146static std::optional<llvm::Error> validate();147 148/// Transforms the selected mangling preference into a Mangled::NamePreference149static Mangled::NamePreference getNamePreference();150 151static int handleSymtabCommand(Debugger &Dbg);152} // namespace symtab153 154namespace symbols {155static cl::opt<std::string> InputFile(cl::Positional, cl::desc("<input file>"),156                                      cl::Required, cl::sub(SymbolsSubcommand));157 158static cl::opt<std::string>159    SymbolPath("symbol-file",160               cl::desc("The file from which to fetch symbol information."),161               cl::value_desc("file"), cl::sub(SymbolsSubcommand));162 163enum class FindType {164  None,165  Function,166  Block,167  Namespace,168  Type,169  Variable,170};171static cl::opt<FindType> Find(172    "find", cl::desc("Choose search type:"),173    cl::values(174        clEnumValN(FindType::None, "none", "No search, just dump the module."),175        clEnumValN(FindType::Function, "function", "Find functions."),176        clEnumValN(FindType::Block, "block", "Find blocks."),177        clEnumValN(FindType::Namespace, "namespace", "Find namespaces."),178        clEnumValN(FindType::Type, "type", "Find types."),179        clEnumValN(FindType::Variable, "variable", "Find global variables.")),180    cl::sub(SymbolsSubcommand));181 182static cl::opt<std::string> Name("name", cl::desc("Name to find."),183                                 cl::sub(SymbolsSubcommand));184static cl::opt<std::string> MangledName(185    "mangled-name",186    cl::desc("Mangled name to find. Only compatible when searching types"),187    cl::sub(SymbolsSubcommand));188static cl::opt<bool>189    Regex("regex",190          cl::desc("Search using regular expressions (available for variables "191                   "and functions only)."),192          cl::sub(SymbolsSubcommand));193static cl::opt<std::string>194    Context("context",195            cl::desc("Restrict search to the context of the given variable."),196            cl::value_desc("variable"), cl::sub(SymbolsSubcommand));197 198static cl::opt<std::string> CompilerContext(199    "compiler-context",200    cl::desc("Specify a compiler context as \"kind:name,...\"."),201    cl::value_desc("context"), cl::sub(SymbolsSubcommand));202 203static cl::opt<bool> FindInAnyModule(204    "find-in-any-module",205    cl::desc("If true, the type will be searched for in all modules. Otherwise "206             "the modules must be provided in -compiler-context"),207    cl::sub(SymbolsSubcommand));208 209static cl::opt<std::string>210    Language("language", cl::desc("Specify a language type, like C99."),211             cl::value_desc("language"), cl::sub(SymbolsSubcommand));212 213static cl::list<FunctionNameType> FunctionNameFlags(214    "function-flags", cl::desc("Function search flags:"),215    cl::values(clEnumValN(eFunctionNameTypeAuto, "auto",216                          "Automatically deduce flags based on name."),217               clEnumValN(eFunctionNameTypeFull, "full", "Full function name."),218               clEnumValN(eFunctionNameTypeBase, "base", "Base name."),219               clEnumValN(eFunctionNameTypeMethod, "method", "Method name."),220               clEnumValN(eFunctionNameTypeSelector, "selector",221                          "Selector name.")),222    cl::sub(SymbolsSubcommand));223static FunctionNameType getFunctionNameFlags() {224  FunctionNameType Result = FunctionNameType(0);225  for (FunctionNameType Flag : FunctionNameFlags)226    Result = FunctionNameType(Result | Flag);227  return Result;228}229 230static cl::opt<bool> DumpAST("dump-ast",231                             cl::desc("Dump AST restored from symbols."),232                             cl::sub(SymbolsSubcommand));233static cl::opt<bool> DumpClangAST(234    "dump-clang-ast",235    cl::desc("Dump clang AST restored from symbols. When used on its own this "236             "will dump the entire AST of all loaded symbols. When combined "237             "with -find, it changes the presentation of the search results "238             "from pretty-printing the types to an AST dump."),239    cl::sub(SymbolsSubcommand));240 241static cl::opt<bool> Verify("verify", cl::desc("Verify symbol information."),242                            cl::sub(SymbolsSubcommand));243 244static cl::opt<std::string> File("file",245                                 cl::desc("File (compile unit) to search."),246                                 cl::sub(SymbolsSubcommand));247static cl::opt<int> Line("line", cl::desc("Line to search."),248                         cl::sub(SymbolsSubcommand));249 250static Expected<CompilerDeclContext> getDeclContext(SymbolFile &Symfile);251 252static Error findFunctions(lldb_private::Module &Module);253static Error findBlocks(lldb_private::Module &Module);254static Error findNamespaces(lldb_private::Module &Module);255static Error findTypes(lldb_private::Module &Module);256static Error findVariables(lldb_private::Module &Module);257static Error dumpModule(lldb_private::Module &Module);258static Error dumpAST(lldb_private::Module &Module);259static Error dumpEntireClangAST(lldb_private::Module &Module);260static Error verify(lldb_private::Module &Module);261 262static Expected<Error (*)(lldb_private::Module &)> getAction();263static int dumpSymbols(Debugger &Dbg);264} // namespace symbols265 266namespace irmemorymap {267static cl::opt<std::string> Target(cl::Positional, cl::desc("<target>"),268                                   cl::Required,269                                   cl::sub(IRMemoryMapSubcommand));270static cl::opt<std::string> CommandFile(cl::Positional,271                                        cl::desc("<command-file>"),272                                        cl::init("-"),273                                        cl::sub(IRMemoryMapSubcommand));274static cl::opt<bool> UseHostOnlyAllocationPolicy(275    "host-only", cl::desc("Use the host-only allocation policy"),276    cl::init(false), cl::sub(IRMemoryMapSubcommand));277 278using AllocationT = std::pair<addr_t, addr_t>;279using AddrIntervalMap =280    IntervalMap<addr_t, unsigned, 8, IntervalMapHalfOpenInfo<addr_t>>;281 282struct IRMemoryMapTestState {283  TargetSP Target;284  IRMemoryMap Map;285 286  AddrIntervalMap::Allocator IntervalMapAllocator;287  AddrIntervalMap Allocations;288 289  StringMap<addr_t> Label2AddrMap;290 291  IRMemoryMapTestState(TargetSP Target)292      : Target(Target), Map(Target), Allocations(IntervalMapAllocator) {}293};294 295bool evalMalloc(StringRef Line, IRMemoryMapTestState &State);296bool evalFree(StringRef Line, IRMemoryMapTestState &State);297int evaluateMemoryMapCommands(Debugger &Dbg);298} // namespace irmemorymap299 300namespace assert {301int lldb_assert(Debugger &Dbg);302} // namespace assert303} // namespace opts304 305llvm::SmallVector<CompilerContext, 4> parseCompilerContext() {306  llvm::SmallVector<CompilerContext, 4> result;307  if (opts::symbols::CompilerContext.empty())308    return result;309 310  StringRef str{opts::symbols::CompilerContext};311  SmallVector<StringRef, 8> entries_str;312  str.split(entries_str, ',', /*maxSplit*/-1, /*keepEmpty=*/false);313  for (auto entry_str : entries_str) {314    StringRef key, value;315    std::tie(key, value) = entry_str.split(':');316    auto kind =317        StringSwitch<CompilerContextKind>(key)318            .Case("TranslationUnit", CompilerContextKind::TranslationUnit)319            .Case("Module", CompilerContextKind::Module)320            .Case("Namespace", CompilerContextKind::Namespace)321            .Case("ClassOrStruct", CompilerContextKind::ClassOrStruct)322            .Case("Union", CompilerContextKind::Union)323            .Case("Function", CompilerContextKind::Function)324            .Case("Variable", CompilerContextKind::Variable)325            .Case("Enum", CompilerContextKind::Enum)326            .Case("Typedef", CompilerContextKind::Typedef)327            .Case("AnyType", CompilerContextKind::AnyType)328            .Default(CompilerContextKind::Invalid);329    if (value.empty()) {330      WithColor::error() << "compiler context entry has no \"name\"\n";331      exit(1);332    }333    result.push_back({kind, ConstString{value}});334  }335  outs() << "Search context: {";336  lldb_private::StreamString s;337  llvm::interleaveComma(result, s, [&](auto &ctx) { ctx.Dump(s); });338  outs() << s.GetString().str() << "}\n";339 340  return result;341}342 343template <typename... Args>344static Error make_string_error(const char *Format, Args &&... args) {345  return llvm::make_error<llvm::StringError>(346      llvm::formatv(Format, std::forward<Args>(args)...).str(),347      llvm::inconvertibleErrorCode());348}349 350TargetSP opts::createTarget(Debugger &Dbg, const std::string &Filename) {351  TargetSP Target;352  Status ST = Dbg.GetTargetList().CreateTarget(353      Dbg, Filename, /*triple*/ "", eLoadDependentsNo,354      /*platform_options*/ nullptr, Target);355  if (ST.Fail()) {356    errs() << formatv("Failed to create target '{0}: {1}\n", Filename, ST);357    exit(1);358  }359  return Target;360}361 362std::unique_ptr<MemoryBuffer> opts::openFile(const std::string &Filename) {363  auto MB = MemoryBuffer::getFileOrSTDIN(Filename);364  if (!MB) {365    errs() << formatv("Could not open file '{0}: {1}\n", Filename,366                      MB.getError().message());367    exit(1);368  }369  return std::move(*MB);370}371 372void opts::breakpoint::dumpState(const BreakpointList &List, LinePrinter &P) {373  P.formatLine("{0} breakpoint{1}", List.GetSize(), plural(List.GetSize()));374  if (List.GetSize() > 0)375    P.formatLine("At least one breakpoint.");376  for (size_t i = 0, e = List.GetSize(); i < e; ++i) {377    BreakpointSP BP = List.GetBreakpointAtIndex(i);378    P.formatLine("Breakpoint ID {0}:", BP->GetID());379    AutoIndent Indent(P, 2);380    P.formatLine("{0} location{1}.", BP->GetNumLocations(),381                 plural(BP->GetNumLocations()));382    if (BP->GetNumLocations() > 0)383      P.formatLine("At least one location.");384    P.formatLine("{0} resolved location{1}.", BP->GetNumResolvedLocations(),385                 plural(BP->GetNumResolvedLocations()));386    if (BP->GetNumResolvedLocations() > 0)387      P.formatLine("At least one resolved location.");388    for (size_t l = 0, le = BP->GetNumLocations(); l < le; ++l) {389      BreakpointLocationSP Loc = BP->GetLocationAtIndex(l);390      P.formatLine("Location ID {0}:", Loc->GetID());391      AutoIndent Indent(P, 2);392      P.formatLine("Enabled: {0}", Loc->IsEnabled());393      P.formatLine("Resolved: {0}", Loc->IsResolved());394      SymbolContext sc;395      Loc->GetAddress().CalculateSymbolContext(&sc);396      lldb_private::StreamString S;397      sc.DumpStopContext(&S, BP->GetTarget().GetProcessSP().get(),398                         Loc->GetAddress(), false, true, false, true, true);399      P.formatLine("Address: {0}", S.GetString());400    }401  }402  P.NewLine();403}404 405std::string opts::breakpoint::substitute(StringRef Cmd) {406  std::string Result;407  raw_string_ostream OS(Result);408  while (!Cmd.empty()) {409    switch (Cmd[0]) {410    case '%':411      if (Cmd.consume_front("%p") && (Cmd.empty() || !isalnum(Cmd[0]))) {412        OS << sys::path::parent_path(breakpoint::CommandFile);413        break;414      }415      [[fallthrough]];416    default:417      size_t pos = Cmd.find('%');418      OS << Cmd.substr(0, pos);419      Cmd = Cmd.substr(pos);420      break;421    }422  }423  return Result;424}425 426int opts::breakpoint::evaluateBreakpoints(Debugger &Dbg) {427  TargetSP Target = opts::createTarget(Dbg, breakpoint::Target);428  std::unique_ptr<MemoryBuffer> MB = opts::openFile(breakpoint::CommandFile);429 430  LinePrinter P(4, outs());431  StringRef Rest = MB->getBuffer();432  int HadErrors = 0;433  while (!Rest.empty()) {434    StringRef Line;435    std::tie(Line, Rest) = Rest.split('\n');436    Line = Line.ltrim().rtrim();437    if (Line.empty() || Line[0] == '#')438      continue;439 440    if (!Persistent)441      Target->RemoveAllBreakpoints(/*internal_also*/ true);442 443    std::string Command = substitute(Line);444    P.formatLine("Command: {0}", Command);445    CommandReturnObject Result(/*colors*/ false);446    if (!Dbg.GetCommandInterpreter().HandleCommand(447            Command.c_str(), /*add_to_history*/ eLazyBoolNo, Result)) {448      P.formatLine("Failed: {0}", Result.GetErrorString());449      HadErrors = 1;450      continue;451    }452 453    dumpState(Target->GetBreakpointList(/*internal*/ false), P);454  }455  return HadErrors;456}457 458Expected<CompilerDeclContext>459opts::symbols::getDeclContext(SymbolFile &Symfile) {460  if (Context.empty())461    return CompilerDeclContext();462  VariableList List;463  Symfile.FindGlobalVariables(ConstString(Context), CompilerDeclContext(),464                              UINT32_MAX, List);465  if (List.Empty())466    return make_string_error("Context search didn't find a match.");467  if (List.GetSize() > 1)468    return make_string_error("Context search found multiple matches.");469  return List.GetVariableAtIndex(0)->GetDeclContext();470}471 472static lldb::DescriptionLevel GetDescriptionLevel() {473  return opts::symbols::DumpClangAST ? eDescriptionLevelVerbose : eDescriptionLevelFull;474}475 476Error opts::symbols::findFunctions(lldb_private::Module &Module) {477  if (!MangledName.empty())478    return make_string_error("Cannot search functions by mangled name.");479 480  SymbolFile &Symfile = *Module.GetSymbolFile();481  SymbolContextList List;482  auto compiler_context = parseCompilerContext();483  if (!File.empty()) {484    assert(Line != 0);485 486    FileSpec src_file(File);487    size_t cu_count = Module.GetNumCompileUnits();488    for (size_t i = 0; i < cu_count; i++) {489      lldb::CompUnitSP cu_sp = Module.GetCompileUnitAtIndex(i);490      if (!cu_sp)491        continue;492 493      LineEntry le;494      cu_sp->FindLineEntry(0, Line, &src_file, false, &le);495      if (!le.IsValid())496        continue;497      const bool include_inlined_functions = false;498      auto addr =499          le.GetSameLineContiguousAddressRange(include_inlined_functions)500              .GetBaseAddress();501      if (!addr.IsValid())502        continue;503 504      SymbolContext sc;505      uint32_t resolved =506          addr.CalculateSymbolContext(&sc, eSymbolContextFunction);507      if (resolved & eSymbolContextFunction)508        List.Append(sc);509    }510  } else if (Regex) {511    RegularExpression RE(Name);512    assert(RE.IsValid());513    List.Clear();514    Symfile.FindFunctions(RE, true, List);515  } else if (!compiler_context.empty()) {516    List.Clear();517    Module.FindFunctions(compiler_context, getFunctionNameFlags(), {}, List);518  } else {519    Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);520    if (!ContextOr)521      return ContextOr.takeError();522    const CompilerDeclContext &ContextPtr =523        ContextOr->IsValid() ? *ContextOr : CompilerDeclContext();524 525    List.Clear();526    lldb_private::Module::LookupInfo lookup_info(527        ConstString(Name), getFunctionNameFlags(), eLanguageTypeUnknown);528    Symfile.FindFunctions(lookup_info, ContextPtr, true, List);529  }530  outs() << formatv("Found {0} functions:\n", List.GetSize());531  StreamString Stream;532  List.Dump(&Stream, nullptr);533  outs() << Stream.GetData() << "\n";534  return Error::success();535}536 537Error opts::symbols::findBlocks(lldb_private::Module &Module) {538  assert(!Regex);539  assert(!File.empty());540  assert(Line != 0);541  if (!MangledName.empty())542    return make_string_error("Cannot search blocks by mangled name.");543 544  SymbolContextList List;545 546  FileSpec src_file(File);547  size_t cu_count = Module.GetNumCompileUnits();548  for (size_t i = 0; i < cu_count; i++) {549    lldb::CompUnitSP cu_sp = Module.GetCompileUnitAtIndex(i);550    if (!cu_sp)551      continue;552 553    LineEntry le;554    cu_sp->FindLineEntry(0, Line, &src_file, false, &le);555    if (!le.IsValid())556      continue;557    const bool include_inlined_functions = false;558    auto addr = le.GetSameLineContiguousAddressRange(include_inlined_functions)559                    .GetBaseAddress();560    if (!addr.IsValid())561      continue;562 563    SymbolContext sc;564    uint32_t resolved = addr.CalculateSymbolContext(&sc, eSymbolContextBlock);565    if (resolved & eSymbolContextBlock)566      List.Append(sc);567  }568 569  outs() << formatv("Found {0} blocks:\n", List.GetSize());570  StreamString Stream;571  List.Dump(&Stream, nullptr);572  outs() << Stream.GetData() << "\n";573  return Error::success();574}575 576Error opts::symbols::findNamespaces(lldb_private::Module &Module) {577  if (!MangledName.empty())578    return make_string_error("Cannot search namespaces by mangled name.");579 580  SymbolFile &Symfile = *Module.GetSymbolFile();581  Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);582  if (!ContextOr)583    return ContextOr.takeError();584  const CompilerDeclContext &ContextPtr =585      ContextOr->IsValid() ? *ContextOr : CompilerDeclContext();586 587  CompilerDeclContext Result =588      Symfile.FindNamespace(ConstString(Name), ContextPtr);589  if (Result)590    outs() << "Found namespace: "591           << Result.GetScopeQualifiedName().GetStringRef() << "\n";592  else593    outs() << "Namespace not found.\n";594  return Error::success();595}596 597Error opts::symbols::findTypes(lldb_private::Module &Module) {598  SymbolFile &Symfile = *Module.GetSymbolFile();599  Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);600  if (!ContextOr)601    return ContextOr.takeError();602  ;603 604  TypeQueryOptions Opts = TypeQueryOptions::e_module_search;605  if (FindInAnyModule)606    Opts |= TypeQueryOptions::e_ignore_modules;607  TypeResults results;608  if (!Name.empty() && !MangledName.empty())609    return make_string_error("Cannot search by both name and mangled name.");610 611  if (!Name.empty()) {612    if (ContextOr->IsValid()) {613      TypeQuery query(*ContextOr, ConstString(Name), Opts);614      if (!Language.empty())615        query.AddLanguage(Language::GetLanguageTypeFromString(Language));616      Symfile.FindTypes(query, results);617    } else {618      TypeQuery query(Name);619      if (!Language.empty())620        query.AddLanguage(Language::GetLanguageTypeFromString(Language));621      Symfile.FindTypes(query, results);622    }623  } else if (!MangledName.empty()) {624    Opts = TypeQueryOptions::e_search_by_mangled_name;625    if (ContextOr->IsValid()) {626      TypeQuery query(*ContextOr, ConstString(MangledName), Opts);627      if (!Language.empty())628        query.AddLanguage(Language::GetLanguageTypeFromString(Language));629      Symfile.FindTypes(query, results);630    } else {631      TypeQuery query(MangledName, Opts);632      if (!Language.empty())633        query.AddLanguage(Language::GetLanguageTypeFromString(Language));634      Symfile.FindTypes(query, results);635    }636 637  } else {638    TypeQuery query(parseCompilerContext(), Opts);639    if (!Language.empty())640      query.AddLanguage(Language::GetLanguageTypeFromString(Language));641    Symfile.FindTypes(query, results);642  }643  outs() << formatv("Found {0} types:\n", results.GetTypeMap().GetSize());644  StreamString Stream;645  // Resolve types to force-materialize typedef types.646  for (const auto &type_sp : results.GetTypeMap().Types())647    type_sp->GetFullCompilerType();648  results.GetTypeMap().Dump(&Stream, false, GetDescriptionLevel());649  outs() << Stream.GetData() << "\n";650  return Error::success();651}652 653Error opts::symbols::findVariables(lldb_private::Module &Module) {654  if (!MangledName.empty())655    return make_string_error("Cannot search variables by mangled name.");656 657  SymbolFile &Symfile = *Module.GetSymbolFile();658  VariableList List;659  if (Regex) {660    RegularExpression RE(Name);661    assert(RE.IsValid());662    Symfile.FindGlobalVariables(RE, UINT32_MAX, List);663  } else if (!File.empty()) {664    CompUnitSP CU;665    for (size_t Ind = 0; !CU && Ind < Module.GetNumCompileUnits(); ++Ind) {666      CompUnitSP Candidate = Module.GetCompileUnitAtIndex(Ind);667      if (!Candidate ||668          Candidate->GetPrimaryFile().GetFilename().GetStringRef() != File)669        continue;670      if (CU)671        return make_string_error("Multiple compile units for file `{0}` found.",672                                 File);673      CU = std::move(Candidate);674    }675 676    if (!CU)677      return make_string_error("Compile unit `{0}` not found.", File);678 679    List.AddVariables(CU->GetVariableList(true).get());680  } else {681    Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);682    if (!ContextOr)683      return ContextOr.takeError();684    const CompilerDeclContext &ContextPtr =685        ContextOr->IsValid() ? *ContextOr : CompilerDeclContext();686 687    Symfile.FindGlobalVariables(ConstString(Name), ContextPtr, UINT32_MAX, List);688  }689  outs() << formatv("Found {0} variables:\n", List.GetSize());690  StreamString Stream;691  List.Dump(&Stream, false);692  outs() << Stream.GetData() << "\n";693  return Error::success();694}695 696Error opts::symbols::dumpModule(lldb_private::Module &Module) {697  StreamString Stream;698  Module.ParseAllDebugSymbols();699  Module.Dump(&Stream);700  outs() << Stream.GetData() << "\n";701  return Error::success();702}703 704Error opts::symbols::dumpAST(lldb_private::Module &Module) {705  Module.ParseAllDebugSymbols();706 707  SymbolFile *symfile = Module.GetSymbolFile();708  if (!symfile)709    return make_string_error("Module has no symbol file.");710 711  auto type_system_or_err =712      symfile->GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);713  if (!type_system_or_err)714    return make_string_error("Can't retrieve TypeSystemClang");715 716  auto ts = *type_system_or_err;717  auto *clang_ast_ctx = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());718  if (!clang_ast_ctx)719    return make_string_error("Retrieved TypeSystem was not a TypeSystemClang");720 721  clang::ASTContext &ast_ctx = clang_ast_ctx->getASTContext();722 723  clang::TranslationUnitDecl *tu = ast_ctx.getTranslationUnitDecl();724  if (!tu)725    return make_string_error("Can't retrieve translation unit declaration.");726 727  tu->print(outs());728 729  return Error::success();730}731 732Error opts::symbols::dumpEntireClangAST(lldb_private::Module &Module) {733  Module.ParseAllDebugSymbols();734 735  SymbolFile *symfile = Module.GetSymbolFile();736  if (!symfile)737    return make_string_error("Module has no symbol file.");738 739  auto type_system_or_err =740      symfile->GetTypeSystemForLanguage(eLanguageTypeObjC_plus_plus);741  if (!type_system_or_err)742    return make_string_error("Can't retrieve TypeSystemClang");743  auto ts = *type_system_or_err;744  auto *clang_ast_ctx = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());745  if (!clang_ast_ctx)746    return make_string_error("Retrieved TypeSystem was not a TypeSystemClang");747 748  StreamString Stream;749  clang_ast_ctx->DumpFromSymbolFile(Stream, Name);750  outs() << Stream.GetData() << "\n";751 752  return Error::success();753}754 755Error opts::symbols::verify(lldb_private::Module &Module) {756  SymbolFile *symfile = Module.GetSymbolFile();757  if (!symfile)758    return make_string_error("Module has no symbol file.");759 760  uint32_t comp_units_count = symfile->GetNumCompileUnits();761 762  outs() << "Found " << comp_units_count << " compile units.\n";763 764  for (uint32_t i = 0; i < comp_units_count; i++) {765    lldb::CompUnitSP comp_unit = symfile->GetCompileUnitAtIndex(i);766    if (!comp_unit)767      return make_string_error("Cannot parse compile unit {0}.", i);768 769    outs() << "Processing '"770           << comp_unit->GetPrimaryFile().GetFilename().AsCString()771           << "' compile unit.\n";772 773    LineTable *lt = comp_unit->GetLineTable();774    if (!lt)775      return make_string_error("Can't get a line table of a compile unit.");776 777    uint32_t count = lt->GetSize();778 779    outs() << "The line table contains " << count << " entries.\n";780 781    if (count == 0)782      continue;783 784    LineEntry le;785    if (!lt->GetLineEntryAtIndex(0, le))786      return make_string_error("Can't get a line entry of a compile unit.");787 788    for (uint32_t i = 1; i < count; i++) {789      lldb::addr_t curr_end =790          le.range.GetBaseAddress().GetFileAddress() + le.range.GetByteSize();791 792      if (!lt->GetLineEntryAtIndex(i, le))793        return make_string_error("Can't get a line entry of a compile unit");794 795      if (curr_end > le.range.GetBaseAddress().GetFileAddress())796        return make_string_error(797            "Line table of a compile unit is inconsistent.");798    }799  }800 801  outs() << "The symbol information is verified.\n";802 803  return Error::success();804}805 806Expected<Error (*)(lldb_private::Module &)> opts::symbols::getAction() {807  if (Verify && DumpAST)808    return make_string_error(809        "Cannot both verify symbol information and dump AST.");810 811  if (Verify) {812    if (Find != FindType::None)813      return make_string_error(814          "Cannot both search and verify symbol information.");815    if (Regex || !Context.empty() || !Name.empty() || !File.empty() ||816        Line != 0)817      return make_string_error(818          "-regex, -context, -name, -file and -line options are not "819          "applicable for symbol verification.");820    return verify;821  }822 823  if (DumpAST) {824    if (Find != FindType::None)825      return make_string_error("Cannot both search and dump AST.");826    if (Regex || !Context.empty() || !Name.empty() || !File.empty() ||827        Line != 0)828      return make_string_error(829          "-regex, -context, -name, -file and -line options are not "830          "applicable for dumping AST.");831    return dumpAST;832  }833 834  if (DumpClangAST) {835    if (Find == FindType::None) {836      if (Regex || !Context.empty() || !File.empty() || Line != 0)837        return make_string_error(838            "-regex, -context, -name, -file and -line options are not "839            "applicable for dumping the entire clang AST. Either combine with "840            "-find, or use -dump-clang-ast as a standalone option.");841      return dumpEntireClangAST;842    }843    if (Find != FindType::Type)844      return make_string_error("This combination of -dump-clang-ast and -find "845                               "<kind> is not yet implemented.");846  }847 848  if (Regex && !Context.empty())849    return make_string_error(850        "Cannot search using both regular expressions and context.");851 852  if (Regex && !RegularExpression(Name).IsValid())853    return make_string_error("`{0}` is not a valid regular expression.", Name);854 855  if (Regex + !Context.empty() + !File.empty() >= 2)856    return make_string_error(857        "Only one of -regex, -context and -file may be used simultaneously.");858  if (Regex && Name.empty())859    return make_string_error("-regex used without a -name");860 861  if (FindInAnyModule && (Find != FindType::Type))862    return make_string_error("-find-in-any-module only works with -find=type");863 864  switch (Find) {865  case FindType::None:866    if (!Context.empty() || !Name.empty() || !File.empty() || Line != 0)867      return make_string_error(868          "Specify search type (-find) to use search options.");869    return dumpModule;870 871  case FindType::Function:872    if (!File.empty() + (Line != 0) == 1)873      return make_string_error("Both file name and line number must be "874                               "specified when searching a function "875                               "by file position.");876    if (Regex + (getFunctionNameFlags() != 0) + !File.empty() >= 2)877      return make_string_error("Only one of regular expression, function-flags "878                               "and file position may be used simultaneously "879                               "when searching a function.");880    return findFunctions;881 882  case FindType::Block:883    if (File.empty() || Line == 0)884      return make_string_error("Both file name and line number must be "885                               "specified when searching a block.");886    if (Regex || getFunctionNameFlags() != 0)887      return make_string_error("Cannot use regular expression or "888                               "function-flags for searching a block.");889    return findBlocks;890 891  case FindType::Namespace:892    if (Regex || !File.empty() || Line != 0)893      return make_string_error("Cannot search for namespaces using regular "894                               "expressions, file names or line numbers.");895    return findNamespaces;896 897  case FindType::Type:898    if (Regex || !File.empty() || Line != 0)899      return make_string_error("Cannot search for types using regular "900                               "expressions, file names or line numbers.");901    if (!Name.empty() && !CompilerContext.empty())902      return make_string_error("Name is ignored if compiler context present.");903 904    return findTypes;905 906  case FindType::Variable:907    if (Line != 0)908      return make_string_error("Cannot search for variables "909                               "using line numbers.");910    return findVariables;911  }912 913  llvm_unreachable("Unsupported symbol action.");914}915 916std::optional<llvm::Error> opts::symtab::validate() {917  if (ManglingPreference != ManglingPreference::None &&918      FindSymbolsByRegex.empty())919    return make_string_error("Mangling preference set but no regex specified.");920 921  return {};922}923 924static Mangled::NamePreference opts::symtab::getNamePreference() {925  switch (ManglingPreference) {926  case ManglingPreference::None:927  case ManglingPreference::Mangled:928    return Mangled::ePreferMangled;929  case ManglingPreference::Demangled:930    return Mangled::ePreferDemangled;931  case ManglingPreference::MangledWithoutArguments:932    return Mangled::ePreferDemangledWithoutArguments;933  }934  llvm_unreachable("Fully covered switch above!");935}936 937int opts::symtab::handleSymtabCommand(Debugger &Dbg) {938  if (auto error = validate()) {939    logAllUnhandledErrors(std::move(*error), WithColor::error(), "");940    return 1;941  }942 943  if (!FindSymbolsByRegex.empty()) {944    ModuleSpec Spec{FileSpec(InputFile)};945 946    auto ModulePtr = std::make_shared<lldb_private::Module>(Spec);947    auto *Symtab = ModulePtr->GetSymtab();948    auto NamePreference = getNamePreference();949    std::vector<uint32_t> Indexes;950 951    Symtab->FindAllSymbolsMatchingRexExAndType(952        RegularExpression(FindSymbolsByRegex), lldb::eSymbolTypeAny,953        Symtab::eDebugAny, Symtab::eVisibilityAny, Indexes, NamePreference);954    for (auto i : Indexes) {955      auto *symbol = Symtab->SymbolAtIndex(i);956      if (symbol) {957        StreamString stream;958        symbol->Dump(&stream, nullptr, i, NamePreference);959        outs() << stream.GetString();960      }961    }962  }963 964  return 0;965}966 967int opts::symbols::dumpSymbols(Debugger &Dbg) {968  auto ActionOr = getAction();969  if (!ActionOr) {970    logAllUnhandledErrors(ActionOr.takeError(), WithColor::error(), "");971    return 1;972  }973  auto Action = *ActionOr;974 975  outs() << "Module: " << InputFile << "\n";976  ModuleSpec Spec{FileSpec(InputFile)};977  StringRef Symbols = SymbolPath.empty() ? InputFile : SymbolPath;978  Spec.GetSymbolFileSpec().SetFile(Symbols, FileSpec::Style::native);979 980  auto ModulePtr = std::make_shared<lldb_private::Module>(Spec);981  SymbolFile *Symfile = ModulePtr->GetSymbolFile();982  if (!Symfile) {983    WithColor::error() << "Module has no symbol vendor.\n";984    return 1;985  }986 987  if (Error E = Action(*ModulePtr)) {988    WithColor::error() << toString(std::move(E)) << "\n";989    return 1;990  }991 992  return 0;993}994 995static void dumpSectionList(LinePrinter &Printer, const SectionList &List, bool is_subsection) {996  size_t Count = List.GetNumSections(0);997  if (Count == 0) {998    Printer.formatLine("There are no {0}sections", is_subsection ? "sub" : "");999    return;1000  }1001  Printer.formatLine("Showing {0} {1}sections", Count,1002                     is_subsection ? "sub" : "");1003  for (size_t I = 0; I < Count; ++I) {1004    auto S = List.GetSectionAtIndex(I);1005    assert(S);1006    AutoIndent Indent(Printer, 2);1007    Printer.formatLine("Index: {0}", I);1008    Printer.formatLine("ID: {0:x}", S->GetID());1009    Printer.formatLine("Name: {0}", S->GetName().GetStringRef());1010    Printer.formatLine("Type: {0}", S->GetTypeAsCString());1011    Printer.formatLine("Permissions: {0}", GetPermissionsAsCString(S->GetPermissions()));1012    Printer.formatLine("Thread specific: {0:y}", S->IsThreadSpecific());1013    Printer.formatLine("VM address: {0:x}", S->GetFileAddress());1014    Printer.formatLine("VM size: {0}", S->GetByteSize());1015    Printer.formatLine("File size: {0}", S->GetFileSize());1016 1017    if (opts::object::SectionContents) {1018      lldb_private::DataExtractor Data;1019      S->GetSectionData(Data);1020      ArrayRef<uint8_t> Bytes(Data.GetDataStart(), Data.GetDataEnd());1021      Printer.formatBinary("Data: ", Bytes, 0);1022    }1023 1024    if (S->GetType() == eSectionTypeContainer)1025      dumpSectionList(Printer, S->GetChildren(), true);1026    Printer.NewLine();1027  }1028}1029 1030static int dumpObjectFiles(Debugger &Dbg) {1031  LinePrinter Printer(4, llvm::outs());1032 1033  int HadErrors = 0;1034  for (const auto &File : opts::object::InputFilenames) {1035    ModuleSpec Spec{FileSpec(File)};1036 1037    auto ModulePtr = std::make_shared<lldb_private::Module>(Spec);1038 1039    ObjectFile *ObjectPtr = ModulePtr->GetObjectFile();1040    if (!ObjectPtr) {1041      WithColor::error() << File << " not recognised as an object file\n";1042      HadErrors = 1;1043      continue;1044    }1045 1046    // Fetch symbol vendor before we get the section list to give the symbol1047    // vendor a chance to populate it.1048    ModulePtr->GetSymbolFile();1049    SectionList *Sections = ModulePtr->GetSectionList();1050    if (!Sections) {1051      llvm::errs() << "Could not load sections for module " << File << "\n";1052      HadErrors = 1;1053      continue;1054    }1055 1056    Printer.formatLine("Plugin name: {0}", ObjectPtr->GetPluginName());1057    Printer.formatLine("Architecture: {0}",1058                       ModulePtr->GetArchitecture().GetTriple().getTriple());1059    Printer.formatLine("UUID: {0}", ModulePtr->GetUUID().GetAsString());1060    Printer.formatLine("Executable: {0}", ObjectPtr->IsExecutable());1061    Printer.formatLine("Stripped: {0}", ObjectPtr->IsStripped());1062    Printer.formatLine("Type: {0}", ObjectPtr->GetType());1063    Printer.formatLine("Strata: {0}", ObjectPtr->GetStrata());1064    Printer.formatLine("Base VM address: {0:x}",1065                       ObjectPtr->GetBaseAddress().GetFileAddress());1066 1067    dumpSectionList(Printer, *Sections, /*is_subsection*/ false);1068 1069    if (opts::object::SectionDependentModules) {1070      // A non-empty section list ensures a valid object file.1071      auto Obj = ModulePtr->GetObjectFile();1072      FileSpecList Files;1073      auto Count = Obj->GetDependentModules(Files);1074      Printer.formatLine("Showing {0} dependent module(s)", Count);1075      for (size_t I = 0; I < Files.GetSize(); ++I) {1076        AutoIndent Indent(Printer, 2);1077        Printer.formatLine("Name: {0}",1078                           Files.GetFileSpecAtIndex(I).GetPath());1079      }1080      Printer.NewLine();1081    }1082  }1083  return HadErrors;1084}1085 1086bool opts::irmemorymap::evalMalloc(StringRef Line,1087                                   IRMemoryMapTestState &State) {1088  // ::= <label> = malloc <size> <alignment>1089  StringRef Label;1090  std::tie(Label, Line) = Line.split('=');1091  if (Line.empty())1092    return false;1093  Label = Label.trim();1094  Line = Line.trim();1095  size_t Size;1096  uint8_t Alignment;1097  int Matches = sscanf(Line.data(), "malloc %zu %hhu", &Size, &Alignment);1098  if (Matches != 2)1099    return false;1100 1101  outs() << formatv("Command: {0} = malloc(size={1}, alignment={2})\n", Label,1102                    Size, Alignment);1103  if (!isPowerOf2_32(Alignment)) {1104    outs() << "Malloc error: alignment is not a power of 2\n";1105    exit(1);1106  }1107 1108  IRMemoryMap::AllocationPolicy AP =1109      UseHostOnlyAllocationPolicy ? IRMemoryMap::eAllocationPolicyHostOnly1110                                  : IRMemoryMap::eAllocationPolicyProcessOnly;1111 1112  // Issue the malloc in the target process with "-rw" permissions.1113  const uint32_t Permissions = 0x3;1114  const bool ZeroMemory = false;1115  auto AddrOrErr =1116      State.Map.Malloc(Size, Alignment, Permissions, AP, ZeroMemory);1117  if (!AddrOrErr) {1118    outs() << formatv("Malloc error: {0}\n", toString(AddrOrErr.takeError()));1119    return true;1120  }1121  addr_t Addr = *AddrOrErr;1122 1123  // Print the result of the allocation before checking its validity.1124  outs() << formatv("Malloc: address = {0:x}\n", Addr);1125 1126  // Check that the allocation is aligned.1127  if (!Addr || Addr % Alignment != 0) {1128    outs() << "Malloc error: zero or unaligned allocation detected\n";1129    exit(1);1130  }1131 1132  // In case of Size == 0, we still expect the returned address to be unique and1133  // non-overlapping.1134  addr_t EndOfRegion = Addr + std::max<size_t>(Size, 1);1135  if (State.Allocations.overlaps(Addr, EndOfRegion)) {1136    auto I = State.Allocations.find(Addr);1137    outs() << "Malloc error: overlapping allocation detected"1138           << formatv(", previous allocation at [{0:x}, {1:x})\n", I.start(),1139                      I.stop());1140    exit(1);1141  }1142 1143  // Insert the new allocation into the interval map. Use unique allocation1144  // IDs to inhibit interval coalescing.1145  static unsigned AllocationID = 0;1146  State.Allocations.insert(Addr, EndOfRegion, AllocationID++);1147 1148  // Store the label -> address mapping.1149  State.Label2AddrMap[Label] = Addr;1150 1151  return true;1152}1153 1154bool opts::irmemorymap::evalFree(StringRef Line, IRMemoryMapTestState &State) {1155  // ::= free <label>1156  if (!Line.consume_front("free"))1157    return false;1158  StringRef Label = Line.trim();1159 1160  outs() << formatv("Command: free({0})\n", Label);1161  auto LabelIt = State.Label2AddrMap.find(Label);1162  if (LabelIt == State.Label2AddrMap.end()) {1163    outs() << "Free error: Invalid allocation label\n";1164    exit(1);1165  }1166 1167  Status ST;1168  addr_t Addr = LabelIt->getValue();1169  State.Map.Free(Addr, ST);1170  if (ST.Fail()) {1171    outs() << formatv("Free error: {0}\n", ST);1172    exit(1);1173  }1174 1175  // Erase the allocation from the live interval map.1176  auto Interval = State.Allocations.find(Addr);1177  if (Interval != State.Allocations.end()) {1178    outs() << formatv("Free: [{0:x}, {1:x})\n", Interval.start(),1179                      Interval.stop());1180    Interval.erase();1181  }1182 1183  return true;1184}1185 1186int opts::irmemorymap::evaluateMemoryMapCommands(Debugger &Dbg) {1187  // Set up a Target.1188  TargetSP Target = opts::createTarget(Dbg, irmemorymap::Target);1189 1190  // Set up a Process. In order to allocate memory within a target, this1191  // process must be alive and must support JIT'ing.1192  CommandReturnObject Result(/*colors*/ false);1193  Dbg.SetAsyncExecution(false);1194  CommandInterpreter &CI = Dbg.GetCommandInterpreter();1195  auto IssueCmd = [&](const char *Cmd) -> bool {1196    return CI.HandleCommand(Cmd, eLazyBoolNo, Result);1197  };1198  if (!IssueCmd("b main") || !IssueCmd("run")) {1199    outs() << formatv("Failed: {0}\n", Result.GetErrorString());1200    exit(1);1201  }1202 1203  ProcessSP Process = Target->GetProcessSP();1204  if (!Process || !Process->IsAlive() || !Process->CanJIT()) {1205    outs() << "Cannot use process to test IRMemoryMap\n";1206    exit(1);1207  }1208 1209  // Set up an IRMemoryMap and associated testing state.1210  IRMemoryMapTestState State(Target);1211 1212  // Parse and apply commands from the command file.1213  std::unique_ptr<MemoryBuffer> MB = opts::openFile(irmemorymap::CommandFile);1214  StringRef Rest = MB->getBuffer();1215  while (!Rest.empty()) {1216    StringRef Line;1217    std::tie(Line, Rest) = Rest.split('\n');1218    Line = Line.ltrim().rtrim();1219 1220    if (Line.empty() || Line[0] == '#')1221      continue;1222 1223    if (evalMalloc(Line, State))1224      continue;1225 1226    if (evalFree(Line, State))1227      continue;1228 1229    errs() << "Could not parse line: " << Line << "\n";1230    exit(1);1231  }1232  return 0;1233}1234 1235int opts::assert::lldb_assert(Debugger &Dbg) {1236  lldbassert(false && "lldb-test assert");1237  return 1;1238}1239 1240int main(int argc, const char *argv[]) {1241  StringRef ToolName = argv[0];1242  sys::PrintStackTraceOnErrorSignal(ToolName);1243  PrettyStackTraceProgram X(argc, argv);1244  llvm_shutdown_obj Y;1245 1246  cl::ParseCommandLineOptions(argc, argv, "LLDB Testing Utility\n");1247 1248  SystemLifetimeManager DebuggerLifetime;1249  if (auto e = DebuggerLifetime.Initialize(1250          std::make_unique<SystemInitializerTest>())) {1251    WithColor::error() << "initialization failed: " << toString(std::move(e))1252                       << '\n';1253    return 1;1254  }1255 1256  auto TerminateDebugger =1257      llvm::make_scope_exit([&] { DebuggerLifetime.Terminate(); });1258 1259  auto Dbg = lldb_private::Debugger::CreateInstance();1260  ModuleList::GetGlobalModuleListProperties().SetEnableExternalLookup(false);1261  CommandReturnObject Result(/*colors*/ false);1262  Dbg->GetCommandInterpreter().HandleCommand(1263      "settings set plugin.process.gdb-remote.packet-timeout 60",1264      /*add_to_history*/ eLazyBoolNo, Result);1265  Dbg->GetCommandInterpreter().HandleCommand(1266      "settings set target.inherit-tcc true",1267      /*add_to_history*/ eLazyBoolNo, Result);1268  Dbg->GetCommandInterpreter().HandleCommand(1269      "settings set target.detach-on-error false",1270      /*add_to_history*/ eLazyBoolNo, Result);1271 1272  if (!opts::Log.empty())1273    Dbg->EnableLog("lldb", {"all"}, opts::Log, 0, 0, eLogHandlerStream, errs());1274 1275  if (opts::BreakpointSubcommand)1276    return opts::breakpoint::evaluateBreakpoints(*Dbg);1277  if (opts::ObjectFileSubcommand)1278    return dumpObjectFiles(*Dbg);1279  if (opts::SymbolsSubcommand)1280    return opts::symbols::dumpSymbols(*Dbg);1281  if (opts::SymTabSubcommand)1282    return opts::symtab::handleSymtabCommand(*Dbg);1283  if (opts::IRMemoryMapSubcommand)1284    return opts::irmemorymap::evaluateMemoryMapCommands(*Dbg);1285  if (opts::AssertSubcommand)1286    return opts::assert::lldb_assert(*Dbg);1287 1288  WithColor::error() << "No command specified.\n";1289  return 1;1290}1291