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

Side by Side Diff: src/trusted/validator_ragel/unreviewed/validator_test.c

Issue 11418063: Validator_ragel: get rid of validator_test.c (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Created 8 years, 1 month 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
« no previous file with comments | « src/trusted/validator_ragel/build.scons ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include <assert.h>
8 #include <stdio.h>
9 #include <stddef.h>
10 #include <stdlib.h>
11 #include <string.h>
12
13 #include "native_client/src/include/elf32.h"
14 #include "native_client/src/include/elf64.h"
15 #include "native_client/src/shared/platform/nacl_check.h"
16 #include "native_client/src/shared/utils/types.h"
17 #include "native_client/src/trusted/validator_ragel/unreviewed/validator_interna l.h"
18
19 /* This is a copy of NaClLog from shared/platform/nacl_log.c to avoid
20 * linking in code in NaCl shared code in the unreviewed/Makefile and be able to
21 * use CHECK().
22
23 * TODO(khim): remove the copy of NaClLog implementation as soon as
24 * unreviewed/Makefile is eliminated.
25 */
26 void NaClLog(int detail_level, char const *fmt, ...) {
27 va_list ap;
28
29 UNREFERENCED_PARAMETER(detail_level);
30 va_start(ap, fmt);
31 vfprintf(stderr, fmt, ap);
32 exit(1);
33 }
34
35 static void CheckBounds(const unsigned char *data, size_t data_size,
36 const void *ptr, size_t inside_size) {
37 CHECK(data <= (const unsigned char *) ptr);
38 CHECK((const unsigned char *) ptr + inside_size <= data + data_size);
39 }
40
41 void ReadImage(const char *filename, uint8_t **result, size_t *result_size) {
42 FILE *fp;
43 uint8_t *data;
44 size_t file_size;
45 size_t got;
46
47 fp = fopen(filename, "rb");
48 if (fp == NULL) {
49 fprintf(stderr, "Failed to open input file: %s\n", filename);
50 exit(1);
51 }
52 /* Find the file size. */
53 fseek(fp, 0, SEEK_END);
54 file_size = ftell(fp);
55 data = malloc(file_size);
56 if (data == NULL) {
57 fprintf(stderr, "Unable to create memory image of input file: %s\n",
58 filename);
59 exit(1);
60 }
61 fseek(fp, 0, SEEK_SET);
62 got = fread(data, 1, file_size, fp);
63 if (got != file_size) {
64 fprintf(stderr, "Unable to read data from input file: %s\n",
65 filename);
66 exit(1);
67 }
68 fclose(fp);
69
70 *result = data;
71 *result_size = file_size;
72 }
73
74 struct ValidateState {
75 uint8_t width;
76 const uint8_t *offset;
77 };
78
79 Bool ProcessError(const uint8_t *begin, const uint8_t *end,
80 uint32_t error_code, void *userdata) {
81 size_t offset = begin - (((struct ValidateState *)userdata)->offset);
82 UNREFERENCED_PARAMETER(end);
83
84 if (error_code & UNRECOGNIZED_INSTRUCTION)
85 printf("offset 0x%"NACL_PRIxS": unrecognized instruction\n", offset);
86 if (error_code & DIRECT_JUMP_OUT_OF_RANGE)
87 printf("offset 0x%"NACL_PRIxS": direct jump out of range\n", offset);
88 if (error_code & CPUID_UNSUPPORTED_INSTRUCTION)
89 printf("offset 0x%"NACL_PRIxS": required CPU feature not found\n", offset);
90 if (error_code & FORBIDDEN_BASE_REGISTER)
91 printf("offset 0x%"NACL_PRIxS": improper memory address - bad base\n",
92 offset);
93 if (error_code & UNRESTRICTED_INDEX_REGISTER)
94 printf("offset 0x%"NACL_PRIxS": improper memory address - bad index\n",
95 offset);
96 if ((error_code & BAD_RSP_RBP_PROCESSING_MASK) == RESTRICTED_RBP_UNPROCESSED)
97 printf("offset 0x%"NACL_PRIxS": improper %%rbp sandboxing\n", offset);
98 if ((error_code & BAD_RSP_RBP_PROCESSING_MASK) == UNRESTRICTED_RBP_PROCESSED)
99 printf("offset 0x%"NACL_PRIxS": improper %%rbp sandboxing\n", offset);
100 if ((error_code & BAD_RSP_RBP_PROCESSING_MASK) == RESTRICTED_RSP_UNPROCESSED)
101 printf("offset 0x%"NACL_PRIxS": improper %%rsp sandboxing\n", offset);
102 if ((error_code & BAD_RSP_RBP_PROCESSING_MASK) == UNRESTRICTED_RSP_PROCESSED)
103 printf("offset 0x%"NACL_PRIxS": improper %%rsp sandboxing\n", offset);
104 if (error_code & R15_MODIFIED)
105 printf("offset 0x%"NACL_PRIxS": error - %%r15 is changed\n", offset);
106 if (error_code & BPL_MODIFIED)
107 printf("offset 0x%"NACL_PRIxS": error - %%bpl or %%bp is changed\n",
108 offset);
109 if (error_code & SPL_MODIFIED)
110 printf("offset 0x%"NACL_PRIxS": error - %%spl or %%sp is changed\n",
111 offset);
112 if (error_code & BAD_JUMP_TARGET)
113 printf("bad jump to around 0x%"NACL_PRIxS"\n", offset);
114 if (error_code & (VALIDATION_ERRORS_MASK | BAD_JUMP_TARGET))
115 return FALSE;
116 else
117 return TRUE;
118 }
119
120 Bool ProcessErrorOrWarning(const uint8_t *begin, const uint8_t *end,
121 uint32_t error_code, void *userdata) {
122 size_t offset = begin - (((struct ValidateState *)userdata)->offset);
123 UNREFERENCED_PARAMETER(end);
124
125 if (error_code & BAD_CALL_ALIGNMENT)
126 printf("offset 0x%"NACL_PRIxS": warning - bad call alignment\n", offset);
127 return ProcessError(begin, end, error_code, userdata);
128 }
129
130 Bool ValidateElf32(const uint8_t *data, size_t data_size,
131 Bool warnings,
132 uint32_t options,
133 const NaClCPUFeaturesX86 *cpu_features) {
134 Elf32_Ehdr *header;
135 int index;
136
137 header = (Elf32_Ehdr *) data;
138 CheckBounds(data, data_size, header, sizeof *header);
139 assert(memcmp(header->e_ident, ELFMAG, strlen(ELFMAG)) == 0);
140
141 for (index = 0; index < header->e_shnum; ++index) {
142 Elf32_Shdr *section = (Elf32_Shdr *) (data + header->e_shoff +
143 header->e_shentsize * index);
144 CheckBounds(data, data_size, section, sizeof *section);
145
146 if ((section->sh_flags & SHF_EXECINSTR) != 0) {
147 struct ValidateState state;
148 Bool res;
149
150 state.offset = data + section->sh_offset - section->sh_addr;
151 if (section->sh_size <= 0xfff) {
152 state.width = 4;
153 } else if (section->sh_size <= 0xfffffff) {
154 state.width = 8;
155 } else {
156 state.width = 12;
157 }
158 CheckBounds(data, data_size,
159 data + section->sh_offset, section->sh_size);
160 res = ValidateChunkIA32(data + section->sh_offset, section->sh_size,
161 options, cpu_features,
162 warnings ? ProcessErrorOrWarning : ProcessError,
163 &state);
164 if (!res)
165 return res;
166 }
167 }
168 return TRUE;
169 }
170
171 Bool ValidateElf64(const uint8_t *data, size_t data_size,
172 Bool warnings,
173 uint32_t options,
174 const NaClCPUFeaturesX86 *cpu_features) {
175 Elf64_Ehdr *header;
176 int index;
177
178 header = (Elf64_Ehdr *) data;
179 CheckBounds(data, data_size, header, sizeof *header);
180 assert(memcmp(header->e_ident, ELFMAG, strlen(ELFMAG)) == 0);
181
182 for (index = 0; index < header->e_shnum; ++index) {
183 Elf64_Shdr *section = (Elf64_Shdr *) (data + header->e_shoff +
184 header->e_shentsize * index);
185 CheckBounds(data, data_size, section, sizeof *section);
186
187 if ((section->sh_flags & SHF_EXECINSTR) != 0) {
188 struct ValidateState state;
189 Bool res;
190
191 state.offset = data + section->sh_offset - section->sh_addr;
192 if (section->sh_size <= 0xfff) {
193 state.width = 4;
194 } else if (section->sh_size <= 0xfffffff) {
195 state.width = 8;
196 } else if (section->sh_size <= 0xfffffffffffLL) {
197 state.width = 12;
198 } else {
199 state.width = 16;
200 }
201 CheckBounds(data, data_size,
202 data + section->sh_offset, (size_t)section->sh_size);
203 res = ValidateChunkAMD64(data + section->sh_offset,
204 (size_t)section->sh_size,
205 options, cpu_features,
206 warnings ? ProcessErrorOrWarning : ProcessError,
207 &state);
208 if (!res)
209 return res;
210 }
211 }
212 return TRUE;
213 }
214
215 Bool ValidateElf(const char *filename,
216 const uint8_t *data, size_t data_size,
217 Bool warnings,
218 uint32_t options,
219 const NaClCPUFeaturesX86 *cpu_features) {
220 if (data[4] == 1) {
221 return ValidateElf32(data, data_size, warnings, options, cpu_features);
222 } else if (data[4] == 2) {
223 return ValidateElf64(data, data_size, warnings, options, cpu_features);
224 } else {
225 printf("Unknown ELF class: %s\n", filename);
226 exit(1);
227 }
228 }
229
230 void ProcessFile(const char *filename,
231 int repeat_count,
232 int raw_bitness,
233 Bool warnings,
234 uint32_t options,
235 const NaClCPUFeaturesX86 *cpu_features) {
236 size_t data_size;
237 uint8_t *data;
238 int count;
239
240 ReadImage(filename, &data, &data_size);
241
242 for (count = 0; count < repeat_count; ++count) {
243 Bool rc = FALSE;
244 if (raw_bitness == 0)
245 rc = ValidateElf(filename,
246 data, data_size,
247 warnings,
248 options,
249 cpu_features);
250 else if (raw_bitness == 32) {
251 struct ValidateState state;
252 state.offset = data;
253 CHECK(data_size % kBundleSize == 0);
254 rc = ValidateChunkIA32(data, data_size,
255 options, cpu_features,
256 warnings ? ProcessErrorOrWarning : ProcessError,
257 &state);
258 }
259 else if (raw_bitness == 64) {
260 struct ValidateState state;
261 state.offset = data;
262 CHECK(data_size % kBundleSize == 0);
263 rc = ValidateChunkAMD64(data, data_size,
264 options, cpu_features,
265 warnings ? ProcessErrorOrWarning : ProcessError,
266 &state);
267 }
268 if (!rc) {
269 printf("file '%s' can not be fully validated\n", filename);
270 exit(1);
271 }
272 }
273 }
274
275 int main(int argc, char **argv) {
276 int index, initial_index = 1, repeat_count = 1;
277 const NaClCPUFeaturesX86 *cpu_features = &kFullCPUIDFeatures;
278 int raw_bitness = 0;
279 Bool warnings = FALSE;
280 uint32_t options = 0;
281
282 if (argc == 1) {
283 printf("%s: no input files\n", argv[0]);
284 return 2;
285 }
286 while (initial_index < argc) {
287 char *arg = argv[initial_index];
288 if (!strcmp(arg, "--compatible")) {
289 cpu_features = &kValidatorCPUIDFeatures;
290 initial_index++;
291 } else if (!strcmp(argv[initial_index], "--warnings")) {
292 warnings = TRUE;
293 options |= CALL_USER_CALLBACK_ON_EACH_INSTRUCTION;
294 initial_index++;
295 } else if (!strcmp(arg, "--nobundles")) {
296 options |= PROCESS_CHUNK_AS_A_CONTIGUOUS_STREAM;
297 initial_index++;
298 } else if (!strcmp(arg, "--repeat")) {
299 if (initial_index+1 >= argc) {
300 printf("%s: no integer after --repeat\n", argv[0]);
301 return 2;
302 }
303 repeat_count = atoi(argv[initial_index + 1]);
304 initial_index += 2;
305 } else if (!strcmp(argv[initial_index], "--raw32")) {
306 raw_bitness = 32;
307 initial_index++;
308 } else if (!strcmp(argv[initial_index], "--raw64")) {
309 raw_bitness = 64;
310 initial_index++;
311 } else {
312 break;
313 }
314 }
315 for (index = initial_index; index < argc; ++index) {
316 const char *filename = argv[index];
317 ProcessFile(filename, repeat_count, raw_bitness, warnings, options,
318 cpu_features);
319 }
320 return 0;
321 }
OLDNEW
« no previous file with comments | « src/trusted/validator_ragel/build.scons ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698