summaryrefslogtreecommitdiff
path: root/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llvm-dwarfdump/llvm-dwarfdump.cpp')
-rw-r--r--tools/llvm-dwarfdump/llvm-dwarfdump.cpp106
1 files changed, 95 insertions, 11 deletions
diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index ec0b4aeb63c6..e73300a0cd8d 100644
--- a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -1,4 +1,4 @@
-//===-- llvm-dwarfdump.cpp - Debug info dumping utility for llvm -----------===//
+//===-- llvm-dwarfdump.cpp - Debug info dumping utility for llvm ----------===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,6 +15,7 @@
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/RelocVisitor.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
@@ -28,6 +29,9 @@
#include "llvm/Support/system_error.h"
#include <algorithm>
#include <cstring>
+#include <list>
+#include <string>
+
using namespace llvm;
using namespace object;
@@ -44,6 +48,18 @@ PrintFunctions("functions", cl::init(false),
cl::desc("Print function names as well as line information "
"for a given address"));
+static cl::opt<bool>
+PrintInlining("inlining", cl::init(false),
+ cl::desc("Print all inlined frames for a given address"));
+
+static void PrintDILineInfo(DILineInfo dli) {
+ if (PrintFunctions)
+ outs() << (dli.getFunctionName() ? dli.getFunctionName() : "<unknown>")
+ << "\n";
+ outs() << (dli.getFileName() ? dli.getFileName() : "<unknown>") << ':'
+ << dli.getLine() << ':' << dli.getColumn() << '\n';
+}
+
static void DumpInput(const StringRef &Filename) {
OwningPtr<MemoryBuffer> Buff;
@@ -55,10 +71,12 @@ static void DumpInput(const StringRef &Filename) {
OwningPtr<ObjectFile> Obj(ObjectFile::createObjectFile(Buff.take()));
StringRef DebugInfoSection;
+ RelocAddrMap RelocMap;
StringRef DebugAbbrevSection;
StringRef DebugLineSection;
StringRef DebugArangesSection;
StringRef DebugStringSection;
+ StringRef DebugRangesSection;
error_code ec;
for (section_iterator i = Obj->begin_sections(),
@@ -82,6 +100,59 @@ static void DumpInput(const StringRef &Filename) {
DebugArangesSection = data;
else if (name == "debug_str")
DebugStringSection = data;
+ else if (name == "debug_ranges")
+ DebugRangesSection = data;
+ // Any more debug info sections go here.
+ else
+ continue;
+
+ // TODO: For now only handle relocations for the debug_info section.
+ if (name != "debug_info")
+ continue;
+
+ if (i->begin_relocations() != i->end_relocations()) {
+ uint64_t SectionSize;
+ i->getSize(SectionSize);
+ for (relocation_iterator reloc_i = i->begin_relocations(),
+ reloc_e = i->end_relocations();
+ reloc_i != reloc_e; reloc_i.increment(ec)) {
+ uint64_t Address;
+ reloc_i->getAddress(Address);
+ uint64_t Type;
+ reloc_i->getType(Type);
+
+ RelocVisitor V(Obj->getFileFormatName());
+ // The section address is always 0 for debug sections.
+ RelocToApply R(V.visit(Type, *reloc_i));
+ if (V.error()) {
+ SmallString<32> Name;
+ error_code ec(reloc_i->getTypeName(Name));
+ if (ec) {
+ errs() << "Aaaaaa! Nameless relocation! Aaaaaa!\n";
+ }
+ errs() << "error: failed to compute relocation: "
+ << Name << "\n";
+ continue;
+ }
+
+ if (Address + R.Width > SectionSize) {
+ errs() << "error: " << R.Width << "-byte relocation starting "
+ << Address << " bytes into section " << name << " which is "
+ << SectionSize << " bytes long.\n";
+ continue;
+ }
+ if (R.Width > 8) {
+ errs() << "error: can't handle a relocation of more than 8 bytes at "
+ "a time.\n";
+ continue;
+ }
+ DEBUG(dbgs() << "Writing " << format("%p", R.Value)
+ << " at " << format("%p", Address)
+ << " with width " << format("%d", R.Width)
+ << "\n");
+ RelocMap[Address] = std::make_pair(R.Width, R.Value);
+ }
+ }
}
OwningPtr<DIContext> dictx(DIContext::getDWARFContext(/*FIXME*/true,
@@ -89,7 +160,9 @@ static void DumpInput(const StringRef &Filename) {
DebugAbbrevSection,
DebugArangesSection,
DebugLineSection,
- DebugStringSection));
+ DebugStringSection,
+ DebugRangesSection,
+ RelocMap));
if (Address == -1ULL) {
outs() << Filename
<< ":\tfile format " << Obj->getFileFormatName() << "\n\n";
@@ -97,16 +170,27 @@ static void DumpInput(const StringRef &Filename) {
dictx->dump(outs());
} else {
// Print line info for the specified address.
- int spec_flags = DILineInfoSpecifier::FileLineInfo |
- DILineInfoSpecifier::AbsoluteFilePath;
- if (PrintFunctions)
- spec_flags |= DILineInfoSpecifier::FunctionName;
- DILineInfo dli = dictx->getLineInfoForAddress(Address, spec_flags);
+ int SpecFlags = DILineInfoSpecifier::FileLineInfo |
+ DILineInfoSpecifier::AbsoluteFilePath;
if (PrintFunctions)
- outs() << (dli.getFunctionName() ? dli.getFunctionName() : "<unknown>")
- << "\n";
- outs() << (dli.getFileName() ? dli.getFileName() : "<unknown>") << ':'
- << dli.getLine() << ':' << dli.getColumn() << '\n';
+ SpecFlags |= DILineInfoSpecifier::FunctionName;
+ if (PrintInlining) {
+ DIInliningInfo InliningInfo =
+ dictx->getInliningInfoForAddress(Address, SpecFlags);
+ uint32_t n = InliningInfo.getNumberOfFrames();
+ if (n == 0) {
+ // Print one empty debug line info in any case.
+ PrintDILineInfo(DILineInfo());
+ } else {
+ for (uint32_t i = 0; i < n; i++) {
+ DILineInfo dli = InliningInfo.getFrame(i);
+ PrintDILineInfo(dli);
+ }
+ }
+ } else {
+ DILineInfo dli = dictx->getLineInfoForAddress(Address, SpecFlags);
+ PrintDILineInfo(dli);
+ }
}
}