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

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 nit. 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 613 matching lines...) Expand 10 before | Expand all | Expand 10 after
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()),
958 DummyGlobalVar( 945 DummyGlobalVar(
959 Ice::VariableDeclaration::create(getTranslator().getContext())), 946 Ice::VariableDeclaration::create(getTranslator().getContext())),
960 CurGlobalVar(DummyGlobalVar) {} 947 CurGlobalVar(DummyGlobalVar) {
948 NumFunctionIDs = Context->getNumFunctionIDs();
Jim Stichnoth 2015/08/06 22:09:12 Can this be added to the member initializer list?
Karl 2015/08/07 16:29:22 I originally thought it had to wait. However, sinc
949 }
961 950
962 ~GlobalsParser() final = default; 951 ~GlobalsParser() final = default;
963 952
964 const char *getBlockName() const override { return "globals"; } 953 const char *getBlockName() const override { return "globals"; }
965 954
966 private: 955 private:
956 typedef std::unordered_map<NaClBcIndexSize_t, Ice::VariableDeclaration *>
957 GlobalVarsMapType;
958
967 Ice::TimerMarker Timer; 959 Ice::TimerMarker Timer;
960
961 // Holds global variables generated/referenced in the global variables block.
962 GlobalVarsMapType GlobalVarsMap;
963
964 // Holds the number of defined function IDs.
965 NaClBcIndexSize_t NumFunctionIDs;
966
967 // Holds the specified number of global variables by the count record in
968 // the global variables block.
969 NaClBcIndexSize_t SpecifiedNumberVars = 0;
970
968 // Keeps track of how many initializers are expected for the global variable 971 // Keeps track of how many initializers are expected for the global variable
969 // declaration being built. 972 // declaration being built.
970 NaClBcIndexSize_t InitializersNeeded = 0; 973 NaClBcIndexSize_t InitializersNeeded = 0;
971 974
972 // The index of the next global variable declaration. 975 // The index of the next global variable declaration.
973 NaClBcIndexSize_t NextGlobalID = 0; 976 NaClBcIndexSize_t NextGlobalID = 0;
974 977
975 // Dummy global variable declaration to guarantee CurGlobalVar is 978 // Dummy global variable declaration to guarantee CurGlobalVar is
976 // always defined (allowing code to not need to check if 979 // always defined (allowing code to not need to check if
977 // CurGlobalVar is nullptr). 980 // CurGlobalVar is nullptr).
978 Ice::VariableDeclaration *DummyGlobalVar; 981 Ice::VariableDeclaration *DummyGlobalVar;
979 982
980 // Holds the current global variable declaration being built. 983 // Holds the current global variable declaration being built.
981 Ice::VariableDeclaration *CurGlobalVar; 984 Ice::VariableDeclaration *CurGlobalVar;
982 985
986 // Returns the global variable associated with the given Index.
987 Ice::VariableDeclaration *getGlobalVarByID(NaClBcIndexSize_t Index) {
988 Ice::VariableDeclaration *&Decl = GlobalVarsMap[Index];
989 if (Decl == nullptr)
990 Decl = Ice::VariableDeclaration::create(getTranslator().getContext());
991 return Decl;
992 }
993
994 // Returns the global declaratoin associated with the given index.
Jim Stichnoth 2015/08/06 22:09:12 declaration
Karl 2015/08/07 16:29:22 Done.
995 Ice::GlobalDeclaration *getGlobalDeclByID(NaClBcIndexSize_t Index) {
996 if (Index < NumFunctionIDs)
997 return Context->getFunctionByID(Index);
998 return getGlobalVarByID(Index - NumFunctionIDs);
999 }
1000
1001 // If global variables parsed correctly, install them into the top-level
1002 // context.
1003 void installGlobalVariables() {
1004 // Verify specified number of globals matches number found.
1005 size_t NumGlobals = GlobalVarsMap.size();
1006 if (SpecifiedNumberVars != NumGlobals ||
1007 SpecifiedNumberVars != NextGlobalID) {
1008 std::string Buffer;
1009 raw_string_ostream StrBuf(Buffer);
1010 StrBuf << getBlockName() << " block expects " << SpecifiedNumberVars
1011 << " global variables. Found: " << GlobalVarsMap.size();
1012 Error(StrBuf.str());
1013 return;
1014 }
1015 // Install global variables into top-level context.
1016 for (size_t I = 0; I < NumGlobals; ++I)
1017 Context->addGlobalDeclaration(GlobalVarsMap[I]);
1018 }
1019
983 void ExitBlock() override { 1020 void ExitBlock() override {
984 verifyNoMissingInitializers(); 1021 verifyNoMissingInitializers();
985 unsigned NumIDs = Context->getNumGlobalVariables(); 1022 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(); 1023 BlockParserBaseClass::ExitBlock();
994 } 1024 }
995 1025
996 void ProcessRecord() override; 1026 void ProcessRecord() override;
997 1027
998 // Checks if the number of initializers for the CurGlobalVar is the same as 1028 // 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 1029 // 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 1030 // generated, and the internal state of the parser is fixed so this condition
1001 // is no longer violated. 1031 // is no longer violated.
1002 void verifyNoMissingInitializers() { 1032 void verifyNoMissingInitializers() {
(...skipping 12 matching lines...) Expand all
1015 } 1045 }
1016 }; 1046 };
1017 1047
1018 void GlobalsParser::ProcessRecord() { 1048 void GlobalsParser::ProcessRecord() {
1019 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 1049 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1020 switch (Record.GetCode()) { 1050 switch (Record.GetCode()) {
1021 case naclbitc::GLOBALVAR_COUNT: 1051 case naclbitc::GLOBALVAR_COUNT:
1022 // COUNT: [n] 1052 // COUNT: [n]
1023 if (!isValidRecordSize(1, "count")) 1053 if (!isValidRecordSize(1, "count"))
1024 return; 1054 return;
1025 if (NextGlobalID != Context->getNumGlobalVariables()) { 1055 if (SpecifiedNumberVars || NextGlobalID) {
1026 Error("Globals count record not first in block."); 1056 Error("Globals count record not first in block.");
1027 return; 1057 return;
1028 } 1058 }
1029 Context->createGlobalVariables(Values[0]); 1059 SpecifiedNumberVars = Values[0];
1030 return; 1060 return;
1031 case naclbitc::GLOBALVAR_VAR: { 1061 case naclbitc::GLOBALVAR_VAR: {
1032 // VAR: [align, isconst] 1062 // VAR: [align, isconst]
1033 if (!isValidRecordSize(2, "variable")) 1063 if (!isValidRecordSize(2, "variable"))
1034 return; 1064 return;
1035 verifyNoMissingInitializers(); 1065 verifyNoMissingInitializers();
1066 // Always build the global variable, even if IR generation is turned off.
1067 // This is needed because we need a placeholder in the top-level context
1068 // when no IR is generated.
1069 CurGlobalVar = getGlobalVarByID(NextGlobalID);
1036 if (!isIRGenerationDisabled()) { 1070 if (!isIRGenerationDisabled()) {
1037 InitializersNeeded = 1; 1071 InitializersNeeded = 1;
1038 CurGlobalVar = Context->getGlobalVariableByID(NextGlobalID);
1039 CurGlobalVar->setAlignment((1 << Values[0]) >> 1); 1072 CurGlobalVar->setAlignment((1 << Values[0]) >> 1);
1040 CurGlobalVar->setIsConstant(Values[1] != 0); 1073 CurGlobalVar->setIsConstant(Values[1] != 0);
1041 } 1074 }
1042 ++NextGlobalID; 1075 ++NextGlobalID;
1043 return; 1076 return;
1044 } 1077 }
1045 case naclbitc::GLOBALVAR_COMPOUND: 1078 case naclbitc::GLOBALVAR_COMPOUND:
1046 // COMPOUND: [size] 1079 // COMPOUND: [size]
1047 if (!isValidRecordSize(1, "compound")) 1080 if (!isValidRecordSize(1, "compound"))
1048 return; 1081 return;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 CurGlobalVar->addInitializer( 1114 CurGlobalVar->addInitializer(
1082 Ice::VariableDeclaration::DataInitializer::create(Values)); 1115 Ice::VariableDeclaration::DataInitializer::create(Values));
1083 return; 1116 return;
1084 } 1117 }
1085 case naclbitc::GLOBALVAR_RELOC: { 1118 case naclbitc::GLOBALVAR_RELOC: {
1086 // RELOC: [val, [addend]] 1119 // RELOC: [val, [addend]]
1087 if (!isValidRecordSizeInRange(1, 2, "reloc")) 1120 if (!isValidRecordSizeInRange(1, 2, "reloc"))
1088 return; 1121 return;
1089 if (isIRGenerationDisabled()) 1122 if (isIRGenerationDisabled())
1090 return; 1123 return;
1091 unsigned Index = Values[0]; 1124 NaClBcIndexSize_t Index = Values[0];
Jim Stichnoth 2015/08/06 22:09:12 Nice. Any other "unsigned" types that you can cha
Karl 2015/08/07 16:29:22 Acknowledged.
1125 NaClBcIndexSize_t IndexLimit = SpecifiedNumberVars + NumFunctionIDs;
1126 if (Index >= IndexLimit) {
1127 std::string Buffer;
1128 raw_string_ostream StrBuf(Buffer);
1129 StrBuf << "Relocation index " << Index << " to big. Expect index < "
1130 << IndexLimit;
1131 Error(StrBuf.str());
1132 }
1092 uint64_t Offset = 0; 1133 uint64_t Offset = 0;
1093 if (Values.size() == 2) { 1134 if (Values.size() == 2) {
1094 Offset = Values[1]; 1135 Offset = Values[1];
1095 if (Offset > std::numeric_limits<uint32_t>::max()) { 1136 if (Offset > std::numeric_limits<uint32_t>::max()) {
1096 std::string Buffer; 1137 std::string Buffer;
1097 raw_string_ostream StrBuf(Buffer); 1138 raw_string_ostream StrBuf(Buffer);
1098 StrBuf << "Addend of global reloc record too big: " << Offset; 1139 StrBuf << "Addend of global reloc record too big: " << Offset;
1099 Error(StrBuf.str()); 1140 Error(StrBuf.str());
1100 } 1141 }
1101 } 1142 }
1102 CurGlobalVar->addInitializer( 1143 CurGlobalVar->addInitializer(
1103 Ice::VariableDeclaration::RelocInitializer::create( 1144 Ice::VariableDeclaration::RelocInitializer::create(
1104 Context->getGlobalDeclarationByID(Index), Offset)); 1145 getGlobalDeclByID(Index), Offset));
1105 return; 1146 return;
1106 } 1147 }
1107 default: 1148 default:
1108 BlockParserBaseClass::ProcessRecord(); 1149 BlockParserBaseClass::ProcessRecord();
1109 return; 1150 return;
1110 } 1151 }
1111 } 1152 }
1112 1153
1113 /// Base class for parsing a valuesymtab block in the bitcode file. 1154 /// Base class for parsing a valuesymtab block in the bitcode file.
1114 class ValuesymtabParser : public BlockParserBaseClass { 1155 class ValuesymtabParser : public BlockParserBaseClass {
(...skipping 2025 matching lines...) Expand 10 before | Expand all | Expand 10 after
3140 } 3181 }
3141 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { 3182 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) {
3142 ErrStream 3183 ErrStream
3143 << IRFilename 3184 << IRFilename
3144 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; 3185 << ": 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"); 3186 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes");
3146 } 3187 }
3147 } 3188 }
3148 3189
3149 } // end of namespace Ice 3190 } // 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