- add third_party src.
[platform/framework/web/crosswalk.git] / src / native_client / pnacl / driver / pnacl-ld.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 from driver_tools import *
13 from driver_env import env
14 from driver_log import Log, DriverOpen, TempFiles
15 import filetype
16 import platform
17
18 EXTRA_ENV = {
19   'ALLOW_NATIVE': '0', # Allow LD args which will change the behavior
20                        # of native linking. This must be accompanied by
21                        # -arch to produce a .nexe.
22   'USE_IRT': '1',  # Use stable IRT interfaces.
23
24   'INPUTS'   : '',
25   'OUTPUT'   : '',
26
27   'SHARED'   : '0',
28   'STATIC'   : '0',
29   'PIC'      : '0',
30   'USE_STDLIB': '1',
31   'RELOCATABLE': '0',
32   'SONAME'   : '',
33
34   'STRIP_MODE' : 'none',
35
36   'STRIP_FLAGS'      : '${STRIP_FLAGS_%STRIP_MODE%}',
37   'STRIP_FLAGS_all'  : '-s',
38   'STRIP_FLAGS_debug': '-S',
39
40   'OPT_INLINE_THRESHOLD': '100',
41   'OPT_LEVEL': '',  # Default opt is 0, but we need to know if it's explicitly
42                     # requested or not, since we don't want to propagate
43                     # the value to TRANSLATE_FLAGS if it wasn't explicitly set.
44   'OPT_LTO_FLAGS': '-std-link-opts -disable-internalize',
45   'OPT_FLAGS': '${#OPT_LEVEL && !OPT_LEVEL == 0 ? ${OPT_LTO_FLAGS}} ${OPT_STRIP_%STRIP_MODE%} ' +
46                '-inline-threshold=${OPT_INLINE_THRESHOLD} ',
47   'OPT_STRIP_none': '',
48   'OPT_STRIP_all': '-disable-opt --strip',
49   'OPT_STRIP_debug': '-disable-opt --strip-debug',
50
51   'TRANSLATE_FLAGS': '${PIC ? -fPIC} ${!USE_STDLIB ? -nostdlib} ' +
52                      '${STATIC ? -static} ' +
53                      '${SHARED ? -shared} ' +
54                      '${#SONAME ? -Wl,--soname=${SONAME}} ' +
55                      '${#OPT_LEVEL ? -O${OPT_LEVEL}} ' +
56                      '--allow-llvm-bitcode-input ' +
57                      '${TRANSLATE_FLAGS_USER}',
58
59   # Extra pnacl-translate flags specified by the user using -Wt
60   'TRANSLATE_FLAGS_USER': '',
61
62   'GOLD_PLUGIN_ARGS': '-plugin=${GOLD_PLUGIN_SO} ' +
63                       '-plugin-opt=emit-llvm',
64
65   'LD_FLAGS'       : '-nostdlib ${@AddPrefix:-L:SEARCH_DIRS} ' +
66                      '${SHARED ? -shared} ${STATIC ? -static} ' +
67                      '${RELOCATABLE ? -relocatable} ' +
68                      '${#SONAME ? --soname=${SONAME}}',
69
70   # Flags for native linking.
71   # Only allowed if ALLOW_NATIVE is true.
72   'LD_FLAGS_NATIVE': '',
73
74   'SEARCH_DIRS'        : '${SEARCH_DIRS_USER} ${SEARCH_DIRS_BUILTIN}',
75   'SEARCH_DIRS_USER'   : '',
76
77   # Standard Library Directories
78   'SEARCH_DIRS_BUILTIN': '${USE_STDLIB ? ' +
79                          '  ${BASE_USR}/lib/ ' +
80                          '  ${BASE_SDK}/lib/ ' +
81                          '  ${BASE_LIB}/ ' +
82                          '}',
83
84   'BCLD_OFORMAT'        : '${BCLD_OFORMAT_%ARCH%}',
85   'BCLD_OFORMAT_ARM'    : 'elf32-littlearm',
86   'BCLD_OFORMAT_X8632'  : 'elf32-i386-nacl',
87   'BCLD_OFORMAT_X8664'  : 'elf64-x86-64-nacl',
88   'BCLD_OFORMAT_MIPS32' : 'elf32-tradlittlemips',
89
90   'BCLD_ALLOW_UNRESOLVED'  :
91     # The following functions are implemented in the native support library.
92     # Before a .pexe is produced, they get rewritten to intrinsic calls.
93     # However, this rewriting happens after bitcode linking - so gold has
94     # to be told that these are allowed to remain unresolved.
95     '--allow-unresolved=memcpy '
96     '--allow-unresolved=memset '
97     '--allow-unresolved=memmove '
98     '--allow-unresolved=setjmp '
99     '--allow-unresolved=longjmp '
100     # For exception-handling enabled tests.
101     '${ALLOW_CXX_EXCEPTIONS ? '
102       '--allow-unresolved=_Unwind_Backtrace '
103       '--allow-unresolved=_Unwind_DeleteException '
104       '--allow-unresolved=_Unwind_GetCFA '
105       '--allow-unresolved=_Unwind_GetDataRelBase '
106       '--allow-unresolved=_Unwind_GetGR '
107       '--allow-unresolved=_Unwind_GetIP '
108       '--allow-unresolved=_Unwind_GetIPInfo '
109       '--allow-unresolved=_Unwind_GetLanguageSpecificData '
110       '--allow-unresolved=_Unwind_GetRegionStart '
111       '--allow-unresolved=_Unwind_GetTextRelBase '
112       '--allow-unresolved=_Unwind_PNaClSetResult0 '
113       '--allow-unresolved=_Unwind_PNaClSetResult1 '
114       '--allow-unresolved=_Unwind_RaiseException '
115       '--allow-unresolved=_Unwind_Resume '
116       '--allow-unresolved=_Unwind_Resume_or_Rethrow '
117       '--allow-unresolved=_Unwind_SetGR '
118       '--allow-unresolved=_Unwind_SetIP}',
119
120   'BCLD_FLAGS':
121     '--oformat ${BCLD_OFORMAT} -Ttext=0x20000 ' +
122     '${!SHARED && !RELOCATABLE ? --undef-sym-check ${BCLD_ALLOW_UNRESOLVED}} ' +
123     '${GOLD_PLUGIN_ARGS} ${LD_FLAGS}',
124   'RUN_BCLD': ('${LD} ${BCLD_FLAGS} ${inputs} -o ${output}'),
125
126   'ALLOW_CXX_EXCEPTIONS': '0',
127   'ALLOW_NEXE_BUILD_ID': '0',
128   'DISABLE_ABI_CHECK': '0',
129   'LLVM_PASSES_TO_DISABLE': '',
130   # Skip dev intrinsic checks in ABI verifier.  Used for pnacl-llc.pexe and
131   # gold.pexe, which currently use llvm.nacl.target.arch.
132   # TODO(jvoung): find way to stop using llvm.nacl.target.arch.
133   'ALLOW_DEV_INTRINSICS': '0',
134 }
135
136 def AddToBCLinkFlags(*args):
137   env.append('LD_FLAGS', *args)
138
139 def AddToNativeFlags(*args):
140   env.append('LD_FLAGS_NATIVE', *args)
141
142 def AddToBothFlags(*args):
143   env.append('LD_FLAGS', *args)
144   env.append('LD_FLAGS_NATIVE', *args)
145
146 def AddAllowCXXExceptions(*args):
147   env.set('ALLOW_CXX_EXCEPTIONS', '1')
148   env.append('TRANSLATE_FLAGS', *args)
149
150 def SetLibTarget(*args):
151   arch = ParseTriple(args[0])
152   if arch != 'le32':
153     env.set('BCLIB_ARCH', arch)
154
155 def IsPortable():
156   return env.getone('BCLIB_ARCH') == ''
157
158 LDPatterns = [
159   ( '--pnacl-allow-native', "env.set('ALLOW_NATIVE', '1')"),
160   ( '--noirt',              "env.set('USE_IRT', '0')"),
161   ( '(--pnacl-allow-exceptions)', AddAllowCXXExceptions),
162   ( '(--pnacl-allow-nexe-build-id)', "env.set('ALLOW_NEXE_BUILD_ID', '1')"),
163   ( '--pnacl-disable-abi-check', "env.set('DISABLE_ABI_CHECK', '1')"),
164   # "--pnacl-disable-pass" allows an ABI simplification pass to be
165   # disabled if it is causing problems.  These passes are generally
166   # required for ABI-stable pexes but can be omitted when the PNaCl
167   # toolchain is used for producing native nexes.
168   ( '--pnacl-disable-pass=(.+)', "env.append('LLVM_PASSES_TO_DISABLE', $0)"),
169   ( '--pnacl-allow-dev-intrinsics', "env.set('ALLOW_DEV_INTRINSICS', '1')"),
170   ( ('-target', '(.+)'), SetLibTarget),
171   ( ('--target=(.+)'), SetLibTarget),
172
173   ( '-o(.+)',          "env.set('OUTPUT', pathtools.normalize($0))"),
174   ( ('-o', '(.+)'),    "env.set('OUTPUT', pathtools.normalize($0))"),
175
176   ( '-shared',         "env.set('SHARED', '1')"),
177   ( '-static',         "env.set('STATIC', '1')"),
178   ( '-nostdlib',       "env.set('USE_STDLIB', '0')"),
179   ( '-r',              "env.set('RELOCATABLE', '1')"),
180   ( '-relocatable',    "env.set('RELOCATABLE', '1')"),
181
182   ( ('-L', '(.+)'),
183     "env.append('SEARCH_DIRS_USER', pathtools.normalize($0))\n"),
184   ( '-L(.+)',
185     "env.append('SEARCH_DIRS_USER', pathtools.normalize($0))\n"),
186   ( ('--library-path', '(.+)'),
187     "env.append('SEARCH_DIRS_USER', pathtools.normalize($0))\n"),
188
189   # We just ignore undefined symbols in shared objects, so
190   # -rpath-link should not be necessary.
191   #
192   # However, libsrpc.so still needs to be linked in directly (in non-IRT mode)
193   # or it malfunctions. This is the only way that -rpath-link is still used.
194   # There's a corresponding hack in pnacl-translate to recognize libsrpc.so
195   # and link it in directly.
196   # TODO(pdox): Investigate this situation.
197   ( ('(-rpath)','(.*)'), ""),
198   ( ('(-rpath)=(.*)'), ""),
199   ( ('(-rpath-link)','(.*)'),
200     "env.append('TRANSLATE_FLAGS', $0+'='+pathtools.normalize($1))"),
201   ( ('(-rpath-link)=(.*)'),
202     "env.append('TRANSLATE_FLAGS', $0+'='+pathtools.normalize($1))"),
203
204   # This overrides the builtin linker script.
205   ( ('(-T)', '(.*)'),    AddToNativeFlags),
206
207   # TODO(pdox): Allow setting an alternative _start symbol in bitcode
208   ( ('(-e)','(.*)'),     AddToBothFlags),
209
210   # TODO(pdox): Support GNU versioning.
211   ( '(--version-script=.*)', ""),
212
213   # Flags to pass to the native linker.
214   ( '-Wn,(.*)', "env.append('LD_FLAGS_NATIVE', *($0.split(',')))"),
215   ( ('(-Ttext-segment=.*)'), AddToNativeFlags),
216   ( ('(-Trodata-segment=.*)'), AddToNativeFlags),
217   ( ('(--section-start)', '(.+)'), AddToNativeFlags),
218   ( ('(--build-id)'), AddToNativeFlags),
219
220   # Flags to pass to translate
221   ( '-Wt,(.*)', "env.append('TRANSLATE_FLAGS_USER', *($0.split(',')))"),
222
223   # NOTE: -export-dynamic doesn't actually do anything to the bitcode link
224   # right now.  This is just in case we do want to record that in metadata
225   # eventually, and have that influence the native linker flags.
226   ( '(-export-dynamic)', AddToBCLinkFlags),
227
228   ( '-?-soname=(.*)',             "env.set('SONAME', $0)"),
229   ( ('-?-soname', '(.*)'),        "env.set('SONAME', $0)"),
230
231   ( '(-M)',                       AddToBCLinkFlags),
232   ( '(-t)',                       AddToBCLinkFlags),
233   ( ('(-y)','(.*)'),              AddToBCLinkFlags),
234   ( ('(-defsym)','(.*)'),         AddToBCLinkFlags),
235
236   ( '-melf_nacl',            "env.set('ARCH', 'X8632')"),
237   ( ('-m','elf_nacl'),       "env.set('ARCH', 'X8632')"),
238   ( '-melf64_nacl',          "env.set('ARCH', 'X8664')"),
239   ( ('-m','elf64_nacl'),     "env.set('ARCH', 'X8664')"),
240   ( '-marmelf_nacl',         "env.set('ARCH', 'ARM')"),
241   ( ('-m','armelf_nacl'),    "env.set('ARCH', 'ARM')"),
242   ( '-mmipselelf_nacl',      "env.set('ARCH', 'MIPS32')"),
243   ( ('-m','mipselelf_nacl'), "env.set('ARCH', 'MIPS32')"),
244
245   # NOTE: For scons tests, the code generation fPIC flag is used with pnacl-ld.
246   ( '-fPIC',               "env.set('PIC', '1')"),
247
248   # This controls LTO optimization.
249   # opt does not support -Os but internally it is identical to -O2
250   # opt also does not support -O4 but -O4 is how you ask clang for LTO, so we
251   # can support it as well
252   ( '-Os',                 "env.set('OPT_LEVEL', '2')"),
253   ( '-O([0-3])',           "env.set('OPT_LEVEL', $0)"),
254   ( '-O([0-9]+)',          "env.set('OPT_LEVEL', '3')"),
255
256   ( '(-translate-fast)',   "env.append('TRANSLATE_FLAGS', $0)"),
257
258   ( '-s',                  "env.set('STRIP_MODE', 'all')"),
259   ( '--strip-all',         "env.set('STRIP_MODE', 'all')"),
260   ( '-S',                  "env.set('STRIP_MODE', 'debug')"),
261   ( '--strip-debug',       "env.set('STRIP_MODE', 'debug')"),
262
263   ( '-g', ""),
264
265   # Inputs and options that need to be kept in order
266   ( '(-l.*)',              "env.append('INPUTS', $0)"),
267   ( ('(-l)','(.*)'),       "env.append('INPUTS', $0+$1)"),
268   ( '(--no-as-needed)',    "env.append('INPUTS', $0)"),
269   ( '(--as-needed)',       "env.append('INPUTS', $0)"),
270   ( '(--start-group)',     "env.append('INPUTS', $0)"),
271   ( '(--end-group)',       "env.append('INPUTS', $0)"),
272   ( '(-Bstatic)',          "env.append('INPUTS', $0)"),
273   ( '(-Bdynamic)',          "env.append('INPUTS', $0)"),
274   ( '(--(no-)?whole-archive)', "env.append('INPUTS', $0)"),
275   ( '(--undefined=.*)',    "env.append('INPUTS', $0)"),
276   ( '(-.*)',               UnrecognizedOption),
277   ( '(.*)',                "env.append('INPUTS', pathtools.normalize($0))"),
278 ]
279
280 def main(argv):
281   env.update(EXTRA_ENV)
282   ParseArgs(argv, LDPatterns)
283   # If the user passed -arch, then they want native output.
284   arch_flag_given = GetArch() is not None
285
286   # Both LD_FLAGS_NATIVE and TRANSLATE_FLAGS_USER affect
287   # the translation process. If they are non-empty,
288   # then --pnacl-allow-native must be given.
289   allow_native = env.getbool('ALLOW_NATIVE')
290   native_flags = env.get('LD_FLAGS_NATIVE') + env.get('TRANSLATE_FLAGS_USER')
291   if len(native_flags) > 0:
292     if not allow_native:
293       flagstr = ' '.join(native_flags)
294       Log.Fatal('"%s" affects translation. '
295                 'To allow, specify --pnacl-allow-native' % flagstr)
296
297   if env.getbool('ALLOW_NATIVE') and not arch_flag_given:
298       Log.Fatal("--pnacl-allow-native given, but translation "
299                 "is not happening (missing -arch?)")
300
301   # Overriding the lib target uses native-flavored bitcode libs rather than the
302   # portable bitcode libs. It is currently only tested/supported for
303   # building the IRT.
304   if not IsPortable():
305     env.set('BASE_USR', "${BASE_USR_ARCH}")
306     env.set('BASE_LIB', "${BASE_LIB_ARCH}")
307
308   if env.getbool('RELOCATABLE'):
309     if env.getbool('SHARED'):
310       Log.Fatal("-r and -shared may not be used together")
311     env.set('STATIC', '0')
312
313   inputs = env.get('INPUTS')
314   output = env.getone('OUTPUT')
315
316   if output == '':
317     output = pathtools.normalize('a.out')
318
319   if not arch_flag_given:
320     # If -arch is not given, assume X86-32.
321     # This is because gold requires an arch (even for bitcode linking).
322     SetArch('X8632')
323   assert(GetArch() is not None)
324
325   # Expand all parameters
326   # This resolves -lfoo into actual filenames,
327   # and expands linker scripts into command-line arguments.
328   inputs = ldtools.ExpandInputs(inputs,
329                                 env.get('SEARCH_DIRS'),
330                                 env.getbool('STATIC'),
331                                 # Once all glibc bitcode link is purely
332                                 # bitcode (e.g., even libc_nonshared.a)
333                                 # we may be able to restrict this more.
334                                 # This is also currently used by
335                                 # pnacl_generate_pexe=0 with glibc,
336                                 # for user libraries.
337                                 ldtools.LibraryTypes.ANY)
338
339   # Make sure the inputs have matching arch.
340   CheckInputsArch(inputs)
341
342   regular_inputs, native_objects = SplitLinkLine(inputs)
343
344   if not env.getbool('USE_IRT'):
345     inputs = UsePrivateLibraries(inputs)
346
347   inputs = ReorderPrivateLibs(inputs)
348
349   if env.getbool('SHARED'):
350     bitcode_type = 'pso'
351     native_type = 'so'
352   elif env.getbool('RELOCATABLE'):
353     bitcode_type = 'po'
354     native_type = 'o'
355   else:
356     bitcode_type = 'pexe'
357     native_type = 'nexe'
358
359   if native_objects and not allow_native:
360     argstr = ' '.join(native_objects)
361     Log.Fatal("Native objects '%s' detected in the link. "
362               "To allow, specify --pnacl-allow-native" % argstr)
363
364   tng = TempNameGen([], output)
365
366   # Do the bitcode link.
367   if HasBitcodeInputs(inputs):
368     chain = DriverChain(inputs, output, tng)
369     chain.add(LinkBC, 'pre_opt.' + bitcode_type)
370
371     # Some ABI simplification passes assume the whole program is
372     # available (e.g. -expand-varargs, -nacl-expand-ctors and
373     # -nacl-expand-tls).  While we could try running a subset of
374     # simplification passes when linking native objects, we don't
375     # do this because it complicates testing.  For example,
376     # it requires '-expand-constant-expr' to be able to handle
377     # 'landingpad' instructions.
378     # However, if we aren't using biased bitcode, then at least -expand-byval
379     # must be run to work with the PPAPI shim calling convention.
380     # This assumes that PPAPI does not use var-args, so passes like
381     # -expand-varargs and other calling-convention-changing passes are
382     # not needed.
383     abi_simplify = (env.getbool('STATIC') and
384                     len(native_objects) == 0 and
385                     not env.getbool('ALLOW_CXX_EXCEPTIONS') and
386                     not env.getbool('ALLOW_NEXE_BUILD_ID') and
387                     IsPortable())
388     still_need_expand_byval = IsPortable()
389
390     preopt_passes = []
391     if abi_simplify:
392       preopt_passes += ['-pnacl-abi-simplify-preopt']
393     elif not env.getbool('ALLOW_CXX_EXCEPTIONS'):
394       # '-lowerinvoke' prevents use of C++ exception handling, which
395       # is not yet supported in the PNaCl ABI.  '-simplifycfg' removes
396       # landingpad blocks made unreachable by '-lowerinvoke'.
397       #
398       # We run this in order to remove 'resume' instructions,
399       # otherwise these are translated to calls to _Unwind_Resume(),
400       # which will not be available at native link time.
401       preopt_passes += ['-lowerinvoke', '-simplifycfg']
402     if len(preopt_passes) != 0:
403       chain.add(DoLLVMPasses(preopt_passes), 'simplify_preopt.' + bitcode_type)
404
405     if env.getone('OPT_LEVEL') != '' and env.getone('OPT_LEVEL') != '0':
406       chain.add(DoLTO, 'opt.' + bitcode_type)
407     elif env.getone('STRIP_MODE') != 'none':
408       chain.add(DoStrip, 'stripped.' + bitcode_type)
409
410     postopt_passes = []
411     if abi_simplify:
412       postopt_passes = ['-pnacl-abi-simplify-postopt']
413       if not env.getbool('DISABLE_ABI_CHECK'):
414         postopt_passes += [
415             '-verify-pnaclabi-module',
416             '-verify-pnaclabi-functions',
417             # A flag for the above -verify-pnaclabi-* passes.
418             '-pnaclabi-allow-debug-metadata']
419         if env.getbool('ALLOW_DEV_INTRINSICS'):
420           # A flag for the above -verify-pnaclabi-* passes.
421           postopt_passes += ['-pnaclabi-allow-dev-intrinsics']
422     elif still_need_expand_byval:
423       # We may still need -expand-byval to match the PPAPI shim
424       # calling convention.
425       postopt_passes = ['-expand-byval']
426     if len(postopt_passes) != 0:
427       chain.add(DoLLVMPasses(postopt_passes),
428                 'simplify_postopt.' + bitcode_type)
429   else:
430     chain = DriverChain('', output, tng)
431
432   # If -arch is also specified, invoke pnacl-translate afterwards.
433   if arch_flag_given:
434     env.set('NATIVE_OBJECTS', *native_objects)
435     chain.add(DoTranslate, native_type)
436
437   chain.run()
438
439   if bitcode_type == 'pexe' and not arch_flag_given:
440     # Mark .pexe files as executable.
441     # Some versions of 'configure' expect this.
442     SetExecutableMode(output)
443   return 0
444
445 def UsePrivateLibraries(libs):
446   """ Place libnacl_sys_private.a before libnacl.a
447   Replace libpthread.a with libpthread_private.a
448   Replace libnacl_dyncode.a with libnacl_dyncode_private.a
449   This assumes that the private libs can be found at the same directory
450   as the public libs.
451   """
452   result_libs = []
453   for l in libs:
454     base = pathtools.basename(l)
455     dname = pathtools.dirname(l)
456     if base == 'libnacl.a':
457       Log.Info('Not using IRT -- injecting libnacl_sys_private.a to link line')
458       result_libs.append(pathtools.join(dname, 'libnacl_sys_private.a'))
459       result_libs.append(l)
460     elif base == 'libpthread.a':
461       Log.Info('Not using IRT -- swapping private lib for libpthread')
462       result_libs.append(pathtools.join(dname, 'libpthread_private.a'))
463     elif base == 'libnacl_dyncode.a':
464       Log.Info('Not using IRT -- swapping private lib for libnacl_dyncode')
465       result_libs.append(pathtools.join(dname, 'libnacl_dyncode_private.a'))
466     else:
467       result_libs.append(l)
468   return result_libs
469
470 def ReorderPrivateLibs(libs):
471   """ Place private libraries just before their non-private equivalent
472   if there is one.
473   """
474   result_libs = list(libs)
475   bases = {}
476   for l in libs:
477     bases[pathtools.basename(l)] = l
478   lib_map = {
479       'libnacl_sys_private.a': 'libnacl.a',
480       'libpthread_private.a': 'libpthread.a',
481       'libnacl_dyncode_private.a': 'libnacl_dyncode.a'
482       }
483   for l in libs:
484     base = pathtools.basename(l)
485     if base in lib_map and lib_map[base] in bases:
486       result_libs.remove(l)
487       result_libs.insert(result_libs.index(bases[lib_map[base]]), l)
488   return result_libs
489
490 def SplitLinkLine(inputs):
491   """ Split the input list into bitcode and native objects (.o, .a)
492   """
493   normal = []
494   native = []
495   # Group flags need special handling because they need to go into the right
496   # list based on the type of the inputs in the group. If the group has both
497   # native and bitcode files (which is unfortunately the case for
498   # irt_browser_lib) then the group flags need to go in both lists.
499   if '--start-group' in inputs:
500     start_group = inputs.index('--start-group')
501     # Start with the inputs before the first group
502     normal, native = SplitLinkLine(inputs[:start_group])
503     try:
504       end_group = inputs.index('--end-group')
505     except ValueError:
506       Log.Fatal("Found --start-group without matching --end-group")
507     # Add the contents of the group together with the --{start,end}-group flags
508     norm_group, native_group = SplitLinkLine(inputs[start_group + 1:end_group])
509     if len(norm_group) > 0:
510       normal.extend(['--start-group'] + norm_group + ['--end-group'])
511     if len(native_group) > 0:
512       native.extend(['--start-group'] + native_group + ['--end-group'])
513     # Add the inputs after the first group
514     norm_last, native_last = SplitLinkLine(inputs[end_group + 1:])
515     return normal + norm_last, native + native_last
516
517   # If no groups, split the inputs based on their type.
518   for f in inputs:
519     if ldtools.IsFlag(f):
520       normal.append(f)
521     elif filetype.IsNativeArchive(f) or filetype.IsNativeObject(f):
522       native.append(f)
523     else:
524       normal.append(f)
525   return (normal, native)
526
527 def HasBitcodeInputs(inputs):
528   for f in inputs:
529     if ldtools.IsFlag(f):
530       continue
531     elif filetype.IsLLVMBitcode(f) or filetype.IsBitcodeArchive(f):
532       return True
533   return False
534
535 def CheckInputsArch(inputs):
536   count = 0
537   for f in inputs:
538     if ldtools.IsFlag(f):
539       continue
540     elif filetype.IsLLVMBitcode(f) or filetype.IsBitcodeArchive(f):
541       pass
542     elif filetype.IsNative(f):
543       ArchMerge(f, True)
544     else:
545       Log.Fatal("%s: Unexpected type of file for linking (%s)",
546                 pathtools.touser(f), FileType(f))
547     count += 1
548
549   if count == 0:
550     Log.Fatal("no input files")
551
552 def DoLLVMPasses(pass_list):
553   def Func(infile, outfile):
554     filtered_list = [pass_option for pass_option in pass_list
555                      if pass_option not in env.get('LLVM_PASSES_TO_DISABLE')]
556     RunDriver('opt', filtered_list + [infile, '-o', outfile])
557   return Func
558
559 def DoLTO(infile, outfile):
560   opt_flags = env.get('OPT_FLAGS')
561   RunDriver('opt', opt_flags + [ infile, '-o', outfile ])
562
563 def DoStrip(infile, outfile):
564   strip_flags = env.get('STRIP_FLAGS')
565   RunDriver('strip', strip_flags + [ infile, '-o', outfile ])
566
567 def DoTranslate(infile, outfile):
568   args = env.get('TRANSLATE_FLAGS')
569   args += ['-Wl,'+s for s in env.get('LD_FLAGS_NATIVE')]
570   if infile:
571     args += [infile]
572   args += ['-Wl,'+s if ldtools.IsFlag(s) else s
573            for s in env.get('NATIVE_OBJECTS')]
574   args += ['-o', outfile]
575   RunDriver('translate', args)
576
577 def LinkBC(inputs, output):
578   '''Input: a bunch of bc/o/lib input files
579      Output: a combined & optimized bitcode file
580   '''
581   # Produce combined bitcode file
582   RunWithEnv('${RUN_BCLD}',
583              inputs=inputs,
584              output=output)
585
586 def get_help(unused_argv):
587   return """Usage: pnacl-ld [options] <input files> -o <output>
588
589 Bitcode linker for PNaCl.  Similar to the binutils "ld" tool,
590 but links bitcode instead of native code.  Supports many of the
591 "ld" flags.
592
593 OPTIONS:
594
595   -o <file>                   Set output file name
596   -l LIBNAME                  Search for library LIBNAME
597   -L DIRECTORY, --library-path DIRECTORY
598                               Add DIRECTORY to library search path
599
600   -r, --relocatable           Generate relocatable output
601
602   -O<opt-level>               Optimize output file
603   -M, --print-map             Print map file on standard output
604   --whole-archive             Include all objects from following archives
605   --no-whole-archive          Turn off --whole-archive
606   -s, --strip-all             Strip all symbols
607   -S, --strip-debug           Strip debugging symbols
608   --undefined SYMBOL          Start with undefined reference to SYMBOL
609
610   -help | -h                  Output this help.
611 """