OLD | NEW |
---|---|
1 /* Copyright 2012 The Native Client Authors. All rights reserved. | 1 /* Copyright 2012 The Native Client Authors. All rights reserved. |
2 * Use of this source code is governed by a BSD-style license that can | 2 * Use of this source code is governed by a BSD-style license that can |
3 * be found in the LICENSE file. | 3 * be found in the LICENSE file. |
4 * | 4 * |
5 * This file provides wrappers to open() to use pre-opened file descriptors | 5 * This file provides wrappers to open() to use pre-opened file descriptors |
6 * for the input bitcode and the output file. | 6 * for the input bitcode and the output file. |
7 * | 7 * |
8 * It also has the SRPC interfaces, but that should probably be refactored | 8 * It also has the SRPC interfaces, but that should probably be refactored |
9 * into a separate file. | 9 * into a separate file. |
10 */ | 10 */ |
11 | 11 |
12 #if defined(__native_client__) && defined(NACL_SRPC) | 12 #if defined(__native_client__) && defined(NACL_SRPC) |
13 | 13 |
14 #include <argz.h> | 14 #include <argz.h> |
15 #include <stdio.h> | 15 #include <stdio.h> |
16 #include <stdlib.h> | 16 #include <stdlib.h> |
17 #include <string.h> | 17 #include <string.h> |
18 // Headers which are not properly part of the SDK are included by their | 18 // Headers which are not properly part of the SDK are included by their |
19 // path in the nacl tree | 19 // path in the nacl tree |
20 #include "native_client/src/shared/srpc/nacl_srpc.h" | 20 #include "native_client/src/shared/srpc/nacl_srpc.h" |
21 #ifdef __pnacl__ | 21 #ifdef __pnacl__ |
22 #include <nacl/pnacl.h> | 22 #include <nacl/pnacl.h> |
23 #endif | 23 #endif |
24 #include "SRPCStreamer.h" | 24 #include "SRPCStreamer.h" |
25 | 25 |
26 | |
27 #include <string> | 26 #include <string> |
28 #include <map> | 27 #include <map> |
29 #include <vector> | 28 #include <vector> |
30 | 29 |
31 #include "llvm/ADT/OwningPtr.h" | 30 #include "llvm/ADT/OwningPtr.h" |
32 #include "llvm/ADT/StringRef.h" | 31 #include "llvm/ADT/StringRef.h" |
33 #include "llvm/Support/MemoryBuffer.h" | 32 #include "llvm/Support/MemoryBuffer.h" |
34 #include "llvm/Support/system_error.h" | 33 #include "llvm/Support/system_error.h" |
35 | 34 |
36 | 35 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
113 return llc_main(static_cast<int>(argc), argv); | 112 return llc_main(static_cast<int>(argc), argv); |
114 } | 113 } |
115 | 114 |
116 string_vector* CommandLineFromArgz(char* str, size_t str_len) { | 115 string_vector* CommandLineFromArgz(char* str, size_t str_len) { |
117 char* entry = str; | 116 char* entry = str; |
118 string_vector* vec = new string_vector; | 117 string_vector* vec = new string_vector; |
119 while (entry != NULL) { | 118 while (entry != NULL) { |
120 vec->push_back(entry); | 119 vec->push_back(entry); |
121 entry = argz_next(str, str_len, entry); | 120 entry = argz_next(str, str_len, entry); |
122 } | 121 } |
122 return vec; | |
123 } | |
124 | |
125 void AddFixedArguments(string_vector* vec) { | |
123 // Add fixed arguments to the command line. These specify the bitcode | 126 // Add fixed arguments to the command line. These specify the bitcode |
124 // and object code filenames, removing them from the contract with the | 127 // and object code filenames, removing them from the contract with the |
125 // coordinator. | 128 // coordinator. |
126 vec->push_back(kBitcodeFilename); | 129 vec->push_back(kBitcodeFilename); |
127 vec->push_back("-o"); | 130 vec->push_back("-o"); |
128 vec->push_back(kObjectFilename); | 131 vec->push_back(kObjectFilename); |
129 return vec; | 132 } |
133 | |
134 bool AddDefaultCPU(string_vector* vec) { | |
135 #if defined (__pnacl__) | |
136 switch (__builtin_nacl_target_arch()) { | |
137 case PnaclTargetArchitectureX86_32: { | |
138 vec->push_back("-mcpu=pentium4"); | |
139 break; | |
140 } | |
141 case PnaclTargetArchitectureX86_64: { | |
142 vec->push_back("-mcpu=core2"); | |
143 break; | |
144 } | |
145 case PnaclTargetArchitectureARM_32: { | |
146 vec->push_back("-mcpu=cortex-a8"); | |
147 break; | |
148 } | |
149 default: | |
150 printerr("no target architecture match.\n"); | |
151 return false; | |
152 } | |
153 // Some cases for building this with nacl-gcc. | |
154 #elif defined (__i386__) | |
155 vec->push_back("-mcpu=pentium4"); | |
156 #elif defined (__x86_64__) | |
157 vec->push_back("-mcpu=core2"); | |
158 #elif defined (__arm__) | |
159 vec->push_back("-mcpu=cortex-a8"); | |
160 #error "Unknown architecture" | |
161 #endif | |
162 return true; | |
163 } | |
164 | |
165 bool HadCPUOverride(string_vector* vec) { | |
Derek Schuff
2013/03/06 17:45:27
s/Had/Has?
jvoung (off chromium)
2013/03/06 18:24:44
Done.
| |
166 std::string mcpu = std::string("-mcpu="); | |
167 size_t len = mcpu.length(); | |
168 for (size_t i = 0; i < vec->size(); ++i) { | |
169 std::string prefix = (*vec)[i].substr(0, len); | |
170 if (prefix.compare(mcpu) == 0) | |
171 return true; | |
172 } | |
173 return false; | |
130 } | 174 } |
131 | 175 |
132 string_vector* GetDefaultCommandLine() { | 176 string_vector* GetDefaultCommandLine() { |
133 string_vector* command_line = new string_vector; | 177 string_vector* command_line = new string_vector; |
134 size_t i; | 178 size_t i; |
135 // First, those common to all architectures. | 179 // First, those common to all architectures. |
136 static const char* common_args[] = { "pnacl_translator", | 180 static const char* common_args[] = { "pnacl_translator", |
137 "-filetype=obj", | 181 "-filetype=obj" }; |
138 kBitcodeFilename, | |
139 "-o", | |
140 kObjectFilename }; | |
141 for (i = 0; i < ARRAY_SIZE(common_args); ++i) { | 182 for (i = 0; i < ARRAY_SIZE(common_args); ++i) { |
142 command_line->push_back(common_args[i]); | 183 command_line->push_back(common_args[i]); |
143 } | 184 } |
144 // Then those particular to a platform. | 185 // Then those particular to a platform. |
145 static const char* llc_args_x8632[] = { "-march=x86", | 186 static const char* llc_args_x8632[] = { "-mtriple=i686-none-nacl-gnu", |
146 "-mcpu=pentium4", | |
147 "-mtriple=i686-none-nacl-gnu", | |
148 NULL }; | 187 NULL }; |
149 static const char* llc_args_x8664[] = { "-march=x86-64", | 188 static const char* llc_args_x8664[] = { "-mtriple=x86_64-none-nacl-gnu", |
150 "-mcpu=core2", | |
151 "-mtriple=x86_64-none-nacl-gnu", | |
152 NULL }; | 189 NULL }; |
153 static const char* llc_args_arm[] = { "-mcpu=cortex-a8", | 190 static const char* llc_args_arm[] = { "-mtriple=armv7a-none-nacl-gnueabi", |
154 "-mtriple=armv7a-none-nacl-gnueabi", | |
155 "-arm-reserve-r9", | 191 "-arm-reserve-r9", |
156 "-sfi-disable-cp", | 192 "-sfi-disable-cp", |
157 "-sfi-store", | 193 "-sfi-store", |
158 "-sfi-load", | 194 "-sfi-load", |
159 "-sfi-stack", | 195 "-sfi-stack", |
160 "-sfi-branch", | 196 "-sfi-branch", |
161 "-sfi-data", | 197 "-sfi-data", |
162 "-no-inline-jumptables", | 198 "-no-inline-jumptables", |
163 "-float-abi=hard", | 199 "-float-abi=hard", |
164 NULL }; | 200 NULL }; |
165 | 201 |
166 const char **llc_args = NULL; | 202 const char **llc_args = NULL; |
167 #if defined (__pnacl__) | 203 #if defined (__pnacl__) |
168 switch (__builtin_nacl_target_arch()) { | 204 switch (__builtin_nacl_target_arch()) { |
169 case PnaclTargetArchitectureX86_32: { | 205 case PnaclTargetArchitectureX86_32: { |
170 llc_args = llc_args_x8632; | 206 llc_args = llc_args_x8632; |
171 break; | 207 break; |
172 } | 208 } |
173 case PnaclTargetArchitectureX86_64: { | 209 case PnaclTargetArchitectureX86_64: { |
174 llc_args = llc_args_x8664; | 210 llc_args = llc_args_x8664; |
175 break; | 211 break; |
176 } | 212 } |
177 case PnaclTargetArchitectureARM_32: { | 213 case PnaclTargetArchitectureARM_32: { |
178 llc_args = llc_args_arm; | 214 llc_args = llc_args_arm; |
179 break; | 215 break; |
180 } | 216 } |
181 default: | 217 default: |
182 printerr("no target architecture match.\n"); | 218 printerr("no target architecture match.\n"); |
183 delete command_line; | 219 delete command_line; |
184 command_line = NULL; | 220 return NULL; |
185 break; | |
186 } | 221 } |
222 // Some cases for building this with nacl-gcc. | |
187 #elif defined (__i386__) | 223 #elif defined (__i386__) |
188 llc_args = llc_args_x8632; | 224 llc_args = llc_args_x8632; |
189 #elif defined (__x86_64__) | 225 #elif defined (__x86_64__) |
190 llc_args = llc_args_x8664; | 226 llc_args = llc_args_x8664; |
227 #elif defined (__arm__) | |
228 llc_args = llc_args_arm; | |
191 #else | 229 #else |
192 #error | 230 #error "Unknown architecture" |
193 #endif | 231 #endif |
194 for (i = 0; llc_args[i] != NULL; i++) command_line->push_back(llc_args[i]); | 232 for (i = 0; llc_args[i] != NULL; i++) command_line->push_back(llc_args[i]); |
195 return command_line; | 233 return command_line; |
196 } | 234 } |
197 | 235 |
198 // Data passed from main thread to compile thread. | 236 // Data passed from main thread to compile thread. |
199 // Takes ownership of the commandline vector. | 237 // Takes ownership of the commandline vector. |
200 class StreamingThreadData { | 238 class StreamingThreadData { |
201 public: | 239 public: |
202 StreamingThreadData(int object_fd, string_vector* cmd_line_vec) : | 240 StreamingThreadData(int object_fd, string_vector* cmd_line_vec) : |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
246 // Under the hood it forks a new thread at starts the llc_main, which sets | 284 // Under the hood it forks a new thread at starts the llc_main, which sets |
247 // up the compilation and blocks when it tries to start reading the bitcode. | 285 // up the compilation and blocks when it tries to start reading the bitcode. |
248 // Input arg is a file descriptor to write the output object file to. | 286 // Input arg is a file descriptor to write the output object file to. |
249 // Returns a string, containing an error message if the call fails. | 287 // Returns a string, containing an error message if the call fails. |
250 void stream_init(NaClSrpcRpc *rpc, | 288 void stream_init(NaClSrpcRpc *rpc, |
251 NaClSrpcArg **in_args, | 289 NaClSrpcArg **in_args, |
252 NaClSrpcArg **out_args, | 290 NaClSrpcArg **out_args, |
253 NaClSrpcClosure *done) { | 291 NaClSrpcClosure *done) { |
254 // cmd_line_vec allocated by GetDefaultCommandLine() is freed by the | 292 // cmd_line_vec allocated by GetDefaultCommandLine() is freed by the |
255 // translation thread in run_streamed() | 293 // translation thread in run_streamed() |
256 do_stream_init(rpc, in_args, out_args, done, GetDefaultCommandLine()); | 294 string_vector* cmd_line_vec = GetDefaultCommandLine(); |
295 if (!cmd_line_vec || !AddDefaultCPU(cmd_line_vec)) { | |
296 NaClSrpcClosureRunner runner(done); | |
297 rpc->result = NACL_SRPC_RESULT_APP_ERROR; | |
298 out_args[0]->arrays.str = strdup("Failed to get default commandline."); | |
299 return; | |
300 } | |
301 AddFixedArguments(cmd_line_vec); | |
302 do_stream_init(rpc, in_args, out_args, done, cmd_line_vec); | |
257 } | 303 } |
258 | 304 |
259 // Invoked by StreamInitWithCommandLine RPC. Same as stream_init, but | 305 // Invoked by StreamInitWithCommandLine RPC. Same as stream_init, but |
260 // provides a command line to use instead of the default. | 306 // provides a command line to use instead of the default. |
261 void stream_init_with_command_line(NaClSrpcRpc *rpc, | 307 void stream_init_with_command_line(NaClSrpcRpc *rpc, |
262 NaClSrpcArg **in_args, | 308 NaClSrpcArg **in_args, |
263 NaClSrpcArg **out_args, | 309 NaClSrpcArg **out_args, |
264 NaClSrpcClosure *done) { | 310 NaClSrpcClosure *done) { |
265 char* command_line = in_args[1]->arrays.carr; | 311 char* command_line = in_args[1]->arrays.carr; |
266 size_t command_line_len = in_args[1]->u.count; | 312 size_t command_line_len = in_args[1]->u.count; |
267 string_vector* cmd_line_vec = | 313 string_vector* cmd_line_vec = |
268 CommandLineFromArgz(command_line, command_line_len); | 314 CommandLineFromArgz(command_line, command_line_len); |
315 AddFixedArguments(cmd_line_vec); | |
269 // cmd_line_vec is freed by the translation thread in run_streamed | 316 // cmd_line_vec is freed by the translation thread in run_streamed |
270 do_stream_init(rpc, in_args, out_args, done, cmd_line_vec); | 317 do_stream_init(rpc, in_args, out_args, done, cmd_line_vec); |
271 } | 318 } |
272 | 319 |
320 // Invoked by StreamInitWithOverrides RPC. Same as stream_init, but | |
321 // provides commandline flag overrides (appended to the default). | |
322 void stream_init_with_overrides(NaClSrpcRpc *rpc, | |
323 NaClSrpcArg **in_args, | |
324 NaClSrpcArg **out_args, | |
325 NaClSrpcClosure *done) { | |
326 string_vector* cmd_line_vec = GetDefaultCommandLine(); | |
327 if (!cmd_line_vec) { | |
328 NaClSrpcClosureRunner runner(done); | |
329 rpc->result = NACL_SRPC_RESULT_APP_ERROR; | |
330 out_args[0]->arrays.str = strdup("Failed to get default commandline."); | |
331 return; | |
332 } | |
333 AddFixedArguments(cmd_line_vec); | |
334 | |
335 char* command_line = in_args[1]->arrays.carr; | |
336 size_t command_line_len = in_args[1]->u.count; | |
337 llvm::OwningPtr<string_vector> extra_vec( | |
338 CommandLineFromArgz(command_line, command_line_len)); | |
339 cmd_line_vec->insert(cmd_line_vec->end(), | |
340 extra_vec->begin(), extra_vec->end()); | |
341 // Make sure some -mcpu override exists for now to prevent | |
342 // auto-cpu feature detection from triggering instructions that | |
343 // we do not validate yet. | |
344 if (!HadCPUOverride(extra_vec.get())) { | |
345 AddDefaultCPU(cmd_line_vec); | |
346 } | |
347 extra_vec.reset(NULL); | |
348 // cmd_line_vec is freed by the translation thread in run_streamed. | |
349 do_stream_init(rpc, in_args, out_args, done, cmd_line_vec); | |
350 } | |
351 | |
273 // Invoked by the StreamChunk RPC. Receives a chunk of the bitcode and | 352 // Invoked by the StreamChunk RPC. Receives a chunk of the bitcode and |
274 // buffers it for later retrieval by the compilation thread. | 353 // buffers it for later retrieval by the compilation thread. |
275 void stream_chunk(NaClSrpcRpc *rpc, | 354 void stream_chunk(NaClSrpcRpc *rpc, |
276 NaClSrpcArg **in_args, | 355 NaClSrpcArg **in_args, |
277 NaClSrpcArg **out_args, | 356 NaClSrpcArg **out_args, |
278 NaClSrpcClosure *done) { | 357 NaClSrpcClosure *done) { |
279 NaClSrpcClosureRunner runner(done); | 358 NaClSrpcClosureRunner runner(done); |
280 rpc->result = NACL_SRPC_RESULT_APP_ERROR; | 359 rpc->result = NACL_SRPC_RESULT_APP_ERROR; |
281 size_t len = in_args[0]->u.count; | 360 size_t len = in_args[0]->u.count; |
282 unsigned char *bytes = reinterpret_cast<unsigned char*>( | 361 unsigned char *bytes = reinterpret_cast<unsigned char*>( |
(...skipping 28 matching lines...) Expand all Loading... | |
311 } | 390 } |
312 | 391 |
313 const struct NaClSrpcHandlerDesc srpc_methods[] = { | 392 const struct NaClSrpcHandlerDesc srpc_methods[] = { |
314 // Protocol for streaming: | 393 // Protocol for streaming: |
315 // (StreamInit(obj_fd) -> error_str | | 394 // (StreamInit(obj_fd) -> error_str | |
316 // StreamInitWIthCommandLine(obj_fd, escaped_cmdline) -> error_str) | 395 // StreamInitWIthCommandLine(obj_fd, escaped_cmdline) -> error_str) |
317 // StreamChunk(data) + | 396 // StreamChunk(data) + |
318 // StreamEnd() -> (is_shared_lib,soname,dependencies,error_str) | 397 // StreamEnd() -> (is_shared_lib,soname,dependencies,error_str) |
319 { "StreamInit:h:s", stream_init }, | 398 { "StreamInit:h:s", stream_init }, |
320 { "StreamInitWithCommandLine:hC:s:", stream_init_with_command_line }, | 399 { "StreamInitWithCommandLine:hC:s:", stream_init_with_command_line }, |
400 { "StreamInitWithOverrides:hC:s:", stream_init_with_overrides }, | |
321 { "StreamChunk:C:", stream_chunk }, | 401 { "StreamChunk:C:", stream_chunk }, |
322 { "StreamEnd::isss", stream_end }, | 402 { "StreamEnd::isss", stream_end }, |
323 { NULL, NULL }, | 403 { NULL, NULL }, |
324 }; | 404 }; |
325 | 405 |
326 } // namespace | 406 } // namespace |
327 | 407 |
328 int | 408 int |
329 main() { | 409 main() { |
330 if (!NaClSrpcModuleInit()) { | 410 if (!NaClSrpcModuleInit()) { |
331 return 1; | 411 return 1; |
332 } | 412 } |
333 | 413 |
334 if (!NaClSrpcAcceptClientConnection(srpc_methods)) { | 414 if (!NaClSrpcAcceptClientConnection(srpc_methods)) { |
335 return 1; | 415 return 1; |
336 } | 416 } |
337 NaClSrpcModuleFini(); | 417 NaClSrpcModuleFini(); |
338 return 0; | 418 return 0; |
339 } | 419 } |
340 | 420 |
341 #endif | 421 #endif |
OLD | NEW |