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

Side by Side Diff: src/trusted/validator/x86/testing/enuminsts/input_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
(Empty)
1 /*
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
4 * found in the LICENSE file.
5 */
6
7 /*
8 * input_tester.c
9 * Implements a decoder that matches the input enumeration fed into stdin.
10 */
11
12 #include "native_client/src/trusted/validator/x86/testing/enuminsts/input_tester .h"
13
14 #include <stdio.h>
15 #include <string.h>
16
17 #include "native_client/src/trusted/validator/types_memory_model.h"
18 #include "native_client/src/trusted/validator/x86/ncinstbuffer.h"
19 #include "native_client/src/trusted/validator/x86/testing/enuminsts/str_utils.h"
20 #include "native_client/src/trusted/validator/x86/testing/enuminsts/text2hex.h"
21
22 #define kBufferSize 1024
23
24 /* Defines the virtual table for the input decoder. */
25 static struct {
26 /* The virtual table that implements this decoder. */
27 NaClEnumeratorDecoder base_;
28 /* The iput text line. */
29 char line_[kBufferSize];
30 /* The number of bytes in the last instruction read from the
31 * input stream.
32 */
33 int num_bytes_;
34 /* The input line number associated with the last instruction
35 * read from the input stream.
36 */
37 int line_number_;
38 /* The specified pc address when parsing. */
39 NaClPcAddress pc_address_;
40 /* The instruction mnemonic, if defined. */
41 char* mnemonic_;
42 /* The instruction arguments, if defined. */
43 char* operands_;
44 /* Buffer used to hold mnemonic name and operands. */
45 char buffer_[kBufferSize];
46 /* Boolean flag defining if we have processed the first
47 * line of input, which specifies how to configure the
48 * the input decoder.
49 */
50 Bool configured_;
51 } input_decoder;
52
53 /* Defines the function to parse the first instruction in the enumerator
54 * text. Since we are accepting the input that was set up the input
55 * enumeration, there is nothing to do.
56 */
57 static void ParseInst(NaClEnumerator* enumerator, int pc_address) {
Brad Chen 2012/03/28 17:26:43 const int pc_address? What is the enumerator for?
Karl 2012/03/28 18:25:28 It is there because of the API expected by callers
58 input_decoder.pc_address_ = pc_address;
59 input_decoder.mnemonic_ = NULL;
60 input_decoder.operands_ = NULL;
61 }
62
63 /* Finds the instruction mnemonic, by looking at the end of the
64 * input line. Looks for a comment of the form '#mnemonic operands'
65 */
66 static void AssembleDesc(NaClEnumerator* enumerator) {
Brad Chen 2012/03/28 17:26:43 Please make these parameters const if they are not
Karl 2012/03/28 18:25:28 At one time, API functions updated the enumerator.
67 char* desc;
68 char* end;
69 /* Start by looking for description. */
70 desc = (char*) strip(strskip(input_decoder.line_, "#"));
71 if (desc == NULL) {
72 /* Not found, fill in a default value. */
73 input_decoder.mnemonic_ = "???";
74 input_decoder.operands_ = "";
75 return;
76 }
77 /* Copy the description into the buffer, and then extract the needed parts. */
78 cstrncpy(input_decoder.buffer_, desc, kBufferSize);
79 input_decoder.mnemonic_ = input_decoder.buffer_;
80 end = (char*) strfind(input_decoder.buffer_, " ");
81 if (end == NULL) {
82 /* No operands, clean up mnemonic. */
83 rstrip(input_decoder.buffer_);
84 input_decoder.operands_ = "";
85 return;
86 }
87 /* Has mnemonic and operands. Separate out parts. */
88 *end = '\0';
89 input_decoder.operands_ = (char*) strip(end + 1);
90 rstrip(input_decoder.operands_);
91 }
92
93 /* Finds the instruction mnemonic, by looking at the end of the
94 * input line. Looks for a comment of the form '#mnemonic operands'
95 */
96 static const char* GetInstMnemonic(NaClEnumerator* enumerator) {
97 if (input_decoder.mnemonic_ != NULL) return input_decoder.mnemonic_;
98 AssembleDesc(enumerator);
99 return input_decoder.mnemonic_;
100 }
101
102 /* Finst the instruction operands, by looking at the end of the
103 * input line. Looks for a comment of the form '#mnemonic operands'
104 */
105 static const char* GetInstOperandsText(NaClEnumerator* enumerator) {
106 if (input_decoder.operands_ != NULL) return input_decoder.operands_;
107 AssembleDesc(enumerator);
108 return input_decoder.operands_;
109 }
110
111
112 /* Prints out the disassembled instruction. */
113 static void PrintInst(NaClEnumerator* enumerator) {
114 size_t i;
115 const char* desc;
116 size_t num_bytes;
117 printf(" IN: %"NACL_PRIxNaClPcAddressAll": ", input_decoder.pc_address_);
118 for (i = 0; i < input_decoder.num_bytes_; ++i) {
119 printf("%02x ", enumerator->_itext[i]);
120 }
121 for (i = input_decoder.num_bytes_; i < MAX_INST_LENGTH; ++i) {
122 printf(" ");
123 }
124
125 /* Print out decoding if included on the input line. */
126 if (NULL == input_decoder.base_._get_inst_mnemonic_fn) {
127 printf("\n");
128 } else {
129 printf("%s %s\n", GetInstMnemonic(enumerator),
130 GetInstOperandsText(enumerator));
131 }
132 }
133
134 /* Returns true if the instruction parsed a legal instruction. */
135 static Bool IsInstLegal(NaClEnumerator* enumerator) {
136 return TRUE;
137 }
138
139 static size_t InstLength(NaClEnumerator* enumerator) {
140 return (size_t) input_decoder.num_bytes_;
141 }
142
143 static void InstallFlag(NaClEnumerator* enumerator,
144 const char* flag_name,
145 void* flag_address) {
146 }
147
148
149 /* Defines the registry function that creates a input decoder, and returns
150 * the decoder to be registered.
151 */
152 NaClEnumeratorDecoder* RegisterInputDecoder() {
153 input_decoder.base_._id_name = "in";
154 input_decoder.base_._legal_only = TRUE;
155 input_decoder.base_._parse_inst_fn = ParseInst;
156 input_decoder.base_._inst_length_fn = InstLength;
157 input_decoder.base_._print_inst_fn = PrintInst;
158 /* Initially assume that the input doesn't get information on
159 * mnemonic and operand text. Change (in InstallFlag) above if
160 * specified on command line.
161 */
162 input_decoder.base_._get_inst_mnemonic_fn = NULL;
163 input_decoder.base_._get_inst_num_operands_fn = NULL;
164 input_decoder.base_._get_inst_operands_text_fn = NULL;
165 input_decoder.base_._writes_to_reserved_reg_fn = NULL;
166 input_decoder.base_._is_inst_legal_fn = IsInstLegal;
167 input_decoder.base_._maybe_inst_validates_fn = NULL;
168 input_decoder.base_._segment_validates_fn = NULL;
169 input_decoder.base_._install_flag_fn = InstallFlag;
170 input_decoder.base_._usage_message = "Defines legal instructions from stdin";
171 input_decoder.num_bytes_ = 0;
172 input_decoder.line_number_ = 0;
173 input_decoder.pc_address_ = 0;
174 input_decoder.mnemonic_ = NULL;
175 input_decoder.operands_ = NULL;
176 input_decoder.configured_ = FALSE;
177 return &input_decoder.base_;
178 }
179
180 int ReadAnInstruction(uint8_t ibytes[NACL_ENUM_MAX_INSTRUCTION_BYTES]) {
Brad Chen 2012/03/28 17:26:43 Would a typedef for this array make this code clea
Karl 2012/03/28 18:25:28 Done.
181 input_decoder.num_bytes_ = 0;
182 while (input_decoder.num_bytes_ == 0) {
183 ++input_decoder.line_number_;
184 if (fgets(input_decoder.line_, kBufferSize, stdin) == NULL) return 0;
185
186 /* If the line specifies that the input has opcode sequences plus
187 * descriptions, then install the virtuals to handle the input.
188 */
189 if (!input_decoder.configured_) {
190 if (input_decoder.line_ ==
191 strstr(input_decoder.line_, "#OPCODEPLUSDESC#")) {
192 input_decoder.base_._get_inst_mnemonic_fn = GetInstMnemonic;
193 input_decoder.base_._get_inst_operands_text_fn = GetInstOperandsText;
194 }
195 input_decoder.configured_ = TRUE;
196 }
197
198 /* If the line is a progress line, print out the corresponding progress
199 * message.
200 */
201 if (input_decoder.line_ == strstr(input_decoder.line_, "#PROGRESS#")) {
202 printf("%s", &input_decoder.line_[strlen("#PROGRESS#")]);
203 }
204
205 /* Finally, convert the input into the corresponding sequence of bytes
206 * that defines the instruction.
207 */
208 input_decoder.num_bytes_ =
209 Text2Bytes(ibytes, input_decoder.line_, "stdin",
210 input_decoder.line_number_);
211 }
212 return input_decoder.num_bytes_;
213 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698