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