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

Side by Side Diff: src/trusted/validator/x86/testing/enuminsts/nacl_tester.c

Issue 9861030: Modify enuminsts to be able to communicate matched instructions accross (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client/
Patch Set: Created 8 years, 8 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 /* 7 /*
8 * nacl_tester.c 8 * nacl_tester.c
9 * Uses the NaCl x86 validator/decoder to implement a NaClEnumeratorDecoder. 9 * Uses the NaCl x86 validator/decoder to implement a NaClEnumeratorDecoder.
10 */ 10 */
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 /* If non-empty, stores the operands of the corresponding instruction. */ 42 /* If non-empty, stores the operands of the corresponding instruction. */
43 char _operands[kBufferSize]; 43 char _operands[kBufferSize];
44 /* True if we should translate special opcodes to matching xed nops. */ 44 /* True if we should translate special opcodes to matching xed nops. */
45 Bool _translate_to_xed_nops; 45 Bool _translate_to_xed_nops;
46 /* True if we shouldn't accept instructions that aren't also implemented 46 /* True if we shouldn't accept instructions that aren't also implemented
47 * in xed. 47 * in xed.
48 */ 48 */
49 Bool _ignore_instructions_not_xed_implemented; 49 Bool _ignore_instructions_not_xed_implemented;
50 } nacl_decoder; 50 } nacl_decoder;
51 51
52 static Bool IsInstLegal(NaClEnumerator *enumerator) { 52 static Bool IsInstLegal(const NaClEnumerator *enumerator) {
53 return !nacl_decoder._ignore_instruction && 53 return !nacl_decoder._ignore_instruction &&
54 NaClInstDecodesCorrectly(nacl_decoder._inst); 54 NaClInstDecodesCorrectly(nacl_decoder._inst);
55 } 55 }
56 56
57 /* Instructions we assume that the NaCl validator accept and are valid, but 57 /* Instructions we assume that the NaCl validator accept and are valid, but
58 * are not legal according to xed. 58 * are not legal according to xed.
59 */ 59 */
60 static Bool NaClIsntXedImplemented(NaClEnumerator *enumerator) { 60 static Bool NaClIsntXedImplemented(const NaClEnumerator *enumerator) {
61 static const char* nacl_but_not_xed[] = { 61 static const char* nacl_but_not_xed[] = {
62 "Pf2iw", 62 "Pf2iw",
63 "Pf2id" 63 "Pf2id"
64 }; 64 };
65 const char* name = NaClOpcodeName(nacl_decoder._inst); 65 const char* name = NaClOpcodeName(nacl_decoder._inst);
66 int i; 66 int i;
67 for (i = 0; i < NACL_ARRAY_SIZE(nacl_but_not_xed); ++i) { 67 for (i = 0; i < NACL_ARRAY_SIZE(nacl_but_not_xed); ++i) {
68 if (0 == strcmp(name, nacl_but_not_xed[i])) { 68 if (0 == strcmp(name, nacl_but_not_xed[i])) {
69 return TRUE; 69 return TRUE;
70 } 70 }
71 } 71 }
72 return FALSE; 72 return FALSE;
73 } 73 }
74 74
75 /* Defines the funcdtion to parse the first instruction. */ 75 /* Defines the funcdtion to parse the first instruction. */
76 static void ParseInst(NaClEnumerator* enumerator, int pc_address) { 76 static void ParseInst(const NaClEnumerator* enumerator,
77 const int pc_address) {
77 nacl_decoder._inst = NULL; 78 nacl_decoder._inst = NULL;
78 nacl_decoder._ignore_instruction = FALSE; 79 nacl_decoder._ignore_instruction = FALSE;
79 nacl_decoder._pc_address = pc_address; 80 nacl_decoder._pc_address = pc_address;
80 nacl_decoder._disassembly[0] = 0; 81 nacl_decoder._disassembly[0] = 0;
81 nacl_decoder._simplified_disassembly[0] = 0; 82 nacl_decoder._simplified_disassembly[0] = 0;
82 nacl_decoder._mnemonic[0] = 0; 83 nacl_decoder._mnemonic[0] = 0;
83 nacl_decoder._mnemonic_lower[0] = 0; 84 nacl_decoder._mnemonic_lower[0] = 0;
84 nacl_decoder._operands[0] = 0; 85 nacl_decoder._operands[0] = 0;
85 nacl_decoder._inst = 86 nacl_decoder._inst =
86 NaClParseInst(enumerator->_itext, enumerator->_num_bytes, pc_address); 87 NaClParseInst((char*) enumerator->_itext,
88 enumerator->_num_bytes, pc_address);
87 if (nacl_decoder._ignore_instructions_not_xed_implemented && 89 if (nacl_decoder._ignore_instructions_not_xed_implemented &&
88 IsInstLegal(enumerator)) { 90 IsInstLegal(enumerator)) {
89 nacl_decoder._ignore_instruction = NaClIsntXedImplemented(enumerator); 91 nacl_decoder._ignore_instruction = NaClIsntXedImplemented(enumerator);
90 } 92 }
91 } 93 }
92 94
93 95
94 /* Returns the disassembled instruction. */ 96 /* Returns the disassembled instruction. */
95 static const char* Disassemble(NaClEnumerator* enumerator) { 97 static const char* Disassemble(const NaClEnumerator* enumerator) {
96 char* stmp; 98 char* stmp;
97 99
98 /* First see if we have cached it. If so, return it. */ 100 /* First see if we have cached it. If so, return it. */
99 if (nacl_decoder._disassembly[0] != 0) return nacl_decoder._disassembly; 101 if (nacl_decoder._disassembly[0] != 0) return nacl_decoder._disassembly;
100 102
101 stmp = NaClInstToStr(nacl_decoder._inst); 103 stmp = NaClInstToStr(nacl_decoder._inst);
102 cstrncpy(nacl_decoder._disassembly, stmp, kBufferSize); 104 cstrncpy(nacl_decoder._disassembly, stmp, kBufferSize);
103 free(stmp); 105 free(stmp);
104 return nacl_decoder._disassembly; 106 return nacl_decoder._disassembly;
105 } 107 }
106 108
107 /* Returns the lower case name of the instruction. */ 109 /* Returns the lower case name of the instruction. */
108 static const char* GetInstMnemonicLower(NaClEnumerator* enumerator) { 110 static const char* GetInstMnemonicLower(const NaClEnumerator* enumerator) {
109 char mnemonic[kBufferSize]; 111 char mnemonic[kBufferSize];
110 size_t i; 112 size_t i;
111 113
112 if (nacl_decoder._mnemonic_lower[0] != 0) return nacl_decoder._mnemonic_lower; 114 if (nacl_decoder._mnemonic_lower[0] != 0) return nacl_decoder._mnemonic_lower;
113 115
114 cstrncpy(mnemonic, NaClOpcodeName(nacl_decoder._inst), kBufferSize); 116 cstrncpy(mnemonic, NaClOpcodeName(nacl_decoder._inst), kBufferSize);
115 for (i = 0; i < kBufferSize; ++i) { 117 for (i = 0; i < kBufferSize; ++i) {
116 mnemonic[i] = tolower(mnemonic[i]); 118 mnemonic[i] = tolower(mnemonic[i]);
117 if (mnemonic[i] == '\0') break; 119 if (mnemonic[i] == '\0') break;
118 } 120 }
119 cstrncpy(nacl_decoder._mnemonic_lower, mnemonic, kBufferSize); 121 cstrncpy(nacl_decoder._mnemonic_lower, mnemonic, kBufferSize);
120 return nacl_decoder._mnemonic_lower; 122 return nacl_decoder._mnemonic_lower;
121 } 123 }
122 124
123 /* Defines nacl/xed mnemonic renaming pairs. */ 125 /* Defines nacl/xed mnemonic renaming pairs. */
124 typedef struct { 126 typedef struct {
125 const char* nacl_name; 127 const char* nacl_name;
126 const char* xed_name; 128 const char* xed_name;
127 } NaClToXedPairs; 129 } NaClToXedPairs;
128 130
129 /* Returns the disassembled instruction with the opcode byte sequence 131 /* Returns the disassembled instruction with the opcode byte sequence
130 * removed. 132 * removed.
131 */ 133 */
132 static const char* SimplifiedDisassembly(NaClEnumerator *enumerator) { 134 static const char* SimplifiedDisassembly(const NaClEnumerator *enumerator) {
133 const char* disassembly; 135 const char* disassembly;
134 const char* mnemonic; 136 const char* mnemonic;
135 const char* start; 137 const char* start;
136 138
137 /* First see if we have cache it. If so, return it. */ 139 /* First see if we have cache it. If so, return it. */
138 if (nacl_decoder._simplified_disassembly[0] != 0) 140 if (nacl_decoder._simplified_disassembly[0] != 0)
139 return nacl_decoder._simplified_disassembly; 141 return nacl_decoder._simplified_disassembly;
140 142
141 /* Take first guess of simplified assembly. */ 143 /* Take first guess of simplified assembly. */
142 /* Find start of instruction mnemonic, and define as start of simplified 144 /* Find start of instruction mnemonic, and define as start of simplified
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 cstrncpy(nacl_decoder._simplified_disassembly, 176 cstrncpy(nacl_decoder._simplified_disassembly,
175 pairs[i].xed_name, kBufferSize); 177 pairs[i].xed_name, kBufferSize);
176 cstrncpy(nacl_decoder._mnemonic, pairs[i].xed_name, kBufferSize); 178 cstrncpy(nacl_decoder._mnemonic, pairs[i].xed_name, kBufferSize);
177 return; 179 return;
178 } 180 }
179 } 181 }
180 } 182 }
181 } 183 }
182 184
183 /* Returns the mnemonic name for the disassembled instruction. */ 185 /* Returns the mnemonic name for the disassembled instruction. */
184 static const char* GetInstMnemonic(NaClEnumerator* enumerator) { 186 static const char* GetInstMnemonic(const NaClEnumerator* enumerator) {
185 char mnemonic[kBufferSize]; 187 char mnemonic[kBufferSize];
186 const char* disassembly; 188 const char* disassembly;
187 189
188 /* First see if we have cached it. If so, return it. */ 190 /* First see if we have cached it. If so, return it. */
189 if (nacl_decoder._mnemonic[0] != 0) return nacl_decoder._mnemonic; 191 if (nacl_decoder._mnemonic[0] != 0) return nacl_decoder._mnemonic;
190 192
191 /* Force simplifications if needed. Use mnemonic if defined. */ 193 /* Force simplifications if needed. Use mnemonic if defined. */
192 disassembly = SimplifiedDisassembly(enumerator); 194 disassembly = SimplifiedDisassembly(enumerator);
193 if (nacl_decoder._mnemonic[0] != 0) return nacl_decoder._mnemonic; 195 if (nacl_decoder._mnemonic[0] != 0) return nacl_decoder._mnemonic;
194 196
(...skipping 22 matching lines...) Expand all
217 } 219 }
218 220
219 /* Install mnemonic and return. */ 221 /* Install mnemonic and return. */
220 cstrncpy(nacl_decoder._mnemonic, mnemonic, kBufferSize); 222 cstrncpy(nacl_decoder._mnemonic, mnemonic, kBufferSize);
221 return nacl_decoder._mnemonic; 223 return nacl_decoder._mnemonic;
222 } 224 }
223 225
224 /* Returns the text for the operands. To be used by the driver 226 /* Returns the text for the operands. To be used by the driver
225 * to compare accross decoders. 227 * to compare accross decoders.
226 */ 228 */
227 static const char* GetInstOperandsText(NaClEnumerator* enumerator) { 229 static const char* GetInstOperandsText(const NaClEnumerator* enumerator) {
228 char sbuf[kBufferSize]; 230 char sbuf[kBufferSize];
229 char operands[kBufferSize]; 231 char operands[kBufferSize];
230 const char* disassembly; 232 const char* disassembly;
231 const char* after_mnemonic; 233 const char* after_mnemonic;
232 234
233 /* First see if we have cached it. If so, return it. */ 235 /* First see if we have cached it. If so, return it. */
234 if (nacl_decoder._operands[0] != 0) return nacl_decoder._operands; 236 if (nacl_decoder._operands[0] != 0) return nacl_decoder._operands;
235 237
236 disassembly = SimplifiedDisassembly(enumerator); 238 disassembly = SimplifiedDisassembly(enumerator);
237 after_mnemonic = strskip(disassembly, GetInstMnemonicLower(enumerator)); 239 after_mnemonic = strskip(disassembly, GetInstMnemonicLower(enumerator));
238 if (NULL == after_mnemonic) after_mnemonic = disassembly; 240 if (NULL == after_mnemonic) after_mnemonic = disassembly;
239 cstrncpy(operands, after_mnemonic, kBufferSize); 241 cstrncpy(operands, after_mnemonic, kBufferSize);
240 strnzapchar(operands, '%'); 242 strnzapchar(operands, '%');
241 strnzapchar(operands, '\n'); 243 strnzapchar(operands, '\n');
242 cstrncpy(nacl_decoder._operands, strip(operands), kBufferSize); 244 cstrncpy(nacl_decoder._operands, strip(operands), kBufferSize);
243 return nacl_decoder._operands; 245 return nacl_decoder._operands;
244 } 246 }
245 247
246 /* Prints out the disassembled instruction. */ 248 /* Prints out the disassembled instruction. */
247 static void PrintInst(NaClEnumerator* enumerator) { 249 static void PrintInst(const NaClEnumerator* enumerator) {
248 int i; 250 printf(" NaCl: %s", Disassemble(enumerator));
249 uint8_t length = NaClInstLength(nacl_decoder._inst);
250 if (enumerator->_print_opcode_bytes_only) {
251 for (i = 0; i < length; ++i) {
252 printf("%02x", enumerator->_itext[i]);
253 }
254 printf("\n");
255 } else {
256 if (enumerator->_print_enumerated_instruction) {
257 for (i = 0; i < length; ++i) {
258 printf("%02x ", enumerator->_itext[i]);
259 }
260 printf("#%s %s\n", GetInstMnemonic(enumerator),
261 GetInstOperandsText(enumerator));
262 } else {
263 printf(" NaCl: %s", Disassemble(enumerator));
264 }
265 }
266 } 251 }
267 252
268 /* Returns the number of bytes in the disassembled instruction. */ 253 /* Returns the number of bytes in the disassembled instruction. */
269 static size_t InstLength(NaClEnumerator* enumerator) { 254 static size_t InstLength(const NaClEnumerator* enumerator) {
270 return (size_t) NaClInstLength(nacl_decoder._inst); 255 return (size_t) NaClInstLength(nacl_decoder._inst);
271 } 256 }
272 257
273 /* Returns true if the instruction decodes, and static (single instruction) 258 /* Returns true if the instruction decodes, and static (single instruction)
274 * validator tests pass. 259 * validator tests pass.
275 */ 260 */
276 static Bool MaybeInstValidates(NaClEnumerator *enumerator) { 261 static Bool MaybeInstValidates(const NaClEnumerator *enumerator) {
277 return NaClInstValidates(enumerator->_itext, 262 return NaClInstValidates((char*) enumerator->_itext,
278 NaClInstLength(nacl_decoder._inst), 263 NaClInstLength(nacl_decoder._inst),
279 nacl_decoder._pc_address, 264 nacl_decoder._pc_address,
280 nacl_decoder._inst); 265 nacl_decoder._inst);
281 } 266 }
282 267
283 /* Runs the validator on the given code segment. */ 268 /* Runs the validator on the given code segment. */
284 static Bool SegmentValidates(NaClEnumerator *enumerator, 269 static Bool SegmentValidates(const NaClEnumerator *enumerator,
285 uint8_t* segment, 270 const uint8_t* segment,
286 size_t size, 271 const size_t size,
287 int pc_address) { 272 const int pc_address) {
288 return NaClSegmentValidates(segment, size, pc_address); 273 return NaClSegmentValidates((uint8_t*) segment, size, pc_address);
289 } 274 }
290 275
291 /* Installs NaCl-specific flags. */ 276 /* Installs NaCl-specific flags. */
292 static void InstallFlag(NaClEnumerator* enumerator, 277 static void InstallFlag(const NaClEnumerator* enumerator,
293 const char* flag_name, 278 const char* flag_name,
294 void* flag_address) { 279 const void* flag_address) {
295 if (0 == strcmp(flag_name, "--nops")) { 280 if (0 == strcmp(flag_name, "--nops")) {
296 nacl_decoder._translate_to_xed_nops = *((Bool*) flag_address); 281 nacl_decoder._translate_to_xed_nops = *((Bool*) flag_address);
297 } else if (0 == strcmp(flag_name, "--xedimplemented")) { 282 } else if (0 == strcmp(flag_name, "--xedimplemented")) {
298 nacl_decoder._ignore_instructions_not_xed_implemented = 283 nacl_decoder._ignore_instructions_not_xed_implemented =
299 *((Bool*) flag_address); 284 *((Bool*) flag_address);
300 } 285 }
301 } 286 }
302 287
303 /* Generates a decoder for the (sel_ldr) nacl validator. */ 288 /* Generates a decoder for the (sel_ldr) nacl validator. */
304 NaClEnumeratorDecoder* RegisterNaClDecoder() { 289 NaClEnumeratorDecoder* RegisterNaClDecoder() {
305 nacl_decoder._base._id_name = "nacl"; 290 nacl_decoder._base._id_name = "nacl";
306 nacl_decoder._base._legal_only = TRUE;
307 nacl_decoder._base._print_only = FALSE;
308 nacl_decoder._base._parse_inst_fn = ParseInst; 291 nacl_decoder._base._parse_inst_fn = ParseInst;
309 nacl_decoder._base._inst_length_fn = InstLength; 292 nacl_decoder._base._inst_length_fn = InstLength;
310 nacl_decoder._base._print_inst_fn = PrintInst; 293 nacl_decoder._base._print_inst_fn = PrintInst;
311 nacl_decoder._base._get_inst_mnemonic_fn = GetInstMnemonic; 294 nacl_decoder._base._get_inst_mnemonic_fn = GetInstMnemonic;
312 nacl_decoder._base._get_inst_num_operands_fn = NULL; 295 nacl_decoder._base._get_inst_num_operands_fn = NULL;
313 nacl_decoder._base._get_inst_operands_text_fn = GetInstOperandsText; 296 nacl_decoder._base._get_inst_operands_text_fn = GetInstOperandsText;
314 nacl_decoder._base._writes_to_reserved_reg_fn = NULL; 297 nacl_decoder._base._writes_to_reserved_reg_fn = NULL;
315 nacl_decoder._base._is_inst_legal_fn = IsInstLegal; 298 nacl_decoder._base._is_inst_legal_fn = IsInstLegal;
316 nacl_decoder._base._maybe_inst_validates_fn = MaybeInstValidates; 299 nacl_decoder._base._maybe_inst_validates_fn = MaybeInstValidates;
317 nacl_decoder._base._segment_validates_fn = SegmentValidates; 300 nacl_decoder._base._segment_validates_fn = SegmentValidates;
318 nacl_decoder._base._install_flag_fn = InstallFlag; 301 nacl_decoder._base._install_flag_fn = InstallFlag;
319 nacl_decoder._base._usage_message = 302 nacl_decoder._base._usage_message =
320 "Runs nacl decoder to decode instructions"; 303 "Runs nacl decoder to decode instructions";
321 return &nacl_decoder._base; 304 return &nacl_decoder._base;
322 } 305 }
OLDNEW
« no previous file with comments | « src/trusted/validator/x86/testing/enuminsts/input_tester.c ('k') | src/trusted/validator/x86/testing/enuminsts/str_utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698