diff options
author | Zachary Turner <zturner@google.com> | 2015-05-06 22:26:30 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2015-05-06 22:26:30 +0000 |
commit | 43afa429082f1a90e2ca22d73456c2219ec8d774 (patch) | |
tree | 2d444ada2aa54a759fb4c05c9b0bf22d0033201d /lib/DebugInfo/PDB/PDBContext.cpp | |
parent | b6ca45c39fd1cae93225bf517cc15b72c4da9686 (diff) |
A few fixes for llvm-symbolizer on Windows.
Specifically, this patch correctly respects the -demangle option,
and additionally adds a hidden --relative-address option allows
input addresses to be relative to the module load address instead
of absolute addresses into the image.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236653 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/DebugInfo/PDB/PDBContext.cpp')
-rw-r--r-- | lib/DebugInfo/PDB/PDBContext.cpp | 70 |
1 files changed, 50 insertions, 20 deletions
diff --git a/lib/DebugInfo/PDB/PDBContext.cpp b/lib/DebugInfo/PDB/PDBContext.cpp index 328bcc65ea9..83f27c7fa3d 100644 --- a/lib/DebugInfo/PDB/PDBContext.cpp +++ b/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(); +} |