LLVM: lib/DebugInfo/PDB/DIA/DIASession.cpp Source File (original) (raw)

1

2

3

4

5

6

7

29

30using namespace llvm;

32

33template <typename... Ts>

37 if (sizeof...(Args) > 0) {

38 MessageStorage = formatv(Str, std::forward(Args)...).str();

39 Context = MessageStorage;

40 } else

41 Context = Str;

42

43 switch (Result) {

44 case E_PDB_NOT_FOUND:

45 return errorCodeToError(std::error_code(ENOENT, std::generic_category()));

46 case E_PDB_FORMAT:

48 case E_INVALIDARG:

50 case E_UNEXPECTED:

52 case E_PDB_INVALID_SIG:

53 case E_PDB_INVALID_AGE:

55 default: {

56 std::string S;

58 OS << "HRESULT: " << format_hex(static_cast<DWORD>(Result), 10, true)

59 << ": " << Context;

61 }

62 }

63}

64

65static Error LoadDIA(CComPtr &DiaDataSource) {

66 if (SUCCEEDED(CoCreateInstance(CLSID_DiaSource, nullptr, CLSCTX_INPROC_SERVER,

67 IID_IDiaDataSource,

68 reinterpret_cast<LPVOID *>(&DiaDataSource))))

70

71

72

73#if !defined(_MSC_VER)

75#else

76 const wchar_t *msdia_dll = L"msdia140.dll";

77 HRESULT HR;

78 if (FAILED(HR = NoRegCoCreate(msdia_dll, CLSID_DiaSource, IID_IDiaDataSource,

79 reinterpret_cast<LPVOID *>(&DiaDataSource))))

82#endif

83}

84

86

88 std::unique_ptr &Session) {

89 CComPtr DiaDataSource;

90 CComPtr DiaSession;

91

92

93 if (auto E = LoadDIA(DiaDataSource))

94 return E;

95

99

100 const wchar_t *Path16Str = reinterpret_cast<const wchar_t *>(Path16.data());

101 HRESULT HR;

102 if (FAILED(HR = DiaDataSource->loadDataFromPdb(Path16Str))) {

104 }

105

106 if (FAILED(HR = DiaDataSource->openSession(&DiaSession)))

108

109 Session.reset(new DIASession(DiaSession));

111}

112

114 std::unique_ptr &Session) {

115 CComPtr DiaDataSource;

116 CComPtr DiaSession;

117

118

119 if (auto EC = LoadDIA(DiaDataSource))

120 return EC;

121

125

126 const wchar_t *Path16Str = reinterpret_cast<const wchar_t *>(Path16.data());

127 HRESULT HR;

128 if (FAILED(HR = DiaDataSource->loadDataForExe(Path16Str, nullptr, nullptr)))

130

131 if (FAILED(HR = DiaDataSource->openSession(&DiaSession)))

133

134 Session.reset(new DIASession(DiaSession));

136}

137

140 bool success = (S_OK == Session->get_loadAddress(&LoadAddress));

141 return (success) ? LoadAddress : 0;

142}

143

145 return (S_OK == Session->put_loadAddress(Address));

146}

147

149 CComPtr GlobalScope;

150 if (S_OK != Session->get_globalScope(&GlobalScope))

151 return nullptr;

152

153 auto RawSymbol = std::make_unique(*this, GlobalScope);

155 std::unique_ptr ExeSymbol(

156 static_cast<PDBSymbolExe *>(PdbSymbol.release()));

157 return ExeSymbol;

158}

159

162 DWORD ArgSection, ArgOffset = 0;

163 if (S_OK == Session->addressForVA(VA, &ArgSection, &ArgOffset)) {

164 Section = static_cast<uint32_t>(ArgSection);

166 return true;

167 }

168 return false;

169}

170

173 DWORD ArgSection, ArgOffset = 0;

174 if (S_OK == Session->addressForRVA(RVA, &ArgSection, &ArgOffset)) {

175 Section = static_cast<uint32_t>(ArgSection);

177 return true;

178 }

179 return false;

180}

181

182std::unique_ptr

184 CComPtr LocatedSymbol;

185 if (S_OK != Session->symbolById(SymbolId, &LocatedSymbol))

186 return nullptr;

187

188 auto RawSymbol = std::make_unique(*this, LocatedSymbol);

190}

191

194 enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type);

195

196 CComPtr Symbol;

197 if (S_OK != Session->findSymbolByVA(Address, EnumVal, &Symbol)) {

198 ULONGLONG LoadAddr = 0;

199 if (S_OK != Session->get_loadAddress(&LoadAddr))

200 return nullptr;

201 DWORD RVA = static_cast<DWORD>(Address - LoadAddr);

202 if (S_OK != Session->findSymbolByRVA(RVA, EnumVal, &Symbol))

203 return nullptr;

204 }

