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