1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===//
2 //
3 // The Subzero Code Generator
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// \brief Implements the interface for translation from PNaCl bitcode files to
12 /// ICE to machine code.
13 ///
14 //===----------------------------------------------------------------------===//
15
16 #include "PNaClTranslator.h"
17
18 #include "IceCfg.h"
19 #include "IceCfgNode.h"
20 #include "IceClFlags.h"
21 #include "IceDefs.h"
22 #include "IceGlobalInits.h"
23 #include "IceInst.h"
24 #include "IceOperand.h"
25 #include "IceRangeSpec.h"
26
27 #ifdef __clang__
28 #pragma clang diagnostic push
29 #pragma clang diagnostic ignored "-Wunused-parameter"
30 #endif // __clang__
31
32 #include "llvm/ADT/Hashing.h"
33 #include "llvm/ADT/SmallString.h"
34 #include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h"
35 #include "llvm/Bitcode/NaCl/NaClBitcodeDefs.h"
36 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h"
37 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h"
38 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h"
39 #include "llvm/Support/Format.h"
40 #include "llvm/Support/MemoryBuffer.h"
41 #include "llvm/Support/raw_ostream.h"
42
43 #ifdef __clang__
44 #pragma clang diagnostic pop
45 #endif // __clang__
46
47 #include <unordered_set>
48
49 // Define a hash function for SmallString's, so that it can be used in hash
50 // tables.
51 namespace std {
52 template <unsigned InternalLen> struct hash<llvm::SmallString<InternalLen>> {
operator ()std::hash53 size_t operator()(const llvm::SmallString<InternalLen> &Key) const {
54 return llvm::hash_combine_range(Key.begin(), Key.end());
55 }
56 };
57 } // end of namespace std
58
59 namespace {
60 using namespace llvm;
61
62 // Models elements in the list of types defined in the types block. These
63 // elements can be undefined, a (simple) type, or a function type signature.
64 // Note that an extended type is undefined on construction. Use methods
65 // setAsSimpleType and setAsFuncSigType to define the extended type.
66 class ExtendedType {
67 ExtendedType &operator=(const ExtendedType &Ty) = delete;
68
69 public:
70 /// Discriminator for LLVM-style RTTI.
71 enum TypeKind { Undefined, Simple, FuncSig };
72
73 ExtendedType() = default;
74 ExtendedType(const ExtendedType &Ty) = default;
75
76 virtual ~ExtendedType() = default;
77
getKind() const78 ExtendedType::TypeKind getKind() const { return Kind; }
79 void dump(Ice::Ostream &Stream) const;
80
81 /// Changes the extended type to a simple type with the given / value.
setAsSimpleType(Ice::Type Ty)82 void setAsSimpleType(Ice::Type Ty) {
83 assert(Kind == Undefined);
84 Kind = Simple;
85 Signature.setReturnType(Ty);
86 }
87
88 /// Changes the extended type to an (empty) function signature type.
setAsFunctionType()89 void setAsFunctionType() {
90 assert(Kind == Undefined);
91 Kind = FuncSig;
92 }
93
94 protected:
95 // Note: For simple types, the return type of the signature will be used to
96 // hold the simple type.
97 Ice::FuncSigType Signature;
98
99 private:
100 ExtendedType::TypeKind Kind = Undefined;
101 };
102
operator <<(Ice::Ostream & Stream,const ExtendedType & Ty)103 Ice::Ostream &operator<<(Ice::Ostream &Stream, const ExtendedType &Ty) {
104 if (!Ice::BuildDefs::dump())
105 return Stream;
106 Ty.dump(Stream);
107 return Stream;
108 }
109
operator <<(Ice::Ostream & Stream,ExtendedType::TypeKind Kind)110 Ice::Ostream &operator<<(Ice::Ostream &Stream, ExtendedType::TypeKind Kind) {
111 if (!Ice::BuildDefs::dump())
112 return Stream;
113 Stream << "ExtendedType::";
114 switch (Kind) {
115 case ExtendedType::Undefined:
116 Stream << "Undefined";
117 break;
118 case ExtendedType::Simple:
119 Stream << "Simple";
120 break;
121 case ExtendedType::FuncSig:
122 Stream << "FuncSig";
123 break;
124 }
125 return Stream;
126 }
127
128 // Models an ICE type as an extended type.
129 class SimpleExtendedType : public ExtendedType {
130 SimpleExtendedType() = delete;
131 SimpleExtendedType(const SimpleExtendedType &) = delete;
132 SimpleExtendedType &operator=(const SimpleExtendedType &) = delete;
133
134 public:
getType() const135 Ice::Type getType() const { return Signature.getReturnType(); }
136
classof(const ExtendedType * Ty)137 static bool classof(const ExtendedType *Ty) {
138 return Ty->getKind() == Simple;
139 }
140 };
141
142 // Models a function signature as an extended type.
143 class FuncSigExtendedType : public ExtendedType {
144 FuncSigExtendedType() = delete;
145 FuncSigExtendedType(const FuncSigExtendedType &) = delete;
146 FuncSigExtendedType &operator=(const FuncSigExtendedType &) = delete;
147
148 public:
getSignature() const149 const Ice::FuncSigType &getSignature() const { return Signature; }
setReturnType(Ice::Type ReturnType)150 void setReturnType(Ice::Type ReturnType) {
151 Signature.setReturnType(ReturnType);
152 }
appendArgType(Ice::Type ArgType)153 void appendArgType(Ice::Type ArgType) { Signature.appendArgType(ArgType); }
classof(const ExtendedType * Ty)154 static bool classof(const ExtendedType *Ty) {
155 return Ty->getKind() == FuncSig;
156 }
157 };
158
dump(Ice::Ostream & Stream) const159 void ExtendedType::dump(Ice::Ostream &Stream) const {
160 if (!Ice::BuildDefs::dump())
161 return;
162 Stream << Kind;
163 switch (Kind) {
164 case Simple: {
165 Stream << " " << Signature.getReturnType();
166 break;
167 }
168 case FuncSig: {
169 Stream << " " << Signature;
170 }
171 default:
172 break;
173 }
174 }
175
176 // Models integer literals as a sequence of bits. Used to read integer values
177 // from bitcode files. Based on llvm::APInt.
178 class BitcodeInt {
179 BitcodeInt() = delete;
180 BitcodeInt(const BitcodeInt &) = delete;
181 BitcodeInt &operator=(const BitcodeInt &) = delete;
182
183 public:
BitcodeInt(Ice::SizeT Bits,uint64_t Val)184 BitcodeInt(Ice::SizeT Bits, uint64_t Val) : BitWidth(Bits), Val(Val) {
185 assert(Bits && "bitwidth too small");
186 assert(Bits <= BITS_PER_WORD && "bitwidth too big");
187 clearUnusedBits();
188 }
189
getSExtValue() const190 int64_t getSExtValue() const {
191 return static_cast<int64_t>(Val << (BITS_PER_WORD - BitWidth)) >>
192 (BITS_PER_WORD - BitWidth);
193 }
194
195 template <typename IntType, typename FpType>
convertToFp() const196 inline FpType convertToFp() const {
197 static_assert(sizeof(IntType) == sizeof(FpType),
198 "IntType and FpType should be the same width");
199 assert(BitWidth == sizeof(IntType) * CHAR_BIT);
200 auto V = static_cast<IntType>(Val);
201 return Ice::Utils::bitCopy<FpType>(V);
202 }
203
204 private:
205 /// Bits in the (internal) value.
206 static const Ice::SizeT BITS_PER_WORD = sizeof(uint64_t) * CHAR_BIT;
207
208 uint32_t BitWidth; /// The number of bits in the floating point number.
209 uint64_t Val; /// The (64-bit) equivalent integer value.
210
211 /// Clear unused high order bits.
clearUnusedBits()212 void clearUnusedBits() {
213 // If all bits are used, we want to leave the value alone.
214 if (BitWidth == BITS_PER_WORD)
215 return;
216
217 // Mask out the high bits.
218 Val &= ~static_cast<uint64_t>(0) >> (BITS_PER_WORD - BitWidth);
219 }
220 };
221
222 class BlockParserBaseClass;
223
224 // Top-level class to read PNaCl bitcode files, and translate to ICE.
225 class TopLevelParser final : public NaClBitcodeParser {
226 TopLevelParser() = delete;
227 TopLevelParser(const TopLevelParser &) = delete;
228 TopLevelParser &operator=(const TopLevelParser &) = delete;
229
230 public:
TopLevelParser(Ice::Translator & Translator,NaClBitstreamCursor & Cursor,Ice::ErrorCode & ErrorStatus)231 TopLevelParser(Ice::Translator &Translator, NaClBitstreamCursor &Cursor,
232 Ice::ErrorCode &ErrorStatus)
233 : NaClBitcodeParser(Cursor), Translator(Translator),
234 ErrorStatus(ErrorStatus),
235 VariableDeclarations(new Ice::VariableDeclarationList()) {}
236
237 ~TopLevelParser() override = default;
238
getTranslator() const239 Ice::Translator &getTranslator() const { return Translator; }
240
241 /// Generates error with given Message, occurring at BitPosition within the
242 /// bitcode file. Always returns true.
243 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t BitPosition,
244 const std::string &Message) override;
245
246 /// Generates error message with respect to the current block parser.
247 bool blockError(const std::string &Message);
248
249 /// Changes the size of the type list to the given size.
resizeTypeIDValues(size_t NewSize)250 void resizeTypeIDValues(size_t NewSize) { TypeIDValues.resize(NewSize); }
251
getNumTypeIDValues() const252 size_t getNumTypeIDValues() const { return TypeIDValues.size(); }
253
254 /// Returns a pointer to the pool where globals are allocated.
getGlobalVariablesPool()255 Ice::VariableDeclarationList *getGlobalVariablesPool() {
256 return VariableDeclarations.get();
257 }
258
259 /// Returns the undefined type associated with type ID. Note: Returns extended
260 /// type ready to be defined.
getTypeByIDForDefining(NaClBcIndexSize_t ID)261 ExtendedType *getTypeByIDForDefining(NaClBcIndexSize_t ID) {
262 // Get corresponding element, verifying the value is still undefined (and
263 // hence allowed to be defined).
264 ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Undefined);
265 if (Ty)
266 return Ty;
267 if (ID >= TypeIDValues.size()) {
268 if (ID >= NaClBcIndexSize_t_Max) {
269 std::string Buffer;
270 raw_string_ostream StrBuf(Buffer);
271 StrBuf << "Can't define more than " << NaClBcIndexSize_t_Max
272 << " types\n";
273 blockError(StrBuf.str());
274 // Recover by using existing type slot.
275 return &TypeIDValues[0];
276 }
277 Ice::Utils::reserveAndResize(TypeIDValues, ID + 1);
278 }
279 return &TypeIDValues[ID];
280 }
281
282 /// Returns the type associated with the given index.
getSimpleTypeByID(NaClBcIndexSize_t ID)283 Ice::Type getSimpleTypeByID(NaClBcIndexSize_t ID) {
284 const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Simple);
285 if (Ty == nullptr)
286 // Return error recovery value.
287 return Ice::IceType_void;
288 return cast<SimpleExtendedType>(Ty)->getType();
289 }
290
291 /// Returns the type signature associated with the given index.
getFuncSigTypeByID(NaClBcIndexSize_t ID)292 const Ice::FuncSigType &getFuncSigTypeByID(NaClBcIndexSize_t ID) {
293 const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::FuncSig);
294 if (Ty == nullptr)
295 // Return error recovery value.
296 return UndefinedFuncSigType;
297 return cast<FuncSigExtendedType>(Ty)->getSignature();
298 }
299
300 /// Sets the next function ID to the given LLVM function.
setNextFunctionID(Ice::FunctionDeclaration * Fcn)301 void setNextFunctionID(Ice::FunctionDeclaration *Fcn) {
302 FunctionDeclarations.push_back(Fcn);
303 }
304
305 /// Returns the value id that should be associated with the the current
306 /// function block. Increments internal counters during call so that it will
307 /// be in correct position for next function block.
getNextFunctionBlockValueID()308 NaClBcIndexSize_t getNextFunctionBlockValueID() {
309 size_t NumDeclaredFunctions = FunctionDeclarations.size();
310 while (NextDefiningFunctionID < NumDeclaredFunctions &&
311 FunctionDeclarations[NextDefiningFunctionID]->isProto())
312 ++NextDefiningFunctionID;
313 if (NextDefiningFunctionID >= NumDeclaredFunctions)
314 Fatal("More function blocks than defined function addresses");
315 return NextDefiningFunctionID++;
316 }
317
318 /// Returns the function associated with ID.
getFunctionByID(NaClBcIndexSize_t ID)319 Ice::FunctionDeclaration *getFunctionByID(NaClBcIndexSize_t ID) {
320 if (ID < FunctionDeclarations.size())
321 return FunctionDeclarations[ID];
322 return reportGetFunctionByIDError(ID);
323 }
324
325 /// Returns the constant associated with the given global value ID.
getGlobalConstantByID(NaClBcIndexSize_t ID)326 Ice::Constant *getGlobalConstantByID(NaClBcIndexSize_t ID) {
327 assert(ID < ValueIDConstants.size());
328 return ValueIDConstants[ID];
329 }
330
331 /// Install names for all global values without names. Called after the global
332 /// value symbol table is processed, but before any function blocks are
333 /// processed.
installGlobalNames()334 void installGlobalNames() {
335 assert(VariableDeclarations);
336 installGlobalVarNames();
337 installFunctionNames();
338 }
339
340 void verifyFunctionTypeSignatures();
341
createValueIDs()342 void createValueIDs() {
343 assert(VariableDeclarations);
344 ValueIDConstants.reserve(VariableDeclarations->size() +
345 FunctionDeclarations.size());
346 createValueIDsForFunctions();
347 createValueIDsForGlobalVars();
348 }
349
350 /// Returns the number of function declarations in the bitcode file.
getNumFunctionIDs() const351 size_t getNumFunctionIDs() const { return FunctionDeclarations.size(); }
352
353 /// Returns the number of global declarations (i.e. IDs) defined in the
354 /// bitcode file.
getNumGlobalIDs() const355 size_t getNumGlobalIDs() const {
356 if (VariableDeclarations) {
357 return FunctionDeclarations.size() + VariableDeclarations->size();
358 } else {
359 return ValueIDConstants.size();
360 }
361 }
362
363 /// Adds the given global declaration to the end of the list of global
364 /// declarations.
addGlobalDeclaration(Ice::VariableDeclaration * Decl)365 void addGlobalDeclaration(Ice::VariableDeclaration *Decl) {
366 assert(VariableDeclarations);
367 VariableDeclarations->push_back(Decl);
368 }
369
370 /// Returns the global variable declaration with the given index.
getGlobalVariableByID(NaClBcIndexSize_t Index)371 Ice::VariableDeclaration *getGlobalVariableByID(NaClBcIndexSize_t Index) {
372 assert(VariableDeclarations);
373 if (Index < VariableDeclarations->size())
374 return VariableDeclarations->at(Index);
375 return reportGetGlobalVariableByIDError(Index);
376 }
377
378 /// Returns the global declaration (variable or function) with the given
379 /// Index.
getGlobalDeclarationByID(NaClBcIndexSize_t Index)380 Ice::GlobalDeclaration *getGlobalDeclarationByID(NaClBcIndexSize_t Index) {
381 size_t NumFunctionIds = FunctionDeclarations.size();
382 if (Index < NumFunctionIds)
383 return getFunctionByID(Index);
384 else
385 return getGlobalVariableByID(Index - NumFunctionIds);
386 }
387
388 /// Returns true if a module block has been parsed.
parsedModuleBlock() const389 bool parsedModuleBlock() const { return ParsedModuleBlock; }
390
391 /// Returns the list of parsed global variable declarations. Releases
392 /// ownership of the current list of global variables. Note: only returns
393 /// non-null pointer on first call. All successive calls return a null
394 /// pointer.
getGlobalVariables()395 std::unique_ptr<Ice::VariableDeclarationList> getGlobalVariables() {
396 // Before returning, check that ValidIDConstants has already been built.
397 assert(!VariableDeclarations ||
398 VariableDeclarations->size() <= ValueIDConstants.size());
399 return std::move(VariableDeclarations);
400 }
401
402 // Upper limit of alignment power allowed by LLVM
403 static constexpr uint32_t AlignPowerLimit = 29;
404
405 // Extracts the corresponding Alignment to use, given the AlignPower (i.e.
406 // 2**(AlignPower-1), or 0 if AlignPower == 0). Parser defines the block
407 // context the alignment check appears in, and Prefix defines the context the
408 // alignment appears in.
extractAlignment(NaClBitcodeParser * Parser,const char * Prefix,uint32_t AlignPower)409 uint32_t extractAlignment(NaClBitcodeParser *Parser, const char *Prefix,
410 uint32_t AlignPower) {
411 if (AlignPower <= AlignPowerLimit + 1)
412 return (1 << AlignPower) >> 1;
413 std::string Buffer;
414 raw_string_ostream StrBuf(Buffer);
415 StrBuf << Prefix << " alignment greater than 2**" << AlignPowerLimit
416 << ". Found: 2**" << (AlignPower - 1);
417 Parser->Error(StrBuf.str());
418 // Error recover with value that is always acceptable.
419 return 1;
420 }
421
422 private:
423 // The translator associated with the parser.
424 Ice::Translator &Translator;
425
426 // ErrorStatus should only be updated while this lock is locked.
427 Ice::GlobalLockType ErrorReportingLock;
428 // The exit status that should be set to true if an error occurs.
429 Ice::ErrorCode &ErrorStatus;
430
431 // The types associated with each type ID.
432 std::vector<ExtendedType> TypeIDValues;
433 // The set of functions (prototype and defined).
434 Ice::FunctionDeclarationList FunctionDeclarations;
435 // The ID of the next possible defined function ID in FunctionDeclarations.
436 // FunctionDeclarations is filled first. It's the set of functions (either
437 // defined or isproto). Then function definitions are encountered/parsed and
438 // NextDefiningFunctionID is incremented to track the next actually-defined
439 // function.
440 size_t NextDefiningFunctionID = 0;
441 // The set of global variables.
442 std::unique_ptr<Ice::VariableDeclarationList> VariableDeclarations;
443 // Relocatable constants associated with global declarations.
444 Ice::ConstantList ValueIDConstants;
445 // Error recovery value to use when getFuncSigTypeByID fails.
446 Ice::FuncSigType UndefinedFuncSigType;
447 // Defines if a module block has already been parsed.
448 bool ParsedModuleBlock = false;
449
450 bool ParseBlock(unsigned BlockID) override;
451
452 // Gets extended type associated with the given index, assuming the extended
453 // type is of the WantedKind. Generates error message if corresponding
454 // extended type of WantedKind can't be found, and returns nullptr.
getTypeByIDAsKind(NaClBcIndexSize_t ID,ExtendedType::TypeKind WantedKind)455 ExtendedType *getTypeByIDAsKind(NaClBcIndexSize_t ID,
456 ExtendedType::TypeKind WantedKind) {
457 ExtendedType *Ty = nullptr;
458 if (ID < TypeIDValues.size()) {
459 Ty = &TypeIDValues[ID];
460 if (Ty->getKind() == WantedKind)
461 return Ty;
462 }
463 // Generate an error message and set ErrorStatus.
464 this->reportBadTypeIDAs(ID, Ty, WantedKind);
465 return nullptr;
466 }
467
468 // Gives Decl a name if it doesn't already have one. Prefix and NameIndex are
469 // used to generate the name. NameIndex is automatically incremented if a new
470 // name is created. DeclType is literal text describing the type of name being
471 // created. Also generates a warning if created names may conflict with named
472 // declarations.
installDeclarationName(Ice::GlobalDeclaration * Decl,const std::string & Prefix,const char * DeclType,NaClBcIndexSize_t & NameIndex)473 void installDeclarationName(Ice::GlobalDeclaration *Decl,
474 const std::string &Prefix, const char *DeclType,
475 NaClBcIndexSize_t &NameIndex) {
476 if (Decl->hasName()) {
477 Translator.checkIfUnnamedNameSafe(Decl->getName().toString(), DeclType,
478 Prefix);
479 } else {
480 Ice::GlobalContext *Ctx = Translator.getContext();
481 // Synthesize a dummy name if any of the following is true:
482 // - DUMP is enabled
483 // - The symbol is external
484 // - The -timing-funcs flag is enabled
485 // - Some RangeSpec is initialized with actual names
486 if (Ice::BuildDefs::dump() || !Decl->isInternal() ||
487 Ice::RangeSpec::hasNames() || Ice::getFlags().getTimeEachFunction()) {
488 Decl->setName(Ctx, Translator.createUnnamedName(Prefix, NameIndex));
489 } else {
490 Decl->setName(Ctx);
491 }
492 ++NameIndex;
493 }
494 }
495
496 // Installs names for global variables without names.
installGlobalVarNames()497 void installGlobalVarNames() {
498 assert(VariableDeclarations);
499 const std::string &GlobalPrefix = Ice::getFlags().getDefaultGlobalPrefix();
500 if (!GlobalPrefix.empty()) {
501 NaClBcIndexSize_t NameIndex = 0;
502 for (Ice::VariableDeclaration *Var : *VariableDeclarations) {
503 installDeclarationName(Var, GlobalPrefix, "global", NameIndex);
504 }
505 }
506 }
507
508 // Installs names for functions without names.
installFunctionNames()509 void installFunctionNames() {
510 const std::string &FunctionPrefix =
511 Ice::getFlags().getDefaultFunctionPrefix();
512 if (!FunctionPrefix.empty()) {
513 NaClBcIndexSize_t NameIndex = 0;
514 for (Ice::FunctionDeclaration *Func : FunctionDeclarations) {
515 installDeclarationName(Func, FunctionPrefix, "function", NameIndex);
516 }
517 }
518 }
519
520 // Builds a constant symbol named Name. IsExternal is true iff the symbol is
521 // external.
getConstantSym(Ice::GlobalString Name,bool IsExternal) const522 Ice::Constant *getConstantSym(Ice::GlobalString Name, bool IsExternal) const {
523 Ice::GlobalContext *Ctx = getTranslator().getContext();
524 if (IsExternal) {
525 return Ctx->getConstantExternSym(Name);
526 } else {
527 const Ice::RelocOffsetT Offset = 0;
528 return Ctx->getConstantSym(Offset, Name);
529 }
530 }
531
reportLinkageError(const char * Kind,const Ice::GlobalDeclaration & Decl)532 void reportLinkageError(const char *Kind,
533 const Ice::GlobalDeclaration &Decl) {
534 std::string Buffer;
535 raw_string_ostream StrBuf(Buffer);
536 StrBuf << Kind << " " << Decl.getName()
537 << " has incorrect linkage: " << Decl.getLinkageName();
538 if (Decl.isExternal())
539 StrBuf << "\n Use flag -allow-externally-defined-symbols to override";
540 Error(StrBuf.str());
541 }
542
543 // Converts function declarations into constant value IDs.
createValueIDsForFunctions()544 void createValueIDsForFunctions() {
545 Ice::GlobalContext *Ctx = getTranslator().getContext();
546 for (const Ice::FunctionDeclaration *Func : FunctionDeclarations) {
547 if (!Func->verifyLinkageCorrect(Ctx))
548 reportLinkageError("Function", *Func);
549 Ice::Constant *C = getConstantSym(Func->getName(), Func->isProto());
550 ValueIDConstants.push_back(C);
551 }
552 }
553
554 // Converts global variable declarations into constant value IDs.
createValueIDsForGlobalVars()555 void createValueIDsForGlobalVars() {
556 for (const Ice::VariableDeclaration *Decl : *VariableDeclarations) {
557 if (!Decl->verifyLinkageCorrect())
558 reportLinkageError("Global", *Decl);
559 Ice::Constant *C =
560 getConstantSym(Decl->getName(), !Decl->hasInitializer());
561 ValueIDConstants.push_back(C);
562 }
563 }
564
565 // Reports that type ID is undefined, or not of the WantedType.
566 void reportBadTypeIDAs(NaClBcIndexSize_t ID, const ExtendedType *Ty,
567 ExtendedType::TypeKind WantedType);
568
569 // Reports that there is no function declaration for ID. Returns an error
570 // recovery value to use.
571 Ice::FunctionDeclaration *reportGetFunctionByIDError(NaClBcIndexSize_t ID);
572
573 // Reports that there is not global variable declaration for ID. Returns an
574 // error recovery value to use.
575 Ice::VariableDeclaration *
576 reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index);
577
578 // Reports that there is no corresponding ICE type for LLVMTy, and returns
579 // Ice::IceType_void.
580 Ice::Type convertToIceTypeError(Type *LLVMTy);
581 };
582
ErrorAt(naclbitc::ErrorLevel Level,uint64_t Bit,const std::string & Message)583 bool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
584 const std::string &Message) {
585 Ice::GlobalContext *Context = Translator.getContext();
586 {
587 std::unique_lock<Ice::GlobalLockType> _(ErrorReportingLock);
588 ErrorStatus.assign(Ice::EC_Bitcode);
589 }
590 { // Lock while printing out error message.
591 Ice::OstreamLocker L(Context);
592 raw_ostream &OldErrStream = setErrStream(Context->getStrError());
593 NaClBitcodeParser::ErrorAt(Level, Bit, Message);
594 setErrStream(OldErrStream);
595 }
596 if (Level >= naclbitc::Error && !Ice::getFlags().getAllowErrorRecovery())
597 Fatal();
598 return true;
599 }
600
reportBadTypeIDAs(NaClBcIndexSize_t ID,const ExtendedType * Ty,ExtendedType::TypeKind WantedType)601 void TopLevelParser::reportBadTypeIDAs(NaClBcIndexSize_t ID,
602 const ExtendedType *Ty,
603 ExtendedType::TypeKind WantedType) {
604 std::string Buffer;
605 raw_string_ostream StrBuf(Buffer);
606 if (Ty == nullptr) {
607 StrBuf << "Can't find extended type for type id: " << ID;
608 } else {
609 StrBuf << "Type id " << ID << " not " << WantedType << ". Found: " << *Ty;
610 }
611 blockError(StrBuf.str());
612 }
613
614 Ice::FunctionDeclaration *
reportGetFunctionByIDError(NaClBcIndexSize_t ID)615 TopLevelParser::reportGetFunctionByIDError(NaClBcIndexSize_t ID) {
616 std::string Buffer;
617 raw_string_ostream StrBuf(Buffer);
618 StrBuf << "Function index " << ID
619 << " not allowed. Out of range. Must be less than "
620 << FunctionDeclarations.size();
621 blockError(StrBuf.str());
622 if (!FunctionDeclarations.empty())
623 return FunctionDeclarations[0];
624 Fatal();
625 }
626
627 Ice::VariableDeclaration *
reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index)628 TopLevelParser::reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index) {
629 std::string Buffer;
630 raw_string_ostream StrBuf(Buffer);
631 StrBuf << "Global index " << Index
632 << " not allowed. Out of range. Must be less than "
633 << VariableDeclarations->size();
634 blockError(StrBuf.str());
635 if (!VariableDeclarations->empty())
636 return VariableDeclarations->at(0);
637 Fatal();
638 }
639
convertToIceTypeError(Type * LLVMTy)640 Ice::Type TopLevelParser::convertToIceTypeError(Type *LLVMTy) {
641 std::string Buffer;
642 raw_string_ostream StrBuf(Buffer);
643 StrBuf << "Invalid LLVM type: " << *LLVMTy;
644 Error(StrBuf.str());
645 return Ice::IceType_void;
646 }
647
verifyFunctionTypeSignatures()648 void TopLevelParser::verifyFunctionTypeSignatures() {
649 const Ice::GlobalContext *Ctx = getTranslator().getContext();
650 for (Ice::FunctionDeclaration *FuncDecl : FunctionDeclarations) {
651 if (!FuncDecl->validateTypeSignature(Ctx))
652 Error(FuncDecl->getTypeSignatureError(Ctx));
653 }
654 }
655
656 // Base class for parsing blocks within the bitcode file. Note: Because this is
657 // the base class of block parsers, we generate error messages if ParseBlock or
658 // ParseRecord is not overridden in derived classes.
659 class BlockParserBaseClass : public NaClBitcodeParser {
660 BlockParserBaseClass() = delete;
661 BlockParserBaseClass(const BlockParserBaseClass &) = delete;
662 BlockParserBaseClass &operator=(const BlockParserBaseClass &) = delete;
663
664 public:
665 // Constructor for the top-level module block parser.
BlockParserBaseClass(unsigned BlockID,TopLevelParser * Context)666 BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context)
667 : NaClBitcodeParser(BlockID, Context), Context(Context) {}
668
BlockParserBaseClass(unsigned BlockID,BlockParserBaseClass * EnclosingParser,NaClBitstreamCursor & Cursor)669 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser,
670 NaClBitstreamCursor &Cursor)
671 : NaClBitcodeParser(BlockID, EnclosingParser, Cursor),
672 Context(EnclosingParser->Context) {}
673
~BlockParserBaseClass()674 ~BlockParserBaseClass() override {}
675
676 // Returns the printable name of the type of block being parsed.
getBlockName() const677 virtual const char *getBlockName() const {
678 // If this class is used, it is parsing an unknown block.
679 return "unknown";
680 }
681
682 // Generates an error Message with the Bit address prefixed to it.
683 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
684 const std::string &Message) override;
685
686 protected:
687 // The context parser that contains the decoded state.
688 TopLevelParser *Context;
689 // True if ErrorAt has been called in this block.
690 bool BlockHasError = false;
691
692 // Constructor for nested block parsers.
BlockParserBaseClass(unsigned BlockID,BlockParserBaseClass * EnclosingParser)693 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
694 : NaClBitcodeParser(BlockID, EnclosingParser),
695 Context(EnclosingParser->Context) {}
696
697 // Gets the translator associated with the bitcode parser.
getTranslator() const698 Ice::Translator &getTranslator() const { return Context->getTranslator(); }
699
700 // Default implementation. Reports that block is unknown and skips its
701 // contents.
702 bool ParseBlock(unsigned BlockID) override;
703
704 // Default implementation. Reports that the record is not understood.
705 void ProcessRecord() override;
706
707 // Checks if the size of the record is Size. Return true if valid. Otherwise
708 // generates an error and returns false.
isValidRecordSize(size_t Size,const char * RecordName)709 bool isValidRecordSize(size_t Size, const char *RecordName) {
710 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
711 if (Values.size() == Size)
712 return true;
713 reportRecordSizeError(Size, RecordName, nullptr);
714 return false;
715 }
716
717 // Checks if the size of the record is at least as large as the LowerLimit.
718 // Returns true if valid. Otherwise generates an error and returns false.
isValidRecordSizeAtLeast(size_t LowerLimit,const char * RecordName)719 bool isValidRecordSizeAtLeast(size_t LowerLimit, const char *RecordName) {
720 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
721 if (Values.size() >= LowerLimit)
722 return true;
723 reportRecordSizeError(LowerLimit, RecordName, "at least");
724 return false;
725 }
726
727 // Checks if the size of the record is no larger than the
728 // UpperLimit. Returns true if valid. Otherwise generates an error and
729 // returns false.
isValidRecordSizeAtMost(size_t UpperLimit,const char * RecordName)730 bool isValidRecordSizeAtMost(size_t UpperLimit, const char *RecordName) {
731 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
732 if (Values.size() <= UpperLimit)
733 return true;
734 reportRecordSizeError(UpperLimit, RecordName, "no more than");
735 return false;
736 }
737
738 // Checks if the size of the record is at least as large as the LowerLimit,
739 // and no larger than the UpperLimit. Returns true if valid. Otherwise
740 // generates an error and returns false.
isValidRecordSizeInRange(size_t LowerLimit,size_t UpperLimit,const char * RecordName)741 bool isValidRecordSizeInRange(size_t LowerLimit, size_t UpperLimit,
742 const char *RecordName) {
743 return isValidRecordSizeAtLeast(LowerLimit, RecordName) ||
744 isValidRecordSizeAtMost(UpperLimit, RecordName);
745 }
746
747 private:
748 /// Generates a record size error. ExpectedSize is the number of elements
749 /// expected. RecordName is the name of the kind of record that has incorrect
750 /// size. ContextMessage (if not nullptr) is appended to "record expects" to
751 /// describe how ExpectedSize should be interpreted.
752 void reportRecordSizeError(size_t ExpectedSize, const char *RecordName,
753 const char *ContextMessage);
754 };
755
blockError(const std::string & Message)756 bool TopLevelParser::blockError(const std::string &Message) {
757 // TODO(kschimpf): Remove this method. This method used to redirect
758 // block-level errors to the block we are in, rather than the top-level
759 // block. This gave better bit location for error messages. However, with
760 // parallel parsing, we can't keep a field to redirect (there could be many
761 // and we don't know which block parser applies). Hence, This redirect can't
762 // be applied anymore.
763 return Error(Message);
764 }
765
766 // Generates an error Message with the bit address prefixed to it.
ErrorAt(naclbitc::ErrorLevel Level,uint64_t Bit,const std::string & Message)767 bool BlockParserBaseClass::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
768 const std::string &Message) {
769 BlockHasError = true;
770 std::string Buffer;
771 raw_string_ostream StrBuf(Buffer);
772 // Note: If dump routines have been turned off, the error messages will not
773 // be readable. Hence, replace with simple error. We also use the simple form
774 // for unit tests.
775 if (Ice::getFlags().getGenerateUnitTestMessages()) {
776 StrBuf << "Invalid " << getBlockName() << " record: <" << Record.GetCode();
777 for (const uint64_t Val : Record.GetValues()) {
778 StrBuf << " " << Val;
779 }
780 StrBuf << ">";
781 } else {
782 StrBuf << Message;
783 }
784 return Context->ErrorAt(Level, Record.GetCursor().getErrorBitNo(Bit),
785 StrBuf.str());
786 }
787
reportRecordSizeError(size_t ExpectedSize,const char * RecordName,const char * ContextMessage)788 void BlockParserBaseClass::reportRecordSizeError(size_t ExpectedSize,
789 const char *RecordName,
790 const char *ContextMessage) {
791 std::string Buffer;
792 raw_string_ostream StrBuf(Buffer);
793 const char *BlockName = getBlockName();
794 const char FirstChar = toupper(*BlockName);
795 StrBuf << FirstChar << (BlockName + 1) << " " << RecordName
796 << " record expects";
797 if (ContextMessage)
798 StrBuf << " " << ContextMessage;
799 StrBuf << " " << ExpectedSize << " argument";
800 if (ExpectedSize > 1)
801 StrBuf << "s";
802 StrBuf << ". Found: " << Record.GetValues().size();
803 Error(StrBuf.str());
804 }
805
ParseBlock(unsigned BlockID)806 bool BlockParserBaseClass::ParseBlock(unsigned BlockID) {
807 // If called, derived class doesn't know how to handle block. Report error
808 // and skip.
809 std::string Buffer;
810 raw_string_ostream StrBuf(Buffer);
811 StrBuf << "Don't know how to parse block id: " << BlockID;
812 Error(StrBuf.str());
813 SkipBlock();
814 return false;
815 }
816
ProcessRecord()817 void BlockParserBaseClass::ProcessRecord() {
818 // If called, derived class doesn't know how to handle.
819 std::string Buffer;
820 raw_string_ostream StrBuf(Buffer);
821 StrBuf << "Don't know how to process " << getBlockName()
822 << " record:" << Record;
823 Error(StrBuf.str());
824 }
825
826 // Class to parse a types block.
827 class TypesParser final : public BlockParserBaseClass {
828 TypesParser() = delete;
829 TypesParser(const TypesParser &) = delete;
830 TypesParser &operator=(const TypesParser &) = delete;
831
832 public:
TypesParser(unsigned BlockID,BlockParserBaseClass * EnclosingParser)833 TypesParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
834 : BlockParserBaseClass(BlockID, EnclosingParser),
835 Timer(Ice::TimerStack::TT_parseTypes, getTranslator().getContext()) {}
836
~TypesParser()837 ~TypesParser() override {
838 if (ExpectedNumTypes != Context->getNumTypeIDValues()) {
839 std::string Buffer;
840 raw_string_ostream StrBuf(Buffer);
841 StrBuf << "Types block expected " << ExpectedNumTypes
842 << " types but found: " << NextTypeId;
843 Error(StrBuf.str());
844 }
845 }
846
847 private:
848 Ice::TimerMarker Timer;
849 // The type ID that will be associated with the next type defining record in
850 // the types block.
851 NaClBcIndexSize_t NextTypeId = 0;
852
853 // The expected number of types, based on record TYPE_CODE_NUMENTRY.
854 NaClBcIndexSize_t ExpectedNumTypes = 0;
855
856 void ProcessRecord() override;
857
getBlockName() const858 const char *getBlockName() const override { return "type"; }
859
setNextTypeIDAsSimpleType(Ice::Type Ty)860 void setNextTypeIDAsSimpleType(Ice::Type Ty) {
861 Context->getTypeByIDForDefining(NextTypeId++)->setAsSimpleType(Ty);
862 }
863 };
864
ProcessRecord()865 void TypesParser::ProcessRecord() {
866 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
867 switch (Record.GetCode()) {
868 case naclbitc::TYPE_CODE_NUMENTRY: {
869 // NUMENTRY: [numentries]
870 if (!isValidRecordSize(1, "count"))
871 return;
872 uint64_t Size = Values[0];
873 if (Size > NaClBcIndexSize_t_Max) {
874 std::string Buffer;
875 raw_string_ostream StrBuf(Buffer);
876 StrBuf << "Size to big for count record: " << Size;
877 Error(StrBuf.str());
878 ExpectedNumTypes = NaClBcIndexSize_t_Max;
879 }
880 // The code double checks that Expected size and the actual size at the end
881 // of the block. To reduce allocations we preallocate the space.
882 //
883 // However, if the number is large, we suspect that the number is
884 // (possibly) incorrect. In that case, we preallocate a smaller space.
885 constexpr uint64_t DefaultLargeResizeValue = 1000000;
886 Context->resizeTypeIDValues(std::min(Size, DefaultLargeResizeValue));
887 ExpectedNumTypes = Size;
888 return;
889 }
890 case naclbitc::TYPE_CODE_VOID:
891 // VOID
892 if (!isValidRecordSize(0, "void"))
893 return;
894 setNextTypeIDAsSimpleType(Ice::IceType_void);
895 return;
896 case naclbitc::TYPE_CODE_FLOAT:
897 // FLOAT
898 if (!isValidRecordSize(0, "float"))
899 return;
900 setNextTypeIDAsSimpleType(Ice::IceType_f32);
901 return;
902 case naclbitc::TYPE_CODE_DOUBLE:
903 // DOUBLE
904 if (!isValidRecordSize(0, "double"))
905 return;
906 setNextTypeIDAsSimpleType(Ice::IceType_f64);
907 return;
908 case naclbitc::TYPE_CODE_INTEGER:
909 // INTEGER: [width]
910 if (!isValidRecordSize(1, "integer"))
911 return;
912 switch (Values[0]) {
913 case 1:
914 setNextTypeIDAsSimpleType(Ice::IceType_i1);
915 return;
916 case 8:
917 setNextTypeIDAsSimpleType(Ice::IceType_i8);
918 return;
919 case 16:
920 setNextTypeIDAsSimpleType(Ice::IceType_i16);
921 return;
922 case 32:
923 setNextTypeIDAsSimpleType(Ice::IceType_i32);
924 return;
925 case 64:
926 setNextTypeIDAsSimpleType(Ice::IceType_i64);
927 return;
928 default:
929 break;
930 }
931 {
932 std::string Buffer;
933 raw_string_ostream StrBuf(Buffer);
934 StrBuf << "Type integer record with invalid bitsize: " << Values[0];
935 Error(StrBuf.str());
936 }
937 return;
938 case naclbitc::TYPE_CODE_VECTOR: {
939 // VECTOR: [numelts, eltty]
940 if (!isValidRecordSize(2, "vector"))
941 return;
942 Ice::Type BaseTy = Context->getSimpleTypeByID(Values[1]);
943 Ice::SizeT Size = Values[0];
944 switch (BaseTy) {
945 case Ice::IceType_i1:
946 switch (Size) {
947 case 4:
948 setNextTypeIDAsSimpleType(Ice::IceType_v4i1);
949 return;
950 case 8:
951 setNextTypeIDAsSimpleType(Ice::IceType_v8i1);
952 return;
953 case 16:
954 setNextTypeIDAsSimpleType(Ice::IceType_v16i1);
955 return;
956 default:
957 break;
958 }
959 break;
960 case Ice::IceType_i8:
961 if (Size == 16) {
962 setNextTypeIDAsSimpleType(Ice::IceType_v16i8);
963 return;
964 }
965 break;
966 case Ice::IceType_i16:
967 if (Size == 8) {
968 setNextTypeIDAsSimpleType(Ice::IceType_v8i16);
969 return;
970 }
971 break;
972 case Ice::IceType_i32:
973 if (Size == 4) {
974 setNextTypeIDAsSimpleType(Ice::IceType_v4i32);
975 return;
976 }
977 break;
978 case Ice::IceType_f32:
979 if (Size == 4) {
980 setNextTypeIDAsSimpleType(Ice::IceType_v4f32);
981 return;
982 }
983 break;
984 default:
985 break;
986 }
987 {
988 std::string Buffer;
989 raw_string_ostream StrBuf(Buffer);
990 StrBuf << "Invalid type vector record: <" << Values[0] << " x " << BaseTy
991 << ">";
992 Error(StrBuf.str());
993 }
994 return;
995 }
996 case naclbitc::TYPE_CODE_FUNCTION: {
997 // FUNCTION: [vararg, retty, paramty x N]
998 if (!isValidRecordSizeAtLeast(2, "signature"))
999 return;
1000 if (Values[0])
1001 Error("Function type can't define varargs");
1002 ExtendedType *Ty = Context->getTypeByIDForDefining(NextTypeId++);
1003 Ty->setAsFunctionType();
1004 auto *FuncTy = cast<FuncSigExtendedType>(Ty);
1005 FuncTy->setReturnType(Context->getSimpleTypeByID(Values[1]));
1006 for (size_t i = 2, e = Values.size(); i != e; ++i) {
1007 // Check that type void not used as argument type. Note: PNaCl
1008 // restrictions can't be checked until we know the name, because we have
1009 // to check for intrinsic signatures.
1010 Ice::Type ArgTy = Context->getSimpleTypeByID(Values[i]);
1011 if (ArgTy == Ice::IceType_void) {
1012 std::string Buffer;
1013 raw_string_ostream StrBuf(Buffer);
1014 StrBuf << "Type for parameter " << (i - 1)
1015 << " not valid. Found: " << ArgTy;
1016 ArgTy = Ice::IceType_i32;
1017 }
1018 FuncTy->appendArgType(ArgTy);
1019 }
1020 return;
1021 }
1022 default:
1023 BlockParserBaseClass::ProcessRecord();
1024 return;
1025 }
1026 llvm_unreachable("Unknown type block record not processed!");
1027 }
1028
1029 /// Parses the globals block (i.e. global variable declarations and
1030 /// corresponding initializers).
1031 class GlobalsParser final : public BlockParserBaseClass {
1032 GlobalsParser() = delete;
1033 GlobalsParser(const GlobalsParser &) = delete;
1034 GlobalsParser &operator=(const GlobalsParser &) = delete;
1035
1036 public:
GlobalsParser(unsigned BlockID,BlockParserBaseClass * EnclosingParser)1037 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
1038 : BlockParserBaseClass(BlockID, EnclosingParser),
1039 Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()),
1040 NumFunctionIDs(Context->getNumFunctionIDs()),
1041 DummyGlobalVar(Ice::VariableDeclaration::create(
1042 Context->getGlobalVariablesPool())),
1043 CurGlobalVar(DummyGlobalVar) {
1044 Context->getGlobalVariablesPool()->willNotBeEmitted(DummyGlobalVar);
1045 }
1046
1047 ~GlobalsParser() override = default;
1048
getBlockName() const1049 const char *getBlockName() const override { return "globals"; }
1050
1051 private:
1052 using GlobalVarsMapType =
1053 std::unordered_map<NaClBcIndexSize_t, Ice::VariableDeclaration *>;
1054
1055 Ice::TimerMarker Timer;
1056
1057 // Holds global variables generated/referenced in the global variables block.
1058 GlobalVarsMapType GlobalVarsMap;
1059
1060 // Holds the number of defined function IDs.
1061 NaClBcIndexSize_t NumFunctionIDs;
1062
1063 // Holds the specified number of global variables by the count record in the
1064 // global variables block.
1065 NaClBcIndexSize_t SpecifiedNumberVars = 0;
1066
1067 // Keeps track of how many initializers are expected for the global variable
1068 // declaration being built.
1069 NaClBcIndexSize_t InitializersNeeded = 0;
1070
1071 // The index of the next global variable declaration.
1072 NaClBcIndexSize_t NextGlobalID = 0;
1073
1074 // Dummy global variable declaration to guarantee CurGlobalVar is always
1075 // defined (allowing code to not need to check if CurGlobalVar is nullptr).
1076 Ice::VariableDeclaration *DummyGlobalVar;
1077
1078 // Holds the current global variable declaration being built.
1079 Ice::VariableDeclaration *CurGlobalVar;
1080
1081 // Returns the global variable associated with the given Index.
getGlobalVarByID(NaClBcIndexSize_t Index)1082 Ice::VariableDeclaration *getGlobalVarByID(NaClBcIndexSize_t Index) {
1083 Ice::VariableDeclaration *&Decl = GlobalVarsMap[Index];
1084 if (Decl == nullptr)
1085 Decl =
1086 Ice::VariableDeclaration::create(Context->getGlobalVariablesPool());
1087 return Decl;
1088 }
1089
1090 // Returns the global declaration associated with the given index.
getGlobalDeclByID(NaClBcIndexSize_t Index)1091 Ice::GlobalDeclaration *getGlobalDeclByID(NaClBcIndexSize_t Index) {
1092 if (Index < NumFunctionIDs)
1093 return Context->getFunctionByID(Index);
1094 return getGlobalVarByID(Index - NumFunctionIDs);
1095 }
1096
1097 // If global variables parsed correctly, install them into the top-level
1098 // context.
installGlobalVariables()1099 void installGlobalVariables() {
1100 // Verify specified number of globals matches number found.
1101 size_t NumGlobals = GlobalVarsMap.size();
1102 if (SpecifiedNumberVars != NumGlobals ||
1103 SpecifiedNumberVars != NextGlobalID) {
1104 std::string Buffer;
1105 raw_string_ostream StrBuf(Buffer);
1106 StrBuf << getBlockName() << " block expects " << SpecifiedNumberVars
1107 << " global variables. Found: " << GlobalVarsMap.size();
1108 Error(StrBuf.str());
1109 return;
1110 }
1111 // Install global variables into top-level context.
1112 for (size_t I = 0; I < NumGlobals; ++I)
1113 Context->addGlobalDeclaration(GlobalVarsMap[I]);
1114 }
1115
ExitBlock()1116 void ExitBlock() override {
1117 verifyNoMissingInitializers();
1118 installGlobalVariables();
1119 BlockParserBaseClass::ExitBlock();
1120 }
1121
1122 void ProcessRecord() override;
1123
1124 // Checks if the number of initializers for the CurGlobalVar is the same as
1125 // the number found in the bitcode file. If different, and error message is
1126 // generated, and the internal state of the parser is fixed so this condition
1127 // is no longer violated.
verifyNoMissingInitializers()1128 void verifyNoMissingInitializers() {
1129 size_t NumInits = CurGlobalVar->getInitializers().size();
1130 if (InitializersNeeded != NumInits) {
1131 std::string Buffer;
1132 raw_string_ostream StrBuf(Buffer);
1133 StrBuf << "Global variable @g" << NextGlobalID << " expected "
1134 << InitializersNeeded << " initializer";
1135 if (InitializersNeeded > 1)
1136 StrBuf << "s";
1137 StrBuf << ". Found: " << NumInits;
1138 Error(StrBuf.str());
1139 InitializersNeeded = NumInits;
1140 }
1141 }
1142 };
1143
ProcessRecord()1144 void GlobalsParser::ProcessRecord() {
1145 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1146 switch (Record.GetCode()) {
1147 case naclbitc::GLOBALVAR_COUNT:
1148 // COUNT: [n]
1149 if (!isValidRecordSize(1, "count"))
1150 return;
1151 if (SpecifiedNumberVars || NextGlobalID) {
1152 Error("Globals count record not first in block.");
1153 return;
1154 }
1155 SpecifiedNumberVars = Values[0];
1156 return;
1157 case naclbitc::GLOBALVAR_VAR: {
1158 // VAR: [align, isconst]
1159 if (!isValidRecordSize(2, "variable"))
1160 return;
1161 verifyNoMissingInitializers();
1162 // Always build the global variable, even if IR generation is turned off.
1163 // This is needed because we need a placeholder in the top-level context
1164 // when no IR is generated.
1165 uint32_t Alignment =
1166 Context->extractAlignment(this, "Global variable", Values[0]);
1167 CurGlobalVar = getGlobalVarByID(NextGlobalID);
1168 InitializersNeeded = 1;
1169 CurGlobalVar->setAlignment(Alignment);
1170 CurGlobalVar->setIsConstant(Values[1] != 0);
1171 ++NextGlobalID;
1172 return;
1173 }
1174 case naclbitc::GLOBALVAR_COMPOUND:
1175 // COMPOUND: [size]
1176 if (!isValidRecordSize(1, "compound"))
1177 return;
1178 if (!CurGlobalVar->getInitializers().empty()) {
1179 Error("Globals compound record not first initializer");
1180 return;
1181 }
1182 if (Values[0] < 2) {
1183 std::string Buffer;
1184 raw_string_ostream StrBuf(Buffer);
1185 StrBuf << getBlockName()
1186 << " compound record size invalid. Found: " << Values[0];
1187 Error(StrBuf.str());
1188 return;
1189 }
1190 InitializersNeeded = Values[0];
1191 return;
1192 case naclbitc::GLOBALVAR_ZEROFILL: {
1193 // ZEROFILL: [size]
1194 if (!isValidRecordSize(1, "zerofill"))
1195 return;
1196 auto *Pool = Context->getGlobalVariablesPool();
1197 CurGlobalVar->addInitializer(
1198 Ice::VariableDeclaration::ZeroInitializer::create(Pool, Values[0]));
1199 return;
1200 }
1201 case naclbitc::GLOBALVAR_DATA: {
1202 // DATA: [b0, b1, ...]
1203 if (!isValidRecordSizeAtLeast(1, "data"))
1204 return;
1205 auto *Pool = Context->getGlobalVariablesPool();
1206 CurGlobalVar->addInitializer(
1207 Ice::VariableDeclaration::DataInitializer::create(Pool, Values));
1208 return;
1209 }
1210 case naclbitc::GLOBALVAR_RELOC: {
1211 // RELOC: [val, [addend]]
1212 if (!isValidRecordSizeInRange(1, 2, "reloc"))
1213 return;
1214 NaClBcIndexSize_t Index = Values[0];
1215 NaClBcIndexSize_t IndexLimit = SpecifiedNumberVars + NumFunctionIDs;
1216 if (Index >= IndexLimit) {
1217 std::string Buffer;
1218 raw_string_ostream StrBuf(Buffer);
1219 StrBuf << "Relocation index " << Index << " to big. Expect index < "
1220 << IndexLimit;
1221 Error(StrBuf.str());
1222 }
1223 uint64_t Offset = 0;
1224 if (Values.size() == 2) {
1225 Offset = Values[1];
1226 if (Offset > std::numeric_limits<uint32_t>::max()) {
1227 std::string Buffer;
1228 raw_string_ostream StrBuf(Buffer);
1229 StrBuf << "Addend of global reloc record too big: " << Offset;
1230 Error(StrBuf.str());
1231 }
1232 }
1233 auto *Pool = Context->getGlobalVariablesPool();
1234 Ice::GlobalContext *Ctx = getTranslator().getContext();
1235 CurGlobalVar->addInitializer(
1236 Ice::VariableDeclaration::RelocInitializer::create(
1237 Pool, getGlobalDeclByID(Index),
1238 {Ice::RelocOffset::create(Ctx, Offset)}));
1239 return;
1240 }
1241 default:
1242 BlockParserBaseClass::ProcessRecord();
1243 return;
1244 }
1245 }
1246
1247 /// Base class for parsing a valuesymtab block in the bitcode file.
1248 class ValuesymtabParser : public BlockParserBaseClass {
1249 ValuesymtabParser() = delete;
1250 ValuesymtabParser(const ValuesymtabParser &) = delete;
1251 void operator=(const ValuesymtabParser &) = delete;
1252
1253 public:
ValuesymtabParser(unsigned BlockID,BlockParserBaseClass * EnclosingParser)1254 ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
1255 : BlockParserBaseClass(BlockID, EnclosingParser) {}
1256
1257 ~ValuesymtabParser() override = default;
1258
getBlockName() const1259 const char *getBlockName() const override { return "valuesymtab"; }
1260
1261 protected:
1262 using StringType = SmallString<128>;
1263
1264 // Returns the name to identify the kind of symbol table this is
1265 // in error messages.
1266 virtual const char *getTableKind() const = 0;
1267
1268 // Associates Name with the value defined by the given Index.
1269 virtual void setValueName(NaClBcIndexSize_t Index, StringType &Name) = 0;
1270
1271 // Associates Name with the value defined by the given Index;
1272 virtual void setBbName(NaClBcIndexSize_t Index, StringType &Name) = 0;
1273
1274 // Reports that the assignment of Name to the value associated with
1275 // index is not possible, for the given Context.
1276 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index,
1277 StringType &Name);
1278
1279 private:
1280 using NamesSetType = std::unordered_set<StringType>;
1281 NamesSetType ValueNames;
1282 NamesSetType BlockNames;
1283
1284 void ProcessRecord() override;
1285
1286 // Extracts out ConvertedName. Returns true if unique wrt to Names.
convertToString(NamesSetType & Names,StringType & ConvertedName)1287 bool convertToString(NamesSetType &Names, StringType &ConvertedName) {
1288 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1289 for (size_t i = 1, e = Values.size(); i != e; ++i) {
1290 ConvertedName += static_cast<char>(Values[i]);
1291 }
1292 auto Pair = Names.insert(ConvertedName);
1293 return Pair.second;
1294 }
1295
1296 void ReportDuplicateName(const char *NameCat, StringType &Name);
1297 };
1298
reportUnableToAssign(const char * Context,NaClBcIndexSize_t Index,StringType & Name)1299 void ValuesymtabParser::reportUnableToAssign(const char *Context,
1300 NaClBcIndexSize_t Index,
1301 StringType &Name) {
1302 std::string Buffer;
1303 raw_string_ostream StrBuf(Buffer);
1304 StrBuf << getTableKind() << " " << getBlockName() << ": " << Context
1305 << " name '" << Name << "' can't be associated with index " << Index;
1306 Error(StrBuf.str());
1307 }
1308
ReportDuplicateName(const char * NameCat,StringType & Name)1309 void ValuesymtabParser::ReportDuplicateName(const char *NameCat,
1310 StringType &Name) {
1311 std::string Buffer;
1312 raw_string_ostream StrBuf(Buffer);
1313 StrBuf << getTableKind() << " " << getBlockName() << " defines duplicate "
1314 << NameCat << " name: '" << Name << "'";
1315 Error(StrBuf.str());
1316 }
1317
ProcessRecord()1318 void ValuesymtabParser::ProcessRecord() {
1319 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1320 StringType ConvertedName;
1321 switch (Record.GetCode()) {
1322 case naclbitc::VST_CODE_ENTRY: {
1323 // VST_ENTRY: [ValueId, namechar x N]
1324 if (!isValidRecordSizeAtLeast(2, "value entry"))
1325 return;
1326 if (convertToString(ValueNames, ConvertedName))
1327 setValueName(Values[0], ConvertedName);
1328 else
1329 ReportDuplicateName("value", ConvertedName);
1330 return;
1331 }
1332 case naclbitc::VST_CODE_BBENTRY: {
1333 // VST_BBENTRY: [BbId, namechar x N]
1334 if (!isValidRecordSizeAtLeast(2, "basic block entry"))
1335 return;
1336 if (convertToString(BlockNames, ConvertedName))
1337 setBbName(Values[0], ConvertedName);
1338 else
1339 ReportDuplicateName("block", ConvertedName);
1340 return;
1341 }
1342 default:
1343 break;
1344 }
1345 // If reached, don't know how to handle record.
1346 BlockParserBaseClass::ProcessRecord();
1347 return;
1348 }
1349
1350 /// Parses function blocks in the bitcode file.
1351 class FunctionParser final : public BlockParserBaseClass {
1352 FunctionParser() = delete;
1353 FunctionParser(const FunctionParser &) = delete;
1354 FunctionParser &operator=(const FunctionParser &) = delete;
1355
1356 public:
FunctionParser(unsigned BlockID,BlockParserBaseClass * EnclosingParser,NaClBcIndexSize_t FcnId)1357 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser,
1358 NaClBcIndexSize_t FcnId)
1359 : BlockParserBaseClass(BlockID, EnclosingParser),
1360 Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()),
1361 Func(nullptr), FuncDecl(Context->getFunctionByID(FcnId)),
1362 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()),
1363 NextLocalInstIndex(Context->getNumGlobalIDs()) {}
1364
FunctionParser(unsigned BlockID,BlockParserBaseClass * EnclosingParser,NaClBcIndexSize_t FcnId,NaClBitstreamCursor & Cursor)1365 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser,
1366 NaClBcIndexSize_t FcnId, NaClBitstreamCursor &Cursor)
1367 : BlockParserBaseClass(BlockID, EnclosingParser, Cursor),
1368 Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()),
1369 Func(nullptr), FuncDecl(Context->getFunctionByID(FcnId)),
1370 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()),
1371 NextLocalInstIndex(Context->getNumGlobalIDs()) {}
1372
parseFunction(uint32_t SeqNumber)1373 std::unique_ptr<Ice::Cfg> parseFunction(uint32_t SeqNumber) {
1374 bool ParserResult;
1375 Ice::GlobalContext *Ctx = getTranslator().getContext();
1376 {
1377 Ice::TimerMarker T(Ctx, FuncDecl->getName().toStringOrEmpty());
1378 // Note: The Cfg is created, even when IR generation is disabled. This is
1379 // done to install a CfgLocalAllocator for various internal containers.
1380 Ice::GlobalContext *Ctx = getTranslator().getContext();
1381 Func = Ice::Cfg::create(Ctx, SeqNumber);
1382
1383 Ice::CfgLocalAllocatorScope _(Func.get());
1384
1385 // TODO(kschimpf) Clean up API to add a function signature to a CFG.
1386 const Ice::FuncSigType &Signature = FuncDecl->getSignature();
1387
1388 Func->setFunctionName(FuncDecl->getName());
1389 Func->setReturnType(Signature.getReturnType());
1390 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage);
1391 CurrentNode = installNextBasicBlock();
1392 Func->setEntryNode(CurrentNode);
1393 for (Ice::Type ArgType : Signature.getArgList()) {
1394 Func->addArg(getNextInstVar(ArgType));
1395 }
1396
1397 ParserResult = ParseThisBlock();
1398 }
1399
1400 if (ParserResult || BlockHasError)
1401 Func->setError("Unable to parse function");
1402
1403 return std::move(Func);
1404 }
1405
1406 ~FunctionParser() override = default;
1407
getBlockName() const1408 const char *getBlockName() const override { return "function"; }
1409
getFunc() const1410 Ice::Cfg *getFunc() const { return Func.get(); }
1411
getNumGlobalIDs() const1412 size_t getNumGlobalIDs() const { return CachedNumGlobalValueIDs; }
1413
setNextLocalInstIndex(Ice::Operand * Op)1414 void setNextLocalInstIndex(Ice::Operand *Op) {
1415 setOperand(NextLocalInstIndex++, Op);
1416 }
1417
1418 // Set the next constant ID to the given constant C.
setNextConstantID(Ice::Constant * C)1419 void setNextConstantID(Ice::Constant *C) { setNextLocalInstIndex(C); }
1420
1421 // Returns the value referenced by the given value Index.
getOperand(NaClBcIndexSize_t Index)1422 Ice::Operand *getOperand(NaClBcIndexSize_t Index) {
1423 if (Index < CachedNumGlobalValueIDs) {
1424 return Context->getGlobalConstantByID(Index);
1425 }
1426 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs;
1427 if (LocalIndex >= LocalOperands.size())
1428 reportGetOperandUndefined(Index);
1429 Ice::Operand *Op = LocalOperands[LocalIndex];
1430 if (Op == nullptr)
1431 reportGetOperandUndefined(Index);
1432 return Op;
1433 }
1434
1435 private:
1436 Ice::TimerMarker Timer;
1437 // The number of words in the bitstream defining the function block.
1438 uint64_t NumBytesDefiningFunction = 0;
1439 // Maximum number of records that can appear in the function block, based on
1440 // the number of bytes defining the function block.
1441 uint64_t MaxRecordsInBlock = 0;
1442 // The corresponding ICE function defined by the function block.
1443 std::unique_ptr<Ice::Cfg> Func;
1444 // The index to the current basic block being built.
1445 NaClBcIndexSize_t CurrentBbIndex = 0;
1446 // The number of basic blocks declared for the function block.
1447 NaClBcIndexSize_t DeclaredNumberBbs = 0;
1448 // The basic block being built.
1449 Ice::CfgNode *CurrentNode = nullptr;
1450 // The corresponding function declaration.
1451 Ice::FunctionDeclaration *FuncDecl;
1452 // Holds the dividing point between local and global absolute value indices.
1453 size_t CachedNumGlobalValueIDs;
1454 // Holds operands local to the function block, based on indices defined in
1455 // the bitcode file.
1456 Ice::OperandList LocalOperands;
1457 // Holds the index within LocalOperands corresponding to the next instruction
1458 // that generates a value.
1459 NaClBcIndexSize_t NextLocalInstIndex;
1460 // True if the last processed instruction was a terminating instruction.
1461 bool InstIsTerminating = false;
1462
1463 bool ParseBlock(unsigned BlockID) override;
1464
1465 void ProcessRecord() override;
1466
EnterBlock(unsigned NumWords)1467 void EnterBlock(unsigned NumWords) override {
1468 // Note: Bitstream defines words as 32-bit values.
1469 NumBytesDefiningFunction = NumWords * sizeof(uint32_t);
1470 // We know that all records are minimally defined by a two-bit abreviation.
1471 MaxRecordsInBlock = NumBytesDefiningFunction * (CHAR_BIT >> 1);
1472 }
1473
1474 void ExitBlock() override;
1475
1476 // Creates and appends a new basic block to the list of basic blocks.
installNextBasicBlock()1477 Ice::CfgNode *installNextBasicBlock() {
1478 Ice::CfgNode *Node = Func->makeNode();
1479 return Node;
1480 }
1481
1482 // Returns the Index-th basic block in the list of basic blocks.
getBasicBlock(NaClBcIndexSize_t Index)1483 Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) {
1484 if (Index >= Func->getNumNodes()) {
1485 std::string Buffer;
1486 raw_string_ostream StrBuf(Buffer);
1487 StrBuf << "Reference to basic block " << Index
1488 << " not found. Must be less than " << Func->getNumNodes();
1489 Error(StrBuf.str());
1490 Index = 0;
1491 }
1492 return Func->getNodes()[Index];
1493 }
1494
1495 // Returns the Index-th basic block in the list of basic blocks. Assumes
1496 // Index corresponds to a branch instruction. Hence, if the branch references
1497 // the entry block, it also generates a corresponding error.
getBranchBasicBlock(NaClBcIndexSize_t Index)1498 Ice::CfgNode *getBranchBasicBlock(NaClBcIndexSize_t Index) {
1499 if (Index == 0) {
1500 Error("Branch to entry block not allowed");
1501 }
1502 return getBasicBlock(Index);
1503 }
1504
1505 // Generate an instruction variable with type Ty.
createInstVar(Ice::Type Ty)1506 Ice::Variable *createInstVar(Ice::Type Ty) {
1507 if (Ty == Ice::IceType_void) {
1508 Error("Can't define instruction value using type void");
1509 // Recover since we can't throw an exception.
1510 Ty = Ice::IceType_i32;
1511 }
1512 return Func->makeVariable(Ty);
1513 }
1514
1515 // Generates the next available local variable using the given type.
getNextInstVar(Ice::Type Ty)1516 Ice::Variable *getNextInstVar(Ice::Type Ty) {
1517 assert(NextLocalInstIndex >= CachedNumGlobalValueIDs);
1518 // Before creating one, see if a forwardtyperef has already defined it.
1519 NaClBcIndexSize_t LocalIndex = NextLocalInstIndex - CachedNumGlobalValueIDs;
1520 if (LocalIndex < LocalOperands.size()) {
1521 Ice::Operand *Op = LocalOperands[LocalIndex];
1522 if (Op != nullptr) {
1523 if (auto *Var = dyn_cast<Ice::Variable>(Op)) {
1524 if (Var->getType() == Ty) {
1525 ++NextLocalInstIndex;
1526 return Var;
1527 }
1528 }
1529 std::string Buffer;
1530 raw_string_ostream StrBuf(Buffer);
1531 StrBuf << "Illegal forward referenced instruction ("
1532 << NextLocalInstIndex << "): " << *Op;
1533 Error(StrBuf.str());
1534 ++NextLocalInstIndex;
1535 return createInstVar(Ty);
1536 }
1537 }
1538 Ice::Variable *Var = createInstVar(Ty);
1539 setOperand(NextLocalInstIndex++, Var);
1540 return Var;
1541 }
1542
1543 // Converts a relative index (wrt to BaseIndex) to an absolute value index.
convertRelativeToAbsIndex(NaClRelBcIndexSize_t Id,NaClRelBcIndexSize_t BaseIndex)1544 NaClBcIndexSize_t convertRelativeToAbsIndex(NaClRelBcIndexSize_t Id,
1545 NaClRelBcIndexSize_t BaseIndex) {
1546 if (BaseIndex < Id) {
1547 std::string Buffer;
1548 raw_string_ostream StrBuf(Buffer);
1549 StrBuf << "Invalid relative value id: " << Id
1550 << " (must be <= " << BaseIndex << ")";
1551 Error(StrBuf.str());
1552 return 0;
1553 }
1554 return BaseIndex - Id;
1555 }
1556
1557 // Sets element Index (in the local operands list) to Op.
setOperand(NaClBcIndexSize_t Index,Ice::Operand * Op)1558 void setOperand(NaClBcIndexSize_t Index, Ice::Operand *Op) {
1559 assert(Op);
1560 // Check if simple push works.
1561 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs;
1562 if (LocalIndex == LocalOperands.size()) {
1563 LocalOperands.push_back(Op);
1564 return;
1565 }
1566
1567 // Must be forward reference, expand vector to accommodate.
1568 if (LocalIndex >= LocalOperands.size()) {
1569 if (LocalIndex > MaxRecordsInBlock) {
1570 std::string Buffer;
1571 raw_string_ostream StrBuf(Buffer);
1572 StrBuf << "Forward reference @" << Index << " too big. Have "
1573 << CachedNumGlobalValueIDs << " globals and function contains "
1574 << NumBytesDefiningFunction << " bytes";
1575 Fatal(StrBuf.str());
1576 // Recover by using index one beyond the maximal allowed.
1577 LocalIndex = MaxRecordsInBlock;
1578 }
1579 Ice::Utils::reserveAndResize(LocalOperands, LocalIndex + 1);
1580 }
1581
1582 // If element not defined, set it.
1583 Ice::Operand *OldOp = LocalOperands[LocalIndex];
1584 if (OldOp == nullptr) {
1585 LocalOperands[LocalIndex] = Op;
1586 return;
1587 }
1588
1589 // See if forward reference matches.
1590 if (OldOp == Op)
1591 return;
1592
1593 // Error has occurred.
1594 std::string Buffer;
1595 raw_string_ostream StrBuf(Buffer);
1596 StrBuf << "Multiple definitions for index " << Index << ": " << *Op
1597 << " and " << *OldOp;
1598 Error(StrBuf.str());
1599 LocalOperands[LocalIndex] = Op;
1600 }
1601
1602 // Returns the relative operand (wrt to BaseIndex) referenced by the given
1603 // value Index.
getRelativeOperand(NaClBcIndexSize_t Index,NaClBcIndexSize_t BaseIndex)1604 Ice::Operand *getRelativeOperand(NaClBcIndexSize_t Index,
1605 NaClBcIndexSize_t BaseIndex) {
1606 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex));
1607 }
1608
1609 // Returns the absolute index of the next value generating instruction.
getNextInstIndex() const1610 NaClBcIndexSize_t getNextInstIndex() const { return NextLocalInstIndex; }
1611
1612 // Generates type error message for binary operator Op operating on Type
1613 // OpTy.
1614 void reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy);
1615
1616 // Validates if integer logical Op, for type OpTy, is valid. Returns true if
1617 // valid. Otherwise generates error message and returns false.
isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op,Ice::Type OpTy)1618 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1619 if (Ice::isIntegerType(OpTy))
1620 return true;
1621 reportInvalidBinaryOp(Op, OpTy);
1622 return false;
1623 }
1624
1625 // Validates if integer (or vector of integers) arithmetic Op, for type OpTy,
1626 // is valid. Returns true if valid. Otherwise generates error message and
1627 // returns false.
isValidIntegerArithOp(Ice::InstArithmetic::OpKind Op,Ice::Type OpTy)1628 bool isValidIntegerArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1629 if (Ice::isIntegerArithmeticType(OpTy))
1630 return true;
1631 reportInvalidBinaryOp(Op, OpTy);
1632 return false;
1633 }
1634
1635 // Checks if floating arithmetic Op, for type OpTy, is valid. Returns true if
1636 // valid. Otherwise generates an error message and returns false;
isValidFloatingArithOp(Ice::InstArithmetic::OpKind Op,Ice::Type OpTy)1637 bool isValidFloatingArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1638 if (Ice::isFloatingType(OpTy))
1639 return true;
1640 reportInvalidBinaryOp(Op, OpTy);
1641 return false;
1642 }
1643
1644 // Checks if the type of operand Op is the valid pointer type, for the given
1645 // InstructionName. Returns true if valid. Otherwise generates an error
1646 // message and returns false.
isValidPointerType(Ice::Operand * Op,const char * InstructionName)1647 bool isValidPointerType(Ice::Operand *Op, const char *InstructionName) {
1648 Ice::Type PtrType = Ice::getPointerType();
1649 if (Op->getType() == PtrType)
1650 return true;
1651 std::string Buffer;
1652 raw_string_ostream StrBuf(Buffer);
1653 StrBuf << InstructionName << " address not " << PtrType
1654 << ". Found: " << Op->getType();
1655 Error(StrBuf.str());
1656 return false;
1657 }
1658
1659 // Checks if loading/storing a value of type Ty is allowed. Returns true if
1660 // Valid. Otherwise generates an error message and returns false.
isValidLoadStoreType(Ice::Type Ty,const char * InstructionName)1661 bool isValidLoadStoreType(Ice::Type Ty, const char *InstructionName) {
1662 if (isLoadStoreType(Ty))
1663 return true;
1664 std::string Buffer;
1665 raw_string_ostream StrBuf(Buffer);
1666 StrBuf << InstructionName << " type not allowed: " << Ty << "*";
1667 Error(StrBuf.str());
1668 return false;
1669 }
1670
1671 // Checks if loading/storing a value of type Ty is allowed for the given
1672 // Alignment. Otherwise generates an error message and returns false.
isValidLoadStoreAlignment(size_t Alignment,Ice::Type Ty,const char * InstructionName)1673 bool isValidLoadStoreAlignment(size_t Alignment, Ice::Type Ty,
1674 const char *InstructionName) {
1675 if (!isValidLoadStoreType(Ty, InstructionName))
1676 return false;
1677 if (isAllowedAlignment(Alignment, Ty))
1678 return true;
1679 std::string Buffer;
1680 raw_string_ostream StrBuf(Buffer);
1681 StrBuf << InstructionName << " " << Ty << "*: not allowed for alignment "
1682 << Alignment;
1683 Error(StrBuf.str());
1684 return false;
1685 }
1686
1687 // Defines if the given alignment is valid for the given type. Simplified
1688 // version of PNaClABIProps::isAllowedAlignment, based on API's offered for
1689 // Ice::Type.
isAllowedAlignment(size_t Alignment,Ice::Type Ty) const1690 bool isAllowedAlignment(size_t Alignment, Ice::Type Ty) const {
1691 return Alignment == typeAlignInBytes(Ty) ||
1692 (Alignment == 1 && !isVectorType(Ty));
1693 }
1694
1695 // Types of errors that can occur for insertelement and extractelement
1696 // instructions.
1697 enum VectorIndexCheckValue {
1698 VectorIndexNotVector,
1699 VectorIndexNotConstant,
1700 VectorIndexNotInRange,
1701 VectorIndexNotI32,
1702 VectorIndexValid
1703 };
1704
dumpVectorIndexCheckValue(raw_ostream & Stream,VectorIndexCheckValue Value) const1705 void dumpVectorIndexCheckValue(raw_ostream &Stream,
1706 VectorIndexCheckValue Value) const {
1707 if (!Ice::BuildDefs::dump())
1708 return;
1709 switch (Value) {
1710 case VectorIndexNotVector:
1711 Stream << "Vector index on non vector";
1712 break;
1713 case VectorIndexNotConstant:
1714 Stream << "Vector index not integer constant";
1715 break;
1716 case VectorIndexNotInRange:
1717 Stream << "Vector index not in range of vector";
1718 break;
1719 case VectorIndexNotI32:
1720 Stream << "Vector index not of type " << Ice::IceType_i32;
1721 break;
1722 case VectorIndexValid:
1723 Stream << "Valid vector index";
1724 break;
1725 }
1726 }
1727
1728 // Returns whether the given vector index (for insertelement and
1729 // extractelement instructions) is valid.
validateVectorIndex(const Ice::Operand * Vec,const Ice::Operand * Index) const1730 VectorIndexCheckValue validateVectorIndex(const Ice::Operand *Vec,
1731 const Ice::Operand *Index) const {
1732 Ice::Type VecType = Vec->getType();
1733 if (!Ice::isVectorType(VecType))
1734 return VectorIndexNotVector;
1735 const auto *C = dyn_cast<Ice::ConstantInteger32>(Index);
1736 if (C == nullptr)
1737 return VectorIndexNotConstant;
1738 if (static_cast<size_t>(C->getValue()) >= typeNumElements(VecType))
1739 return VectorIndexNotInRange;
1740 if (Index->getType() != Ice::IceType_i32)
1741 return VectorIndexNotI32;
1742 return VectorIndexValid;
1743 }
1744
1745 // Takes the PNaCl bitcode binary operator Opcode, and the opcode type Ty,
1746 // and sets Op to the corresponding ICE binary opcode. Returns true if able
1747 // to convert, false otherwise.
convertBinopOpcode(unsigned Opcode,Ice::Type Ty,Ice::InstArithmetic::OpKind & Op)1748 bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty,
1749 Ice::InstArithmetic::OpKind &Op) {
1750 switch (Opcode) {
1751 default: {
1752 std::string Buffer;
1753 raw_string_ostream StrBuf(Buffer);
1754 StrBuf << "Binary opcode " << Opcode << "not understood for type " << Ty;
1755 Error(StrBuf.str());
1756 Op = Ice::InstArithmetic::Add;
1757 return false;
1758 }
1759 case naclbitc::BINOP_ADD:
1760 if (Ice::isIntegerType(Ty)) {
1761 Op = Ice::InstArithmetic::Add;
1762 return isValidIntegerArithOp(Op, Ty);
1763 } else {
1764 Op = Ice::InstArithmetic::Fadd;
1765 return isValidFloatingArithOp(Op, Ty);
1766 }
1767 case naclbitc::BINOP_SUB:
1768 if (Ice::isIntegerType(Ty)) {
1769 Op = Ice::InstArithmetic::Sub;
1770 return isValidIntegerArithOp(Op, Ty);
1771 } else {
1772 Op = Ice::InstArithmetic::Fsub;
1773 return isValidFloatingArithOp(Op, Ty);
1774 }
1775 case naclbitc::BINOP_MUL:
1776 if (Ice::isIntegerType(Ty)) {
1777 Op = Ice::InstArithmetic::Mul;
1778 return isValidIntegerArithOp(Op, Ty);
1779 } else {
1780 Op = Ice::InstArithmetic::Fmul;
1781 return isValidFloatingArithOp(Op, Ty);
1782 }
1783 case naclbitc::BINOP_UDIV:
1784 Op = Ice::InstArithmetic::Udiv;
1785 return isValidIntegerArithOp(Op, Ty);
1786 case naclbitc::BINOP_SDIV:
1787 if (Ice::isIntegerType(Ty)) {
1788 Op = Ice::InstArithmetic::Sdiv;
1789 return isValidIntegerArithOp(Op, Ty);
1790 } else {
1791 Op = Ice::InstArithmetic::Fdiv;
1792 return isValidFloatingArithOp(Op, Ty);
1793 }
1794 case naclbitc::BINOP_UREM:
1795 Op = Ice::InstArithmetic::Urem;
1796 return isValidIntegerArithOp(Op, Ty);
1797 case naclbitc::BINOP_SREM:
1798 if (Ice::isIntegerType(Ty)) {
1799 Op = Ice::InstArithmetic::Srem;
1800 return isValidIntegerArithOp(Op, Ty);
1801 } else {
1802 Op = Ice::InstArithmetic::Frem;
1803 return isValidFloatingArithOp(Op, Ty);
1804 }
1805 case naclbitc::BINOP_SHL:
1806 Op = Ice::InstArithmetic::Shl;
1807 return isValidIntegerArithOp(Op, Ty);
1808 case naclbitc::BINOP_LSHR:
1809 Op = Ice::InstArithmetic::Lshr;
1810 return isValidIntegerArithOp(Op, Ty);
1811 case naclbitc::BINOP_ASHR:
1812 Op = Ice::InstArithmetic::Ashr;
1813 return isValidIntegerArithOp(Op, Ty);
1814 case naclbitc::BINOP_AND:
1815 Op = Ice::InstArithmetic::And;
1816 return isValidIntegerLogicalOp(Op, Ty);
1817 case naclbitc::BINOP_OR:
1818 Op = Ice::InstArithmetic::Or;
1819 return isValidIntegerLogicalOp(Op, Ty);
1820 case naclbitc::BINOP_XOR:
1821 Op = Ice::InstArithmetic::Xor;
1822 return isValidIntegerLogicalOp(Op, Ty);
1823 }
1824 }
1825
1826 /// Simplifies out vector types from Type1 and Type2, if both are vectors of
1827 /// the same size. Returns true iff both are vectors of the same size, or are
1828 /// both scalar types.
simplifyOutCommonVectorType(Ice::Type & Type1,Ice::Type & Type2)1829 static bool simplifyOutCommonVectorType(Ice::Type &Type1, Ice::Type &Type2) {
1830 bool IsType1Vector = isVectorType(Type1);
1831 bool IsType2Vector = isVectorType(Type2);
1832 if (IsType1Vector != IsType2Vector)
1833 return false;
1834 if (!IsType1Vector)
1835 return true;
1836 if (typeNumElements(Type1) != typeNumElements(Type2))
1837 return false;
1838 Type1 = typeElementType(Type1);
1839 Type2 = typeElementType(Type2);
1840 return true;
1841 }
1842
1843 /// Returns true iff an integer truncation from SourceType to TargetType is
1844 /// valid.
isIntTruncCastValid(Ice::Type SourceType,Ice::Type TargetType)1845 static bool isIntTruncCastValid(Ice::Type SourceType, Ice::Type TargetType) {
1846 return Ice::isIntegerType(SourceType) && Ice::isIntegerType(TargetType) &&
1847 simplifyOutCommonVectorType(SourceType, TargetType) &&
1848 getScalarIntBitWidth(SourceType) > getScalarIntBitWidth(TargetType);
1849 }
1850
1851 /// Returns true iff a floating type truncation from SourceType to TargetType
1852 /// is valid.
isFloatTruncCastValid(Ice::Type SourceType,Ice::Type TargetType)1853 static bool isFloatTruncCastValid(Ice::Type SourceType,
1854 Ice::Type TargetType) {
1855 return simplifyOutCommonVectorType(SourceType, TargetType) &&
1856 SourceType == Ice::IceType_f64 && TargetType == Ice::IceType_f32;
1857 }
1858
1859 /// Returns true iff an integer extension from SourceType to TargetType is
1860 /// valid.
isIntExtCastValid(Ice::Type SourceType,Ice::Type TargetType)1861 static bool isIntExtCastValid(Ice::Type SourceType, Ice::Type TargetType) {
1862 return isIntTruncCastValid(TargetType, SourceType);
1863 }
1864
1865 /// Returns true iff a floating type extension from SourceType to TargetType
1866 /// is valid.
isFloatExtCastValid(Ice::Type SourceType,Ice::Type TargetType)1867 static bool isFloatExtCastValid(Ice::Type SourceType, Ice::Type TargetType) {
1868 return isFloatTruncCastValid(TargetType, SourceType);
1869 }
1870
1871 /// Returns true iff a cast from floating type SourceType to integer type
1872 /// TargetType is valid.
isFloatToIntCastValid(Ice::Type SourceType,Ice::Type TargetType)1873 static bool isFloatToIntCastValid(Ice::Type SourceType,
1874 Ice::Type TargetType) {
1875 if (!(Ice::isFloatingType(SourceType) && Ice::isIntegerType(TargetType)))
1876 return false;
1877 bool IsSourceVector = isVectorType(SourceType);
1878 bool IsTargetVector = isVectorType(TargetType);
1879 if (IsSourceVector != IsTargetVector)
1880 return false;
1881 if (IsSourceVector) {
1882 return typeNumElements(SourceType) == typeNumElements(TargetType);
1883 }
1884 return true;
1885 }
1886
1887 /// Returns true iff a cast from integer type SourceType to floating type
1888 /// TargetType is valid.
isIntToFloatCastValid(Ice::Type SourceType,Ice::Type TargetType)1889 static bool isIntToFloatCastValid(Ice::Type SourceType,
1890 Ice::Type TargetType) {
1891 return isFloatToIntCastValid(TargetType, SourceType);
1892 }
1893
1894 /// Returns the number of bits used to model type Ty when defining the bitcast
1895 /// instruction.
bitcastSizeInBits(Ice::Type Ty)1896 static Ice::SizeT bitcastSizeInBits(Ice::Type Ty) {
1897 if (Ice::isVectorType(Ty))
1898 return Ice::typeNumElements(Ty) *
1899 bitcastSizeInBits(Ice::typeElementType(Ty));
1900 if (Ty == Ice::IceType_i1)
1901 return 1;
1902 return Ice::typeWidthInBytes(Ty) * CHAR_BIT;
1903 }
1904
1905 /// Returns true iff a bitcast from SourceType to TargetType is allowed.
isBitcastValid(Ice::Type SourceType,Ice::Type TargetType)1906 static bool isBitcastValid(Ice::Type SourceType, Ice::Type TargetType) {
1907 return bitcastSizeInBits(SourceType) == bitcastSizeInBits(TargetType);
1908 }
1909
1910 /// Returns true iff the NaCl bitcode Opcode is a valid cast opcode for
1911 /// converting SourceType to TargetType. Updates CastKind to the corresponding
1912 /// instruction cast opcode. Also generates an error message when this
1913 /// function returns false.
convertCastOpToIceOp(uint64_t Opcode,Ice::Type SourceType,Ice::Type TargetType,Ice::InstCast::OpKind & CastKind)1914 bool convertCastOpToIceOp(uint64_t Opcode, Ice::Type SourceType,
1915 Ice::Type TargetType,
1916 Ice::InstCast::OpKind &CastKind) {
1917 bool Result;
1918 switch (Opcode) {
1919 default: {
1920 std::string Buffer;
1921 raw_string_ostream StrBuf(Buffer);
1922 StrBuf << "Cast opcode " << Opcode << " not understood.\n";
1923 Error(StrBuf.str());
1924 CastKind = Ice::InstCast::Bitcast;
1925 return false;
1926 }
1927 case naclbitc::CAST_TRUNC:
1928 CastKind = Ice::InstCast::Trunc;
1929 Result = isIntTruncCastValid(SourceType, TargetType);
1930 break;
1931 case naclbitc::CAST_ZEXT:
1932 CastKind = Ice::InstCast::Zext;
1933 Result = isIntExtCastValid(SourceType, TargetType);
1934 break;
1935 case naclbitc::CAST_SEXT:
1936 CastKind = Ice::InstCast::Sext;
1937 Result = isIntExtCastValid(SourceType, TargetType);
1938 break;
1939 case naclbitc::CAST_FPTOUI:
1940 CastKind = Ice::InstCast::Fptoui;
1941 Result = isFloatToIntCastValid(SourceType, TargetType);
1942 break;
1943 case naclbitc::CAST_FPTOSI:
1944 CastKind = Ice::InstCast::Fptosi;
1945 Result = isFloatToIntCastValid(SourceType, TargetType);
1946 break;
1947 case naclbitc::CAST_UITOFP:
1948 CastKind = Ice::InstCast::Uitofp;
1949 Result = isIntToFloatCastValid(SourceType, TargetType);
1950 break;
1951 case naclbitc::CAST_SITOFP:
1952 CastKind = Ice::InstCast::Sitofp;
1953 Result = isIntToFloatCastValid(SourceType, TargetType);
1954 break;
1955 case naclbitc::CAST_FPTRUNC:
1956 CastKind = Ice::InstCast::Fptrunc;
1957 Result = isFloatTruncCastValid(SourceType, TargetType);
1958 break;
1959 case naclbitc::CAST_FPEXT:
1960 CastKind = Ice::InstCast::Fpext;
1961 Result = isFloatExtCastValid(SourceType, TargetType);
1962 break;
1963 case naclbitc::CAST_BITCAST:
1964 CastKind = Ice::InstCast::Bitcast;
1965 Result = isBitcastValid(SourceType, TargetType);
1966 break;
1967 }
1968 if (!Result) {
1969 std::string Buffer;
1970 raw_string_ostream StrBuf(Buffer);
1971 StrBuf << "Illegal cast: " << Ice::InstCast::getCastName(CastKind) << " "
1972 << SourceType << " to " << TargetType;
1973 Error(StrBuf.str());
1974 }
1975 return Result;
1976 }
1977
1978 // Converts PNaCl bitcode Icmp operator to corresponding ICE op. Returns true
1979 // if able to convert, false otherwise.
convertNaClBitcICmpOpToIce(uint64_t Op,Ice::InstIcmp::ICond & Cond) const1980 bool convertNaClBitcICmpOpToIce(uint64_t Op,
1981 Ice::InstIcmp::ICond &Cond) const {
1982 switch (Op) {
1983 case naclbitc::ICMP_EQ:
1984 Cond = Ice::InstIcmp::Eq;
1985 return true;
1986 case naclbitc::ICMP_NE:
1987 Cond = Ice::InstIcmp::Ne;
1988 return true;
1989 case naclbitc::ICMP_UGT:
1990 Cond = Ice::InstIcmp::Ugt;
1991 return true;
1992 case naclbitc::ICMP_UGE:
1993 Cond = Ice::InstIcmp::Uge;
1994 return true;
1995 case naclbitc::ICMP_ULT:
1996 Cond = Ice::InstIcmp::Ult;
1997 return true;
1998 case naclbitc::ICMP_ULE:
1999 Cond = Ice::InstIcmp::Ule;
2000 return true;
2001 case naclbitc::ICMP_SGT:
2002 Cond = Ice::InstIcmp::Sgt;
2003 return true;
2004 case naclbitc::ICMP_SGE:
2005 Cond = Ice::InstIcmp::Sge;
2006 return true;
2007 case naclbitc::ICMP_SLT:
2008 Cond = Ice::InstIcmp::Slt;
2009 return true;
2010 case naclbitc::ICMP_SLE:
2011 Cond = Ice::InstIcmp::Sle;
2012 return true;
2013 default:
2014 // Make sure Cond is always initialized.
2015 Cond = static_cast<Ice::InstIcmp::ICond>(0);
2016 return false;
2017 }
2018 }
2019
2020 // Converts PNaCl bitcode Fcmp operator to corresponding ICE op. Returns true
2021 // if able to convert, false otherwise.
convertNaClBitcFCompOpToIce(uint64_t Op,Ice::InstFcmp::FCond & Cond) const2022 bool convertNaClBitcFCompOpToIce(uint64_t Op,
2023 Ice::InstFcmp::FCond &Cond) const {
2024 switch (Op) {
2025 case naclbitc::FCMP_FALSE:
2026 Cond = Ice::InstFcmp::False;
2027 return true;
2028 case naclbitc::FCMP_OEQ:
2029 Cond = Ice::InstFcmp::Oeq;
2030 return true;
2031 case naclbitc::FCMP_OGT:
2032 Cond = Ice::InstFcmp::Ogt;
2033 return true;
2034 case naclbitc::FCMP_OGE:
2035 Cond = Ice::InstFcmp::Oge;
2036 return true;
2037 case naclbitc::FCMP_OLT:
2038 Cond = Ice::InstFcmp::Olt;
2039 return true;
2040 case naclbitc::FCMP_OLE:
2041 Cond = Ice::InstFcmp::Ole;
2042 return true;
2043 case naclbitc::FCMP_ONE:
2044 Cond = Ice::InstFcmp::One;
2045 return true;
2046 case naclbitc::FCMP_ORD:
2047 Cond = Ice::InstFcmp::Ord;
2048 return true;
2049 case naclbitc::FCMP_UNO:
2050 Cond = Ice::InstFcmp::Uno;
2051 return true;
2052 case naclbitc::FCMP_UEQ:
2053 Cond = Ice::InstFcmp::Ueq;
2054 return true;
2055 case naclbitc::FCMP_UGT:
2056 Cond = Ice::InstFcmp::Ugt;
2057 return true;
2058 case naclbitc::FCMP_UGE:
2059 Cond = Ice::InstFcmp::Uge;
2060 return true;
2061 case naclbitc::FCMP_ULT:
2062 Cond = Ice::InstFcmp::Ult;
2063 return true;
2064 case naclbitc::FCMP_ULE:
2065 Cond = Ice::InstFcmp::Ule;
2066 return true;
2067 case naclbitc::FCMP_UNE:
2068 Cond = Ice::InstFcmp::Une;
2069 return true;
2070 case naclbitc::FCMP_TRUE:
2071 Cond = Ice::InstFcmp::True;
2072 return true;
2073 default:
2074 // Make sure Cond is always initialized.
2075 Cond = static_cast<Ice::InstFcmp::FCond>(0);
2076 return false;
2077 }
2078 }
2079
2080 // Creates an error instruction, generating a value of type Ty, and adds a
2081 // placeholder so that instruction indices line up. Some instructions, such
2082 // as a call, will not generate a value if the return type is void. In such
2083 // cases, a placeholder value for the badly formed instruction is not needed.
2084 // Hence, if Ty is void, an error instruction is not appended.
appendErrorInstruction(Ice::Type Ty)2085 void appendErrorInstruction(Ice::Type Ty) {
2086 // Note: we don't worry about downstream translation errors because the
2087 // function will not be translated if any errors occur.
2088 if (Ty == Ice::IceType_void)
2089 return;
2090 Ice::Variable *Var = getNextInstVar(Ty);
2091 CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var));
2092 }
2093
reportGetOperandUndefined(NaClBcIndexSize_t Index)2094 Ice::Operand *reportGetOperandUndefined(NaClBcIndexSize_t Index) {
2095 std::string Buffer;
2096 raw_string_ostream StrBuf(Buffer);
2097 StrBuf << "Value index " << Index << " not defined!";
2098 Error(StrBuf.str());
2099 // Recover and return some value.
2100 if (!LocalOperands.empty())
2101 return LocalOperands.front();
2102 return Context->getGlobalConstantByID(0);
2103 }
2104
verifyCallArgTypeMatches(Ice::FunctionDeclaration * Fcn,Ice::SizeT Index,Ice::Type ArgType,Ice::Type ParamType)2105 void verifyCallArgTypeMatches(Ice::FunctionDeclaration *Fcn, Ice::SizeT Index,
2106 Ice::Type ArgType, Ice::Type ParamType) {
2107 if (ArgType != ParamType) {
2108 std::string Buffer;
2109 raw_string_ostream StrBuf(Buffer);
2110 StrBuf << "Argument " << (Index + 1) << " of " << printName(Fcn)
2111 << " expects " << ParamType << ". Found: " << ArgType;
2112 Error(StrBuf.str());
2113 }
2114 }
2115
printName(Ice::FunctionDeclaration * Fcn)2116 const std::string printName(Ice::FunctionDeclaration *Fcn) {
2117 if (Fcn)
2118 return Fcn->getName().toString();
2119 return "function";
2120 }
2121 };
2122
ExitBlock()2123 void FunctionParser::ExitBlock() {
2124 // Check if the last instruction in the function was terminating.
2125 if (!InstIsTerminating) {
2126 Error("Last instruction in function not terminator");
2127 // Recover by inserting an unreachable instruction.
2128 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get()));
2129 }
2130 ++CurrentBbIndex;
2131 if (CurrentBbIndex != DeclaredNumberBbs) {
2132 std::string Buffer;
2133 raw_string_ostream StrBuf(Buffer);
2134 StrBuf << "Function declared " << DeclaredNumberBbs
2135 << " basic blocks, but defined " << CurrentBbIndex << ".";
2136 Error(StrBuf.str());
2137 }
2138 // Before translating, check for blocks without instructions, and insert
2139 // unreachable. This shouldn't happen, but be safe.
2140 size_t Index = 0;
2141 for (Ice::CfgNode *Node : Func->getNodes()) {
2142 if (Node->getInsts().empty()) {
2143 std::string Buffer;
2144 raw_string_ostream StrBuf(Buffer);
2145 StrBuf << "Basic block " << Index << " contains no instructions";
2146 Error(StrBuf.str());
2147 Node->appendInst(Ice::InstUnreachable::create(Func.get()));
2148 }
2149 ++Index;
2150 }
2151 Func->computeInOutEdges();
2152 }
2153
reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op,Ice::Type OpTy)2154 void FunctionParser::reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op,
2155 Ice::Type OpTy) {
2156 std::string Buffer;
2157 raw_string_ostream StrBuf(Buffer);
2158 StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op)
2159 << ". Found " << OpTy;
2160 Error(StrBuf.str());
2161 }
2162
ProcessRecord()2163 void FunctionParser::ProcessRecord() {
2164 // Note: To better separate parse/IR generation times, when IR generation is
2165 // disabled we do the following:
2166 // 1) Delay exiting until after we extract operands.
2167 // 2) return before we access operands, since all operands will be a nullptr.
2168 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
2169 if (InstIsTerminating) {
2170 InstIsTerminating = false;
2171 ++CurrentBbIndex;
2172 CurrentNode = getBasicBlock(CurrentBbIndex);
2173 }
2174 // The base index for relative indexing.
2175 NaClBcIndexSize_t BaseIndex = getNextInstIndex();
2176 switch (Record.GetCode()) {
2177 case naclbitc::FUNC_CODE_DECLAREBLOCKS: {
2178 // DECLAREBLOCKS: [n]
2179 if (!isValidRecordSize(1, "count"))
2180 return;
2181 if (DeclaredNumberBbs > 0) {
2182 Error("Duplicate function block count record");
2183 return;
2184 }
2185
2186 // Check for bad large sizes, since they can make ridiculous memory
2187 // requests and hang the user for large amounts of time.
2188 uint64_t NumBbs = Values[0];
2189 if (NumBbs > MaxRecordsInBlock) {
2190 std::string Buffer;
2191 raw_string_ostream StrBuf(Buffer);
2192 StrBuf << "Function defines " << NumBbs
2193 << " basic blocks, which is too big for a function containing "
2194 << NumBytesDefiningFunction << " bytes";
2195 Error(StrBuf.str());
2196 NumBbs = MaxRecordsInBlock;
2197 }
2198
2199 if (NumBbs == 0) {
2200 Error("Functions must contain at least one basic block.");
2201 NumBbs = 1;
2202 }
2203
2204 DeclaredNumberBbs = NumBbs;
2205 // Install the basic blocks, skipping bb0 which was created in the
2206 // constructor.
2207 for (size_t i = 1; i < NumBbs; ++i)
2208 installNextBasicBlock();
2209 return;
2210 }
2211 case naclbitc::FUNC_CODE_INST_BINOP: {
2212 // Note: Old bitcode files may have an additional 'flags' operand, which is
2213 // ignored.
2214
2215 // BINOP: [opval, opval, opcode, [flags]]
2216
2217 if (!isValidRecordSizeInRange(3, 4, "binop"))
2218 return;
2219 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
2220 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
2221 Ice::Type Type1 = Op1->getType();
2222 Ice::Type Type2 = Op2->getType();
2223 if (Type1 != Type2) {
2224 std::string Buffer;
2225 raw_string_ostream StrBuf(Buffer);
2226 StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2;
2227 Error(StrBuf.str());
2228 appendErrorInstruction(Type1);
2229 return;
2230 }
2231
2232 Ice::InstArithmetic::OpKind Opcode;
2233 if (!convertBinopOpcode(Values[2], Type1, Opcode)) {
2234 appendErrorInstruction(Type1);
2235 return;
2236 }
2237 CurrentNode->appendInst(Ice::InstArithmetic::create(
2238 Func.get(), Opcode, getNextInstVar(Type1), Op1, Op2));
2239 return;
2240 }
2241 case naclbitc::FUNC_CODE_INST_CAST: {
2242 // CAST: [opval, destty, castopc]
2243 if (!isValidRecordSize(3, "cast"))
2244 return;
2245 Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex);
2246 Ice::Type CastType = Context->getSimpleTypeByID(Values[1]);
2247 Ice::InstCast::OpKind CastKind;
2248 if (!convertCastOpToIceOp(Values[2], Src->getType(), CastType, CastKind)) {
2249 appendErrorInstruction(CastType);
2250 return;
2251 }
2252 CurrentNode->appendInst(Ice::InstCast::create(
2253 Func.get(), CastKind, getNextInstVar(CastType), Src));
2254 return;
2255 }
2256 case naclbitc::FUNC_CODE_INST_VSELECT: {
2257 // VSELECT: [opval, opval, pred]
2258 if (!isValidRecordSize(3, "select"))
2259 return;
2260 Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex);
2261 Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex);
2262 Ice::Operand *CondVal = getRelativeOperand(Values[2], BaseIndex);
2263 Ice::Type ThenType = ThenVal->getType();
2264 Ice::Type ElseType = ElseVal->getType();
2265 if (ThenType != ElseType) {
2266 std::string Buffer;
2267 raw_string_ostream StrBuf(Buffer);
2268 StrBuf << "Select operands not same type. Found " << ThenType << " and "
2269 << ElseType;
2270 Error(StrBuf.str());
2271 appendErrorInstruction(ThenType);
2272 return;
2273 }
2274 Ice::Type CondType = CondVal->getType();
2275 if (isVectorType(CondType)) {
2276 if (!isVectorType(ThenType) ||
2277 typeElementType(CondType) != Ice::IceType_i1 ||
2278 typeNumElements(ThenType) != typeNumElements(CondType)) {
2279 std::string Buffer;
2280 raw_string_ostream StrBuf(Buffer);
2281 StrBuf << "Select condition type " << CondType
2282 << " not allowed for values of type " << ThenType;
2283 Error(StrBuf.str());
2284 appendErrorInstruction(ThenType);
2285 return;
2286 }
2287 } else if (CondVal->getType() != Ice::IceType_i1) {
2288 std::string Buffer;
2289 raw_string_ostream StrBuf(Buffer);
2290 StrBuf << "Select condition " << CondVal
2291 << " not type i1. Found: " << CondVal->getType();
2292 Error(StrBuf.str());
2293 appendErrorInstruction(ThenType);
2294 return;
2295 }
2296 CurrentNode->appendInst(Ice::InstSelect::create(
2297 Func.get(), getNextInstVar(ThenType), CondVal, ThenVal, ElseVal));
2298 return;
2299 }
2300 case naclbitc::FUNC_CODE_INST_EXTRACTELT: {
2301 // EXTRACTELT: [opval, opval]
2302 if (!isValidRecordSize(2, "extract element"))
2303 return;
2304 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
2305 Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex);
2306 Ice::Type VecType = Vec->getType();
2307 VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index);
2308 if (IndexCheckValue != VectorIndexValid) {
2309 std::string Buffer;
2310 raw_string_ostream StrBuf(Buffer);
2311 dumpVectorIndexCheckValue(StrBuf, IndexCheckValue);
2312 StrBuf << ": extractelement " << VecType << " " << *Vec << ", "
2313 << Index->getType() << " " << *Index;
2314 Error(StrBuf.str());
2315 appendErrorInstruction(VecType);
2316 return;
2317 }
2318 CurrentNode->appendInst(Ice::InstExtractElement::create(
2319 Func.get(), getNextInstVar(typeElementType(VecType)), Vec, Index));
2320 return;
2321 }
2322 case naclbitc::FUNC_CODE_INST_INSERTELT: {
2323 // INSERTELT: [opval, opval, opval]
2324 if (!isValidRecordSize(3, "insert element"))
2325 return;
2326 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
2327 Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex);
2328 Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex);
2329 Ice::Type VecType = Vec->getType();
2330 VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index);
2331 if (IndexCheckValue != VectorIndexValid) {
2332 std::string Buffer;
2333 raw_string_ostream StrBuf(Buffer);
2334 dumpVectorIndexCheckValue(StrBuf, IndexCheckValue);
2335 StrBuf << ": insertelement " << VecType << " " << *Vec << ", "
2336 << Elt->getType() << " " << *Elt << ", " << Index->getType() << " "
2337 << *Index;
2338 Error(StrBuf.str());
2339 appendErrorInstruction(Elt->getType());
2340 return;
2341 }
2342 if (Ice::typeElementType(VecType) != Elt->getType()) {
2343 std::string Buffer;
2344 raw_string_ostream StrBuf(Buffer);
2345 StrBuf << "Insertelement: Element type "
2346 << Ice::typeString(Elt->getType()) << " doesn't match vector type "
2347 << Ice::typeString(VecType);
2348 Error(StrBuf.str());
2349 appendErrorInstruction(Elt->getType());
2350 return;
2351 }
2352 CurrentNode->appendInst(Ice::InstInsertElement::create(
2353 Func.get(), getNextInstVar(VecType), Vec, Elt, Index));
2354 return;
2355 }
2356 case naclbitc::FUNC_CODE_INST_CMP2: {
2357 // CMP2: [opval, opval, pred]
2358 if (!isValidRecordSize(3, "compare"))
2359 return;
2360 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
2361 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
2362 Ice::Type Op1Type = Op1->getType();
2363 Ice::Type Op2Type = Op2->getType();
2364 Ice::Type DestType = getCompareResultType(Op1Type);
2365 if (Op1Type != Op2Type) {
2366 std::string Buffer;
2367 raw_string_ostream StrBuf(Buffer);
2368 StrBuf << "Compare argument types differ: " << Op1Type << " and "
2369 << Op2Type;
2370 Error(StrBuf.str());
2371 appendErrorInstruction(DestType);
2372 Op2 = Op1;
2373 }
2374 if (DestType == Ice::IceType_void) {
2375 std::string Buffer;
2376 raw_string_ostream StrBuf(Buffer);
2377 StrBuf << "Compare not defined for type " << Op1Type;
2378 Error(StrBuf.str());
2379 return;
2380 }
2381 Ice::Variable *Dest = getNextInstVar(DestType);
2382 if (isIntegerType(Op1Type)) {
2383 Ice::InstIcmp::ICond Cond;
2384 if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) {
2385 std::string Buffer;
2386 raw_string_ostream StrBuf(Buffer);
2387 StrBuf << "Compare record contains unknown integer predicate index: "
2388 << Values[2];
2389 Error(StrBuf.str());
2390 appendErrorInstruction(DestType);
2391 }
2392 CurrentNode->appendInst(
2393 Ice::InstIcmp::create(Func.get(), Cond, Dest, Op1, Op2));
2394 } else if (isFloatingType(Op1Type)) {
2395 Ice::InstFcmp::FCond Cond;
2396 if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) {
2397 std::string Buffer;
2398 raw_string_ostream StrBuf(Buffer);
2399 StrBuf << "Compare record contains unknown float predicate index: "
2400 << Values[2];
2401 Error(StrBuf.str());
2402 appendErrorInstruction(DestType);
2403 }
2404 CurrentNode->appendInst(
2405 Ice::InstFcmp::create(Func.get(), Cond, Dest, Op1, Op2));
2406 } else {
2407 // Not sure this can happen, but be safe.
2408 std::string Buffer;
2409 raw_string_ostream StrBuf(Buffer);
2410 StrBuf << "Compare on type not understood: " << Op1Type;
2411 Error(StrBuf.str());
2412 appendErrorInstruction(DestType);
2413 return;
2414 }
2415 return;
2416 }
2417 case naclbitc::FUNC_CODE_INST_RET: {
2418 // RET: [opval?]
2419 InstIsTerminating = true;
2420 if (!isValidRecordSizeInRange(0, 1, "return"))
2421 return;
2422 if (Values.empty()) {
2423 CurrentNode->appendInst(Ice::InstRet::create(Func.get()));
2424 } else {
2425 Ice::Operand *RetVal = getRelativeOperand(Values[0], BaseIndex);
2426 CurrentNode->appendInst(Ice::InstRet::create(Func.get(), RetVal));
2427 }
2428 return;
2429 }
2430 case naclbitc::FUNC_CODE_INST_BR: {
2431 InstIsTerminating = true;
2432 if (Values.size() == 1) {
2433 // BR: [bb#]
2434 Ice::CfgNode *Block = getBranchBasicBlock(Values[0]);
2435 if (Block == nullptr)
2436 return;
2437 CurrentNode->appendInst(Ice::InstBr::create(Func.get(), Block));
2438 } else {
2439 // BR: [bb#, bb#, opval]
2440 if (!isValidRecordSize(3, "branch"))
2441 return;
2442 Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex);
2443 if (Cond->getType() != Ice::IceType_i1) {
2444 std::string Buffer;
2445 raw_string_ostream StrBuf(Buffer);
2446 StrBuf << "Branch condition " << *Cond
2447 << " not i1. Found: " << Cond->getType();
2448 Error(StrBuf.str());
2449 return;
2450 }
2451 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]);
2452 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]);
2453 if (ThenBlock == nullptr || ElseBlock == nullptr)
2454 return;
2455 CurrentNode->appendInst(
2456 Ice::InstBr::create(Func.get(), Cond, ThenBlock, ElseBlock));
2457 }
2458 return;
2459 }
2460 case naclbitc::FUNC_CODE_INST_SWITCH: {
2461 // SWITCH: [Condty, Cond, BbIndex, NumCases Case ...]
2462 // where Case = [1, 1, Value, BbIndex].
2463 //
2464 // Note: Unlike most instructions, we don't infer the type of Cond, but
2465 // provide it as a separate field. There are also unnecessary data fields
2466 // (i.e. constants 1). These were not cleaned up in PNaCl bitcode because
2467 // the bitcode format was already frozen when the problem was noticed.
2468 InstIsTerminating = true;
2469 if (!isValidRecordSizeAtLeast(4, "switch"))
2470 return;
2471
2472 Ice::Type CondTy = Context->getSimpleTypeByID(Values[0]);
2473 if (!Ice::isScalarIntegerType(CondTy)) {
2474 std::string Buffer;
2475 raw_string_ostream StrBuf(Buffer);
2476 StrBuf << "Case condition must be non-wide integer. Found: " << CondTy;
2477 Error(StrBuf.str());
2478 return;
2479 }
2480 Ice::SizeT BitWidth = Ice::getScalarIntBitWidth(CondTy);
2481 Ice::Operand *Cond = getRelativeOperand(Values[1], BaseIndex);
2482
2483 if (CondTy != Cond->getType()) {
2484 std::string Buffer;
2485 raw_string_ostream StrBuf(Buffer);
2486 StrBuf << "Case condition expects type " << CondTy
2487 << ". Found: " << Cond->getType();
2488 Error(StrBuf.str());
2489 return;
2490 }
2491 Ice::CfgNode *DefaultLabel = getBranchBasicBlock(Values[2]);
2492 if (DefaultLabel == nullptr)
2493 return;
2494 uint64_t NumCasesRaw = Values[3];
2495 if (NumCasesRaw > std::numeric_limits<uint32_t>::max()) {
2496 std::string Buffer;
2497 raw_string_ostream StrBuf(Buffer);
2498 StrBuf << "Too many cases specified in switch: " << NumCasesRaw;
2499 Error(StrBuf.str());
2500 NumCasesRaw = std::numeric_limits<uint32_t>::max();
2501 }
2502 uint32_t NumCases = NumCasesRaw;
2503
2504 // Now recognize each of the cases.
2505 if (!isValidRecordSize(4 + NumCases * 4, "switch"))
2506 return;
2507 std::unique_ptr<Ice::InstSwitch> Switch(
2508 Ice::InstSwitch::create(Func.get(), NumCases, Cond, DefaultLabel));
2509 unsigned ValCaseIndex = 4; // index to beginning of case entry.
2510 for (uint32_t CaseIndex = 0; CaseIndex < NumCases;
2511 ++CaseIndex, ValCaseIndex += 4) {
2512 if (Values[ValCaseIndex] != 1 || Values[ValCaseIndex + 1] != 1) {
2513 std::string Buffer;
2514 raw_string_ostream StrBuf(Buffer);
2515 StrBuf << "Sequence [1, 1, value, label] expected for case entry "
2516 << "in switch record. (at index" << ValCaseIndex << ")";
2517 Error(StrBuf.str());
2518 return;
2519 }
2520 BitcodeInt Value(BitWidth,
2521 NaClDecodeSignRotatedValue(Values[ValCaseIndex + 2]));
2522 Ice::CfgNode *Label = getBranchBasicBlock(Values[ValCaseIndex + 3]);
2523 if (Label == nullptr)
2524 return;
2525 Switch->addBranch(CaseIndex, Value.getSExtValue(), Label);
2526 }
2527 CurrentNode->appendInst(Switch.release());
2528 return;
2529 }
2530 case naclbitc::FUNC_CODE_INST_UNREACHABLE: {
2531 // UNREACHABLE: []
2532 InstIsTerminating = true;
2533 if (!isValidRecordSize(0, "unreachable"))
2534 return;
2535 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get()));
2536 return;
2537 }
2538 case naclbitc::FUNC_CODE_INST_PHI: {
2539 // PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2.
2540 if (!isValidRecordSizeAtLeast(3, "phi"))
2541 return;
2542 Ice::Type Ty = Context->getSimpleTypeByID(Values[0]);
2543 if ((Values.size() & 0x1) == 0) {
2544 // Not an odd number of values.
2545 std::string Buffer;
2546 raw_string_ostream StrBuf(Buffer);
2547 StrBuf << "function block phi record size not valid: " << Values.size();
2548 Error(StrBuf.str());
2549 appendErrorInstruction(Ty);
2550 return;
2551 }
2552 if (Ty == Ice::IceType_void) {
2553 Error("Phi record using type void not allowed");
2554 return;
2555 }
2556 Ice::Variable *Dest = getNextInstVar(Ty);
2557 Ice::InstPhi *Phi =
2558 Ice::InstPhi::create(Func.get(), Values.size() >> 1, Dest);
2559 for (size_t i = 1; i < Values.size(); i += 2) {
2560 Ice::Operand *Op =
2561 getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex);
2562 if (Op->getType() != Ty) {
2563 std::string Buffer;
2564 raw_string_ostream StrBuf(Buffer);
2565 StrBuf << "Value " << *Op << " not type " << Ty
2566 << " in phi instruction. Found: " << Op->getType();
2567 Error(StrBuf.str());
2568 appendErrorInstruction(Ty);
2569 return;
2570 }
2571 Phi->addArgument(Op, getBasicBlock(Values[i + 1]));
2572 }
2573 CurrentNode->appendInst(Phi);
2574 return;
2575 }
2576 case naclbitc::FUNC_CODE_INST_ALLOCA: {
2577 // ALLOCA: [Size, align]
2578 if (!isValidRecordSize(2, "alloca"))
2579 return;
2580 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex);
2581 uint32_t Alignment = Context->extractAlignment(this, "Alloca", Values[1]);
2582 Ice::Type PtrTy = Ice::getPointerType();
2583 if (ByteCount->getType() != Ice::IceType_i32) {
2584 std::string Buffer;
2585 raw_string_ostream StrBuf(Buffer);
2586 StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount;
2587 Error(StrBuf.str());
2588 appendErrorInstruction(PtrTy);
2589 return;
2590 }
2591 CurrentNode->appendInst(Ice::InstAlloca::create(
2592 Func.get(), getNextInstVar(PtrTy), ByteCount, Alignment));
2593 return;
2594 }
2595 case naclbitc::FUNC_CODE_INST_LOAD: {
2596 // LOAD: [address, align, ty]
2597 if (!isValidRecordSize(3, "load"))
2598 return;
2599 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
2600 Ice::Type Ty = Context->getSimpleTypeByID(Values[2]);
2601 uint32_t Alignment = Context->extractAlignment(this, "Load", Values[1]);
2602 if (!isValidPointerType(Address, "Load")) {
2603 appendErrorInstruction(Ty);
2604 return;
2605 }
2606 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) {
2607 appendErrorInstruction(Ty);
2608 return;
2609 }
2610 CurrentNode->appendInst(Ice::InstLoad::create(
2611 Func.get(), getNextInstVar(Ty), Address, Alignment));
2612 return;
2613 }
2614 case naclbitc::FUNC_CODE_INST_STORE: {
2615 // STORE: [address, value, align]
2616 if (!isValidRecordSize(3, "store"))
2617 return;
2618 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
2619 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex);
2620 uint32_t Alignment = Context->extractAlignment(this, "Store", Values[2]);
2621 if (!isValidPointerType(Address, "Store"))
2622 return;
2623 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store"))
2624 return;
2625 CurrentNode->appendInst(
2626 Ice::InstStore::create(Func.get(), Value, Address, Alignment));
2627 return;
2628 }
2629 case naclbitc::FUNC_CODE_INST_CALL:
2630 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: {
2631 // CALL: [cc, fnid, arg0, arg1...]
2632 // CALL_INDIRECT: [cc, fn, returnty, args...]
2633 //
2634 // Note: The difference between CALL and CALL_INDIRECT is that CALL has a
2635 // reference to an explicit function declaration, while the CALL_INDIRECT
2636 // is just an address. For CALL, we can infer the return type by looking up
2637 // the type signature associated with the function declaration. For
2638 // CALL_INDIRECT we can only infer the type signature via argument types,
2639 // and the corresponding return type stored in CALL_INDIRECT record.
2640 Ice::SizeT ParamsStartIndex = 2;
2641 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
2642 if (!isValidRecordSizeAtLeast(2, "call"))
2643 return;
2644 } else {
2645 if (!isValidRecordSizeAtLeast(3, "call indirect"))
2646 return;
2647 ParamsStartIndex = 3;
2648 }
2649
2650 uint32_t CalleeIndex = convertRelativeToAbsIndex(Values[1], BaseIndex);
2651 Ice::Operand *Callee = getOperand(CalleeIndex);
2652
2653 // Pull out signature/return type of call (if possible).
2654 Ice::FunctionDeclaration *Fcn = nullptr;
2655 const Ice::FuncSigType *Signature = nullptr;
2656 Ice::Type ReturnType = Ice::IceType_void;
2657 const Ice::Intrinsics::FullIntrinsicInfo *IntrinsicInfo = nullptr;
2658 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
2659 Fcn = Context->getFunctionByID(CalleeIndex);
2660 Signature = &Fcn->getSignature();
2661 ReturnType = Signature->getReturnType();
2662 Ice::SizeT NumParams = Values.size() - ParamsStartIndex;
2663 if (NumParams != Signature->getNumArgs()) {
2664 std::string Buffer;
2665 raw_string_ostream StrBuf(Buffer);
2666 StrBuf << "Call to " << printName(Fcn) << " has " << NumParams
2667 << " parameters. Signature expects: " << Signature->getNumArgs();
2668 Error(StrBuf.str());
2669 if (ReturnType != Ice::IceType_void)
2670 setNextLocalInstIndex(nullptr);
2671 return;
2672 }
2673
2674 // Check if this direct call is to an Intrinsic (starts with "llvm.")
2675 IntrinsicInfo = Fcn->getIntrinsicInfo(getTranslator().getContext());
2676 if (IntrinsicInfo && IntrinsicInfo->getNumArgs() != NumParams) {
2677 std::string Buffer;
2678 raw_string_ostream StrBuf(Buffer);
2679 StrBuf << "Call to " << printName(Fcn) << " has " << NumParams
2680 << " parameters. Intrinsic expects: " << Signature->getNumArgs();
2681 Error(StrBuf.str());
2682 if (ReturnType != Ice::IceType_void)
2683 setNextLocalInstIndex(nullptr);
2684 return;
2685 }
2686 } else { // Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL_INDIRECT
2687 // There is no signature. Assume defined by parameter types.
2688 ReturnType = Context->getSimpleTypeByID(Values[2]);
2689 if (Callee != nullptr)
2690 isValidPointerType(Callee, "Call indirect");
2691 }
2692
2693 if (Callee == nullptr)
2694 return;
2695
2696 // Extract out the the call parameters.
2697 SmallVector<Ice::Operand *, 8> Params;
2698 for (Ice::SizeT Index = ParamsStartIndex; Index < Values.size(); ++Index) {
2699 Ice::Operand *Op = getRelativeOperand(Values[Index], BaseIndex);
2700 if (Op == nullptr) {
2701 std::string Buffer;
2702 raw_string_ostream StrBuf(Buffer);
2703 StrBuf << "Parameter " << (Index - ParamsStartIndex + 1) << " of "
2704 << printName(Fcn) << " is not defined";
2705 Error(StrBuf.str());
2706 if (ReturnType != Ice::IceType_void)
2707 setNextLocalInstIndex(nullptr);
2708 return;
2709 }
2710 Params.push_back(Op);
2711 }
2712
2713 // Check return type.
2714 if (IntrinsicInfo == nullptr && !isCallReturnType(ReturnType)) {
2715 std::string Buffer;
2716 raw_string_ostream StrBuf(Buffer);
2717 StrBuf << "Return type of " << printName(Fcn)
2718 << " is invalid: " << ReturnType;
2719 Error(StrBuf.str());
2720 ReturnType = Ice::IceType_i32;
2721 }
2722
2723 // Type check call parameters.
2724 for (Ice::SizeT Index = 0; Index < Params.size(); ++Index) {
2725 Ice::Operand *Op = Params[Index];
2726 Ice::Type OpType = Op->getType();
2727 if (Signature)
2728 verifyCallArgTypeMatches(Fcn, Index, OpType,
2729 Signature->getArgType(Index));
2730 else if (!isCallParameterType(OpType)) {
2731 std::string Buffer;
2732 raw_string_ostream StrBuf(Buffer);
2733 StrBuf << "Argument " << *Op << " of " << printName(Fcn)
2734 << " has invalid type: " << Op->getType();
2735 Error(StrBuf.str());
2736 appendErrorInstruction(ReturnType);
2737 return;
2738 }
2739 }
2740
2741 // Extract call information.
2742 uint64_t CCInfo = Values[0];
2743 CallingConv::ID CallingConv;
2744 if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) {
2745 std::string Buffer;
2746 raw_string_ostream StrBuf(Buffer);
2747 StrBuf << "Function call calling convention value " << (CCInfo >> 1)
2748 << " not understood.";
2749 Error(StrBuf.str());
2750 appendErrorInstruction(ReturnType);
2751 return;
2752 }
2753 const bool IsTailCall = (CCInfo & 1);
2754
2755 // Create the call instruction.
2756 Ice::Variable *Dest = (ReturnType == Ice::IceType_void)
2757 ? nullptr
2758 : getNextInstVar(ReturnType);
2759 std::unique_ptr<Ice::InstCall> Instr;
2760 if (IntrinsicInfo) {
2761 Instr.reset(Ice::InstIntrinsicCall::create(
2762 Func.get(), Params.size(), Dest, Callee, IntrinsicInfo->Info));
2763 } else {
2764 Instr.reset(Ice::InstCall::create(Func.get(), Params.size(), Dest, Callee,
2765 IsTailCall));
2766 }
2767 for (Ice::Operand *Param : Params)
2768 Instr->addArg(Param);
2769 CurrentNode->appendInst(Instr.release());
2770 return;
2771 }
2772 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: {
2773 // FORWARDTYPEREF: [opval, ty]
2774 if (!isValidRecordSize(2, "forward type ref"))
2775 return;
2776 Ice::Type OpType = Context->getSimpleTypeByID(Values[1]);
2777 setOperand(Values[0], createInstVar(OpType));
2778 return;
2779 }
2780 default:
2781 // Generate error message!
2782 BlockParserBaseClass::ProcessRecord();
2783 return;
2784 }
2785 }
2786
2787 /// Parses constants within a function block.
2788 class ConstantsParser final : public BlockParserBaseClass {
2789 ConstantsParser() = delete;
2790 ConstantsParser(const ConstantsParser &) = delete;
2791 ConstantsParser &operator=(const ConstantsParser &) = delete;
2792
2793 public:
ConstantsParser(unsigned BlockID,FunctionParser * FuncParser)2794 ConstantsParser(unsigned BlockID, FunctionParser *FuncParser)
2795 : BlockParserBaseClass(BlockID, FuncParser),
2796 Timer(Ice::TimerStack::TT_parseConstants, getTranslator().getContext()),
2797 FuncParser(FuncParser) {}
2798
2799 ~ConstantsParser() override = default;
2800
getBlockName() const2801 const char *getBlockName() const override { return "constants"; }
2802
2803 private:
2804 Ice::TimerMarker Timer;
2805 // The parser of the function block this constants block appears in.
2806 FunctionParser *FuncParser;
2807 // The type to use for succeeding constants.
2808 Ice::Type NextConstantType = Ice::IceType_void;
2809
2810 void ProcessRecord() override;
2811
getContext()2812 Ice::GlobalContext *getContext() { return getTranslator().getContext(); }
2813
2814 // Returns true if the type to use for succeeding constants is defined. If
2815 // false, also generates an error message.
isValidNextConstantType()2816 bool isValidNextConstantType() {
2817 if (NextConstantType != Ice::IceType_void)
2818 return true;
2819 Error("Constant record not preceded by set type record");
2820 return false;
2821 }
2822 };
2823
ProcessRecord()2824 void ConstantsParser::ProcessRecord() {
2825 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
2826 switch (Record.GetCode()) {
2827 case naclbitc::CST_CODE_SETTYPE: {
2828 // SETTYPE: [typeid]
2829 if (!isValidRecordSize(1, "set type"))
2830 return;
2831 NextConstantType = Context->getSimpleTypeByID(Values[0]);
2832 if (NextConstantType == Ice::IceType_void)
2833 Error("constants block set type not allowed for void type");
2834 return;
2835 }
2836 case naclbitc::CST_CODE_UNDEF: {
2837 // UNDEF
2838 if (!isValidRecordSize(0, "undef"))
2839 return;
2840 if (!isValidNextConstantType())
2841 return;
2842 FuncParser->setNextConstantID(
2843 getContext()->getConstantUndef(NextConstantType));
2844 return;
2845 }
2846 case naclbitc::CST_CODE_INTEGER: {
2847 // INTEGER: [intval]
2848 if (!isValidRecordSize(1, "integer"))
2849 return;
2850 if (!isValidNextConstantType())
2851 return;
2852 if (Ice::isScalarIntegerType(NextConstantType)) {
2853 BitcodeInt Value(Ice::getScalarIntBitWidth(NextConstantType),
2854 NaClDecodeSignRotatedValue(Values[0]));
2855 if (Ice::Constant *C = getContext()->getConstantInt(
2856 NextConstantType, Value.getSExtValue())) {
2857 FuncParser->setNextConstantID(C);
2858 return;
2859 }
2860 }
2861 std::string Buffer;
2862 raw_string_ostream StrBuf(Buffer);
2863 StrBuf << "constant block integer record for non-integer type "
2864 << NextConstantType;
2865 Error(StrBuf.str());
2866 return;
2867 }
2868 case naclbitc::CST_CODE_FLOAT: {
2869 // FLOAT: [fpval]
2870 if (!isValidRecordSize(1, "float"))
2871 return;
2872 if (!isValidNextConstantType())
2873 return;
2874 switch (NextConstantType) {
2875 case Ice::IceType_f32: {
2876 const BitcodeInt Value(32, static_cast<uint32_t>(Values[0]));
2877 float FpValue = Value.convertToFp<int32_t, float>();
2878 FuncParser->setNextConstantID(getContext()->getConstantFloat(FpValue));
2879 return;
2880 }
2881 case Ice::IceType_f64: {
2882 const BitcodeInt Value(64, Values[0]);
2883 double FpValue = Value.convertToFp<uint64_t, double>();
2884 FuncParser->setNextConstantID(getContext()->getConstantDouble(FpValue));
2885 return;
2886 }
2887 default: {
2888 std::string Buffer;
2889 raw_string_ostream StrBuf(Buffer);
2890 StrBuf << "constant block float record for non-floating type "
2891 << NextConstantType;
2892 Error(StrBuf.str());
2893 return;
2894 }
2895 }
2896 }
2897 default:
2898 // Generate error message!
2899 BlockParserBaseClass::ProcessRecord();
2900 return;
2901 }
2902 }
2903
2904 // Parses valuesymtab blocks appearing in a function block.
2905 class FunctionValuesymtabParser final : public ValuesymtabParser {
2906 FunctionValuesymtabParser() = delete;
2907 FunctionValuesymtabParser(const FunctionValuesymtabParser &) = delete;
2908 void operator=(const FunctionValuesymtabParser &) = delete;
2909
2910 public:
FunctionValuesymtabParser(unsigned BlockID,FunctionParser * EnclosingParser)2911 FunctionValuesymtabParser(unsigned BlockID, FunctionParser *EnclosingParser)
2912 : ValuesymtabParser(BlockID, EnclosingParser),
2913 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs,
2914 getTranslator().getContext()) {}
2915
2916 private:
2917 Ice::TimerMarker Timer;
2918 // Returns the enclosing function parser.
getFunctionParser() const2919 FunctionParser *getFunctionParser() const {
2920 return reinterpret_cast<FunctionParser *>(GetEnclosingParser());
2921 }
2922
getTableKind() const2923 const char *getTableKind() const override { return "Function"; }
2924
2925 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override;
2926 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override;
2927
2928 // Reports that the assignment of Name to the value associated with index is
2929 // not possible, for the given Context.
reportUnableToAssign(const char * Context,NaClBcIndexSize_t Index,StringType & Name)2930 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index,
2931 StringType &Name) {
2932 std::string Buffer;
2933 raw_string_ostream StrBuf(Buffer);
2934 StrBuf << "Function-local " << Context << " name '" << Name
2935 << "' can't be associated with index " << Index;
2936 Error(StrBuf.str());
2937 }
2938 };
2939
setValueName(NaClBcIndexSize_t Index,StringType & Name)2940 void FunctionValuesymtabParser::setValueName(NaClBcIndexSize_t Index,
2941 StringType &Name) {
2942 // Note: We check when Index is too small, so that we can error recover
2943 // (FP->getOperand will create fatal error).
2944 if (Index < getFunctionParser()->getNumGlobalIDs()) {
2945 reportUnableToAssign("Global value", Index, Name);
2946 return;
2947 }
2948 Ice::Operand *Op = getFunctionParser()->getOperand(Index);
2949 if (auto *V = dyn_cast<Ice::Variable>(Op)) {
2950 if (Ice::BuildDefs::dump()) {
2951 std::string Nm(Name.data(), Name.size());
2952 V->setName(getFunctionParser()->getFunc(), Nm);
2953 }
2954 } else {
2955 reportUnableToAssign("Local value", Index, Name);
2956 }
2957 }
2958
setBbName(NaClBcIndexSize_t Index,StringType & Name)2959 void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index,
2960 StringType &Name) {
2961 if (!Ice::BuildDefs::dump())
2962 return;
2963 if (Index >= getFunctionParser()->getFunc()->getNumNodes()) {
2964 reportUnableToAssign("Basic block", Index, Name);
2965 return;
2966 }
2967 std::string Nm(Name.data(), Name.size());
2968 if (Ice::BuildDefs::dump())
2969 getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm);
2970 }
2971
ParseBlock(unsigned BlockID)2972 bool FunctionParser::ParseBlock(unsigned BlockID) {
2973 #ifndef PNACL_LLVM
2974 constexpr bool PNaClAllowLocalSymbolTables = true;
2975 #endif // !PNACL_LLVM
2976 switch (BlockID) {
2977 case naclbitc::CONSTANTS_BLOCK_ID: {
2978 ConstantsParser Parser(BlockID, this);
2979 return Parser.ParseThisBlock();
2980 }
2981 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
2982 if (PNaClAllowLocalSymbolTables) {
2983 FunctionValuesymtabParser Parser(BlockID, this);
2984 return Parser.ParseThisBlock();
2985 }
2986 break;
2987 }
2988 default:
2989 break;
2990 }
2991 return BlockParserBaseClass::ParseBlock(BlockID);
2992 }
2993
2994 /// Parses the module block in the bitcode file.
2995 class ModuleParser final : public BlockParserBaseClass {
2996 ModuleParser() = delete;
2997 ModuleParser(const ModuleParser &) = delete;
2998 ModuleParser &operator=(const ModuleParser &) = delete;
2999
3000 public:
ModuleParser(unsigned BlockID,TopLevelParser * Context)3001 ModuleParser(unsigned BlockID, TopLevelParser *Context)
3002 : BlockParserBaseClass(BlockID, Context),
3003 Timer(Ice::TimerStack::TT_parseModule,
3004 Context->getTranslator().getContext()),
3005 IsParseParallel(Ice::getFlags().isParseParallel()) {}
3006 ~ModuleParser() override = default;
getBlockName() const3007 const char *getBlockName() const override { return "module"; }
getCursor() const3008 NaClBitstreamCursor &getCursor() const { return Record.GetCursor(); }
3009
3010 private:
3011 Ice::TimerMarker Timer;
3012 // True if we have already installed names for unnamed global declarations,
3013 // and have generated global constant initializers.
3014 bool GlobalDeclarationNamesAndInitializersInstalled = false;
3015 // True if we have already processed the symbol table for the module.
3016 bool FoundValuesymtab = false;
3017 const bool IsParseParallel;
3018
3019 // Generates names for unnamed global addresses (i.e. functions and global
3020 // variables). Then lowers global variable declaration initializers to the
3021 // target. May be called multiple times. Only the first call will do the
3022 // installation.
installGlobalNamesAndGlobalVarInitializers()3023 void installGlobalNamesAndGlobalVarInitializers() {
3024 if (!GlobalDeclarationNamesAndInitializersInstalled) {
3025 Context->installGlobalNames();
3026 Context->createValueIDs();
3027 Context->verifyFunctionTypeSignatures();
3028 std::unique_ptr<Ice::VariableDeclarationList> Globals =
3029 Context->getGlobalVariables();
3030 if (Globals)
3031 getTranslator().lowerGlobals(std::move(Globals));
3032 GlobalDeclarationNamesAndInitializersInstalled = true;
3033 }
3034 }
3035 bool ParseBlock(unsigned BlockID) override;
3036
ExitBlock()3037 void ExitBlock() override {
3038 installGlobalNamesAndGlobalVarInitializers();
3039 Context->getTranslator().getContext()->waitForWorkerThreads();
3040 }
3041
3042 void ProcessRecord() override;
3043 };
3044
3045 class ModuleValuesymtabParser : public ValuesymtabParser {
3046 ModuleValuesymtabParser() = delete;
3047 ModuleValuesymtabParser(const ModuleValuesymtabParser &) = delete;
3048 void operator=(const ModuleValuesymtabParser &) = delete;
3049
3050 public:
ModuleValuesymtabParser(unsigned BlockID,ModuleParser * MP)3051 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP)
3052 : ValuesymtabParser(BlockID, MP),
3053 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs,
3054 getTranslator().getContext()) {}
3055
3056 ~ModuleValuesymtabParser() override = default;
3057
3058 private:
3059 Ice::TimerMarker Timer;
getTableKind() const3060 const char *getTableKind() const override { return "Module"; }
3061 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override;
3062 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override;
3063 };
3064
setValueName(NaClBcIndexSize_t Index,StringType & Name)3065 void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index,
3066 StringType &Name) {
3067 Ice::GlobalDeclaration *Decl = Context->getGlobalDeclarationByID(Index);
3068 if (llvm::isa<Ice::VariableDeclaration>(Decl) &&
3069 Decl->isPNaClABIExternalName(Name.str())) {
3070 // Force linkage of (specific) Global Variables be external for the PNaCl
3071 // ABI. PNaCl bitcode has a linkage field for Functions, but not for
3072 // GlobalVariables (because the latter is not needed for pexes, so it has
3073 // been removed).
3074 Decl->setLinkage(llvm::GlobalValue::ExternalLinkage);
3075 }
3076
3077 // Unconditionally capture the name if it is provided in the input file,
3078 // regardless of whether dump is enabled or whether the symbol is internal vs
3079 // external. This fits in well with the lit tests, and most symbols in a
3080 // conforming pexe are nameless and don't take this path.
3081 Decl->setName(getTranslator().getContext(),
3082 StringRef(Name.data(), Name.size()));
3083 }
3084
setBbName(NaClBcIndexSize_t Index,StringType & Name)3085 void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index,
3086 StringType &Name) {
3087 reportUnableToAssign("Basic block", Index, Name);
3088 }
3089
3090 class CfgParserWorkItem final : public Ice::OptWorkItem {
3091 CfgParserWorkItem() = delete;
3092 CfgParserWorkItem(const CfgParserWorkItem &) = delete;
3093 CfgParserWorkItem &operator=(const CfgParserWorkItem &) = delete;
3094
3095 public:
CfgParserWorkItem(unsigned BlockID,NaClBcIndexSize_t FcnId,ModuleParser * ModParser,std::unique_ptr<uint8_t[]> Buffer,uintptr_t BufferSize,uint64_t StartBit,uint32_t SeqNumber)3096 CfgParserWorkItem(unsigned BlockID, NaClBcIndexSize_t FcnId,
3097 ModuleParser *ModParser, std::unique_ptr<uint8_t[]> Buffer,
3098 uintptr_t BufferSize, uint64_t StartBit, uint32_t SeqNumber)
3099 : BlockID(BlockID), FcnId(FcnId), ModParser(ModParser),
3100 Buffer(std::move(Buffer)), BufferSize(BufferSize), StartBit(StartBit),
3101 SeqNumber(SeqNumber) {}
3102 std::unique_ptr<Ice::Cfg> getParsedCfg() override;
3103 ~CfgParserWorkItem() override = default;
3104
3105 private:
3106 const unsigned BlockID;
3107 const NaClBcIndexSize_t FcnId;
3108 // Note: ModParser can't be const because the function parser needs to
3109 // access non-const member functions (of ModuleParser and TopLevelParser).
3110 // TODO(kschimpf): Fix this issue.
3111 ModuleParser *ModParser;
3112 const std::unique_ptr<uint8_t[]> Buffer;
3113 const uintptr_t BufferSize;
3114 const uint64_t StartBit;
3115 const uint32_t SeqNumber;
3116 };
3117
getParsedCfg()3118 std::unique_ptr<Ice::Cfg> CfgParserWorkItem::getParsedCfg() {
3119 NaClBitstreamCursor &OldCursor(ModParser->getCursor());
3120 llvm::NaClBitstreamReader Reader(OldCursor.getStartWordByteForBit(StartBit),
3121 Buffer.get(), Buffer.get() + BufferSize,
3122 OldCursor.getBitStreamReader());
3123 NaClBitstreamCursor NewCursor(Reader);
3124 NewCursor.JumpToBit(NewCursor.getWordBitNo(StartBit));
3125 FunctionParser Parser(BlockID, ModParser, FcnId, NewCursor);
3126 return Parser.parseFunction(SeqNumber);
3127 }
3128
ParseBlock(unsigned BlockID)3129 bool ModuleParser::ParseBlock(unsigned BlockID) {
3130 switch (BlockID) {
3131 case naclbitc::BLOCKINFO_BLOCK_ID:
3132 return NaClBitcodeParser::ParseBlock(BlockID);
3133 case naclbitc::TYPE_BLOCK_ID_NEW: {
3134 TypesParser Parser(BlockID, this);
3135 return Parser.ParseThisBlock();
3136 }
3137 case naclbitc::GLOBALVAR_BLOCK_ID: {
3138 GlobalsParser Parser(BlockID, this);
3139 return Parser.ParseThisBlock();
3140 }
3141 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
3142 if (FoundValuesymtab)
3143 Fatal("Duplicate valuesymtab in module");
3144
3145 // If we have already processed a function block (i.e. we have already
3146 // installed global names and variable initializers) we can no longer accept
3147 // the value symbol table. Names have already been generated.
3148 if (GlobalDeclarationNamesAndInitializersInstalled)
3149 Fatal("Module valuesymtab not allowed after function blocks");
3150
3151 FoundValuesymtab = true;
3152 ModuleValuesymtabParser Parser(BlockID, this);
3153 return Parser.ParseThisBlock();
3154 }
3155 case naclbitc::FUNCTION_BLOCK_ID: {
3156 installGlobalNamesAndGlobalVarInitializers();
3157 Ice::GlobalContext *Ctx = Context->getTranslator().getContext();
3158 uint32_t SeqNumber = Context->getTranslator().getNextSequenceNumber();
3159 NaClBcIndexSize_t FcnId = Context->getNextFunctionBlockValueID();
3160 if (IsParseParallel) {
3161 // Skip the block and copy into a buffer. Note: We copy into a buffer
3162 // using the top-level parser to make sure that the underlying
3163 // buffer reading from the data streamer is not thread safe.
3164 NaClBitstreamCursor &Cursor = Record.GetCursor();
3165 uint64_t StartBit = Cursor.GetCurrentBitNo();
3166 if (SkipBlock())
3167 return true;
3168 const uint64_t EndBit = Cursor.GetCurrentBitNo();
3169 const uintptr_t StartByte = Cursor.getStartWordByteForBit(StartBit);
3170 const uintptr_t EndByte = Cursor.getEndWordByteForBit(EndBit);
3171 const uintptr_t BufferSize = EndByte - StartByte;
3172 std::unique_ptr<uint8_t[]> Buffer((uint8_t *)(new uint8_t[BufferSize]));
3173 for (size_t i = Cursor.fillBuffer(Buffer.get(), BufferSize, StartByte);
3174 i < BufferSize; ++i) {
3175 Buffer[i] = 0;
3176 }
3177 Ctx->optQueueBlockingPush(Ice::makeUnique<CfgParserWorkItem>(
3178 BlockID, FcnId, this, std::move(Buffer), BufferSize, StartBit,
3179 SeqNumber));
3180 return false;
3181 } else {
3182 FunctionParser Parser(BlockID, this, FcnId);
3183 std::unique_ptr<Ice::Cfg> Func = Parser.parseFunction(SeqNumber);
3184 bool Failed = Func->hasError();
3185 getTranslator().translateFcn(std::move(Func));
3186 return Failed && !Ice::getFlags().getAllowErrorRecovery();
3187 }
3188 }
3189 default:
3190 return BlockParserBaseClass::ParseBlock(BlockID);
3191 }
3192 }
3193
ProcessRecord()3194 void ModuleParser::ProcessRecord() {
3195 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
3196 switch (Record.GetCode()) {
3197 case naclbitc::MODULE_CODE_VERSION: {
3198 // VERSION: [version#]
3199 if (!isValidRecordSize(1, "version"))
3200 return;
3201 uint64_t Version = Values[0];
3202 if (Version != 1) {
3203 std::string Buffer;
3204 raw_string_ostream StrBuf(Buffer);
3205 StrBuf << "Unknown bitstream version: " << Version;
3206 Error(StrBuf.str());
3207 }
3208 return;
3209 }
3210 case naclbitc::MODULE_CODE_FUNCTION: {
3211 // FUNCTION: [type, callingconv, isproto, linkage]
3212 if (!isValidRecordSize(4, "address"))
3213 return;
3214 const Ice::FuncSigType &Signature = Context->getFuncSigTypeByID(Values[0]);
3215 CallingConv::ID CallingConv;
3216 if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) {
3217 std::string Buffer;
3218 raw_string_ostream StrBuf(Buffer);
3219 StrBuf << "Function address has unknown calling convention: "
3220 << Values[1];
3221 Error(StrBuf.str());
3222 return;
3223 }
3224 GlobalValue::LinkageTypes Linkage;
3225 if (!naclbitc::DecodeLinkage(Values[3], Linkage)) {
3226 std::string Buffer;
3227 raw_string_ostream StrBuf(Buffer);
3228 StrBuf << "Function address has unknown linkage. Found " << Values[3];
3229 Error(StrBuf.str());
3230 return;
3231 }
3232 bool IsProto = Values[2] == 1;
3233 auto *Func = Ice::FunctionDeclaration::create(
3234 Context->getTranslator().getContext(), Signature, CallingConv, Linkage,
3235 IsProto);
3236 Context->setNextFunctionID(Func);
3237 return;
3238 }
3239 default:
3240 BlockParserBaseClass::ProcessRecord();
3241 return;
3242 }
3243 }
3244
ParseBlock(unsigned BlockID)3245 bool TopLevelParser::ParseBlock(unsigned BlockID) {
3246 if (BlockID == naclbitc::MODULE_BLOCK_ID) {
3247 if (ParsedModuleBlock)
3248 Fatal("Input can't contain more than one module");
3249 ModuleParser Parser(BlockID, this);
3250 bool ParseFailed = Parser.ParseThisBlock();
3251 ParsedModuleBlock = true;
3252 return ParseFailed;
3253 }
3254 // Generate error message by using default block implementation.
3255 BlockParserBaseClass Parser(BlockID, this);
3256 return Parser.ParseThisBlock();
3257 }
3258
3259 } // end of anonymous namespace
3260
3261 namespace Ice {
3262
translateBuffer(const std::string & IRFilename,MemoryBuffer * MemBuf)3263 void PNaClTranslator::translateBuffer(const std::string &IRFilename,
3264 MemoryBuffer *MemBuf) {
3265 std::unique_ptr<MemoryObject> MemObj(getNonStreamedMemoryObject(
3266 reinterpret_cast<const unsigned char *>(MemBuf->getBufferStart()),
3267 reinterpret_cast<const unsigned char *>(MemBuf->getBufferEnd())));
3268 translate(IRFilename, std::move(MemObj));
3269 }
3270
translate(const std::string & IRFilename,std::unique_ptr<MemoryObject> && MemObj)3271 void PNaClTranslator::translate(const std::string &IRFilename,
3272 std::unique_ptr<MemoryObject> &&MemObj) {
3273 // On error, we report_fatal_error to avoid destroying the MemObj. That may
3274 // still be in use by IceBrowserCompileServer. Otherwise, we need to change
3275 // the MemObj to be ref-counted, or have a wrapper, or simply leak. We also
3276 // need a hook to tell the IceBrowserCompileServer to unblock its
3277 // QueueStreamer.
3278 // https://code.google.com/p/nativeclient/issues/detail?id=4163
3279 // Read header and verify it is good.
3280 NaClBitcodeHeader Header;
3281 if (Header.Read(MemObj.get())) {
3282 llvm::report_fatal_error("Invalid PNaCl bitcode header");
3283 }
3284 if (!Header.IsSupported()) {
3285 getContext()->getStrError() << Header.Unsupported();
3286 if (!Header.IsReadable()) {
3287 llvm::report_fatal_error("Invalid PNaCl bitcode header");
3288 }
3289 }
3290
3291 // Create a bitstream reader to read the bitcode file.
3292 NaClBitstreamReader InputStreamFile(MemObj.release(), Header);
3293 NaClBitstreamCursor InputStream(InputStreamFile);
3294
3295 TopLevelParser Parser(*this, InputStream, ErrorStatus);
3296 while (!InputStream.AtEndOfStream()) {
3297 if (Parser.Parse()) {
3298 ErrorStatus.assign(EC_Bitcode);
3299 return;
3300 }
3301 }
3302
3303 if (!Parser.parsedModuleBlock()) {
3304 std::string Buffer;
3305 raw_string_ostream StrBuf(Buffer);
3306 StrBuf << IRFilename << ": Does not contain a module!";
3307 llvm::report_fatal_error(StrBuf.str());
3308 }
3309 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) {
3310 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes");
3311 }
3312 }
3313
3314 } // end of namespace Ice
3315