//===-- llvm-dwarfdump.cpp - Debug info dumping utility for llvm ----------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This program is a utility that works like "dwarfdump". // //===----------------------------------------------------------------------===// #include "llvm-dwarfdump.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringSet.h" #include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h" #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Object/Archive.h" #include "llvm/Object/MachOUniversal.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Format.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/Regex.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/ToolOutputFile.h" #include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Triple.h" #include using namespace llvm; using namespace llvm::dwarfdump; using namespace llvm::object; namespace { /// Parser for options that take an optional offest argument. /// @{ struct OffsetOption { uint64_t Val = 0; bool HasValue = false; bool IsRequested = false; }; struct BoolOption : public OffsetOption {}; } // namespace namespace llvm { namespace cl { template <> class parser final : public basic_parser { public: parser(Option &O) : basic_parser(O) {} /// Return true on error. bool parse(Option &O, StringRef ArgName, StringRef Arg, OffsetOption &Val) { if (Arg == "") { Val.Val = 0; Val.HasValue = false; Val.IsRequested = true; return false; } if (Arg.getAsInteger(0, Val.Val)) return O.error("'" + Arg + "' value invalid for integer argument"); Val.HasValue = true; Val.IsRequested = true; return false; } enum ValueExpected getValueExpectedFlagDefault() const { return ValueOptional; } StringRef getValueName() const override { return StringRef("offset"); } void printOptionDiff(const Option &O, OffsetOption V, OptVal Default, size_t GlobalWidth) const { printOptionName(O, GlobalWidth); outs() << "[=offset]"; } }; template <> class parser final : public basic_parser { public: parser(Option &O) : basic_parser(O) {} /// Return true on error. bool parse(Option &O, StringRef ArgName, StringRef Arg, BoolOption &Val) { if (Arg != "") return O.error("this is a flag and does not take a value"); Val.Val = 0; Val.HasValue = false; Val.IsRequested = true; return false; } enum ValueExpected getValueExpectedFlagDefault() const { return ValueOptional; } StringRef getValueName() const override { return StringRef(); } void printOptionDiff(const Option &O, OffsetOption V, OptVal Default, size_t GlobalWidth) const { printOptionName(O, GlobalWidth); } }; } // namespace cl } // namespace llvm /// @} /// Command line options. /// @{ namespace { using namespace cl; enum ErrorDetailLevel { OnlyDetailsNoSummary, NoDetailsOnlySummary, NoDetailsOrSummary, BothDetailsAndSummary, Unspecified }; OptionCategory DwarfDumpCategory("Specific Options"); static list InputFilenames(Positional, desc(""), cat(DwarfDumpCategory)); cl::OptionCategory SectionCategory("Section-specific Dump Options", "These control which sections are dumped. " "Where applicable these parameters take an " "optional = argument to dump only " "the entry at the specified offset."); static opt DumpAll("all", desc("Dump all debug info sections"), cat(SectionCategory)); static alias DumpAllAlias("a", desc("Alias for --all"), aliasopt(DumpAll), cl::NotHidden); // Options for dumping specific sections. static unsigned DumpType = DIDT_Null; static std::array, (unsigned)DIDT_ID_Count> DumpOffsets; #define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME, OPTION) \ static opt