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