diff options
Diffstat (limited to 'llvm/lib/DebugInfo/PDB/PDBContext.cpp')
-rw-r--r-- | llvm/lib/DebugInfo/PDB/PDBContext.cpp | 70 |
1 files changed, 50 insertions, 20 deletions
diff --git a/llvm/lib/DebugInfo/PDB/PDBContext.cpp b/llvm/lib/DebugInfo/PDB/PDBContext.cpp index 328bcc65ea9..83f27c7fa3d 100644 --- a/llvm/lib/DebugInfo/PDB/PDBContext.cpp +++ b/llvm/lib/DebugInfo/PDB/PDBContext.cpp @@ -14,43 +14,44 @@ #include "llvm/DebugInfo/PDB/PDBSymbol.h" #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" #include "llvm/DebugInfo/PDB/PDBSymbolData.h" +#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h" #include "llvm/Object/COFF.h" using namespace llvm; using namespace llvm::object; PDBContext::PDBContext(const COFFObjectFile &Object, - std::unique_ptr<IPDBSession> PDBSession) + std::unique_ptr<IPDBSession> PDBSession, + bool RelativeAddress) : DIContext(CK_PDB), Session(std::move(PDBSession)) { - uint64_t ImageBase = 0; - if (Object.is64()) { - const pe32plus_header *Header = nullptr; - Object.getPE32PlusHeader(Header); - if (Header) - ImageBase = Header->ImageBase; - } else { - const pe32_header *Header = nullptr; - Object.getPE32Header(Header); - if (Header) - ImageBase = static_cast<uint64_t>(Header->ImageBase); + if (!RelativeAddress) { + uint64_t ImageBase = 0; + if (Object.is64()) { + const pe32plus_header *Header = nullptr; + Object.getPE32PlusHeader(Header); + if (Header) + ImageBase = Header->ImageBase; + } else { + const pe32_header *Header = nullptr; + Object.getPE32Header(Header); + if (Header) + ImageBase = static_cast<uint64_t>(Header->ImageBase); + } + Session->setLoadAddress(ImageBase); } - Session->setLoadAddress(ImageBase); } void PDBContext::dump(raw_ostream &OS, DIDumpType DumpType) {} DILineInfo PDBContext::getLineInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier) { - auto Symbol = Session->findSymbolByAddress(Address, PDB_SymType::None); + DILineInfo Result; + Result.FunctionName = getFunctionName(Address, Specifier.FNKind); uint32_t Length = 1; - DILineInfo Result; + std::unique_ptr<PDBSymbol> Symbol = + Session->findSymbolByAddress(Address, PDB_SymType::None); if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(Symbol.get())) { - if (Specifier.FNKind == DINameKind::LinkageName) - Result.FunctionName = Func->getUndecoratedName(); - else if (Specifier.FNKind == DINameKind::ShortName) - Result.FunctionName = Func->getName(); - Length = Func->getLength(); } else if (auto Data = dyn_cast_or_null<PDBSymbolData>(Symbol.get())) { Length = Data->getLength(); @@ -101,3 +102,32 @@ PDBContext::getInliningInfoForAddress(uint64_t Address, InlineInfo.addFrame(Frame); return InlineInfo; } + +std::string PDBContext::getFunctionName(uint64_t Address, + DINameKind NameKind) const { + if (NameKind == DINameKind::None) + return std::string(); + + if (NameKind == DINameKind::LinkageName) { + // It is not possible to get the mangled linkage name through a + // PDBSymbolFunc. For that we have to specifically request a + // PDBSymbolPublicSymbol. + auto PublicSym = + Session->findSymbolByAddress(Address, PDB_SymType::PublicSymbol); + if (auto PS = dyn_cast_or_null<PDBSymbolPublicSymbol>(PublicSym.get())) + return PS->getName(); + } + + auto FuncSymbol = + Session->findSymbolByAddress(Address, PDB_SymType::Function); + + // This could happen either if there was no public symbol (e.g. not + // external) or the user requested the short name. In the former case, + // although they technically requested the linkage name, if the linkage + // name is not available we fallback to at least returning a non-empty + // string. + if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(FuncSymbol.get())) + return Func->getName(); + + return std::string(); +} |