def RunDriver(invocation, args, suppress_inherited_arch_args=False): """ RunDriver() is used to invoke "driver" tools, e.g. those prefixed with "pnacl-" It automatically appends some additional flags to the invocation which were inherited from the current invocation. Those flags were preserved by ParseArgs """ if isinstance(args, str): args = shell.split(env.eval(args)) module_name = 'pnacl-%s' % invocation script = env.eval('${DRIVER_BIN}/%s' % module_name) script = shell.unescape(script) inherited_driver_args = env.get('INHERITED_DRIVER_ARGS') if suppress_inherited_arch_args: inherited_driver_args = FilterOutArchArgs(inherited_driver_args) script = pathtools.tosys(script) cmd = [script] + args + inherited_driver_args Log.Info('Driver invocation: %s', repr(cmd)) module = __import__(module_name) # Save the environment, reset the environment, run # the driver module, and then restore the environment. env.push() env.reset() DriverMain(module, cmd) env.pop()
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) 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 RunDriver(module_name, args, suppress_inherited_arch_args=False): """ RunDriver() is used to invoke "driver" tools, e.g. those prefixed with "pnacl-" It automatically appends some additional flags to the invocation which were inherited from the current invocation. Those flags were preserved by ParseArgs """ if isinstance(args, str): args = shell.split(env.eval(args)) script = env.eval('${DRIVER_BIN}/%s' % module_name) script = shell.unescape(script) inherited_driver_args = env.get('INHERITED_DRIVER_ARGS') if suppress_inherited_arch_args: inherited_driver_args = FilterOutArchArgs(inherited_driver_args) script = pathtools.tosys(script) cmd = [script] + args + inherited_driver_args Log.Info('Driver invocation: %s', repr(cmd)) module = __import__(module_name) # Save the environment, reset the environment, run # the driver module, and then restore the environment. env.push() env.reset() DriverMain(module, cmd) env.pop()
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: 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, 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, 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): 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 test_SaveTempsNotWiped(self): """Test that driver-generated temp files don't get wiped w/ "-save-temps". """ env.push() env.set('SAVE_TEMPS', '1') t_gen_out, t_gen_in = self.nameGenTemps() # Now wipe! driver_temps.TempFiles.wipe() env.pop() # They are *not* gone. self.assertTrue(os.path.exists(t_gen_out)) self.assertTrue(os.path.exists(t_gen_in))
def RunLLC(infile, outfile, filetype): env.push() env.setmany(input=infile, output=outfile, filetype=filetype) if env.getbool('SANDBOXED'): is_shared, soname, needed = RunLLCSandboxed() env.pop() # soname and dt_needed libs are returned from LLC and passed to LD driver_tools.SetBitcodeMetadata(infile, is_shared, soname, needed) else: driver_tools.Run("${RUN_LLC}") # As a side effect, this creates a temporary file if not env.getbool('SAVE_TEMPS'): TempFiles.add(outfile + '.meta') env.pop() return 0
def RunLLC(infile, outfile, filetype): env.push() env.setmany(input=infile, output=outfile, filetype=filetype) if env.getbool('SANDBOXED'): is_shared, soname, needed = RunLLCSandboxed() env.pop() # soname and dt_needed libs are returned from LLC and passed to LD driver_tools.SetBitcodeMetadata(infile, is_shared, soname, needed) else: args = ["${RUN_LLC}"] if driver_tools.IsPNaClBitcode(infile): args.append("-bitcode-format=pnacl") driver_tools.Run(' '.join(args)) env.pop() return 0
def RunCompiler(infile, outfile, outfiletype, use_sz): env.push() env.setmany(input=infile, output=outfile, outfiletype=outfiletype) if env.getbool('SANDBOXED'): RunSandboxedCompiler(use_sz) else: args = ["${RUN_SZ}" if use_sz else "${RUN_LLC}"] if filetype.IsPNaClBitcode(infile): args.append("-bitcode-format=pnacl") elif filetype.IsLLVMBitcode(infile): if not env.getbool('ALLOW_LLVM_BITCODE_INPUT'): Log.Fatal('Translator expects finalized PNaCl bitcode. ' 'Pass --allow-llvm-bitcode-input to override.') driver_tools.Run(' '.join(args)) env.pop() return 0
def RunLLC(infile, outfile, outfiletype): env.push() env.setmany(input=infile, output=outfile, outfiletype=outfiletype) if env.getbool('SANDBOXED'): is_shared, soname, needed = RunLLCSandboxed() # Ignore is_shared, soname, and needed for now, since we aren't # dealing with bitcode shared libraries. env.pop() else: args = ["${RUN_LLC}"] if filetype.IsPNaClBitcode(infile): args.append("-bitcode-format=pnacl") elif filetype.IsLLVMBitcode(infile): if not env.getbool('ALLOW_LLVM_BITCODE_INPUT'): Log.Fatal('Translator expects finalized PNaCl bitcode. ' 'Pass --allow-llvm-bitcode-input to override.') driver_tools.Run(' '.join(args)) env.pop() 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, 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 setUp(self): env.push()
def RunWithEnv(cmd, **kwargs): env.push() env.setmany(**kwargs) ret = Run(cmd) env.pop() return ret