def mod(): """ Build LlvmSysctlModule for net.core.* sysctl options shared among tests. """ source = KernelSource("kernel/linux-3.10.0-862.el7", True) kernel_module = source.get_module_from_source("net/core/sysctl_net_core.c") yield LlvmSysctlModule(kernel_module, "net_core_table") source.finalize()
def generate(args): """ Generate snapshot of sources of kernel functions. This involves: - find source code with functions definitions - compile the source codes into LLVM IR - copy LLVM and C source files into snapshot directory - create YAML with list mapping functions to their LLVM sources """ source = KernelSource(args.kernel_dir, True) args.output_dir = os.path.abspath(args.output_dir) fun_list = FunctionList(args.output_dir) # Cleanup or create the output directory if os.path.isdir(args.output_dir): shutil.rmtree(args.output_dir) os.mkdir(args.output_dir) # Build sources for functions from the list into LLVM IR with open(args.functions_list, "r") as fun_list_file: for line in fun_list_file.readlines(): fun = line.strip() if not fun or not (fun[0].isalpha() or fun[0] == "_"): continue sys.stdout.write("{}: ".format(fun)) try: llvm_mod = source.get_module_for_symbol(fun) print(os.path.relpath(llvm_mod.llvm, args.kernel_dir)) fun_list.add(fun, llvm_mod) except SourceNotFoundException: print("source not found") # Copy LLVM files to the snapshot source.copy_source_files(fun_list.modules(), args.output_dir) source.copy_cscope_files(args.output_dir) # Create YAML with functions list with open(os.path.join(args.output_dir, "functions.yaml"), "w") as fun_list_yaml: fun_list_yaml.write(fun_list.to_yaml()) source.finalize()
def source(): """Create KernelSource shared among multiple tests.""" s = KernelSource("kernel/linux-3.10.0-957.el7", True) yield s s.finalize()
class TaskSpec: """ Task specification representing testing scenario. Contains a list of functions to be compared with DiffKemp during the test. """ def __init__(self, spec, task_name, tasks_path, kernel_path): self.old_kernel_dir = os.path.join(kernel_path, spec["old_kernel"]) self.new_kernel_dir = os.path.join(kernel_path, spec["new_kernel"]) self.name = task_name self.task_dir = os.path.join(tasks_path, task_name) if "control_flow_only" in spec: self.control_flow_only = spec["control_flow_only"] else: self.control_flow_only = False # Create LLVM sources and configuration self.old_kernel = KernelSource(self.old_kernel_dir, True) self.new_kernel = KernelSource(self.new_kernel_dir, True) self.old_snapshot = Snapshot(self.old_kernel, self.old_kernel) self.new_snapshot = Snapshot(self.new_kernel, self.new_kernel) self.config = Config(self.old_snapshot, self.new_snapshot, False, False, self.control_flow_only, False, False, False, None) self.functions = dict() def finalize(self): """ Task finalization - should be called before the task is destroyed. """ self.old_kernel.finalize() self.new_kernel.finalize() def add_function_spec(self, fun, result): """Add a function comparison specification.""" self.functions[fun] = FunctionSpec(fun, result) def build_modules_for_function(self, fun): """ Build LLVM modules containing definition of the compared function in both kernels. """ # Since PyTest may share KernelSource objects among tasks, we need # to explicitly initialize kernels. self.old_kernel.initialize() self.new_kernel.initialize() mod_old = self.old_kernel.get_module_for_symbol(fun) mod_new = self.new_kernel.get_module_for_symbol(fun) self.functions[fun].old_module = mod_old self.functions[fun].new_module = mod_new return mod_old, mod_new def _file_name(self, suffix, ext, name=None): """ Get name of a task file having the given name, suffix, and extension. """ return os.path.join(self.task_dir, "{}_{}.{}".format(name or self.name, suffix, ext)) def old_llvm_file(self, name=None): """Name of the old LLVM file in the task dir.""" return self._file_name("old", "ll", name) def new_llvm_file(self, name=None): """Name of the new LLVM file in the task dir.""" return self._file_name("new", "ll", name) def old_src_file(self, name=None): """Name of the old C file in the task dir.""" return self._file_name("old", "c", name) def new_src_file(self, name=None): """Name of the new C file in the task dir.""" return self._file_name("new", "c", name) def prepare_dir(self, old_module, new_module, old_src, new_src, name=None): """ Create the task directory and copy the LLVM and the C files there. :param old_module: Old LLVM module (instance of LlvmKernelModule). :param old_src: C source from the old kernel version to be copied. :param new_module: New LLVM module (instance of LlvmKernelModule). :param new_src: C source from the new kernel version to be copied. :param name: Optional parameter to specify the new file names. If None then the spec name is used. """ if not os.path.isdir(self.task_dir): os.mkdir(self.task_dir) if not os.path.isfile(self.old_llvm_file(name)): shutil.copyfile(old_module.llvm, self.old_llvm_file(name)) if old_src and not os.path.isfile(self.old_src_file(name)): shutil.copyfile(old_src, self.old_src_file(name)) if not os.path.isfile(self.new_llvm_file(name)): shutil.copyfile(new_module.llvm, self.new_llvm_file(name)) if new_src and not os.path.isfile(self.new_src_file(name)): shutil.copyfile(new_src, self.new_src_file(name))
def source(): s = KernelSource("kernel/linux-3.10.0-957.el7", True) yield s s.finalize()