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