OLD | NEW |
---|---|
1 //===- NaClBitcodeMunge.h - Bitcode Munger ----------------------*- C++ -*-===// | 1 //===- NaClBitcodeMunge.h - Bitcode Munger ----------------------*- C++ -*-===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
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 // Test harness for generating a PNaCl bitcode memory buffer from | 10 // Test harness for generating a PNaCl bitcode memory buffer from |
11 // an array, and objdump the resulting contents. | 11 // an array, and parse/objdump the resulting contents. |
12 // | 12 // |
13 // Generates a bitcode memory buffer from an array containing 1 or | 13 // Generates a bitcode memory buffer from an array containing 1 or |
14 // more PNaCl records. Used to test errors in PNaCl bitcode. | 14 // more PNaCl records. Used to test errors in PNaCl bitcode. |
15 // | 15 // |
16 // For simplicity of API, we model records as an array of uint64_t. To | 16 // For simplicity of API, we model records as an array of uint64_t. To |
17 // specify the end of a record in the array, a special "terminator" | 17 // specify the end of a record in the array, a special "terminator" |
18 // value is used. This terminator value must be a uint64_t value that | 18 // value is used. This terminator value must be a uint64_t value that |
19 // is not used by any of the records. | 19 // is not used by any of the records. |
20 // | 20 // |
21 // A record is defined as a sequence of integers consisting of: | 21 // A record is defined as a sequence of integers consisting of: |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
56 | 56 |
57 #include "llvm/ADT/SmallVector.h" | 57 #include "llvm/ADT/SmallVector.h" |
58 #include "llvm/Support/DataTypes.h" | 58 #include "llvm/Support/DataTypes.h" |
59 #include "llvm/Support/ErrorHandling.h" | 59 #include "llvm/Support/ErrorHandling.h" |
60 #include "llvm/Support/raw_ostream.h" | 60 #include "llvm/Support/raw_ostream.h" |
61 | 61 |
62 #include <string> | 62 #include <string> |
63 | 63 |
64 namespace llvm { | 64 namespace llvm { |
65 | 65 |
66 class MemoryBuffer; | |
66 class NaClBitstreamWriter; | 67 class NaClBitstreamWriter; |
67 class NaClBitCodeAbbrev; | 68 class NaClBitCodeAbbrev; |
68 | 69 |
69 /// Class to run tests for function llvm::NaClObjDump. | 70 /// Base class to run tests on munged bitcode files. |
70 class NaClBitcodeMunger { | 71 class NaClBitcodeMunger { |
71 public: | 72 public: |
72 /// The types of editing actions that can be applied. | 73 /// The types of editing actions that can be applied. |
73 enum EditAction { | 74 enum EditAction { |
74 AddBefore, // Insert record before record with index. | 75 AddBefore, // Insert record before record with index. |
75 AddAfter, // Insert record after record with index. | 76 AddAfter, // Insert record after record with index. |
76 Remove, // Remove record with index. | 77 Remove, // Remove record with index. |
77 Replace // Replace record with index with specified record. | 78 Replace // Replace record with index with specified record. |
78 }; | 79 }; |
79 | 80 |
80 /// Creates a bitcode munger, based on the given array of values. | 81 /// Creates a bitcode munger, based on the given array of values. |
81 NaClBitcodeMunger(const uint64_t Records[], size_t RecordsSize, | 82 NaClBitcodeMunger(const uint64_t Records[], size_t RecordsSize, |
82 uint64_t RecordTerminator) | 83 uint64_t RecordTerminator) |
83 : Records(Records), RecordsSize(RecordsSize), | 84 : Records(Records), RecordsSize(RecordsSize), |
84 RecordTerminator(RecordTerminator), WriteBlockID(-1), SetBID(-1), | 85 RecordTerminator(RecordTerminator), WriteBlockID(-1), SetBID(-1), |
85 DumpResults("Error: No previous dump results!\n"), | 86 DumpResults("Error: No previous dump results!\n"), MungedInput(nullptr), |
86 DumpStream(NULL), Writer(NULL), FoundErrors(false), | 87 DumpStream(nullptr), Writer(nullptr), FoundErrors(false), |
87 FatalBuffer(), FatalStream(FatalBuffer) {} | 88 FatalBuffer(), FatalStream(FatalBuffer) {} |
88 | 89 |
89 /// Runs function NaClObjDump on the sequence of records associated | 90 /// Creates MungedInput and DumpStream for running tests, based on |
90 /// with the instance. The memory buffer containing the bitsequence | 91 /// given Munges. |
91 /// associated with the record is automatically generated, and | 92 void setupTest( |
92 /// passed to NaClObjDump. TestName is the name associated with the | 93 const char *TestName, const uint64_t Munges[], size_t MungesSize, |
93 /// memory buffer. If AddHeader is true, test assumes that the | 94 bool AddHeader); |
94 /// sequence of records doesn't contain a header record, and the | |
95 /// test should add one. Arguments NoRecords and NoAssembly are | |
96 /// passed to NaClObjDump. Returns true if test succeeds without | |
97 /// errors. | |
98 bool runTestWithFlags(const char *TestName, bool AddHeader, | |
99 bool NoRecords, bool NoAssembly) { | |
100 uint64_t NoMunges[] = {0}; | |
101 return runTestWithFlags(TestName, NoMunges, 0, AddHeader, NoRecords, | |
102 NoAssembly); | |
103 } | |
104 | 95 |
105 /// Same as above except it runs function NaClObjDump with flags | 96 /// Cleans up state after a test. |
106 /// NoRecords and NoAssembly set to false, and AddHeader set to true. | 97 void cleanupTest(); |
107 bool runTest(const char *TestName) { | |
108 return runTestWithFlags(TestName, true, false, false); | |
109 } | |
110 | |
111 /// Same as runTest, but only print out assembly and errors. | |
112 bool runTestForAssembly(const char *TestName) { | |
113 return runTestWithFlags(TestName, true, true, false); | |
114 } | |
115 | |
116 /// Same as runTest, but only generate error messages. | |
117 bool runTestForErrors(const char *TestName) { | |
118 return runTestWithFlags(TestName, true, true, true); | |
119 } | |
120 | |
121 /// Runs function llvm::NaClObjDump on the sequence of records | |
122 /// associated with the instance. Array Munges contains the sequence | |
123 /// of edits to apply to the sequence of records when generating the | |
124 /// bitsequence in a memory buffer. This generated bitsequence is | |
125 /// then passed to NaClObjDump. TestName is the name associated | |
126 /// with the memory buffer. Arguments NoRecords and NoAssembly are | |
127 /// passed to NaClObjDump. Returns true if test succeeds without | |
128 /// errors. | |
129 bool runTestWithFlags(const char* TestName, const uint64_t Munges[], | |
130 size_t MungesSize, bool AddHeader, | |
131 bool NoRecords, bool NoAssembly); | |
132 | |
133 /// Same as above except it runs function NaClObjDump with flags | |
134 /// NoRecords and NoAssembly set to false, and AddHeader set to | |
135 /// true. | |
136 bool runTest(const char* TestName, const uint64_t Munges[], | |
137 size_t MungesSize) { | |
138 return runTestWithFlags(TestName, Munges, MungesSize, true, false, false); | |
139 } | |
140 | |
141 bool runTestForAssembly(const char* TestName, const uint64_t Munges[], | |
142 size_t MungesSize) { | |
143 return runTestWithFlags(TestName, Munges, MungesSize, true, true, false); | |
144 } | |
145 | |
146 bool runTestForErrors(const char* TestName, const uint64_t Munges[], | |
147 size_t MungesSize) { | |
148 return runTestWithFlags(TestName, Munges, MungesSize, true, true, true); | |
149 } | |
150 | 98 |
151 /// Returns the resulting string generated by NaClObjDump. | 99 /// Returns the resulting string generated by NaClObjDump. |
jvoung (off chromium)
2014/12/03 19:43:46
cleanup for comment: this is now more generic than
Karl
2014/12/03 20:53:44
Done.
| |
152 const std::string &getTestResults() const { | 100 const std::string &getTestResults() const { |
153 return DumpResults; | 101 return DumpResults; |
154 } | 102 } |
155 | 103 |
156 /// Returns the lines containing the given Substring, from the | 104 /// Returns the lines containing the given Substring, from the |
157 /// string getTestResults(). | 105 /// string getTestResults(). |
158 std::string getLinesWithSubstring(const std::string &Substring) const { | 106 std::string getLinesWithSubstring(const std::string &Substring) const { |
159 return getLinesWithTextMatch(Substring, false); | 107 return getLinesWithTextMatch(Substring, false); |
160 } | 108 } |
161 | 109 |
162 /// Returns the lines starting with the given Prefix, from the string | 110 /// Returns the lines starting with the given Prefix, from the string |
163 /// getTestResults(). | 111 /// getTestResults(). |
164 std::string getLinesWithPrefix(const std::string &Prefix) const { | 112 std::string getLinesWithPrefix(const std::string &Prefix) const { |
165 return getLinesWithTextMatch(Prefix, true); | 113 return getLinesWithTextMatch(Prefix, true); |
166 } | 114 } |
167 | 115 |
168 private: | 116 protected: |
169 // The list of (base) records. | 117 // The list of (base) records. |
170 const uint64_t *Records; | 118 const uint64_t *Records; |
171 // The number of (base) records. | 119 // The number of (base) records. |
172 size_t RecordsSize; | 120 size_t RecordsSize; |
173 // The value used as record terminator. | 121 // The value used as record terminator. |
174 uint64_t RecordTerminator; | 122 uint64_t RecordTerminator; |
175 // The block ID associated with the block being written. | 123 // The block ID associated with the block being written. |
176 int WriteBlockID; | 124 int WriteBlockID; |
177 // The SetBID for the blockinfo block. | 125 // The SetBID for the blockinfo block. |
178 int SetBID; | 126 int SetBID; |
179 // The results buffer of the last dump. | 127 // The results buffer of the last dump. |
180 std::string DumpResults; | 128 std::string DumpResults; |
129 // The memory buffer containing the munged input. | |
130 MemoryBuffer *MungedInput; | |
181 // The stream containing errors and the objdump of the generated bitcode file. | 131 // The stream containing errors and the objdump of the generated bitcode file. |
182 raw_ostream *DumpStream; | 132 raw_ostream *DumpStream; |
183 // The bitstream writer to use to generate the bitcode file. | 133 // The bitstream writer to use to generate the bitcode file. |
184 NaClBitstreamWriter *Writer; | 134 NaClBitstreamWriter *Writer; |
185 // True if any errors were reported. | 135 // True if any errors were reported. |
186 bool FoundErrors; | 136 bool FoundErrors; |
187 // The buffer to hold the generated fatal message. | 137 // The buffer to hold the generated fatal message. |
188 std::string FatalBuffer; | 138 std::string FatalBuffer; |
189 // The stream to write the fatal message to. | 139 // The stream to write the fatal message to. |
190 raw_string_ostream FatalStream; | 140 raw_string_ostream FatalStream; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
232 // updates Index by one. | 182 // updates Index by one. |
233 void emitRecordAtIndex(const uint64_t Record[], size_t RecordSize, | 183 void emitRecordAtIndex(const uint64_t Record[], size_t RecordSize, |
234 size_t &Index); | 184 size_t &Index); |
235 | 185 |
236 // Skips the record starting at Index by advancing Index past the | 186 // Skips the record starting at Index by advancing Index past the |
237 // contents of the record. | 187 // contents of the record. |
238 void deleteRecord(const uint64_t Record[], size_t RecordSize, | 188 void deleteRecord(const uint64_t Record[], size_t RecordSize, |
239 size_t &Index); | 189 size_t &Index); |
240 }; | 190 }; |
241 | 191 |
192 /// Class to run tests for function llvm::NaClObjDump. | |
193 class NaClObjDumpMunger : public NaClBitcodeMunger { | |
194 public: | |
195 | |
196 /// Creates a bitcode munger, based on the given array of values. | |
197 NaClObjDumpMunger(const uint64_t Records[], size_t RecordsSize, | |
198 uint64_t RecordTerminator) | |
199 : NaClBitcodeMunger(Records, RecordsSize, RecordTerminator) {} | |
200 | |
201 /// Runs function NaClObjDump on the sequence of records associated | |
202 /// with the instance. The memory buffer containing the bitsequence | |
203 /// associated with the record is automatically generated, and | |
204 /// passed to NaClObjDump. TestName is the name associated with the | |
205 /// memory buffer. If AddHeader is true, test assumes that the | |
206 /// sequence of records doesn't contain a header record, and the | |
207 /// test should add one. Arguments NoRecords and NoAssembly are | |
208 /// passed to NaClObjDump. Returns true if test succeeds without | |
209 /// errors. | |
210 bool runTestWithFlags(const char *TestName, bool AddHeader, | |
211 bool NoRecords, bool NoAssembly) { | |
212 uint64_t NoMunges[] = {0}; | |
213 return runTestWithFlags(TestName, NoMunges, 0, AddHeader, NoRecords, | |
214 NoAssembly); | |
215 } | |
216 | |
217 /// Same as above except it runs function NaClObjDump with flags | |
218 /// NoRecords and NoAssembly set to false, and AddHeader set to true. | |
219 bool runTest(const char *TestName) { | |
220 return runTestWithFlags(TestName, true, false, false); | |
221 } | |
222 | |
223 /// Same as runTest, but only print out assembly and errors. | |
224 bool runTestForAssembly(const char *TestName) { | |
225 return runTestWithFlags(TestName, true, true, false); | |
226 } | |
227 | |
228 /// Same as runTest, but only generate error messages. | |
229 bool runTestForErrors(const char *TestName) { | |
230 return runTestWithFlags(TestName, true, true, true); | |
231 } | |
232 | |
233 /// Runs function llvm::NaClObjDump on the sequence of records | |
234 /// associated with the instance. Array Munges contains the sequence | |
235 /// of edits to apply to the sequence of records when generating the | |
236 /// bitsequence in a memory buffer. This generated bitsequence is | |
237 /// then passed to NaClObjDump. TestName is the name associated | |
238 /// with the memory buffer. Arguments NoRecords and NoAssembly are | |
239 /// passed to NaClObjDump. Returns true if test succeeds without | |
240 /// errors. | |
241 bool runTestWithFlags(const char* TestName, const uint64_t Munges[], | |
242 size_t MungesSize, bool AddHeader, | |
243 bool NoRecords, bool NoAssembly); | |
244 | |
245 /// Same as above except it runs function NaClObjDump with flags | |
246 /// NoRecords and NoAssembly set to false, and AddHeader set to | |
247 /// true. | |
248 bool runTest(const char* TestName, const uint64_t Munges[], | |
249 size_t MungesSize) { | |
250 return runTestWithFlags(TestName, Munges, MungesSize, true, false, false); | |
251 } | |
252 | |
253 bool runTestForAssembly(const char* TestName, const uint64_t Munges[], | |
254 size_t MungesSize) { | |
255 return runTestWithFlags(TestName, Munges, MungesSize, true, true, false); | |
256 } | |
257 | |
258 bool runTestForErrors(const char* TestName, const uint64_t Munges[], | |
259 size_t MungesSize) { | |
260 return runTestWithFlags(TestName, Munges, MungesSize, true, true, true); | |
261 } | |
262 }; | |
263 | |
264 // Class to run tests for function NaClParseBitcodeFile. | |
265 // TODO(kschimpf) Capture verbose errors when parsing bitcode file. | |
266 class NaClParseBitcodeMunger : public NaClBitcodeMunger { | |
267 public: | |
268 NaClParseBitcodeMunger(const uint64_t Records[], size_t RecordsSize, | |
269 uint64_t RecordTerminator) | |
270 : NaClBitcodeMunger(Records, RecordsSize, RecordTerminator) {} | |
271 | |
272 /// Runs function llvm::NaClParseBitcodeFile, and puts error messages | |
273 /// into DumpResults. Returns true if parse is successful. | |
274 bool runTest(const char* TestName, const uint64_t Munges[], | |
275 size_t MungesSize, bool VerboseErrors); | |
276 | |
277 // Same as above, but without any edits. | |
278 bool runTest(const char* TestName, bool VerboseErrors) { | |
279 uint64_t NoMunges[] = {0}; | |
280 return runTest(TestName, NoMunges, 0, VerboseErrors); | |
281 } | |
282 }; | |
283 | |
242 } // end namespace llvm. | 284 } // end namespace llvm. |
243 | 285 |
244 #endif // LLVM_BITCODE_NACL_NACLBITCODEMUNGE_H | 286 #endif // LLVM_BITCODE_NACL_NACLBITCODEMUNGE_H |
OLD | NEW |