brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.8 KiB · a5e2d39 Raw
142 lines · cpp
1//===-- llvm-debuginfo-analyzer.cpp - LLVM Debug info analysis utility ---===//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// This program is a utility that displays the logical view for the debug10// information.11//12//===----------------------------------------------------------------------===//13 14#include "Options.h"15#include "llvm/DebugInfo/LogicalView/Core/LVOptions.h"16#include "llvm/DebugInfo/LogicalView/LVReaderHandler.h"17#include "llvm/Support/COM.h"18#include "llvm/Support/CommandLine.h"19#include "llvm/Support/InitLLVM.h"20#include "llvm/Support/TargetSelect.h"21#include "llvm/Support/ToolOutputFile.h"22#include "llvm/Support/WithColor.h"23 24using namespace llvm;25using namespace logicalview;26using namespace cmdline;27 28/// Create formatted StringError object.29static StringRef ToolName = "llvm-debuginfo-analyzer";30template <typename... Ts>31static void error(std::error_code EC, char const *Fmt, const Ts &...Vals) {32  if (!EC)33    return;34  std::string Buffer;35  raw_string_ostream Stream(Buffer);36  Stream << format(Fmt, Vals...);37  WithColor::error(errs(), ToolName) << Buffer << "\n";38  exit(1);39}40 41static void error(Error EC) {42  if (!EC)43    return;44  handleAllErrors(std::move(EC), [&](const ErrorInfoBase &EI) {45    errs() << "\n";46    WithColor::error(errs(), ToolName) << EI.message() << ".\n";47    exit(1);48  });49}50 51/// If the input path is a .dSYM bundle (as created by the dsymutil tool),52/// replace it with individual entries for each of the object files inside the53/// bundle otherwise return the input path.54static std::vector<std::string> expandBundle(const std::string &InputPath) {55  std::vector<std::string> BundlePaths;56  SmallString<256> BundlePath(InputPath);57  // Normalize input path. This is necessary to accept `bundle.dSYM/`.58  sys::path::remove_dots(BundlePath);59  // Manually open up the bundle to avoid introducing additional dependencies.60  if (sys::fs::is_directory(BundlePath) &&61      sys::path::extension(BundlePath) == ".dSYM") {62    std::error_code EC;63    sys::path::append(BundlePath, "Contents", "Resources", "DWARF");64    for (sys::fs::directory_iterator Dir(BundlePath, EC), DirEnd;65         Dir != DirEnd && !EC; Dir.increment(EC)) {66      const std::string &Path = Dir->path();67      sys::fs::file_status Status;68      EC = sys::fs::status(Path, Status);69      error(EC, "%s", Path.c_str());70      switch (Status.type()) {71      case sys::fs::file_type::regular_file:72      case sys::fs::file_type::symlink_file:73      case sys::fs::file_type::type_unknown:74        BundlePaths.push_back(Path);75        break;76      default: /*ignore*/;77      }78    }79  }80  if (BundlePaths.empty())81    BundlePaths.push_back(InputPath);82  return BundlePaths;83}84 85int main(int argc, char **argv) {86  InitLLVM X(argc, argv);87 88  // Initialize targets and assembly printers/parsers.89  llvm::InitializeAllTargetInfos();90  llvm::InitializeAllTargetMCs();91  InitializeAllDisassemblers();92 93  llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded);94 95  cl::extrahelp HelpResponse(96      "\nPass @FILE as argument to read options from FILE.\n");97 98  cl::HideUnrelatedOptions(99      {&AttributeCategory, &CompareCategory, &InternalCategory, &OutputCategory,100       &PrintCategory, &ReportCategory, &SelectCategory, &WarningCategory});101  cl::ParseCommandLineOptions(argc, argv,102                              "Printing a logical representation of low-level "103                              "debug information.\n");104  cl::PrintOptionValues();105 106  std::error_code EC;107  ToolOutputFile OutputFile(OutputFilename, EC, sys::fs::OF_None);108  error(EC, "Unable to open output file %s", OutputFilename.c_str());109  // Don't remove output file if we exit with an error.110  OutputFile.keep();111 112  // Defaults to a.out if no filenames specified.113  if (InputFilenames.empty())114    InputFilenames.push_back("a.out");115 116  // Expand any .dSYM bundles to the individual object files contained therein.117  std::vector<std::string> Objects;118  for (const std::string &Filename : InputFilenames) {119    std::vector<std::string> Objs = expandBundle(Filename);120    llvm::append_range(Objects, Objs);121  }122 123  propagateOptions();124  ScopedPrinter W(OutputFile.os());125  LVReaderHandler ReaderHandler(Objects, W, ReaderOptions);126 127  // Print the command line.128  if (options().getInternalCmdline()) {129    raw_ostream &Stream = W.getOStream();130    Stream << "\nCommand line:\n";131    for (int Index = 0; Index < argc; ++Index)132      Stream << "  " << argv[Index] << "\n";133    Stream << "\n";134  }135 136  // Create readers and perform requested tasks on them.137  if (Error Err = ReaderHandler.process())138    error(std::move(Err));139 140  return EXIT_SUCCESS;141}142