• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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