Index: tools/llc/nacl_file.cpp |
diff --git a/tools/llc/nacl_file.cpp b/tools/llc/nacl_file.cpp |
index c5cd4d55aec0234b4d756f43f66baa3faf300ebd..3d56b79840f4feb1bb101c287b8e58cc70b10008 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 }, |