205 auto RawSymbol = std::make_unique(*this, Symbol);

207}

208

211 enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type);

212

213 CComPtr Symbol;

214 if (S_OK != Session->findSymbolByRVA(RVA, EnumVal, &Symbol))

215 return nullptr;

216

217 auto RawSymbol = std::make_unique(*this, Symbol);

219}

220

221std::unique_ptr

224 enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type);

225

226 CComPtr Symbol;

227 if (S_OK != Session->findSymbolByAddr(Sect, Offset, EnumVal, &Symbol))

228 return nullptr;

229

230 auto RawSymbol = std::make_unique(*this, Symbol);

232}

233

234std::unique_ptr

240

241 CComPtr LineNumbers;

242 if (S_OK != Session->findLines(RawCompiland.getDiaSymbol(),

244 return nullptr;

245

246 return std::make_unique(LineNumbers);

247}

248

249std::unique_ptr

251 CComPtr LineNumbers;

253 ULONGLONG LoadAddr = 0;

254 if (S_OK != Session->get_loadAddress(&LoadAddr))

255 return nullptr;

256 DWORD RVA = static_cast<DWORD>(Address - LoadAddr);

258 return nullptr;

259 }

260 return std::make_unique(LineNumbers);

261}

262

263std::unique_ptr

265 CComPtr LineNumbers;

267 return nullptr;

268

269 return std::make_unique(LineNumbers);

270}

271

272std::unique_ptr

275 CComPtr LineNumbers;

277 return nullptr;

278

279 return std::make_unique(LineNumbers);

280}

281

282std::unique_ptr

286 IDiaSymbol *DiaCompiland = nullptr;

287 CComBSTR Utf16Pattern;

289 Utf16Pattern = CComBSTR(Pattern.data());

290

294

297 CComPtr SourceFiles;

298 if (S_OK !=

299 Session->findFile(DiaCompiland, Utf16Pattern.m_str, Flags, &SourceFiles))

300 return nullptr;

301 return std::make_unique(*this, SourceFiles);

302}

303

304std::unique_ptr

313

314std::unique_ptr<IPDBEnumChildren>

318 if (!File)

319 return nullptr;

320 return File->getCompilands();

321}

322

323std::unique_ptr

327 if (!Compilands || Compilands->getChildCount() == 0)

328 return nullptr;

329 return Compilands->getNext();

330}

331

333 CComPtr Files;

334 if (S_OK != Session->findFile(nullptr, nullptr, nsNone, &Files))

335 return nullptr;

336

337 return std::make_unique(*this, Files);

338}

339

342 CComPtr Files;

343

346 if (S_OK !=

347 Session->findFile(RawSymbol.getDiaSymbol(), nullptr, nsNone, &Files))

348 return nullptr;

349

350 return std::make_unique(*this, Files);

351}

352

353std::unique_ptr

355 CComPtr LocatedFile;

356 if (S_OK != Session->findFileById(FileId, &LocatedFile))

357 return nullptr;

358

359 return std::make_unique(*this, LocatedFile);

360}

361

363 CComPtr DiaEnumerator;

364 if (S_OK != Session->getEnumDebugStreams(&DiaEnumerator))

365 return nullptr;

366

367 return std::make_unique(DiaEnumerator);

368}

369

371 CComPtr DiaEnumerator;

372 if (S_OK != Session->getEnumTables(&DiaEnumerator))

373 return nullptr;

374

375 return std::make_unique(DiaEnumerator);

376}

377

380 CComPtr ET;

381 CComPtr Table;

383

384 if (Session.getEnumTables(&ET) != S_OK)

385 return nullptr;

386

387 while (ET->Next(1, &Table, &Count) == S_OK && Count == 1) {

388

389 if (S_OK == Table->QueryInterface(__uuidof(T), (void **)&Enumerator))

390 break;

391 Table.Release();

392 }

394}

395std::unique_ptr

397 CComPtr Files =

399 if (!Files)

400 return nullptr;

401

402 return std::make_unique(Files);

403}

404

405std::unique_ptr

407 CComPtr Sections =

409 if (!Sections)

410 return nullptr;

411

412 return std::make_unique(*this, Sections);

413}

414

415std::unique_ptr

417 CComPtr FD =

419 if (!FD)

420 return nullptr;

421

422 return std::make_unique(FD);

423}

static Error ErrorFromHResult(HRESULT Result, const char *Str, Ts &&... Args)

Definition DIASession.cpp:34

static CComPtr< T > getTableEnumerator(IDiaSession &Session)

Definition DIASession.cpp:378

static Error LoadDIA(CComPtr< IDiaDataSource > &DiaDataSource)

Definition DIASession.cpp:65

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

StringRef str() const

Explicit conversion to StringRef.

pointer data()

Return a pointer to the vector's buffer, even if empty().

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringRef - Represent a constant reference to a string, i.e.

