def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, PATTERNS) inputs = env.get('INPUTS') if len(inputs) == 0: Log.Fatal("No input files given") for infile in inputs: env.push() env.set('input', infile) # For frozen PNaCl bitcode, use 'llvm-nm -bitcode-format=pnacl'. For all # other formats, use the binutils nm with our gold plugin. if filetype.IsPNaClBitcode(infile): env.set('TOOLNAME', '${LLVM_NM}') env.append('FLAGS', '-bitcode-format=pnacl') else: env.set('TOOLNAME', '${NM}') env.append('FLAGS', '--plugin=${GOLD_PLUGIN_SO}') driver_tools.Run('"${TOOLNAME}" ${FLAGS} ${input}') env.pop() # only reached in case of no errors return 0
def AddHostBinarySearchPath(prefix): """ Add a path to the list searched for host binaries. """ prefix = pathtools.normalize(prefix) if pathtools.isdir(prefix) and not prefix.endswith('/'): prefix += '/' env.append('BPREFIXES', prefix)
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, PATTERNS) inputs = env.get('INPUTS') if len(inputs) == 0: Log.Fatal("No input files given") for infile in inputs: driver_tools.CheckPathLength(infile) env.push() env.set('input', infile) # For frozen PNaCl bitcode, use 'llvm-nm -bitcode-format=pnacl'. For all # other formats, use the binutils nm with our gold plugin. # Update: llvm-nm -bitcode-format=pnacl is currently disabled. if filetype.IsPNaClBitcode(infile): Log.Fatal( 'nm on finalized bitcode is currently disabled.\n' 'See: https://code.google.com/p/nativeclient/issues/detail?id=3993') else: env.set('TOOLNAME', '${NM}') env.append('FLAGS', '--plugin=${GOLD_PLUGIN_SO}') driver_tools.Run('"${TOOLNAME}" ${FLAGS} ${input}') env.pop() # only reached in case of no errors return 0
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, PATTERNS) inputs = env.get('INPUTS') if len(inputs) == 0: Log.Fatal("No input files given") for infile in inputs: driver_tools.CheckPathLength(infile) env.push() env.set('input', infile) # For frozen PNaCl bitcode, use 'llvm-nm -bitcode-format=pnacl'. For all # other formats, use the binutils nm with our gold plugin. # Update: llvm-nm -bitcode-format=pnacl is currently disabled. if filetype.IsPNaClBitcode(infile): Log.Fatal( 'nm on finalized bitcode is currently disabled.\n' 'See: https://code.google.com/p/nativeclient/issues/detail?id=3993' ) else: env.set('TOOLNAME', '${NM}') env.append('FLAGS', '--plugin=${GOLD_PLUGIN_SO}') driver_tools.Run('"${TOOLNAME}" ${FLAGS} ${input}') env.pop() # only reached in case of no errors return 0
def main(argv): env.update(EXTRA_ENV) ParseArgs(argv, LDPatterns) GetArch(required=True) inputs = env.get('INPUTS') output = env.getone('OUTPUT') if output == '': output = pathtools.normalize('a.out') # Expand all parameters # This resolves -lfoo into actual filenames, # and expands linker scripts into command-line arguments. inputs = ldtools.ExpandInputs(inputs, env.get('SEARCH_DIRS'), env.getbool('STATIC'), ldtools.LibraryTypes.NATIVE) env.push() env.set('inputs', *inputs) env.set('output', output) if GetArch(required=True) == 'X8664': env.append('LD_FLAGS', '--metadata-is64') if env.getbool('SANDBOXED'): RunLDSandboxed() else: Run('${RUN_LD}') env.pop() # only reached in case of no errors return 0
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, PATTERNS) args = env.get('ARGS') input = pathtools.normalize(args[-1]) if filetype.IsPNaClBitcode(input): env.append('ARGS', '--bitcode-format=pnacl') driver_tools.Run('"${PNACL_ABICHECK}" ${ARGS}') return 0;
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, PATTERNS) args = env.get('ARGS') input = pathtools.normalize(args[-1]) if filetype.IsPNaClBitcode(input): env.append('ARGS', '--bitcode-format=pnacl') driver_tools.Run('"${PNACL_ABICHECK}" ${ARGS}') return 0
def SetUpArch(): base_arch = env.getone('BASE_ARCH') env.set('TARGET_OS', 'nacl') if base_arch.endswith('_LINUX'): base_arch = base_arch[:-len('_LINUX')] env.set('TARGET_OS', 'linux') elif base_arch.endswith('_MAC'): base_arch = base_arch[:-len('_MAC')] env.set('TARGET_OS', 'mac') if env.getbool('NONSFI_NACL'): triple_map = { 'nacl': {'X8632': 'i686-linux-gnu', 'ARM': 'armv7a-linux-gnueabihf'}} else: triple_map = { 'nacl': {'X8632': 'i686-none-nacl-gnu', 'X8664': 'x86_64-none-nacl-gnu', 'ARM': 'armv7a-none-nacl-gnueabihf', 'MIPS32': 'mipsel-none-nacl-gnu'}, 'linux': {'X8632': 'i686-linux-gnu'}, 'mac': {'X8632': 'i686-apple-darwin'}} env.set('TRIPLE', triple_map[env.getone('TARGET_OS')][base_arch]) # CPU that is representative of baseline feature requirements for NaCl # and/or chrome. We may want to make this more like "-mtune" # by specifying both "-mcpu=X" and "-mattr=+feat1,-feat2,...". # Note: this may be different from the in-browser translator, which may # do auto feature detection based on CPUID, but constrained by what is # accepted by NaCl validators. cpu_map = { 'X8632': 'pentium4', 'X8664': 'core2', 'ARM': 'cortex-a9', 'MIPS32': 'mips32r2'} env.set('LLC_MCPU', '-mcpu=%s' % cpu_map[base_arch]) llc_flags_map = { 'ARM': ['-arm-reserve-r9', '-sfi-disable-cp', '-sfi-load', '-sfi-store', '-sfi-stack', '-sfi-branch', '-sfi-data', '-no-inline-jumptables', '-float-abi=hard', '-mattr=+neon'], # Once PNaCl's build of compiler-rt (libgcc.a) defines __aeabi_* # functions, we can drop the following ad-hoc option. 'ARM_NONSFI': ['-arm-enable-aeabi-functions=0'], 'MIPS32': ['-sfi-load', '-sfi-store', '-sfi-stack', '-sfi-branch', '-sfi-data']} env.set('LLC_FLAGS_ARCH', *llc_flags_map.get(env.getone('ARCH'), [])) # When linking against a host OS's libc (such as Linux glibc), don't # use %gs:0 to read the thread pointer because that won't be # compatible with the libc's use of %gs:0. Similarly, Non-SFI Mode # currently offers no optimized path for reading the thread pointer. if env.getone('TARGET_OS') != 'nacl' or env.getbool('NONSFI_NACL'): env.append('LLC_FLAGS_ARCH', '-mtls-use-call')
def AddBPrefix(prefix): prefix = pathtools.normalize(prefix) if pathtools.isdir(prefix) and not prefix.endswith("/"): prefix += "/" env.append("PREFIXES", prefix) # Add prefix/include to isystem if it exists include_dir = prefix + "include" if pathtools.isdir(include_dir): env.append("ISYSTEM_USER", include_dir)
def AddBPrefix(prefix): prefix = pathtools.normalize(prefix) if pathtools.isdir(prefix) and not prefix.endswith('/'): prefix += '/' env.append('PREFIXES', prefix) # Add prefix/include to isystem if it exists include_dir = prefix + 'include' if pathtools.isdir(include_dir): env.append('ISYSTEM_USER', include_dir)
def AddInputFileStdin(): global stdin_count # When stdin is an input, -x or -E must be given. forced_type = GetForcedFileType() if not forced_type: # Only allowed if -E is specified. forced_type = "c" env.set("NEED_DASH_E", "1") stdin_name = "__stdin%d__" % stdin_count env.append("INPUTS", stdin_name) ForceFileType(stdin_name, forced_type) stdin_count += 1
def AddInputFileStdin(): global stdin_count # When stdin is an input, -x or -E must be given. forced_type = filetype.GetForcedFileType() if not forced_type: # Only allowed if -E is specified. forced_type = 'c' env.set('NEED_DASH_E', '1') stdin_name = '__stdin%d__' % stdin_count env.append('INPUTS', stdin_name) filetype.ForceFileType(stdin_name, forced_type) stdin_count += 1
def AddBPrefix(prefix): """ Add a path to the list searched for host binaries and include dirs. """ AddHostBinarySearchPath(prefix) prefix = pathtools.normalize(prefix) if pathtools.isdir(prefix) and not prefix.endswith('/'): prefix += '/' # Add prefix/ to the library search dir if it exists if pathtools.isdir(prefix): env.append('SEARCH_DIRS', prefix) # Add prefix/include to isystem if it exists include_dir = prefix + 'include' if pathtools.isdir(include_dir): env.append('ISYSTEM_USER', include_dir)
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, DISPatterns) inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(inputs) == 0: Log.Fatal("No input files given") if len(inputs) > 1 and output != '': Log.Fatal("Cannot have -o with multiple inputs") for infile in inputs: env.push() env.set('input', infile) env.set('output', output) # When we output to stdout, set redirect_stdout and set log_stdout # to False to bypass the driver's line-by-line handling of stdout # which is extremely slow when you have a lot of output if driver_tools.IsLLVMBitcode(infile): if output == '': # LLVM by default outputs to a file if -o is missing # Let's instead output to stdout env.set('output', '-') env.append('FLAGS', '-f') driver_tools.Run('${LLVM_DIS} ${FLAGS} ${input} -o ${output}') elif driver_tools.IsELF(infile): flags = env.get('FLAGS') if len(flags) == 0: env.append('FLAGS', '-d') if output == '': # objdump to stdout driver_tools.Run('"${OBJDUMP}" ${FLAGS} ${input}') else: # objdump always outputs to stdout, and doesn't recognize -o # Let's add this feature to be consistent. fp = driver_tools.DriverOpen(output, 'w') driver_tools.Run('${OBJDUMP} ${FLAGS} ${input}', redirect_stdout=fp) driver_tools.DriverClose(fp) else: Log.Fatal('Unknown file type') env.pop() # only reached in case of no errors return 0
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, DISPatterns) inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(inputs) == 0: Log.Fatal("No input files given") if len(inputs) > 1 and output != '': Log.Fatal("Cannot have -o with multiple inputs") for infile in inputs: env.push() env.set('input', infile) env.set('output', output) # When we output to stdout, set redirect_stdout and set log_stdout # to False to bypass the driver's line-by-line handling of stdout # which is extremely slow when you have a lot of output if driver_tools.IsBitcode(infile): if output == '': # LLVM by default outputs to a file if -o is missing # Let's instead output to stdout env.set('output', '-') env.append('FLAGS', '-f') driver_tools.Run('${LLVM_DIS} ${FLAGS} ${input} -o ${output}') elif driver_tools.IsELF(infile): flags = env.get('FLAGS') if len(flags) == 0: env.append('FLAGS', '-d') if output == '': # objdump to stdout driver_tools.Run('"${OBJDUMP}" ${FLAGS} ${input}') else: # objdump always outputs to stdout, and doesn't recognize -o # Let's add this feature to be consistent. fp = driver_tools.DriverOpen(output, 'w') driver_tools.Run('${OBJDUMP} ${FLAGS} ${input}', redirect_stdout=fp) driver_tools.DriverClose(fp) else: Log.Fatal('Unknown file type') env.pop() # only reached in case of no errors return 0
def SetUpLinkOptions(): if env.getbool('TRANSLATE_PSO'): # Using "-pie" rather than "-shared" has the effect of suppressing the # creation of a PLT and R_*_JUMP_SLOT relocations, which come from the # external symbol references that multi-threaded translation produces. env.append('LD_FLAGS', '-pie') return if env.getbool('NONSFI_NACL'): # "_begin" allows a PIE to find its load address in order to apply # dynamic relocations. env.append('LD_FLAGS', '-defsym=_begin=0') env.append('LD_FLAGS', '-pie') else: env.append('LD_FLAGS', '-static') # Give non-IRT builds 12MB of text before starting rodata instead of # the larger default gap. The gap cannot be too small (e.g., 0) because # sel_ldr requires space for adding a halt sled. if not env.getbool('USE_IRT'): env.append('LD_FLAGS', '--rosegment-gap=0xc00000')
def ParseArgs(argv, patternlist, driver_patternlist=DriverArgPatterns, driver_patternlist_not_inherited=DriverArgPatternsNotInherited): """Parse argv using the patterns in patternlist Also apply the built-in DriverArgPatterns unless instructed otherwise. This function must be called by all (real) drivers. """ if driver_patternlist: driver_args, argv = ParseArgsBase(argv, driver_patternlist) # TODO(robertm): think about a less obscure mechanism to # replace the inherited args feature assert not env.get('INHERITED_DRIVER_ARGS') env.append('INHERITED_DRIVER_ARGS', *driver_args) _, argv = ParseArgsBase(argv, driver_patternlist_not_inherited) _, unmatched = ParseArgsBase(argv, patternlist) if unmatched: for u in unmatched: Log.Error('Unrecognized argument: ' + u) Log.Fatal('unknown arguments')
def AddCCFlag(*args): env.append('CC_FLAGS', *args)
def ApplyBitcodeConfig(metadata, bctype): # Read the bitcode metadata to extract library # dependencies and SOName. # For now, we use LD_FLAGS to convey the information. # However, if the metadata becomes richer we will need another mechanism. # TODO(jvoung): at least grep out the SRPC output from LLC and transmit # that directly to LD to avoid issues with mismatching delimiters. for needed in metadata['NeedsLibrary']: env.append('LD_FLAGS', '--add-extra-dt-needed=' + needed) if bctype == 'pso': soname = metadata['SOName'] if soname: env.append('LD_FLAGS', '-soname=' + soname) # For the current LD final linker, native libraries still need to be # linked directly, since --add-extra-dt-needed isn't enough. # BUG= http://code.google.com/p/nativeclient/issues/detail?id=2451 # For the under-construction gold final linker, it expects to have # the needed libraries on the commandline as "-llib1 -llib2", which actually # refer to the stub metadata file. for needed in metadata['NeedsLibrary']: # Specify the ld-nacl-${arch}.so as the --dynamic-linker to set PT_INTERP. # Also, the original libc.so linker script had it listed as --as-needed, # so let's do that. if needed.startswith('ld-nacl-'): env.append('NEEDED_LIBRARIES', '--dynamic-linker=' + needed) env.append( 'NEEDED_LIBRARIES', '--as-needed', # We normally would have a symlink between # ld-2.9 <-> ld-nacl-${arch}.so, but our native lib directory # has no symlinks (to make windows + cygwin happy). # Link to ld-2.9.so instead for now. '-l:ld-2.9.so', '--no-as-needed') else: env.append('NEEDED_LIBRARIES', '-l:' + needed) # libc and libpthread may need the nonshared components too. # Normally these are enclosed in --start-group and --end-group... if not env.getbool('NEWLIB_SHARED_EXPERIMENT'): if needed.startswith('libc.so'): env.append('NEEDED_LIBRARIES', '-l:libc_nonshared.a') elif needed.startswith('libpthread.so'): env.append('NEEDED_LIBRARIES', '-l:libpthread_nonshared.a')
def PassThrough(*args): env.append('LD_FLAGS', *args)
def AddLDFlag(*args): env.append('LD_FLAGS', *args)
def SetUpArch(): base_arch = env.getone('BASE_ARCH') env.set('TARGET_OS', 'nacl') if base_arch.endswith('_LINUX'): base_arch = base_arch[:-len('_LINUX')] env.set('TARGET_OS', 'linux') elif base_arch.endswith('_MAC'): base_arch = base_arch[:-len('_MAC')] env.set('TARGET_OS', 'mac') if env.getbool('NONSFI_NACL'): triple_map = { 'nacl': { 'X8632': 'i686-linux-gnu', 'ARM': 'armv7a-linux-gnueabihf' } } else: triple_map = { 'nacl': { 'X8632': 'i686-none-nacl-gnu', 'X8664': 'x86_64-none-nacl-gnu', 'ARM': 'armv7a-none-nacl-gnueabihf', 'MIPS32': 'mipsel-none-nacl-gnu' }, 'linux': { 'X8632': 'i686-linux-gnu' }, 'mac': { 'X8632': 'i686-apple-darwin' } } env.set('TRIPLE', triple_map[env.getone('TARGET_OS')][base_arch]) # CPU that is representative of baseline feature requirements for NaCl # and/or chrome. We may want to make this more like "-mtune" # by specifying both "-mcpu=X" and "-mattr=+feat1,-feat2,...". # Note: this may be different from the in-browser translator, which may # do auto feature detection based on CPUID, but constrained by what is # accepted by NaCl validators. cpu_map = { 'X8632': 'pentium4', 'X8664': 'core2', 'ARM': 'cortex-a9', 'MIPS32': 'mips32r2' } env.set('LLC_MCPU', '-mcpu=%s' % cpu_map[base_arch]) llc_flags_map = { 'ARM': [ '-arm-reserve-r9', '-sfi-disable-cp', '-sfi-load', '-sfi-store', '-sfi-stack', '-sfi-branch', '-sfi-data', '-no-inline-jumptables', '-float-abi=hard', '-mattr=+neon' ], # Once PNaCl's build of compiler-rt (libgcc.a) defines __aeabi_* # functions, we can drop the following ad-hoc option. 'ARM_NONSFI': ['-arm-enable-aeabi-functions=0'], 'MIPS32': ['-sfi-load', '-sfi-store', '-sfi-stack', '-sfi-branch', '-sfi-data'] } env.set('LLC_FLAGS_ARCH', *llc_flags_map.get(env.getone('ARCH'), [])) # When linking against a host OS's libc (such as Linux glibc), don't # use %gs:0 to read the thread pointer because that won't be # compatible with the libc's use of %gs:0. Similarly, Non-SFI Mode # currently offers no optimized path for reading the thread pointer. if env.getone('TARGET_OS') != 'nacl' or env.getbool('NONSFI_NACL'): env.append('LLC_FLAGS_ARCH', '-mtls-use-call')
def AddToNativeFlags(*args): env.append('LD_FLAGS_NATIVE', *args)
def AddTranslatorFlag(*args): # pass translator args to ld in case we go all the way to .nexe env.append('LD_FLAGS', *['-Wt,' + a for a in args]) # pass translator args to translator in case we go to .o env.append('TRANSLATE_FLAGS', *args)
def AddAllowCXXExceptions(*args): env.set('ALLOW_CXX_EXCEPTIONS', '1') env.append('TRANSLATE_FLAGS', *args)
def RecordRelevantArg(category, value): Env.append(category, value) RawRelevantArgs.append(value)
def AddLLVMPassDisableFlag(*args): env.append('LLVM_PASSES_TO_DISABLE', *args) env.append('LD_FLAGS', *args)
def AddToBCLinkFlags(*args): env.append('LD_FLAGS', *args)
def SetUpArch(): base_arch = env.getone('BASE_ARCH') env.set('TARGET_OS', 'nacl') if base_arch.endswith('_LINUX'): base_arch = base_arch[:-len('_LINUX')] env.set('TARGET_OS', 'linux') elif base_arch.endswith('_MAC'): base_arch = base_arch[:-len('_MAC')] env.set('TARGET_OS', 'mac') if env.getbool('NONSFI_NACL'): triple_map = { 'nacl': {'X8632': 'i686-linux-gnu', 'ARM': 'armv7a-linux-gnueabihf'}} else: triple_map = { 'nacl': {'X8632': 'i686-none-nacl-gnu', 'X8664': 'x86_64-none-nacl-gnu', 'ARM': 'armv7a-none-nacl-gnueabihf', 'MIPS32': 'mipsel-none-nacl-gnu'}, 'linux': {'X8632': 'i686-linux-gnu'}, 'mac': {'X8632': 'i686-apple-darwin'}} env.set('TRIPLE', triple_map[env.getone('TARGET_OS')][base_arch]) # CPU that is representative of baseline feature requirements for NaCl # and/or chrome. We may want to make this more like "-mtune" # by specifying both "-mcpu=X" and "-mattr=+feat1,-feat2,...". # Note: this may be different from the in-browser translator, which may # do auto feature detection based on CPUID, but constrained by what is # accepted by NaCl validators. cpu_map = { 'X8632': 'pentium4m', 'X8664': 'x86-64', 'ARM': 'cortex-a9', 'MIPS32': 'mips32r2'} env.set('LLC_MCPU', '-mcpu=%s' % cpu_map[base_arch]) llc_flags_map = { 'ARM': ['-float-abi=hard', '-mattr=+neon'], 'ARM_NONSFI': ['-float-abi=hard', '-arm-enable-dwarf-eh=1'], # To translate x86-32 binary, we set -malign-double option so that the # backend's datalayout matches the datalayout for "le32" used by the # frontend. The le32 datalayout uses 8-byte alignment for the types i64 # and double. i386's datalayout usually uses only 4-byte alignment for # these types, but -malign-double changes that to 8-byte alignment. # This is only needed when translating LLVM IR that hasn't had PNaCl's IR # simplification passes applied to it. 'X8632_NONSFI': ['-malign-double'], } env.set('LLC_FLAGS_ARCH', *llc_flags_map.get(env.getone('ARCH'), [])) env.set('SZ_FLAGS_ARCH', '') # When linking against a host OS's libc (such as Linux glibc), don't # use %gs:0 to read the thread pointer because that won't be # compatible with the libc's use of %gs:0. Similarly, Non-SFI Mode # currently offers no optimized path for reading the thread pointer. if env.getone('TARGET_OS') != 'nacl' or env.getbool('NONSFI_NACL'): env.append('LLC_FLAGS_ARCH', '-mtls-use-call') # For Subzero, determine -target and -sandbox options. env.append('SZ_FLAGS_ARCH', '--sandbox=' + ('1' if env.getone('TARGET_OS') == 'nacl' else '0')) env.append('SZ_FLAGS_ARCH', '--target=' + base_arch.lower()) if base_arch != 'X8632': env.set('SZ_UNSUPPORTED', '1') # Hard-fail on an unsupported architecture. if env.getbool('USE_SZ'): Log.Fatal('Unsupported architecture when using --sz: ' + base_arch) # This is a fine place to map OPT_LEVEL to the Subzero equivalent, with # default of -O2. sz_opt_map = { '0': '-Om1', '1': '-O2', '2': '-O2', } env.append('SZ_FLAGS_EXTRA', sz_opt_map.get(env.getone('OPT_LEVEL'), '-O2'))
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, TranslatorPatterns) driver_tools.GetArch(required = True) SetUpArch() SetUpLinkOptions() # Now commit to whether or not Subzero is used. use_sz = env.getbool('USE_SZ') and not env.getbool('SZ_UNSUPPORTED') inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(inputs) == 0: Log.Fatal("No input files") for path in inputs: driver_tools.CheckPathLength(path) if output == '': Log.Fatal("Please specify output file with -o") # Find the bitcode file on the command line. bcfiles = [f for f in inputs if not ldtools.IsFlag(f) and (filetype.IsPNaClBitcode(f) or filetype.IsLLVMBitcode(f) or filetype.FileType(f) == 'll')] if len(bcfiles) > 1: Log.Fatal('Expecting at most 1 bitcode file') elif len(bcfiles) == 1: bcfile = bcfiles[0] else: bcfile = None if ((env.getbool('ALLOW_LLVM_BITCODE_INPUT') or env.getone('TARGET_OS') != 'nacl' or env.getbool('USE_EMULATOR')) and env.getone('SPLIT_MODULE') == 'auto'): # When llvm input is allowed, the pexe may not be ABI-stable, so do not # split it. Non-ABI-stable pexes may have symbol naming and visibility # issues that the current splitting scheme doesn't account for. # # For now, also do not enable multi-threaded translation when TARGET_OS != # 'nacl', since in these cases we will be using the host toolchain's # linker. # # The x86->arm emulator is very flaky when threading is used, so don't # do module splitting when using it. env.set('SPLIT_MODULE', 'seq') # Do not set -streaming-bitcode for sandboxed mode, because it is already # in the default command line. if not env.getbool('SANDBOXED') and env.getbool('STREAM_BITCODE'): env.append('LLC_FLAGS_EXTRA', '-streaming-bitcode') if env.getone('SPLIT_MODULE') == 'seq': env.set('SPLIT_MODULE', '1') env.set('SZ_THREADS', '0') elif env.getone('SPLIT_MODULE') == 'auto': try: num_modules = min(4, multiprocessing.cpu_count()) except NotImplementedError: num_modules = 2 env.set('SPLIT_MODULE', str(num_modules)) env.set('SZ_THREADS', str(num_modules)) else: num_modules = int(env.getone('SPLIT_MODULE')) if num_modules < 1: Log.Fatal('Value given for -split-module must be > 0') env.set('SPLIT_MODULE', str(num_modules)) env.set('SZ_THREADS', str(num_modules)) modules = env.getone('SPLIT_MODULE') module_sched = env.getone('SPLIT_MODULE_SCHED') sz_threads = env.getone('SZ_THREADS') # TODO(dschuff,jvoung): No need to specify -split-module=X since the IPC # already has a parameter for the number of threads and modules. env.append('LLC_FLAGS_EXTRA', '-split-module=' + modules) env.append('LD_FLAGS', '-split-module=' + ('1' if use_sz else modules)) env.append('LLC_FLAGS_EXTRA', '-split-module-sched=' + module_sched) # In sandboxed mode, the IPC already has a parameter for the number # of threads, so no need to specify that again via argv[]. if not env.getbool('SANDBOXED'): env.append('SZ_FLAGS_EXTRA', '--threads=' + sz_threads) # If there's a bitcode file, translate it now. tng = driver_tools.TempNameGen(inputs + bcfiles, output) output_type = env.getone('OUTPUT_TYPE') if bcfile: sfile = None if output_type == 's': sfile = output ofile = None if output_type == 'o': ofile = output elif output_type != 's': ofile = tng.TempNameForInput(bcfile, 'o') if sfile: RunCompiler(bcfile, sfile, outfiletype='asm', use_sz=use_sz) if ofile: RunAS(sfile, ofile) else: RunCompiler(bcfile, ofile, outfiletype='obj', use_sz=use_sz) else: ofile = None # If we've been told to stop after translation, stop now. if output_type in ('o','s'): return 0 if use_sz: # Reset SPLIT_MODULE to 1 to fall back to normal linking behavior. env.set('SPLIT_MODULE', '1') # Replace the bitcode file with __BITCODE__ in the input list if bcfile: inputs = ListReplace(inputs, bcfile, '__BITCODE__') env.set('INPUTS', *inputs) if int(env.getone('SPLIT_MODULE')) > 1: modules = int(env.getone('SPLIT_MODULE')) for i in range(1, modules): filename = ofile + '.module%d' % i TempFiles.add(filename) env.append('INPUTS', filename) if env.getone('TARGET_OS') != 'nacl': RunHostLD(ofile, output) else: RunLD(ofile, output) return 0
def AddDiagnosticFlag(*args): env.append('CC_FLAGS', *args) env.set('DIAGNOSTIC', '1')
def main(argv): env.update(EXTRA_ENV) CheckSetup() ParseArgs(argv, CustomPatterns + GCCPatterns) # "configure", especially when run as part of a toolchain bootstrap # process, will invoke gcc with various diagnostic options and # parse the output. In these cases we do not alter the incoming # commandline. It is also important to not emit spurious messages. if env.getbool('DIAGNOSTIC'): if env.getbool('SHOW_VERSION'): code, stdout, stderr = Run(env.get('CC') + env.get('CC_FLAGS'), redirect_stdout=subprocess.PIPE) out = stdout.split('\n') nacl_version = ReadDriverRevision() out[0] += ' nacl-version=%s' % nacl_version stdout = '\n'.join(out) print stdout, else: Run(env.get('CC') + env.get('CC_FLAGS')) return 0 unmatched = env.get('UNMATCHED') if len(unmatched) > 0: UnrecognizedOption(*unmatched) # If -arch was given, we are compiling directly to native code compiling_to_native = GetArch() is not None if env.getbool('ALLOW_NATIVE'): if not compiling_to_native: Log.Fatal("--pnacl-allow-native without -arch is not meaningful.") # For native/mixed links, also bring in the native libgcc and # libcrt_platform to avoid link failure if pre-translated native # code needs functions from it. env.append('LD_FLAGS', env.eval('-L${LIBS_NATIVE_ARCH}')) env.append('STDLIBS', '-lgcc') env.append('STDLIBS', '-lcrt_platform') flags_and_inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(flags_and_inputs) == 0: if env.getbool('VERBOSE'): # -v can be invoked without any inputs. Runs the original # command without modifying the commandline for this case. Run(env.get('CC') + env.get('CC_FLAGS')) return 0 else: Log.Fatal('No input files') gcc_mode = env.getone('GCC_MODE') output_type = DriverOutputTypes(gcc_mode, compiling_to_native) # INPUTS consists of actual input files and a subset of flags like -Wl,<foo>. # Create a version with just the files. inputs = [f for f in flags_and_inputs if not IsFlag(f)] header_inputs = [f for f in inputs if filetype.IsHeaderType(filetype.FileType(f))] # Handle PCH case specially (but only for a limited sense...) if header_inputs and gcc_mode != '-E': # We only handle doing pre-compiled headers for all inputs or not at # all at the moment. This is because DriverOutputTypes only assumes # one type of output, depending on the "gcc_mode" flag. When mixing # header inputs w/ non-header inputs, some of the outputs will be # pch while others will be output_type. We would also need to modify # the input->output chaining for the needs_linking case. if len(header_inputs) != len(inputs): Log.Fatal('mixed compiling of headers and source not supported') CompileHeaders(header_inputs, output) return 0 needs_linking = (gcc_mode == '') if env.getbool('NEED_DASH_E') and gcc_mode != '-E': Log.Fatal("-E or -x required when input is from stdin") # There are multiple input files and no linking is being done. # There will be multiple outputs. Handle this case separately. if not needs_linking: if output != '' and len(inputs) > 1: Log.Fatal('Cannot have -o with -c, -S, or -E and multiple inputs: %s', repr(inputs)) for f in inputs: intype = filetype.FileType(f) if not (filetype.IsSourceType(intype) or filetype.IsHeaderType(intype)): if ((output_type == 'pp' and intype != 'S') or (output_type == 'll') or (output_type == 'po' and intype != 'll') or (output_type == 's' and intype not in ('ll','po','S')) or (output_type == 'o' and intype not in ('ll','po','S','s'))): Log.Fatal("%s: Unexpected type of file for '%s'", pathtools.touser(f), gcc_mode) if output == '': f_output = DefaultOutputName(f, output_type) else: f_output = output namegen = TempNameGen([f], f_output) CompileOne(f, output_type, namegen, f_output) return 0 # Linking case assert(needs_linking) assert(output_type in ('pso','so','pexe','nexe')) if output == '': output = pathtools.normalize('a.out') namegen = TempNameGen(flags_and_inputs, output) # Compile all source files (c/c++/ll) to .po for i in xrange(0, len(flags_and_inputs)): if IsFlag(flags_and_inputs[i]): continue intype = filetype.FileType(flags_and_inputs[i]) if filetype.IsSourceType(intype) or intype == 'll': flags_and_inputs[i] = CompileOne(flags_and_inputs[i], 'po', namegen) # Compile all .s/.S to .o if env.getbool('ALLOW_NATIVE'): for i in xrange(0, len(flags_and_inputs)): if IsFlag(flags_and_inputs[i]): continue intype = filetype.FileType(flags_and_inputs[i]) if intype in ('s','S'): flags_and_inputs[i] = CompileOne(flags_and_inputs[i], 'o', namegen) # We should only be left with .po and .o and libraries for f in flags_and_inputs: if IsFlag(f): continue intype = filetype.FileType(f) if intype in ('o','s','S') or filetype.IsNativeArchive(f): if not env.getbool('ALLOW_NATIVE'): Log.Fatal('%s: Native object files not allowed in link. ' 'Use --pnacl-allow-native to override.', pathtools.touser(f)) assert(intype in ('po','o','so','ldscript') or filetype.IsArchive(f)) # Fix the user-specified linker arguments ld_inputs = [] for f in flags_and_inputs: if f.startswith('-Xlinker='): ld_inputs.append(f[len('-Xlinker='):]) elif f.startswith('-Wl,'): ld_inputs += f[len('-Wl,'):].split(',') else: ld_inputs.append(f) if env.getbool('ALLOW_NATIVE'): ld_inputs.append('--pnacl-allow-native') # Invoke the linker env.set('ld_inputs', *ld_inputs) ld_args = env.get('LD_ARGS') ld_flags = env.get('LD_FLAGS') RunDriver('pnacl-ld', ld_flags + ld_args + ['-o', output]) return 0
def AddCCFlag(*args): env.append("CC_FLAGS", *args)
def AddLDFlag(*args): env.append("LD_FLAGS", *args)
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, DISPatterns) inputs = env.get('INPUTS') output = env.getone('OUTPUT') for path in inputs + [output]: driver_tools.CheckPathLength(path) if len(inputs) == 0: Log.Fatal("No input files given") if len(inputs) > 1 and output != '': Log.Fatal("Cannot have -o with multiple inputs") for infile in inputs: env.push() env.set('input', infile) env.set('output', output) # When we output to stdout, set redirect_stdout and set log_stdout # to False to bypass the driver's line-by-line handling of stdout # which is extremely slow when you have a lot of output if (filetype.IsLLVMBitcode(infile) or filetype.IsPNaClBitcode(infile)): bitcodetype = 'PNaCl' if filetype.IsPNaClBitcode( infile) else 'LLVM' format = bitcodetype.lower() if env.has('FILE_TYPE'): sys.stdout.write('%s: %s bitcode\n' % (infile, bitcodetype)) continue env.append('FLAGS', '-bitcode-format=' + format) if output == '': # LLVM by default outputs to a file if -o is missing # Let's instead output to stdout env.set('output', '-') env.append('FLAGS', '-f') driver_tools.Run('${LLVM_DIS} ${FLAGS} ${input} -o ${output}') elif filetype.IsELF(infile): if env.has('FILE_TYPE'): sys.stdout.write('%s: ELF\n' % infile) continue flags = env.get('FLAGS') if len(flags) == 0: env.append('FLAGS', '-d') if output == '': # objdump to stdout driver_tools.Run('"${OBJDUMP}" ${FLAGS} ${input}') else: # objdump always outputs to stdout, and doesn't recognize -o # Let's add this feature to be consistent. fp = DriverOpen(output, 'w') driver_tools.Run('${OBJDUMP} ${FLAGS} ${input}', redirect_stdout=fp) DriverClose(fp) else: Log.Fatal('Unknown file type') env.pop() # only reached in case of no errors return 0
def main(argv): env.update(EXTRA_ENV) CheckSetup() ParseArgs(argv, CustomPatterns + GCCPatterns) # "configure", especially when run as part of a toolchain bootstrap # process, will invoke gcc with various diagnostic options and # parse the output. In these cases we do not alter the incoming # commandline. It is also important to not emit spurious messages. if env.getbool('DIAGNOSTIC'): if env.getbool('SHOW_VERSION'): code, stdout, stderr = Run(env.get('CC') + env.get('CC_FLAGS'), redirect_stdout=subprocess.PIPE) out = stdout.split('\n') nacl_version = ReadDriverRevision() out[0] += ' nacl-version=%s' % nacl_version stdout = '\n'.join(out) print stdout, else: Run(env.get('CC') + env.get('CC_FLAGS')) return 0 unmatched = env.get('UNMATCHED') if len(unmatched) > 0: UnrecognizedOption(*unmatched) # If -arch was given, we are compiling directly to native code compiling_to_native = GetArch() is not None if env.getbool('ALLOW_NATIVE'): if not compiling_to_native: Log.Fatal("--pnacl-allow-native without -arch is not meaningful.") # For native/mixed links, also bring in the native libgcc and # libcrt_platform to avoid link failure if pre-translated native # code needs functions from it. env.append('LD_FLAGS', env.eval('-L${LIBS_NATIVE_ARCH}')) env.append('STDLIBS', '-lgcc') env.append('STDLIBS', '-lcrt_platform') flags_and_inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(flags_and_inputs) == 0: if env.getbool('VERBOSE'): # -v can be invoked without any inputs. Runs the original # command without modifying the commandline for this case. Run(env.get('CC') + env.get('CC_FLAGS')) return 0 else: Log.Fatal('No input files') gcc_mode = env.getone('GCC_MODE') output_type = DriverOutputTypes(gcc_mode, compiling_to_native) # '-shared' modifies the output from the linker and should be considered when # determining the final output type. if env.getbool('SHARED'): if compiling_to_native: Log.Fatal('Building native shared libraries not supported') if gcc_mode != '': Log.Fatal('-c, -S, and -E are disallowed with -shared') output_type = 'pll' # INPUTS consists of actual input files and a subset of flags like -Wl,<foo>. # Create a version with just the files. inputs = [f for f in flags_and_inputs if not IsFlag(f)] header_inputs = [ f for f in inputs if filetype.IsHeaderType(filetype.FileType(f)) ] # Handle PCH case specially (but only for a limited sense...) if header_inputs and gcc_mode != '-E': # We only handle doing pre-compiled headers for all inputs or not at # all at the moment. This is because DriverOutputTypes only assumes # one type of output, depending on the "gcc_mode" flag. When mixing # header inputs w/ non-header inputs, some of the outputs will be # pch while others will be output_type. We would also need to modify # the input->output chaining for the needs_linking case. if len(header_inputs) != len(inputs): Log.Fatal('mixed compiling of headers and source not supported') CompileHeaders(header_inputs, output) return 0 needs_linking = (gcc_mode == '') if env.getbool('NEED_DASH_E') and gcc_mode != '-E': Log.Fatal("-E or -x required when input is from stdin") # There are multiple input files and no linking is being done. # There will be multiple outputs. Handle this case separately. if not needs_linking: if output != '' and len(inputs) > 1: Log.Fatal( 'Cannot have -o with -c, -S, or -E and multiple inputs: %s', repr(inputs)) for f in inputs: intype = filetype.FileType(f) if not (filetype.IsSourceType(intype) or filetype.IsHeaderType(intype)): if ((output_type == 'pp' and intype != 'S') or (output_type == 'll') or (output_type == 'po' and intype != 'll') or (output_type == 's' and intype not in ('ll', 'po', 'S')) or (output_type == 'o' and intype not in ('ll', 'po', 'S', 's'))): Log.Fatal("%s: Unexpected type of file for '%s'", pathtools.touser(f), gcc_mode) if output == '': f_output = DefaultOutputName(f, output_type) else: f_output = output namegen = TempNameGen([f], f_output) CompileOne(f, output_type, namegen, f_output) return 0 # Linking case assert (needs_linking) assert (output_type in ('pll', 'pexe', 'nexe')) if output == '': output = pathtools.normalize('a.out') namegen = TempNameGen(flags_and_inputs, output) # Compile all source files (c/c++/ll) to .po for i in xrange(0, len(flags_and_inputs)): if IsFlag(flags_and_inputs[i]): continue intype = filetype.FileType(flags_and_inputs[i]) if filetype.IsSourceType(intype) or intype == 'll': flags_and_inputs[i] = CompileOne(flags_and_inputs[i], 'po', namegen) # Compile all .s/.S to .o if env.getbool('ALLOW_NATIVE'): for i in xrange(0, len(flags_and_inputs)): if IsFlag(flags_and_inputs[i]): continue intype = filetype.FileType(flags_and_inputs[i]) if intype in ('s', 'S'): flags_and_inputs[i] = CompileOne(flags_and_inputs[i], 'o', namegen) # We should only be left with .po and .o and libraries for f in flags_and_inputs: if IsFlag(f): continue intype = filetype.FileType(f) if intype in ('o', 's', 'S') or filetype.IsNativeArchive(f): if not env.getbool('ALLOW_NATIVE'): Log.Fatal( '%s: Native object files not allowed in link. ' 'Use --pnacl-allow-native to override.', pathtools.touser(f)) assert (intype in ('po', 'o', 'so', 'ldscript') or filetype.IsArchive(f)) # Fix the user-specified linker arguments ld_inputs = [] for f in flags_and_inputs: if f.startswith('-Xlinker='): ld_inputs.append(f[len('-Xlinker='):]) elif f.startswith('-Wl,'): ld_inputs += f[len('-Wl,'):].split(',') else: ld_inputs.append(f) if env.getbool('ALLOW_NATIVE'): ld_inputs.append('--pnacl-allow-native') # Invoke the linker env.set('ld_inputs', *ld_inputs) ld_args = env.get('LD_ARGS') ld_flags = env.get('LD_FLAGS') RunDriver('pnacl-ld', ld_flags + ld_args + ['-o', output]) return 0
def AddToBothFlags(*args): env.append('LD_FLAGS', *args) env.append('LD_FLAGS_NATIVE', *args)
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, TranslatorPatterns) driver_tools.GetArch(required=True) inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(inputs) == 0: Log.Fatal("No input files") if output == '': Log.Fatal("Please specify output file with -o") # Find the bitcode file on the command line. bcfiles = [ f for f in inputs if not ldtools.IsFlag(f) and (filetype.IsPNaClBitcode( f) or filetype.IsLLVMBitcode(f) or filetype.FileType(f) == 'll') ] if len(bcfiles) > 1: Log.Fatal('Expecting at most 1 bitcode file') elif len(bcfiles) == 1: bcfile = bcfiles[0] else: bcfile = None if not env.getbool('SPLIT_MODULE'): try: env.set('SPLIT_MODULE', str(min(4, multiprocessing.cpu_count()))) except NotImplementedError: env.set('SPLIT_MODULE', '2') elif int(env.getone('SPLIT_MODULE')) < 1: Log.Fatal('Value given for -split-module must be > 0') if (env.getbool('ALLOW_LLVM_BITCODE_INPUT') or env.getone('ARCH') == 'X8632_LINUX' or env.getbool('USE_EMULATOR')): # When llvm input is allowed, the pexe may not be ABI-stable, so do not # split it. For now also do not support threading non-SFI baremetal mode. # Non-ABI-stable pexes may have symbol naming and visibility issues that the # current splitting scheme doesn't account for. # If the link would require a non-standard command line, do not split the # modules because the sandboxed linker doesn't support that combination. # The x86->arm emulator is very flaky when threading is used, so don't # do module splitting when using it. env.set('SPLIT_MODULE', '1') else: modules = env.getone('SPLIT_MODULE') if modules != '1': env.append('LLC_FLAGS_EXTRA', '-split-module=' + modules) env.append('LD_FLAGS', '-split-module=' + modules) if not env.getbool('SANDBOXED') and env.getbool('STREAM_BITCODE'): # Do not set -streaming-bitcode for sandboxed mode, because it is already # in the default command line. env.append('LLC_FLAGS_EXTRA', '-streaming-bitcode') # If there's a bitcode file, translate it now. tng = driver_tools.TempNameGen(inputs + bcfiles, output) output_type = env.getone('OUTPUT_TYPE') if bcfile: sfile = None if output_type == 's': sfile = output ofile = None if output_type == 'o': ofile = output elif output_type != 's': ofile = tng.TempNameForInput(bcfile, 'o') if sfile: RunLLC(bcfile, sfile, outfiletype='asm') if ofile: RunAS(sfile, ofile) else: RunLLC(bcfile, ofile, outfiletype='obj') else: ofile = None # If we've been told to stop after translation, stop now. if output_type in ('o', 's'): return 0 # Replace the bitcode file with __BITCODE__ in the input list if bcfile: inputs = ListReplace(inputs, bcfile, '__BITCODE__') env.set('INPUTS', *inputs) if int(env.getone('SPLIT_MODULE')) > 1: modules = int(env.getone('SPLIT_MODULE')) for i in range(1, modules): filename = ofile + '.module%d' % i TempFiles.add(filename) env.append('INPUTS', filename) if env.getone('ARCH') == 'X8632_LINUX': RunHostLD(ofile, output) else: RunLD(ofile, output) return 0
def ApplyBitcodeConfig(metadata, bctype): # Read the bitcode metadata to extract library # dependencies and SOName. # For now, we use LD_FLAGS to convey the information. # However, if the metadata becomes richer we will need another mechanism. # TODO(jvoung): at least grep out the SRPC output from LLC and transmit # that directly to LD to avoid issues with mismatching delimiters. for needed in metadata['NeedsLibrary']: env.append('LD_FLAGS', '--add-extra-dt-needed=' + needed) if bctype == 'pso': soname = metadata['SOName'] if soname: env.append('LD_FLAGS', '-soname=' + soname) # For the current LD final linker, native libraries still need to be # linked directly, since --add-extra-dt-needed isn't enough. # BUG= http://code.google.com/p/nativeclient/issues/detail?id=2451 # For the under-construction gold final linker, it expects to have # the needed libraries on the commandline as "-llib1 -llib2", which actually # refer to the stub metadata file. for needed in metadata['NeedsLibrary']: # Specify the ld-nacl-${arch}.so as the --dynamic-linker to set PT_INTERP. # Also, the original libc.so linker script had it listed as --as-needed, # so let's do that. if needed.startswith('ld-nacl-'): env.append('NEEDED_LIBRARIES', '--dynamic-linker=' + needed) env.append('NEEDED_LIBRARIES', '--as-needed', # We normally would have a symlink between # ld-2.9 <-> ld-nacl-${arch}.so, but our native lib directory # has no symlinks (to make windows + cygwin happy). # Link to ld-2.9.so instead for now. '-l:ld-2.9.so', '--no-as-needed') else: env.append('NEEDED_LIBRARIES', '-l:' + needed) # libc and libpthread may need the nonshared components too. # Normally these are enclosed in --start-group and --end-group... if not env.getbool('NEWLIB_SHARED_EXPERIMENT'): if needed.startswith('libc.so'): env.append('NEEDED_LIBRARIES', '-l:libc_nonshared.a') elif needed.startswith('libpthread.so'): env.append('NEEDED_LIBRARIES', '-l:libpthread_nonshared.a')
def AddToNativeIgnoredFlags(*args): env.append('LD_FLAGS_NATIVE_OR_IGNORED', *args)
def SetUpArch(): base_arch = env.getone('BASE_ARCH') env.set('TARGET_OS', 'nacl') if base_arch.endswith('_LINUX'): base_arch = base_arch[:-len('_LINUX')] env.set('TARGET_OS', 'linux') elif base_arch.endswith('_MAC'): base_arch = base_arch[:-len('_MAC')] env.set('TARGET_OS', 'mac') if env.getbool('NONSFI_NACL'): triple_map = { 'nacl': {'X8632': 'i686-linux-gnu', 'ARM': 'armv7a-linux-gnueabihf'}} else: triple_map = { 'nacl': {'X8632': 'i686-none-nacl-gnu', 'X8664': 'x86_64-none-nacl-gnu', 'ARM': 'armv7a-none-nacl-gnueabihf', 'MIPS32': 'mipsel-none-nacl-gnu'}, 'linux': {'X8632': 'i686-linux-gnu', 'X8664': 'x86_64-linux-gnux32'}, 'mac': {'X8632': 'i686-apple-darwin'}} env.set('TRIPLE', triple_map[env.getone('TARGET_OS')][base_arch]) # CPU that is representative of baseline feature requirements for NaCl # and/or chrome. We may want to make this more like "-mtune" # by specifying both "-mcpu=X" and "-mattr=+feat1,-feat2,...". # Note: this may be different from the in-browser translator, which may # do auto feature detection based on CPUID, but constrained by what is # accepted by NaCl validators. cpu_map = { 'X8632': 'pentium4m', 'X8664': 'x86-64', 'ARM': 'cortex-a9', 'MIPS32': 'mips32r2'} env.set('LLC_MCPU', '-mcpu=%s' % cpu_map[base_arch]) llc_flags_map = { 'ARM': ['-float-abi=hard', '-mattr=+neon'], 'ARM_NONSFI': ['-float-abi=hard', '-arm-enable-dwarf-eh=1'], # To translate x86-32 binary, we set -malign-double option so that the # backend's datalayout matches the datalayout for "le32" used by the # frontend. The le32 datalayout uses 8-byte alignment for the types i64 # and double. i386's datalayout usually uses only 4-byte alignment for # these types, but -malign-double changes that to 8-byte alignment. # This is only needed when translating LLVM IR that hasn't had PNaCl's IR # simplification passes applied to it. 'X8632_NONSFI': ['-malign-double'], } env.set('LLC_FLAGS_ARCH', *llc_flags_map.get(env.getone('ARCH'), [])) env.set('SZ_FLAGS_ARCH', '') # When linking against a host OS's libc (such as Linux glibc), don't # use %gs:0 to read the thread pointer because that won't be # compatible with the libc's use of %gs:0. Similarly, Non-SFI Mode # currently offers no optimized path for reading the thread pointer. if env.getone('TARGET_OS') != 'nacl' or env.getbool('NONSFI_NACL'): env.append('LLC_FLAGS_ARCH', '-mtls-use-call') # For Subzero, determine -target, -sandbox, and -nonsfi options. is_sandbox = '0' is_nonsfi = '0' if env.getone('TARGET_OS') == 'nacl': if env.getbool('NONSFI_NACL'): is_nonsfi = '1' else: is_sandbox = '1' # Subzero arch setup below. if base_arch not in ('X8632', 'X8664', 'ARM'): env.set('SZ_UNSUPPORTED', '1') # Hard-fail on an unsupported architecture. if env.getbool('USE_SZ'): Log.Fatal('Unsupported architecture when using --sz: ' + base_arch) return sz_target = { 'arm': 'arm32', 'x8632': 'x8632', 'x8664': 'x8664', }[base_arch.lower()] env.append('SZ_FLAGS_ARCH', '--sandbox=' + is_sandbox) env.append('SZ_FLAGS_ARCH', '--nonsfi=' + is_nonsfi) env.append('SZ_FLAGS_ARCH', '--target=' + sz_target) # This is a fine place to map OPT_LEVEL to the Subzero equivalent, with # default of -O2. sz_opt_map = { '0': '-Om1', '1': '-O2', '2': '-O2', } env.append('SZ_FLAGS_EXTRA', sz_opt_map.get(env.getone('OPT_LEVEL'), '-O2'))