def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, StripPatterns) inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(inputs) > 1 and output != '': Log.Fatal('Cannot have -o with multiple inputs') if '--info' in env.get('STRIP_FLAGS'): code, _, _ = driver_tools.Run('${STRIP} ${STRIP_FLAGS}') return code for f in inputs: if output != '': f_output = output else: f_output = f if driver_tools.IsBitcode(f): driver_tools.RunWithEnv('${RUN_OPT}', input=f, output=f_output) if env.getbool('DO_WRAP'): driver_tools.WrapBitcode(f_output) elif driver_tools.IsELF(f) or driver_tools.IsNativeArchive(f): driver_tools.RunWithEnv('${RUN_STRIP}', input=f, output=f_output) elif driver_tools.IsBitcodeArchive(f): # The strip tool supports native archives, but it does not support the # LLVM gold plugin so cannot handle bitcode. There is also no bitcode # tool like opt that support archives. Log.Fatal('%s: strip does not support bitcode archives', pathtools.touser(f)) else: Log.Fatal('%s: File is neither ELF, nor bitcode', pathtools.touser(f)) return 0
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, PrepPatterns) inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(inputs) != 1: Log.Fatal('Can only have one input') f_input = inputs[0] # Allow in-place file changes if output isn't specified.. if output != '': f_output = output else: f_output = f_input if env.getbool('DISABLE_FINALIZE'): # Just copy the input file to the output file. if f_input != f_output: shutil.copyfile(f_input, f_output) return 0 # Transform the file, and convert it to a PNaCl bitcode file. driver_tools.RunWithEnv(' '.join(['${RUN_OPT}', '--bitcode-format=pnacl']), input=inputs[0], output=f_output) 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 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) 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) if filetype.IsLLVMBitcode(infile): # Hack to support newlib build. # Newlib determines whether the toolchain supports .init_array, etc., by # compiling a small test and looking for a specific section tidbit using # "readelf -S". Since pnacl compiles to bitcode, readelf isn't available. # (there is a line: "if ${READELF} -S conftest | grep -e INIT_ARRAY" # in newlib's configure file). # TODO(sehr): we may want to implement a whole readelf on bitcode. flags = env.get('FLAGS') if len(flags) == 1 and flags[0] == '-S': print 'INIT_ARRAY' return 0 Log.Fatal('Cannot handle pnacl-readelf %s' % str(argv)) return 1 driver_tools.Run('"${READELF}" ${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) 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, PrepPatterns) inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(inputs) != 1: Log.Fatal('Can only have one input') f_input = inputs[0] # Allow in-place file changes if output isn't specified.. if output != '': f_output = output else: f_output = f_input if env.getbool('DISABLE_FINALIZE') or filetype.IsPNaClBitcode(f_input): # Just copy the input file to the output file. if f_input != f_output: shutil.copyfile(f_input, f_output) return 0 opt_flags = ['-disable-opt', '-strip', '-strip-metadata', '--bitcode-format=pnacl', f_input, '-o', f_output] # Transform the file, and convert it to a PNaCl bitcode file. driver_tools.RunDriver('opt', opt_flags) return 0
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, PrepPatterns) inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(inputs) != 1: Log.Fatal('Can only have one input') f_input = inputs[0] # Allow in-place file changes if output isn't specified.. if output != '': f_output = output else: f_output = f_input if env.getbool('DISABLE_FINALIZE') or filetype.IsPNaClBitcode(f_input): # Just copy the input file to the output file. if f_input != f_output: shutil.copyfile(f_input, f_output) return 0 opt_flags = ['-disable-opt', '-strip', '-strip-metadata', '--bitcode-format=pnacl', f_input, '-o', f_output] # Transform the file, and convert it to a PNaCl bitcode file. driver_tools.RunDriver('opt', opt_flags) # Compress the result if requested. if env.getbool('COMPRESS'): driver_tools.RunDriver('compress', [f_output]) 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: 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 main(argv): env.update(EXTRA_ENV) 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) if filetype.IsLLVMBitcode(infile): # Hack to support newlib build. # Newlib determines whether the toolchain supports .init_array, etc., by # compiling a small test and looking for a specific section tidbit using # "readelf -S". Since pnacl compiles to bitcode, readelf isn't available. # (there is a line: "if ${READELF} -S conftest | grep -e INIT_ARRAY" # in newlib's configure file). # TODO(sehr): we may want to implement a whole readelf on bitcode. flags = env.get('FLAGS') if len(flags) == 1 and flags[0] == '-S': print 'INIT_ARRAY' return 0 Log.Fatal('Cannot handle pnacl-readelf %s' % str(argv)) return 1 Run('"${READELF}" ${FLAGS} ${input}') env.pop() # only reached in case of no errors return 0
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, StripPatterns) inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(inputs) > 1 and output != '': Log.Fatal('Cannot have -o with multiple inputs') if '--info' in env.get('STRIP_FLAGS'): code, _, _ = driver_tools.Run('${STRIP} ${STRIP_FLAGS}') return code for f in inputs: if output != '': f_output = output else: f_output = f if driver_tools.IsLLVMBitcode(f): driver_tools.RunWithEnv('${RUN_OPT}', input=f, output=f_output) elif driver_tools.IsELF(f) or driver_tools.IsNativeArchive(f): driver_tools.RunWithEnv('${RUN_STRIP}', input=f, output=f_output) elif driver_tools.IsBitcodeArchive(f): # The strip tool supports native archives, but it does not support the # LLVM gold plugin so cannot handle bitcode. There is also no bitcode # tool like opt that support archives. Log.Fatal('%s: strip does not support bitcode archives', pathtools.touser(f)) else: Log.Fatal('%s: File is neither ELF, nor bitcode', pathtools.touser(f)) return 0
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, StripPatterns) inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(inputs) > 1 and output != '': Log.Fatal('Cannot have -o with multiple inputs') if '--info' in env.get('STRIP_FLAGS'): code, _, _ = driver_tools.Run('${STRIP} ${STRIP_FLAGS}') return code for f in inputs: if output != '': f_output = output else: f_output = f if driver_tools.IsBitcode(f): driver_tools.RunWithEnv('${RUN_OPT}', input=f, output=f_output) if env.getbool('DO_WRAP'): driver_tools.WrapBitcode(f_output) elif driver_tools.IsELF(f): driver_tools.RunWithEnv('${RUN_STRIP}', input=f, output=f_output) else: Log.Fatal('%s: File is neither ELF nor bitcode', pathtools.touser(f)) 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 (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) 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 (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): if len(argv) == 0: print get_help(argv) return 1 env.update(EXTRA_ENV) ParseArgs(argv, PATTERNS) Run('"${RANLIB}" --plugin=${GOLD_PLUGIN_SO} ${ARGS}') # 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 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') # As we will modify the output file in-place for non-SFI, we output # the file to a temporary file first and then rename it. Otherwise, # build systems such as make assume the output file is ready even # if the last build failed during the in-place update. tmp_output = output + '.tmp' # 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'), True, ldtools.LibraryTypes.NATIVE) env.push() env.set('inputs', *inputs) env.set('output', tmp_output) if env.getbool('SANDBOXED'): RunLDSandboxed() else: Run('${RUN_LD}') if env.getbool('NONSFI_NACL'): # Remove PT_INTERP in non-SFI binaries as we never use host's # dynamic linker/loader. # # This is necessary otherwise we get a statically linked # executable that is not directly runnable by Linux, because Linux # tries to load the non-existent file that PT_INTERP points to. # # This is fairly hacky. It would be better if the linker provided # an option for omitting PT_INTERP (e.g. "--dynamic-linker ''"). RemoveInterpProgramHeader(tmp_output) if driver_tools.IsWindowsPython() and os.path.exists(output): # On Windows (but not on Unix), the os.rename() call would fail if the # output file already exists. os.remove(output) os.rename(tmp_output, output) env.pop() # only reached in case of no errors return 0
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, PATTERNS) driver_tools.Run( '"${LLVM_OPT}" ${ARGS} ' + '${DISABLE_SIMPLIFY_LIBCALLS ? -disable-simplify-libcalls} ' + '${HAVE_OUTPUT ? -o ${OUTPUT}}') # only reached in case of no errors return 0
def get_help(argv): tool = env.getone('SCRIPT_NAME') if '--help-full' in argv: # To get ${CC}, etc. env.update(EXTRA_ENV) code, stdout, stderr = Run('"${CC}" -help', redirect_stdout=subprocess.PIPE, redirect_stderr=subprocess.STDOUT, errexit=False) return stdout else: return """ This is a "GCC-compatible" driver using clang under the hood. Usage: %s [options] <inputs> ... BASIC OPTIONS: -o <file> Output to <file>. -E Only run the preprocessor. -S Generate bitcode assembly. -c Generate bitcode object. -I <dir> Add header search path. -L <dir> Add library search path. -D<key>[=<val>] Add definition for the preprocessor. -W<id> Toggle warning <id>. -f<feature> Enable <feature>. -Wl,<arg> Pass <arg> to the linker. -Xlinker <arg> Pass <arg> to the linker. -Wt,<arg> Pass <arg> to the translator. -Xtranslator <arg> Pass <arg> to the translator. -Wp,<arg> Pass <arg> to the preprocessor. -Xpreprocessor,<arg> Pass <arg> to the preprocessor. -x <language> Treat subsequent input files as having type <language>. -static Produce a static executable. -shared Produce a shared object. -Bstatic Link subsequent libraries statically. -Bdynamic Link subsequent libraries dynamically. -fPIC Ignored (only used by translator backend) (accepted for compatibility). -pipe Ignored (for compatibility). -O<n> Optimation level <n>: 0, 1, 2, 3, 4 or s. -g Generate complete debug information. -gline-tables-only Generate debug line-information only (allowing for stack traces). -flimit-debug-info Generate limited debug information. -save-temps Keep intermediate compilation results. -v Verbose output / show commands. -h | --help Show this help. --help-full Show underlying clang driver's help message (warning: not all options supported). """ % (tool)
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, PATTERNS) # Binary output may go to stdout (when -o was not specified) driver_tools.Run('"${LLVM_OPT}" ${ARGS} ${HAVE_OUTPUT ? -o ${OUTPUT}}') if env.getbool('DO_WRAP'): if not env.getbool('HAVE_OUTPUT'): Log.Error("unable to wrap pexe on stdout, use: --do-no-wrap flag") else: driver_tools.WrapBitcode(env.getone('OUTPUT')) # only reached in case of no errors return 0
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, PATTERNS) driver_tools.Run( '"${LLVM_OPT}" ${ARGS} ' + '${DISABLE_SIMPLIFY_LIBCALLS ? -disable-simplify-libcalls} ' + '${HAVE_OUTPUT ? -o ${OUTPUT}} ' + '${INPUT}') # Opt is the only tool that will modify a file in-place. If this happens we # need to clear the filetype cache so future invocations of the type checking # routines will re-check the file. if env.getone('INPUT') == env.getone('OUTPUT'): filetype.ClearFileTypeCaches() # only reached in case of no errors return 0
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, PrepPatterns) inputs = env.get("INPUTS") output = env.getone("OUTPUT") for path in inputs + [output]: driver_tools.CheckPathLength(path) if len(inputs) != 1: Log.Fatal("Can only have one input") f_input = inputs[0] # Allow in-place file changes if output isn't specified.. if output != "": f_output = output else: f_output = f_input if env.getbool("DISABLE_FINALIZE") or filetype.IsPNaClBitcode(f_input): # Just copy the input file to the output file. if f_input != f_output: shutil.copyfile(f_input, f_output) return 0 opt_flags = [ "-disable-opt", "-strip-metadata", "-strip-module-flags", "--bitcode-format=pnacl", f_input, "-o", f_output, ] if env.getbool("DISABLE_STRIP_SYMS"): opt_flags += ["-strip-debug"] else: opt_flags += ["-strip"] # Transform the file, and convert it to a PNaCl bitcode file. driver_tools.RunDriver("pnacl-opt", opt_flags) # Compress the result if requested. if env.getbool("COMPRESS"): driver_tools.RunDriver("pnacl-compress", [f_output]) return 0
def main(argv): if len(argv) == 0: print get_help(argv) return 1 env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, PATTERNS) # Note: --plugin must come after the command flags, but before the filename. # (definitely confirmed that it cannot go before the command) # for now assume command is just the very first args args = env.get('ARGS') command = args.pop(0) env.set('COMMAND', command) env.set('ARGS', *args) driver_tools.Run('"${AR}" ${COMMAND} --plugin=${GOLD_PLUGIN_SO} ${ARGS}') # only reached in case of no errors return 0
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, META_PATTERNS) inputs = env.get('INPUTS') if not inputs: Usage() DriverExit(1) for f in inputs: if not driver_tools.IsBitcode(f): Log.Fatal("%s: File is not bitcode", pathtools.touser(f)) metadata = driver_tools.GetBitcodeMetadata(f) if env.getbool('RAW'): DumpRaw(metadata) else: DumpPretty(f, metadata) return 0
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, PrepPatterns) inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(inputs) != 1: Log.Fatal('Can only have one input') # Allow in-place file changes if output isn't specified.. if output != '': f_output = output else: f_output = inputs[0] # Transform the file, and wrap the result. driver_tools.RunWithEnv('${RUN_OPT}', input=inputs[0], output=f_output) driver_tools.WrapBitcode(f_output) return 0
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, PrepPatterns) inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(inputs) != 1: Log.Fatal('Can only have one input') f_input = inputs[0] # Allow in-place file changes if output isn't specified. if output != '': f_output = output else: f_output = f_input Compress(f_input, f_output) return 0
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, ASPatterns) arch = driver_tools.GetArch() inputs = env.get('INPUTS') output = env.getone('OUTPUT') for path in inputs + [output]: driver_tools.CheckPathLength(path) num_inputs = len(inputs) if num_inputs > 1: Log.Fatal('Expecting exactly one input file') elif num_inputs == 1: the_input = inputs[0] else: # stdin the_input = '-' if arch: output_type = 'o' else: output_type = 'po' if output == '': output = 'a.out' env.push() env.set('input', the_input) env.set('output', output) if output_type == 'po': # .ll to .po driver_tools.Run("${RUN_LLVM_AS}") else: # .s to .o driver_tools.Run("${RUN_LLVM_MC}") env.pop() # only reached in case of no errors return 0
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, ASPatterns) arch = driver_tools.GetArch() inputs = env.get("INPUTS") output = env.getone("OUTPUT") for path in inputs + [output]: driver_tools.CheckPathLength(path) num_inputs = len(inputs) if num_inputs > 1: Log.Fatal("Expecting exactly one input file") elif num_inputs == 1: the_input = inputs[0] else: # stdin the_input = "-" if arch: output_type = "o" else: output_type = "po" if output == "": output = "a.out" env.push() env.set("input", the_input) env.set("output", output) if output_type == "po": # .ll to .po driver_tools.Run("${RUN_LLVM_AS}") else: # .s to .o driver_tools.Run("${RUN_LLVM_MC}") env.pop() # only reached in case of no errors return 0
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, PrepPatterns) inputs = env.get('INPUTS') output = env.getone('OUTPUT') for path in inputs + [output]: driver_tools.CheckPathLength(path) if len(inputs) != 1: Log.Fatal('Can only have one input') f_input = inputs[0] # Allow in-place file changes if output isn't specified.. if output != '': f_output = output else: f_output = f_input if env.getbool('DISABLE_FINALIZE') or filetype.IsPNaClBitcode(f_input): # Just copy the input file to the output file. if f_input != f_output: shutil.copyfile(f_input, f_output) return 0 opt_flags = [ '-disable-opt', '-strip-metadata', '-strip-module-flags', '--bitcode-format=pnacl', f_input, '-o', f_output ] if env.getbool('DISABLE_STRIP_SYMS'): opt_flags += ['-strip-debug'] else: opt_flags += ['-strip'] # Transform the file, and convert it to a PNaCl bitcode file. driver_tools.RunDriver('pnacl-opt', opt_flags) # Compress the result if requested. if env.getbool('COMPRESS'): driver_tools.RunDriver('pnacl-compress', [f_output]) return 0
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, ASPatterns) arch = driver_tools.GetArch() inputs = env.get('INPUTS') output = env.getone('OUTPUT') num_inputs = len(inputs) if num_inputs > 1: Log.Fatal('Expecting exactly one input file') elif num_inputs == 1: the_input = inputs[0] else: # stdin the_input = '-' if arch: output_type = 'o' else: output_type = 'po' if output == '': output = 'a.out' env.push() env.set('input', the_input) env.set('output', output) if output_type == 'po': # .ll to .po driver_tools.Run("${RUN_LLVM_AS}") else: # .s to .o driver_tools.Run("${RUN_LLVM_MC}") env.pop() # only reached in case of no errors return 0
def main(argv): env.update(EXTRA_ENV) ParseArgs(argv, NMF_PATTERNS) exe_file = env.getone('INPUTS') if not exe_file: Log.Fatal('Expecting input exe_file') DriverExit(1) baseline_file = env.getone('BASELINE_NMF') if not baseline_file: baseline_nmf = {} else: baseline_nmf = ReadBaselineNMF(baseline_file) output = env.getone('OUTPUT') if output == '': output_file = sys.stdout else: output_file = DriverOpen(output, 'w') if not FileType(exe_file) == 'pexe': EchoBaselineNMF(baseline_nmf, output_file) return 0 needed = GetBitcodeMetadata(exe_file).get('NeedsLibrary', []) if len(needed) == 0: GenerateStaticNMF(exe_file, baseline_nmf, output_file) else: # runnable_ld.so is going to ask for libgcc_s.so.1 even though it does # not show up in the pexe's NEEDED metadata, so it won't show up # in the NMF and on the App's webserver. # # For now, hack in libgcc_s.so.1. # http://code.google.com/p/nativeclient/issues/detail?id=2582 needed.append('libgcc_s.so.1') GenerateDynamicNMF(exe_file, baseline_nmf, needed, output_file) DriverClose(output_file) return 0
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, StripPatterns) inputs = env.get('INPUTS') output = env.getone('OUTPUT') for path in inputs + [output]: driver_tools.CheckPathLength(path) if len(inputs) > 1 and output != '': Log.Fatal('Cannot have -o with multiple inputs') if '--info' in env.get('STRIP_FLAGS'): code, _, _ = driver_tools.Run('${STRIP} ${STRIP_FLAGS}') return code for f in inputs: if output != '': f_output = output else: f_output = f if filetype.IsPNaClBitcode(f): # PNaCl-format bitcode has no symbols, i.e. it is already stripped. if f != f_output: shutil.copyfile(f, f_output) elif filetype.IsLLVMBitcode(f): driver_tools.RunWithEnv('${RUN_OPT}', input=f, output=f_output) elif filetype.IsELF(f) or filetype.IsNativeArchive(f): driver_tools.RunWithEnv('${RUN_STRIP}', input=f, output=f_output) elif filetype.IsBitcodeArchive(f): # The strip tool supports native archives, but it does not support the # LLVM gold plugin so cannot handle bitcode. There is also no bitcode # tool like opt that support archives. Log.Fatal('%s: strip does not support bitcode archives', pathtools.touser(f)) else: Log.Fatal('%s: File is neither ELF, nor bitcode', pathtools.touser(f)) return 0
def main(argv): DumpCommand("@incoming", argv) Env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, ARG_PATTERNS) output = Env.getone('OUTPUT') if output == '': Log.Fatal('No output specified. Use -o to specify output') if Env.getone('ARCH') == '': Log.Fatal('No arch specified') mode = Env.getone('MODE') if mode == 'shared': BuildSharedLib() elif mode == 'dynamic': BuildDynamicExecutable() elif mode == 'static': BuildStaticExecutable() else: Log.Fatal('You must specify at least one of -static, -shared, -dynamic') return 0
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 main(argv): env.update(EXTRA_ENV) ParseArgs(argv, LDPatterns) # If the user passed -arch, then they want native output. arch_flag_given = GetArch() is not None # Both LD_FLAGS_NATIVE and TRANSLATE_FLAGS_USER affect # the translation process. If they are non-empty, # then --pnacl-allow-native must be given. allow_native = env.getbool('ALLOW_NATIVE') native_flags = env.get('LD_FLAGS_NATIVE') + env.get('TRANSLATE_FLAGS_USER') if len(native_flags) > 0: if not allow_native: flagstr = ' '.join(native_flags) Log.Fatal('"%s" affects translation. ' 'To allow, specify --pnacl-allow-native' % flagstr) if env.getbool('ALLOW_NATIVE') and not arch_flag_given: Log.Fatal("--pnacl-allow-native given, but translation " "is not happening (missing -arch?)") # Overriding the lib target uses native-flavored bitcode libs rather than the # portable bitcode libs. It is currently only tested/supported for # building the IRT. if not IsPortable(): env.set('BASE_USR', "${BASE_USR_ARCH}") env.set('BASE_LIB', "${BASE_LIB_ARCH}") if env.getbool('RELOCATABLE'): env.set('STATIC', '0') inputs = env.get('INPUTS') output = env.getone('OUTPUT') if output == '': output = pathtools.normalize('a.out') if not arch_flag_given: # If -arch is not given, assume X86-32. # This is because gold requires an arch (even for bitcode linking). SetArch('X8632') assert(GetArch() is not None) inputs = FixPrivateLibs(inputs) # 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'), # Once all glibc bitcode link is purely # bitcode (e.g., even libc_nonshared.a) # we may be able to restrict this more. # This is also currently used by # pnacl_generate_pexe=0 with glibc, # for user libraries. ldtools.LibraryTypes.ANY) # Make sure the inputs have matching arch. CheckInputsArch(inputs) regular_inputs, native_objects = SplitLinkLine(inputs) if env.getbool('RELOCATABLE'): bitcode_type = 'po' native_type = 'o' else: bitcode_type = 'pexe' native_type = 'nexe' if native_objects and not allow_native: argstr = ' '.join(native_objects) Log.Fatal("Native objects '%s' detected in the link. " "To allow, specify --pnacl-allow-native" % argstr) tng = TempNameGen([], output) # Do the bitcode link. if HasBitcodeInputs(inputs): chain = DriverChain(inputs, output, tng) chain.add(LinkBC, 'pre_opt.' + bitcode_type) # Some ABI simplification passes assume the whole program is # available (e.g. -expand-varargs, -nacl-expand-ctors and # -nacl-expand-tls). While we could try running a subset of # simplification passes when linking native objects, we don't # do this because it complicates testing. For example, # it requires '-expand-constant-expr' to be able to handle # 'landingpad' instructions. # However, if we aren't using biased bitcode, then at least -expand-byval # must be run to work with the PPAPI shim calling convention, and # -expand-varargs is needed because after LLVM 3.5 the x86-32 backend does # not expand the llvm.va_arg intrinsic correctly. # (see https://code.google.com/p/nativeclient/issues/detail?id=3913#c24) abi_simplify = (env.getbool('STATIC') and len(native_objects) == 0 and not env.getbool('ALLOW_NEXE_BUILD_ID') and IsPortable()) still_need_expand_byval = IsPortable() and env.getbool('STATIC') still_need_expand_varargs = (still_need_expand_byval and len(native_objects) == 0) # A list of groups of args. Each group should contain a pass to run # along with relevant flags that go with that pass. opt_args = [] if abi_simplify: pre_simplify = ['-pnacl-abi-simplify-preopt'] if env.getone('CXX_EH_MODE') == 'sjlj': pre_simplify += ['-enable-pnacl-sjlj-eh'] else: assert env.getone('CXX_EH_MODE') == 'none' opt_args.append(pre_simplify) else: # '-lowerinvoke' prevents use of C++ exception handling, which # is not yet supported in the PNaCl ABI. '-simplifycfg' removes # landingpad blocks made unreachable by '-lowerinvoke'. # # We run this in order to remove 'resume' instructions, # otherwise these are translated to calls to _Unwind_Resume(), # which will not be available at native link time. opt_args.append(['-lowerinvoke', '-simplifycfg']) if still_need_expand_varargs: opt_args.append(['-expand-varargs']) if env.getone('OPT_LEVEL') != '' and env.getone('OPT_LEVEL') != '0': opt_args.append(env.get('OPT_FLAGS')) if env.getone('STRIP_MODE') != 'none': opt_args.append(env.get('STRIP_FLAGS')) if abi_simplify: post_simplify = ['-pnacl-abi-simplify-postopt'] if not env.getbool('DISABLE_ABI_CHECK'): post_simplify += [ '-verify-pnaclabi-module', '-verify-pnaclabi-functions', # A flag for the above -verify-pnaclabi-* passes. '-pnaclabi-allow-debug-metadata'] opt_args.append(post_simplify) elif still_need_expand_byval: # We may still need -expand-byval to match the PPAPI shim # calling convention. opt_args.append(['-expand-byval']) if len(opt_args) != 0: if env.getbool('RUN_PASSES_SEPARATELY'): for i, group in enumerate(opt_args): chain.add(DoLLVMPasses(group), 'simplify_%d.%s' % (i, bitcode_type)) else: flattened_opt_args = [flag for group in opt_args for flag in group] chain.add(DoLLVMPasses(flattened_opt_args), 'simplify_and_opt.' + bitcode_type) else: chain = DriverChain('', output, tng) if env.getbool('FINALIZE'): chain.add(DoFinalize, 'finalize.' + bitcode_type) # If -arch is also specified, invoke pnacl-translate afterwards. if arch_flag_given: env.set('NATIVE_OBJECTS', *native_objects) chain.add(DoTranslate, native_type) chain.run() if bitcode_type == 'pexe' and not arch_flag_given: # Mark .pexe files as executable. # Some versions of 'configure' expect this. SetExecutableMode(output) return 0
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 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 main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, TranslatorPatterns) if env.getbool('SHARED'): Log.Fatal('Not handling SHARED') 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 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 elif env.getbool('FORCE_INTERMEDIATE_S'): sfile = tng.TempNameForInput(bcfile, 's') 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) # Determine the output type, in this order of precedence: # 1) Output type can be specified on command-line (-S, -c, -static) # -S and -c are handled above by the check that output_type in ('o', 's'). # 2) Otherwise, assume static nexe output. if env.getbool('STATIC'): output_type = 'nexe' else: # Until we stabilize the ABI for shared libraries, # assume that pnacl-translate only handles pexes -> nexes, # to avoid a dependency on bitcode metadata. output_type = 'nexe' env.set('STATIC', '1') assert output_type in ('so','nexe') if env.getone('ARCH') == 'LINUX_X8632': RunHostLD(ofile, output) else: RunLD(ofile, output) return 0
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 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 env.getone('ARCH') == 'LINUX_X8632': RunHostLD(ofile, output) else: RunLD(ofile, output) return 0
def main(argv): env.update(EXTRA_ENV) ParseArgs(argv, LDPatterns) # If the user passed -arch, then they want native output. arch_flag_given = GetArch() is not None # Both LD_FLAGS_NATIVE and TRANSLATE_FLAGS_USER affect # the translation process. If they are non-empty, # then --pnacl-allow-native must be given. allow_native = env.getbool('ALLOW_NATIVE') native_flags = env.get('LD_FLAGS_NATIVE') + env.get('TRANSLATE_FLAGS_USER') if len(native_flags) > 0: if not allow_native: flagstr = ' '.join(native_flags) Log.Fatal('"%s" affects translation. ' 'To allow, specify --pnacl-allow-native' % flagstr) if allow_native: if not arch_flag_given: Log.Fatal("--pnacl-allow-native given, but translation " "is not happening (missing -arch?)") if env.getbool('SHARED'): Log.Fatal('Native shared libraries are not supported with pnacl-ld.') if env.getbool('SHARED'): if env.getbool('RELOCATABLE'): Log.Fatal('-r/-relocatable and -shared may not be passed together.') env.set('RELOCATABLE', '1') # Overriding the lib target uses native-flavored bitcode libs rather than the # portable bitcode libs. It is currently only tested/supported for # building the IRT. if not IsPortable(): env.set('BASE_USR', "${BASE_USR_ARCH}") env.set('BASE_LIB', "${BASE_LIB_ARCH}") if env.getbool('RELOCATABLE'): env.set('STATIC', '0') inputs = env.get('INPUTS') output = env.getone('OUTPUT') if output == '': output = pathtools.normalize('a.out') if not arch_flag_given: # If -arch is not given, assume X86-32. # This is because gold requires an arch (even for bitcode linking). SetArch('X8632') assert(GetArch() is not None) inputs = FixPrivateLibs(inputs) # 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'), # Once all glibc bitcode link is purely # bitcode (e.g., even libc_nonshared.a) # we may be able to restrict this more. # This is also currently used by # pnacl_generate_pexe=0 with glibc, # for user libraries. ldtools.LibraryTypes.ANY) plls, inputs = FilterPlls(inputs) plls = [os.path.basename(pll) for pll in plls] if not env.getbool('SHARED') and plls != []: Log.Fatal('Passing a PLL to the linker requires the "-shared" option.') # Make sure the inputs have matching arch. CheckInputsArch(inputs) regular_inputs, native_objects = SplitLinkLine(inputs) if env.getbool('RELOCATABLE'): bitcode_type = 'po' native_type = 'o' else: bitcode_type = 'pexe' native_type = 'nexe' if native_objects and not allow_native: argstr = ' '.join(native_objects) Log.Fatal("Native objects '%s' detected in the link. " "To allow, specify --pnacl-allow-native" % argstr) tng = TempNameGen([], output) # Do the bitcode link. if HasBitcodeInputs(inputs): chain = DriverChain(inputs, output, tng) chain.add(LinkBC, 'pre_opt.' + bitcode_type) # Some ABI simplification passes assume the whole program is # available (e.g. -expand-varargs, -nacl-expand-ctors and # -nacl-expand-tls). While we could try running a subset of # simplification passes when linking native objects, we don't # do this because it complicates testing. For example, # it requires '-expand-constant-expr' to be able to handle # 'landingpad' instructions. # However, if we aren't using biased bitcode, then at least -expand-byval # must be run to work with the PPAPI shim calling convention, and # -expand-varargs is needed because after LLVM 3.5 the x86-32 backend does # not expand the llvm.va_arg intrinsic correctly. # (see https://code.google.com/p/nativeclient/issues/detail?id=3913#c24) abi_simplify = (env.getbool('STATIC') and len(native_objects) == 0 and not env.getbool('ALLOW_NEXE_BUILD_ID') and IsPortable()) still_need_expand_byval = IsPortable() and env.getbool('STATIC') still_need_expand_varargs = (still_need_expand_byval and len(native_objects) == 0) # A list of groups of args. Each group should contain a pass to run # along with relevant flags that go with that pass. opt_args = [] if env.getbool('SHARED'): pre_simplify_shared = [ # The following is a subset of "-pnacl-abi-simplify-preopt". We don't # want to run the full "-pnacl-abi-simplify-preopt" because it # internalizes symbols that we want to export via "-convert-to-pso". '-nacl-global-cleanup', '-expand-varargs', '-rewrite-pnacl-library-calls', '-rewrite-llvm-intrinsic-calls', '-convert-to-pso', ] # ConvertToPso takes a list of comma-separated PLL dependencies as an # argument. if plls != []: pre_simplify_shared += ['-convert-to-pso-deps=' + ','.join(plls)] opt_args.append(pre_simplify_shared) # Post-opt is required, since '-convert-to-pso' adds metadata which must # be simplified before finalization. Additionally, all functions must be # simplified in the post-opt passes. abi_simplify = True elif abi_simplify: pre_simplify = ['-pnacl-abi-simplify-preopt'] if env.getone('CXX_EH_MODE') == 'sjlj': pre_simplify += ['-enable-pnacl-sjlj-eh'] else: assert env.getone('CXX_EH_MODE') == 'none' opt_args.append(pre_simplify) else: # '-lowerinvoke' prevents use of C++ exception handling, which # is not yet supported in the PNaCl ABI. '-simplifycfg' removes # landingpad blocks made unreachable by '-lowerinvoke'. # # We run this in order to remove 'resume' instructions, # otherwise these are translated to calls to _Unwind_Resume(), # which will not be available at native link time. opt_args.append(['-lowerinvoke', '-simplifycfg']) if still_need_expand_varargs: opt_args.append(['-expand-varargs']) if env.getone('OPT_LEVEL') != '' and env.getone('OPT_LEVEL') != '0': opt_args.append(env.get('OPT_FLAGS')) if env.getone('STRIP_MODE') != 'none': opt_args.append(env.get('STRIP_FLAGS')) if abi_simplify: post_simplify = ['-pnacl-abi-simplify-postopt'] if not env.getbool('DISABLE_ABI_CHECK'): post_simplify += [ '-verify-pnaclabi-module', '-verify-pnaclabi-functions', # A flag for the above -verify-pnaclabi-* passes. '-pnaclabi-allow-debug-metadata'] opt_args.append(post_simplify) elif still_need_expand_byval: # We may still need -expand-byval to match the PPAPI shim # calling convention. opt_args.append(['-expand-byval']) if len(opt_args) != 0: if env.getbool('RUN_PASSES_SEPARATELY'): for i, group in enumerate(opt_args): chain.add(DoLLVMPasses(group), 'simplify_%d.%s' % (i, bitcode_type)) else: flattened_opt_args = [flag for group in opt_args for flag in group] chain.add(DoLLVMPasses(flattened_opt_args), 'simplify_and_opt.' + bitcode_type) else: chain = DriverChain('', output, tng) if env.getbool('FINALIZE'): chain.add(DoFinalize, 'finalize.' + bitcode_type) # If -arch is also specified, invoke pnacl-translate afterwards. if arch_flag_given: env.set('NATIVE_OBJECTS', *native_objects) chain.add(DoTranslate, native_type) chain.run() if bitcode_type == 'pexe' and not arch_flag_given: # Mark .pexe files as executable. # Some versions of 'configure' expect this. SetExecutableMode(output) 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') and not compiling_to_native: Log.Fatal("--pnacl-allow-native without -arch is not meaningful.") if not env.get('STDLIB'): # Default C++ Standard Library. SetStdLib('libc++') inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(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) 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: # Filter out flags inputs = [f for f in inputs if not IsFlag(f)] 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: if IsFlag(f): continue intype = filetype.FileType(f) if not filetype.IsSourceType(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(inputs, output) # Compile all source files (c/c++/ll) to .po for i in xrange(0, len(inputs)): if IsFlag(inputs[i]): continue intype = filetype.FileType(inputs[i]) if filetype.IsSourceType(intype) or intype == 'll': inputs[i] = CompileOne(inputs[i], 'po', namegen) # Compile all .s/.S to .o if env.getbool('ALLOW_NATIVE'): for i in xrange(0, len(inputs)): if IsFlag(inputs[i]): continue intype = filetype.FileType(inputs[i]) if intype in ('s', 'S'): inputs[i] = CompileOne(inputs[i], 'o', namegen) # We should only be left with .po and .o and libraries for f in 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 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('ld', ld_flags + ld_args + ['-o', output]) return 0
def main(argv): env.update(EXTRA_ENV) ParseArgs(argv, LDPatterns) # If the user passed -arch, then they want native output. arch_flag_given = GetArch() is not None # Both LD_FLAGS_NATIVE and TRANSLATE_FLAGS_USER affect # the translation process. If they are non-empty, # then --pnacl-allow-native must be given. allow_native = env.getbool('ALLOW_NATIVE') native_flags = env.get('LD_FLAGS_NATIVE') + env.get('TRANSLATE_FLAGS_USER') if len(native_flags) > 0: if not allow_native: flagstr = ' '.join(native_flags) Log.Fatal('"%s" affects translation. ' 'To allow, specify --pnacl-allow-native' % flagstr) if env.getbool('ALLOW_NATIVE') and not arch_flag_given: Log.Fatal("--pnacl-allow-native given, but translation " "is not happening (missing -arch?)") if env.getbool('RELOCATABLE'): if env.getbool('SHARED'): Log.Fatal("-r and -shared may not be used together") env.set('STATIC', '0') inputs = env.get('INPUTS') output = env.getone('OUTPUT') if output == '': output = pathtools.normalize('a.out') if not arch_flag_given: # If -arch is not given, assume X86-32. # This is because gold requires an arch (even for bitcode linking). SetArch('X8632') assert(GetArch() is not None) # 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'), # Once all glibc bitcode link is purely # bitcode (e.g., even libc_nonshared.a) # we may be able to restrict this more. # This is also currently used by # pnacl_generate_pexe=0 with glibc, # for user libraries. ldtools.LibraryTypes.ANY) # Make sure the inputs have matching arch. CheckInputsArch(inputs) regular_inputs, native_objects = SplitLinkLine(inputs) if not env.getbool('USE_IRT'): inputs = UsePrivateLibraries(inputs) # Filter out object files which are currently used in the bitcode link. # These don't actually need to be treated separately, since the # translator includes them automatically. Eventually, these will # be compiled to bitcode or replaced by bitcode stubs, and this list # can go away. if env.getbool('STDLIB'): native_objects = RemoveNativeStdLibs(native_objects) 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' if native_objects and not allow_native: argstr = ' '.join(native_objects) Log.Fatal("Native objects '%s' detected in the link. " "To allow, specify --pnacl-allow-native" % argstr) tng = TempNameGen([], output) # Do the bitcode link. if HasBitcodeInputs(inputs): chain = DriverChain(inputs, output, tng) chain.add(LinkBC, 'pre_opt.' + bitcode_type) # Some ABI simplification passes assume the whole program is # available (e.g. -expand-varargs, -nacl-expand-ctors and # -nacl-expand-tls). While we could try running a subset of # simplification passes when linking native objects or enabling # C++ exception handling, we don't do this because it complicates # testing. For example, it requires '-expand-constant-expr' to be # able to handle 'landingpad' instructions. abi_simplify = (env.getbool('STATIC') and len(native_objects) == 0 and not env.getbool('ALLOW_CXX_EXCEPTIONS') and not env.getbool('ALLOW_NEXE_BUILD_ID')) preopt_passes = [] if abi_simplify: preopt_passes += ['-pnacl-abi-simplify-preopt'] elif not env.getbool('ALLOW_CXX_EXCEPTIONS'): # '-lowerinvoke' prevents use of C++ exception handling, which # is not yet supported in the PNaCl ABI. '-simplifycfg' removes # landingpad blocks made unreachable by '-lowerinvoke'. # # We run this in order to remove 'resume' instructions, # otherwise these are translated to calls to _Unwind_Resume(), # which will not be available at native link time. preopt_passes += ['-lowerinvoke', '-simplifycfg'] if len(preopt_passes) != 0: chain.add(DoLLVMPasses(preopt_passes), 'simplify_preopt.' + bitcode_type) if env.getone('OPT_LEVEL') != '' and env.getone('OPT_LEVEL') != '0': chain.add(DoLTO, 'opt.' + bitcode_type) elif env.getone('STRIP_MODE') != 'none': chain.add(DoStrip, 'stripped.' + bitcode_type) if abi_simplify: postopt_passes = ['-pnacl-abi-simplify-postopt'] if not env.getbool('DISABLE_ABI_CHECK'): postopt_passes += [ '-verify-pnaclabi-module', '-verify-pnaclabi-functions', # A flag for the above -verify-pnaclabi-* passes. '-pnaclabi-allow-debug-metadata'] chain.add(DoLLVMPasses(postopt_passes), 'simplify_postopt.' + bitcode_type) else: chain = DriverChain('', output, tng) # If -arch is also specified, invoke pnacl-translate afterwards. if arch_flag_given: env.set('NATIVE_OBJECTS', *native_objects) chain.add(DoTranslate, native_type) chain.run() if bitcode_type == 'pexe' and not arch_flag_given: # Mark .pexe files as executable. # Some versions of 'configure' expect this. SetExecutableMode(output) return 0
def main(argv): env.update(EXTRA_ENV) ParseArgs(argv, PATTERNS) Run('"${NM}" --plugin=${GOLD_PLUGIN_SO} ${ARGS}') # only reached in case of no errors return 0
def main(argv): env.update(EXTRA_ENV) ParseArgs(argv, LDPatterns) # If the user passed -arch, then they want native output. arch_flag_given = GetArch() is not None # Both LD_FLAGS_NATIVE and TRANSLATE_FLAGS_USER affect # the translation process. If they are non-empty, # then --pnacl-allow-native must be given. allow_native = env.getbool('ALLOW_NATIVE') native_flags = env.get('LD_FLAGS_NATIVE') + env.get('TRANSLATE_FLAGS_USER') if len(native_flags) > 0: if not allow_native: flagstr = ' '.join(native_flags) Log.Fatal('"%s" affects translation. ' 'To allow, specify --pnacl-allow-native' % flagstr) if env.getbool('ALLOW_NATIVE') and not arch_flag_given: Log.Fatal("--pnacl-allow-native given, but translation " "is not happening (missing -arch?)") # Overriding the lib target uses native-flavored bitcode libs rather than the # portable bitcode libs. It is currently only tested/supported for # building the IRT. if not IsPortable(): env.set('BASE_USR', "${BASE_USR_ARCH}") env.set('BASE_LIB', "${BASE_LIB_ARCH}") if env.getbool('RELOCATABLE'): env.set('STATIC', '0') inputs = env.get('INPUTS') output = env.getone('OUTPUT') if output == '': output = pathtools.normalize('a.out') if not arch_flag_given: # If -arch is not given, assume X86-32. # This is because gold requires an arch (even for bitcode linking). SetArch('X8632') assert (GetArch() is not None) inputs = FixPrivateLibs(inputs) # 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'), # Once all glibc bitcode link is purely # bitcode (e.g., even libc_nonshared.a) # we may be able to restrict this more. # This is also currently used by # pnacl_generate_pexe=0 with glibc, # for user libraries. ldtools.LibraryTypes.ANY) # Make sure the inputs have matching arch. CheckInputsArch(inputs) regular_inputs, native_objects = SplitLinkLine(inputs) if env.getbool('RELOCATABLE'): bitcode_type = 'po' native_type = 'o' else: bitcode_type = 'pexe' native_type = 'nexe' if native_objects and not allow_native: argstr = ' '.join(native_objects) Log.Fatal("Native objects '%s' detected in the link. " "To allow, specify --pnacl-allow-native" % argstr) tng = TempNameGen([], output) # Do the bitcode link. if HasBitcodeInputs(inputs): chain = DriverChain(inputs, output, tng) chain.add(LinkBC, 'pre_opt.' + bitcode_type) # Some ABI simplification passes assume the whole program is # available (e.g. -expand-varargs, -nacl-expand-ctors and # -nacl-expand-tls). While we could try running a subset of # simplification passes when linking native objects, we don't # do this because it complicates testing. For example, # it requires '-expand-constant-expr' to be able to handle # 'landingpad' instructions. # However, if we aren't using biased bitcode, then at least -expand-byval # must be run to work with the PPAPI shim calling convention. # This assumes that PPAPI does not use var-args, so passes like # -expand-varargs and other calling-convention-changing passes are # not needed. abi_simplify = (env.getbool('STATIC') and len(native_objects) == 0 and env.getone('CXX_EH_MODE') != 'zerocost' and not env.getbool('ALLOW_NEXE_BUILD_ID') and IsPortable()) still_need_expand_byval = IsPortable() abi_simplify_opts = [] if env.getone('CXX_EH_MODE') == 'sjlj': abi_simplify_opts += ['-enable-pnacl-sjlj-eh'] preopt_passes = [] if abi_simplify: preopt_passes += ['-pnacl-abi-simplify-preopt'] + abi_simplify_opts elif env.getone('CXX_EH_MODE') != 'zerocost': # '-lowerinvoke' prevents use of C++ exception handling, which # is not yet supported in the PNaCl ABI. '-simplifycfg' removes # landingpad blocks made unreachable by '-lowerinvoke'. # # We run this in order to remove 'resume' instructions, # otherwise these are translated to calls to _Unwind_Resume(), # which will not be available at native link time. preopt_passes += ['-lowerinvoke', '-simplifycfg'] if len(preopt_passes) != 0: chain.add(DoLLVMPasses(preopt_passes), 'simplify_preopt.' + bitcode_type) if env.getone('OPT_LEVEL') != '' and env.getone('OPT_LEVEL') != '0': chain.add(DoLTO, 'opt.' + bitcode_type) elif env.getone('STRIP_MODE') != 'none': chain.add(DoStrip, 'stripped.' + bitcode_type) postopt_passes = [] if abi_simplify: postopt_passes = ['-pnacl-abi-simplify-postopt' ] + abi_simplify_opts if not env.getbool('DISABLE_ABI_CHECK'): postopt_passes += [ '-verify-pnaclabi-module', '-verify-pnaclabi-functions', # A flag for the above -verify-pnaclabi-* passes. '-pnaclabi-allow-debug-metadata' ] if env.getbool('ALLOW_DEV_INTRINSICS'): # A flag for the above -verify-pnaclabi-* passes. postopt_passes += ['-pnaclabi-allow-dev-intrinsics'] elif still_need_expand_byval: # We may still need -expand-byval to match the PPAPI shim # calling convention. postopt_passes = ['-expand-byval'] if len(postopt_passes) != 0: chain.add(DoLLVMPasses(postopt_passes), 'simplify_postopt.' + bitcode_type) else: chain = DriverChain('', output, tng) # If -arch is also specified, invoke pnacl-translate afterwards. if arch_flag_given: env.set('NATIVE_OBJECTS', *native_objects) chain.add(DoTranslate, native_type) chain.run() if bitcode_type == 'pexe' and not arch_flag_given: # Mark .pexe files as executable. # Some versions of 'configure' expect this. SetExecutableMode(output) return 0
def main(argv): env.update(EXTRA_ENV) ParseArgs(argv, LDPatterns) # If the user passed -arch, then they want native output. arch_flag_given = GetArch() is not None # Both LD_FLAGS_NATIVE and TRANSLATE_FLAGS_USER affect # the translation process. If they are non-empty, # then --pnacl-allow-native must be given. allow_native = env.getbool('ALLOW_NATIVE') native_flags = env.get('LD_FLAGS_NATIVE') + env.get('TRANSLATE_FLAGS_USER') if len(native_flags) > 0: if not allow_native: flagstr = ' '.join(native_flags) Log.Fatal('"%s" affects translation. ' 'To allow, specify --pnacl-allow-native' % flagstr) if env.getbool('ALLOW_NATIVE') and not arch_flag_given: Log.Fatal("--pnacl-allow-native given, but translation " "is not happening (missing -arch?)") if env.getbool('RELOCATABLE'): if env.getbool('SHARED'): Log.Fatal("-r and -shared may not be used together") env.set('STATIC', '0') inputs = env.get('INPUTS') output = env.getone('OUTPUT') if output == '': output = pathtools.normalize('a.out') if not arch_flag_given: # If -arch is not given, assume X86-32. # This is because gold requires an arch (even for bitcode linking). SetArch('X8632') assert(GetArch() is not None) # 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'), # Once all glibc bitcode link is purely # bitcode (e.g., even libc_nonshared.a) # we may be able to restrict this more. # This is also currently used by # pnacl_generate_pexe=0 with glibc, # for user libraries. ldtools.LibraryTypes.ANY) # Make sure the inputs have matching arch. CheckInputsArch(inputs) regular_inputs, native_objects = SplitLinkLine(inputs) if not env.getbool('USE_IRT'): inputs = UsePrivateLibraries(inputs) # Filter out object files which are currently used in the bitcode link. # These don't actually need to be treated separately, since the # translator includes them automatically. Eventually, these will # be compiled to bitcode or replaced by bitcode stubs, and this list # can go away. if env.getbool('STDLIB'): native_objects = RemoveNativeStdLibs(native_objects) 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' if native_objects and not allow_native: argstr = ' '.join(native_objects) Log.Fatal("Native objects '%s' detected in the link. " "To allow, specify --pnacl-allow-native" % argstr) tng = TempNameGen([], output) # Do the bitcode link. if HasBitcodeInputs(inputs): chain = DriverChain(inputs, output, tng) chain.add(LinkBC, 'pre_opt.' + bitcode_type) if env.getbool('STATIC') and len(native_objects) == 0: chain.add(DoExpandCtors, 'expand_ctors.' + 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) else: chain = DriverChain('', output, tng) # If -arch is also specified, invoke pnacl-translate afterwards. if arch_flag_given: env.set('NATIVE_OBJECTS', *native_objects) chain.add(DoTranslate, native_type) chain.run() if bitcode_type == 'pexe' and not arch_flag_given: # Add bitcode wrapper header WrapBitcode(output) # Mark .pexe files as executable. # Some versions of 'configure' expect this. SetExecutableMode(output) return 0
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 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 elif env.getbool('FORCE_INTERMEDIATE_S'): sfile = tng.TempNameForInput(bcfile, 's') 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 env.getone('ARCH') == 'LINUX_X8632': RunHostLD(ofile, output) else: RunLD(ofile, output) 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') and not compiling_to_native: Log.Fatal("--pnacl-allow-native without -arch is not meaningful.") if not env.get('STDLIB'): # Default C++ Standard Library. SetStdLib('libc++') inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(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) 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: # Filter out flags inputs = [f for f in inputs if not IsFlag(f)] 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: if IsFlag(f): continue intype = filetype.FileType(f) if not filetype.IsSourceType(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(inputs, output) # Compile all source files (c/c++/ll) to .po for i in xrange(0, len(inputs)): if IsFlag(inputs[i]): continue intype = filetype.FileType(inputs[i]) if filetype.IsSourceType(intype) or intype == 'll': inputs[i] = CompileOne(inputs[i], 'po', namegen) # Compile all .s/.S to .o if env.getbool('ALLOW_NATIVE'): for i in xrange(0, len(inputs)): if IsFlag(inputs[i]): continue intype = filetype.FileType(inputs[i]) if intype in ('s','S'): inputs[i] = CompileOne(inputs[i], 'o', namegen) # We should only be left with .po and .o and libraries for f in 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 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('ld', ld_flags + ld_args + ['-o', output]) 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