1//===-- llvm-dwarfdump.cpp - Debug info dumping utility for llvm -----------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This program is a utility that works like "dwarfdump". 11// 12//===----------------------------------------------------------------------===// 13 14#include "llvm/ADT/OwningPtr.h" 15#include "llvm/ADT/Triple.h" 16#include "llvm/ADT/STLExtras.h" 17#include "llvm/Object/ObjectFile.h" 18#include "llvm/DebugInfo/DIContext.h" 19#include "llvm/Support/CommandLine.h" 20#include "llvm/Support/Debug.h" 21#include "llvm/Support/Format.h" 22#include "llvm/Support/ManagedStatic.h" 23#include "llvm/Support/MemoryBuffer.h" 24#include "llvm/Support/MemoryObject.h" 25#include "llvm/Support/PrettyStackTrace.h" 26#include "llvm/Support/Signals.h" 27#include "llvm/Support/raw_ostream.h" 28#include "llvm/Support/system_error.h" 29#include <algorithm> 30#include <cstring> 31using namespace llvm; 32using namespace object; 33 34static cl::list<std::string> 35InputFilenames(cl::Positional, cl::desc("<input object files>"), 36 cl::ZeroOrMore); 37 38static cl::opt<unsigned long long> 39Address("address", cl::init(-1ULL), 40 cl::desc("Print line information for a given address")); 41 42static void DumpInput(const StringRef &Filename) { 43 OwningPtr<MemoryBuffer> Buff; 44 45 if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) { 46 errs() << Filename << ": " << ec.message() << "\n"; 47 return; 48 } 49 50 OwningPtr<ObjectFile> Obj(ObjectFile::createObjectFile(Buff.take())); 51 52 StringRef DebugInfoSection; 53 StringRef DebugAbbrevSection; 54 StringRef DebugLineSection; 55 StringRef DebugArangesSection; 56 StringRef DebugStringSection; 57 58 error_code ec; 59 for (section_iterator i = Obj->begin_sections(), 60 e = Obj->end_sections(); 61 i != e; i.increment(ec)) { 62 StringRef name; 63 i->getName(name); 64 StringRef data; 65 i->getContents(data); 66 67 if (name.startswith("__DWARF,")) 68 name = name.substr(8); // Skip "__DWARF," prefix. 69 name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes. 70 if (name == "debug_info") 71 DebugInfoSection = data; 72 else if (name == "debug_abbrev") 73 DebugAbbrevSection = data; 74 else if (name == "debug_line") 75 DebugLineSection = data; 76 else if (name == "debug_aranges") 77 DebugArangesSection = data; 78 else if (name == "debug_str") 79 DebugStringSection = data; 80 } 81 82 OwningPtr<DIContext> dictx(DIContext::getDWARFContext(/*FIXME*/true, 83 DebugInfoSection, 84 DebugAbbrevSection, 85 DebugArangesSection, 86 DebugLineSection, 87 DebugStringSection)); 88 if (Address == -1ULL) { 89 outs() << Filename 90 << ":\tfile format " << Obj->getFileFormatName() << "\n\n"; 91 // Dump the complete DWARF structure. 92 dictx->dump(outs()); 93 } else { 94 // Print line info for the specified address. 95 DILineInfo dli = dictx->getLineInfoForAddress(Address); 96 outs() << (dli.getFileName() ? dli.getFileName() : "<unknown>") << ':' 97 << dli.getLine() << ':' << dli.getColumn() << '\n'; 98 } 99} 100 101int main(int argc, char **argv) { 102 // Print a stack trace if we signal out. 103 sys::PrintStackTraceOnErrorSignal(); 104 PrettyStackTraceProgram X(argc, argv); 105 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 106 107 cl::ParseCommandLineOptions(argc, argv, "llvm dwarf dumper\n"); 108 109 // Defaults to a.out if no filenames specified. 110 if (InputFilenames.size() == 0) 111 InputFilenames.push_back("a.out"); 112 113 std::for_each(InputFilenames.begin(), InputFilenames.end(), DumpInput); 114 115 return 0; 116} 117