llvm-dwarfdump.cpp revision f010c464a11444733ec67e31aace8bcebeaf2588
1d7169e9f067d60796269f1a77b1f10195742a453Eric Christopher//===-- llvm-dwarfdump.cpp - Debug info dumping utility for llvm ----------===//
272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//                     The LLVM Compiler Infrastructure
472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// This file is distributed under the University of Illinois Open Source
672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// License. See LICENSE.TXT for details.
772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//===----------------------------------------------------------------------===//
972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
1072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// This program is a utility that works like "dwarfdump".
1172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
1272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//===----------------------------------------------------------------------===//
1372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/ADT/OwningPtr.h"
1572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/ADT/STLExtras.h"
16f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/ADT/Triple.h"
17f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/DebugInfo/DIContext.h"
1872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Object/ObjectFile.h"
19806e03d2381709ddfb5a8012729bbe6eae12caf5Eric Christopher#include "llvm/Object/RelocVisitor.h"
2072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/CommandLine.h"
2172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/Debug.h"
2272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/Format.h"
2372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/ManagedStatic.h"
2472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/MemoryBuffer.h"
2572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/MemoryObject.h"
2672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/PrettyStackTrace.h"
2772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/Signals.h"
2872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/raw_ostream.h"
2972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/system_error.h"
3072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include <algorithm>
3172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include <cstring>
32806e03d2381709ddfb5a8012729bbe6eae12caf5Eric Christopher#include <list>
33806e03d2381709ddfb5a8012729bbe6eae12caf5Eric Christopher#include <string>
34806e03d2381709ddfb5a8012729bbe6eae12caf5Eric Christopher
3572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerusing namespace llvm;
3672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerusing namespace object;
3772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
3872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerstatic cl::list<std::string>
3972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin KramerInputFilenames(cl::Positional, cl::desc("<input object files>"),
4072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer               cl::ZeroOrMore);
4172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
426b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramerstatic cl::opt<unsigned long long>
436b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin KramerAddress("address", cl::init(-1ULL),
446b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramer        cl::desc("Print line information for a given address"));
456b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramer
463e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonovstatic cl::opt<bool>
473e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey SamsonovPrintFunctions("functions", cl::init(false),
483e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov               cl::desc("Print function names as well as line information "
493e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov                        "for a given address"));
503e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov
515eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonovstatic cl::opt<bool>
525eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey SamsonovPrintInlining("inlining", cl::init(false),
535eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov              cl::desc("Print all inlined frames for a given address"));
545eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
555eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonovstatic void PrintDILineInfo(DILineInfo dli) {
565eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  if (PrintFunctions)
575eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    outs() << (dli.getFunctionName() ? dli.getFunctionName() : "<unknown>")
585eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov           << "\n";
595eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  outs() << (dli.getFileName() ? dli.getFileName() : "<unknown>") << ':'
605eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov         << dli.getLine() << ':' << dli.getColumn() << '\n';
615eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov}
625eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
6372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerstatic void DumpInput(const StringRef &Filename) {
6472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  OwningPtr<MemoryBuffer> Buff;
6572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
6672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {
6772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    errs() << Filename << ": " << ec.message() << "\n";
6872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return;
6972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
7072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
7172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  OwningPtr<ObjectFile> Obj(ObjectFile::createObjectFile(Buff.take()));
72d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher  OwningPtr<DIContext> dictx(DIContext::getDWARFContext(Obj.get()));
7372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
746b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramer  if (Address == -1ULL) {
756b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramer    outs() << Filename
766b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramer           << ":\tfile format " << Obj->getFileFormatName() << "\n\n";
776b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramer    // Dump the complete DWARF structure.
786b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramer    dictx->dump(outs());
796b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramer  } else {
806b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramer    // Print line info for the specified address.
815eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    int SpecFlags = DILineInfoSpecifier::FileLineInfo |
825eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov                    DILineInfoSpecifier::AbsoluteFilePath;
833e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov    if (PrintFunctions)
845eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      SpecFlags |= DILineInfoSpecifier::FunctionName;
855eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    if (PrintInlining) {
86d7169e9f067d60796269f1a77b1f10195742a453Eric Christopher      DIInliningInfo InliningInfo =
87d7169e9f067d60796269f1a77b1f10195742a453Eric Christopher        dictx->getInliningInfoForAddress(Address, SpecFlags);
885eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      uint32_t n = InliningInfo.getNumberOfFrames();
895eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      if (n == 0) {
905eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        // Print one empty debug line info in any case.
915eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        PrintDILineInfo(DILineInfo());
925eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      } else {
935eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        for (uint32_t i = 0; i < n; i++) {
945eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov          DILineInfo dli = InliningInfo.getFrame(i);
955eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov          PrintDILineInfo(dli);
965eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        }
975eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      }
985eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    } else {
995eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      DILineInfo dli = dictx->getLineInfoForAddress(Address, SpecFlags);
1005eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      PrintDILineInfo(dli);
1015eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    }
1026b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramer  }
10372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
10472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
10572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerint main(int argc, char **argv) {
10672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // Print a stack trace if we signal out.
10772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  sys::PrintStackTraceOnErrorSignal();
10872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  PrettyStackTraceProgram X(argc, argv);
10972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
11072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
11172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  cl::ParseCommandLineOptions(argc, argv, "llvm dwarf dumper\n");
11272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
11372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // Defaults to a.out if no filenames specified.
11472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (InputFilenames.size() == 0)
11572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    InputFilenames.push_back("a.out");
11672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
11772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  std::for_each(InputFilenames.begin(), InputFilenames.end(), DumpInput);
11872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
11972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return 0;
12072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
121