示例#1
0
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()
示例#2
0
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()
示例#3
0
def source():
    """Create KernelSource shared among multiple tests."""
    s = KernelSource("kernel/linux-3.10.0-957.el7", True)
    yield s
    s.finalize()
示例#4
0
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))
示例#5
0
def source():
    s = KernelSource("kernel/linux-3.10.0-957.el7", True)
    yield s
    s.finalize()