aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-07-03 14:10:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-07-03 14:10:23 +0000
commit145449b1e420787bb99721a429341fa6be3adfb6 (patch)
tree1d56ae694a6de602e348dd80165cf881a36600ed /llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
parentecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (diff)
Diffstat (limited to 'llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp')
-rw-r--r--llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp93
1 files changed, 92 insertions, 1 deletions
diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 9c2ddc3867a5..f7d3052c8c4d 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -15,6 +15,8 @@
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/Triple.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/Object/Archive.h"
#include "llvm/Object/MachOUniversal.h"
@@ -24,6 +26,7 @@
#include "llvm/Support/Format.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"
@@ -119,7 +122,7 @@ using namespace cl;
OptionCategory DwarfDumpCategory("Specific Options");
static list<std::string>
InputFilenames(Positional, desc("<input object files or .dSYM bundles>"),
- ZeroOrMore, cat(DwarfDumpCategory));
+ cat(DwarfDumpCategory));
cl::OptionCategory SectionCategory("Section-specific Dump Options",
"These control which sections are dumped. "
@@ -245,6 +248,10 @@ static cl::opt<bool>
cl::desc("Show the sizes of all debug sections, "
"expressed in bytes."),
cat(DwarfDumpCategory));
+static cl::opt<bool>
+ ShowSources("show-sources",
+ cl::desc("Show the sources across all compilation units."),
+ cat(DwarfDumpCategory));
static opt<bool> Verify("verify", desc("Verify the DWARF debug info."),
cat(DwarfDumpCategory));
static opt<bool> Quiet("quiet", desc("Use with -verify to not emit to STDOUT."),
@@ -464,6 +471,87 @@ static bool lookup(ObjectFile &Obj, DWARFContext &DICtx, uint64_t Address,
return true;
}
+// Collect all sources referenced from the given line table, scoped to the given
+// CU compilation directory.
+static bool collectLineTableSources(const DWARFDebugLine::LineTable &LT,
+ StringRef CompDir,
+ std::vector<std::string> &Sources) {
+ bool Result = true;
+ llvm::Optional<uint64_t> LastIndex = LT.getLastValidFileIndex();
+ for (uint64_t I = LT.hasFileAtIndex(0) ? 0 : 1,
+ E = LastIndex ? *LastIndex + 1 : 0;
+ I < E; ++I) {
+ std::string Path;
+ Result &= LT.getFileNameByIndex(
+ I, CompDir, DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
+ Path);
+ Sources.push_back(std::move(Path));
+ }
+ return Result;
+}
+
+static bool collectObjectSources(ObjectFile &Obj, DWARFContext &DICtx,
+ const Twine &Filename, raw_ostream &OS) {
+ bool Result = true;
+ std::vector<std::string> Sources;
+
+ bool HasCompileUnits = false;
+ for (const auto &CU : DICtx.compile_units()) {
+ HasCompileUnits = true;
+ // Extract paths from the line table for this CU. This allows combining the
+ // compilation directory with the line information, in case both the include
+ // directory and file names in the line table are relative.
+ const DWARFDebugLine::LineTable *LT = DICtx.getLineTableForUnit(CU.get());
+ StringRef CompDir = CU->getCompilationDir();
+ if (LT) {
+ Result &= collectLineTableSources(*LT, CompDir, Sources);
+ } else {
+ // Since there's no line table for this CU, collect the name from the CU
+ // itself.
+ const char *Name = CU->getUnitDIE().getShortName();
+ if (!Name) {
+ WithColor::warning()
+ << Filename << ": missing name for compilation unit\n";
+ continue;
+ }
+ SmallString<64> AbsName;
+ if (sys::path::is_relative(Name, sys::path::Style::posix) &&
+ sys::path::is_relative(Name, sys::path::Style::windows))
+ AbsName = CompDir;
+ sys::path::append(AbsName, Name);
+ Sources.push_back(std::string(AbsName));
+ }
+ }
+
+ if (!HasCompileUnits) {
+ // Since there's no compile units available, walk the line tables and
+ // extract out any referenced paths.
+ DWARFDataExtractor LineData(DICtx.getDWARFObj(),
+ DICtx.getDWARFObj().getLineSection(),
+ DICtx.isLittleEndian(), 0);
+ DWARFDebugLine::SectionParser Parser(LineData, DICtx, DICtx.normal_units());
+ while (!Parser.done()) {
+ const auto RecoverableErrorHandler = [&](Error Err) {
+ Result = false;
+ WithColor::defaultErrorHandler(std::move(Err));
+ };
+ void (*UnrecoverableErrorHandler)(Error Err) = error;
+
+ DWARFDebugLine::LineTable LT =
+ Parser.parseNext(RecoverableErrorHandler, UnrecoverableErrorHandler);
+ Result &= collectLineTableSources(LT, /*CompDir=*/"", Sources);
+ }
+ }
+
+ // Dedup and order the sources.
+ llvm::sort(Sources.begin(), Sources.end());
+ Sources.erase(std::unique(Sources.begin(), Sources.end()), Sources.end());
+
+ for (StringRef Name : Sources)
+ OS << Name << "\n";
+ return Result;
+}
+
static bool dumpObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
const Twine &Filename, raw_ostream &OS) {
logAllUnhandledErrors(DICtx.loadRegisterInfo(Obj), errs(),
@@ -677,6 +765,9 @@ int main(int argc, char **argv) {
} else if (ShowSectionSizes) {
for (auto Object : Objects)
Success &= handleFile(Object, collectObjectSectionSizes, OutputFile.os());
+ } else if (ShowSources) {
+ for (auto Object : Objects)
+ Success &= handleFile(Object, collectObjectSources, OutputFile.os());
} else {
for (auto Object : Objects)
Success &= handleFile(Object, dumpObjectFile, OutputFile.os());