LLVM: lib/DebugInfo/PDB/Native/PDBFile.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

28#include

29#include

30#include

31

32using namespace llvm;

36

37namespace {

39}

40

43 : FilePath(std::string(Path)), Allocator(Allocator),

44 Buffer(std::move(PdbFileBuffer)) {}

45

47

49

53

55

57 return ContainerLayout.SB->FreeBlockMapBlock;

58}

59

61 return ContainerLayout.SB->NumBlocks;

62}

63

65 return ContainerLayout.SB->NumDirectoryBytes;

66}

67

69 return ContainerLayout.SB->BlockMapAddr;

70}

71

73

76 ContainerLayout.SB->BlockSize);

77}

78

80 return (uint64_t)ContainerLayout.SB->BlockMapAddr *

81 ContainerLayout.SB->BlockSize;

82}

83

85 return ContainerLayout.StreamSizes.size();

86}

87

91

93 return ContainerLayout.StreamSizes[StreamIndex];

94}

95

98 return ContainerLayout.StreamMap[StreamIndex];

99}

100

102

106

108 if (auto EC = Buffer->readBytes(StreamBlockOffset, NumBytes, Result))

109 return std::move(EC);

110 return Result;

111}

112

116 "PDBFile is immutable");

117}

118

121

122

127 "MSF superblock is missing");

128 }

129

131 return EC;

132

133 if (Buffer->getLength() % SB->BlockSize != 0)

135 "File size is not a multiple of block size");

136 ContainerLayout.SB = SB;

137

138

139 ContainerLayout.FreePageMap.resize(SB->NumBlocks);

140

141

142

143

144

145

146

147

148

149

150

151

152

153 auto FpmStream =

158 return EC;

161 for (auto Byte : FpmBytes) {

162 uint32_t BlocksThisByte = std::min(BlocksRemaining, 8U);

163 for (uint32_t I = 0; I < BlocksThisByte; ++I) {

164 if (Byte & (1 << I))

165 ContainerLayout.FreePageMap[BI] = true;

166 --BlocksRemaining;

167 ++BI;

168 }

169 }

170

172 if (auto EC = Reader.readArray(ContainerLayout.DirectoryBlocks,

174 return EC;

175

177}

178

180 assert(ContainerLayout.SB);

181 if (DirectoryStream)

183

185

186

187

188

189

190

192 Allocator);

195 return EC;

196

197 if (auto EC = Reader.readArray(ContainerLayout.StreamSizes, NumStreams))

198 return EC;

199 for (uint32_t I = 0; I < NumStreams; ++I) {

201

202 uint64_t NumExpectedStreamBlocks =

203 StreamSize == UINT32_MAX

204 ? 0

206

207

208

209

210

211

212

214 if (auto EC = Reader.readArray(Blocks, NumExpectedStreamBlocks))

215 return EC;

218 (uint64_t)(Block + 1) * ContainerLayout.SB->BlockSize;

221 "Stream block map is corrupt.");

222 }

223 ContainerLayout.StreamMap.push_back(Blocks);

224 }

225

226

228 DirectoryStream = std::move(DS);

230}

231

233 return ContainerLayout.DirectoryBlocks;

234}

235

236std::unique_ptr

239 return nullptr;

241 Allocator);

242}

243

247 Result.Blocks.assign(Blocks.begin(), Blocks.end());

249 return Result;

250}

251

255

257 if (!Globals) {

259 if (!DbiS)

260 return DbiS.takeError();

261

262 auto GlobalS =

264 if (!GlobalS)

265 return GlobalS.takeError();

266 auto TempGlobals = std::make_unique(std::move(*GlobalS));

267 if (auto EC = TempGlobals->reload())

268 return std::move(EC);

269 Globals = std::move(TempGlobals);

270 }

271 return *Globals;

272}

273

275 if (!Info) {

277 if (!InfoS)

278 return InfoS.takeError();

279 auto TempInfo = std::make_unique(std::move(*InfoS));

280 if (auto EC = TempInfo->reload())

281 return std::move(EC);

282 Info = std::move(TempInfo);

283 }

284 return *Info;

285}

286

288 if (!Dbi) {

290 if (!DbiS)

291 return DbiS.takeError();

292 auto TempDbi = std::make_unique(std::move(*DbiS));

293 if (auto EC = TempDbi->reload(this))

294 return std::move(EC);

295 Dbi = std::move(TempDbi);

296 }

297 return *Dbi;

298}

299

301 if (!Tpi) {

303 if (!TpiS)

304 return TpiS.takeError();

305 auto TempTpi = std::make_unique(*this, std::move(*TpiS));

306 if (auto EC = TempTpi->reload())

307 return std::move(EC);

308 Tpi = std::move(TempTpi);

309 }

310 return *Tpi;

311}

312

314 if (!Ipi) {

317

319 if (!IpiS)

320 return IpiS.takeError();

321 auto TempIpi = std::make_unique(*this, std::move(*IpiS));

322 if (auto EC = TempIpi->reload())

323 return std::move(EC);

324 Ipi = std::move(TempIpi);

325 }

