Home | History | Annotate | Download | only in llvm-dwarfdump
      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>
     31 using namespace llvm;
     32 using namespace object;
     33 
     34 static cl::list<std::string>
     35 InputFilenames(cl::Positional, cl::desc("<input object files>"),
     36                cl::ZeroOrMore);
     37 
     38 static cl::opt<unsigned long long>
     39 Address("address", cl::init(-1ULL),
     40         cl::desc("Print line information for a given address"));
     41 
     42 static 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 
    101 int 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