aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp')
-rw-r--r--llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp91
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 &LT,
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;
}