blob: 20aa3041fdaa4f2e568d7e47be7c9de69a5f104a [file] [log] [blame]
Zachary Turnerf5c59652016-05-03 00:28:21 +00001//===- TpiStream.cpp - PDB Type Info (TPI) Stream 2 Access ----------------===//
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 "llvm/DebugInfo/PDB/Raw/TpiStream.h"
11
12#include "llvm/DebugInfo/CodeView/CodeView.h"
13#include "llvm/DebugInfo/CodeView/TypeRecord.h"
14#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
15#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
16#include "llvm/DebugInfo/PDB/Raw/StreamReader.h"
17
18#include "llvm/Support/Endian.h"
19
20using namespace llvm;
21using namespace llvm::support;
22using namespace llvm::pdb;
23
24namespace {
Zachary Turnerf5c59652016-05-03 00:28:21 +000025const uint32_t MinHashBuckets = 0x1000;
26const uint32_t MaxHashBuckets = 0x40000;
27}
28
29static uint32_t HashBufferV8(uint8_t *buffer, uint32_t NumBuckets) {
30 // Not yet implemented, this is probably some variation of CRC32 but we need
31 // to be sure of the precise implementation otherwise we won't be able to work
32 // with persisted hash values.
33 return 0;
34}
35
36struct TpiStream::HeaderInfo {
37 struct EmbeddedBuf {
38 little32_t Off;
39 ulittle32_t Length;
40 };
41
42 ulittle32_t Version;
43 ulittle32_t HeaderSize;
44 ulittle32_t TypeIndexBegin;
45 ulittle32_t TypeIndexEnd;
46 ulittle32_t TypeRecordBytes;
47
48 ulittle16_t HashStreamIndex;
49 ulittle16_t HashAuxStreamIndex;
50 ulittle32_t HashKeySize;
51 ulittle32_t NumHashBuckets;
52
53 EmbeddedBuf HashValueBuffer;
54 EmbeddedBuf IndexOffsetBuffer;
55 EmbeddedBuf HashAdjBuffer;
56};
57
58TpiStream::TpiStream(PDBFile &File)
59 : Pdb(File), Stream(StreamTPI, File), HashFunction(nullptr) {}
60
61TpiStream::~TpiStream() {}
62
63std::error_code TpiStream::reload() {
64 StreamReader Reader(Stream);
65
66 if (Reader.bytesRemaining() < sizeof(HeaderInfo))
67 return std::make_error_code(std::errc::illegal_byte_sequence);
68
69 Header.reset(new HeaderInfo());
70 Reader.readObject(Header.get());
71
72 if (Header->Version != PdbTpiV80)
73 return std::make_error_code(std::errc::not_supported);
74
75 if (Header->HeaderSize != sizeof(HeaderInfo))
76 return std::make_error_code(std::errc::illegal_byte_sequence);
77
78 if (Header->HashKeySize != sizeof(ulittle32_t))
79 return std::make_error_code(std::errc::illegal_byte_sequence);
80
81 if (Header->NumHashBuckets < MinHashBuckets ||
82 Header->NumHashBuckets > MaxHashBuckets)
83 return std::make_error_code(std::errc::illegal_byte_sequence);
84
85 HashFunction = HashBufferV8;
86
87 // The actual type records themselves come from this stream
88 RecordsBuffer.initialize(Reader, Header->TypeRecordBytes);
Zachary Turnerf5c59652016-05-03 00:28:21 +000089
90 // Hash indices, hash values, etc come from the hash stream.
91 MappedBlockStream HS(Header->HashStreamIndex, Pdb);
92 StreamReader HSR(HS);
93 HSR.setOffset(Header->HashValueBuffer.Off);
94 HashValuesBuffer.initialize(HSR, Header->HashValueBuffer.Length);
95
96 HSR.setOffset(Header->HashAdjBuffer.Off);
97 HashAdjBuffer.initialize(HSR, Header->HashAdjBuffer.Length);
98
99 HSR.setOffset(Header->IndexOffsetBuffer.Off);
100 TypeIndexOffsetBuffer.initialize(HSR, Header->IndexOffsetBuffer.Length);
101
102 return std::error_code();
103}
104
105PdbRaw_TpiVer TpiStream::getTpiVersion() const {
106 uint32_t Value = Header->Version;
107 return static_cast<PdbRaw_TpiVer>(Value);
108}
109
110uint32_t TpiStream::TypeIndexBegin() const { return Header->TypeIndexBegin; }
111
112uint32_t TpiStream::TypeIndexEnd() const { return Header->TypeIndexEnd; }
113
114uint32_t TpiStream::NumTypeRecords() const {
115 return TypeIndexEnd() - TypeIndexBegin();
116}
117
Zachary Turner2d02cee2016-05-03 22:18:17 +0000118iterator_range<codeview::TypeIterator> TpiStream::types() const {
Reid Kleckner7960de92016-05-04 19:39:28 +0000119 return codeview::makeTypeRange(RecordsBuffer.data());
Zachary Turnerf5c59652016-05-03 00:28:21 +0000120}