Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(214)

Side by Side Diff: src/PNaClTranslator.cpp

Issue 1278793006: Fix processing of global variable indices in the global vars block. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===// 1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 /// Returns the number of global declarations (i.e. IDs) defined in 299 /// Returns the number of global declarations (i.e. IDs) defined in
300 /// the bitcode file. 300 /// the bitcode file.
301 size_t getNumGlobalIDs() const { 301 size_t getNumGlobalIDs() const {
302 if (VariableDeclarations) { 302 if (VariableDeclarations) {
303 return FunctionDeclarationList.size() + VariableDeclarations->size(); 303 return FunctionDeclarationList.size() + VariableDeclarations->size();
304 } else { 304 } else {
305 return ValueIDConstants.size(); 305 return ValueIDConstants.size();
306 } 306 }
307 } 307 }
308 308
309 /// Creates Count global variable declarations. 309 /// Adds the given global declaration to the end of the list of global
310 void createGlobalVariables(NaClBcIndexSize_t Count) { 310 /// declarations.
311 void addGlobalDeclaration(Ice::VariableDeclaration *Decl) {
311 assert(VariableDeclarations); 312 assert(VariableDeclarations);
312 assert(VariableDeclarations->empty()); 313 VariableDeclarations->push_back(Decl);
313 for (size_t i = 0; i < Count; ++i) {
314 VariableDeclarations->push_back(
315 Ice::VariableDeclaration::create(getTranslator().getContext()));
316 }
317 }
318
319 /// Returns the number of global variable declarations in the
320 /// bitcode file.
321 size_t getNumGlobalVariables() const {
322 if (VariableDeclarations) {
323 return VariableDeclarations->size();
324 } else {
325 return ValueIDConstants.size() - FunctionDeclarationList.size();
326 }
327 } 314 }
328 315
329 /// Returns the global variable declaration with the given index. 316 /// Returns the global variable declaration with the given index.
330 Ice::VariableDeclaration *getGlobalVariableByID(NaClBcIndexSize_t Index) { 317 Ice::VariableDeclaration *getGlobalVariableByID(NaClBcIndexSize_t Index) {
331 assert(VariableDeclarations); 318 assert(VariableDeclarations);
332 if (Index < VariableDeclarations->size()) 319 if (Index < VariableDeclarations->size())
333 return VariableDeclarations->at(Index); 320 return VariableDeclarations->at(Index);
334 return reportGetGlobalVariableByIDError(Index); 321 return reportGetGlobalVariableByIDError(Index);
335 } 322 }
336 323
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after
948 /// corresponding initializers). 935 /// corresponding initializers).
949 class GlobalsParser : public BlockParserBaseClass { 936 class GlobalsParser : public BlockParserBaseClass {
950 GlobalsParser() = delete; 937 GlobalsParser() = delete;
951 GlobalsParser(const GlobalsParser &) = delete; 938 GlobalsParser(const GlobalsParser &) = delete;
952 GlobalsParser &operator=(const GlobalsParser &) = delete; 939 GlobalsParser &operator=(const GlobalsParser &) = delete;
953 940
954 public: 941 public:
955 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) 942 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
956 : BlockParserBaseClass(BlockID, EnclosingParser), 943 : BlockParserBaseClass(BlockID, EnclosingParser),
957 Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()), 944 Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()),
945 NumFunctionIDs(Context->getNumFunctionIDs()),
958 DummyGlobalVar( 946 DummyGlobalVar(
959 Ice::VariableDeclaration::create(getTranslator().getContext())), 947 Ice::VariableDeclaration::create(getTranslator().getContext())),
960 CurGlobalVar(DummyGlobalVar) {} 948 CurGlobalVar(DummyGlobalVar) {}
961 949
962 ~GlobalsParser() final = default; 950 ~GlobalsParser() final = default;
963 951
964 const char *getBlockName() const override { return "globals"; } 952 const char *getBlockName() const override { return "globals"; }
965 953
966 private: 954 private:
955 typedef std::unordered_map<NaClBcIndexSize_t, Ice::VariableDeclaration *>
956 GlobalVarsMapType;
957
967 Ice::TimerMarker Timer; 958 Ice::TimerMarker Timer;
959
960 // Holds global variables generated/referenced in the global variables block.
961 GlobalVarsMapType GlobalVarsMap;
962
963 // Holds the number of defined function IDs.
964 NaClBcIndexSize_t NumFunctionIDs;
965
966 // Holds the specified number of global variables by the count record in
967 // the global variables block.
968 NaClBcIndexSize_t SpecifiedNumberVars = 0;
969
968 // Keeps track of how many initializers are expected for the global variable 970 // Keeps track of how many initializers are expected for the global variable
969 // declaration being built. 971 // declaration being built.
970 NaClBcIndexSize_t InitializersNeeded = 0; 972 NaClBcIndexSize_t InitializersNeeded = 0;
971 973
972 // The index of the next global variable declaration. 974 // The index of the next global variable declaration.
973 NaClBcIndexSize_t NextGlobalID = 0; 975 NaClBcIndexSize_t NextGlobalID = 0;
974 976
975 // Dummy global variable declaration to guarantee CurGlobalVar is 977 // Dummy global variable declaration to guarantee CurGlobalVar is
976 // always defined (allowing code to not need to check if 978 // always defined (allowing code to not need to check if
977 // CurGlobalVar is nullptr). 979 // CurGlobalVar is nullptr).
978 Ice::VariableDeclaration *DummyGlobalVar; 980 Ice::VariableDeclaration *DummyGlobalVar;
979 981
980 // Holds the current global variable declaration being built. 982 // Holds the current global variable declaration being built.
981 Ice::VariableDeclaration *CurGlobalVar; 983 Ice::VariableDeclaration *CurGlobalVar;
982 984
985 // Returns the global variable associated with the given Index.
986 Ice::VariableDeclaration *getGlobalVarByID(NaClBcIndexSize_t Index) {
987 Ice::VariableDeclaration *&Decl = GlobalVarsMap[Index];
988 if (Decl == nullptr)
989 Decl = Ice::VariableDeclaration::create(getTranslator().getContext());
990 return Decl;
991 }
992
993 // Returns the global declaration associated with the given index.
994 Ice::GlobalDeclaration *getGlobalDeclByID(NaClBcIndexSize_t Index) {
995 if (Index < NumFunctionIDs)
996 return Context->getFunctionByID(Index);
997 return getGlobalVarByID(Index - NumFunctionIDs);
998 }
999
1000 // If global variables parsed correctly, install them into the top-level
1001 // context.
1002 void installGlobalVariables() {
1003 // Verify specified number of globals matches number found.
1004 size_t NumGlobals = GlobalVarsMap.size();
1005 if (SpecifiedNumberVars != NumGlobals ||
1006 SpecifiedNumberVars != NextGlobalID) {
1007 std::string Buffer;
1008 raw_string_ostream StrBuf(Buffer);
1009 StrBuf << getBlockName() << " block expects " << SpecifiedNumberVars
1010 << " global variables. Found: " << GlobalVarsMap.size();
1011 Error(StrBuf.str());
1012 return;
1013 }
1014 // Install global variables into top-level context.
1015 for (size_t I = 0; I < NumGlobals; ++I)
1016 Context->addGlobalDeclaration(GlobalVarsMap[I]);
1017 }
1018
983 void ExitBlock() override { 1019 void ExitBlock() override {
984 verifyNoMissingInitializers(); 1020 verifyNoMissingInitializers();
985 unsigned NumIDs = Context->getNumGlobalVariables(); 1021 installGlobalVariables();
986 if (NextGlobalID < NumIDs) {
987 std::string Buffer;
988 raw_string_ostream StrBuf(Buffer);
989 StrBuf << getBlockName() << " block expects " << NumIDs
990 << " global variable declarations. Found: " << NextGlobalID;
991 Error(StrBuf.str());
992 }
993 BlockParserBaseClass::ExitBlock(); 1022 BlockParserBaseClass::ExitBlock();
994 } 1023 }
995 1024
996 void ProcessRecord() override; 1025 void ProcessRecord() override;
997 1026
998 // Checks if the number of initializers for the CurGlobalVar is the same as 1027 // Checks if the number of initializers for the CurGlobalVar is the same as
999 // the number found in the bitcode file. If different, and error message is 1028 // the number found in the bitcode file. If different, and error message is
1000 // generated, and the internal state of the parser is fixed so this condition 1029 // generated, and the internal state of the parser is fixed so this condition
1001 // is no longer violated. 1030 // is no longer violated.
1002 void verifyNoMissingInitializers() { 1031 void verifyNoMissingInitializers() {
(...skipping 12 matching lines...) Expand all
1015 } 1044 }
1016 }; 1045 };
1017 1046
1018 void GlobalsParser::ProcessRecord() { 1047 void GlobalsParser::ProcessRecord() {
1019 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 1048 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1020 switch (Record.GetCode()) { 1049 switch (Record.GetCode()) {
1021 case naclbitc::GLOBALVAR_COUNT: 1050 case naclbitc::GLOBALVAR_COUNT:
1022 // COUNT: [n] 1051 // COUNT: [n]
1023 if (!isValidRecordSize(1, "count")) 1052 if (!isValidRecordSize(1, "count"))
1024 return; 1053 return;
1025 if (NextGlobalID != Context->getNumGlobalVariables()) { 1054 if (SpecifiedNumberVars || NextGlobalID) {
1026 Error("Globals count record not first in block."); 1055 Error("Globals count record not first in block.");
1027 return; 1056 return;
1028 } 1057 }
1029 Context->createGlobalVariables(Values[0]); 1058 SpecifiedNumberVars = Values[0];
1030 return; 1059 return;
1031 case naclbitc::GLOBALVAR_VAR: { 1060 case naclbitc::GLOBALVAR_VAR: {
1032 // VAR: [align, isconst] 1061 // VAR: [align, isconst]
1033 if (!isValidRecordSize(2, "variable")) 1062 if (!isValidRecordSize(2, "variable"))
1034 return; 1063 return;
1035 verifyNoMissingInitializers(); 1064 verifyNoMissingInitializers();
1065 // Always build the global variable, even if IR generation is turned off.
1066 // This is needed because we need a placeholder in the top-level context
1067 // when no IR is generated.
1068 CurGlobalVar = getGlobalVarByID(NextGlobalID);
1036 if (!isIRGenerationDisabled()) { 1069 if (!isIRGenerationDisabled()) {
1037 InitializersNeeded = 1; 1070 InitializersNeeded = 1;
1038 CurGlobalVar = Context->getGlobalVariableByID(NextGlobalID);
1039 CurGlobalVar->setAlignment((1 << Values[0]) >> 1); 1071 CurGlobalVar->setAlignment((1 << Values[0]) >> 1);
1040 CurGlobalVar->setIsConstant(Values[1] != 0); 1072 CurGlobalVar->setIsConstant(Values[1] != 0);
1041 } 1073 }
1042 ++NextGlobalID; 1074 ++NextGlobalID;
1043 return; 1075 return;
1044 } 1076 }
1045 case naclbitc::GLOBALVAR_COMPOUND: 1077 case naclbitc::GLOBALVAR_COMPOUND:
1046 // COMPOUND: [size] 1078 // COMPOUND: [size]
1047 if (!isValidRecordSize(1, "compound")) 1079 if (!isValidRecordSize(1, "compound"))
1048 return; 1080 return;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 CurGlobalVar->addInitializer( 1113 CurGlobalVar->addInitializer(
1082 Ice::VariableDeclaration::DataInitializer::create(Values)); 1114 Ice::VariableDeclaration::DataInitializer::create(Values));
1083 return; 1115 return;
1084 } 1116 }
1085 case naclbitc::GLOBALVAR_RELOC: { 1117 case naclbitc::GLOBALVAR_RELOC: {
1086 // RELOC: [val, [addend]] 1118 // RELOC: [val, [addend]]
1087 if (!isValidRecordSizeInRange(1, 2, "reloc")) 1119 if (!isValidRecordSizeInRange(1, 2, "reloc"))
1088 return; 1120 return;
1089 if (isIRGenerationDisabled()) 1121 if (isIRGenerationDisabled())
1090 return; 1122 return;
1091 unsigned Index = Values[0]; 1123 NaClBcIndexSize_t Index = Values[0];
1124 NaClBcIndexSize_t IndexLimit = SpecifiedNumberVars + NumFunctionIDs;
1125 if (Index >= IndexLimit) {
1126 std::string Buffer;
1127 raw_string_ostream StrBuf(Buffer);
1128 StrBuf << "Relocation index " << Index << " to big. Expect index < "
1129 << IndexLimit;
1130 Error(StrBuf.str());
1131 }
1092 uint64_t Offset = 0; 1132 uint64_t Offset = 0;
1093 if (Values.size() == 2) { 1133 if (Values.size() == 2) {
1094 Offset = Values[1]; 1134 Offset = Values[1];
1095 if (Offset > std::numeric_limits<uint32_t>::max()) { 1135 if (Offset > std::numeric_limits<uint32_t>::max()) {
1096 std::string Buffer; 1136 std::string Buffer;
1097 raw_string_ostream StrBuf(Buffer); 1137 raw_string_ostream StrBuf(Buffer);
1098 StrBuf << "Addend of global reloc record too big: " << Offset; 1138 StrBuf << "Addend of global reloc record too big: " << Offset;
1099 Error(StrBuf.str()); 1139 Error(StrBuf.str());
1100 } 1140 }
1101 } 1141 }
1102 CurGlobalVar->addInitializer( 1142 CurGlobalVar->addInitializer(
1103 Ice::VariableDeclaration::RelocInitializer::create( 1143 Ice::VariableDeclaration::RelocInitializer::create(
1104 Context->getGlobalDeclarationByID(Index), Offset)); 1144 getGlobalDeclByID(Index), Offset));
1105 return; 1145 return;
1106 } 1146 }
1107 default: 1147 default:
1108 BlockParserBaseClass::ProcessRecord(); 1148 BlockParserBaseClass::ProcessRecord();
1109 return; 1149 return;
1110 } 1150 }
1111 } 1151 }
1112 1152
1113 /// Base class for parsing a valuesymtab block in the bitcode file. 1153 /// Base class for parsing a valuesymtab block in the bitcode file.
1114 class ValuesymtabParser : public BlockParserBaseClass { 1154 class ValuesymtabParser : public BlockParserBaseClass {
(...skipping 2025 matching lines...) Expand 10 before | Expand all | Expand 10 after
3140 } 3180 }
3141 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { 3181 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) {
3142 ErrStream 3182 ErrStream
3143 << IRFilename 3183 << IRFilename
3144 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; 3184 << ": Bitcode stream should be a multiple of 4 bytes in length.\n";
3145 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); 3185 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes");
3146 } 3186 }
3147 } 3187 }
3148 3188
3149 } // end of namespace Ice 3189 } // end of namespace Ice
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698