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

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 nit. 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
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. These 56 // Models elements in the list of types defined in the types block. These
45 // elements can be undefined, a (simple) type, or a function type signature. 57 // elements can be undefined, a (simple) type, or a function type signature.
46 // Note that an extended type is undefined on construction. Use methods 58 // Note that an extended type is undefined on construction. Use methods
47 // setAsSimpleType and setAsFuncSigType to define the extended type. 59 // setAsSimpleType and setAsFuncSigType to define the extended type.
48 class ExtendedType { 60 class ExtendedType {
49 ExtendedType &operator=(const ExtendedType &Ty) = delete; 61 ExtendedType &operator=(const ExtendedType &Ty) = delete;
50 62
(...skipping 1088 matching lines...) Expand 10 before | Expand all | Expand 10 after
1139 ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) 1151 ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
1140 : BlockParserBaseClass(BlockID, EnclosingParser) {} 1152 : BlockParserBaseClass(BlockID, EnclosingParser) {}
1141 1153
1142 ~ValuesymtabParser() override = default; 1154 ~ValuesymtabParser() override = default;
1143 1155
1144 const char *getBlockName() const override { return "valuesymtab"; } 1156 const char *getBlockName() const override { return "valuesymtab"; }
1145 1157
1146 protected: 1158 protected:
1147 using StringType = SmallString<128>; 1159 using StringType = SmallString<128>;
1148 1160
1161 // Returns the name to identify the kind of symbol table this is
1162 // in error messages.
1163 virtual const char *getTableKind() const = 0;
1164
1149 // Associates Name with the value defined by the given Index. 1165 // Associates Name with the value defined by the given Index.
1150 virtual void setValueName(NaClBcIndexSize_t Index, StringType &Name) = 0; 1166 virtual void setValueName(NaClBcIndexSize_t Index, StringType &Name) = 0;
1151 1167
1152 // Associates Name with the value defined by the given Index; 1168 // Associates Name with the value defined by the given Index;
1153 virtual void setBbName(NaClBcIndexSize_t Index, StringType &Name) = 0; 1169 virtual void setBbName(NaClBcIndexSize_t Index, StringType &Name) = 0;
1154 1170
1171 // Reports that the assignment of Name to the value associated with
1172 // index is not possible, for the given Context.
1173 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index,
1174 StringType &Name);
1175
1155 private: 1176 private:
1177 using NamesSetType = std::unordered_set<StringType>;
1178 NamesSetType ValueNames;
1179 NamesSetType BlockNames;
1180
1156 void ProcessRecord() override; 1181 void ProcessRecord() override;
1157 1182
1158 void convertToString(StringType &ConvertedName) { 1183 // Extracts out ConvertedName. Returns true if unique wrt to Names.
1184 bool convertToString(NamesSetType &Names, StringType &ConvertedName) {
1159 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 1185 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1160 for (size_t i = 1, e = Values.size(); i != e; ++i) { 1186 for (size_t i = 1, e = Values.size(); i != e; ++i) {
1161 ConvertedName += static_cast<char>(Values[i]); 1187 ConvertedName += static_cast<char>(Values[i]);
1162 } 1188 }
1189 auto Pair = Names.insert(ConvertedName);
1190 return Pair.second;
1163 } 1191 }
1192
1193 void ReportDuplicateName(const char *NameCat, StringType &Name);
1164 }; 1194 };
1165 1195
1196 void ValuesymtabParser::reportUnableToAssign(const char *Context,
1197 NaClBcIndexSize_t Index,
1198 StringType &Name) {
1199 std::string Buffer;
1200 raw_string_ostream StrBuf(Buffer);
1201 StrBuf << getTableKind() << " " << getBlockName() << ": " << Context
1202 << " name '" << Name << "' can't be associated with index " << Index;
1203 Error(StrBuf.str());
1204 }
1205
1206 void ValuesymtabParser::ReportDuplicateName(const char *NameCat,
1207 StringType &Name) {
1208 std::string Buffer;
1209 raw_string_ostream StrBuf(Buffer);
1210 StrBuf << getTableKind() << " " << getBlockName() << " defines duplicate "
1211 << NameCat << " name: '" << Name << "'";
1212 Error(StrBuf.str());
1213 }
1214
1166 void ValuesymtabParser::ProcessRecord() { 1215 void ValuesymtabParser::ProcessRecord() {
1167 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 1216 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1168 StringType ConvertedName; 1217 StringType ConvertedName;
1169 switch (Record.GetCode()) { 1218 switch (Record.GetCode()) {
1170 case naclbitc::VST_CODE_ENTRY: { 1219 case naclbitc::VST_CODE_ENTRY: {
1171 // VST_ENTRY: [ValueId, namechar x N] 1220 // VST_ENTRY: [ValueId, namechar x N]
1172 if (!isValidRecordSizeAtLeast(2, "value entry")) 1221 if (!isValidRecordSizeAtLeast(2, "value entry"))
1173 return; 1222 return;
1174 convertToString(ConvertedName); 1223 if (convertToString(ValueNames, ConvertedName))
1175 setValueName(Values[0], ConvertedName); 1224 setValueName(Values[0], ConvertedName);
1225 else
1226 ReportDuplicateName("value", ConvertedName);
1176 return; 1227 return;
1177 } 1228 }
1178 case naclbitc::VST_CODE_BBENTRY: { 1229 case naclbitc::VST_CODE_BBENTRY: {
1179 // VST_BBENTRY: [BbId, namechar x N] 1230 // VST_BBENTRY: [BbId, namechar x N]
1180 if (!isValidRecordSizeAtLeast(2, "basic block entry")) 1231 if (!isValidRecordSizeAtLeast(2, "basic block entry"))
1181 return; 1232 return;
1182 convertToString(ConvertedName); 1233 if (convertToString(BlockNames, ConvertedName))
1183 setBbName(Values[0], ConvertedName); 1234 setBbName(Values[0], ConvertedName);
1235 else
1236 ReportDuplicateName("block", ConvertedName);
1184 return; 1237 return;
1185 } 1238 }
1186 default: 1239 default:
1187 break; 1240 break;
1188 } 1241 }
1189 // If reached, don't know how to handle record. 1242 // If reached, don't know how to handle record.
1190 BlockParserBaseClass::ProcessRecord(); 1243 BlockParserBaseClass::ProcessRecord();
1191 return; 1244 return;
1192 } 1245 }
1193 1246
(...skipping 1663 matching lines...) Expand 10 before | Expand all | Expand 10 after
2857 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs, 2910 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs,
2858 getTranslator().getContext()) {} 2911 getTranslator().getContext()) {}
2859 2912
2860 private: 2913 private:
2861 Ice::TimerMarker Timer; 2914 Ice::TimerMarker Timer;
2862 // Returns the enclosing function parser. 2915 // Returns the enclosing function parser.
2863 FunctionParser *getFunctionParser() const { 2916 FunctionParser *getFunctionParser() const {
2864 return reinterpret_cast<FunctionParser *>(GetEnclosingParser()); 2917 return reinterpret_cast<FunctionParser *>(GetEnclosingParser());
2865 } 2918 }
2866 2919
2867 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; 2920 const char *getTableKind() const final { return "Function"; }
2868 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; 2921
2922 void setValueName(NaClBcIndexSize_t Index, StringType &Name) final;
2923 void setBbName(NaClBcIndexSize_t Index, StringType &Name) final;
2869 2924
2870 // Reports that the assignment of Name to the value associated with index is 2925 // Reports that the assignment of Name to the value associated with index is
2871 // not possible, for the given Context. 2926 // not possible, for the given Context.
2872 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index, 2927 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index,
2873 StringType &Name) { 2928 StringType &Name) {
2874 std::string Buffer; 2929 std::string Buffer;
2875 raw_string_ostream StrBuf(Buffer); 2930 raw_string_ostream StrBuf(Buffer);
2876 StrBuf << "Function-local " << Context << " name '" << Name 2931 StrBuf << "Function-local " << Context << " name '" << Name
2877 << "' can't be associated with index " << Index; 2932 << "' can't be associated with index " << Index;
2878 Error(StrBuf.str()); 2933 Error(StrBuf.str());
2879 } 2934 }
2880 }; 2935 };
2881 2936
2882 void FunctionValuesymtabParser::setValueName(NaClBcIndexSize_t Index, 2937 void FunctionValuesymtabParser::setValueName(NaClBcIndexSize_t Index,
2883 StringType &Name) { 2938 StringType &Name) {
2884 // Note: We check when Index is too small, so that we can error recover 2939 // Note: We check when Index is too small, so that we can error recover
2885 // (FP->getOperand will create fatal error). 2940 // (FP->getOperand will create fatal error).
2886 if (Index < getFunctionParser()->getNumGlobalIDs()) { 2941 if (Index < getFunctionParser()->getNumGlobalIDs()) {
2887 reportUnableToAssign("instruction", Index, Name); 2942 reportUnableToAssign("Global value", Index, Name);
2888 return; 2943 return;
2889 } 2944 }
2890 if (isIRGenerationDisabled()) 2945 if (isIRGenerationDisabled())
2891 return; 2946 return;
2892 Ice::Operand *Op = getFunctionParser()->getOperand(Index); 2947 Ice::Operand *Op = getFunctionParser()->getOperand(Index);
2893 if (Ice::Variable *V = dyn_cast<Ice::Variable>(Op)) { 2948 if (Ice::Variable *V = dyn_cast<Ice::Variable>(Op)) {
2894 if (Ice::BuildDefs::dump()) { 2949 if (Ice::BuildDefs::dump()) {
2895 std::string Nm(Name.data(), Name.size()); 2950 std::string Nm(Name.data(), Name.size());
2896 V->setName(getFunctionParser()->getFunc(), Nm); 2951 V->setName(getFunctionParser()->getFunc(), Nm);
2897 } 2952 }
2898 } else { 2953 } else {
2899 reportUnableToAssign("variable", Index, Name); 2954 reportUnableToAssign("Local value", Index, Name);
2900 } 2955 }
2901 } 2956 }
2902 2957
2903 void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index, 2958 void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index,
2904 StringType &Name) { 2959 StringType &Name) {
2905 if (!Ice::BuildDefs::dump()) 2960 if (!Ice::BuildDefs::dump())
2906 return; 2961 return;
2907 if (isIRGenerationDisabled()) 2962 if (isIRGenerationDisabled())
2908 return; 2963 return;
2909 if (Index >= getFunctionParser()->getFunc()->getNumNodes()) { 2964 if (Index >= getFunctionParser()->getFunc()->getNumNodes()) {
2910 reportUnableToAssign("block", Index, Name); 2965 reportUnableToAssign("Basic block", Index, Name);
2911 return; 2966 return;
2912 } 2967 }
2913 std::string Nm(Name.data(), Name.size()); 2968 std::string Nm(Name.data(), Name.size());
2914 if (Ice::BuildDefs::dump()) 2969 if (Ice::BuildDefs::dump())
2915 getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm); 2970 getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm);
2916 } 2971 }
2917 2972
2918 bool FunctionParser::ParseBlock(unsigned BlockID) { 2973 bool FunctionParser::ParseBlock(unsigned BlockID) {
2919 switch (BlockID) { 2974 switch (BlockID) {
2920 case naclbitc::CONSTANTS_BLOCK_ID: { 2975 case naclbitc::CONSTANTS_BLOCK_ID: {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2983 public: 3038 public:
2984 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP) 3039 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP)
2985 : ValuesymtabParser(BlockID, MP), 3040 : ValuesymtabParser(BlockID, MP),
2986 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs, 3041 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs,
2987 getTranslator().getContext()) {} 3042 getTranslator().getContext()) {}
2988 3043
2989 ~ModuleValuesymtabParser() override = default; 3044 ~ModuleValuesymtabParser() override = default;
2990 3045
2991 private: 3046 private:
2992 Ice::TimerMarker Timer; 3047 Ice::TimerMarker Timer;
2993 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; 3048 const char *getTableKind() const final { return "Module"; }
2994 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; 3049 void setValueName(NaClBcIndexSize_t Index, StringType &Name) final;
3050 void setBbName(NaClBcIndexSize_t Index, StringType &Name) final;
2995 }; 3051 };
2996 3052
2997 void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index, 3053 void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index,
2998 StringType &Name) { 3054 StringType &Name) {
2999 Context->getGlobalDeclarationByID(Index) 3055 Context->getGlobalDeclarationByID(Index)
3000 ->setName(StringRef(Name.data(), Name.size())); 3056 ->setName(StringRef(Name.data(), Name.size()));
3001 } 3057 }
3002 3058
3003 void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index, 3059 void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index,
3004 StringType &Name) { 3060 StringType &Name) {
3005 std::string Buffer; 3061 reportUnableToAssign("Basic block", Index, Name);
3006 raw_string_ostream StrBuf(Buffer);
3007 StrBuf << "Can't define basic block name at global level: '" << Name
3008 << "' -> " << Index;
3009 Error(StrBuf.str());
3010 } 3062 }
3011 3063
3012 bool ModuleParser::ParseBlock(unsigned BlockID) { 3064 bool ModuleParser::ParseBlock(unsigned BlockID) {
3013 switch (BlockID) { 3065 switch (BlockID) {
3014 case naclbitc::BLOCKINFO_BLOCK_ID: 3066 case naclbitc::BLOCKINFO_BLOCK_ID:
3015 return NaClBitcodeParser::ParseBlock(BlockID); 3067 return NaClBitcodeParser::ParseBlock(BlockID);
3016 case naclbitc::TYPE_BLOCK_ID_NEW: { 3068 case naclbitc::TYPE_BLOCK_ID_NEW: {
3017 TypesParser Parser(BlockID, this); 3069 TypesParser Parser(BlockID, this);
3018 return Parser.ParseThisBlock(); 3070 return Parser.ParseThisBlock();
3019 } 3071 }
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
3151 } 3203 }
3152 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { 3204 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) {
3153 ErrStream 3205 ErrStream
3154 << IRFilename 3206 << IRFilename
3155 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; 3207 << ": Bitcode stream should be a multiple of 4 bytes in length.\n";
3156 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); 3208 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes");
3157 } 3209 }
3158 } 3210 }
3159 3211
3160 } // end of namespace Ice 3212 } // 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