diff options
-rw-r--r-- | tools/llc/nacl_file.cpp | 116 |
1 files changed, 98 insertions, 18 deletions
diff --git a/tools/llc/nacl_file.cpp b/tools/llc/nacl_file.cpp index c5cd4d55ae..3d56b79840 100644 --- a/tools/llc/nacl_file.cpp +++ b/tools/llc/nacl_file.cpp @@ -23,7 +23,6 @@ #endif #include "SRPCStreamer.h" - #include <string> #include <map> #include <vector> @@ -120,13 +119,58 @@ string_vector* CommandLineFromArgz(char* str, size_t str_len) { vec->push_back(entry); entry = argz_next(str, str_len, entry); } + return vec; +} + +void AddFixedArguments(string_vector* vec) { // Add fixed arguments to the command line. These specify the bitcode // and object code filenames, removing them from the contract with the // coordinator. vec->push_back(kBitcodeFilename); vec->push_back("-o"); vec->push_back(kObjectFilename); - return vec; +} + +bool AddDefaultCPU(string_vector* vec) { +#if defined (__pnacl__) + switch (__builtin_nacl_target_arch()) { + case PnaclTargetArchitectureX86_32: { + vec->push_back("-mcpu=pentium4"); + break; + } + case PnaclTargetArchitectureX86_64: { + vec->push_back("-mcpu=core2"); + break; + } + case PnaclTargetArchitectureARM_32: { + vec->push_back("-mcpu=cortex-a8"); + break; + } + default: + printerr("no target architecture match.\n"); + return false; + } +// Some cases for building this with nacl-gcc. +#elif defined (__i386__) + vec->push_back("-mcpu=pentium4"); +#elif defined (__x86_64__) + vec->push_back("-mcpu=core2"); +#elif defined (__arm__) + vec->push_back("-mcpu=cortex-a8"); +#error "Unknown architecture" +#endif + return true; +} + +bool HasCPUOverride(string_vector* vec) { + std::string mcpu = std::string("-mcpu="); + size_t len = mcpu.length(); + for (size_t i = 0; i < vec->size(); ++i) { + std::string prefix = (*vec)[i].substr(0, len); + if (prefix.compare(mcpu) == 0) + return true; + } + return false; } string_vector* GetDefaultCommandLine() { @@ -134,24 +178,16 @@ string_vector* GetDefaultCommandLine() { size_t i; // First, those common to all architectures. static const char* common_args[] = { "pnacl_translator", - "-filetype=obj", - kBitcodeFilename, - "-o", - kObjectFilename }; + "-filetype=obj" }; for (i = 0; i < ARRAY_SIZE(common_args); ++i) { command_line->push_back(common_args[i]); } // Then those particular to a platform. - static const char* llc_args_x8632[] = { "-march=x86", - "-mcpu=pentium4", - "-mtriple=i686-none-nacl-gnu", + static const char* llc_args_x8632[] = { "-mtriple=i686-none-nacl-gnu", NULL }; - static const char* llc_args_x8664[] = { "-march=x86-64", - "-mcpu=core2", - "-mtriple=x86_64-none-nacl-gnu", + static const char* llc_args_x8664[] = { "-mtriple=x86_64-none-nacl-gnu", NULL }; - static const char* llc_args_arm[] = { "-mcpu=cortex-a8", - "-mtriple=armv7a-none-nacl-gnueabi", + static const char* llc_args_arm[] = { "-mtriple=armv7a-none-nacl-gnueabi", "-arm-reserve-r9", "-sfi-disable-cp", "-sfi-store", @@ -181,15 +217,17 @@ string_vector* GetDefaultCommandLine() { default: printerr("no target architecture match.\n"); delete command_line; - command_line = NULL; - break; + return NULL; } +// Some cases for building this with nacl-gcc. #elif defined (__i386__) llc_args = llc_args_x8632; #elif defined (__x86_64__) llc_args = llc_args_x8664; +#elif defined (__arm__) + llc_args = llc_args_arm; #else -#error +#error "Unknown architecture" #endif for (i = 0; llc_args[i] != NULL; i++) command_line->push_back(llc_args[i]); return command_line; @@ -253,7 +291,15 @@ void stream_init(NaClSrpcRpc *rpc, NaClSrpcClosure *done) { // cmd_line_vec allocated by GetDefaultCommandLine() is freed by the // translation thread in run_streamed() - do_stream_init(rpc, in_args, out_args, done, GetDefaultCommandLine()); + string_vector* cmd_line_vec = GetDefaultCommandLine(); + if (!cmd_line_vec || !AddDefaultCPU(cmd_line_vec)) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + out_args[0]->arrays.str = strdup("Failed to get default commandline."); + return; + } + AddFixedArguments(cmd_line_vec); + do_stream_init(rpc, in_args, out_args, done, cmd_line_vec); } // Invoked by StreamInitWithCommandLine RPC. Same as stream_init, but @@ -266,10 +312,43 @@ void stream_init_with_command_line(NaClSrpcRpc *rpc, size_t command_line_len = in_args[1]->u.count; string_vector* cmd_line_vec = CommandLineFromArgz(command_line, command_line_len); + AddFixedArguments(cmd_line_vec); // cmd_line_vec is freed by the translation thread in run_streamed do_stream_init(rpc, in_args, out_args, done, cmd_line_vec); } +// Invoked by StreamInitWithOverrides RPC. Same as stream_init, but +// provides commandline flag overrides (appended to the default). +void stream_init_with_overrides(NaClSrpcRpc *rpc, + NaClSrpcArg **in_args, + NaClSrpcArg **out_args, + NaClSrpcClosure *done) { + string_vector* cmd_line_vec = GetDefaultCommandLine(); + if (!cmd_line_vec) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + out_args[0]->arrays.str = strdup("Failed to get default commandline."); + return; + } + AddFixedArguments(cmd_line_vec); + + char* command_line = in_args[1]->arrays.carr; + size_t command_line_len = in_args[1]->u.count; + llvm::OwningPtr<string_vector> extra_vec( + CommandLineFromArgz(command_line, command_line_len)); + cmd_line_vec->insert(cmd_line_vec->end(), + extra_vec->begin(), extra_vec->end()); + // Make sure some -mcpu override exists for now to prevent + // auto-cpu feature detection from triggering instructions that + // we do not validate yet. + if (!HasCPUOverride(extra_vec.get())) { + AddDefaultCPU(cmd_line_vec); + } + extra_vec.reset(NULL); + // cmd_line_vec is freed by the translation thread in run_streamed. + do_stream_init(rpc, in_args, out_args, done, cmd_line_vec); +} + // Invoked by the StreamChunk RPC. Receives a chunk of the bitcode and // buffers it for later retrieval by the compilation thread. void stream_chunk(NaClSrpcRpc *rpc, @@ -318,6 +397,7 @@ const struct NaClSrpcHandlerDesc srpc_methods[] = { // StreamEnd() -> (is_shared_lib,soname,dependencies,error_str) { "StreamInit:h:s", stream_init }, { "StreamInitWithCommandLine:hC:s:", stream_init_with_command_line }, + { "StreamInitWithOverrides:hC:s:", stream_init_with_overrides }, { "StreamChunk:C:", stream_chunk }, { "StreamEnd::isss", stream_end }, { NULL, NULL }, |