CComPtr< IDiaSymbol > getDiaSymbol() const

std::unique_ptr< IPDBSourceFile > findOneSourceFile(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const override

Definition DIASession.cpp:305

std::unique_ptr< IPDBEnumSourceFiles > findSourceFiles(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const override

Definition DIASession.cpp:283

std::unique_ptr< IPDBEnumLineNumbers > findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const override

Definition DIASession.cpp:264

std::unique_ptr< IPDBEnumSourceFiles > getSourceFilesForCompiland(const PDBSymbolCompiland &Compiland) const override

Definition DIASession.cpp:340

std::unique_ptr< IPDBEnumLineNumbers > findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override

Definition DIASession.cpp:250

static Error createFromExe(StringRef Path, std::unique_ptr< IPDBSession > &Session)

Definition DIASession.cpp:113

uint64_t getLoadAddress() const override

Definition DIASession.cpp:138

std::unique_ptr< IPDBEnumSourceFiles > getAllSourceFiles() const override

Definition DIASession.cpp:332

bool addressForVA(uint64_t VA, uint32_t &Section, uint32_t &Offset) const override

Definition DIASession.cpp:160

std::unique_ptr< PDBSymbolExe > getGlobalScope() override

Definition DIASession.cpp:148

std::unique_ptr< PDBSymbol > findSymbolByAddress(uint64_t Address, PDB_SymType Type) override

Definition DIASession.cpp:192

std::unique_ptr< IPDBEnumInjectedSources > getInjectedSources() const override

Definition DIASession.cpp:396

std::unique_ptr< PDBSymbolCompiland > findOneCompilandForSourceFile(llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const override

Definition DIASession.cpp:324

DIASession(CComPtr< IDiaSession > DiaSession)

Definition DIASession.cpp:85

std::unique_ptr< IPDBEnumChildren< PDBSymbolCompiland > > findCompilandsForSourceFile(llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const override

Definition DIASession.cpp:315

bool setLoadAddress(uint64_t Address) override

Definition DIASession.cpp:144

static Error createFromPdb(StringRef Path, std::unique_ptr< IPDBSession > &Session)

Definition DIASession.cpp:87

std::unique_ptr< IPDBEnumLineNumbers > findLineNumbers(const PDBSymbolCompiland &Compiland, const IPDBSourceFile &File) const override

Definition DIASession.cpp:235

std::unique_ptr< IPDBEnumDataStreams > getDebugStreams() const override

Definition DIASession.cpp:362

bool addressForRVA(uint32_t RVA, uint32_t &Section, uint32_t &Offset) const override

Definition DIASession.cpp:171

std::unique_ptr< PDBSymbol > getSymbolById(SymIndexId SymbolId) const override

Definition DIASession.cpp:183

std::unique_ptr< IPDBSourceFile > getSourceFileById(uint32_t FileId) const override

Definition DIASession.cpp:354

std::unique_ptr< IPDBEnumFrameData > getFrameData() const override

Definition DIASession.cpp:416

std::unique_ptr< IPDBEnumLineNumbers > findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset, uint32_t Length) const override

Definition DIASession.cpp:273

std::unique_ptr< PDBSymbol > findSymbolByRVA(uint32_t RVA, PDB_SymType Type) override

Definition DIASession.cpp:209

std::unique_ptr< IPDBEnumTables > getEnumTables() const override

Definition DIASession.cpp:370

std::unique_ptr< PDBSymbol > findSymbolBySectOffset(uint32_t Section, uint32_t Offset, PDB_SymType Type) override

Definition DIASession.cpp:222

std::unique_ptr< IPDBEnumSectionContribs > getSectionContribs() const override

Definition DIASession.cpp:406

CComPtr< IDiaSourceFile > getDiaFile() const

IPDBSourceFile defines an interface used to represent source files whose information are stored in th...

static std::unique_ptr< PDBSymbol > create(const IPDBSession &PDBSession, std::unique_ptr< IPDBRawSymbol > RawSymbol)

A raw_ostream that writes to an std::string.

std::string & str()

Returns the string's reference.

PDB_NameSearchFlags

Defines flags used for enumerating child symbols.

PDB_SymType

These values correspond to the SymTagEnum enumeration, and are documented here: https://msdn....

This is an optimization pass for GlobalISel generic memory operations.

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

FunctionAddr VTableAddr Count

FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)

format_hex - Output N as a fixed width hexadecimal.

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

LLVM_ABI Error errorCodeToError(std::error_code EC)

Helper for converting an std::error_code to a Error.

LLVM_ABI bool convertUTF8ToUTF16String(StringRef SrcUTF8, SmallVectorImpl< UTF16 > &DstUTF16)

Converts a UTF-8 string into a UTF-16 string with native endianness.

LogicalResult success(bool IsSuccess=true)

Utility function to generate a LogicalResult.