summaryrefslogtreecommitdiff
path: root/lib/DebugInfo/PDB/PDBContext.cpp
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2015-05-06 22:26:30 +0000
committerZachary Turner <zturner@google.com>2015-05-06 22:26:30 +0000
commit43afa429082f1a90e2ca22d73456c2219ec8d774 (patch)
tree2d444ada2aa54a759fb4c05c9b0bf22d0033201d /lib/DebugInfo/PDB/PDBContext.cpp
parentb6ca45c39fd1cae93225bf517cc15b72c4da9686 (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.cpp70
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();
+}