Index: include/llvm/DebugInfo/DWARF/DIContext.h =================================================================== --- include/llvm/DebugInfo/DWARF/DIContext.h +++ include/llvm/DebugInfo/DWARF/DIContext.h @@ -63,6 +63,10 @@ void addFrame(const DILineInfo &Frame) { Frames.push_back(Frame); } + void setFrame(unsigned Index, const DILineInfo &Frame) { + assert(Index < Frames.size()); + Frames[Index] = Frame; + } }; /// A DINameKind is passed to name search methods to specify a Index: tools/llvm-symbolizer/CMakeLists.txt =================================================================== --- tools/llvm-symbolizer/CMakeLists.txt +++ tools/llvm-symbolizer/CMakeLists.txt @@ -5,11 +5,14 @@ set(LLVM_LINK_COMPONENTS DebugInfoDWARF + DebugInfoPDB Object Support ) add_llvm_tool(llvm-symbolizer + SymbolizationContextPDB.cpp + SymbolizationContextDWARF.cpp LLVMSymbolize.cpp llvm-symbolizer.cpp ) Index: tools/llvm-symbolizer/LLVMSymbolize.h =================================================================== --- tools/llvm-symbolizer/LLVMSymbolize.h +++ tools/llvm-symbolizer/LLVMSymbolize.h @@ -13,19 +13,21 @@ #ifndef LLVM_TOOLS_LLVM_SYMBOLIZER_LLVMSYMBOLIZE_H #define LLVM_TOOLS_LLVM_SYMBOLIZER_LLVMSYMBOLIZE_H +#include "SymbolizationContext.h" +#include "SymbolizerOptions.h" + #include "llvm/ADT/SmallVector.h" -#include "llvm/DebugInfo/DWARF/DIContext.h" #include "llvm/Object/MachOUniversal.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/MemoryBuffer.h" + #include #include #include namespace llvm { -typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind; using namespace object; namespace symbolize { @@ -34,23 +36,8 @@ class LLVMSymbolizer { public: - struct Options { - bool UseSymbolTable : 1; - FunctionNameKind PrintFunctions; - bool PrintInlining : 1; - bool Demangle : 1; - std::string DefaultArch; - std::vector DsymHints; - Options(bool UseSymbolTable = true, - FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName, - bool PrintInlining = true, bool Demangle = true, - std::string DefaultArch = "") - : UseSymbolTable(UseSymbolTable), - PrintFunctions(PrintFunctions), PrintInlining(PrintInlining), - Demangle(Demangle), DefaultArch(DefaultArch) {} - }; - - LLVMSymbolizer(const Options &Opts = Options()) : Opts(Opts) {} + LLVMSymbolizer(const SymbolizerOptions &Opts = SymbolizerOptions()) + : Opts(Opts) {} ~LLVMSymbolizer() { flush(); } @@ -63,9 +50,12 @@ symbolizeData(const std::string &ModuleName, uint64_t ModuleOffset); void flush(); static std::string DemangleName(const std::string &Name); + static const char kBadString[]; + private: typedef std::pair ObjectPair; + SymbolizationContext *createSymbolizationContext(const ObjectFile &Obj) const; ModuleInfo *getOrCreateModuleInfo(const std::string &ModuleName); ObjectFile *lookUpDsymFile(const std::string &Path, const MachOObjectFile *ExeObj, const std::string &ArchName); @@ -77,7 +67,8 @@ /// universal binary (or the binary itself if it is an object file). ObjectFile *getObjectFileFromBinary(Binary *Bin, const std::string &ArchName); - std::string printDILineInfo(DILineInfo LineInfo) const; + std::string + printLineInfo(const llvm::symbolize::SymbolizedLineInfo &LineInfo) const; // Owns all the parsed binaries and object files. SmallVector, 4> ParsedBinariesAndObjects; @@ -97,18 +88,18 @@ std::map, ObjectPair> ObjectPairForPathArch; - Options Opts; - static const char kBadString[]; + SymbolizerOptions Opts; }; class ModuleInfo { public: - ModuleInfo(ObjectFile *Obj, DIContext *DICtx); + ModuleInfo(ObjectFile *Obj, llvm::symbolize::SymbolizationContext *Context); - DILineInfo symbolizeCode(uint64_t ModuleOffset, - const LLVMSymbolizer::Options &Opts) const; - DIInliningInfo symbolizeInlinedCode( - uint64_t ModuleOffset, const LLVMSymbolizer::Options &Opts) const; + std::unique_ptr + symbolizeCode(uint64_t ModuleOffset, const SymbolizerOptions &Opts) const; + std::unique_ptr + symbolizeInlinedCode(uint64_t ModuleOffset, + const SymbolizerOptions &Opts) const; bool symbolizeData(uint64_t ModuleOffset, std::string &Name, uint64_t &Start, uint64_t &Size) const; @@ -122,7 +113,7 @@ DataExtractor *OpdExtractor = nullptr, uint64_t OpdAddress = 0); ObjectFile *Module; - std::unique_ptr DebugInfoContext; + std::unique_ptr DebugInfoContext; struct SymbolDesc { uint64_t Addr; Index: tools/llvm-symbolizer/LLVMSymbolize.cpp =================================================================== --- tools/llvm-symbolizer/LLVMSymbolize.cpp +++ tools/llvm-symbolizer/LLVMSymbolize.cpp @@ -12,8 +12,14 @@ //===----------------------------------------------------------------------===// #include "LLVMSymbolize.h" +#include "SymbolizationContext.h" +#include "SymbolizationContextDWARF.h" +#include "SymbolizationContextPDB.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Config/config.h" +#include "llvm/DebugInfo/DWARF/DIContext.h" +#include "llvm/DebugInfo/PDB/IPDBSession.h" +#include "llvm/DebugInfo/PDB/PDB.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/MachO.h" #include "llvm/Support/Casting.h" @@ -36,15 +42,8 @@ return true; } -static DILineInfoSpecifier -getDILineInfoSpecifier(const LLVMSymbolizer::Options &Opts) { - return DILineInfoSpecifier( - DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, - Opts.PrintFunctions); -} - -ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx) - : Module(Obj), DebugInfoContext(DICtx) { +ModuleInfo::ModuleInfo(ObjectFile *Obj, SymbolizationContext *Ctx) + : Module(Obj), DebugInfoContext(Ctx) { std::unique_ptr OpdExtractor; uint64_t OpdAddress = 0; // Find the .opd (function descriptor) section if any, for big-endian @@ -141,52 +140,56 @@ return true; } -DILineInfo ModuleInfo::symbolizeCode( - uint64_t ModuleOffset, const LLVMSymbolizer::Options &Opts) const { - DILineInfo LineInfo; +std::unique_ptr +ModuleInfo::symbolizeCode(uint64_t ModuleOffset, + const SymbolizerOptions &Opts) const { + std::unique_ptr LineInfo; if (DebugInfoContext) { - LineInfo = DebugInfoContext->getLineInfoForAddress( - ModuleOffset, getDILineInfoSpecifier(Opts)); + LineInfo = DebugInfoContext->getLineInfoForAddress(ModuleOffset, Opts); } // Override function name from symbol table if necessary. - if (Opts.PrintFunctions != FunctionNameKind::None && Opts.UseSymbolTable) { + if (Opts.PrintFunctions != SymbolizerOptions::FunctionNameKind::None && + Opts.UseSymbolTable) { std::string FunctionName; uint64_t Start, Size; if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset, FunctionName, Start, Size)) { - LineInfo.FunctionName = FunctionName; + LineInfo->setFunctionName(FunctionName); } } return LineInfo; } -DIInliningInfo ModuleInfo::symbolizeInlinedCode( - uint64_t ModuleOffset, const LLVMSymbolizer::Options &Opts) const { - DIInliningInfo InlinedContext; - if (DebugInfoContext) { - InlinedContext = DebugInfoContext->getInliningInfoForAddress( - ModuleOffset, getDILineInfoSpecifier(Opts)); - } +std::unique_ptr +ModuleInfo::symbolizeInlinedCode(uint64_t ModuleOffset, + const SymbolizerOptions &Opts) const { + std::unique_ptr InlinedContext; + if (!DebugInfoContext) + return nullptr; + + InlinedContext = + DebugInfoContext->getInliningInfoForAddress(ModuleOffset, Opts); + if (!InlinedContext) + return nullptr; + // Make sure there is at least one frame in context. - if (InlinedContext.getNumberOfFrames() == 0) { - InlinedContext.addFrame(DILineInfo()); + if (InlinedContext->getNumberOfFrames() == 0) { + InlinedContext->addExplicitFrame(); } // Override the function name in lower frame with name from symbol table. - if (Opts.PrintFunctions != FunctionNameKind::None && Opts.UseSymbolTable) { - DIInliningInfo PatchedInlinedContext; - for (uint32_t i = 0, n = InlinedContext.getNumberOfFrames(); i < n; i++) { - DILineInfo LineInfo = InlinedContext.getFrame(i); - if (i == n - 1) { - std::string FunctionName; - uint64_t Start, Size; - if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset, - FunctionName, Start, Size)) { - LineInfo.FunctionName = FunctionName; - } - } - PatchedInlinedContext.addFrame(LineInfo); + if (Opts.PrintFunctions != SymbolizerOptions::FunctionNameKind::None && + Opts.UseSymbolTable) { + std::string FunctionName; + uint64_t Start, Size; + if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset, + FunctionName, Start, Size)) { + + int LastFrame = InlinedContext->getNumberOfFrames() - 1; + std::unique_ptr LowerFrame = + InlinedContext->getFrame(LastFrame); + LowerFrame->setFunctionName(FunctionName); + InlinedContext->setFrame(LastFrame, *LowerFrame); } - InlinedContext = PatchedInlinedContext; } return InlinedContext; } @@ -203,21 +206,27 @@ uint64_t ModuleOffset) { ModuleInfo *Info = getOrCreateModuleInfo(ModuleName); if (!Info) - return printDILineInfo(DILineInfo()); + return printLineInfo(NullLineInfo()); + if (Opts.PrintInlining) { - DIInliningInfo InlinedContext = + std::unique_ptr InlinedContext = Info->symbolizeInlinedCode(ModuleOffset, Opts); - uint32_t FramesNum = InlinedContext.getNumberOfFrames(); + if (!InlinedContext) + return printLineInfo(NullLineInfo()); + + uint32_t FramesNum = InlinedContext->getNumberOfFrames(); assert(FramesNum > 0); std::string Result; for (uint32_t i = 0; i < FramesNum; i++) { - DILineInfo LineInfo = InlinedContext.getFrame(i); - Result += printDILineInfo(LineInfo); + std::unique_ptr LineInfo = + InlinedContext->getFrame(i); + Result += printLineInfo(*LineInfo); } return Result; } - DILineInfo LineInfo = Info->symbolizeCode(ModuleOffset, Opts); - return printDILineInfo(LineInfo); + std::unique_ptr LineInfo = + Info->symbolizeCode(ModuleOffset, Opts); + return printLineInfo(*LineInfo); } std::string LLVMSymbolizer::symbolizeData(const std::string &ModuleName, @@ -437,6 +446,19 @@ return Res; } +SymbolizationContext * +LLVMSymbolizer::createSymbolizationContext(const ObjectFile &Obj) const { + std::unique_ptr PDBSession; + llvm::PDB_ErrorCode PDBError = + llvm::createPDBReader(PDB_ReaderType::DIA, Obj.getFileName(), PDBSession); + if (PDBError == PDB_ErrorCode::Success) { + return new SymbolizationContextPDB(PDBSession); + } else { + std::unique_ptr Context(DIContext::getDWARFContext(Obj)); + return new SymbolizationContextDWARF(std::move(Context)); + } +} + ModuleInfo * LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) { const auto &I = Modules.find(ModuleName); @@ -460,30 +482,32 @@ Modules.insert(make_pair(ModuleName, (ModuleInfo *)nullptr)); return nullptr; } - DIContext *Context = DIContext::getDWARFContext(*Objects.second); + SymbolizationContext *Context = createSymbolizationContext(*Objects.second); assert(Context); ModuleInfo *Info = new ModuleInfo(Objects.first, Context); Modules.insert(make_pair(ModuleName, Info)); return Info; } -std::string LLVMSymbolizer::printDILineInfo(DILineInfo LineInfo) const { - // By default, DILineInfo contains "" for function/filename it - // cannot fetch. We replace it to "??" to make our output closer to addr2line. - static const std::string kDILineInfoBadString = ""; +std::string +LLVMSymbolizer::printLineInfo(const SymbolizedLineInfo &LineInfo) const { + // If there is an error fetching function/filename, we replace it to "??" to + // make + // our output closer to addr2line. std::stringstream Result; - if (Opts.PrintFunctions != FunctionNameKind::None) { - std::string FunctionName = LineInfo.FunctionName; - if (FunctionName == kDILineInfoBadString) + if (Opts.PrintFunctions != SymbolizerOptions::FunctionNameKind::None) { + std::string FunctionName = LineInfo.getFunctionName(); + if (FunctionName.empty()) FunctionName = kBadString; else if (Opts.Demangle) FunctionName = DemangleName(FunctionName); Result << FunctionName << "\n"; } - std::string Filename = LineInfo.FileName; - if (Filename == kDILineInfoBadString) + std::string Filename = LineInfo.getFileName(); + if (Filename.empty()) Filename = kBadString; - Result << Filename << ":" << LineInfo.Line << ":" << LineInfo.Column << "\n"; + Result << Filename << ":" << LineInfo.getLineNumber() << ":" + << LineInfo.getColumn() << "\n"; return Result.str(); } Index: tools/llvm-symbolizer/SymbolizationContext.h =================================================================== --- /dev/null +++ tools/llvm-symbolizer/SymbolizationContext.h @@ -0,0 +1,75 @@ +//===-- SymbolizationContext.h ---------------------------------- C++ -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Header for LLVM symbolization context, abstracting away the differences +// between symbolization strategies via different types of debug information. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_TOOLS_LLVM_SYMBOLIZER_SYMBOLIZATIONCONTEXT_H +#define LLVM_TOOLS_LLVM_SYMBOLIZER_SYMBOLIZATIONCONTEXT_H + +#include +#include +#include + +namespace llvm { +namespace symbolize { + +struct SymbolizerOptions; + +class SymbolizedLineInfo { +public: + virtual ~SymbolizedLineInfo() {} + + virtual std::string getFileName() const = 0; + virtual std::string getFunctionName() const = 0; + virtual uint32_t getLineNumber() const = 0; + virtual uint32_t getColumn() const = 0; + + virtual void setFunctionName(const std::string &name) = 0; +}; + +class NullLineInfo : public SymbolizedLineInfo { +public: + std::string getFileName() const override { return ""; } + std::string getFunctionName() const override { return ""; } + uint32_t getLineNumber() const override { return 0; } + uint32_t getColumn() const override { return 0; } + + void setFunctionName(const std::string &name) override {} +}; + +class SymbolizedInliningInfo { +public: + virtual ~SymbolizedInliningInfo() {} + + virtual uint32_t getNumberOfFrames() const = 0; + virtual void addExplicitFrame() = 0; + virtual void addExplicitFrame(const SymbolizedLineInfo &Frame) = 0; + + virtual std::unique_ptr + getFrame(uint32_t Index) const = 0; + virtual void setFrame(uint32_t Index, const SymbolizedLineInfo &Frame) = 0; +}; + +class SymbolizationContext { +public: + virtual ~SymbolizationContext() {} + + virtual std::unique_ptr + getLineInfoForAddress(uint64_t ModuleOffset, + const SymbolizerOptions &Opts) = 0; + virtual std::unique_ptr + getInliningInfoForAddress(uint64_t ModuleOffset, + const SymbolizerOptions &Opts) = 0; +}; +} +} + +#endif Index: tools/llvm-symbolizer/SymbolizationContextDWARF.h =================================================================== --- /dev/null +++ tools/llvm-symbolizer/SymbolizationContextDWARF.h @@ -0,0 +1,75 @@ +//===-- SymbolizationContextDWARF.h ----------------------------- C++ -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Header for PDB symbolization context, used to symbolize with DWARF debug +// information. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_TOOLS_LLVM_SYMBOLIZER_SYMBOLIZATIONCONTEXTDWARF_H +#define LLVM_TOOLS_LLVM_SYMBOLIZER_SYMBOLIZATIONCONTEXTDWARF_H + +#include "SymbolizationContext.h" +#include "llvm/DebugInfo/DWARF/DIContext.h" + +namespace llvm { +namespace symbolize { + +class SymbolizedLineInfoDWARF : public SymbolizedLineInfo { +public: + explicit SymbolizedLineInfoDWARF(const DILineInfo &Info) : LineInfo(Info) {} + virtual ~SymbolizedLineInfoDWARF() {} + + std::string getFileName() const override; + std::string getFunctionName() const override; + uint32_t getLineNumber() const override; + uint32_t getColumn() const override; + + void setFunctionName(const std::string &name) override; + +private: + DILineInfo LineInfo; +}; + +class SymbolizedInliningInfoDWARF : public SymbolizedInliningInfo { +public: + explicit SymbolizedInliningInfoDWARF(const DIInliningInfo &Info) + : InliningInfo(Info) {} + virtual ~SymbolizedInliningInfoDWARF() {} + + uint32_t getNumberOfFrames() const override; + void addExplicitFrame() override; + void addExplicitFrame(const SymbolizedLineInfo &Frame) override; + + std::unique_ptr getFrame(uint32_t Index) const override; + void setFrame(uint32_t Index, const SymbolizedLineInfo &Frame) override; + +private: + DIInliningInfo InliningInfo; +}; + +class SymbolizationContextDWARF : public SymbolizationContext { +public: + explicit SymbolizationContextDWARF(std::unique_ptr Context) + : DebugContext(std::move(Context)) {} + virtual ~SymbolizationContextDWARF() {} + + std::unique_ptr + getLineInfoForAddress(uint64_t ModuleOffset, + const SymbolizerOptions &Opts) override; + std::unique_ptr + getInliningInfoForAddress(uint64_t ModuleOffset, + const SymbolizerOptions &Opts) override; + +private: + std::unique_ptr DebugContext; +}; +} +} + +#endif Index: tools/llvm-symbolizer/SymbolizationContextDWARF.cpp =================================================================== --- /dev/null +++ tools/llvm-symbolizer/SymbolizationContextDWARF.cpp @@ -0,0 +1,116 @@ +//===-- SymbolizationContextDWARF.cpp --------------------------- C++ -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Implementation file for PDB symbolization context, used to symbolize with +// Microsoft PDB debug information. +// +//===----------------------------------------------------------------------===// + +#include "SymbolizationContextDWARF.h" +#include "SymbolizerOptions.h" + +#include "llvm/ADT/STLExtras.h" + +using namespace llvm; +using namespace llvm::symbolize; + +static const std::string kDILineInfoBadString = ""; + +static void getDILineInfoSpecifier(const SymbolizerOptions &Opts, + DILineInfoSpecifier &Specifier) { + Specifier.FLIKind = DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath; + Specifier.FNKind = DILineInfoSpecifier::FunctionNameKind::None; + + if (Opts.PrintFunctions == SymbolizerOptions::FunctionNameKind::None) + Specifier.FNKind = DILineInfoSpecifier::FunctionNameKind::None; + else if (Opts.PrintFunctions == + SymbolizerOptions::FunctionNameKind::LinkageName) + Specifier.FNKind = DILineInfoSpecifier::FunctionNameKind::LinkageName; + else if (Opts.PrintFunctions == + SymbolizerOptions::FunctionNameKind::ShortName) + Specifier.FNKind = DILineInfoSpecifier::FunctionNameKind::ShortName; +} + +std::string SymbolizedLineInfoDWARF::getFileName() const { + if (LineInfo.FileName == kDILineInfoBadString) + return std::string(); + return LineInfo.FileName; +} + +std::string SymbolizedLineInfoDWARF::getFunctionName() const { + if (LineInfo.FunctionName == kDILineInfoBadString) + return std::string(); + return LineInfo.FunctionName; +} + +uint32_t SymbolizedLineInfoDWARF::getLineNumber() const { + return LineInfo.Line; +} + +uint32_t SymbolizedLineInfoDWARF::getColumn() const { return LineInfo.Column; } + +void SymbolizedLineInfoDWARF::setFunctionName(const std::string &Name) { + LineInfo.FunctionName = Name; +} + +uint32_t SymbolizedInliningInfoDWARF::getNumberOfFrames() const { + return InliningInfo.getNumberOfFrames(); +} + +void SymbolizedInliningInfoDWARF::addExplicitFrame() { + InliningInfo.addFrame(DILineInfo()); +} + +void SymbolizedInliningInfoDWARF::addExplicitFrame( + const SymbolizedLineInfo &Frame) { + DILineInfo DIFrame; + DIFrame.Column = Frame.getColumn(); + DIFrame.FileName = Frame.getFileName(); + DIFrame.FunctionName = Frame.getFunctionName(); + DIFrame.Line = Frame.getLineNumber(); + InliningInfo.addFrame(DIFrame); +} + +std::unique_ptr +SymbolizedInliningInfoDWARF::getFrame(uint32_t Index) const { + DILineInfo Frame = InliningInfo.getFrame(Index); + return llvm::make_unique(Frame); +} + +void SymbolizedInliningInfoDWARF::setFrame(uint32_t Index, + const SymbolizedLineInfo &Frame) { + DILineInfo DIFrame; + DIFrame.Column = Frame.getColumn(); + DIFrame.FileName = Frame.getFileName(); + DIFrame.FunctionName = Frame.getFunctionName(); + DIFrame.Line = Frame.getLineNumber(); + InliningInfo.setFrame(Index, DIFrame); +} + +std::unique_ptr +SymbolizationContextDWARF::getLineInfoForAddress( + uint64_t ModuleOffset, const SymbolizerOptions &Opts) { + DILineInfoSpecifier Specifier; + getDILineInfoSpecifier(Opts, Specifier); + + DILineInfo Result = + DebugContext->getLineInfoForAddress(ModuleOffset, Specifier); + return llvm::make_unique(Result); +} + +std::unique_ptr +SymbolizationContextDWARF::getInliningInfoForAddress( + uint64_t ModuleOffset, const SymbolizerOptions &Opts) { + DILineInfoSpecifier Specifier; + getDILineInfoSpecifier(Opts, Specifier); + + DIInliningInfo Result = + DebugContext->getInliningInfoForAddress(ModuleOffset, Specifier); + return llvm::make_unique(Result); +} Index: tools/llvm-symbolizer/SymbolizationContextPDB.h =================================================================== --- /dev/null +++ tools/llvm-symbolizer/SymbolizationContextPDB.h @@ -0,0 +1,65 @@ +//===-- SymbolizationContextPDB.h ------------------------------- C++ -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Header for PDB symbolization context, used to symbolize with Microsoft PDB +// debug information. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_TOOLS_LLVM_SYMBOLIZER_SYMBOLIZATIONCONTEXTPDB_H +#define LLVM_TOOLS_LLVM_SYMBOLIZER_SYMBOLIZATIONCONTEXTPDB_H + +#include "SymbolizationContext.h" + +#include "llvm/DebugInfo/PDB/IPDBSession.h" +#include "llvm/DebugInfo/PDB/PDB.h" + +namespace llvm { +namespace symbolize { + +class SymbolizedLineInfoPDB : public SymbolizedLineInfo { +public: + virtual ~SymbolizedLineInfoPDB() {} + + virtual std::string getFileName() const = 0; + virtual uint32_t getLineNumber() const = 0; + virtual uint32_t getColumn() const = 0; +}; + +class SymbolizedInliningInfoPDB : public SymbolizedInliningInfo { +public: + virtual ~SymbolizedInliningInfoPDB() {} + + uint32_t getNumberOfFrames() const override; + void addExplicitFrame() override; + void addExplicitFrame(const SymbolizedLineInfo &Frame) override; + + std::unique_ptr getFrame(uint32_t Index) const override; + void setFrame(uint32_t Index, const SymbolizedLineInfo &Frame) override; +}; + +class SymbolizationContextPDB : public SymbolizationContext { +public: + explicit SymbolizationContextPDB(std::unique_ptr &PDBSession) + : Session(std::move(PDBSession)) {} + virtual ~SymbolizationContextPDB() {} + + std::unique_ptr + getLineInfoForAddress(uint64_t ModuleOffset, + const SymbolizerOptions &Opts) override; + std::unique_ptr + getInliningInfoForAddress(uint64_t ModuleOffset, + const SymbolizerOptions &Opts) override; + +private: + std::unique_ptr Session; +}; +} +} + +#endif Index: tools/llvm-symbolizer/SymbolizationContextPDB.cpp =================================================================== --- /dev/null +++ tools/llvm-symbolizer/SymbolizationContextPDB.cpp @@ -0,0 +1,51 @@ +//===-- SymbolizationContextPDB.cpp ----------------------------- C++ -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Implementation file for PDB symbolization context, used to symbolize with +// Microsoft PDB debug information. +// +//===----------------------------------------------------------------------===// + +#include "SymbolizationContextPDB.h" + +using namespace llvm; +using namespace llvm::symbolize; + +std::string SymbolizedLineInfoPDB::getFileName() const { return ""; } + +uint32_t SymbolizedLineInfoPDB::getLineNumber() const { return 0; } + +uint32_t SymbolizedLineInfoPDB::getColumn() const { return 0; } + +uint32_t SymbolizedInliningInfoPDB::getNumberOfFrames() const { return 0; } + +void SymbolizedInliningInfoPDB::addExplicitFrame() {} + +void SymbolizedInliningInfoPDB::addExplicitFrame( + const SymbolizedLineInfo &Frame) {} + +std::unique_ptr +SymbolizedInliningInfoPDB::getFrame(uint32_t Index) const { + return nullptr; +} + +void SymbolizedInliningInfoPDB::setFrame(uint32_t Index, + const SymbolizedLineInfo &Frame) {} + +std::unique_ptr +SymbolizationContextPDB::getLineInfoForAddress(uint64_t ModuleOffset, + const SymbolizerOptions &Opts) { + return nullptr; +} + +std::unique_ptr +SymbolizationContextPDB::getInliningInfoForAddress( + uint64_t ModuleOffset, const SymbolizerOptions &Opts) { + return nullptr; +} Index: tools/llvm-symbolizer/SymbolizerOptions.h =================================================================== --- /dev/null +++ tools/llvm-symbolizer/SymbolizerOptions.h @@ -0,0 +1,44 @@ +//===-- SymbolizerOptions.h ------------------------------------- C++ -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Options class definition for LLVMSymbolizer. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_TOOLS_LLVM_SYMBOLIZER_SYMBOLIZEROPTIONS_H +#define LLVM_TOOLS_LLVM_SYMBOLIZER_SYMBOLIZEROPTIONS_H + +#include + +namespace llvm { +namespace symbolize { +struct SymbolizerOptions { + // We reproduce the DWARF enum here, because llvm-symbolizer supports other + // types of debug information than DWARF, so we can't rely on implementation + // specific enums. + enum class FunctionNameKind { None, ShortName, LinkageName }; + + bool UseSymbolTable : 1; + bool PrintInlining : 1; + bool Demangle : 1; + FunctionNameKind PrintFunctions; + std::string DefaultArch; + std::vector DsymHints; + SymbolizerOptions( + bool UseSymbolTable = true, + FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName, + bool PrintInlining = true, bool Demangle = true, + std::string DefaultArch = "") + : UseSymbolTable(UseSymbolTable), PrintInlining(PrintInlining), + Demangle(Demangle), PrintFunctions(PrintFunctions), + DefaultArch(DefaultArch) {} +}; +} +} + +#endif Index: tools/llvm-symbolizer/llvm-symbolizer.cpp =================================================================== --- tools/llvm-symbolizer/llvm-symbolizer.cpp +++ tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -16,6 +16,7 @@ //===----------------------------------------------------------------------===// #include "LLVMSymbolize.h" +#include "SymbolizerOptions.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -37,14 +38,15 @@ cl::desc("Prefer names in symbol table to names " "in debug info")); -static cl::opt ClPrintFunctions( - "functions", cl::init(FunctionNameKind::LinkageName), +static cl::opt ClPrintFunctions( + "functions", cl::init(SymbolizerOptions::FunctionNameKind::LinkageName), cl::desc("Print function name for a given address:"), - cl::values(clEnumValN(FunctionNameKind::None, "none", "omit function name"), - clEnumValN(FunctionNameKind::ShortName, "short", - "print short function name"), - clEnumValN(FunctionNameKind::LinkageName, "linkage", - "print function linkage name"), + cl::values(clEnumValN(SymbolizerOptions::FunctionNameKind::None, "none", + "omit function name"), + clEnumValN(SymbolizerOptions::FunctionNameKind::ShortName, + "short", "print short function name"), + clEnumValN(SymbolizerOptions::FunctionNameKind::LinkageName, + "linkage", "print function linkage name"), clEnumValEnd)); static cl::opt @@ -124,8 +126,8 @@ llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. cl::ParseCommandLineOptions(argc, argv, "llvm-symbolizer\n"); - LLVMSymbolizer::Options Opts(ClUseSymbolTable, ClPrintFunctions, - ClPrintInlining, ClDemangle, ClDefaultArch); + SymbolizerOptions Opts(ClUseSymbolTable, ClPrintFunctions, ClPrintInlining, + ClDemangle, ClDefaultArch); for (const auto &hint : ClDsymHint) { if (sys::path::extension(hint) == ".dSYM") { Opts.DsymHints.push_back(hint);