326 return *Ipi;

327}

328

330 if (!Publics) {

332 if (!DbiS)

333 return DbiS.takeError();

334

335 auto PublicS =

337 if (!PublicS)

338 return PublicS.takeError();

339 auto TempPublics = std::make_unique(std::move(*PublicS));

340 if (auto EC = TempPublics->reload())

341 return std::move(EC);

342 Publics = std::move(TempPublics);

343 }

344 return *Publics;

345}

346

348 if (!Symbols) {

350 if (!DbiS)

351 return DbiS.takeError();

352

353 uint32_t SymbolStreamNum = DbiS->getSymRecordStreamIndex();

355 if (!SymbolS)

356 return SymbolS.takeError();

357

358 auto TempSymbols = std::make_unique(std::move(*SymbolS));

359 if (auto EC = TempSymbols->reload())

360 return std::move(EC);

361 Symbols = std::move(TempSymbols);

362 }

363 return *Symbols;

364}

365

367 if (!Strings) {

369 if (!NS)

370 return NS.takeError();

371

372 auto N = std::make_unique();

374 if (auto EC = N->reload(Reader))

375 return std::move(EC);

377 StringTableStream = std::move(*NS);

378 Strings = std::move(N);

379 }

380 return *Strings;

381}

382

384 if (!InjectedSources) {

386 if (!IJS)

387 return IJS.takeError();

388

390 if (!Strings)

391 return Strings.takeError();

392

393 auto IJ = std::make_unique(std::move(*IJS));

394 if (auto EC = IJ->reload(*Strings))

395 return std::move(EC);

396 InjectedSources = std::move(IJ);

397 }

398 return *InjectedSources;

399}

400

403 if (!DbiS)

404 return 0;

407 return 8;

408 return 4;

409}

410

414

417 if (!DbiS) {

419 return false;

420 }

421

422 return DbiS->getGlobalSymbolStreamIndex() < getNumStreams();

423}

424

426

429 return false;

430

432 return false;

433

436}

437

440 if (!DbiS) {

442 return false;

443 }

444 return DbiS->getPublicSymbolStreamIndex() < getNumStreams();

445}

446

449 if (!DbiS)

450 return false;

451 return DbiS->getSymRecordStreamIndex() < getNumStreams();

452}

453

455

458 if (!IS)

459 return false;

461 if (!ExpectedNSI) {

463 return false;

464 }

466 return true;

467}

468

471 if (!IS)

472 return false;

473 Expected<uint32_t> ExpectedNSI = IS->getNamedStreamIndex("/src/headerblock");

474 if (!ExpectedNSI) {

476 return false;

477 }

479 return true;

480}

481

482

483

484

485

493

497 if (!IS)

498 return IS.takeError();

499

501 if (!ExpectedNSI)

503 uint32_t NameStreamIndex = *ExpectedNSI;

504

506}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

Lightweight arrays that are backed by an arbitrary BinaryStream.

Function const char TargetMachine * Machine

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

Provides read only access to a subclass of BinaryStream.

Error readObject(const T *&Dest)

Get a pointer to an object of type T from the underlying stream, as if by memcpy, and store the resul...

LLVM_ABI Error readBytes(ArrayRef< uint8_t > &Buffer, uint32_t Size)

Read Size bytes from the underlying stream at the current offset and and set Buffer to the resulting ...

Error readInteger(T &Dest)

Read an integer of the specified endianness into Dest and update the stream's offset.

uint64_t bytesRemaining() const

void setOffset(uint64_t Off)

Error readArray(ArrayRef< T > &Array, uint32_t NumElements)

Get a reference to a NumElements element array of objects of type T from the underlying stream as if ...

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

Error takeError()

Take ownership of the stored error.

FixedStreamArray is similar to VarStreamArray, except with each record having a fixed-length.

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

Describes the layout of a stream in an MSF layout.

static std::unique_ptr< MappedBlockStream > createIndexedStream(const MSFLayout &Layout, BinaryStreamRef MsfData, uint32_t StreamIndex, BumpPtrAllocator &Allocator)

static std::unique_ptr< MappedBlockStream > createDirectoryStream(const MSFLayout &Layout, BinaryStreamRef MsfData, BumpPtrAllocator &Allocator)

static std::unique_ptr< MappedBlockStream > createFpmStream(const MSFLayout &Layout, BinaryStreamRef MsfData, BumpPtrAllocator &Allocator)

LLVM_ABI bool containsIdStream() const

uint32_t getNumDirectoryBlocks() const

Definition PDBFile.cpp:74

Error parseStreamData()

Definition PDBFile.cpp:179

bool hasPDBInjectedSourceStream()

Definition PDBFile.cpp:469

Expected< InjectedSourceStream & > getInjectedSourceStream()

Definition PDBFile.cpp:383

Expected< GlobalsStream & > getPDBGlobalsStream()

Definition PDBFile.cpp:256

uint32_t getPointerSize()

Definition PDBFile.cpp:401

Expected< TpiStream & > getPDBIpiStream()

Definition PDBFile.cpp:313

uint32_t getBlockSize() const override

Definition PDBFile.cpp:54

Expected< std::unique_ptr< msf::MappedBlockStream > > safelyCreateIndexedStream(uint32_t StreamIndex) const

Wrapper around MappedBlockStream::createIndexedStream() that checks if a stream with that index actua...

Definition PDBFile.cpp:487

uint32_t getUnknown1() const

Definition PDBFile.cpp:72

uint32_t getBlockMapIndex() const

Definition PDBFile.cpp:68

Expected< DbiStream & > getPDBDbiStream()

Definition PDBFile.cpp:287

Expected< InfoStream & > getPDBInfoStream()

Definition PDBFile.cpp:274

bool hasPDBTpiStream() const

Definition PDBFile.cpp:454

PDBFile(StringRef Path, std::unique_ptr< BinaryStream > PdbFileBuffer, BumpPtrAllocator &Allocator)

Definition PDBFile.cpp:41

bool hasPDBSymbolStream()

Definition PDBFile.cpp:447

bool hasPDBPublicsStream()

Definition PDBFile.cpp:438

uint32_t getBlockCount() const override

Definition PDBFile.cpp:60

bool hasPDBGlobalsStream()

Definition PDBFile.cpp:415

StringRef getFileDirectory() const

Definition PDBFile.cpp:50

uint32_t getMaxStreamSize() const

Definition PDBFile.cpp:88

msf::MSFStreamLayout getFpmStreamLayout() const

Definition PDBFile.cpp:252

Expected< PublicsStream & > getPDBPublicsStream()

Definition PDBFile.cpp:329

Error setBlockData(uint32_t BlockIndex, uint32_t Offset, ArrayRef< uint8_t > Data) const override

Definition PDBFile.cpp:113

Expected< TpiStream & > getPDBTpiStream()

Definition PDBFile.cpp:300

msf::MSFStreamLayout getStreamLayout(uint32_t StreamIdx) const

Definition PDBFile.cpp:244

bool hasPDBIpiStream() const

Definition PDBFile.cpp:427

Expected< SymbolStream & > getPDBSymbolStream()

Definition PDBFile.cpp:347

uint64_t getBlockMapOffset() const

Definition PDBFile.cpp:79

Error parseFileHeaders()

Definition PDBFile.cpp:119

uint64_t getFileSize() const

Definition PDBFile.cpp:101

Expected< ArrayRef< uint8_t > > getBlockData(uint32_t BlockIndex, uint32_t NumBytes) const override

Definition PDBFile.cpp:103

uint32_t getFreeBlockMapBlock() const

Definition PDBFile.cpp:56

uint32_t getStreamByteSize(uint32_t StreamIndex) const override

Definition PDBFile.cpp:92

uint32_t getNumStreams() const override

Definition PDBFile.cpp:84

bool hasPDBInfoStream() const

Definition PDBFile.cpp:425

StringRef getFilePath() const

Definition PDBFile.cpp:48

ArrayRef< support::ulittle32_t > getStreamBlockList(uint32_t StreamIndex) const override

Definition PDBFile.cpp:97

uint32_t getNumDirectoryBytes() const

Definition PDBFile.cpp:64

bool hasPDBDbiStream() const

Definition PDBFile.cpp:411

Expected< std::unique_ptr< msf::MappedBlockStream > > safelyCreateNamedStream(StringRef Name)

Definition PDBFile.cpp:495

ArrayRef< support::ulittle32_t > getDirectoryBlockArray() const

Definition PDBFile.cpp:232

bool hasPDBStringTable()

Definition PDBFile.cpp:456

Expected< PDBStringTable & > getStringTable()

Definition PDBFile.cpp:366

std::unique_ptr< msf::MappedBlockStream > createIndexedStream(uint16_t SN) const

Definition PDBFile.cpp:237

LLVM_ABI Error validateSuperBlock(const SuperBlock &SB)

uint64_t blockToOffset(uint64_t BlockNumber, uint64_t BlockSize)

LLVM_ABI MSFStreamLayout getFpmStreamLayout(const MSFLayout &Msf, bool IncludeUnusedFpmData=false, bool AltFpm=false)

Determine the layout of the FPM stream, given the MSF layout.

uint64_t bytesToBlocks(uint64_t NumBytes, uint64_t BlockSize)

const uint16_t kInvalidStreamIndex

LLVM_ABI StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)

Get parent path.

This is an optimization pass for GlobalISel generic memory operations.

Error make_error(ArgTs &&... Args)

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

void cantFail(Error Err, const char *Msg=nullptr)

Report a fatal error if Err is a failure value.

auto max_element(R &&Range)

Provide wrappers to std::max_element which take ranges instead of having to pass begin/end explicitly...

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

BumpPtrAllocatorImpl<> BumpPtrAllocator

The standard BumpPtrAllocator which just uses the default template parameters.

void consumeError(Error Err)

Consume a Error without doing anything.

Implement std::hash so that hash_code can be used in STL containers.

support::ulittle32_t NumBlocks

support::ulittle32_t BlockSize