blob: 5d0c724b8b9ab0b48b6bdcc2670e2b9035e4d8f4 [file] [log] [blame]
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +00001//==- Deserialize.cpp - Generic Object Serialization to Bitcode --*- C++ -*-==//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Ted Kremenek and is distributed under the
6// University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the internal methods used for object serialization.
11//
12//===----------------------------------------------------------------------===//
13
Ted Kremenek6e9b4962007-10-24 19:06:40 +000014#include "llvm/Bitcode/Deserialize.h"
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000015
Ted Kremenek26e25b32007-11-06 19:49:16 +000016#ifdef DEBUG_BACKPATCH
17#include "llvm/Support/Streams.h"
18#endif
19
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000020using namespace llvm;
21
22Deserializer::Deserializer(BitstreamReader& stream)
Ted Kremenek5973ef42007-10-28 21:17:59 +000023 : Stream(stream), RecIdx(0), FreeList(NULL) {
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000024}
25
26Deserializer::~Deserializer() {
27 assert (RecIdx >= Record.size() &&
28 "Still scanning bitcode record when deserialization completed.");
Ted Kremenekadc9b9c2007-10-28 23:38:38 +000029
30#ifdef NDEBUG
31 for (MapTy::iterator I=BPatchMap.begin(), E=BPatchMap.end(); I!=E; ++I)
Ted Kremenek066ff5b2007-11-01 00:57:37 +000032 assert (I->first.hasFinalPtr() &&
Ted Kremenekadc9b9c2007-10-28 23:38:38 +000033 "Some pointers were not backpatched.");
34#endif
Ted Kremenekfe2a0122007-10-25 00:10:21 +000035}
36
37
38bool Deserializer::inRecord() {
39 if (Record.size() > 0) {
40 if (RecIdx >= Record.size()) {
41 RecIdx = 0;
42 Record.clear();
43 return false;
44 }
45 else return true;
46 }
47 else return false;
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000048}
49
50void Deserializer::ReadRecord() {
51 // FIXME: Check if we haven't run off the edge of the stream.
52 // FIXME: Handle abbreviations.
Ted Kremenek6e9b4962007-10-24 19:06:40 +000053
Ted Kremenek0a6d98e2007-11-05 21:36:35 +000054 assert (Record.size() == 0);
55
Ted Kremenek14ac17e2007-11-05 20:47:27 +000056 unsigned Code;
Ted Kremenek6e9b4962007-10-24 19:06:40 +000057
Ted Kremenek14ac17e2007-11-05 20:47:27 +000058 while (true) {
59
Ted Kremenek0a6d98e2007-11-05 21:36:35 +000060 if (Stream.AtEndOfStream())
61 return;
62
Ted Kremenek14ac17e2007-11-05 20:47:27 +000063 Code = Stream.ReadCode();
64
65 if (Code == bitc::ENTER_SUBBLOCK) {
Ted Kremenekec8cd062007-11-08 19:50:46 +000066 BlockLocs.push_back(Stream.GetCurrentBitNo());
Ted Kremenek14ac17e2007-11-05 20:47:27 +000067 unsigned id = Stream.ReadSubBlockID();
68 Stream.EnterSubBlock(id);
69 continue;
70 }
71
Ted Kremenekec8cd062007-11-08 19:50:46 +000072 if (Code == bitc::END_BLOCK) {
Ted Kremenek14ac17e2007-11-05 20:47:27 +000073 bool x = Stream.ReadBlockEnd();
74 assert (!x && "Error at block end.");
Ted Kremenekec8cd062007-11-08 19:50:46 +000075 BlockLocs.pop_back();
Ted Kremenek14ac17e2007-11-05 20:47:27 +000076 continue;
77 }
78
Ted Kremenek26e25b32007-11-06 19:49:16 +000079 if (Code == bitc::DEFINE_ABBREV) {
80 Stream.ReadAbbrevRecord();
81 continue;
82 }
83
Ted Kremenek14ac17e2007-11-05 20:47:27 +000084 break;
85 }
86
Ted Kremenek6e9b4962007-10-24 19:06:40 +000087 assert (Record.size() == 0);
88 Stream.ReadRecord(Code,Record);
Ted Kremenek0a6d98e2007-11-05 21:36:35 +000089 assert (Record.size() > 0 || Stream.AtEndOfStream());
90}
91
Ted Kremenekec8cd062007-11-08 19:50:46 +000092Deserializer::Location Deserializer::GetCurrentBlockLocation() {
93 if (!inRecord())
94 ReadRecord();
95
96 assert (!BlockLocs.empty());
97 return BlockLocs.back();
98}
99
100bool Deserializer::FinishedBlock(Location BlockLoc) {
101 if (!inRecord())
102 ReadRecord();
103
104 for (llvm::SmallVector<Location,5>::reverse_iterator
105 I=BlockLocs.rbegin(), E=BlockLocs.rend(); I!=E; ++I)
106 if (*I == BlockLoc)
107 return false;
108
109 return true;
110}
111
Ted Kremenek0a6d98e2007-11-05 21:36:35 +0000112bool Deserializer::AtEnd() {
113 if (inRecord())
114 return false;
115
116 ReadRecord();
117
118 return Stream.AtEndOfStream();
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +0000119}
120
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000121uint64_t Deserializer::ReadInt() {
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +0000122 // FIXME: Any error recovery/handling with incomplete or bad files?
123 if (!inRecord())
124 ReadRecord();
125
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +0000126 return Record[RecIdx++];
127}
128
Ted Kremenek2e6452c2007-11-07 18:24:34 +0000129int64_t Deserializer::ReadSInt() {
130 uint64_t x = ReadInt();
131 int64_t magnitude = x >> 1;
132 return x & 0x1 ? -magnitude : magnitude;
133}
134
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000135char* Deserializer::ReadCStr(char* cstr, unsigned MaxLen, bool isNullTerm) {
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +0000136 if (cstr == NULL)
137 MaxLen = 0; // Zero this just in case someone does something funny.
138
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000139 unsigned len = ReadInt();
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +0000140
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +0000141 assert (MaxLen == 0 || (len + (isNullTerm ? 1 : 0)) <= MaxLen);
142
143 if (!cstr)
144 cstr = new char[len + (isNullTerm ? 1 : 0)];
145
146 assert (cstr != NULL);
147
148 for (unsigned i = 0; i < len; ++i)
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000149 cstr[i] = (char) ReadInt();
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +0000150
151 if (isNullTerm)
152 cstr[len+1] = '\0';
153
154 return cstr;
155}
156
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000157void Deserializer::ReadCStr(std::vector<char>& buff, bool isNullTerm) {
158 unsigned len = ReadInt();
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +0000159
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000160 buff.clear();
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +0000161 buff.reserve(len);
162
163 for (unsigned i = 0; i < len; ++i)
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000164 buff.push_back((char) ReadInt());
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +0000165
166 if (isNullTerm)
167 buff.push_back('\0');
168}
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000169
Ted Kremeneka7963a52007-10-31 22:42:03 +0000170void Deserializer::RegisterPtr(unsigned PtrId, const void* Ptr) {
Ted Kremenek066ff5b2007-11-01 00:57:37 +0000171 MapTy::value_type& E = BPatchMap.FindAndConstruct(BPKey(PtrId));
172
173 assert (!HasFinalPtr(E) && "Pointer already registered.");
174
Ted Kremenek26e25b32007-11-06 19:49:16 +0000175#ifdef DEBUG_BACKPATCH
176 llvm::cerr << "RegisterPtr: " << PtrId << " => " << Ptr << "\n";
177#endif
178
Ted Kremenek066ff5b2007-11-01 00:57:37 +0000179 SetPtr(E,Ptr);
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000180}
181
Ted Kremenekb12a82d2007-11-06 22:21:14 +0000182void Deserializer::ReadUIntPtr(uintptr_t& PtrRef, bool AllowBackpatch) {
Ted Kremenekec8cd062007-11-08 19:50:46 +0000183 SerializedPtrID PtrId = ReadPtrID();
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000184
Ted Kremenek2423e032007-10-25 18:42:52 +0000185 if (PtrId == 0) {
Ted Kremenek8308a482007-10-29 18:43:39 +0000186 PtrRef = 0;
Ted Kremenek2423e032007-10-25 18:42:52 +0000187 return;
Ted Kremenek26e25b32007-11-06 19:49:16 +0000188 }
189
190#ifdef DEBUG_BACKPATCH
191 llvm::cerr << "ReadUintPtr: " << PtrId << "\n";
192#endif
193
Ted Kremenek066ff5b2007-11-01 00:57:37 +0000194 MapTy::value_type& E = BPatchMap.FindAndConstruct(BPKey(PtrId));
Ted Kremenek2423e032007-10-25 18:42:52 +0000195
Ted Kremenek066ff5b2007-11-01 00:57:37 +0000196 if (HasFinalPtr(E))
197 PtrRef = GetFinalPtr(E);
Ted Kremenek5973ef42007-10-28 21:17:59 +0000198 else {
Ted Kremenekb12a82d2007-11-06 22:21:14 +0000199 assert (AllowBackpatch &&
200 "Client forbids backpatching for this pointer.");
201
Ted Kremenek5973ef42007-10-28 21:17:59 +0000202 // Register backpatch. Check the freelist for a BPNode.
203 BPNode* N;
204
205 if (FreeList) {
206 N = FreeList;
207 FreeList = FreeList->Next;
208 }
209 else // No available BPNode. Allocate one.
210 N = (BPNode*) Allocator.Allocate<BPNode>();
211
Ted Kremenek066ff5b2007-11-01 00:57:37 +0000212 new (N) BPNode(GetBPNode(E),PtrRef);
213 SetBPNode(E,N);
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000214 }
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000215}
216
Ted Kremenekeb9409d2007-10-31 19:58:32 +0000217uintptr_t Deserializer::ReadInternalRefPtr() {
Ted Kremenekec8cd062007-11-08 19:50:46 +0000218 SerializedPtrID PtrId = ReadPtrID();
Ted Kremenekeb9409d2007-10-31 19:58:32 +0000219
220 assert (PtrId != 0 && "References cannot refer the NULL address.");
221
Ted Kremenek066ff5b2007-11-01 00:57:37 +0000222 MapTy::value_type& E = BPatchMap.FindAndConstruct(BPKey(PtrId));
Ted Kremenekeb9409d2007-10-31 19:58:32 +0000223
Ted Kremenek14ac17e2007-11-05 20:47:27 +0000224 assert (HasFinalPtr(E) &&
Ted Kremenekeb9409d2007-10-31 19:58:32 +0000225 "Cannot backpatch references. Object must be already deserialized.");
226
Ted Kremenek066ff5b2007-11-01 00:57:37 +0000227 return GetFinalPtr(E);
Ted Kremenekeb9409d2007-10-31 19:58:32 +0000228}
Ted Kremenek5973ef42007-10-28 21:17:59 +0000229
Ted Kremenek066ff5b2007-11-01 00:57:37 +0000230void Deserializer::BPEntry::SetPtr(BPNode*& FreeList, void* P) {
Ted Kremenek5973ef42007-10-28 21:17:59 +0000231 BPNode* Last = NULL;
232
Ted Kremenek066ff5b2007-11-01 00:57:37 +0000233 for (BPNode* N = Head; N != NULL; N=N->Next) {
Ted Kremenek5973ef42007-10-28 21:17:59 +0000234 Last = N;
235 N->PtrRef |= reinterpret_cast<uintptr_t>(P);
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000236 }
237
Ted Kremenek5973ef42007-10-28 21:17:59 +0000238 if (Last) {
239 Last->Next = FreeList;
Ted Kremenek066ff5b2007-11-01 00:57:37 +0000240 FreeList = Head;
Ted Kremenek5973ef42007-10-28 21:17:59 +0000241 }
242
Ted Kremenek066ff5b2007-11-01 00:57:37 +0000243 Ptr = const_cast<void*>(P);
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000244}
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000245
Ted Kremenek5973ef42007-10-28 21:17:59 +0000246
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000247#define INT_READ(TYPE)\
248void SerializeTrait<TYPE>::Read(Deserializer& D, TYPE& X) {\
Ted Kremenekff37ccc2007-11-01 22:23:34 +0000249 X = (TYPE) D.ReadInt(); }
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000250
251INT_READ(bool)
252INT_READ(unsigned char)
253INT_READ(unsigned short)
254INT_READ(unsigned int)
255INT_READ(unsigned long)
Ted Kremenek2e6452c2007-11-07 18:24:34 +0000256
257#define SINT_READ(TYPE)\
258void SerializeTrait<TYPE>::Read(Deserializer& D, TYPE& X) {\
259 X = (TYPE) D.ReadSInt(); }
260
261INT_READ(signed char)
262INT_READ(signed short)
263INT_READ(signed int)
264INT_READ(signed long)