Line data Source code
1 : //===- GSI.cpp - Common Functions for GlobalsStream and PublicsStream ----===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 :
10 : #include "GSI.h"
11 :
12 : #include "llvm/DebugInfo/MSF/StreamArray.h"
13 : #include "llvm/DebugInfo/MSF/StreamReader.h"
14 : #include "llvm/DebugInfo/PDB/Raw/RawError.h"
15 : #include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
16 :
17 : #include "llvm/Support/Error.h"
18 :
19 : namespace llvm {
20 : namespace pdb {
21 :
22 8 : static Error checkHashHdrVersion(const GSIHashHeader *HashHdr) {
23 16 : if (HashHdr->VerHdr != GSIHashHeader::HdrVersion)
24 : return make_error<RawError>(
25 : raw_error_code::feature_unsupported,
26 0 : "Encountered unsupported globals stream version.");
27 :
28 24 : return Error::success();
29 : }
30 :
31 4 : Error readGSIHashBuckets(
32 : msf::FixedStreamArray<support::ulittle32_t> &HashBuckets,
33 : const GSIHashHeader *HashHdr, msf::StreamReader &Reader) {
34 12 : if (auto EC = checkHashHdrVersion(HashHdr))
35 0 : return EC;
36 :
37 : // Before the actual hash buckets, there is a bitmap of length determined by
38 : // IPHR_HASH.
39 4 : ArrayRef<uint8_t> Bitmap;
40 4 : size_t BitmapSizeInBits = alignTo(IPHR_HASH + 1, 32);
41 4 : uint32_t NumBitmapEntries = BitmapSizeInBits / 8;
42 12 : if (auto EC = Reader.readBytes(Bitmap, NumBitmapEntries))
43 0 : return joinErrors(std::move(EC),
44 0 : make_error<RawError>(raw_error_code::corrupt_file,
45 0 : "Could not read a bitmap."));
46 4 : uint32_t NumBuckets = 0;
47 2072 : for (uint8_t B : Bitmap)
48 2064 : NumBuckets += countPopulation(B);
49 :
50 : // Hash buckets follow.
51 12 : if (auto EC = Reader.readArray(HashBuckets, NumBuckets))
52 0 : return joinErrors(std::move(EC),
53 0 : make_error<RawError>(raw_error_code::corrupt_file,
54 0 : "Hash buckets corrupted."));
55 :
56 12 : return Error::success();
57 : }
58 :
59 4 : Error readGSIHashHeader(const GSIHashHeader *&HashHdr,
60 : msf::StreamReader &Reader) {
61 12 : if (Reader.readObject(HashHdr))
62 : return make_error<RawError>(raw_error_code::corrupt_file,
63 0 : "Stream does not contain a GSIHashHeader.");
64 :
65 8 : if (HashHdr->VerSignature != GSIHashHeader::HdrSignature)
66 : return make_error<RawError>(
67 : raw_error_code::feature_unsupported,
68 0 : "GSIHashHeader signature (0xffffffff) not found.");
69 :
70 12 : return Error::success();
71 : }
72 :
73 4 : Error readGSIHashRecords(msf::FixedStreamArray<PSHashRecord> &HashRecords,
74 : const GSIHashHeader *HashHdr,
75 : msf::StreamReader &Reader) {
76 12 : if (auto EC = checkHashHdrVersion(HashHdr))
77 0 : return EC;
78 :
79 : // HashHdr->HrSize specifies the number of bytes of PSHashRecords we have.
80 : // Verify that we can read them all.
81 8 : if (HashHdr->HrSize % sizeof(PSHashRecord))
82 : return make_error<RawError>(raw_error_code::corrupt_file,
83 0 : "Invalid HR array size.");
84 8 : uint32_t NumHashRecords = HashHdr->HrSize / sizeof(PSHashRecord);
85 12 : if (auto EC = Reader.readArray(HashRecords, NumHashRecords))
86 0 : return joinErrors(std::move(EC),
87 0 : make_error<RawError>(raw_error_code::corrupt_file,
88 0 : "Error reading hash records."));
89 :
90 12 : return Error::success();
91 : }
92 : }
93 : }
|