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();
// 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
/// 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,
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)
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)
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)
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)
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();
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: