23
23
#endif
24
24
#include " SRPCStreamer.h"
25
25
26
-
27
26
#include < string>
28
27
#include < map>
29
28
#include < vector>
@@ -120,38 +119,75 @@ string_vector* CommandLineFromArgz(char* str, size_t str_len) {
120
119
vec->push_back (entry);
121
120
entry = argz_next (str, str_len, entry);
122
121
}
122
+ return vec;
123
+ }
124
+
125
+ void AddFixedArguments (string_vector* vec) {
123
126
// Add fixed arguments to the command line. These specify the bitcode
124
127
// and object code filenames, removing them from the contract with the
125
128
// coordinator.
126
129
vec->push_back (kBitcodeFilename );
127
130
vec->push_back (" -o" );
128
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 HasCPUOverride (string_vector* vec) {
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
176
string_vector* GetDefaultCommandLine () {
133
177
string_vector* command_line = new string_vector;
134
178
size_t i;
135
179
// First, those common to all architectures.
136
180
static const char * common_args[] = { " pnacl_translator" ,
137
- " -filetype=obj" ,
138
- kBitcodeFilename ,
139
- " -o" ,
140
- kObjectFilename };
181
+ " -filetype=obj" };
141
182
for (i = 0 ; i < ARRAY_SIZE (common_args); ++i) {
142
183
command_line->push_back (common_args[i]);
143
184
}
144
185
// Then those particular to a platform.
145
- static const char * llc_args_x8632[] = { " -march=x86" ,
146
- " -mcpu=pentium4" ,
147
- " -mtriple=i686-none-nacl-gnu" ,
186
+ static const char * llc_args_x8632[] = { " -mtriple=i686-none-nacl-gnu" ,
148
187
NULL };
149
- static const char * llc_args_x8664[] = { " -march=x86-64" ,
150
- " -mcpu=core2" ,
151
- " -mtriple=x86_64-none-nacl-gnu" ,
188
+ static const char * llc_args_x8664[] = { " -mtriple=x86_64-none-nacl-gnu" ,
152
189
NULL };
153
- static const char * llc_args_arm[] = { " -mcpu=cortex-a8" ,
154
- " -mtriple=armv7a-none-nacl-gnueabi" ,
190
+ static const char * llc_args_arm[] = { " -mtriple=armv7a-none-nacl-gnueabi" ,
155
191
" -arm-reserve-r9" ,
156
192
" -sfi-disable-cp" ,
157
193
" -sfi-store" ,
@@ -181,15 +217,17 @@ string_vector* GetDefaultCommandLine() {
181
217
default :
182
218
printerr (" no target architecture match.\n " );
183
219
delete command_line;
184
- command_line = NULL ;
185
- break ;
220
+ return NULL ;
186
221
}
222
+ // Some cases for building this with nacl-gcc.
187
223
#elif defined (__i386__)
188
224
llc_args = llc_args_x8632;
189
225
#elif defined (__x86_64__)
190
226
llc_args = llc_args_x8664;
227
+ #elif defined (__arm__)
228
+ llc_args = llc_args_arm;
191
229
#else
192
- #error
230
+ #error "Unknown architecture"
193
231
#endif
194
232
for (i = 0 ; llc_args[i] != NULL ; i++) command_line->push_back (llc_args[i]);
195
233
return command_line;
@@ -253,7 +291,15 @@ void stream_init(NaClSrpcRpc *rpc,
253
291
NaClSrpcClosure *done) {
254
292
// cmd_line_vec allocated by GetDefaultCommandLine() is freed by the
255
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
305
// Invoked by StreamInitWithCommandLine RPC. Same as stream_init, but
@@ -266,10 +312,43 @@ void stream_init_with_command_line(NaClSrpcRpc *rpc,
266
312
size_t command_line_len = in_args[1 ]->u .count ;
267
313
string_vector* cmd_line_vec =
268
314
CommandLineFromArgz (command_line, command_line_len);
315
+ AddFixedArguments (cmd_line_vec);
269
316
// cmd_line_vec is freed by the translation thread in run_streamed
270
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 (!HasCPUOverride (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
352
// Invoked by the StreamChunk RPC. Receives a chunk of the bitcode and
274
353
// buffers it for later retrieval by the compilation thread.
275
354
void stream_chunk (NaClSrpcRpc *rpc,
@@ -318,6 +397,7 @@ const struct NaClSrpcHandlerDesc srpc_methods[] = {
318
397
// StreamEnd() -> (is_shared_lib,soname,dependencies,error_str)
319
398
{ " StreamInit:h:s" , stream_init },
320
399
{ " StreamInitWithCommandLine:hC:s:" , stream_init_with_command_line },
400
+ { " StreamInitWithOverrides:hC:s:" , stream_init_with_overrides },
321
401
{ " StreamChunk:C:" , stream_chunk },
322
402
{ " StreamEnd::isss" , stream_end },
323
403
{ NULL , NULL },
0 commit comments