diff options
Diffstat (limited to 'llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp')
-rw-r--r-- | llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 91 |
1 files changed, 69 insertions, 22 deletions
diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp index cc7f353330b1..27330a571bbe 100644 --- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -18,6 +18,8 @@ #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" @@ -137,8 +139,7 @@ static alias DumpAllAlias("a", desc("Alias for --all"), aliasopt(DumpAll), // Options for dumping specific sections. static unsigned DumpType = DIDT_Null; -static std::array<llvm::Optional<uint64_t>, (unsigned)DIDT_ID_Count> - DumpOffsets; +static std::array<std::optional<uint64_t>, (unsigned)DIDT_ID_Count> DumpOffsets; #define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME, OPTION) \ static opt<OPTION> Dump##ENUM_NAME(CMDLINE_NAME, \ desc("Dump the " ELF_NAME " section"), \ @@ -248,6 +249,13 @@ static cl::opt<bool> cl::desc("Show the sizes of all debug sections, " "expressed in bytes."), cat(DwarfDumpCategory)); +static cl::opt<bool> ManuallyGenerateUnitIndex( + "manaully-generate-unit-index", + cl::desc("if the input is dwp file, parse .debug_info " + "section and use it to populate " + "DW_SECT_INFO contributions in cu-index. " + "For DWARF5 it also populated TU Index."), + cl::init(false), cl::Hidden, cl::cat(DwarfDumpCategory)); static cl::opt<bool> ShowSources("show-sources", cl::desc("Show the sources across all compilation units."), @@ -341,9 +349,11 @@ using HandlerFn = std::function<bool(ObjectFile &, DWARFContext &DICtx, const Twine &, raw_ostream &)>; /// Print only DIEs that have a certain name. -static bool filterByName(const StringSet<> &Names, DWARFDie Die, - StringRef NameRef, raw_ostream &OS) { +static bool filterByName( + const StringSet<> &Names, DWARFDie Die, StringRef NameRef, raw_ostream &OS, + std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg) { DIDumpOptions DumpOpts = getDumpOpts(Die.getDwarfUnit()->getContext()); + DumpOpts.GetNameForDWARFReg = GetNameForDWARFReg; std::string Name = (IgnoreCase && !UseRegex) ? NameRef.lower() : NameRef.str(); if (UseRegex) { @@ -369,24 +379,25 @@ static bool filterByName(const StringSet<> &Names, DWARFDie Die, } /// Print only DIEs that have a certain name. -static void filterByName(const StringSet<> &Names, - DWARFContext::unit_iterator_range CUs, - raw_ostream &OS) { +static void filterByName( + const StringSet<> &Names, DWARFContext::unit_iterator_range CUs, + raw_ostream &OS, + std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg) { for (const auto &CU : CUs) for (const auto &Entry : CU->dies()) { DWARFDie Die = {CU.get(), &Entry}; if (const char *Name = Die.getName(DINameKind::ShortName)) - if (filterByName(Names, Die, Name, OS)) + if (filterByName(Names, Die, Name, OS, GetNameForDWARFReg)) continue; if (const char *Name = Die.getName(DINameKind::LinkageName)) - filterByName(Names, Die, Name, OS); + filterByName(Names, Die, Name, OS, GetNameForDWARFReg); } } static void getDies(DWARFContext &DICtx, const AppleAcceleratorTable &Accel, StringRef Name, SmallVectorImpl<DWARFDie> &Dies) { for (const auto &Entry : Accel.equal_range(Name)) { - if (llvm::Optional<uint64_t> Off = Entry.getDIESectionOffset()) { + if (std::optional<uint64_t> Off = Entry.getDIESectionOffset()) { if (DWARFDie Die = DICtx.getDIEForOffset(*Off)) Dies.push_back(Die); } @@ -395,8 +406,8 @@ static void getDies(DWARFContext &DICtx, const AppleAcceleratorTable &Accel, static DWARFDie toDie(const DWARFDebugNames::Entry &Entry, DWARFContext &DICtx) { - llvm::Optional<uint64_t> CUOff = Entry.getCUOffset(); - llvm::Optional<uint64_t> Off = Entry.getDIEUnitOffset(); + std::optional<uint64_t> CUOff = Entry.getCUOffset(); + std::optional<uint64_t> Off = Entry.getDIEUnitOffset(); if (!CUOff || !Off) return DWARFDie(); @@ -404,7 +415,7 @@ static DWARFDie toDie(const DWARFDebugNames::Entry &Entry, if (!CU) return DWARFDie(); - if (llvm::Optional<uint64_t> DWOId = CU->getDWOId()) { + if (std::optional<uint64_t> DWOId = CU->getDWOId()) { // This is a skeleton unit. Look up the DIE in the DWO unit. CU = DICtx.getDWOCompileUnitForHash(*DWOId); if (!CU) @@ -423,8 +434,9 @@ static void getDies(DWARFContext &DICtx, const DWARFDebugNames &Accel, } /// Print only DIEs that have a certain name. -static void filterByAccelName(ArrayRef<std::string> Names, DWARFContext &DICtx, - raw_ostream &OS) { +static void filterByAccelName( + ArrayRef<std::string> Names, DWARFContext &DICtx, raw_ostream &OS, + std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg) { SmallVector<DWARFDie, 4> Dies; for (const auto &Name : Names) { getDies(DICtx, DICtx.getAppleNames(), Name, Dies); @@ -436,6 +448,7 @@ static void filterByAccelName(ArrayRef<std::string> Names, DWARFContext &DICtx, Dies.erase(std::unique(Dies.begin(), Dies.end()), Dies.end()); DIDumpOptions DumpOpts = getDumpOpts(DICtx); + DumpOpts.GetNameForDWARFReg = GetNameForDWARFReg; for (DWARFDie Die : Dies) Die.dump(OS, 0, DumpOpts); } @@ -477,7 +490,7 @@ static bool collectLineTableSources(const DWARFDebugLine::LineTable <, StringRef CompDir, std::vector<std::string> &Sources) { bool Result = true; - llvm::Optional<uint64_t> LastIndex = LT.getLastValidFileIndex(); + std::optional<uint64_t> LastIndex = LT.getLastValidFileIndex(); for (uint64_t I = LT.hasFileAtIndex(0) ? 0 : 1, E = LastIndex ? *LastIndex + 1 : 0; I < E; ++I) { @@ -552,10 +565,41 @@ static bool collectObjectSources(ObjectFile &Obj, DWARFContext &DICtx, return Result; } +static std::unique_ptr<MCRegisterInfo> +createRegInfo(const object::ObjectFile &Obj) { + std::unique_ptr<MCRegisterInfo> MCRegInfo; + Triple TT; + TT.setArch(Triple::ArchType(Obj.getArch())); + TT.setVendor(Triple::UnknownVendor); + TT.setOS(Triple::UnknownOS); + std::string TargetLookupError; + const Target *TheTarget = + TargetRegistry::lookupTarget(TT.str(), TargetLookupError); + if (!TargetLookupError.empty()) + return nullptr; + MCRegInfo.reset(TheTarget->createMCRegInfo(TT.str())); + return MCRegInfo; +} + static bool dumpObjectFile(ObjectFile &Obj, DWARFContext &DICtx, const Twine &Filename, raw_ostream &OS) { - logAllUnhandledErrors(DICtx.loadRegisterInfo(Obj), errs(), - Filename.str() + ": "); + + auto MCRegInfo = createRegInfo(Obj); + if (!MCRegInfo) + logAllUnhandledErrors(createStringError(inconvertibleErrorCode(), + "Error in creating MCRegInfo"), + errs(), Filename.str() + ": "); + + auto GetRegName = [&MCRegInfo](uint64_t DwarfRegNum, bool IsEH) -> StringRef { + if (!MCRegInfo) + return {}; + if (std::optional<unsigned> LLVMRegNum = + MCRegInfo->getLLVMRegNum(DwarfRegNum, IsEH)) + if (const char *RegName = MCRegInfo->getName(*LLVMRegNum)) + return StringRef(RegName); + return {}; + }; + // The UUID dump already contains all the same information. if (!(DumpType & DIDT_UUID) || DumpType == DIDT_All) OS << Filename << ":\tfile format " << Obj.getFileFormatName() << '\n'; @@ -570,19 +614,21 @@ static bool dumpObjectFile(ObjectFile &Obj, DWARFContext &DICtx, for (auto name : Name) Names.insert((IgnoreCase && !UseRegex) ? StringRef(name).lower() : name); - filterByName(Names, DICtx.normal_units(), OS); - filterByName(Names, DICtx.dwo_units(), OS); + filterByName(Names, DICtx.normal_units(), OS, GetRegName); + filterByName(Names, DICtx.dwo_units(), OS, GetRegName); return true; } // Handle the --find option and lower it to --debug-info=<offset>. if (!Find.empty()) { - filterByAccelName(Find, DICtx, OS); + filterByAccelName(Find, DICtx, OS, GetRegName); return true; } // Dump the complete DWARF structure. - DICtx.dump(OS, getDumpOpts(DICtx), DumpOffsets); + auto DumpOpts = getDumpOpts(DICtx); + DumpOpts.GetNameForDWARFReg = GetRegName; + DICtx.dump(OS, DumpOpts, DumpOffsets); return true; } @@ -636,6 +682,7 @@ static bool handleBuffer(StringRef Filename, MemoryBufferRef Buffer, std::unique_ptr<DWARFContext> DICtx = DWARFContext::create( *Obj, DWARFContext::ProcessDebugRelocations::Process, nullptr, "", RecoverableErrorHandler); + DICtx->setParseCUTUIndexManually(ManuallyGenerateUnitIndex); if (!HandleObj(*Obj, *DICtx, Filename, OS)) Result = false; } |