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

Side by Side Diff: include/llvm/Bitcode/NaCl/NaClBitcodeMunge.h

Issue 939073008: Rebased PNaCl localmods in LLVM to 223109 (Closed)
Patch Set: undo localmod Created 5 years, 9 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
OLDNEW
(Empty)
1 //===- NaClBitcodeMunge.h - Bitcode Munger ----------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Test harness for generating a PNaCl bitcode memory buffer from
11 // an array, and parse/objdump the resulting contents.
12 //
13 // Generates a bitcode memory buffer from an array containing 1 or
14 // more PNaCl records. Used to test errors in PNaCl bitcode.
15 //
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"
18 // value is used. This terminator value must be a uint64_t value that
19 // is not used by any of the records.
20 //
21 // A record is defined as a sequence of integers consisting of:
22 // * The abbreviation index associated with the record.
23 // * The record code associated with the record.
24 // * The sequence of values associated with the record code.
25 // * The terminator value.
26 //
27 // Note: Since the header record doesn't have any abbreviation indices
28 // associated with it, one can use any value. The value will simply be
29 // ignored.
30 //
31 // In addition to specifying the sequence of records, one can also
32 // define a sequence of edits to be applied to the original sequence
33 // of records. This allows the same record sequence to be used in
34 // multiple tests.
35 //
36 // An edit consists of:
37 //
38 // * A record number defining where the edit is to be applied.
39 // * An action defining the type of edit.
40 // * An optional record associated with the action.
41 //
42 // Note that edits must be sorted by record number, so that the records
43 // and edits can be processed with a linear pass.
44 //
45 // Generally, you can generate any legal/illegal record
46 // sequence. However, abbreviations are intimately tied to the
47 // internals of the bitstream writer and can't contain illegal
48 // data. Whenever class NaClBitcodeMunger is unable to accept illegal
49 // data, a corresponding "Fatal" error is generated and execution
50 // is terminated.
51 //
52 // ===---------------------------------------------------------------------===//
53
54 #ifndef LLVM_BITCODE_NACL_NACLBITCODEMUNGE_H
55 #define LLVM_BITCODE_NACL_NACLBITCODEMUNGE_H
56
57 #include "llvm/ADT/SmallVector.h"
58 #include "llvm/IR/Module.h"
59 #include "llvm/Support/DataTypes.h"
60 #include "llvm/Support/ErrorHandling.h"
61 #include "llvm/Support/MemoryBuffer.h"
62 #include "llvm/Support/raw_ostream.h"
63
64 #include <string>
65
66 namespace llvm {
67
68 class NaClBitstreamWriter;
69 class NaClBitCodeAbbrev;
70
71 /// Base class to run tests on munged bitcode files.
72 class NaClBitcodeMunger {
73 public:
74 /// The types of editing actions that can be applied.
75 enum EditAction {
76 AddBefore, // Insert record before record with index.
77 AddAfter, // Insert record after record with index.
78 Remove, // Remove record with index.
79 Replace // Replace record with index with specified record.
80 };
81
82 /// Creates a bitcode munger, based on the given array of values.
83 NaClBitcodeMunger(const uint64_t Records[], size_t RecordsSize,
84 uint64_t RecordTerminator)
85 : Records(Records), RecordsSize(RecordsSize),
86 RecordTerminator(RecordTerminator), WriteBlockID(-1), SetBID(-1),
87 DumpResults("Error: No previous dump results!\n"),
88 DumpStream(nullptr), Writer(nullptr), FoundErrors(false),
89 FatalBuffer(), FatalStream(FatalBuffer) {}
90
91 /// Creates MungedInput and DumpStream for running tests, based on
92 /// given Munges.
93 void setupTest(
94 const char *TestName, const uint64_t Munges[], size_t MungesSize,
95 bool AddHeader);
96
97 /// Cleans up state after a test.
98 void cleanupTest();
99
100 /// Returns the resulting string generated by the corresponding test.
101 const std::string &getTestResults() const {
102 return DumpResults;
103 }
104
105 /// Returns the lines containing the given Substring, from the
106 /// string getTestResults().
107 std::string getLinesWithSubstring(const std::string &Substring) const {
108 return getLinesWithTextMatch(Substring, false);
109 }
110
111 /// Returns the lines starting with the given Prefix, from the string
112 /// getTestResults().
113 std::string getLinesWithPrefix(const std::string &Prefix) const {
114 return getLinesWithTextMatch(Prefix, true);
115 }
116
117 protected:
118 // The list of (base) records.
119 const uint64_t *Records;
120 // The number of (base) records.
121 size_t RecordsSize;
122 // The value used as record terminator.
123 uint64_t RecordTerminator;
124 // The block ID associated with the block being written.
125 int WriteBlockID;
126 // The SetBID for the blockinfo block.
127 int SetBID;
128 // The results buffer of the last dump.
129 std::string DumpResults;
130 // The memory buffer containing the munged input.
131 std::unique_ptr<MemoryBuffer> MungedInput;
132 // The stream containing errors and the objdump of the generated bitcode file.
133 raw_ostream *DumpStream;
134 // The bitstream writer to use to generate the bitcode file.
135 NaClBitstreamWriter *Writer;
136 // True if any errors were reported.
137 bool FoundErrors;
138 // The buffer to hold the generated fatal message.
139 std::string FatalBuffer;
140 // The stream to write the fatal message to.
141 raw_string_ostream FatalStream;
142
143 // Records that an error occurred, and returns stream to print error
144 // message to.
145 raw_ostream &Error() {
146 FoundErrors = true;
147 return *DumpStream << "Error: ";
148 }
149
150 // Returns stream to print fatal error message to.
151 // Note: Once the fatal error message has been dumped to the stream,
152 // one must call ReportFatalError to display the error and terminate
153 // execution.
154 raw_ostream &Fatal() {
155 return FatalStream << "Fatal: ";
156 }
157
158 // Displays the fatal error message and exits the program.
159 void ReportFatalError() {
160 report_fatal_error(FatalStream.str());
161 }
162
163 /// Returns the lines containing the given Substring, from the
164 /// string getTestResults(). If MustBePrefix, then Substring must
165 /// match at the beginning of the line.
166 std::string getLinesWithTextMatch(const std::string &Substring,
167 bool MustBePrefix = false) const;
168
169 // Writes out sequence of records, applying the given sequence of
170 // munges.
171 void writeMungedData(const uint64_t Munges[], size_t MungesSize,
172 bool AddHeader);
173
174 // Emits the given record to the bitcode file.
175 void emitRecord(unsigned AbbrevIndex, unsigned RecordCode,
176 SmallVectorImpl<uint64_t> &Values);
177
178 // Converts the abbreviation record to the corresponding abbreviation.
179 NaClBitCodeAbbrev *buildAbbrev(unsigned RecordCode,
180 SmallVectorImpl<uint64_t> &Values);
181
182 // Emits the record at the given Index to the bitcode file. Then
183 // updates Index by one.
184 void emitRecordAtIndex(const uint64_t Record[], size_t RecordSize,
185 size_t &Index);
186
187 // Skips the record starting at Index by advancing Index past the
188 // contents of the record.
189 void deleteRecord(const uint64_t Record[], size_t RecordSize,
190 size_t &Index);
191 };
192
193 /// Class to run tests for function llvm::NaClObjDump.
194 class NaClObjDumpMunger : public NaClBitcodeMunger {
195 public:
196
197 /// Creates a bitcode munger, based on the given array of values.
198 NaClObjDumpMunger(const uint64_t Records[], size_t RecordsSize,
199 uint64_t RecordTerminator)
200 : NaClBitcodeMunger(Records, RecordsSize, RecordTerminator) {}
201
202 /// Runs function NaClObjDump on the sequence of records associated
203 /// with the instance. The memory buffer containing the bitsequence
204 /// associated with the record is automatically generated, and
205 /// passed to NaClObjDump. TestName is the name associated with the
206 /// memory buffer. If AddHeader is true, test assumes that the
207 /// sequence of records doesn't contain a header record, and the
208 /// test should add one. Arguments NoRecords and NoAssembly are
209 /// passed to NaClObjDump. Returns true if test succeeds without
210 /// errors.
211 bool runTestWithFlags(const char *TestName, bool AddHeader,
212 bool NoRecords, bool NoAssembly) {
213 uint64_t NoMunges[] = {0};
214 return runTestWithFlags(TestName, NoMunges, 0, AddHeader, NoRecords,
215 NoAssembly);
216 }
217
218 /// Same as above except it runs function NaClObjDump with flags
219 /// NoRecords and NoAssembly set to false, and AddHeader set to true.
220 bool runTest(const char *TestName) {
221 return runTestWithFlags(TestName, true, false, false);
222 }
223
224 /// Same as runTest, but only print out assembly and errors.
225 bool runTestForAssembly(const char *TestName) {
226 return runTestWithFlags(TestName, true, true, false);
227 }
228
229 /// Same as runTest, but only generate error messages.
230 bool runTestForErrors(const char *TestName) {
231 return runTestWithFlags(TestName, true, true, true);
232 }
233
234 /// Runs function llvm::NaClObjDump on the sequence of records
235 /// associated with the instance. Array Munges contains the sequence
236 /// of edits to apply to the sequence of records when generating the
237 /// bitsequence in a memory buffer. This generated bitsequence is
238 /// then passed to NaClObjDump. TestName is the name associated
239 /// with the memory buffer. Arguments NoRecords and NoAssembly are
240 /// passed to NaClObjDump. Returns true if test succeeds without
241 /// errors.
242 bool runTestWithFlags(const char* TestName, const uint64_t Munges[],
243 size_t MungesSize, bool AddHeader,
244 bool NoRecords, bool NoAssembly);
245
246 /// Same as above except it runs function NaClObjDump with flags
247 /// NoRecords and NoAssembly set to false, and AddHeader set to
248 /// true.
249 bool runTest(const char* TestName, const uint64_t Munges[],
250 size_t MungesSize) {
251 return runTestWithFlags(TestName, Munges, MungesSize, true, false, false);
252 }
253
254 bool runTestForAssembly(const char* TestName, const uint64_t Munges[],
255 size_t MungesSize) {
256 return runTestWithFlags(TestName, Munges, MungesSize, true, true, false);
257 }
258
259 bool runTestForErrors(const char* TestName, const uint64_t Munges[],
260 size_t MungesSize) {
261 return runTestWithFlags(TestName, Munges, MungesSize, true, true, true);
262 }
263 };
264
265 // Class to run tests for function NaClParseBitcodeFile.
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
284 } // end namespace llvm.
285
286 #endif // LLVM_BITCODE_NACL_NACLBITCODEMUNGE_H
OLDNEW
« no previous file with comments | « include/llvm/Bitcode/NaCl/NaClBitcodeHeader.h ('k') | include/llvm/Bitcode/NaCl/NaClBitcodeParser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698