Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Unified Diff: tools/llvm/driver/pnacl-ld.py

Issue 8395028: Move tools/llvm/driver to pnacl/driver. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client/
Patch Set: Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/llvm/driver/pnacl-illegal.py ('k') | tools/llvm/driver/pnacl-meta.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/llvm/driver/pnacl-ld.py
===================================================================
--- tools/llvm/driver/pnacl-ld.py (revision 7025)
+++ tools/llvm/driver/pnacl-ld.py (working copy)
@@ -1,880 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) 2011 The Native Client Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# IMPORTANT NOTE: If you make local mods to this file, you must run:
-# % tools/llvm/utman.sh driver
-# in order for them to take effect in the scons build. This command
-# updates the copy in the toolchain/ tree.
-#
-
-from driver_tools import *
-import platform
-import random
-import hashlib
-
-if not IsWindowsPython():
- import fcntl
-
-EXTRA_ENV = {
- 'NATIVE_HACK' : '0', # Only link native code, ignore bitcode libraries.
- #
- # This is currently only used for translating .pexe's
- # which are linked against glibc. Since they continue
- # to have native object dependencies, they have to go
- # through pnacl-gcc again, followed by pnacl-ld.
- # But since we know the bitcode dependencies have
- # already been linked in, we remove those from the
- # link line with this flag.
-
- 'WHICH_LD' : 'BFD', # Which ld to use for native linking: GOLD or BFD
-
- 'INPUTS' : '',
- 'OUTPUT' : '',
-
- # Library dependencies to add (as DT_NEEDED records)
- # This only applies to native dynamic/shared linking.
- # This is used during pso -> so translation to set the
- # correct dependencies on the generated ELF file.
- 'LIBDEPS' : '',
-
- 'SHARED' : '0',
- 'STATIC' : '0',
- 'PIC' : '0',
- 'STDLIB' : '1',
- 'RELOCATABLE': '0',
-
- 'BAREBONES_LINK' : '0',
-
- 'STRIP_MODE' : 'none',
-
- 'STRIP_FLAGS' : '${STRIP_FLAGS_%STRIP_MODE%}',
- 'STRIP_FLAGS_all' : '-s',
- 'STRIP_FLAGS_debug': '-S',
-
- 'PNACL_TRANSLATE_FLAGS': '${PIC ? -fPIC}',
-
- 'OPT_FLAGS': '-O${OPT_LEVEL} ${OPT_STRIP_%STRIP_MODE%} ' +
- '-inline-threshold=${OPT_INLINE_THRESHOLD}',
- 'OPT_INLINE_THRESHOLD': '100',
- 'OPT_LEVEL': '0',
- 'OPT_STRIP_none': '',
- 'OPT_STRIP_all': '-disable-opt --strip',
- 'OPT_STRIP_debug': '-disable-opt --strip-debug',
-
- # Sandboxed LD is always BFD.
- 'LD' : '${SANDBOXED ? ${LD_SB} ${LD_BFD_FLAGS} ' +
- ' : ${LD_%WHICH_LD%} ${LD_%WHICH_LD%_FLAGS}}',
-
- 'LD_BFD_FLAGS': '-m ${LD_EMUL} ${#LD_SCRIPT ? -T ${LD_SCRIPT}}',
-
- 'LD_GOLD_FLAGS': '--native-client --oformat ${LD_GOLD_OFORMAT} ' +
- '${#LD_SCRIPT ? -T ${LD_SCRIPT} : -Ttext=0x20000}',
-
- 'GOLD_PLUGIN_ARGS': '-plugin=${GOLD_PLUGIN_SO} ' +
- '-plugin-opt=emit-llvm ' +
- '${LIBMODE_NEWLIB && !BAREBONES_LINK ? ' +
- '-plugin-opt=-add-nacl-read-tp-dependency ' +
- '-plugin-opt=-add-libgcc-dependencies}',
-
- # Symbols to wrap
- 'WRAP_SYMBOLS': '',
-
- # Common to both GOLD and BFD.
- 'LD_FLAGS' : '-nostdlib ${@AddPrefix:-L:SEARCH_DIRS} ' +
- '${SHARED ? -shared} ${STATIC ? -static} ' +
- '${RELOCATABLE ? -relocatable} ' +
- '${LIBMODE_GLIBC && ' +
- '!STATIC ? ${@AddPrefix:-rpath-link=:SEARCH_DIRS}}',
-
-
-
- 'SEARCH_DIRS' : '${SEARCH_DIRS_USER} ${SEARCH_DIRS_BUILTIN}',
- 'SEARCH_DIRS_USER' : '',
- 'SEARCH_DIRS_BUILTIN': '${STDLIB ? ' +
- '${LIBS_SDK_BC}/ ${LIBS_SDK_ARCH}/ ' +
- '${LIBS_ARCH}/ ${LIBS_BC}/}',
-
- # Standard Library Directories
- 'LIBS_BC' : '${BASE}/lib',
-
- 'LIBS_ARCH' : '${LIBS_%ARCH%}',
- 'LIBS_ARM' : '${BASE}/lib-arm',
- 'LIBS_X8632' : '${BASE}/lib-x86-32',
- 'LIBS_X8664' : '${BASE}/lib-x86-64',
-
- 'LIBS_SDK_BC' : '${BASE_SDK}/lib',
-
- 'LIBS_SDK_ARCH' : '${LIBS_SDK_%ARCH%}',
- 'LIBS_SDK_X8632' : '${BASE_SDK}/lib-x86-32',
- 'LIBS_SDK_X8664' : '${BASE_SDK}/lib-x86-64',
- 'LIBS_SDK_ARM' : '${BASE_SDK}/lib-arm',
-
-
- 'LD_GOLD_OFORMAT' : '${LD_GOLD_OFORMAT_%ARCH%}',
- 'LD_GOLD_OFORMAT_ARM' : 'elf32-littlearm',
- 'LD_GOLD_OFORMAT_X8632' : 'elf32-nacl',
- 'LD_GOLD_OFORMAT_X8664' : 'elf64-nacl',
-
- 'LD_EMUL' : '${LD_EMUL_%ARCH%}',
- 'LD_EMUL_ARM' : 'armelf_nacl',
- 'LD_EMUL_X8632' : 'elf_nacl',
- 'LD_EMUL_X8664' : 'elf64_nacl',
-
- 'EMITMODE' : '${RELOCATABLE ? relocatable : ' +
- '${STATIC ? static : ' +
- '${SHARED ? shared : dynamic}}}',
-
- 'LD_SCRIPT' : '${LD_SCRIPT_%LIBMODE%_%EMITMODE%}',
-
- # For newlib, omit the -T flag (the builtin linker script works fine).
- 'LD_SCRIPT_newlib_static': '',
-
- # For glibc, the linker script is always explicitly specified.
- 'LD_SCRIPT_glibc_static' : '${LD_EMUL}.x.static',
- 'LD_SCRIPT_glibc_shared' : '${LD_EMUL}.xs',
- 'LD_SCRIPT_glibc_dynamic': '${LD_EMUL}.x',
-
- 'LD_SCRIPT_newlib_relocatable': '',
- 'LD_SCRIPT_glibc_relocatable' : '',
-
- 'BCLD' : '${LD_GOLD}',
- 'BCLD_FLAGS': '${LD_GOLD_FLAGS} ' +
- '${!SHARED && !RELOCATABLE ? --undef-sym-check} ' +
- '${GOLD_PLUGIN_ARGS} ${LD_FLAGS}',
-
-
- 'LIBDEPS_FLAGS': '${@AddPrefix:--add-extra-dt-needed :LIBDEPS}',
-
- 'RUN_LD' : '${LD} ${LD_FLAGS} ${LIBDEPS_FLAGS} ${inputs} -o "${output}"',
-
- 'RUN_BCLD': ('${BCLD} ${BCLD_FLAGS} ${inputs} '
- '-o "${output}"'),
-}
-env.update(EXTRA_ENV)
-
-LDPatterns = [
- ( '--pnacl-native-hack', "env.set('NATIVE_HACK', '1')"),
- ( '--pnacl-add-libdep=(.+)', "env.append('LIBDEPS', $0)"),
- ( ('--add-translate-option=(.+)'),
- "env.append('PNACL_TRANSLATE_FLAGS', $0)"),
- # todo(dschuff): get rid of this when we get closer to tip and fix bug 1941
- ( ('--add-opt-option=(.+)'),
- "env.append('OPT_FLAGS', $0)"),
-
- ( '-o(.+)', "env.set('OUTPUT', pathtools.normalize($0))"),
- ( ('-o', '(.+)'), "env.set('OUTPUT', pathtools.normalize($0))"),
-
- ( '-barebones-link', "env.set('BAREBONES_LINK', '1')"),
-
- ( '-shared', "env.set('SHARED', '1')"),
-
- ( '-static', "env.set('STATIC', '1')\n"
- "env.set('SHARED', '0')"),
- ( '-nostdlib', "env.set('STDLIB', '0')"),
-
- ( '-r', "env.set('RELOCATABLE', '1')"),
- ( '-relocatable', "env.set('RELOCATABLE', '1')"),
-
- ( ('-L', '(.+)'),
- "env.append('SEARCH_DIRS_USER', pathtools.normalize($0))\n"),
- ( '-L(.+)',
- "env.append('SEARCH_DIRS_USER', pathtools.normalize($0))\n"),
-
- ( ('(-rpath)','(.*)'),
- "env.append('LD_FLAGS', $0+'='+pathtools.normalize($1))"),
- ( ('(-rpath)=(.*)'),
- "env.append('LD_FLAGS', $0+'='+pathtools.normalize($1))"),
-
- ( ('(-rpath-link)','(.*)'),
- "env.append('LD_FLAGS', $0+'='+pathtools.normalize($1))"),
- ( ('(-rpath-link)=(.*)'),
- "env.append('LD_FLAGS', $0+'='+pathtools.normalize($1))"),
-
- ( ('(-Ttext)','(.*)'), "env.append('LD_FLAGS', $0, $1)"),
- ( ('(-Ttext=.*)'), "env.append('LD_FLAGS', $0)"),
-
- # This overrides the builtin linker script.
- ( ('-T', '(.*)'), "env.set('LD_SCRIPT', pathtools.normalize($0))"),
-
- ( ('-e','(.*)'), "env.append('LD_FLAGS', '-e', $0)"),
- ( ('(--section-start)','(.*)'), "env.append('LD_FLAGS', $0, $1)"),
- ( '(-?-soname=.*)', "env.append('LD_FLAGS', $0)"),
- ( ('(-?-soname)', '(.*)'), "env.append('LD_FLAGS', $0, $1)"),
- ( '(--eh-frame-hdr)', "env.append('LD_FLAGS', $0)"),
- ( '(-M)', "env.append('LD_FLAGS', $0)"),
- ( '(-t)', "env.append('LD_FLAGS', $0)"),
- ( ('-y','(.*)'), "env.append('LD_FLAGS', '-y', $0)"),
- ( ('-defsym','(.*)'), "env.append('LD_FLAGS', '-defsym', $0)"),
-
- ( '(--print-gc-sections)', "env.append('LD_FLAGS', $0)"),
- ( '(-gc-sections)', "env.append('LD_FLAGS', $0)"),
- ( '(--unresolved-symbols=.*)', "env.append('LD_FLAGS', $0)"),
-
- ( '-melf_nacl', "env.set('ARCH', 'X8632')"),
- ( ('-m','elf_nacl'), "env.set('ARCH', 'X8632')"),
- ( '-melf64_nacl', "env.set('ARCH', 'X8664')"),
- ( ('-m','elf64_nacl'), "env.set('ARCH', 'X8664')"),
- ( '-marmelf_nacl', "env.set('ARCH', 'ARM')"),
- ( ('-m','armelf_nacl'), "env.set('ARCH', 'ARM')"),
-
- ( ('-?-wrap', '(.+)'), "env.append('WRAP_SYMBOLS', $0)"),
- ( ('-?-wrap=(.+)'), "env.append('WRAP_SYMBOLS', $0)"),
-
- # NOTE: For scons tests, the code generation fPIC flag is used with pnacl-ld.
- ( '-fPIC', "env.set('PIC', '1')"),
-
- # This controls LTO optimization.
- # opt does not support -Os but internally it is identical to -O2
- # opt also does not support -O4 but -O4 is how you ask llvm-gcc for LTO, so we
- # can support it as well
- ( '-Os', "env.set('OPT_LEVEL', '2')"),
- ( '-O4', "env.set('OPT_LEVEL', '3')"),
- ( '-O([0-3])', "env.set('OPT_LEVEL', $0)"),
-
- ( '-s', "env.append('STRIP_MODE', 'all')"),
- ( '--strip-all', "env.append('STRIP_MODE', 'all')"),
- ( '-S', "env.append('STRIP_MODE', 'debug')"),
- ( '--strip-debug', "env.append('STRIP_MODE', 'debug')"),
-
- # Inputs and options that need to be kept in order
- ( '(-l.*)', "env.append('INPUTS', $0)"),
- ( ('(-l)','(.*)'), "env.append('INPUTS', $0+$1)"),
- ( '(--no-as-needed)', "env.append('INPUTS', $0)"),
- ( '(--as-needed)', "env.append('INPUTS', $0)"),
- ( '(--start-group)', "env.append('INPUTS', $0)"),
- ( '(--end-group)', "env.append('INPUTS', $0)"),
- ( '(-Bstatic)', "env.append('INPUTS', $0)"),
- ( '(-Bdynamic)', "env.append('INPUTS', $0)"),
- ( '(--(no-)?whole-archive)', "env.append('INPUTS', $0)"),
- ( '(-.*)', UnrecognizedOption),
- ( '(.*)', "env.append('INPUTS', pathtools.normalize($0))"),
-]
-
-
-def main(argv):
- ParseArgs(argv, LDPatterns)
-
- if env.getbool('RELOCATABLE'):
- if env.getbool('SHARED'):
- Log.Fatal("-r and -shared may not be used together")
- env.set('STATIC', '0')
- env.set('BAREBONES_LINK', '1')
-
- if env.getbool('LIBMODE_NEWLIB'):
- if env.getbool('SHARED'):
- Log.Fatal("Cannot generate shared objects with newlib-based toolchain")
- env.set('STATIC', '1')
-
- inputs = env.get('INPUTS')
- output = env.getone('OUTPUT')
-
- if output == '':
- output = pathtools.normalize('a.out')
-
- # If the user passed -arch, then they want native output.
- arch_flag_given = GetArch() is not None
-
- if not arch_flag_given:
- # If the arch flag was not given, we must auto-detect the link arch.
- # This is for two reasons:
- # 1) gold (for bitcode linking) requires an architecture
- # 2) we don't know which standard search directories to use
- # until ARCH is correctly set. (see SEARCH_DIRS_BUILTIN)
- DetectArch(inputs)
-
- assert(GetArch() is not None)
-
- # If there's a linker script which needs to be searched for, find it.
- LocateLinkerScript()
-
- # Expand all -l flags
- ExpandLibFlags(inputs)
-
- # Expand input files which are linker scripts
- inputs = ExpandLinkerScripts(inputs)
-
- if env.getbool('LIBMODE_GLIBC'):
- TranslateInputs(inputs)
-
- # NATIVE HACK
- native_left, native_right = RemoveBitcode(inputs)
- if env.getbool('NATIVE_HACK'):
- inputs = native_left + native_right
- # END NATIVE HACK
-
- has_native, has_bitcode = AnalyzeInputs(inputs)
-
- # If there is bitcode, we do a bitcode link. If -arch is also specified,
- # we invoke pnacl-translate afterwards.
- if has_bitcode:
- if env.getbool('SHARED'):
- bitcode_type = 'pso'
- native_type = 'so'
- elif env.getbool('RELOCATABLE'):
- bitcode_type = 'po'
- native_type = 'o'
- else:
- bitcode_type = 'pexe'
- native_type = 'nexe'
- elif has_native:
- # If there is no bitcode, then we do a native link only.
- if not arch_flag_given:
- Log.Fatal("Native linking requires -arch")
- else:
- Log.Fatal("No input objects")
-
- # Path A: Bitcode link, then opt, then translate.
- if has_bitcode:
- tng = TempNameGen([], output)
- chain = DriverChain(inputs, output, tng)
- chain.add(LinkBC, 'pre_opt.' + bitcode_type)
- if NeedsWrap():
- chain.add(WrapDIS, 'before_wrap.ll')
- chain.add(WrapLL, 'after_wrap.ll')
- chain.add(WrapAS, 'after_wrap.' + bitcode_type)
- if env.getone('OPT_LEVEL') != '0':
- chain.add(DoOPT, 'opt.' + bitcode_type)
- elif env.getone('STRIP_MODE') != 'none':
- chain.add(DoStrip, 'stripped.' + bitcode_type)
- if arch_flag_given:
- # TODO(pdox): This should call pnacl-translate and nothing
- # else. However, since we still use native objects in the
- # scons and gcc builds, and special LD flags, we can't
- # translate without including these extra libraries/flags.
- chain.add(DoTranslate, 'o', mode = '-c')
- chain.add(DoNativeLink, native_type,
- native_left = native_left,
- native_right = native_right)
- chain.run()
- return 0
- else:
- # Path B: Native link only
- LinkNative(inputs, output)
-
- return 0
-
-def IsLib(arg):
- return arg.startswith('-l')
-
-def IsFlag(arg):
- return arg.startswith('-') and not IsLib(arg)
-
-def IsUndefMarker(arg):
- return arg.startswith('--undefined=')
-
-def ExpandLibFlags(inputs):
- for i in xrange(len(inputs)):
- f = inputs[i]
- if IsFlag(f):
- continue
- if IsLib(f):
- inputs[i] = FindLib(f)
-
-def LocateLinkerScript():
- ld_script = env.getone('LD_SCRIPT')
- if not ld_script:
- # No linker script specified
- return
-
- if ld_script.startswith('/'):
- # Already absolute path
- return
-
- search_dirs = env.get('SEARCH_DIRS')
- path = FindFile([ld_script], search_dirs)
- if not path:
- Log.Fatal("Unable to find linker script '%s'", ld_script)
-
- env.set('LD_SCRIPT', path)
-
-def FindFirstLinkerScriptInput(inputs):
- for i in xrange(len(inputs)):
- f = inputs[i]
- if IsFlag(f):
- continue
- if FileType(f) == 'ldscript':
- return (i, f)
-
- return (None, None)
-
-def ExpandLinkerScripts(inputs):
- while True:
- # Find a ldscript in the input list
- i, path = FindFirstLinkerScriptInput(inputs)
-
- # If none, we are done.
- if path is None:
- break
-
- new_inputs = ldtools.ParseLinkerScript(path)
- ExpandLibFlags(new_inputs)
- inputs = inputs[:i] + new_inputs + inputs[i+1:]
-
- # Handle --undefined=sym
- ret = []
- for f in inputs:
- if IsUndefMarker(f):
- env.append('LD_FLAGS', f)
- else:
- ret.append(f)
-
- return ret
-
-def IsBitcodeInput(f):
- if IsFlag(f):
- return False
- # .pso files are not considered bitcode input because
- # they are translated to .so before invoking ld
- return IsBitcodeArchive(f) or FileType(f) == 'po'
-
-def RemoveBitcode(inputs):
- # Library order is important. We need to reinsert the
- # bitcode translation object in between the objects on
- # the left and the objects/libraries on the right.
- left = []
- right = []
- found_bc = False
- for f in inputs:
- if IsBitcodeInput(f):
- found_bc = True
- continue
- if not found_bc:
- left.append(f)
- else:
- right.append(f)
-
- return (left,right)
-
-# Determine the kind of input files.
-# Make sure the input files are valid.
-# Make sure the input files have matching architectures.
-# Returns (has_native, has_bitcode)
-def AnalyzeInputs(inputs):
- has_native = False
- has_bitcode = False
- count = 0
-
- for f in inputs:
- if IsFlag(f):
- continue
- elif IsBitcodeInput(f):
- has_bitcode |= True
- elif IsNative(f):
- ArchMerge(f, True)
- has_native |= True
- elif IsNativeArchive(f):
- ArchMerge(f, True)
- has_native |= True
- elif FileType(f) == 'pso':
- pass
- else:
- Log.Fatal("%s: Unexpected type of file for linking (%s)",
- pathtools.touser(f), FileType(f))
- count += 1
-
- if count == 0:
- Log.Fatal("no input files")
-
- return (has_native, has_bitcode)
-
-def DetectArch(inputs):
- # Scan the inputs looking for a native file (.o or .so).
- # At this point, library searches can only use the directories passed in
- # with -L. Since we can't search the arch-specific standard search
- # directories, there may be missing libraries, which we must ignore.
- search_dirs = env.get('SEARCH_DIRS_USER')
-
- for f in inputs:
- if IsFlag(f):
- continue
- if IsLib(f):
- f = FindLib(f, search_dirs, must_find = False)
- if not f:
- # Ignore missing libraries
- continue
-
- # TODO(pdox): If needed, we could also grab ARCH from linker scripts,
- # either directly (using OUTPUT_ARCH or OUTPUT_FORMAT) or
- # indirectly by expanding the linker script's INPUTS/GROUP.
- if IsNative(f) or IsNativeArchive(f):
- ArchMerge(f, True)
- return
-
- # If we've reached here, there are no externally-specified native objects.
- # It should be safe to assume the default neutral architecture.
- SetArch('X8632')
- return
-
-
-def RunLDSRPC():
- CheckTranslatorPrerequisites()
- # The "main" input file is the application's combined object file.
- all_inputs = env.get('inputs')
-
- #############################################################
- # This is kind of arbitrary, but we need to treat one file as
- # the "main" file for sandboxed LD. When this code moves into
- # pnacl-translate, the selection of the main_input will be the
- # object emitted by llc. This make a lot more sense.
- objects = filter(lambda u: u.endswith('.o'), all_inputs)
- if len(objects) == 0:
- print "Sandboxed LD requires at least one .o file"
- main_input = objects[0]
- #############################################################
-
- outfile = env.getone('output')
-
- assert(main_input != '')
- files = LinkerFiles(all_inputs)
- ld_flags = env.get('LD_FLAGS') + env.get('LD_BFD_FLAGS')
-
- # In this mode, we assume we only use the builtin linker script.
- assert(env.getone('LD_SCRIPT') == '')
- script = MakeSelUniversalScriptForLD(ld_flags,
- main_input,
- files,
- outfile)
-
- RunWithLog('${SEL_UNIVERSAL_PREFIX} ${SEL_UNIVERSAL} ' +
- '${SEL_UNIVERSAL_FLAGS} -- ${LD_SRPC}',
- stdin=script, echo_stdout = False, echo_stderr = False)
-
-def MakeSelUniversalScriptForFile(filename):
- """ Return sel_universal script text for sending a commandline argument
- representing an input file to LD.nexe. """
- script = []
- basename = pathtools.basename(filename)
- # A nice name for making a sel_universal variable.
- # Hopefully this does not clash...
- nicename = basename.replace('.','_').replace('-','_')
- script.append('echo "adding %s"' % basename)
- script.append('readonly_file %s %s' % (nicename, filename))
- script.append('rpc AddFile s("%s") h(%s) *' % (basename, nicename))
- script.append('rpc AddArg s("%s") *' % basename)
- return script
-
-
-def MakeSelUniversalScriptForLD(ld_flags,
- main_input,
- files,
- outfile):
- """ Return sel_universal script text for invoking LD.nexe with the
- given ld_flags, main_input (which is treated specially), and
- other input files. The output will be written to outfile. """
- script = []
-
- # Go through all the arguments and add them.
- # Based on the format of RUN_LD, the order of arguments is:
- # ld_flags, then input files (which are more sensitive to order).
- # Omit the "-o" for output so that it will use "a.out" internally.
- # We will take the fd from "a.out" and write it to the proper -o filename.
- for flag in ld_flags:
- script.append('rpc AddArg s("%s") *' % flag)
- script.append('')
-
- # We need to virtualize these files.
- for f in files:
- if f == main_input:
- # Reload the temporary main_input object file into a new shmem region.
- basename = pathtools.basename(f)
- script.append('file_size %s in_size' % f)
- script.append('shmem in_file in_addr ${in_size}')
- script.append('load_from_file %s ${in_addr} 0 ${in_size}' % f)
- script.append('rpc AddFileWithSize s("%s") h(in_file) i(${in_size}) *' %
- basename)
- script.append('rpc AddArg s("%s") *' % basename)
- else:
- script += MakeSelUniversalScriptForFile(f)
- script.append('')
-
- script.append('rpc Link * h() i()')
- script.append('set_variable out_file ${result0}')
- script.append('set_variable out_size ${result1}')
- script.append('map_shmem ${out_file} out_addr')
- script.append('save_to_file %s ${out_addr} 0 ${out_size}' % outfile)
- script.append('echo "ld complete"')
- script.append('')
- return '\n'.join(script)
-
-def DoOPT(infile, outfile):
- opt_flags = env.get('OPT_FLAGS')
- RunDriver('pnacl-opt', opt_flags + [ infile, '-o', outfile ])
-
-def DoStrip(infile, outfile):
- strip_flags = env.get('STRIP_FLAGS')
- RunDriver('pnacl-strip', strip_flags + [ infile, '-o', outfile ])
-
-def DoTranslate(infile, outfile, mode = ''):
- args = [infile, '-o', outfile]
- if mode:
- args += [mode]
- args += env.get('PNACL_TRANSLATE_FLAGS')
- RunDriver('pnacl-translate', args)
-
-def DoNativeLink(infile, outfile, native_left, native_right):
- LinkNative(native_left + [infile] + native_right, outfile)
-
-def LinkBC(inputs, output):
- '''Input: a bunch of bc/o/lib input files
- Output: a combined & optimized bitcode file
- '''
- # Produce combined bitcode file
- RunWithEnv('${RUN_BCLD}',
- inputs=inputs,
- output=output)
-
-######################################################################
-# Bitcode Link Wrap Symbols Hack
-######################################################################
-
-def NeedsWrap():
- return len(env.get('WRAP_SYMBOLS')) > 0
-
-def WrapDIS(infile, outfile):
- RunDriver('pnacl-dis', [infile, '-o', outfile], suppress_arch = True)
-
-def WrapLL(infile, outfile):
- assert(FileType(infile) == 'll')
- symbols = env.get('WRAP_SYMBOLS')
- Log.Info('Wrapping symbols: ' + ' '.join(symbols))
-
- fpin = DriverOpen(infile, 'r')
- fpout = DriverOpen(outfile, 'w')
- while True:
- line = fpin.readline()
- if not line:
- break
-
- for s in symbols:
- # Relabel the real function
- if line.startswith('define'):
- line = line.replace('@' + s + '(', '@__real_' + s + '(')
-
- # Remove declarations of __real_xyz symbol.
- # Because we are actually defining it now, leaving the declaration around
- # would cause an error. (bitcode should have either a define or declare,
- # not both).
- if line.startswith('declare') and '__real_' in line:
- line = ''
-
- # Relabel the wrapper to the original name.
- line = line.replace('@__wrap_' + s + '(', '@' + s + '(')
- # Do the same renaming when the function appears in debug metadata.
- # Case: !123 = metadata !{i32 456, ... metadata !"__wrap_FOO", ..., \
- # i32 (i32)* @__wrap_FOO} ; [ DW_TAG_subprogram ]
- line = line.replace('@__wrap_' + s + '}',
- '@' + s + '}')
- line = line.replace('metadata !"__wrap_' + s + '"',
- 'metadata !"' + s + '"')
- # Case: !llvm.dbg.lv.__wrap_FOO = !{!789}
- line = line.replace('llvm.dbg.lv.__wrap_' + s + ' ',
- 'llvm.dbg.lv.' + s + ' ')
-
- fpout.write(line)
- fpin.close()
- fpout.close()
-
-
-def WrapAS(infile, outfile):
- RunDriver('pnacl-as', [infile, '-o', outfile], suppress_arch = True)
-
-######################################################################
-# END Bitcode Link Wrap Symbols Hack
-######################################################################
-
-
-# This is a temporary hack.
-#
-# Until gold can recognize that .pso files should be treated like
-# dynamic dependencies, we need to translate them first.
-def TranslateInputs(inputs):
- arch = GetArch()
-
- for i in xrange(len(inputs)):
- f = inputs[i]
- if IsFlag(f):
- continue
- if FileType(f) == 'pso':
- inputs[i] = TranslatePSO(arch, f)
-
-def TranslatePSO(arch, path):
- """ Translates a pso and returns the filename of the native so """
- assert(FileType(path) == 'pso')
- assert(arch)
- if not pathtools.exists(path):
- Log.Fatal("Couldn't open %s", pathtools.touser(path))
- path_dir = pathtools.dirname(path)
- cache_dir = pathtools.join(path_dir, 'pnacl_cache')
- try:
- os.mkdir(cache_dir)
- except OSError:
- pass
-
- output_base = pathtools.join(cache_dir, pathtools.basename(path)) + '.' + arch
-
- # Acquire a lock.
- lock = FileLock(output_base)
- if not lock:
- # Add a random number to the file name to prevent collisions
- output_base += '.%d' % random.getrandbits(32)
-
- output = '%s.so' % output_base
-
- # Make sure the existing file matches
- if lock:
- md5file = '%s.md5' % output_base
- md5 = GetMD5Sum(path)
- if pathtools.exists(output):
- existing_md5 = ReadMD5(md5file)
- if existing_md5 == md5:
- lock.release()
- return output
-
- # TODO(pdox): Some driver flags, in particular --pnacl-driver-set
- # and --pnacl-driver-append, could adversely affect the translation,
- # and should probably not be passed along. However, since this is a
- # temporary solution, and we never use those flags in combination
- # with glibc, we'll just let them pass for now.
- RunDriver('pnacl-translate',
- ['-no-save-temps',
- # -arch needs to be provided, whether or not
- # there was an -arch to this invocation.
- '-arch', arch, path, '-o', output],
- suppress_arch = True) # To avoid duplicate -arch
- if lock:
- WriteMD5(md5, md5file)
- lock.release()
- else:
- TempFiles.add(output)
-
- return output
-
-def ReadMD5(file):
- fp = DriverOpen(file, 'r', fail_ok = True)
- if not fp:
- return ''
- s = fp.read()
- fp.close()
- return s
-
-def WriteMD5(s, file):
- fp = DriverOpen(file, 'w')
- fp.write(s)
- fp.close()
-
-def GetMD5Sum(path):
- m = hashlib.md5()
- fp = DriverOpen(path, 'r')
- m.update(fp.read())
- fp.close()
- return m.hexdigest()
-
-def FileLock(filename):
- if IsWindowsPython():
- return None
- else:
- return FileLockUnix(filename)
-
-class FileLockUnix(object):
- def __init__(self, path):
- self.lockfile = path + '.lock'
- self.fd = None
- self.acquire()
-
- def acquire(self):
- fd = DriverOpen(self.lockfile, 'w+')
- fcntl.lockf(fd, fcntl.LOCK_EX)
- self.fd = fd
-
- def release(self):
- if self.fd is not None:
- fcntl.lockf(self.fd, fcntl.LOCK_UN)
- self.fd.close()
- self.fd = None
-
-# Final native linking step
-# TODO(pdox): Move this into pnacl-translator.
-def LinkNative(inputs, output):
- env.push()
- env.set('inputs', *inputs)
- env.set('output', output)
-
- if env.getbool('SANDBOXED') and env.getbool('SRPC'):
- RunLDSRPC()
- else:
- RunWithLog('${RUN_LD}')
-
- env.pop()
- return
-
-def FindFile(search_names, search_dirs):
- for curdir in search_dirs:
- for name in search_names:
- path = pathtools.join(curdir, name)
- if pathtools.exists(path):
- return path
- return None
-
-def FindLib(arg, searchdirs = None, must_find = True):
- """Returns the full pathname for the library input.
- For example, name might be "-lc" or "-lm".
- Returns None if the library is not found.
- """
- assert(IsLib(arg))
- name = arg[len('-l'):]
- is_whole_name = (name[0] == ':')
-
- if searchdirs is None:
- searchdirs = env.get('SEARCH_DIRS')
-
- searchnames = []
- if is_whole_name:
- # -l:filename (search for the filename)
- name = name[1:]
- searchnames.append(name)
-
- # .pso may exist in lieu of .so, or vice versa.
- if '.so' in name:
- searchnames.append(name.replace('.so', '.pso'))
- if '.pso' in name:
- searchnames.append(name.replace('.pso', '.so'))
- else:
- # -lfoo
- shared_ok = not env.getbool('STATIC')
- if shared_ok:
- extensions = [ 'pso', 'so', 'a' ]
- else:
- extensions = [ 'a' ]
- for ext in extensions:
- searchnames.append('lib' + name + '.' + ext)
-
- foundpath = FindFile(searchnames, searchdirs)
- if foundpath:
- return foundpath
-
- if must_find:
- if is_whole_name:
- label = name
- else:
- label = arg
- Log.Fatal("Cannot find '%s'", label)
-
- return None
-
-# Given linker arguments (including -L, -l, and filenames),
-# returns the list of files which are pulled by the linker.
-def LinkerFiles(args):
- ret = []
- for f in args:
- if IsFlag(f):
- continue
- else:
- if not pathtools.exists(f):
- Log.Fatal("Unable to open '%s'", pathtools.touser(f))
- ret.append(f)
- return ret
-
-if __name__ == "__main__":
- DriverMain(main)
« no previous file with comments | « tools/llvm/driver/pnacl-illegal.py ('k') | tools/llvm/driver/pnacl-meta.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698