LLVM  6.0.0svn
GlobalsStream.cpp
Go to the documentation of this file.
1 //===- GlobalsStream.cpp - PDB Index of Symbols by Name ---------*- C++ -*-===//
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 // The on-disk structores used in this file are based on the reference
11 // implementation which is available at
12 // https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h
13 //
14 // When you are reading the reference source code, you'd find the
15 // information below useful.
16 //
17 // - ppdb1->m_fMinimalDbgInfo seems to be always true.
18 // - SMALLBUCKETS macro is defined.
19 //
20 //===----------------------------------------------------------------------===//
21 
25 #include "llvm/Support/Error.h"
26 #include <algorithm>
27 
28 using namespace llvm;
29 using namespace llvm::msf;
30 using namespace llvm::pdb;
31 
32 GlobalsStream::GlobalsStream(std::unique_ptr<MappedBlockStream> Stream)
33  : Stream(std::move(Stream)) {}
34 
36 
38  BinaryStreamReader Reader(*Stream);
39  if (auto E = GlobalsTable.read(Reader))
40  return E;
41  return Error::success();
42 }
43 
44 static Error checkHashHdrVersion(const GSIHashHeader *HashHdr) {
45  if (HashHdr->VerHdr != GSIHashHeader::HdrVersion)
46  return make_error<RawError>(
48  "Encountered unsupported globals stream version.");
49 
50  return Error::success();
51 }
52 
53 static Error readGSIHashHeader(const GSIHashHeader *&HashHdr,
54  BinaryStreamReader &Reader) {
55  if (Reader.readObject(HashHdr))
56  return make_error<RawError>(raw_error_code::corrupt_file,
57  "Stream does not contain a GSIHashHeader.");
58 
60  return make_error<RawError>(
62  "GSIHashHeader signature (0xffffffff) not found.");
63 
64  return Error::success();
65 }
66 
68  const GSIHashHeader *HashHdr,
69  BinaryStreamReader &Reader) {
70  if (auto EC = checkHashHdrVersion(HashHdr))
71  return EC;
72 
73  // HashHdr->HrSize specifies the number of bytes of PSHashRecords we have.
74  // Verify that we can read them all.
75  if (HashHdr->HrSize % sizeof(PSHashRecord))
76  return make_error<RawError>(raw_error_code::corrupt_file,
77  "Invalid HR array size.");
78  uint32_t NumHashRecords = HashHdr->HrSize / sizeof(PSHashRecord);
79  if (auto EC = Reader.readArray(HashRecords, NumHashRecords))
80  return joinErrors(std::move(EC),
81  make_error<RawError>(raw_error_code::corrupt_file,
82  "Error reading hash records."));
83 
84  return Error::success();
85 }
86 
87 static Error
89  ArrayRef<uint8_t> &HashBitmap, const GSIHashHeader *HashHdr,
90  BinaryStreamReader &Reader) {
91  if (auto EC = checkHashHdrVersion(HashHdr))
92  return EC;
93 
94  // Before the actual hash buckets, there is a bitmap of length determined by
95  // IPHR_HASH.
96  size_t BitmapSizeInBits = alignTo(IPHR_HASH + 1, 32);
97  uint32_t NumBitmapEntries = BitmapSizeInBits / 8;
98  if (auto EC = Reader.readBytes(HashBitmap, NumBitmapEntries))
99  return joinErrors(std::move(EC),
100  make_error<RawError>(raw_error_code::corrupt_file,
101  "Could not read a bitmap."));
102  uint32_t NumBuckets = 0;
103  for (uint8_t B : HashBitmap)
104  NumBuckets += countPopulation(B);
105 
106  // Hash buckets follow.
107  if (auto EC = Reader.readArray(HashBuckets, NumBuckets))
108  return joinErrors(std::move(EC),
109  make_error<RawError>(raw_error_code::corrupt_file,
110  "Hash buckets corrupted."));
111 
112  return Error::success();
113 }
114 
116  if (auto EC = readGSIHashHeader(HashHdr, Reader))
117  return EC;
118  if (auto EC = readGSIHashRecords(HashRecords, HashHdr, Reader))
119  return EC;
120  if (HashHdr->HrSize > 0)
121  if (auto EC = readGSIHashBuckets(HashBuckets, HashBitmap, HashHdr, Reader))
122  return EC;
123  return Error::success();
124 }
static Error readGSIHashBuckets(FixedStreamArray< support::ulittle32_t > &HashBuckets, ArrayRef< uint8_t > &HashBitmap, const GSIHashHeader *HashHdr, BinaryStreamReader &Reader)
support::ulittle32_t VerSignature
Definition: RawTypes.h:34
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
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...
support::ulittle32_t VerHdr
Definition: RawTypes.h:35
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
Definition: MathExtras.h:677
Definition: BitVector.h:920
static Error checkHashHdrVersion(const GSIHashHeader *HashHdr)
Header of the hash tables found in the globals and publics sections.
Definition: RawTypes.h:29
Error read(BinaryStreamReader &Reader)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static Error readGSIHashRecords(FixedStreamArray< PSHashRecord > &HashRecords, const GSIHashHeader *HashHdr, BinaryStreamReader &Reader)
static ErrorSuccess success()
Create a success value.
Definition: Error.h:313
unsigned countPopulation(T Value)
Count the number of set bits in a value.
Definition: MathExtras.h:512
static Error readGSIHashHeader(const GSIHashHeader *&HashHdr, BinaryStreamReader &Reader)
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 joinErrors(Error E1, Error E2)
Concatenate errors.
Definition: Error.h:408
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
Provides read only access to a subclass of BinaryStream.
support::ulittle32_t HrSize
Definition: RawTypes.h:36
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 ...