llvm-dwarfdump.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
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/STLExtras.h"
15f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/ADT/Triple.h"
16f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/DebugInfo/DIContext.h"
1772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Object/ObjectFile.h"
18806e03d2381709ddfb5a8012729bbe6eae12caf5Eric Christopher#include "llvm/Object/RelocVisitor.h"
1972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/CommandLine.h"
2072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/Debug.h"
2172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/Format.h"
2272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/ManagedStatic.h"
2372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/MemoryBuffer.h"
2472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/MemoryObject.h"
2572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/PrettyStackTrace.h"
2672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/Signals.h"
2772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/raw_ostream.h"
2872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/system_error.h"
2972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include <algorithm>
3072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include <cstring>
31806e03d2381709ddfb5a8012729bbe6eae12caf5Eric Christopher#include <list>
32806e03d2381709ddfb5a8012729bbe6eae12caf5Eric Christopher#include <string>
33806e03d2381709ddfb5a8012729bbe6eae12caf5Eric Christopher
3472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerusing namespace llvm;
3572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerusing namespace object;
3672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
3772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerstatic cl::list<std::string>
3872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin KramerInputFilenames(cl::Positional, cl::desc("<input object files>"),
3972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer               cl::ZeroOrMore);
4072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
416b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramerstatic cl::opt<unsigned long long>
426b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin KramerAddress("address", cl::init(-1ULL),
436b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramer        cl::desc("Print line information for a given address"));
446b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramer
453e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonovstatic cl::opt<bool>
463e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey SamsonovPrintFunctions("functions", cl::init(false),
473e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov               cl::desc("Print function names as well as line information "
483e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov                        "for a given address"));
493e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov
505eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonovstatic cl::opt<bool>
515eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey SamsonovPrintInlining("inlining", cl::init(false),
525eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov              cl::desc("Print all inlined frames for a given address"));
535eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
54939a4e8b693820d161f362317f7dba9057e66cc7Eli Benderskystatic cl::opt<DIDumpType>
55939a4e8b693820d161f362317f7dba9057e66cc7Eli BenderskyDumpType("debug-dump", cl::init(DIDT_All),
56939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  cl::desc("Dump of debug sections:"),
57939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  cl::values(
58939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky        clEnumValN(DIDT_All, "all", "Dump all debug sections"),
59939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky        clEnumValN(DIDT_Abbrev, "abbrev", ".debug_abbrev"),
60939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky        clEnumValN(DIDT_AbbrevDwo, "abbrev.dwo", ".debug_abbrev.dwo"),
61939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky        clEnumValN(DIDT_Aranges, "aranges", ".debug_aranges"),
62939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky        clEnumValN(DIDT_Info, "info", ".debug_info"),
63939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky        clEnumValN(DIDT_InfoDwo, "info.dwo", ".debug_info.dwo"),
6426efdc5621043d28dc0c78addc7b7a75d1591a10David Blaikie        clEnumValN(DIDT_Types, "types", ".debug_types"),
6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        clEnumValN(DIDT_TypesDwo, "types.dwo", ".debug_types.dwo"),
66939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky        clEnumValN(DIDT_Line, "line", ".debug_line"),
6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        clEnumValN(DIDT_LineDwo, "line.dwo", ".debug_line.dwo"),
683df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie        clEnumValN(DIDT_Loc, "loc", ".debug_loc"),
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        clEnumValN(DIDT_LocDwo, "loc.dwo", ".debug_loc.dwo"),
7060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky        clEnumValN(DIDT_Frames, "frames", ".debug_frame"),
71939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky        clEnumValN(DIDT_Ranges, "ranges", ".debug_ranges"),
72e38825f490b898644089d5cd9cb90cec681bded8Krzysztof Parzyszek        clEnumValN(DIDT_Pubnames, "pubnames", ".debug_pubnames"),
737357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher        clEnumValN(DIDT_Pubtypes, "pubtypes", ".debug_pubtypes"),
74498ffb8a568992d613e654ddec69b04d350aec20Eric Christopher        clEnumValN(DIDT_GnuPubnames, "gnu_pubnames", ".debug_gnu_pubnames"),
75498ffb8a568992d613e654ddec69b04d350aec20Eric Christopher        clEnumValN(DIDT_GnuPubtypes, "gnu_pubtypes", ".debug_gnu_pubtypes"),
76939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky        clEnumValN(DIDT_Str, "str", ".debug_str"),
77939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky        clEnumValN(DIDT_StrDwo, "str.dwo", ".debug_str.dwo"),
78939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky        clEnumValN(DIDT_StrOffsetsDwo, "str_offsets.dwo", ".debug_str_offsets.dwo"),
79939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky        clEnumValEnd));
80939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky
815eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonovstatic void PrintDILineInfo(DILineInfo dli) {
825eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  if (PrintFunctions)
835eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    outs() << (dli.getFunctionName() ? dli.getFunctionName() : "<unknown>")
845eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov           << "\n";
855eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  outs() << (dli.getFileName() ? dli.getFileName() : "<unknown>") << ':'
865eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov         << dli.getLine() << ':' << dli.getColumn() << '\n';
875eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov}
885eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
8972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerstatic void DumpInput(const StringRef &Filename) {
9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<MemoryBuffer> Buff;
9172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
9272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {
9372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    errs() << Filename << ": " << ec.message() << "\n";
9472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return;
9572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
9672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ErrorOr<ObjectFile*> ObjOrErr(ObjectFile::createObjectFile(Buff.release()));
9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (error_code EC = ObjOrErr.getError()) {
9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    errs() << Filename << ": " << EC.message() << '\n';
100a965baca3c7ce1ced00446cff1c6395d03dfed52Eli Bendersky    return;
101a965baca3c7ce1ced00446cff1c6395d03dfed52Eli Bendersky  }
10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<ObjectFile> Obj(ObjOrErr.get());
103a965baca3c7ce1ced00446cff1c6395d03dfed52Eli Bendersky
10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<DIContext> DICtx(DIContext::getDWARFContext(Obj.get()));
10572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1066b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramer  if (Address == -1ULL) {
1076b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramer    outs() << Filename
1086b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramer           << ":\tfile format " << Obj->getFileFormatName() << "\n\n";
1096b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramer    // Dump the complete DWARF structure.
110939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    DICtx->dump(outs(), DumpType);
1116b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramer  } else {
1126b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramer    // Print line info for the specified address.
1135eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    int SpecFlags = DILineInfoSpecifier::FileLineInfo |
1145eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov                    DILineInfoSpecifier::AbsoluteFilePath;
1153e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov    if (PrintFunctions)
1165eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      SpecFlags |= DILineInfoSpecifier::FunctionName;
1175eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    if (PrintInlining) {
118d7169e9f067d60796269f1a77b1f10195742a453Eric Christopher      DIInliningInfo InliningInfo =
119172d5978c835377307f80b2845f1f11276f5ec24Eli Bendersky        DICtx->getInliningInfoForAddress(Address, SpecFlags);
1205eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      uint32_t n = InliningInfo.getNumberOfFrames();
1215eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      if (n == 0) {
1225eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        // Print one empty debug line info in any case.
1235eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        PrintDILineInfo(DILineInfo());
1245eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      } else {
1255eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        for (uint32_t i = 0; i < n; i++) {
1265eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov          DILineInfo dli = InliningInfo.getFrame(i);
1275eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov          PrintDILineInfo(dli);
1285eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        }
1295eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      }
1305eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    } else {
131172d5978c835377307f80b2845f1f11276f5ec24Eli Bendersky      DILineInfo dli = DICtx->getLineInfoForAddress(Address, SpecFlags);
1325eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      PrintDILineInfo(dli);
1335eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    }
1346b3ae4638bc5a3fb3bad286f96a1234b8a53053aBenjamin Kramer  }
13572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
13672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
13772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerint main(int argc, char **argv) {
13872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // Print a stack trace if we signal out.
13972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  sys::PrintStackTraceOnErrorSignal();
14072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  PrettyStackTraceProgram X(argc, argv);
14172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
14272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
14372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  cl::ParseCommandLineOptions(argc, argv, "llvm dwarf dumper\n");
14472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
14572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // Defaults to a.out if no filenames specified.
14672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (InputFilenames.size() == 0)
14772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    InputFilenames.push_back("a.out");
14872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
14972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  std::for_each(InputFilenames.begin(), InputFilenames.end(), DumpInput);
15072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
15172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return 0;
15272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
153