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

Side by Side Diff: src/tools/validator_tools/ncstubout.c

Issue 636933004: stop building/testing old x86 validator. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: rebase master Created 6 years, 2 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 * This tool rewrites ELF files to replace instructions that will be
9 * rejected by the validator with safe HLT instructions. This is
10 * useful if you have a large library in which many functions do not
11 * validate but are not immediately required to work. Replacing the
12 * forbidden instructions with HLTs makes it easier to find the
13 * instructions that are needed first, and fix and test them.
14 */
15
16 #include <assert.h>
17 #include <stdio.h>
18 #include <string.h>
19
20 #include "native_client/src/include/elf.h"
21 #include "native_client/src/shared/gio/gio.h"
22 #include "native_client/src/shared/platform/nacl_check.h"
23 #include "native_client/src/shared/utils/types.h"
24 #include "native_client/src/trusted/validator/ncvalidate.h"
25
26 static Bool FixUpSectionCheckStatus(NaClValidationStatus status) {
27 switch (status) {
28 case NaClValidationSucceeded:
29 return TRUE;
30 default:
31 case NaClValidationFailed:
32 fprintf(stderr, "Errors still exist after attempting to stubout code\n");
33 return FALSE;
34 case NaClValidationFailedOutOfMemory:
35 fprintf(stderr, "Unable to stubout code, not enough memory\n");
36 return FALSE;
37 case NaClValidationFailedNotImplemented:
38 fprintf(stderr, "Unable to stubout code, not implemented\n");
39 return FALSE;
40 case NaClValidationFailedCpuNotSupported:
41 /* This shouldn't happen, but if it does, report the problem. */
42 fprintf(stderr, "Unable to stubout code, cpu not supported\n");
43 return FALSE;
44 case NaClValidationFailedSegmentationIssue:
45 fprintf(stderr, "Unable to stubout code, segmentation issues found\n");
46 return FALSE;
47 }
48 return FALSE;
49 }
50
51 static Bool FixUpSection(const struct NaClValidatorInterface *validator,
52 uintptr_t load_address,
53 unsigned char *code,
54 size_t code_size) {
55 Bool result;
56 NaClValidationStatus status;
57 NaClCPUFeatures *cpu_features = malloc(validator->CPUFeatureSize);
58 if (cpu_features == NULL) {
59 fprintf(stderr, "Unable to create memory for CPU features\n");
60 return FALSE;
61 }
62 /* Pretend that the CPU supports every feature so that we will only stub out
63 * instructions that NaCl will never allow under any condition.
64 */
65 validator->SetAllCPUFeatures(cpu_features);
66
67 status = validator->Validate(
68 load_address, code, code_size,
69 /* stubout_mode= */ TRUE,
70 /* readonly_text= */ FALSE,
71 cpu_features,
72 /* metadata= */ NULL,
73 /* cache= */ NULL);
74 if (status == NaClValidationSucceeded) {
75 /* Now run the validator again, so that we report any errors
76 * that were not fixed by stubbing out. This is done so that
77 * the user knows that stubout doesn't fix all errors.
78 */
79 status = NACL_SUBARCH_NAME(ApplyValidatorVerbosely,
80 NACL_TARGET_ARCH,
81 NACL_TARGET_SUBARCH)
82 (load_address, code, code_size, cpu_features);
83 }
84
85 result = FixUpSectionCheckStatus(status);
86 free(cpu_features);
87 return result;
88 }
89
90 static void CheckBounds(unsigned char *data, size_t data_size,
91 void *ptr, size_t inside_size) {
92 CHECK(data <= (unsigned char *) ptr);
93 CHECK((unsigned char *) ptr + inside_size <= data + data_size);
94 }
95
96 static Bool FixUpELF32(const struct NaClValidatorInterface *validator,
97 unsigned char *data,
98 size_t data_size) {
99 Elf32_Ehdr *header;
100 int index;
101 Bool fixed = TRUE; /* until proven otherwise. */
102
103 header = (Elf32_Ehdr *) data;
104 CheckBounds(data, data_size, header, sizeof(*header));
105 CHECK(memcmp(header->e_ident, ELFMAG, strlen(ELFMAG)) == 0);
106
107 for (index = 0; index < header->e_shnum; index++) {
108 Elf32_Shdr *section = (Elf32_Shdr *) (data + header->e_shoff +
109 header->e_shentsize * index);
110 CheckBounds(data, data_size, section, sizeof(*section));
111
112 if ((section->sh_flags & SHF_EXECINSTR) != 0) {
113 CheckBounds(data, data_size,
114 data + section->sh_offset, section->sh_size);
115 if (!FixUpSection(validator,
116 section->sh_addr,
117 data + section->sh_offset,
118 section->sh_size)) {
119 fixed = FALSE;
120 }
121 }
122 }
123 return fixed;
124 }
125
126 #if NACL_TARGET_SUBARCH == 64
127 static Bool FixUpELF64(const struct NaClValidatorInterface *validator,
128 unsigned char *data,
129 size_t data_size) {
130 Elf64_Ehdr *header;
131 int index;
132 Bool fixed = TRUE; /* until proven otherwise. */
133
134 header = (Elf64_Ehdr *) data;
135 CheckBounds(data, data_size, header, sizeof(*header));
136 CHECK(memcmp(header->e_ident, ELFMAG, strlen(ELFMAG)) == 0);
137
138 for (index = 0; index < header->e_shnum; index++) {
139 Elf64_Shdr *section = (Elf64_Shdr *) (data + header->e_shoff +
140 header->e_shentsize * index);
141 CheckBounds(data, data_size, section, sizeof(*section));
142
143 if ((section->sh_flags & SHF_EXECINSTR) != 0) {
144 CheckBounds(data, data_size,
145 data + section->sh_offset, section->sh_size);
146 if (!FixUpSection(validator,
147 section->sh_addr,
148 data + section->sh_offset,
149 section->sh_size)) {
150 fixed = FALSE;
151 }
152 }
153 }
154 return fixed;
155 }
156 #endif
157
158 static Bool FixUpELF(const struct NaClValidatorInterface *validator,
159 unsigned char *data,
160 size_t data_size) {
161 #if NACL_TARGET_SUBARCH == 64
162 if (data_size > EI_CLASS && data[EI_CLASS] == ELFCLASS64)
163 return FixUpELF64(validator, data, data_size);
164 #endif
165 return FixUpELF32(validator, data, data_size);
166 }
167
168 static Bool FixUpELFFile(const struct NaClValidatorInterface *validator,
169 const char *input_file,
170 const char *output_file) {
171 FILE *fp;
172 size_t file_size;
173 unsigned char *data;
174 size_t got;
175 size_t written;
176
177 /* Read whole ELF file and write it back with modifications. */
178 fp = fopen(input_file, "rb");
179 if (fp == NULL) {
180 fprintf(stderr, "Failed to open input file: %s\n", input_file);
181 return FALSE;
182 }
183 /* Find the file size. */
184 fseek(fp, 0, SEEK_END);
185 file_size = ftell(fp);
186 data = malloc(file_size);
187 if (data == NULL) {
188 fprintf(stderr, "Unable to create memory imate of input file: %s\n",
189 input_file);
190 return FALSE;
191 }
192 fseek(fp, 0, SEEK_SET);
193 got = fread(data, 1, file_size, fp);
194 if (got != file_size) {
195 fprintf(stderr, "Unable to read data from input file: %s\n",
196 input_file);
197 return FALSE;
198 }
199 fclose(fp);
200
201 if (!FixUpELF(validator, data, file_size)) return FALSE;
202
203 fp = fopen(output_file, "wb");
204 if (fp == NULL) {
205 fprintf(stderr, "Failed to open output file: %s\n", output_file);
206 return FALSE;
207 }
208 written = fwrite(data, 1, file_size, fp);
209 if (written != file_size) {
210 fprintf(stderr, "Unable to write data to output file: %s\n",
211 output_file);
212 return FALSE;
213 }
214 fclose(fp);
215 return TRUE;
216 }
217
218 int main(int argc, const char *argv[]) {
219 /* Be sure to redirect validator error messages to stderr. */
220 const struct NaClValidatorInterface *validator;
221 NaClLogModuleInit();
222 validator = NaClCreateValidator();
223 if (!validator->stubout_mode_implemented) {
224 fprintf(stderr,
225 "This platform does not support stubout mode.");
226 return 1;
227 }
228 if (argc != 4 || strcmp(argv[2], "-o") != 0) {
229 fprintf(stderr, "Usage: %s <input-file> -o <output-file>\n\n", argv[0]);
230 fprintf(stderr,
231 "This tool rewrites ELF objects to replace instructions that are\n"
232 "rejected by the NaCl validator with safe HLT instructions.\n");
233 return 1;
234 }
235 return FixUpELFFile(validator, argv[1], argv[3]) ? 0 : 1;
236 }
OLDNEW
« no previous file with comments | « src/tools/validator_tools/build.scons ('k') | src/trusted/service_runtime/arch/x86/service_runtime_x86.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698