forked from OSchip/llvm-project
[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
This commit is contained in:
parent
4841a225b7
commit
12999d749d
|
@ -58,16 +58,25 @@ public:
|
|||
flush();
|
||||
}
|
||||
|
||||
// Overloads accepting ObjectFile does not support COFF currently
|
||||
Expected<DILineInfo> symbolizeCode(const ObjectFile &Obj,
|
||||
object::SectionedAddress ModuleOffset);
|
||||
Expected<DILineInfo> symbolizeCode(const std::string &ModuleName,
|
||||
object::SectionedAddress ModuleOffset);
|
||||
Expected<DIInliningInfo>
|
||||
symbolizeInlinedCode(const ObjectFile &Obj,
|
||||
object::SectionedAddress ModuleOffset);
|
||||
Expected<DIInliningInfo>
|
||||
symbolizeInlinedCode(const std::string &ModuleName,
|
||||
object::SectionedAddress ModuleOffset);
|
||||
|
||||
Expected<DIGlobal> symbolizeData(const ObjectFile &Obj,
|
||||
object::SectionedAddress ModuleOffset);
|
||||
Expected<DIGlobal> symbolizeData(const std::string &ModuleName,
|
||||
object::SectionedAddress ModuleOffset);
|
||||
Expected<std::vector<DILocal>>
|
||||
symbolizeFrame(const ObjectFile &Obj, object::SectionedAddress ModuleOffset);
|
||||
Expected<std::vector<DILocal>>
|
||||
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<const ObjectFile *, const ObjectFile *>;
|
||||
|
||||
template <typename T>
|
||||
Expected<DILineInfo>
|
||||
symbolizeCodeCommon(SymbolizableModule *Info,
|
||||
symbolizeCodeCommon(const T &ModuleSpecifier,
|
||||
object::SectionedAddress ModuleOffset);
|
||||
template <typename T>
|
||||
Expected<DIInliningInfo>
|
||||
symbolizeInlinedCodeCommon(const T &ModuleSpecifier,
|
||||
object::SectionedAddress ModuleOffset);
|
||||
template <typename T>
|
||||
Expected<DIGlobal> symbolizeDataCommon(const T &ModuleSpecifier,
|
||||
object::SectionedAddress ModuleOffset);
|
||||
template <typename T>
|
||||
Expected<std::vector<DILocal>>
|
||||
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<SymbolizableModule *>
|
||||
getOrCreateModuleInfo(const std::string &ModuleName);
|
||||
Expected<SymbolizableModule *> getOrCreateModuleInfo(const ObjectFile &Obj);
|
||||
|
||||
Expected<SymbolizableModule *>
|
||||
createModuleInfo(const ObjectFile *Obj,
|
||||
|
|
|
@ -39,9 +39,17 @@
|
|||
namespace llvm {
|
||||
namespace symbolize {
|
||||
|
||||
template <typename T>
|
||||
Expected<DILineInfo>
|
||||
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<DILineInfo>
|
||||
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<DIContext> Context = DWARFContext::create(Obj);
|
||||
Expected<SymbolizableModule *> InfoOrErr =
|
||||
createModuleInfo(&Obj, std::move(Context), ModuleName);
|
||||
if (!InfoOrErr)
|
||||
return InfoOrErr.takeError();
|
||||
return symbolizeCodeCommon(*InfoOrErr, ModuleOffset);
|
||||
return symbolizeCodeCommon(Obj, ModuleOffset);
|
||||
}
|
||||
|
||||
Expected<DILineInfo>
|
||||
LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
|
||||
object::SectionedAddress ModuleOffset) {
|
||||
Expected<SymbolizableModule *> InfoOrErr = getOrCreateModuleInfo(ModuleName);
|
||||
if (!InfoOrErr)
|
||||
return InfoOrErr.takeError();
|
||||
return symbolizeCodeCommon(*InfoOrErr, ModuleOffset);
|
||||
return symbolizeCodeCommon(ModuleName, ModuleOffset);
|
||||
}
|
||||
|
||||
Expected<DIInliningInfo>
|
||||
LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName,
|
||||
object::SectionedAddress ModuleOffset) {
|
||||
SymbolizableModule *Info;
|
||||
if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName))
|
||||
Info = InfoOrErr.get();
|
||||
else
|
||||
template <typename T>
|
||||
Expected<DIInliningInfo> 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<DIInliningInfo>
|
||||
LLVMSymbolizer::symbolizeInlinedCode(const ObjectFile &Obj,
|
||||
object::SectionedAddress ModuleOffset) {
|
||||
return symbolizeInlinedCodeCommon(Obj, ModuleOffset);
|
||||
}
|
||||
|
||||
Expected<DIInliningInfo>
|
||||
LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName,
|
||||
object::SectionedAddress ModuleOffset) {
|
||||
return symbolizeInlinedCodeCommon(ModuleName, ModuleOffset);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Expected<DIGlobal>
|
||||
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<DIGlobal>
|
||||
LLVMSymbolizer::symbolizeData(const ObjectFile &Obj,
|
||||
object::SectionedAddress ModuleOffset) {
|
||||
return symbolizeDataCommon(Obj, ModuleOffset);
|
||||
}
|
||||
|
||||
Expected<DIGlobal>
|
||||
LLVMSymbolizer::symbolizeData(const std::string &ModuleName,
|
||||
object::SectionedAddress ModuleOffset) {
|
||||
return symbolizeDataCommon(ModuleName, ModuleOffset);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Expected<std::vector<DILocal>>
|
||||
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<std::vector<DILocal>>
|
||||
LLVMSymbolizer::symbolizeFrame(const ObjectFile &Obj,
|
||||
object::SectionedAddress ModuleOffset) {
|
||||
return symbolizeFrameCommon(Obj, ModuleOffset);
|
||||
}
|
||||
|
||||
Expected<std::vector<DILocal>>
|
||||
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<SymbolizableModule *>
|
||||
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<DIContext> 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:
|
||||
|
|
Loading…
Reference in New Issue