Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / native_client / pnacl / driver / pnacl-translate.py
1 #!/usr/bin/python
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 # IMPORTANT NOTE: If you make local mods to this file, you must run:
7 #   %  pnacl/build.sh driver
8 # in order for them to take effect in the scons build.  This command
9 # updates the copy in the toolchain/ tree.
10 #
11
12 import driver_tools
13 import filetype
14 import ldtools
15 import multiprocessing
16 import os
17 import pathtools
18 from driver_env import env
19 from driver_log import Log
20 from driver_temps import TempFiles
21
22 import subprocess
23
24 EXTRA_ENV = {
25   'PIC': '${NONSFI_NACL}',
26
27   # Determine if we should build nexes compatible with the IRT
28   'USE_IRT' : '1',
29
30   # Allow zero-cost C++ exception handling in the pexe, which is not
31   # supported by PNaCl's stable ABI.
32   'ALLOW_ZEROCOST_CXX_EH' : '0',
33
34   # Use the IRT shim by default. This can be disabled with an explicit
35   # flag (--noirtshim) or via -nostdlib.
36   'USE_IRT_SHIM'  : '1',
37
38   # To simulate the sandboxed translator better and avoid user surprises,
39   # reject LLVM bitcode (non-finalized) by default, accepting only PNaCl
40   # (finalized) bitcode. --allow-llvm-bitcode-input has to be passed
41   # explicitly to override this.
42   'ALLOW_LLVM_BITCODE_INPUT': '0',
43
44   # Flags for pnacl-nativeld
45   'LD_FLAGS': '-static',
46
47   'USE_STDLIB'     : '1',
48   'USE_DEFAULTLIBS': '1',
49   'FAST_TRANSLATION': '0',
50
51   'INPUTS'        : '',
52   'OUTPUT'        : '',
53   'OUTPUT_TYPE'   : '',
54
55   # Library Strings
56   'LD_ARGS' : '${USE_STDLIB ? ${LD_ARGS_normal} : ${LD_ARGS_nostdlib}}',
57
58   # Note: we always requires a shim now, but the dummy shim is not doing
59   # anything useful.
60   # libpnacl_irt_shim.a is generated during the SDK packaging not
61   # during the toolchain build and there are hacks in pnacl/driver/ldtools.py
62   # and pnacl/driver/pnacl-nativeld.py that will fall back to
63   # libpnacl_irt_shim_dummy.a if libpnacl_irt_shim.a does not exist.
64   'LD_ARGS_IRT_SHIM': '-l:libpnacl_irt_shim.a',
65   'LD_ARGS_IRT_SHIM_DUMMY': '-l:libpnacl_irt_shim_dummy.a',
66   # In addition to specifying the entry point, we also specify an undefined
67   # reference to _start, which is called by the shim's entry function,
68   # __pnacl_wrapper_start. _start normally comes from libnacl and will be in
69   # the pexe, however for the IRT it comes from irt_entry.c and when linking it
70   # using native object files, this reference is required to make sure it gets
71   # pulled in from the archive.
72   'LD_ARGS_ENTRY': '--entry=__pnacl_start --undefined=_start',
73
74   'CRTBEGIN': '${ALLOW_ZEROCOST_CXX_EH ? -l:crtbegin_for_eh.o : -l:crtbegin.o}',
75   'CRTEND': '-l:crtend.o',
76
77   'LD_ARGS_nostdlib': '-nostdlib ${ld_inputs}',
78
79   # These are just the dependencies in the native link.
80   'LD_ARGS_normal':
81     '${CRTBEGIN} ${ld_inputs} ' +
82     '${USE_IRT_SHIM ? ${LD_ARGS_IRT_SHIM} : ${LD_ARGS_IRT_SHIM_DUMMY}} ' +
83     '--start-group ' +
84     '${USE_DEFAULTLIBS ? ${DEFAULTLIBS}} ' +
85     '--end-group ' +
86     '${CRTEND}',
87
88   'DEFAULTLIBS': '${ALLOW_ZEROCOST_CXX_EH ? -l:libgcc_eh.a} ' +
89                  '-l:libgcc.a -l:libcrt_platform.a ',
90
91   # BE CAREFUL: anything added here can introduce skew between
92   # the pnacl-translate commandline tool and the in-browser translator.
93   # See: llvm/tools/pnacl-llc/srpc_main.cpp and
94   # chromium/src/ppapi/native_client/src/trusted/plugin/pnacl_options.cc
95   'LLC_FLAGS_COMMON': '${PIC ? -relocation-model=pic} ' +
96                       #  -force-tls-non-pic makes the code generator (llc)
97                       # do the work that would otherwise be done by
98                       # linker rewrites which are quite messy in the nacl
99                       # case and hence have not been implemented in gold
100                       '${PIC ? -force-tls-non-pic} ',
101
102   # LLC flags which set the target and output type.
103   'LLC_FLAGS_TARGET' : '-mtriple=${TRIPLE} -filetype=${outfiletype}',
104
105   # Append additional non-default flags here.
106   # BE CAREFUL: anything added here can introduce skew between
107   # the pnacl-translate commandline tool and the in-browser translator.
108   # See: llvm/tools/pnacl-llc/srpc_main.cpp and
109   # chromium/src/ppapi/native_client/src/trusted/plugin/pnacl_options.cc
110   'LLC_FLAGS_EXTRA' : '${FAST_TRANSLATION ? ${LLC_FLAGS_FAST}} ' +
111                       '${#OPT_LEVEL ? -O${OPT_LEVEL}} ' +
112                       '${OPT_LEVEL == 0 ? -disable-fp-elim}',
113
114   # Opt level from command line (if any)
115   'OPT_LEVEL' : '',
116
117   # faster translation == slower code
118   'LLC_FLAGS_FAST' : '-O0'
119                      # This, surprisingly, makes a measurable difference
120                      ' -tail-merge-threshold=20',
121
122   'LLC_FLAGS': '${LLC_FLAGS_TARGET} ${LLC_FLAGS_COMMON} ${LLC_FLAGS_ARCH} ' +
123                '${LLC_FLAGS_EXTRA}',
124
125   # Note: this is only used in the unsandboxed case
126   'RUN_LLC'       : '${LLVM_PNACL_LLC} ${LLC_FLAGS} ${LLC_MCPU} '
127                     '${input} -o ${output} ',
128   # Whether to stream the bitcode from a single FD in unsandboxed mode
129   # (otherwise it will use concurrent file reads when using multithreaded module
130   # splitting)
131   'STREAM_BITCODE' : '1',
132   # Rate in bits/sec to stream the bitcode from sel_universal over SRPC
133   # for testing. Defaults to 1Gbps (effectively unlimited).
134   'BITCODE_STREAM_RATE' : '1000000000',
135   # Default to 0, which means unset by the user. In this cases the driver will
136   # use up to 4 modules if there are enough cores. If the user overrides,
137   # use as many modules as specified (which could be only 1).
138   'SPLIT_MODULE' : '0',
139 }
140
141
142 TranslatorPatterns = [
143   ( '-o(.+)',          "env.set('OUTPUT', pathtools.normalize($0))"),
144   ( ('-o', '(.+)'),    "env.set('OUTPUT', pathtools.normalize($0))"),
145
146   ( '-S',              "env.set('OUTPUT_TYPE', 's')"), # Stop at .s
147   ( '-c',              "env.set('OUTPUT_TYPE', 'o')"), # Stop at .o
148
149   # Expose a very limited set of llc flags.
150   # BE CAREFUL: anything added here can introduce skew between
151   # the pnacl-translate commandline tool and the in-browser translator.
152   # See: llvm/tools/pnacl-llc/srpc_main.cpp and
153   # chromium/src/ppapi/native_client/src/trusted/plugin/pnacl_options.cc
154   ( '(-sfi-.+)',        "env.append('LLC_FLAGS_EXTRA', $0)"),
155   ( '(-mtls-use-call)', "env.append('LLC_FLAGS_EXTRA', $0)"),
156   # These flags are usually used for linktime dead code/data
157   # removal but also help with reloc overflows on ARM
158   ( '(-fdata-sections)',     "env.append('LLC_FLAGS_EXTRA', $0)"),
159   ( '(-ffunction-sections)', "env.append('LLC_FLAGS_EXTRA', $0)"),
160   ( '(--gc-sections)',       "env.append('LD_FLAGS', $0)"),
161   ( '(-mattr=.*)', "env.append('LLC_FLAGS_EXTRA', $0)"),
162   ( '(-mcpu=.*)', "env.set('LLC_MCPU', '')\n"
163                   "env.append('LLC_FLAGS_EXTRA', $0)"),
164   ( '(-pnaclabi-verify=.*)', "env.append('LLC_FLAGS_EXTRA', $0)"),
165   ( '(-pnaclabi-verify-fatal-errors=.*)', "env.append('LLC_FLAGS_EXTRA', $0)"),
166   ( '(-pnaclabi-allow-dev-intrinsics)', "env.append('LLC_FLAGS_EXTRA', $0)"),
167   # Allow overriding the -O level.
168   ( '-O([0-3])', "env.set('OPT_LEVEL', $0)"),
169
170   # This adds arch specific flags to the llc invocation aimed at
171   # improving translation speed at the expense of code quality.
172   ( '-translate-fast',  "env.set('FAST_TRANSLATION', '1')"),
173
174   ( '-nostdlib',       "env.set('USE_STDLIB', '0')"),
175
176   # Disables the default libraries.
177   # This flag is needed for building libgcc_s.so.
178   ( '-nodefaultlibs',  "env.set('USE_DEFAULTLIBS', '0')"),
179
180   ( '--noirt',         "env.set('USE_IRT', '0')\n"
181                        "env.append('LD_FLAGS', '--noirt')"),
182   ( '--noirtshim',     "env.set('USE_IRT_SHIM', '0')"),
183   ( '(--pnacl-nativeld=.+)', "env.append('LD_FLAGS', $0)"),
184
185   # Allowing zero-cost C++ exception handling causes a specific set of
186   # native objects to get linked into the nexe.
187   ( '--pnacl-allow-zerocost-eh', "env.set('ALLOW_ZEROCOST_CXX_EH', '1')"),
188   # TODO(mseaborn): Remove "--pnacl-allow-exceptions", replaced by
189   # "--pnacl-allow-zerocost-eh".
190   ( '--pnacl-allow-exceptions', "env.set('ALLOW_ZEROCOST_CXX_EH', '1')"),
191
192   ( '--allow-llvm-bitcode-input', "env.set('ALLOW_LLVM_BITCODE_INPUT', '1')"),
193
194   ( '-fPIC',           "env.set('PIC', '1')"),
195
196   ( '(--build-id)',    "env.append('LD_FLAGS', $0)"),
197   ( '-bitcode-stream-rate=([0-9]+)', "env.set('BITCODE_STREAM_RATE', $0)"),
198   ( '-split-module=([0-9]+)', "env.set('SPLIT_MODULE', $0)"),
199   ( '-no-stream-bitcode', "env.set('STREAM_BITCODE', '0')"),
200
201   # Treat general linker flags as inputs so they don't get re-ordered
202   ( '-Wl,(.*)',        "env.append('INPUTS', *($0).split(','))"),
203
204   ( '(-.*)',            driver_tools.UnrecognizedOption),
205   ( '(.*)',            "env.append('INPUTS', pathtools.normalize($0))"),
206 ]
207
208
209 def SetUpArch():
210   base_arch = env.getone('BASE_ARCH')
211   env.set('TARGET_OS', 'nacl')
212   if base_arch.endswith('_LINUX'):
213     base_arch = base_arch[:-len('_LINUX')]
214     env.set('TARGET_OS', 'linux')
215   elif base_arch.endswith('_MAC'):
216     base_arch = base_arch[:-len('_MAC')]
217     env.set('TARGET_OS', 'mac')
218
219   if env.getbool('NONSFI_NACL'):
220     triple_map = {
221         'nacl':
222             {'X8632': 'i686-linux-gnu',
223              'ARM': 'armv7a-linux-gnueabihf'}}
224   else:
225     triple_map = {
226         'nacl':
227             {'X8632': 'i686-none-nacl-gnu',
228              'X8664': 'x86_64-none-nacl-gnu',
229              'ARM': 'armv7a-none-nacl-gnueabihf',
230              'MIPS32': 'mipsel-none-nacl-gnu'},
231         'linux': {'X8632': 'i686-linux-gnu'},
232         'mac': {'X8632': 'i686-apple-darwin'}}
233   env.set('TRIPLE', triple_map[env.getone('TARGET_OS')][base_arch])
234
235   # CPU that is representative of baseline feature requirements for NaCl
236   # and/or chrome.  We may want to make this more like "-mtune"
237   # by specifying both "-mcpu=X" and "-mattr=+feat1,-feat2,...".
238   # Note: this may be different from the in-browser translator, which may
239   # do auto feature detection based on CPUID, but constrained by what is
240   # accepted by NaCl validators.
241   cpu_map = {
242       'X8632': 'pentium4',
243       'X8664': 'core2',
244       'ARM': 'cortex-a9',
245       'MIPS32': 'mips32r2'}
246   env.set('LLC_MCPU', '-mcpu=%s' % cpu_map[base_arch])
247
248   llc_flags_map = {
249       'ARM': ['-arm-reserve-r9', '-sfi-disable-cp', '-sfi-load', '-sfi-store',
250               '-sfi-stack', '-sfi-branch', '-sfi-data',
251               '-no-inline-jumptables', '-float-abi=hard', '-mattr=+neon'],
252       # Once PNaCl's build of compiler-rt (libgcc.a) defines __aeabi_*
253       # functions, we can drop the following ad-hoc option.
254       'ARM_NONSFI': ['-arm-enable-aeabi-functions=0'],
255       'MIPS32': ['-sfi-load', '-sfi-store', '-sfi-stack',
256                  '-sfi-branch', '-sfi-data']}
257   env.set('LLC_FLAGS_ARCH', *llc_flags_map.get(env.getone('ARCH'), []))
258   # When linking against a host OS's libc (such as Linux glibc), don't
259   # use %gs:0 to read the thread pointer because that won't be
260   # compatible with the libc's use of %gs:0.  Similarly, Non-SFI Mode
261   # currently offers no optimized path for reading the thread pointer.
262   if env.getone('TARGET_OS') != 'nacl' or env.getbool('NONSFI_NACL'):
263     env.append('LLC_FLAGS_ARCH', '-mtls-use-call')
264
265
266 def main(argv):
267   env.update(EXTRA_ENV)
268   driver_tools.ParseArgs(argv, TranslatorPatterns)
269   driver_tools.GetArch(required = True)
270   SetUpArch()
271
272   inputs = env.get('INPUTS')
273   output = env.getone('OUTPUT')
274
275   if len(inputs) == 0:
276     Log.Fatal("No input files")
277
278   if output == '':
279     Log.Fatal("Please specify output file with -o")
280
281   # Find the bitcode file on the command line.
282   bcfiles = [f for f in inputs
283              if not ldtools.IsFlag(f) and
284                (filetype.IsPNaClBitcode(f)
285                 or filetype.IsLLVMBitcode(f)
286                 or filetype.FileType(f) == 'll')]
287   if len(bcfiles) > 1:
288     Log.Fatal('Expecting at most 1 bitcode file')
289   elif len(bcfiles) == 1:
290     bcfile = bcfiles[0]
291   else:
292     bcfile = None
293
294   if not env.getbool('SPLIT_MODULE'):
295     try:
296       env.set('SPLIT_MODULE', str(min(4, multiprocessing.cpu_count())))
297     except NotImplementedError:
298       env.set('SPLIT_MODULE', '2')
299   elif int(env.getone('SPLIT_MODULE')) < 1:
300     Log.Fatal('Value given for -split-module must be > 0')
301   if (env.getbool('ALLOW_LLVM_BITCODE_INPUT') or
302       env.getone('TARGET_OS') != 'nacl' or
303       env.getbool('USE_EMULATOR')):
304     # When llvm input is allowed, the pexe may not be ABI-stable, so do not
305     # split it.  Non-ABI-stable pexes may have symbol naming and visibility
306     # issues that the current splitting scheme doesn't account for.
307     #
308     # For now, also do not enable multi-threaded translation when TARGET_OS !=
309     # 'nacl', since in these cases we will be using the host toolchain's
310     # linker.
311     #
312     # The x86->arm emulator is very flaky when threading is used, so don't
313     # do module splitting when using it.
314     env.set('SPLIT_MODULE', '1')
315   else:
316     modules = env.getone('SPLIT_MODULE')
317     if modules != '1':
318       env.append('LLC_FLAGS_EXTRA', '-split-module=' + modules)
319       env.append('LD_FLAGS', '-split-module=' + modules)
320     if not env.getbool('SANDBOXED') and env.getbool('STREAM_BITCODE'):
321       # Do not set -streaming-bitcode for sandboxed mode, because it is already
322       # in the default command line.
323       env.append('LLC_FLAGS_EXTRA', '-streaming-bitcode')
324
325   # If there's a bitcode file, translate it now.
326   tng = driver_tools.TempNameGen(inputs + bcfiles, output)
327   output_type = env.getone('OUTPUT_TYPE')
328   if bcfile:
329     sfile = None
330     if output_type == 's':
331       sfile = output
332
333     ofile = None
334     if output_type == 'o':
335       ofile = output
336     elif output_type != 's':
337       ofile = tng.TempNameForInput(bcfile, 'o')
338
339     if sfile:
340       RunLLC(bcfile, sfile, outfiletype='asm')
341       if ofile:
342         RunAS(sfile, ofile)
343     else:
344       RunLLC(bcfile, ofile, outfiletype='obj')
345   else:
346     ofile = None
347
348   # If we've been told to stop after translation, stop now.
349   if output_type in ('o','s'):
350     return 0
351
352   # Replace the bitcode file with __BITCODE__ in the input list
353   if bcfile:
354     inputs = ListReplace(inputs, bcfile, '__BITCODE__')
355     env.set('INPUTS', *inputs)
356   if int(env.getone('SPLIT_MODULE')) > 1:
357     modules = int(env.getone('SPLIT_MODULE'))
358     for i in range(1, modules):
359       filename = ofile + '.module%d' % i
360       TempFiles.add(filename)
361       env.append('INPUTS', filename)
362
363   if env.getone('TARGET_OS') != 'nacl':
364     RunHostLD(ofile, output)
365   else:
366     RunLD(ofile, output)
367   return 0
368
369 def RunAS(infile, outfile):
370   driver_tools.RunDriver('as', [infile, '-o', outfile])
371
372 def ListReplace(items, old, new):
373   ret = []
374   for k in items:
375     if k == old:
376       ret.append(new)
377     else:
378       ret.append(k)
379   return ret
380
381 def RunLD(infile, outfile):
382   inputs = env.get('INPUTS')
383   if infile:
384     # Put llc-translated-file at the beginning of the inputs so that it will
385     # pull in all needed symbols from any native archives that may also be
386     # in the input list. This is in case there are any mixed groups of bitcode
387     # and native archives in the link (as is the case with irt_browser_lib)
388     inputs.remove('__BITCODE__')
389     inputs = ['--llc-translated-file=' + infile] + inputs
390   env.set('ld_inputs', *inputs)
391   args = env.get('LD_ARGS') + ['-o', outfile]
392   if env.getbool('USE_STDLIB'):
393     args += env.get('LD_ARGS_ENTRY')
394   args += env.get('LD_FLAGS')
395   driver_tools.RunDriver('nativeld', args)
396
397 def RunHostLD(infile, outfile):
398   if env.getone('TARGET_OS') == 'linux':
399     driver_tools.Run(['objcopy', '--redefine-sym', '_start=_user_start',
400                       infile])
401   lib_dir = (env.getone('BASE_LIB_NATIVE')
402              + 'x86-32-%s' % env.getone('TARGET_OS'))
403   args = ['gcc', '-m32', infile, '-o', outfile,
404           os.path.join(lib_dir, 'unsandboxed_irt.o'), '-lpthread']
405   if env.getone('TARGET_OS') == 'linux':
406     args.append('-lrt')  # For clock_gettime()
407   driver_tools.Run(args)
408
409 def RunLLC(infile, outfile, outfiletype):
410   env.push()
411   env.setmany(input=infile, output=outfile, outfiletype=outfiletype)
412   if env.getbool('SANDBOXED'):
413     RunLLCSandboxed()
414     env.pop()
415   else:
416     args = ["${RUN_LLC}"]
417     if filetype.IsPNaClBitcode(infile):
418       args.append("-bitcode-format=pnacl")
419     elif filetype.IsLLVMBitcode(infile):
420       if not env.getbool('ALLOW_LLVM_BITCODE_INPUT'):
421         Log.Fatal('Translator expects finalized PNaCl bitcode. '
422                   'Pass --allow-llvm-bitcode-input to override.')
423     driver_tools.Run(' '.join(args))
424     env.pop()
425   return 0
426
427 def RunLLCSandboxed():
428   driver_tools.CheckTranslatorPrerequisites()
429   infile = env.getone('input')
430   outfile = env.getone('output')
431   is_pnacl = filetype.IsPNaClBitcode(infile)
432   if not is_pnacl and not env.getbool('ALLOW_LLVM_BITCODE_INPUT'):
433     Log.Fatal('Translator expects finalized PNaCl bitcode. '
434               'Pass --allow-llvm-bitcode-input to override.')
435   script = MakeSelUniversalScriptForLLC(infile, outfile, is_pnacl)
436   command = ('${SEL_UNIVERSAL_PREFIX} ${SEL_UNIVERSAL} ${SEL_UNIVERSAL_FLAGS} '
437     '-- ${LLC_SB}')
438   driver_tools.Run(command,
439                    stdin_contents=script,
440                    # stdout/stderr will be automatically dumped
441                    # upon failure
442                    redirect_stderr=subprocess.PIPE,
443                    redirect_stdout=subprocess.PIPE)
444
445 def BuildOverrideLLCCommandLine(is_pnacl):
446   extra_flags = env.get('LLC_FLAGS_EXTRA')
447   # The mcpu is not part of the default flags, so append that too.
448   mcpu = env.getone('LLC_MCPU')
449   if mcpu:
450     extra_flags.append(mcpu)
451   if not is_pnacl:
452     extra_flags.append('-bitcode-format=llvm')
453   # command_line is a NUL (\x00) terminated sequence.
454   kTerminator = '\0'
455   command_line = kTerminator.join(extra_flags) + kTerminator
456   command_line_escaped = command_line.replace(kTerminator, '\\x00')
457   return len(command_line), command_line_escaped
458
459 def MakeSelUniversalScriptForLLC(infile, outfile, is_pnacl):
460   script = []
461   script.append('readwrite_file objfile %s' % outfile)
462   modules = int(env.getone('SPLIT_MODULE'))
463   if modules > 1:
464     script.extend(['readwrite_file objfile%d %s.module%d' % (m, outfile, m)
465                    for m in range(1, modules)])
466   stream_rate = int(env.getraw('BITCODE_STREAM_RATE'))
467   assert stream_rate != 0
468   cmdline_len, cmdline_escaped = BuildOverrideLLCCommandLine(is_pnacl)
469   assert modules in range(1, 17)
470   script.append('rpc StreamInitWithSplit i(%d) h(objfile) ' % modules +
471                 ' '.join(['h(objfile%d)' % m for m in range(1, modules)] +
472                          ['h(invalid)' for x in range(modules, 16)]) +
473                 ' C(%d,%s) * s()' % (cmdline_len, cmdline_escaped))
474   # specify filename, chunk size and rate in bits/s
475   script.append('stream_file %s %s %s' % (infile, 64 * 1024, stream_rate))
476   script.append('rpc StreamEnd * i() s() s() s()')
477   script.append('echo "pnacl-llc complete"')
478   script.append('')
479   return '\n'.join(script)
480
481 def get_help(argv):
482   return """
483 PNaCl bitcode to native code translator.
484
485 Usage: pnacl-translate [options] -arch <arch> <input> -o <output>
486
487   <input>                 Input file (bitcode).
488   -arch <arch>            Translate to <arch> (i686, x86-64, armv7).
489                           Note: <arch> is a generic arch specifier.  This
490                           generates code assuming certain baseline CPU features,
491                           required by NaCl or Chrome. For finer control of
492                           tuning and features, see -mattr, and -mcpu.
493   -o <output>             Output file.
494
495   The default output file type is .nexe, which assumes that the input file
496   type is .pexe.  Native object files and assembly can also be generated
497   with the -S and -c commandline flags.
498
499 ADVANCED OPTIONS:
500   -mattr=<+feat1,-feat2>  Toggle specific cpu features on and off.
501   -mcpu=<cpu-name>        Target a specific cpu type.  Tunes code as well as
502                           turns cpu features on and off.
503   -S                      Generate native assembly only.
504   -c                      Generate native object file only.
505   --pnacl-sb              Use the translator which runs inside the NaCl sandbox.
506   -O[0-3]                 Change translation-time optimization level.
507 """