diff options
Diffstat (limited to 'tools/llvm-dwarfdump/llvm-dwarfdump.cpp')
-rw-r--r-- | tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 106 |
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); + } } } |