Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion diffkemp/building/build_kernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@
generate_from_function_list,
read_symbol_list,
EMSG_EMPTY_SYMBOL_LIST)
from diffkemp.utils import init_logger
import errno
import os
import sys


def build_kernel(args):
def build_kernel(args) -> None:
"""
Create snapshot of a Linux kernel source tree. Kernel sources are
compiled into LLVM IR on-the-fly as necessary.
Supports two kinds of symbol lists to generate the snapshot from:
- list of functions (default)
- list of sysctl options
"""
init_logger(args.verbose)
# Create a new snapshot from the kernel source directory.
snapshot = _generate_snapshot(args)

Expand Down
44 changes: 29 additions & 15 deletions diffkemp/llvm_ir/kernel_llvm_source_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@
from diffkemp.llvm_ir.llvm_source_finder import LlvmSourceFinder, \
SourceNotFoundException
from diffkemp.llvm_ir.optimiser import opt_llvm, BuildException
import logging
import os
import shutil
from subprocess import check_call, check_output, CalledProcessError
from subprocess import (check_call, check_output, CalledProcessError, run,
DEVNULL, PIPE)
import subprocess

logger = logging.getLogger(__package__)


class KernelLlvmSourceBuilder(LlvmSourceFinder):
"""
Expand Down Expand Up @@ -489,7 +493,7 @@ def _get_build_source(command):
"""Get name of the object file built by the command."""
return command[command.index("-c") + 1]

def _kbuild_object_command(self, object_file):
def _kbuild_object_command(self, object_file: str) -> str:
"""
Check which command would be run by KBuild to build the given object
file.
Expand All @@ -502,11 +506,14 @@ def _kbuild_object_command(self, object_file):
self._clean_object(object_file)
with open(os.devnull, "w") as stderr:
try:
output = check_output(
["make", "V=1",
"CFLAGS=-w", "EXTRA_CFLAGS=-w",
object_file,
"--just-print"], stderr=stderr).decode("utf-8")
command = [
"make", "V=1",
"CFLAGS=-w", "EXTRA_CFLAGS=-w",
object_file,
"--just-print",
]
logger.debug(f"Running command: {command}")
output = check_output(command, stderr=stderr).decode("utf-8")
except CalledProcessError:
raise BuildException("Error compiling {}".format(object_file))
finally:
Expand Down Expand Up @@ -560,7 +567,7 @@ def _kbuild_module_commands(self, mod_dir, mod_name):
os.chdir(cwd)
raise BuildException("Could not build module {}".format(mod_name))

def _build_source_to_llvm(self, source_file):
def _build_source_to_llvm(self, source_file: str) -> str:
"""
Build C source file into LLVM IR.
Gets the Kbuild command that is used for building an object file,
Expand All @@ -578,16 +585,23 @@ def _build_source_to_llvm(self, source_file):
try:
# Get GCC command for building the .o file
command = self._kbuild_object_command("{}.o".format(name))
logger.debug("Extracted gcc command")
# Convert the GCC command to a corresponding Clang command
command = self._gcc_to_llvm(command)
logger.debug("Translated gcc command to llvm")
# Run the Clang command
with open(os.devnull, "w") as stderr:
try:
check_call(command, stderr=stderr)
except CalledProcessError:
os.chdir(cwd)
raise BuildException(
"Could not build {}".format(llvm_file))
try:
logger.debug(f"Running clang: {command}")
run(command, check=True, text=True,
stdout=DEVNULL, stderr=PIPE)
except CalledProcessError as e:
os.chdir(cwd)
logger.debug(
f"Could not build {source_file} to {llvm_file}:\n"
f"{e.stderr}"
)
raise BuildException(
"Could not build {}".format(llvm_file))
# Run opt with selected optimisations
opt_llvm(llvm_file)
except BuildException:
Expand Down
13 changes: 13 additions & 0 deletions diffkemp/utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import logging
import os
import subprocess
import re
Expand All @@ -8,6 +9,18 @@
CMP_OUTPUT_FILE = "diffkemp-out.yaml"


def init_logger(verbose_level: int) -> None:
"""Initialise logger."""
logger_map = {
0: logging.ERROR,
1: logging.WARNING,
2: logging.INFO,
3: logging.DEBUG,
}
logger_level = logger_map.get(verbose_level, logging.DEBUG)
logging.basicConfig(level=logger_level)


def get_simpll_build_dir():
"""
Return the current SimpLL build directory as specified
Expand Down
Loading