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/PDB/Native/RawError.h"
13 : #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
14 : #include "llvm/Support/BinaryStreamArray.h"
15 : #include "llvm/Support/BinaryStreamReader.h"
16 :
17 : #include "llvm/Support/Error.h"
18 :
19 : namespace llvm {
20 : namespace pdb {
21 :
22 2 : static Error checkHashHdrVersion(const GSIHashHeader *HashHdr) {
23 4 : 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 6 : return Error::success();
29 : }
30 :
31 1 : Error readGSIHashBuckets(FixedStreamArray<support::ulittle32_t> &HashBuckets,
32 : const GSIHashHeader *HashHdr,
33 : BinaryStreamReader &Reader) {
34 3 : 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 1 : ArrayRef<uint8_t> Bitmap;
40 1 : size_t BitmapSizeInBits = alignTo(IPHR_HASH + 1, 32);
41 1 : uint32_t NumBitmapEntries = BitmapSizeInBits / 8;
42 3 : 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 1 : uint32_t NumBuckets = 0;
47 518 : for (uint8_t B : Bitmap)
48 516 : NumBuckets += countPopulation(B);
49 :
50 : // Hash buckets follow.
51 3 : 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 3 : return Error::success();
57 : }
58 :
59 1 : Error readGSIHashHeader(const GSIHashHeader *&HashHdr,
60 : BinaryStreamReader &Reader) {
61 3 : if (Reader.readObject(HashHdr))
62 : return make_error<RawError>(raw_error_code::corrupt_file,
63 0 : "Stream does not contain a GSIHashHeader.");
64 :
65 2 : 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 3 : return Error::success();
71 : }
72 :
73 1 : Error readGSIHashRecords(FixedStreamArray<PSHashRecord> &HashRecords,
74 : const GSIHashHeader *HashHdr,
75 : BinaryStreamReader &Reader) {
76 3 : 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 2 : if (HashHdr->HrSize % sizeof(PSHashRecord))
82 : return make_error<RawError>(raw_error_code::corrupt_file,
83 0 : "Invalid HR array size.");
84 2 : uint32_t NumHashRecords = HashHdr->HrSize / sizeof(PSHashRecord);
85 3 : 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 3 : return Error::success();
91 : }
92 : }
93 : }
|