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

Side by Side Diff: src/PNaClTranslator.cpp

Issue 1347683003: Check that symbol names in symbol tables are unique. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix issues in patch set 2. Created 5 years, 3 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 | tests_lit/parse_errs/Inputs/duplicate-fcn-name.tbc » ('j') | 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
11 /// This file implements the PNaCl bitcode file to Ice, to machine code 11 /// This file implements the PNaCl bitcode file to Ice, to machine code
12 /// translator. 12 /// translator.
13 /// 13 ///
14 //===----------------------------------------------------------------------===// 14 //===----------------------------------------------------------------------===//
15 15
16 #include "PNaClTranslator.h" 16 #include "PNaClTranslator.h"
17 17
18 #include "IceAPInt.h" 18 #include "IceAPInt.h"
19 #include "IceAPFloat.h" 19 #include "IceAPFloat.h"
20 #include "IceCfg.h" 20 #include "IceCfg.h"
21 #include "IceCfgNode.h" 21 #include "IceCfgNode.h"
22 #include "IceClFlags.h" 22 #include "IceClFlags.h"
23 #include "IceDefs.h" 23 #include "IceDefs.h"
24 #include "IceGlobalInits.h" 24 #include "IceGlobalInits.h"
25 #include "IceInst.h" 25 #include "IceInst.h"
26 #include "IceOperand.h" 26 #include "IceOperand.h"
27 27
28 #pragma clang diagnostic push 28 #pragma clang diagnostic push
29 #pragma clang diagnostic ignored "-Wunused-parameter" 29 #pragma clang diagnostic ignored "-Wunused-parameter"
30 #include "llvm/ADT/Hashing.h"
30 #include "llvm/ADT/SmallString.h" 31 #include "llvm/ADT/SmallString.h"
31 #include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h" 32 #include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h"
32 #include "llvm/Bitcode/NaCl/NaClBitcodeDefs.h" 33 #include "llvm/Bitcode/NaCl/NaClBitcodeDefs.h"
33 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" 34 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h"
34 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" 35 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h"
35 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" 36 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h"
36 #include "llvm/Support/Format.h" 37 #include "llvm/Support/Format.h"
37 #include "llvm/Support/MemoryBuffer.h" 38 #include "llvm/Support/MemoryBuffer.h"
38 #include "llvm/Support/raw_ostream.h" 39 #include "llvm/Support/raw_ostream.h"
40 #include <unordered_set>
39 #pragma clang diagnostic pop 41 #pragma clang diagnostic pop
40 42
43 // Define a hash function for SmallString's, so that it can be used in hash
44 // tables.
45 namespace std {
46 template <unsigned InternalLen> struct hash<llvm::SmallString<InternalLen>> {
47 size_t operator()(const llvm::SmallString<InternalLen> &Key) const {
48 return llvm::hash_combine_range(Key.begin(), Key.end());
49 }
50 };
51 } // end of namespace std.
Jim Stichnoth 2015/09/16 19:54:37 no period, for consistency
Karl 2015/09/16 20:51:43 Done.
52
41 namespace { 53 namespace {
42 using namespace llvm; 54 using namespace llvm;
43 55
44 // Models elements in the list of types defined in the types block. 56 // Models elements in the list of types defined in the types block.
45 // These elements can be undefined, a (simple) type, or a function type 57 // These elements can be undefined, a (simple) type, or a function type
46 // signature. Note that an extended type is undefined on construction. 58 // signature. Note that an extended type is undefined on construction.
47 // Use methods setAsSimpleType and setAsFuncSigType to define 59 // Use methods setAsSimpleType and setAsFuncSigType to define
48 // the extended type. 60 // the extended type.
49 class ExtendedType { 61 class ExtendedType {
50 ExtendedType &operator=(const ExtendedType &Ty) = delete; 62 ExtendedType &operator=(const ExtendedType &Ty) = delete;
(...skipping 1102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1153 ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) 1165 ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
1154 : BlockParserBaseClass(BlockID, EnclosingParser) {} 1166 : BlockParserBaseClass(BlockID, EnclosingParser) {}
1155 1167
1156 ~ValuesymtabParser() override = default; 1168 ~ValuesymtabParser() override = default;
1157 1169
1158 const char *getBlockName() const override { return "valuesymtab"; } 1170 const char *getBlockName() const override { return "valuesymtab"; }
1159 1171
1160 protected: 1172 protected:
1161 using StringType = SmallString<128>; 1173 using StringType = SmallString<128>;
1162 1174
1175 // Returns the name to identify the kind of symbol table this is
1176 // in error messages.
1177 virtual const char *getTableKind() const = 0;
1178
1163 // Associates Name with the value defined by the given Index. 1179 // Associates Name with the value defined by the given Index.
1164 virtual void setValueName(NaClBcIndexSize_t Index, StringType &Name) = 0; 1180 virtual void setValueName(NaClBcIndexSize_t Index, StringType &Name) = 0;
1165 1181
1166 // Associates Name with the value defined by the given Index; 1182 // Associates Name with the value defined by the given Index;
1167 virtual void setBbName(NaClBcIndexSize_t Index, StringType &Name) = 0; 1183 virtual void setBbName(NaClBcIndexSize_t Index, StringType &Name) = 0;
1168 1184
1185 // Reports that the assignment of Name to the value associated with
1186 // index is not possible, for the given Context.
1187 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index,
1188 StringType &Name);
1189
1169 private: 1190 private:
1191 using NamesSetType = std::unordered_set<StringType>;
1192 NamesSetType ValueNames;
1193 NamesSetType BlockNames;
1194
1170 void ProcessRecord() override; 1195 void ProcessRecord() override;
1171 1196
1172 void convertToString(StringType &ConvertedName) { 1197 // Extracts out ConvertedName. Returns true if unique wrt to Names.
1198 bool convertToString(NamesSetType &Names, StringType &ConvertedName) {
1173 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 1199 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1174 for (size_t i = 1, e = Values.size(); i != e; ++i) { 1200 for (size_t i = 1, e = Values.size(); i != e; ++i) {
1175 ConvertedName += static_cast<char>(Values[i]); 1201 ConvertedName += static_cast<char>(Values[i]);
1176 } 1202 }
1203 auto Pair = Names.insert(ConvertedName);
1204 return Pair.second;
1177 } 1205 }
1206
1207 void ReportDuplicateName(const char *NameCat, StringType &Name);
1178 }; 1208 };
1179 1209
1210 void ValuesymtabParser::reportUnableToAssign(const char *Context,
1211 NaClBcIndexSize_t Index,
1212 StringType &Name) {
1213 std::string Buffer;
1214 raw_string_ostream StrBuf(Buffer);
1215 StrBuf << getTableKind() << " " << getBlockName() << ": " << Context
1216 << " name '" << Name << "' can't be associated with index " << Index;
1217 Error(StrBuf.str());
1218 }
1219
1220 void ValuesymtabParser::ReportDuplicateName(const char *NameCat,
1221 StringType &Name) {
1222 std::string Buffer;
1223 raw_string_ostream StrBuf(Buffer);
1224 StrBuf << getTableKind() << " " << getBlockName() << " defines duplicate "
1225 << NameCat << " name: '" << Name << "'";
1226 Error(StrBuf.str());
1227 }
1228
1180 void ValuesymtabParser::ProcessRecord() { 1229 void ValuesymtabParser::ProcessRecord() {
1181 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 1230 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1182 StringType ConvertedName; 1231 StringType ConvertedName;
1183 switch (Record.GetCode()) { 1232 switch (Record.GetCode()) {
1184 case naclbitc::VST_CODE_ENTRY: { 1233 case naclbitc::VST_CODE_ENTRY: {
1185 // VST_ENTRY: [ValueId, namechar x N] 1234 // VST_ENTRY: [ValueId, namechar x N]
1186 if (!isValidRecordSizeAtLeast(2, "value entry")) 1235 if (!isValidRecordSizeAtLeast(2, "value entry"))
1187 return; 1236 return;
1188 convertToString(ConvertedName); 1237 if (convertToString(ValueNames, ConvertedName))
1189 setValueName(Values[0], ConvertedName); 1238 setValueName(Values[0], ConvertedName);
1239 else
1240 ReportDuplicateName("value", ConvertedName);
1190 return; 1241 return;
1191 } 1242 }
1192 case naclbitc::VST_CODE_BBENTRY: { 1243 case naclbitc::VST_CODE_BBENTRY: {
1193 // VST_BBENTRY: [BbId, namechar x N] 1244 // VST_BBENTRY: [BbId, namechar x N]
1194 if (!isValidRecordSizeAtLeast(2, "basic block entry")) 1245 if (!isValidRecordSizeAtLeast(2, "basic block entry"))
1195 return; 1246 return;
1196 convertToString(ConvertedName); 1247 if (convertToString(BlockNames, ConvertedName))
1197 setBbName(Values[0], ConvertedName); 1248 setBbName(Values[0], ConvertedName);
1249 else
1250 ReportDuplicateName("block", ConvertedName);
1198 return; 1251 return;
1199 } 1252 }
1200 default: 1253 default:
1201 break; 1254 break;
1202 } 1255 }
1203 // If reached, don't know how to handle record. 1256 // If reached, don't know how to handle record.
1204 BlockParserBaseClass::ProcessRecord(); 1257 BlockParserBaseClass::ProcessRecord();
1205 return; 1258 return;
1206 } 1259 }
1207 1260
(...skipping 1669 matching lines...) Expand 10 before | Expand all | Expand 10 after
2877 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs, 2930 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs,
2878 getTranslator().getContext()) {} 2931 getTranslator().getContext()) {}
2879 2932
2880 private: 2933 private:
2881 Ice::TimerMarker Timer; 2934 Ice::TimerMarker Timer;
2882 // Returns the enclosing function parser. 2935 // Returns the enclosing function parser.
2883 FunctionParser *getFunctionParser() const { 2936 FunctionParser *getFunctionParser() const {
2884 return reinterpret_cast<FunctionParser *>(GetEnclosingParser()); 2937 return reinterpret_cast<FunctionParser *>(GetEnclosingParser());
2885 } 2938 }
2886 2939
2887 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; 2940 const char *getTableKind() const final { return "Function"; }
2888 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override;
2889 2941
2890 // Reports that the assignment of Name to the value associated with 2942 void setValueName(NaClBcIndexSize_t Index, StringType &Name) final;
2891 // index is not possible, for the given Context. 2943 void setBbName(NaClBcIndexSize_t Index, StringType &Name) final;
2892 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index,
2893 StringType &Name) {
2894 std::string Buffer;
2895 raw_string_ostream StrBuf(Buffer);
2896 StrBuf << "Function-local " << Context << " name '" << Name
2897 << "' can't be associated with index " << Index;
2898 Error(StrBuf.str());
2899 }
2900 }; 2944 };
2901 2945
2902 void FunctionValuesymtabParser::setValueName(NaClBcIndexSize_t Index, 2946 void FunctionValuesymtabParser::setValueName(NaClBcIndexSize_t Index,
2903 StringType &Name) { 2947 StringType &Name) {
2904 // Note: We check when Index is too small, so that we can error recover 2948 // Note: We check when Index is too small, so that we can error recover
2905 // (FP->getOperand will create fatal error). 2949 // (FP->getOperand will create fatal error).
2906 if (Index < getFunctionParser()->getNumGlobalIDs()) { 2950 if (Index < getFunctionParser()->getNumGlobalIDs()) {
2907 reportUnableToAssign("instruction", Index, Name); 2951 reportUnableToAssign("Global value", Index, Name);
2908 return; 2952 return;
2909 } 2953 }
2910 if (isIRGenerationDisabled()) 2954 if (isIRGenerationDisabled())
2911 return; 2955 return;
2912 Ice::Operand *Op = getFunctionParser()->getOperand(Index); 2956 Ice::Operand *Op = getFunctionParser()->getOperand(Index);
2913 if (Ice::Variable *V = dyn_cast<Ice::Variable>(Op)) { 2957 if (Ice::Variable *V = dyn_cast<Ice::Variable>(Op)) {
2914 if (Ice::BuildDefs::dump()) { 2958 if (Ice::BuildDefs::dump()) {
2915 std::string Nm(Name.data(), Name.size()); 2959 std::string Nm(Name.data(), Name.size());
2916 V->setName(getFunctionParser()->getFunc(), Nm); 2960 V->setName(getFunctionParser()->getFunc(), Nm);
2917 } 2961 }
2918 } else { 2962 } else {
2919 reportUnableToAssign("variable", Index, Name); 2963 reportUnableToAssign("Local value", Index, Name);
2920 } 2964 }
2921 } 2965 }
2922 2966
2923 void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index, 2967 void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index,
2924 StringType &Name) { 2968 StringType &Name) {
2925 if (!Ice::BuildDefs::dump()) 2969 if (!Ice::BuildDefs::dump())
2926 return; 2970 return;
2927 if (isIRGenerationDisabled()) 2971 if (isIRGenerationDisabled())
2928 return; 2972 return;
2929 if (Index >= getFunctionParser()->getFunc()->getNumNodes()) { 2973 if (Index >= getFunctionParser()->getFunc()->getNumNodes()) {
2930 reportUnableToAssign("block", Index, Name); 2974 reportUnableToAssign("Basic block", Index, Name);
2931 return; 2975 return;
2932 } 2976 }
2933 std::string Nm(Name.data(), Name.size()); 2977 std::string Nm(Name.data(), Name.size());
2934 if (Ice::BuildDefs::dump()) 2978 if (Ice::BuildDefs::dump())
2935 getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm); 2979 getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm);
2936 } 2980 }
2937 2981
2938 bool FunctionParser::ParseBlock(unsigned BlockID) { 2982 bool FunctionParser::ParseBlock(unsigned BlockID) {
2939 switch (BlockID) { 2983 switch (BlockID) {
2940 case naclbitc::CONSTANTS_BLOCK_ID: { 2984 case naclbitc::CONSTANTS_BLOCK_ID: {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
3003 public: 3047 public:
3004 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP) 3048 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP)
3005 : ValuesymtabParser(BlockID, MP), 3049 : ValuesymtabParser(BlockID, MP),
3006 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs, 3050 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs,
3007 getTranslator().getContext()) {} 3051 getTranslator().getContext()) {}
3008 3052
3009 ~ModuleValuesymtabParser() override = default; 3053 ~ModuleValuesymtabParser() override = default;
3010 3054
3011 private: 3055 private:
3012 Ice::TimerMarker Timer; 3056 Ice::TimerMarker Timer;
3013 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; 3057 const char *getTableKind() const final { return "Module"; }
3014 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; 3058 void setValueName(NaClBcIndexSize_t Index, StringType &Name) final;
3059 void setBbName(NaClBcIndexSize_t Index, StringType &Name) final;
3015 }; 3060 };
3016 3061
3017 void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index, 3062 void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index,
3018 StringType &Name) { 3063 StringType &Name) {
3019 Context->getGlobalDeclarationByID(Index) 3064 Context->getGlobalDeclarationByID(Index)
3020 ->setName(StringRef(Name.data(), Name.size())); 3065 ->setName(StringRef(Name.data(), Name.size()));
3021 } 3066 }
3022 3067
3023 void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index, 3068 void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index,
3024 StringType &Name) { 3069 StringType &Name) {
3025 std::string Buffer; 3070 reportUnableToAssign("Basic block", Index, Name);
3026 raw_string_ostream StrBuf(Buffer);
3027 StrBuf << "Can't define basic block name at global level: '" << Name
3028 << "' -> " << Index;
3029 Error(StrBuf.str());
3030 } 3071 }
3031 3072
3032 bool ModuleParser::ParseBlock(unsigned BlockID) { 3073 bool ModuleParser::ParseBlock(unsigned BlockID) {
3033 switch (BlockID) { 3074 switch (BlockID) {
3034 case naclbitc::BLOCKINFO_BLOCK_ID: 3075 case naclbitc::BLOCKINFO_BLOCK_ID:
3035 return NaClBitcodeParser::ParseBlock(BlockID); 3076 return NaClBitcodeParser::ParseBlock(BlockID);
3036 case naclbitc::TYPE_BLOCK_ID_NEW: { 3077 case naclbitc::TYPE_BLOCK_ID_NEW: {
3037 TypesParser Parser(BlockID, this); 3078 TypesParser Parser(BlockID, this);
3038 return Parser.ParseThisBlock(); 3079 return Parser.ParseThisBlock();
3039 } 3080 }
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
3171 } 3212 }
3172 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { 3213 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) {
3173 ErrStream 3214 ErrStream
3174 << IRFilename 3215 << IRFilename
3175 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; 3216 << ": Bitcode stream should be a multiple of 4 bytes in length.\n";
3176 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); 3217 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes");
3177 } 3218 }
3178 } 3219 }
3179 3220
3180 } // end of namespace Ice 3221 } // end of namespace Ice
OLDNEW
« no previous file with comments | « no previous file | tests_lit/parse_errs/Inputs/duplicate-fcn-name.tbc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698