Path: blob/main/contrib/llvm-project/llvm/tools/llvm-debuginfo-analyzer/llvm-debuginfo-analyzer.cpp
35231 views
//===-- llvm-debuginfo-analyzer.cpp - LLVM Debug info analysis utility ---===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This program is a utility that displays the logical view for the debug9// information.10//11//===----------------------------------------------------------------------===//1213#include "Options.h"14#include "llvm/DebugInfo/LogicalView/Core/LVOptions.h"15#include "llvm/DebugInfo/LogicalView/LVReaderHandler.h"16#include "llvm/Support/COM.h"17#include "llvm/Support/CommandLine.h"18#include "llvm/Support/InitLLVM.h"19#include "llvm/Support/TargetSelect.h"20#include "llvm/Support/ToolOutputFile.h"21#include "llvm/Support/WithColor.h"2223using namespace llvm;24using namespace logicalview;25using namespace cmdline;2627/// Create formatted StringError object.28static StringRef ToolName = "llvm-debuginfo-analyzer";29template <typename... Ts>30static void error(std::error_code EC, char const *Fmt, const Ts &...Vals) {31if (!EC)32return;33std::string Buffer;34raw_string_ostream Stream(Buffer);35Stream << format(Fmt, Vals...);36WithColor::error(errs(), ToolName) << Stream.str() << "\n";37exit(1);38}3940static void error(Error EC) {41if (!EC)42return;43handleAllErrors(std::move(EC), [&](const ErrorInfoBase &EI) {44errs() << "\n";45WithColor::error(errs(), ToolName) << EI.message() << ".\n";46exit(1);47});48}4950/// If the input path is a .dSYM bundle (as created by the dsymutil tool),51/// replace it with individual entries for each of the object files inside the52/// bundle otherwise return the input path.53static std::vector<std::string> expandBundle(const std::string &InputPath) {54std::vector<std::string> BundlePaths;55SmallString<256> BundlePath(InputPath);56// Normalize input path. This is necessary to accept `bundle.dSYM/`.57sys::path::remove_dots(BundlePath);58// Manually open up the bundle to avoid introducing additional dependencies.59if (sys::fs::is_directory(BundlePath) &&60sys::path::extension(BundlePath) == ".dSYM") {61std::error_code EC;62sys::path::append(BundlePath, "Contents", "Resources", "DWARF");63for (sys::fs::directory_iterator Dir(BundlePath, EC), DirEnd;64Dir != DirEnd && !EC; Dir.increment(EC)) {65const std::string &Path = Dir->path();66sys::fs::file_status Status;67EC = sys::fs::status(Path, Status);68error(EC, "%s", Path.c_str());69switch (Status.type()) {70case sys::fs::file_type::regular_file:71case sys::fs::file_type::symlink_file:72case sys::fs::file_type::type_unknown:73BundlePaths.push_back(Path);74break;75default: /*ignore*/;76}77}78}79if (BundlePaths.empty())80BundlePaths.push_back(InputPath);81return BundlePaths;82}8384int main(int argc, char **argv) {85InitLLVM X(argc, argv);8687// Initialize targets and assembly printers/parsers.88llvm::InitializeAllTargetInfos();89llvm::InitializeAllTargetMCs();90InitializeAllDisassemblers();9192llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded);9394cl::extrahelp HelpResponse(95"\nPass @FILE as argument to read options from FILE.\n");9697cl::HideUnrelatedOptions(98{&AttributeCategory, &CompareCategory, &InternalCategory, &OutputCategory,99&PrintCategory, &ReportCategory, &SelectCategory, &WarningCategory});100cl::ParseCommandLineOptions(argc, argv,101"Printing a logical representation of low-level "102"debug information.\n");103cl::PrintOptionValues();104105std::error_code EC;106ToolOutputFile OutputFile(OutputFilename, EC, sys::fs::OF_None);107error(EC, "Unable to open output file %s", OutputFilename.c_str());108// Don't remove output file if we exit with an error.109OutputFile.keep();110111// Defaults to a.out if no filenames specified.112if (InputFilenames.empty())113InputFilenames.push_back("a.out");114115// Expand any .dSYM bundles to the individual object files contained therein.116std::vector<std::string> Objects;117for (const std::string &Filename : InputFilenames) {118std::vector<std::string> Objs = expandBundle(Filename);119Objects.insert(Objects.end(), Objs.begin(), Objs.end());120}121122propagateOptions();123ScopedPrinter W(OutputFile.os());124LVReaderHandler ReaderHandler(Objects, W, ReaderOptions);125126// Print the command line.127if (options().getInternalCmdline()) {128raw_ostream &Stream = W.getOStream();129Stream << "\nCommand line:\n";130for (int Index = 0; Index < argc; ++Index)131Stream << " " << argv[Index] << "\n";132Stream << "\n";133}134135// Create readers and perform requested tasks on them.136if (Error Err = ReaderHandler.process())137error(std::move(Err));138139return EXIT_SUCCESS;140}141142143