def dump_c2mpt_template(arguments): """ :param arguments: :type arguments: """ print_info("Creating a c2mpt C file template...") template_file = findfiles(MICROPROBE_RC['template_paths'], "c2mpt_template.c$")[0] if not os.path.isfile(template_file): print_error("Unable to find base template file: %s" % template_file) _exit(-1) output_file = arguments['output_mpt_file'].rstrip(".mpt") + ".c" print_info("Output file name: %s" % output_file) if os.path.isfile(output_file): print_error("Output file '%s' already exists" % output_file) _exit(-1) try: shutil.copy(template_file, output_file) except IOError: print_error("Something wron when copying '%s' to '%s'\nError: %s " % (template_file, output_file, IOError)) _exit(-1) print_info("Done! You can start editing %s " % output_file)
def find_isa_definitions(paths=None): if paths is None: paths = [] paths = paths + MICROPROBE_RC["architecture_paths"] \ + MICROPROBE_RC["default_paths"] results = [] isafiles = findfiles(paths, "^isa.yaml$") if len(isafiles) > 0: from microprobe.target import Definition for isafile in isafiles: try: isadef = read_yaml(isafile, SCHEMA) except MicroprobeYamlFormatError as exc: LOG.info("Exception: %s", exc) LOG.info("Skipping '%s'", isafile) continue try: definition = Definition(isafile, isadef["Name"], isadef["Description"]) if (definition not in results and not definition.name.endswith("common")): results.append(definition) except TypeError as exc: # Skip bad definitions LOG.info("Exception: %s", exc) LOG.info("Skipping '%s'", isafile) continue return results
def find_env_definitions(paths=None): LOG.debug("Start find environment definitions") global _INIT # pylint: disable=global-statement global _ENV_DEFINITIONS # pylint: disable=global-statement if not _INIT: return _ENV_DEFINITIONS _INIT = False if paths is None: paths = [] paths = paths + MICROPROBE_RC["environment_paths"] \ + MICROPROBE_RC["default_paths"] results = [] files = findfiles(paths, "env/.*.py$", full=True) if len(files) > 0: from microprobe.target import Definition LOG.debug("Files found") for modfile in files: LOG.debug("Processing file: '%s'", modfile) try: envclses = list(find_subclasses(modfile, GenericEnvironment)) except (MicroprobeValueError, TypeError) as exc: continue LOG.debug("Classes find: '%s'", envclses) for envcls in envclses: LOG.debug("Trying class: '%s'", envcls) try: env = envcls(None) definition = Definition(modfile, env.name, env.description) if definition not in results: results.append(definition) except TypeError as exc: # Skip not complete environments LOG.debug("Skipping class '%s'...", envcls) LOG.debug(exc) continue LOG.debug("End find environment definitions") _ENV_DEFINITIONS = results return results
def c2mpt_objdump(input_file, arguments): """ :param input_file: :type input_file: :param arguments: :type arguments: """ print_info("Compiling program for target") cprog = arguments["target_c_compiler"] cflags = " -std=c99" cflags += " ".join( [" -I \"" + elem + "\"" for elem in MICROPROBE_RC['template_paths']]) cflags += " \"%s\"" % findfiles(MICROPROBE_RC['template_paths'], "c2mpt.c$")[0] cflags += " -Wl,--section-start,microprobe.text=" cflags += hex(arguments["default_code_address"]) cflags += " -Wl,--section-start,microprobe.data=" cflags += hex(arguments["default_data_address"]) cflags += " " + arguments["target_c_compiler_flags"] suffix = ".target.bin" if "save_temps" in arguments: compile_file = input_file.rstrip(".c") + suffix else: compile_file = _temp_file(suffix=suffix) _RM_FILES.append(compile_file) cmd = "\"%s\" %s \"%s\" -o \"%s\"" % (cprog, cflags, input_file, compile_file) print_info("Executing compilation command") run_cmd(cmd) objdumpprog = arguments["target_objdump"] objdumpflags = " -D -z -j microprobe.data -j microprobe.text" suffix = ".target.dump" if "save_temps" in arguments: objdump_file = input_file.rstrip(".c") + suffix else: objdump_file = _temp_file(suffix=suffix) _RM_FILES.append(objdump_file) cmd = "\"%s\" %s \"%s\"" % (objdumpprog, objdumpflags, compile_file) run_cmd_output_redirect(cmd, objdump_file) print_info("Executing objdump command") return objdump_file
def find_policy(target_name, policy_name): policy = None paths = MICROPROBE_RC["architecture_paths"] \ + MICROPROBE_RC["default_paths"] policyfiles = findfiles(paths, "policies/.*.py$", full=True) for policyfile in policyfiles: name = (os.path.basename(policyfile).replace(".py", "")) module = load_source("%s_test" % name, policyfile) pdef = dict(inspect.getmembers(module)) if len( [elem for elem in pdef if elem in _POLICY_ATTRIBUTES] ) != len(_POLICY_ATTRIBUTES): continue if (target_name not in pdef['SUPPORTED_TARGETS'] and "all" not in pdef['SUPPORTED_TARGETS']): continue if pdef['NAME'] != policy_name: continue if policy is not None: raise MicroprobePolicyError( "Multiple policies found for '%s' in target '%s'" % (policy_name, target_name) ) # Reload source for good policy with correct module # name module = load_source("%s" % name, policyfile) pdef = dict(inspect.getmembers(module)) policy = Policy( pdef['NAME'], pdef['DESCRIPTION'], pdef['policy'], pdef['SUPPORTED_TARGETS'], pdef ) if policy is None: raise MicroprobePolicyError( "No policies found for '%s' in target '%s'" % (policy_name, target_name) ) return policy
def _import_default_wrappers(): modules = [] LOG.debug('Wrapper paths: %s', MICROPROBE_RC['wrapper_paths']) for path in MICROPROBE_RC['wrapper_paths']: for module in findfiles([path], r"wrappers/.+\.py$", full=True): module = os.path.realpath(module) if module not in modules: modules.append(module) lmodules = -1 while lmodules != len(modules): lmodules = len(modules) for module_file in modules[:]: name = (os.path.basename(module_file).replace(".py", "")) if name == "__init__": continue if name in microprobe.code.wrapper.__dict__: raise MicroprobeError( "Wrapper module name '%s' in '%s' already loaded. " % (name, module_file) ) try: module = load_source(name, module_file) except MicroprobeValueError: continue microprobe.code.wrapper.__dict__[name] = module modules.remove(module_file) current_wrappers = \ [elem.__name__ for elem in get_all_subclasses(microprobe.code.wrapper.Wrapper) ] if len(current_wrappers) != len(set(current_wrappers)): for elem in set(current_wrappers): current_wrappers.remove(elem) overwrapper = list(set(current_wrappers))[0] raise MicroprobeError( "Module name '%s' in '%s' overrides an existing wrapper " "with name '%s'" % (name, module_file, overwrapper) )
def c2mpt_local_run(input_file, arguments): """ :param input_file: :type input_file: :param arguments: :type arguments: """ print_info("Compiling program for host") cprog = arguments["host_c_compiler"] cflags = " -std=c99" cflags += " -DMPT_BASE_ADDRESS=%d" % arguments.get("host_displacement", 0) cflags += " ".join( [" -I \"" + elem + "\"" for elem in MICROPROBE_RC['template_paths']]) cflags += " \"%s\"" % findfiles(MICROPROBE_RC['template_paths'], "c2mpt.c$")[0] cflags += " -Wl,--section-start,microprobe.text=" cflags += hex(arguments["default_code_address"]) cflags += " -Wl,--section-start,microprobe.data=" cflags += hex(arguments["default_data_address"]) cflags += " " + arguments["host_c_compiler_flags"] suffix = ".host.bin" if "save_temps" in arguments: compile_file = input_file.rstrip(".c") + suffix else: compile_file = _temp_file(suffix=suffix) _RM_FILES.append(compile_file) cmd = "\"%s\" %s \"%s\" -o \"%s\"" % (cprog, cflags, input_file, compile_file) print_info("Executing compilation command") run_cmd(cmd) print_info("Executing the compiled program") vardefinitions = run_cmd_output("%s" % compile_file) return vardefinitions
def _compile(filename, target, **kwargs): if "compiler" not in kwargs: print_info("Compiler not provided") print_info("To compiler the code, first extract the custom") print_info("ld script embedded in the assembly as comments to do") print_info("so execute:") print_info("grep 'MICROPROBE LD' %s | cut -d '@' -f 2" % filename) print_info("then compile using gcc and providing the ld script") print_info("using the -T option.") return print_info("Compiling %s ..." % filename) outputname = ".".join(filename.split(".")[:-1]+["elf"]) ldscriptname = ".".join(filename.split(".")[:-1]+["ldscript"]) fdout = open(ldscriptname, "w") fdin = open(filename, "r") for line in fdin.readlines(): if "MICROPROBE LD" in line: line = line.split("@")[1] fdout.write(line) fdout.close() fdin.close() try: baseldscriptname = findfiles( MICROPROBE_RC['template_paths'], "%s.ldscript" % target.name )[0] except IndexError: print_error("Unable to find template ld script: %s.ldscript" % target.name) exit(-1) cprog = kwargs["compiler"] cflags = " -o %s" % outputname cflags += " -T %s" % ldscriptname cflags += " -T %s " % baseldscriptname cflags += kwargs["compiler_flags"] # We only support BFD linker cflags += " -fuse-ld=bfd " cmd = "%s %s %s" % (cprog, cflags, filename) print_info("Executing compilation command") print_info("%s" % cmd) try: run_cmd(cmd) print_info("'%s' generated!" % outputname) except MicroprobeRunCmdError: cflags += " -static" cmd = "%s %s %s" % (cprog, cflags, filename) print_info("Executing compilation command (statically)") print_info("%s" % cmd) try: run_cmd(cmd) print_info("'%s' generated!" % outputname) except MicroprobeRunCmdError: print_info("'%s' not generated due compilation" " issues. Try manual compilation." % outputname)
def _main(arguments): """ Program main, after processing the command line arguments :param arguments: Dictionary with command line arguments and values :type arguments: :class:`dict` """ print_info("Arguments processed!") print_info("Checking input arguments for consistency...") slots = arguments['instruction_slots'] instruction_groups = list( iter_flatten(arguments.get('instruction_groups', []))) check_group_length_func = int_type(1, len(instruction_groups)) check_slots_length_func = int_type(0, slots) instruction_map = arguments.get('instruction_map', None) if instruction_map is None: instruction_map = ['-1'] * slots else: instruction_map = list(iter_flatten(instruction_map)) if len(instruction_map) != slots: print_error('Instruction map: %s' % instruction_map) print_error('Instruction map incorrect. Length should be: %s' % slots) exit(-1) new_map = [] for gmap in instruction_map: ngmap = [] if gmap == "-1": ngmap = list(range(1, len(instruction_groups) + 1)) new_map.append(ngmap) continue for cmap in gmap.split(','): try: ngmap.append(check_group_length_func(cmap)) except argparse.ArgumentTypeError as exc: print_error('Instruction map incorrect') print_error(exc) exit(-1) new_map.append(ngmap) instruction_map = new_map group_max = arguments.get('group_max', None) if group_max is None: group_max = ['-1'] * len(instruction_groups) else: group_max = list(iter_flatten(group_max)) if len(group_max) != len(instruction_groups): print_error('Group max: %s' % group_max) print_error('Group max incorrect. Length should be: %s' % len(instruction_groups)) exit(-1) new_map = [] for gmap in group_max: if gmap == "-1": new_map.append(slots) continue try: new_map.append(check_slots_length_func(gmap)) except argparse.ArgumentTypeError as exc: print_error('Group max incorrect') print_error(exc) exit(-1) group_max = new_map group_min = arguments.get('group_min', None) if group_min is None: group_min = ['-1'] * len(instruction_groups) else: group_min = list(iter_flatten(group_min)) if len(group_min) != len(instruction_groups): print_error('Group min: %s' % group_min) print_error('Group min incorrect. Length should be: %s' % len(instruction_groups)) exit(-1) new_map = [] for gmap in group_min: if gmap == "-1": new_map.append(0) continue try: new_map.append(check_slots_length_func(gmap)) except argparse.ArgumentTypeError as exc: print_error('Group min incorrect') print_error(exc) exit(-1) group_min = new_map print_info("Importing target definition...") target = import_definition(arguments.pop('target')) policy = find_policy(target.name, 'seq') if policy is None: print_error("Target does not implement the default SEQ policy") exit(-1) instruction_groups = [ parse_instruction_list(target, group) for group in instruction_groups ] base_seq = [] if 'base_seq' in arguments: base_seq = parse_instruction_list(target, arguments['base_seq']) sequences = [base_seq] if len(instruction_groups) > 0: sequences = _generate_sequences(slots, instruction_groups, instruction_map, group_max, group_min, base_seq) if 'count' in arguments: print_info("Total number of sequences defined : %s" % len(list(sequences))) exit(0) outputdir = arguments['seq_output_dir'] if _BALANCE_EXECUTION: global _DIRCONTENTS # pylint: disable=global-statement _DIRCONTENTS = set(findfiles([outputdir], "")) outputname = "%INSTR%.%EXT%" if 'reset' not in arguments: arguments['reset'] = False if 'skip' not in arguments: arguments['skip'] = False if 'force_switch' not in arguments: arguments['force_switch'] = False if 'parallel' not in arguments: print_info("Start sequential generation. Use parallel flag to speed") print_info("up the benchmark generation.") for sequence in sequences: _generic_policy_wrapper( (sequence, outputdir, outputname, target, arguments)) else: print_info("Start parallel generation. Threads: %s" % mp.cpu_count()) pool = mp.Pool(processes=mp.cpu_count()) pool.map(_generic_policy_wrapper, [(sequence, outputdir, outputname, target, arguments) for sequence in sequences])