llvm.org GIT mirror llvm / 9d74bda
[PDB] Support executables and source/line info. Previously DebugInfoPDB could only load data for a PDB given a path to the PDB. It could not open an EXE and find the matching PDB and verify it matched, etc. This patch adds support for that so that we can simply load debug information for a PDB directly. Additionally, this patch extends DebugInfoPDB to support getting source and line information for symbols. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235237 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 4 years ago
8 changed file(s) with 106 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
2020
2121 static PDB_ErrorCode createFromPdb(StringRef Path,
2222 std::unique_ptr &Session);
23 static PDB_ErrorCode createFromExe(StringRef Path,
24 std::unique_ptr &Session);
2325
2426 uint64_t getLoadAddress() const override;
2527 void setLoadAddress(uint64_t Address) override;
2628 std::unique_ptr getGlobalScope() const override;
2729 std::unique_ptr getSymbolById(uint32_t SymbolId) const override;
30
31 std::unique_ptr
32 findSymbolByAddress(uint64_t Address) const override;
33 std::unique_ptr
34 findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override;
2835
2936 std::unique_ptr getAllSourceFiles() const override;
3037 std::unique_ptr getSourceFilesForCompiland(
4242 return std::unique_ptr(ConcreteSymbol);
4343 }
4444
45 virtual std::unique_ptr
46 findSymbolByAddress(uint64_t Address) const = 0;
47 virtual std::unique_ptr
48 findLineNumbersByAddress(uint64_t Address, uint32_t Length) const = 0;
49
4550 virtual std::unique_ptr getAllSourceFiles() const = 0;
4651 virtual std::unique_ptr
4752 getSourceFilesForCompiland(const PDBSymbolCompiland &Compiland) const = 0;
1515 namespace llvm {
1616 class StringRef;
1717
18 PDB_ErrorCode createPDBReader(PDB_ReaderType Type, StringRef Path,
19 std::unique_ptr &Session);
18 PDB_ErrorCode loadDataForPDB(PDB_ReaderType Type, StringRef Path,
19 std::unique_ptr &Session);
20
21 PDB_ErrorCode loadDataForEXE(PDB_ReaderType Type, StringRef Path,
22 std::unique_ptr &Session);
2023 }
2124
2225 #endif
2020
2121 class IPDBDataStream;
2222 template class IPDBEnumChildren;
23 class IPDBLineNumber;
2324 class IPDBRawSymbol;
2425 class IPDBSession;
2526 class IPDBSourceFile;
2728 typedef IPDBEnumChildren IPDBEnumSymbols;
2829 typedef IPDBEnumChildren IPDBEnumSourceFiles;
2930 typedef IPDBEnumChildren IPDBEnumDataStreams;
31 typedef IPDBEnumChildren IPDBEnumLineNumbers;
3032
3133 class PDBSymbolExe;
3234 class PDBSymbolCompiland;
425427 InvalidParameter,
426428 AlreadyLoaded,
427429 UnknownError,
428 NoMemory
430 NoMemory,
431 DebugInfoMismatch
429432 };
430433
431434 struct VersionInfo {
88
99 #include "llvm/ADT/STLExtras.h"
1010 #include "llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h"
11 #include "llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h"
1112 #include "llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h"
1213 #include "llvm/DebugInfo/PDB/DIA/DIARawSymbol.h"
1314 #include "llvm/DebugInfo/PDB/DIA/DIASession.h"
6364 return PDB_ErrorCode::Success;
6465 }
6566
67 PDB_ErrorCode DIASession::createFromExe(StringRef Path,
68 std::unique_ptr &Session) {
69 CComPtr DiaDataSource;
70 CComPtr DiaSession;
71
72 // We assume that CoInitializeEx has already been called by the executable.
73 HRESULT Result = ::CoCreateInstance(
74 CLSID_DiaSource, nullptr, CLSCTX_INPROC_SERVER, IID_IDiaDataSource,
75 reinterpret_cast(&DiaDataSource));
76 if (FAILED(Result))
77 return PDB_ErrorCode::NoPdbImpl;
78
79 llvm::SmallVector Path16;
80 if (!llvm::convertUTF8ToUTF16String(Path, Path16))
81 return PDB_ErrorCode::InvalidPath;
82
83 const wchar_t *Path16Str = reinterpret_cast(Path16.data());
84 if (FAILED(Result =
85 DiaDataSource->loadDataForExe(Path16Str, nullptr, nullptr))) {
86 if (Result == E_PDB_NOT_FOUND)
87 return PDB_ErrorCode::InvalidPath;
88 else if (Result == E_PDB_FORMAT)
89 return PDB_ErrorCode::InvalidFileFormat;
90 else if (Result == E_PDB_INVALID_SIG || Result == E_PDB_INVALID_AGE)
91 return PDB_ErrorCode::DebugInfoMismatch;
92 else if (Result == E_INVALIDARG)
93 return PDB_ErrorCode::InvalidParameter;
94 else if (Result == E_UNEXPECTED)
95 return PDB_ErrorCode::AlreadyLoaded;
96 else
97 return PDB_ErrorCode::UnknownError;
98 }
99
100 if (FAILED(Result = DiaDataSource->openSession(&DiaSession))) {
101 if (Result == E_OUTOFMEMORY)
102 return PDB_ErrorCode::NoMemory;
103 else
104 return PDB_ErrorCode::UnknownError;
105 }
106
107 Session.reset(new DIASession(DiaSession));
108 return PDB_ErrorCode::Success;
109 }
110
66111 uint64_t DIASession::getLoadAddress() const {
67112 uint64_t LoadAddress;
68113 bool success = (S_OK == Session->get_loadAddress(&LoadAddress));
92137
93138 auto RawSymbol = llvm::make_unique(*this, LocatedSymbol);
94139 return PDBSymbol::create(*this, std::move(RawSymbol));
140 }
141
142 std::unique_ptr
143 DIASession::findSymbolByAddress(uint64_t Address) const {
144 CComPtr Symbol;
145 if (S_OK != Session->findSymbolByVA(Address, SymTagNull, &Symbol))
146 return nullptr;
147 auto RawSymbol = llvm::make_unique(*this, Symbol);
148 return PDBSymbol::create(*this, std::move(RawSymbol));
149 }
150
151 std::unique_ptr
152 DIASession::findLineNumbersByAddress(uint64_t Address, uint32_t Length) const {
153 CComPtr LineNumbers;
154 if (S_OK != Session->findLinesByVA(Address, Length, &LineNumbers))
155 return nullptr;
156
157 return llvm::make_unique(LineNumbers);
95158 }
96159
97160 std::unique_ptr DIASession::getAllSourceFiles() const {
1919
2020 using namespace llvm;
2121
22 PDB_ErrorCode llvm::createPDBReader(PDB_ReaderType Type, StringRef Path,
23 std::unique_ptr &Session) {
22 PDB_ErrorCode llvm::loadDataForPDB(PDB_ReaderType Type, StringRef Path,
23 std::unique_ptr &Session) {
2424 // Create the correct concrete instance type based on the value of Type.
2525 #if HAVE_DIA_SDK
2626 return DIASession::createFromPdb(Path, Session);
2727 #endif
2828 return PDB_ErrorCode::NoPdbImpl;
2929 }
30
31 PDB_ErrorCode llvm::loadDataForEXE(PDB_ReaderType Type, StringRef Path,
32 std::unique_ptr &Session) {
33 // Create the correct concrete instance type based on the value of Type.
34 #if HAVE_DIA_SDK
35 return DIASession::createFromExe(Path, Session);
36 #endif
37 return PDB_ErrorCode::NoPdbImpl;
38 }
100100 static void dumpInput(StringRef Path) {
101101 std::unique_ptr Session;
102102 PDB_ErrorCode Error =
103 llvm::createPDBReader(PDB_ReaderType::DIA, Path, Session);
103 llvm::loadDataForPDB(PDB_ReaderType::DIA, Path, Session);
104104 switch (Error) {
105105 case PDB_ErrorCode::Success:
106106 break;
7171 getSourceFileById(uint32_t SymbolId) const override {
7272 return nullptr;
7373 }
74
75 std::unique_ptr
76 findSymbolByAddress(uint64_t Address) const override {
77 return nullptr;
78 }
79 std::unique_ptr
80 findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override {
81 return nullptr;
82 }
83
7484 std::unique_ptr getAllSourceFiles() const override {
7585 return nullptr;
7686 }