Index: src/PNaClTranslator.cpp |
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp |
index a9f60b859cc41a7b38dec8303756a5c329d1c280..cb05493836d29c60ec0cc242b0d957ec79aaa27e 100644 |
--- a/src/PNaClTranslator.cpp |
+++ b/src/PNaClTranslator.cpp |
@@ -14,6 +14,7 @@ |
#include "llvm/ADT/SmallString.h" |
#include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h" |
+#include "llvm/Bitcode/NaCl/NaClBitcodeDefs.h" |
#include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" |
#include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" |
#include "llvm/Bitcode/NaCl/NaClReaderWriter.h" |
@@ -182,14 +183,16 @@ public: |
const std::string &Message) final; |
/// Generates error message with respect to the current block parser. |
- bool BlockError(const std::string &Message); |
+ bool blockError(const std::string &Message); |
/// Returns the number of errors found while parsing the bitcode |
/// file. |
unsigned getNumErrors() const { return NumErrors; } |
/// Changes the size of the type list to the given size. |
- void resizeTypeIDValues(unsigned NewSize) { TypeIDValues.resize(NewSize); } |
+ void resizeTypeIDValues(size_t NewSize) { TypeIDValues.resize(NewSize); } |
+ |
+ size_t getNumTypeIDValues() const { return TypeIDValues.size(); } |
/// Returns true if generation of Subzero IR is disabled. |
bool isIRGenerationDisabled() const { |
@@ -198,19 +201,29 @@ public: |
/// Returns the undefined type associated with type ID. |
/// Note: Returns extended type ready to be defined. |
- ExtendedType *getTypeByIDForDefining(unsigned ID) { |
+ ExtendedType *getTypeByIDForDefining(NaClBcIndexSize_t ID) { |
// Get corresponding element, verifying the value is still undefined |
// (and hence allowed to be defined). |
ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Undefined); |
if (Ty) |
return Ty; |
- if (ID >= TypeIDValues.size()) |
+ if (ID >= TypeIDValues.size()) { |
+ if (ID >= NaClBcIndexSize_t_Max) { |
+ std::string Buffer; |
+ raw_string_ostream StrBuf(Buffer); |
+ StrBuf << "Can't define more than " << NaClBcIndexSize_t_Max |
+ << " types\n"; |
+ blockError(StrBuf.str()); |
+ // Recover by using existing type slot. |
+ return &TypeIDValues[0]; |
+ } |
TypeIDValues.resize(ID + 1); |
+ } |
return &TypeIDValues[ID]; |
} |
/// Returns the type associated with the given index. |
- Ice::Type getSimpleTypeByID(unsigned ID) { |
+ Ice::Type getSimpleTypeByID(NaClBcIndexSize_t ID) { |
const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Simple); |
if (Ty == nullptr) |
// Return error recovery value. |
@@ -219,7 +232,7 @@ public: |
} |
/// Returns the type signature associated with the given index. |
- const Ice::FuncSigType &getFuncSigTypeByID(unsigned ID) { |
+ const Ice::FuncSigType &getFuncSigTypeByID(NaClBcIndexSize_t ID) { |
const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::FuncSig); |
if (Ty == nullptr) |
// Return error recovery value. |
@@ -235,7 +248,7 @@ public: |
/// Returns the value id that should be associated with the the |
/// current function block. Increments internal counters during call |
/// so that it will be in correct position for next function block. |
- size_t getNextFunctionBlockValueID() { |
+ NaClBcIndexSize_t getNextFunctionBlockValueID() { |
size_t NumDeclaredFunctions = FunctionDeclarationList.size(); |
while (NextDefiningFunctionID < NumDeclaredFunctions && |
FunctionDeclarationList[NextDefiningFunctionID]->isProto()) |
@@ -246,14 +259,14 @@ public: |
} |
/// Returns the function associated with ID. |
- Ice::FunctionDeclaration *getFunctionByID(unsigned ID) { |
+ Ice::FunctionDeclaration *getFunctionByID(NaClBcIndexSize_t ID) { |
if (ID < FunctionDeclarationList.size()) |
return FunctionDeclarationList[ID]; |
return reportGetFunctionByIDError(ID); |
} |
/// Returns the constant associated with the given global value ID. |
- Ice::Constant *getGlobalConstantByID(unsigned ID) { |
+ Ice::Constant *getGlobalConstantByID(NaClBcIndexSize_t ID) { |
assert(ID < ValueIDConstants.size()); |
return ValueIDConstants[ID]; |
} |
@@ -276,11 +289,11 @@ public: |
} |
/// Returns the number of function declarations in the bitcode file. |
- unsigned getNumFunctionIDs() const { return FunctionDeclarationList.size(); } |
+ size_t getNumFunctionIDs() const { return FunctionDeclarationList.size(); } |
/// Returns the number of global declarations (i.e. IDs) defined in |
/// the bitcode file. |
- unsigned getNumGlobalIDs() const { |
+ size_t getNumGlobalIDs() const { |
if (VariableDeclarations) { |
return FunctionDeclarationList.size() + VariableDeclarations->size(); |
} else { |
@@ -289,7 +302,7 @@ public: |
} |
/// Creates Count global variable declarations. |
- void CreateGlobalVariables(size_t Count) { |
+ void createGlobalVariables(NaClBcIndexSize_t Count) { |
assert(VariableDeclarations); |
assert(VariableDeclarations->empty()); |
for (size_t i = 0; i < Count; ++i) { |
@@ -300,7 +313,7 @@ public: |
/// Returns the number of global variable declarations in the |
/// bitcode file. |
- Ice::SizeT getNumGlobalVariables() const { |
+ size_t getNumGlobalVariables() const { |
if (VariableDeclarations) { |
return VariableDeclarations->size(); |
} else { |
@@ -309,7 +322,7 @@ public: |
} |
/// Returns the global variable declaration with the given index. |
- Ice::VariableDeclaration *getGlobalVariableByID(unsigned Index) { |
+ Ice::VariableDeclaration *getGlobalVariableByID(NaClBcIndexSize_t Index) { |
assert(VariableDeclarations); |
if (Index < VariableDeclarations->size()) |
return VariableDeclarations->at(Index); |
@@ -318,7 +331,7 @@ public: |
/// Returns the global declaration (variable or function) with the |
/// given Index. |
- Ice::GlobalDeclaration *getGlobalDeclarationByID(size_t Index) { |
+ Ice::GlobalDeclaration *getGlobalDeclarationByID(NaClBcIndexSize_t Index) { |
size_t NumFunctionIds = FunctionDeclarationList.size(); |
if (Index < NumFunctionIds) |
return getFunctionByID(Index); |
@@ -372,7 +385,7 @@ private: |
// extended type is of the WantedKind. Generates error message if |
// corresponding extended type of WantedKind can't be found, and |
// returns nullptr. |
- ExtendedType *getTypeByIDAsKind(unsigned ID, |
+ ExtendedType *getTypeByIDAsKind(NaClBcIndexSize_t ID, |
ExtendedType::TypeKind WantedKind) { |
ExtendedType *Ty = nullptr; |
if (ID < TypeIDValues.size()) { |
@@ -393,7 +406,8 @@ private: |
// declarations. |
void installDeclarationName(Ice::GlobalDeclaration *Decl, |
const Ice::IceString &Prefix, |
- const char *DeclType, uint32_t &NameIndex) { |
+ const char *DeclType, |
+ NaClBcIndexSize_t &NameIndex) { |
if (Decl->hasName()) { |
Translator.checkIfUnnamedNameSafe(Decl->getName(), DeclType, Prefix); |
} else { |
@@ -408,7 +422,7 @@ private: |
const Ice::IceString &GlobalPrefix = |
getTranslator().getFlags().getDefaultGlobalPrefix(); |
if (!GlobalPrefix.empty()) { |
- uint32_t NameIndex = 0; |
+ NaClBcIndexSize_t NameIndex = 0; |
for (Ice::VariableDeclaration *Var : *VariableDeclarations) { |
installDeclarationName(Var, GlobalPrefix, "global", NameIndex); |
} |
@@ -420,7 +434,7 @@ private: |
const Ice::IceString &FunctionPrefix = |
getTranslator().getFlags().getDefaultFunctionPrefix(); |
if (!FunctionPrefix.empty()) { |
- uint32_t NameIndex = 0; |
+ NaClBcIndexSize_t NameIndex = 0; |
for (Ice::FunctionDeclaration *Func : FunctionDeclarationList) { |
installDeclarationName(Func, FunctionPrefix, "function", NameIndex); |
} |
@@ -465,19 +479,20 @@ private: |
} |
// Reports that type ID is undefined, or not of the WantedType. |
- void reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty, |
+ void reportBadTypeIDAs(NaClBcIndexSize_t ID, const ExtendedType *Ty, |
ExtendedType::TypeKind WantedType); |
// Reports that there is no function declaration for ID. Returns an |
// error recovery value to use. |
- Ice::FunctionDeclaration *reportGetFunctionByIDError(unsigned ID); |
+ Ice::FunctionDeclaration *reportGetFunctionByIDError(NaClBcIndexSize_t ID); |
// Reports that there is not global variable declaration for |
// ID. Returns an error recovery value to use. |
- Ice::VariableDeclaration *reportGetGlobalVariableByIDError(unsigned Index); |
+ Ice::VariableDeclaration * |
+ reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index); |
// Reports that there is no corresponding ICE type for LLVMTy, and |
- // returns ICE::IceType_void. |
+ // returns Ice::IceType_void. |
Ice::Type convertToIceTypeError(Type *LLVMTy); |
}; |
@@ -498,7 +513,8 @@ bool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, |
return true; |
} |
-void TopLevelParser::reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty, |
+void TopLevelParser::reportBadTypeIDAs(NaClBcIndexSize_t ID, |
+ const ExtendedType *Ty, |
ExtendedType::TypeKind WantedType) { |
std::string Buffer; |
raw_string_ostream StrBuf(Buffer); |
@@ -507,17 +523,17 @@ void TopLevelParser::reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty, |
} else { |
StrBuf << "Type id " << ID << " not " << WantedType << ". Found: " << *Ty; |
} |
- BlockError(StrBuf.str()); |
+ blockError(StrBuf.str()); |
} |
Ice::FunctionDeclaration * |
-TopLevelParser::reportGetFunctionByIDError(unsigned ID) { |
+TopLevelParser::reportGetFunctionByIDError(NaClBcIndexSize_t ID) { |
std::string Buffer; |
raw_string_ostream StrBuf(Buffer); |
StrBuf << "Function index " << ID |
<< " not allowed. Out of range. Must be less than " |
<< FunctionDeclarationList.size(); |
- BlockError(StrBuf.str()); |
+ blockError(StrBuf.str()); |
// TODO(kschimpf) Remove error recovery once implementation complete. |
if (!FunctionDeclarationList.empty()) |
return FunctionDeclarationList[0]; |
@@ -525,13 +541,13 @@ TopLevelParser::reportGetFunctionByIDError(unsigned ID) { |
} |
Ice::VariableDeclaration * |
-TopLevelParser::reportGetGlobalVariableByIDError(unsigned Index) { |
+TopLevelParser::reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index) { |
std::string Buffer; |
raw_string_ostream StrBuf(Buffer); |
StrBuf << "Global index " << Index |
<< " not allowed. Out of range. Must be less than " |
<< VariableDeclarations->size(); |
- BlockError(StrBuf.str()); |
+ blockError(StrBuf.str()); |
// TODO(kschimpf) Remove error recovery once implementation complete. |
if (!VariableDeclarations->empty()) |
return VariableDeclarations->at(0); |
@@ -602,40 +618,40 @@ protected: |
// Checks if the size of the record is Size. Return true if valid. |
// Otherwise generates an error and returns false. |
- bool isValidRecordSize(unsigned Size, const char *RecordName) { |
+ bool isValidRecordSize(size_t Size, const char *RecordName) { |
const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
if (Values.size() == Size) |
return true; |
- ReportRecordSizeError(Size, RecordName, nullptr); |
+ reportRecordSizeError(Size, RecordName, nullptr); |
return false; |
} |
// Checks if the size of the record is at least as large as the |
// LowerLimit. Returns true if valid. Otherwise generates an error |
// and returns false. |
- bool isValidRecordSizeAtLeast(unsigned LowerLimit, const char *RecordName) { |
+ bool isValidRecordSizeAtLeast(size_t LowerLimit, const char *RecordName) { |
const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
if (Values.size() >= LowerLimit) |
return true; |
- ReportRecordSizeError(LowerLimit, RecordName, "at least"); |
+ reportRecordSizeError(LowerLimit, RecordName, "at least"); |
return false; |
} |
// Checks if the size of the record is no larger than the |
// UpperLimit. Returns true if valid. Otherwise generates an error |
// and returns false. |
- bool isValidRecordSizeAtMost(unsigned UpperLimit, const char *RecordName) { |
+ bool isValidRecordSizeAtMost(size_t UpperLimit, const char *RecordName) { |
const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
if (Values.size() <= UpperLimit) |
return true; |
- ReportRecordSizeError(UpperLimit, RecordName, "no more than"); |
+ reportRecordSizeError(UpperLimit, RecordName, "no more than"); |
return false; |
} |
// Checks if the size of the record is at least as large as the |
// LowerLimit, and no larger than the UpperLimit. Returns true if |
// valid. Otherwise generates an error and returns false. |
- bool isValidRecordSizeInRange(unsigned LowerLimit, unsigned UpperLimit, |
+ bool isValidRecordSizeInRange(size_t LowerLimit, size_t UpperLimit, |
const char *RecordName) { |
return isValidRecordSizeAtLeast(LowerLimit, RecordName) || |
isValidRecordSizeAtMost(UpperLimit, RecordName); |
@@ -647,11 +663,11 @@ private: |
/// record that has incorrect size. ContextMessage (if not nullptr) |
/// is appended to "record expects" to describe how ExpectedSize |
/// should be interpreted. |
- void ReportRecordSizeError(unsigned ExpectedSize, const char *RecordName, |
+ void reportRecordSizeError(size_t ExpectedSize, const char *RecordName, |
const char *ContextMessage); |
}; |
-bool TopLevelParser::BlockError(const std::string &Message) { |
+bool TopLevelParser::blockError(const std::string &Message) { |
if (BlockParser) |
return BlockParser->Error(Message); |
else |
@@ -678,7 +694,7 @@ bool BlockParserBaseClass::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, |
return Context->ErrorAt(Level, Bit, StrBuf.str()); |
} |
-void BlockParserBaseClass::ReportRecordSizeError(unsigned ExpectedSize, |
+void BlockParserBaseClass::reportRecordSizeError(size_t ExpectedSize, |
const char *RecordName, |
const char *ContextMessage) { |
std::string Buffer; |
@@ -728,13 +744,24 @@ public: |
: BlockParserBaseClass(BlockID, EnclosingParser), |
Timer(Ice::TimerStack::TT_parseTypes, getTranslator().getContext()) {} |
- ~TypesParser() override = default; |
+ ~TypesParser() override { |
+ if (ExpectedNumTypes != Context->getNumTypeIDValues()) { |
+ std::string Buffer; |
+ raw_string_ostream StrBuf(Buffer); |
+ StrBuf << "Types block expected " << ExpectedNumTypes |
+ << " types but found: " << NextTypeId; |
+ Error(StrBuf.str()); |
+ } |
+ } |
private: |
Ice::TimerMarker Timer; |
// The type ID that will be associated with the next type defining |
// record in the types block. |
- unsigned NextTypeId = 0; |
+ NaClBcIndexSize_t NextTypeId = 0; |
+ |
+ // The expected number of types, based on record TYPE_CODE_NUMENTRY. |
+ NaClBcIndexSize_t ExpectedNumTypes = 0; |
void ProcessRecord() override; |
@@ -748,12 +775,30 @@ private: |
void TypesParser::ProcessRecord() { |
const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
switch (Record.GetCode()) { |
- case naclbitc::TYPE_CODE_NUMENTRY: |
+ case naclbitc::TYPE_CODE_NUMENTRY: { |
// NUMENTRY: [numentries] |
if (!isValidRecordSize(1, "count")) |
return; |
- Context->resizeTypeIDValues(Values[0]); |
+ uint64_t Size = Values[0]; |
+ if (Size > NaClBcIndexSize_t_Max) { |
+ std::string Buffer; |
+ raw_string_ostream StrBuf(Buffer); |
+ StrBuf << "Size to big for count record: " << Size; |
+ Error(StrBuf.str()); |
+ ExpectedNumTypes = NaClBcIndexSize_t_Max; |
+ } |
+ // The code double checks that Expected size and the actual size |
+ // at the end of the block. To reduce allocations we preallocate |
+ // the space. |
+ // |
+ // However, if the number is large, we suspect that the number |
+ // is (possibly) incorrect. In that case, we preallocate a |
+ // smaller space. |
+ constexpr uint64_t DefaultLargeResizeValue = 1000000; |
+ Context->resizeTypeIDValues(std::min(Size, DefaultLargeResizeValue)); |
+ ExpectedNumTypes = Size; |
return; |
+ } |
case naclbitc::TYPE_CODE_VOID: |
// VOID |
if (!isValidRecordSize(0, "void")) |
@@ -870,7 +915,7 @@ void TypesParser::ProcessRecord() { |
Ty->setAsFunctionType(); |
FuncSigExtendedType *FuncTy = cast<FuncSigExtendedType>(Ty); |
FuncTy->setReturnType(Context->getSimpleTypeByID(Values[1])); |
- for (unsigned i = 2, e = Values.size(); i != e; ++i) { |
+ for (size_t i = 2, e = Values.size(); i != e; ++i) { |
// Check that type void not used as argument type. |
// Note: PNaCl restrictions can't be checked until we |
// know the name, because we have to check for intrinsic signatures. |
@@ -917,10 +962,10 @@ private: |
Ice::TimerMarker Timer; |
// Keeps track of how many initializers are expected for the global variable |
// declaration being built. |
- unsigned InitializersNeeded = 0; |
+ NaClBcIndexSize_t InitializersNeeded = 0; |
// The index of the next global variable declaration. |
- unsigned NextGlobalID = 0; |
+ NaClBcIndexSize_t NextGlobalID = 0; |
// Dummy global variable declaration to guarantee CurGlobalVar is |
// always defined (allowing code to not need to check if |
@@ -976,7 +1021,7 @@ void GlobalsParser::ProcessRecord() { |
Error("Globals count record not first in block."); |
return; |
} |
- Context->CreateGlobalVariables(Values[0]); |
+ Context->createGlobalVariables(Values[0]); |
return; |
case naclbitc::GLOBALVAR_VAR: { |
// VAR: [align, isconst] |
@@ -1039,9 +1084,16 @@ void GlobalsParser::ProcessRecord() { |
if (isIRGenerationDisabled()) |
return; |
unsigned Index = Values[0]; |
- Ice::SizeT Offset = 0; |
- if (Values.size() == 2) |
+ uint64_t Offset = 0; |
+ if (Values.size() == 2) { |
Offset = Values[1]; |
+ if (Offset > std::numeric_limits<uint32_t>::max()) { |
+ std::string Buffer; |
+ raw_string_ostream StrBuf(Buffer); |
+ StrBuf << "Addend of global reloc record too big: " << Offset; |
+ Error(StrBuf.str()); |
+ } |
+ } |
CurGlobalVar->addInitializer( |
Ice::VariableDeclaration::RelocInitializer::create( |
Context->getGlobalDeclarationByID(Index), Offset)); |
@@ -1071,15 +1123,15 @@ protected: |
typedef SmallString<128> StringType; |
// Associates Name with the value defined by the given Index. |
- virtual void setValueName(uint64_t Index, StringType &Name) = 0; |
+ virtual void setValueName(NaClBcIndexSize_t Index, StringType &Name) = 0; |
// Associates Name with the value defined by the given Index; |
- virtual void setBbName(uint64_t Index, StringType &Name) = 0; |
+ virtual void setBbName(NaClBcIndexSize_t Index, StringType &Name) = 0; |
private: |
void ProcessRecord() override; |
- void ConvertToString(StringType &ConvertedName) { |
+ void convertToString(StringType &ConvertedName) { |
const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
for (size_t i = 1, e = Values.size(); i != e; ++i) { |
ConvertedName += static_cast<char>(Values[i]); |
@@ -1095,7 +1147,7 @@ void ValuesymtabParser::ProcessRecord() { |
// VST_ENTRY: [ValueId, namechar x N] |
if (!isValidRecordSizeAtLeast(2, "value entry")) |
return; |
- ConvertToString(ConvertedName); |
+ convertToString(ConvertedName); |
setValueName(Values[0], ConvertedName); |
return; |
} |
@@ -1103,7 +1155,7 @@ void ValuesymtabParser::ProcessRecord() { |
// VST_BBENTRY: [BbId, namechar x N] |
if (!isValidRecordSizeAtLeast(2, "basic block entry")) |
return; |
- ConvertToString(ConvertedName); |
+ convertToString(ConvertedName); |
setBbName(Values[0], ConvertedName); |
return; |
} |
@@ -1158,7 +1210,7 @@ public: |
Func->setFunctionName(FuncDecl->getName()); |
Func->setReturnType(Signature.getReturnType()); |
Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); |
- CurrentNode = InstallNextBasicBlock(); |
+ CurrentNode = installNextBasicBlock(); |
Func->setEntryNode(CurrentNode); |
for (Ice::Type ArgType : Signature.getArgList()) { |
Func->addArg(getNextInstVar(ArgType)); |
@@ -1193,7 +1245,7 @@ public: |
Ice::Cfg *getFunc() const { return Func.get(); } |
- uint32_t getNumGlobalIDs() const { return CachedNumGlobalValueIDs; } |
+ size_t getNumGlobalIDs() const { return CachedNumGlobalValueIDs; } |
void setNextLocalInstIndex(Ice::Operand *Op) { |
setOperand(NextLocalInstIndex++, Op); |
@@ -1203,11 +1255,11 @@ public: |
void setNextConstantID(Ice::Constant *C) { setNextLocalInstIndex(C); } |
// Returns the value referenced by the given value Index. |
- Ice::Operand *getOperand(uint32_t Index) { |
+ Ice::Operand *getOperand(NaClBcIndexSize_t Index) { |
if (Index < CachedNumGlobalValueIDs) { |
return Context->getGlobalConstantByID(Index); |
} |
- uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; |
+ NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs; |
if (LocalIndex >= LocalOperands.size()) { |
std::string Buffer; |
raw_string_ostream StrBuf(Buffer); |
@@ -1231,21 +1283,21 @@ private: |
// The corresponding ICE function defined by the function block. |
std::unique_ptr<Ice::Cfg> Func; |
// The index to the current basic block being built. |
- uint32_t CurrentBbIndex = 0; |
+ NaClBcIndexSize_t CurrentBbIndex = 0; |
// The basic block being built. |
Ice::CfgNode *CurrentNode = nullptr; |
// The ID for the function. |
- unsigned FcnId; |
+ NaClBcIndexSize_t FcnId; |
// The corresponding function declaration. |
Ice::FunctionDeclaration *FuncDecl; |
// Holds the dividing point between local and global absolute value indices. |
- uint32_t CachedNumGlobalValueIDs; |
+ size_t CachedNumGlobalValueIDs; |
// Holds operands local to the function block, based on indices |
// defined in the bitcode file. |
std::vector<Ice::Operand *> LocalOperands; |
// Holds the index within LocalOperands corresponding to the next |
// instruction that generates a value. |
- uint32_t NextLocalInstIndex; |
+ NaClBcIndexSize_t NextLocalInstIndex; |
// True if the last processed instruction was a terminating |
// instruction. |
bool InstIsTerminating = false; |
@@ -1277,13 +1329,13 @@ private: |
void ExitBlock() override; |
// Creates and appends a new basic block to the list of basic blocks. |
- Ice::CfgNode *InstallNextBasicBlock() { |
+ Ice::CfgNode *installNextBasicBlock() { |
assert(!isIRGenerationDisabled()); |
return Func->makeNode(); |
} |
// Returns the Index-th basic block in the list of basic blocks. |
- Ice::CfgNode *getBasicBlock(uint32_t Index) { |
+ Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) { |
assert(!isIRGenerationDisabled()); |
const Ice::NodeList &Nodes = Func->getNodes(); |
if (Index >= Nodes.size()) { |
@@ -1302,7 +1354,7 @@ private: |
// Assumes Index corresponds to a branch instruction. Hence, if |
// the branch references the entry block, it also generates a |
// corresponding error. |
- Ice::CfgNode *getBranchBasicBlock(uint32_t Index) { |
+ Ice::CfgNode *getBranchBasicBlock(NaClBcIndexSize_t Index) { |
assert(!isIRGenerationDisabled()); |
if (Index == 0) { |
Error("Branch to entry block not allowed"); |
@@ -1327,7 +1379,7 @@ private: |
assert(!isIRGenerationDisabled()); |
assert(NextLocalInstIndex >= CachedNumGlobalValueIDs); |
// Before creating one, see if a forwardtyperef has already defined it. |
- uint32_t LocalIndex = NextLocalInstIndex - CachedNumGlobalValueIDs; |
+ NaClBcIndexSize_t LocalIndex = NextLocalInstIndex - CachedNumGlobalValueIDs; |
if (LocalIndex < LocalOperands.size()) { |
Ice::Operand *Op = LocalOperands[LocalIndex]; |
if (Op != nullptr) { |
@@ -1354,7 +1406,8 @@ private: |
// Converts a relative index (wrt to BaseIndex) to an absolute value |
// index. |
- uint32_t convertRelativeToAbsIndex(int32_t Id, int32_t BaseIndex) { |
+ NaClBcIndexSize_t convertRelativeToAbsIndex(NaClRelBcIndexSize_t Id, |
+ NaClRelBcIndexSize_t BaseIndex) { |
if (BaseIndex < Id) { |
std::string Buffer; |
raw_string_ostream StrBuf(Buffer); |
@@ -1368,10 +1421,10 @@ private: |
} |
// Sets element Index (in the local operands list) to Op. |
- void setOperand(uint32_t Index, Ice::Operand *Op) { |
+ void setOperand(NaClBcIndexSize_t Index, Ice::Operand *Op) { |
assert(Op || isIRGenerationDisabled()); |
// Check if simple push works. |
- uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; |
+ NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs; |
if (LocalIndex == LocalOperands.size()) { |
LocalOperands.push_back(Op); |
return; |
@@ -1404,16 +1457,17 @@ private: |
// Returns the relative operand (wrt to BaseIndex) referenced by |
// the given value Index. |
- Ice::Operand *getRelativeOperand(int32_t Index, int32_t BaseIndex) { |
+ Ice::Operand *getRelativeOperand(NaClBcIndexSize_t Index, |
+ NaClBcIndexSize_t BaseIndex) { |
return getOperand(convertRelativeToAbsIndex(Index, BaseIndex)); |
} |
// Returns the absolute index of the next value generating instruction. |
- uint32_t getNextInstIndex() const { return NextLocalInstIndex; } |
+ NaClBcIndexSize_t getNextInstIndex() const { return NextLocalInstIndex; } |
// Generates type error message for binary operator Op |
// operating on Type OpTy. |
- void ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy); |
+ void reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy); |
// Validates if integer logical Op, for type OpTy, is valid. |
// Returns true if valid. Otherwise generates error message and |
@@ -1421,7 +1475,7 @@ private: |
bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { |
if (Ice::isIntegerType(OpTy)) |
return true; |
- ReportInvalidBinaryOp(Op, OpTy); |
+ reportInvalidBinaryOp(Op, OpTy); |
return false; |
} |
@@ -1431,7 +1485,7 @@ private: |
bool isValidIntegerArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { |
if (Ice::isIntegerArithmeticType(OpTy)) |
return true; |
- ReportInvalidBinaryOp(Op, OpTy); |
+ reportInvalidBinaryOp(Op, OpTy); |
return false; |
} |
@@ -1441,7 +1495,7 @@ private: |
bool isValidFloatingArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { |
if (Ice::isFloatingType(OpTy)) |
return true; |
- ReportInvalidBinaryOp(Op, OpTy); |
+ reportInvalidBinaryOp(Op, OpTy); |
return false; |
} |
@@ -1908,7 +1962,7 @@ void FunctionParser::ExitBlock() { |
} |
// Before translating, check for blocks without instructions, and |
// insert unreachable. This shouldn't happen, but be safe. |
- unsigned Index = 0; |
+ size_t Index = 0; |
for (Ice::CfgNode *Node : Func->getNodes()) { |
if (Node->getInsts().empty()) { |
std::string Buffer; |
@@ -1923,7 +1977,7 @@ void FunctionParser::ExitBlock() { |
Func->computeInOutEdges(); |
} |
-void FunctionParser::ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, |
+void FunctionParser::reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, |
Ice::Type OpTy) { |
std::string Buffer; |
raw_string_ostream StrBuf(Buffer); |
@@ -1944,17 +1998,23 @@ void FunctionParser::ProcessRecord() { |
CurrentNode = getBasicBlock(++CurrentBbIndex); |
} |
// The base index for relative indexing. |
- int32_t BaseIndex = getNextInstIndex(); |
+ NaClBcIndexSize_t BaseIndex = getNextInstIndex(); |
switch (Record.GetCode()) { |
case naclbitc::FUNC_CODE_DECLAREBLOCKS: { |
// DECLAREBLOCKS: [n] |
if (!isValidRecordSize(1, "count")) |
return; |
- uint32_t NumBbs = Values[0]; |
- if (NumBbs == 0) { |
+ uint64_t NumBbsRaw = Values[0]; |
+ if (NumBbsRaw == 0) { |
Error("Functions must contain at least one basic block."); |
// TODO(kschimpf) Remove error recovery once implementation complete. |
- NumBbs = 1; |
+ NumBbsRaw = 1; |
+ } else if (NumBbsRaw > NaClBcIndexSize_t_Max) { |
+ std::string Buffer; |
+ raw_string_ostream StrBuf(Buffer); |
+ StrBuf << "To many basic blocks specified: " << NumBbsRaw; |
+ Error(StrBuf.str()); |
+ NumBbsRaw = NaClBcIndexSize_t_Max; |
} |
if (isIRGenerationDisabled()) |
return; |
@@ -1964,8 +2024,8 @@ void FunctionParser::ProcessRecord() { |
} |
// Install the basic blocks, skipping bb0 which was created in the |
// constructor. |
- for (size_t i = 1; i < NumBbs; ++i) |
- InstallNextBasicBlock(); |
+ for (size_t i = 1, NumBbs = NumBbsRaw; i < NumBbs; ++i) |
+ installNextBasicBlock(); |
return; |
} |
case naclbitc::FUNC_CODE_INST_BINOP: { |
@@ -2281,7 +2341,15 @@ void FunctionParser::ProcessRecord() { |
} |
Ice::CfgNode *DefaultLabel = |
isIRGenDisabled ? nullptr : getBranchBasicBlock(Values[2]); |
- unsigned NumCases = Values[3]; |
+ uint64_t NumCasesRaw = Values[3]; |
+ if (NumCasesRaw > std::numeric_limits<uint32_t>::max()) { |
+ std::string Buffer; |
+ raw_string_ostream StrBuf(Buffer); |
+ StrBuf << "Too many cases specified in switch: " << NumCasesRaw; |
+ Error(StrBuf.str()); |
+ NumCasesRaw = std::numeric_limits<uint32_t>::max(); |
+ } |
+ uint32_t NumCases = NumCasesRaw; |
// Now recognize each of the cases. |
if (!isValidRecordSize(4 + NumCases * 4, "switch")) |
@@ -2291,7 +2359,7 @@ void FunctionParser::ProcessRecord() { |
? nullptr |
: Ice::InstSwitch::create(Func.get(), NumCases, Cond, DefaultLabel); |
unsigned ValCaseIndex = 4; // index to beginning of case entry. |
- for (unsigned CaseIndex = 0; CaseIndex < NumCases; |
+ for (uint32_t CaseIndex = 0; CaseIndex < NumCases; |
++CaseIndex, ValCaseIndex += 4) { |
if (Values[ValCaseIndex] != 1 || Values[ValCaseIndex + 1] != 1) { |
std::string Buffer; |
@@ -2354,7 +2422,7 @@ void FunctionParser::ProcessRecord() { |
Ice::Variable *Dest = getNextInstVar(Ty); |
Ice::InstPhi *Phi = |
Ice::InstPhi::create(Func.get(), Values.size() >> 1, Dest); |
- for (unsigned i = 1; i < Values.size(); i += 2) { |
+ for (size_t i = 1; i < Values.size(); i += 2) { |
Ice::Operand *Op = |
getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex); |
if (Op->getType() != Ty) { |
@@ -2742,12 +2810,12 @@ private: |
return reinterpret_cast<FunctionParser *>(GetEnclosingParser()); |
} |
- void setValueName(uint64_t Index, StringType &Name) override; |
- void setBbName(uint64_t Index, StringType &Name) override; |
+ void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; |
+ void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; |
// Reports that the assignment of Name to the value associated with |
// index is not possible, for the given Context. |
- void reportUnableToAssign(const char *Context, uint64_t Index, |
+ void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index, |
StringType &Name) { |
std::string Buffer; |
raw_string_ostream StrBuf(Buffer); |
@@ -2757,7 +2825,8 @@ private: |
} |
}; |
-void FunctionValuesymtabParser::setValueName(uint64_t Index, StringType &Name) { |
+void FunctionValuesymtabParser::setValueName(NaClBcIndexSize_t Index, |
+ StringType &Name) { |
// Note: We check when Index is too small, so that we can error recover |
// (FP->getOperand will create fatal error). |
if (Index < getFunctionParser()->getNumGlobalIDs()) { |
@@ -2778,7 +2847,8 @@ void FunctionValuesymtabParser::setValueName(uint64_t Index, StringType &Name) { |
} |
} |
-void FunctionValuesymtabParser::setBbName(uint64_t Index, StringType &Name) { |
+void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index, |
+ StringType &Name) { |
if (isIRGenerationDisabled()) |
return; |
if (Index >= getFunctionParser()->getFunc()->getNumNodes()) { |
@@ -2835,7 +2905,7 @@ private: |
// global variables). Then lowers global variable declaration |
// initializers to the target. May be called multiple times. Only |
// the first call will do the installation. |
- void InstallGlobalNamesAndGlobalVarInitializers() { |
+ void installGlobalNamesAndGlobalVarInitializers() { |
if (!GlobalDeclarationNamesAndInitializersInstalled) { |
Context->installGlobalNames(); |
Context->createValueIDs(); |
@@ -2845,7 +2915,7 @@ private: |
} |
bool ParseBlock(unsigned BlockID) override; |
- void ExitBlock() override { InstallGlobalNamesAndGlobalVarInitializers(); } |
+ void ExitBlock() override { installGlobalNamesAndGlobalVarInitializers(); } |
void ProcessRecord() override; |
}; |
@@ -2865,16 +2935,18 @@ public: |
private: |
Ice::TimerMarker Timer; |
- void setValueName(uint64_t Index, StringType &Name) override; |
- void setBbName(uint64_t Index, StringType &Name) override; |
+ void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; |
+ void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; |
}; |
-void ModuleValuesymtabParser::setValueName(uint64_t Index, StringType &Name) { |
+void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index, |
+ StringType &Name) { |
Context->getGlobalDeclarationByID(Index) |
->setName(StringRef(Name.data(), Name.size())); |
} |
-void ModuleValuesymtabParser::setBbName(uint64_t Index, StringType &Name) { |
+void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index, |
+ StringType &Name) { |
std::string Buffer; |
raw_string_ostream StrBuf(Buffer); |
StrBuf << "Can't define basic block name at global level: '" << Name |
@@ -2899,7 +2971,7 @@ bool ModuleParser::ParseBlock(unsigned BlockID) { |
return Parser.ParseThisBlock(); |
} |
case naclbitc::FUNCTION_BLOCK_ID: { |
- InstallGlobalNamesAndGlobalVarInitializers(); |
+ installGlobalNamesAndGlobalVarInitializers(); |
FunctionParser Parser(BlockID, this); |
return Parser.convertFunction(); |
} |
@@ -2915,7 +2987,7 @@ void ModuleParser::ProcessRecord() { |
// VERSION: [version#] |
if (!isValidRecordSize(1, "version")) |
return; |
- unsigned Version = Values[0]; |
+ uint64_t Version = Values[0]; |
if (Version != 1) { |
std::string Buffer; |
raw_string_ostream StrBuf(Buffer); |