From 12999d749d722f33c3e66a4afbf1206d37e26be8 Mon Sep 17 00:00:00 2001 From: Scott Linder Date: Fri, 12 Feb 2021 18:14:44 +0000 Subject: [PATCH] [Symbolize] Teach symbolizer to work directly on object file. This patch intended to provide additional interface to LLVMsymbolizer such that they work directly on object files. There is an existing method - symbolizecode which takes an object file, this patch provides similar overloads for symbolizeInlinedCode, symbolizeData, symbolizeFrame. This can be useful for clients who already have a in-memory object files to symbolize for. Patch By: pvellien (praveen velliengiri) Reviewed By: scott.linder Differential Revision: https://reviews.llvm.org/D95232 --- llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h | 24 ++++- llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 114 +++++++++++++++------- 2 files changed, 102 insertions(+), 36 deletions(-) diff --git a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h index 1c8fa11..baff2fa 100644 --- a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -58,16 +58,25 @@ public: flush(); } + // Overloads accepting ObjectFile does not support COFF currently Expected symbolizeCode(const ObjectFile &Obj, object::SectionedAddress ModuleOffset); Expected symbolizeCode(const std::string &ModuleName, object::SectionedAddress ModuleOffset); Expected + symbolizeInlinedCode(const ObjectFile &Obj, + object::SectionedAddress ModuleOffset); + Expected symbolizeInlinedCode(const std::string &ModuleName, object::SectionedAddress ModuleOffset); + + Expected symbolizeData(const ObjectFile &Obj, + object::SectionedAddress ModuleOffset); Expected symbolizeData(const std::string &ModuleName, object::SectionedAddress ModuleOffset); Expected> + symbolizeFrame(const ObjectFile &Obj, object::SectionedAddress ModuleOffset); + Expected> symbolizeFrame(const std::string &ModuleName, object::SectionedAddress ModuleOffset); void flush(); @@ -81,9 +90,21 @@ private: // corresponding debug info. These objects can be the same. using ObjectPair = std::pair; + template Expected - symbolizeCodeCommon(SymbolizableModule *Info, + symbolizeCodeCommon(const T &ModuleSpecifier, object::SectionedAddress ModuleOffset); + template + Expected + symbolizeInlinedCodeCommon(const T &ModuleSpecifier, + object::SectionedAddress ModuleOffset); + template + Expected symbolizeDataCommon(const T &ModuleSpecifier, + object::SectionedAddress ModuleOffset); + template + Expected> + symbolizeFrameCommon(const T &ModuleSpecifier, + object::SectionedAddress ModuleOffset); /// Returns a SymbolizableModule or an error if loading debug info failed. /// Only one attempt is made to load a module, and errors during loading are @@ -91,6 +112,7 @@ private: /// failed to load will return nullptr. Expected getOrCreateModuleInfo(const std::string &ModuleName); + Expected getOrCreateModuleInfo(const ObjectFile &Obj); Expected createModuleInfo(const ObjectFile *Obj, diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index da157a5..33a2501 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -39,9 +39,17 @@ namespace llvm { namespace symbolize { +template Expected -LLVMSymbolizer::symbolizeCodeCommon(SymbolizableModule *Info, +LLVMSymbolizer::symbolizeCodeCommon(const T &ModuleSpecifier, object::SectionedAddress ModuleOffset) { + + auto InfoOrErr = getOrCreateModuleInfo(ModuleSpecifier); + if (!InfoOrErr) + return InfoOrErr.takeError(); + + SymbolizableModule *Info = *InfoOrErr; + // A null module means an error has already been reported. Return an empty // result. if (!Info) @@ -63,37 +71,24 @@ LLVMSymbolizer::symbolizeCodeCommon(SymbolizableModule *Info, Expected LLVMSymbolizer::symbolizeCode(const ObjectFile &Obj, object::SectionedAddress ModuleOffset) { - StringRef ModuleName = Obj.getFileName(); - auto I = Modules.find(ModuleName); - if (I != Modules.end()) - return symbolizeCodeCommon(I->second.get(), ModuleOffset); - - std::unique_ptr Context = DWARFContext::create(Obj); - Expected InfoOrErr = - createModuleInfo(&Obj, std::move(Context), ModuleName); - if (!InfoOrErr) - return InfoOrErr.takeError(); - return symbolizeCodeCommon(*InfoOrErr, ModuleOffset); + return symbolizeCodeCommon(Obj, ModuleOffset); } Expected LLVMSymbolizer::symbolizeCode(const std::string &ModuleName, object::SectionedAddress ModuleOffset) { - Expected InfoOrErr = getOrCreateModuleInfo(ModuleName); - if (!InfoOrErr) - return InfoOrErr.takeError(); - return symbolizeCodeCommon(*InfoOrErr, ModuleOffset); + return symbolizeCodeCommon(ModuleName, ModuleOffset); } -Expected -LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName, - object::SectionedAddress ModuleOffset) { - SymbolizableModule *Info; - if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName)) - Info = InfoOrErr.get(); - else +template +Expected LLVMSymbolizer::symbolizeInlinedCodeCommon( + const T &ModuleSpecifier, object::SectionedAddress ModuleOffset) { + auto InfoOrErr = getOrCreateModuleInfo(ModuleSpecifier); + if (!InfoOrErr) return InfoOrErr.takeError(); + SymbolizableModule *Info = *InfoOrErr; + // A null module means an error has already been reported. Return an empty // result. if (!Info) @@ -116,15 +111,28 @@ LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName, return InlinedContext; } +Expected +LLVMSymbolizer::symbolizeInlinedCode(const ObjectFile &Obj, + object::SectionedAddress ModuleOffset) { + return symbolizeInlinedCodeCommon(Obj, ModuleOffset); +} + +Expected +LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName, + object::SectionedAddress ModuleOffset) { + return symbolizeInlinedCodeCommon(ModuleName, ModuleOffset); +} + +template Expected -LLVMSymbolizer::symbolizeData(const std::string &ModuleName, - object::SectionedAddress ModuleOffset) { - SymbolizableModule *Info; - if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName)) - Info = InfoOrErr.get(); - else +LLVMSymbolizer::symbolizeDataCommon(const T &ModuleSpecifier, + object::SectionedAddress ModuleOffset) { + + auto InfoOrErr = getOrCreateModuleInfo(ModuleSpecifier); + if (!InfoOrErr) return InfoOrErr.takeError(); + SymbolizableModule *Info = *InfoOrErr; // A null module means an error has already been reported. Return an empty // result. if (!Info) @@ -142,15 +150,27 @@ LLVMSymbolizer::symbolizeData(const std::string &ModuleName, return Global; } +Expected +LLVMSymbolizer::symbolizeData(const ObjectFile &Obj, + object::SectionedAddress ModuleOffset) { + return symbolizeDataCommon(Obj, ModuleOffset); +} + +Expected +LLVMSymbolizer::symbolizeData(const std::string &ModuleName, + object::SectionedAddress ModuleOffset) { + return symbolizeDataCommon(ModuleName, ModuleOffset); +} + +template Expected> -LLVMSymbolizer::symbolizeFrame(const std::string &ModuleName, - object::SectionedAddress ModuleOffset) { - SymbolizableModule *Info; - if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName)) - Info = InfoOrErr.get(); - else +LLVMSymbolizer::symbolizeFrameCommon(const T &ModuleSpecifier, + object::SectionedAddress ModuleOffset) { + auto InfoOrErr = getOrCreateModuleInfo(ModuleSpecifier); + if (!InfoOrErr) return InfoOrErr.takeError(); + SymbolizableModule *Info = *InfoOrErr; // A null module means an error has already been reported. Return an empty // result. if (!Info) @@ -165,6 +185,18 @@ LLVMSymbolizer::symbolizeFrame(const std::string &ModuleName, return Info->symbolizeFrame(ModuleOffset); } +Expected> +LLVMSymbolizer::symbolizeFrame(const ObjectFile &Obj, + object::SectionedAddress ModuleOffset) { + return symbolizeFrameCommon(Obj, ModuleOffset); +} + +Expected> +LLVMSymbolizer::symbolizeFrame(const std::string &ModuleName, + object::SectionedAddress ModuleOffset) { + return symbolizeFrameCommon(ModuleName, ModuleOffset); +} + void LLVMSymbolizer::flush() { ObjectForUBPathAndArch.clear(); BinaryForPath.clear(); @@ -571,6 +603,18 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) { return createModuleInfo(Objects.first, std::move(Context), ModuleName); } +Expected +LLVMSymbolizer::getOrCreateModuleInfo(const ObjectFile &Obj) { + StringRef ObjName = Obj.getFileName(); + auto I = Modules.find(ObjName); + if (I != Modules.end()) + return I->second.get(); + + std::unique_ptr Context = DWARFContext::create(Obj); + // FIXME: handle COFF object with PDB info to use PDBContext + return createModuleInfo(&Obj, std::move(Context), ObjName); +} + namespace { // Undo these various manglings for Win32 extern "C" functions: -- 2.7.4