From 695afd3d7d58ec3044d25c9d2fe384ab8627fd20 Mon Sep 17 00:00:00 2001 From: Sedat Dilek Date: Sun, 16 Aug 2020 14:32:44 +0200 Subject: [PATCH 01/34] kbuild: Simplify DEBUG_INFO Kconfig handling While playing with [1] I saw that the handling of CONFIG_DEBUG_INFO can be simplified. [1] https://patchwork.kernel.org/patch/11716107/ Signed-off-by: Sedat Dilek Signed-off-by: Masahiro Yamada --- Makefile | 6 +++++- lib/Kconfig.debug | 10 ++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index f21168154160..4ef6a73e48a7 100644 --- a/Makefile +++ b/Makefile @@ -816,13 +816,15 @@ endif DEBUG_CFLAGS := $(call cc-option, -fno-var-tracking-assignments) ifdef CONFIG_DEBUG_INFO + ifdef CONFIG_DEBUG_INFO_SPLIT DEBUG_CFLAGS += -gsplit-dwarf else DEBUG_CFLAGS += -g endif + KBUILD_AFLAGS += -Wa,-gdwarf-2 -endif + ifdef CONFIG_DEBUG_INFO_DWARF4 DEBUG_CFLAGS += -gdwarf-4 endif @@ -838,6 +840,8 @@ KBUILD_AFLAGS += -gz=zlib KBUILD_LDFLAGS += --compress-debug-sections=zlib endif +endif # CONFIG_DEBUG_INFO + KBUILD_CFLAGS += $(DEBUG_CFLAGS) export DEBUG_CFLAGS diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index e068c3c7189a..60f3837f608c 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -212,9 +212,10 @@ config DEBUG_INFO If unsure, say N. +if DEBUG_INFO + config DEBUG_INFO_REDUCED bool "Reduce debugging information" - depends on DEBUG_INFO help If you say Y here gcc is instructed to generate less debugging information for structure types. This means that tools that @@ -227,7 +228,6 @@ config DEBUG_INFO_REDUCED config DEBUG_INFO_COMPRESSED bool "Compressed debugging information" - depends on DEBUG_INFO depends on $(cc-option,-gz=zlib) depends on $(ld-option,--compress-debug-sections=zlib) help @@ -243,7 +243,6 @@ config DEBUG_INFO_COMPRESSED config DEBUG_INFO_SPLIT bool "Produce split debuginfo in .dwo files" - depends on DEBUG_INFO depends on $(cc-option,-gsplit-dwarf) help Generate debug info into separate .dwo files. This significantly @@ -259,7 +258,6 @@ config DEBUG_INFO_SPLIT config DEBUG_INFO_DWARF4 bool "Generate dwarf4 debuginfo" - depends on DEBUG_INFO depends on $(cc-option,-gdwarf-4) help Generate dwarf4 debug info. This requires recent versions @@ -269,7 +267,6 @@ config DEBUG_INFO_DWARF4 config DEBUG_INFO_BTF bool "Generate BTF typeinfo" - depends on DEBUG_INFO depends on !DEBUG_INFO_SPLIT && !DEBUG_INFO_REDUCED depends on !GCC_PLUGIN_RANDSTRUCT || COMPILE_TEST help @@ -279,7 +276,6 @@ config DEBUG_INFO_BTF config GDB_SCRIPTS bool "Provide GDB scripts for kernel debugging" - depends on DEBUG_INFO help This creates the required links to GDB helper scripts in the build directory. If you load vmlinux into gdb, the helper @@ -288,6 +284,8 @@ config GDB_SCRIPTS instance. See Documentation/dev-tools/gdb-kernel-debugging.rst for further details. +endif # DEBUG_INFO + config ENABLE_MUST_CHECK bool "Enable __must_check logic" default y From 23cd88c91343349a0d67a227f9effdde0cbe09af Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 21 Aug 2020 11:43:58 +0900 Subject: [PATCH 02/34] kbuild: hide commands to run Kconfig, and show short log for syncconfig Some targets (localyesconfig, localmodconfig, defconfig) hide the command running, but the others do not. Users know which Kconfig flavor they are running, so it is OK to hide the command. Add $(Q) to all commands consistently. If you want to see the full command running, pass V=1 from the command line. syncconfig is the exceptional case, which occurs without explicit command invocation by the user. Display the Kbuild-style log for it. The ugly bare log will go away. [Before] scripts/kconfig/conf --syncconfig Kconfig [After] SYNC include/config/auto.conf Signed-off-by: Masahiro Yamada --- Makefile | 5 ++++- scripts/kconfig/Makefile | 16 ++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 4ef6a73e48a7..d96f2feddbfb 100644 --- a/Makefile +++ b/Makefile @@ -707,8 +707,11 @@ $(KCONFIG_CONFIG): # This exploits the 'multi-target pattern rule' trick. # The syncconfig should be executed only once to make all the targets. # (Note: use the grouped target '&:' when we bump to GNU Make 4.3) +quiet_cmd_syncconfig = SYNC $@ + cmd_syncconfig = $(MAKE) -f $(srctree)/Makefile syncconfig + %/config/auto.conf %/config/auto.conf.cmd %/generated/autoconf.h: $(KCONFIG_CONFIG) - $(Q)$(MAKE) -f $(srctree)/Makefile syncconfig + +$(call cmd,syncconfig) else # !may-sync-config # External modules and some install targets need include/generated/autoconf.h # and include/config/auto.conf but do not care if they are up-to-date. diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 52b59bf9efe4..e46df0a2d4f9 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -20,19 +20,19 @@ endif unexport CONFIG_ xconfig: $(obj)/qconf - $< $(silent) $(Kconfig) + $(Q)$< $(silent) $(Kconfig) gconfig: $(obj)/gconf - $< $(silent) $(Kconfig) + $(Q)$< $(silent) $(Kconfig) menuconfig: $(obj)/mconf - $< $(silent) $(Kconfig) + $(Q)$< $(silent) $(Kconfig) config: $(obj)/conf - $< $(silent) --oldaskconfig $(Kconfig) + $(Q)$< $(silent) --oldaskconfig $(Kconfig) nconfig: $(obj)/nconf - $< $(silent) $(Kconfig) + $(Q)$< $(silent) $(Kconfig) build_menuconfig: $(obj)/mconf @@ -68,12 +68,12 @@ simple-targets := oldconfig allnoconfig allyesconfig allmodconfig \ PHONY += $(simple-targets) $(simple-targets): $(obj)/conf - $< $(silent) --$@ $(Kconfig) + $(Q)$< $(silent) --$@ $(Kconfig) PHONY += savedefconfig defconfig savedefconfig: $(obj)/conf - $< $(silent) --$@=defconfig $(Kconfig) + $(Q)$< $(silent) --$@=defconfig $(Kconfig) defconfig: $(obj)/conf ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)),) @@ -111,7 +111,7 @@ tinyconfig: # CHECK: -o cache_dir= working? PHONY += testconfig testconfig: $(obj)/conf - $(PYTHON3) -B -m pytest $(srctree)/$(src)/tests \ + $(Q)$(PYTHON3) -B -m pytest $(srctree)/$(src)/tests \ -o cache_dir=$(abspath $(obj)/tests/.cache) \ $(if $(findstring 1,$(KBUILD_VERBOSE)),--capture=no) clean-files += tests/.cache From 8a685db32f2b3495c91efab6e9462c2fd934778f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 22 Aug 2020 23:56:09 +0900 Subject: [PATCH 03/34] gen_compile_commands: parse only the first line of .*.cmd files After the allmodconfig build, this script takes about 5 sec on my machine. Most of the run-time is consumed for needless regex matching. We know the format of .*.cmd file; the first line is the build command. There is no need to parse the rest. With this optimization, now it runs 4 times faster. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers Tested-by: Nick Desaulniers --- scripts/gen_compile_commands.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/scripts/gen_compile_commands.py b/scripts/gen_compile_commands.py index c458696ef3a7..1bcf33a93cb9 100755 --- a/scripts/gen_compile_commands.py +++ b/scripts/gen_compile_commands.py @@ -125,11 +125,8 @@ def main(): filepath = os.path.join(dirpath, filename) with open(filepath, 'rt') as f: - for line in f: - result = line_matcher.match(line) - if not result: - continue - + result = line_matcher.match(f.readline()) + if result: try: entry = process_line(directory, dirpath, result.group(1), result.group(2)) From ea6cedc5b8a4e666da41f1173ea19970fa60683f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 22 Aug 2020 23:56:10 +0900 Subject: [PATCH 04/34] gen_compile_commands: use choices for --log_levels option Use 'choices' to check if the given parameter is valid. I also simplified the help message because, with 'choices', --help shows the list of valid parameters: --log_level {DEBUG,INFO,WARNING,ERROR,CRITICAL} I started the help message with a lower case, "the level of log ..." in order to be consistent with the -h option: -h, --help show this help message and exit The message "show this help ..." comes from the ArgumentParser library code, and I do not know how to change it. So, I changed our code. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/gen_compile_commands.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/scripts/gen_compile_commands.py b/scripts/gen_compile_commands.py index 1bcf33a93cb9..535248cf2d7e 100755 --- a/scripts/gen_compile_commands.py +++ b/scripts/gen_compile_commands.py @@ -45,24 +45,18 @@ def parse_arguments(): 'compile_commands.json in the search directory)') parser.add_argument('-o', '--output', type=str, help=output_help) - log_level_help = ('The level of log messages to produce (one of ' + - ', '.join(_VALID_LOG_LEVELS) + '; defaults to ' + + log_level_help = ('the level of log messages to produce (defaults to ' + _DEFAULT_LOG_LEVEL + ')') - parser.add_argument( - '--log_level', type=str, default=_DEFAULT_LOG_LEVEL, - help=log_level_help) + parser.add_argument('--log_level', choices=_VALID_LOG_LEVELS, + default=_DEFAULT_LOG_LEVEL, help=log_level_help) args = parser.parse_args() - log_level = args.log_level - if log_level not in _VALID_LOG_LEVELS: - raise ValueError('%s is not a valid log level' % log_level) - directory = args.directory or os.getcwd() output = args.output or os.path.join(directory, _DEFAULT_OUTPUT) directory = os.path.abspath(directory) - return log_level, directory, output + return args.log_level, directory, output def process_line(root_directory, file_directory, command_prefix, relative_path): From 6ca4c6d25949117dc5b4845612e290b6d89e70a8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 22 Aug 2020 23:56:11 +0900 Subject: [PATCH 05/34] gen_compile_commands: do not support .cmd files under tools/ directory The tools/ directory uses a different build system, and the format of .cmd files is different because the tools builds run in a different work directory. Supporting two formats compilicates the script. The only loss by this change is objtool. Also, rename the confusing variable 'relative_path' because it is not necessarily a relative path. When the output directory is not the direct child of the source tree (e.g. O=foo/bar), it is an absolute path. Rename it to 'file_path'. os.path.join(root_directory, file_path) works whether the file_path is relative or not. If file_path is already absolute, it returns it as-is. I used os.path.abspath() to normalize file paths. If you run this script against the kernel built with O=foo option, the file_path contains '../' patterns. os.path.abspath() fixes up 'foo/bar/../baz' into 'foo/baz', and produces a cleaner commands_database.json. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/gen_compile_commands.py | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/scripts/gen_compile_commands.py b/scripts/gen_compile_commands.py index 535248cf2d7e..49fff0b0b385 100755 --- a/scripts/gen_compile_commands.py +++ b/scripts/gen_compile_commands.py @@ -59,23 +59,21 @@ def parse_arguments(): return args.log_level, directory, output -def process_line(root_directory, file_directory, command_prefix, relative_path): +def process_line(root_directory, command_prefix, file_path): """Extracts information from a .cmd line and creates an entry from it. Args: root_directory: The directory that was searched for .cmd files. Usually used directly in the "directory" entry in compile_commands.json. - file_directory: The path to the directory the .cmd file was found in. command_prefix: The extracted command line, up to the last element. - relative_path: The .c file from the end of the extracted command. - Usually relative to root_directory, but sometimes relative to - file_directory and sometimes neither. + file_path: The .c file from the end of the extracted command. + Usually relative to root_directory, but sometimes absolute. Returns: An entry to append to compile_commands. Raises: - ValueError: Could not find the extracted file based on relative_path and + ValueError: Could not find the extracted file based on file_path and root_directory or file_directory. """ # The .cmd files are intended to be included directly by Make, so they @@ -84,20 +82,14 @@ def process_line(root_directory, file_directory, command_prefix, relative_path): # by Make, so this code replaces the escaped version with '#'. prefix = command_prefix.replace('\#', '#').replace('$(pound)', '#') - cur_dir = root_directory - expected_path = os.path.join(cur_dir, relative_path) - if not os.path.exists(expected_path): - # Try using file_directory instead. Some of the tools have a different - # style of .cmd file than the kernel. - cur_dir = file_directory - expected_path = os.path.join(cur_dir, relative_path) - if not os.path.exists(expected_path): - raise ValueError('File %s not in %s or %s' % - (relative_path, root_directory, file_directory)) + # Use os.path.abspath() to normalize the path resolving '.' and '..' . + abs_path = os.path.abspath(os.path.join(root_directory, file_path)) + if not os.path.exists(abs_path): + raise ValueError('File %s not found' % abs_path) return { - 'directory': cur_dir, - 'file': relative_path, - 'command': prefix + relative_path, + 'directory': root_directory, + 'file': abs_path, + 'command': prefix + file_path, } @@ -122,7 +114,7 @@ def main(): result = line_matcher.match(f.readline()) if result: try: - entry = process_line(directory, dirpath, + entry = process_line(directory, result.group(1), result.group(2)) compile_commands.append(entry) except ValueError as err: From 0a7d376d04a3c84b503f1efecde8f9d9a7430269 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 22 Aug 2020 23:56:12 +0900 Subject: [PATCH 06/34] gen_compile_commands: reword the help message of -d option I think the help message of the -d option is somewhat misleading. Path to the kernel source directory to search (defaults to the working directory) The part "kernel source directory" is the source of the confusion. Some people misunderstand as if this script did not support separate output directories. Actually, this script also works for out-of-tree builds. You can use the -d option to point to the object output directory, not to the source directory. It should match to the O= option used in the previous kernel build, and then appears in the "directory" field of compile_commands.json. Reword the help message. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/gen_compile_commands.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/gen_compile_commands.py b/scripts/gen_compile_commands.py index 49fff0b0b385..f37c1dac8db4 100755 --- a/scripts/gen_compile_commands.py +++ b/scripts/gen_compile_commands.py @@ -31,13 +31,13 @@ def parse_arguments(): Returns: log_level: A logging level to filter log output. - directory: The directory to search for .cmd files. + directory: The work directory where the objects were built. output: Where to write the compile-commands JSON file. """ usage = 'Creates a compile_commands.json database from kernel .cmd files' parser = argparse.ArgumentParser(description=usage) - directory_help = ('Path to the kernel source directory to search ' + directory_help = ('specify the output directory used for the kernel build ' '(defaults to the working directory)') parser.add_argument('-d', '--directory', type=str, help=directory_help) From 6fca36f1d82ad5bc385187f0aed93bbaefaa2172 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 22 Aug 2020 23:56:13 +0900 Subject: [PATCH 07/34] gen_compile_commands: make -o option independent of -d option Change the -o option independent of the -d option, which is I think clearer behavior. Some people may like to use -d to specify a separate output directory, but still output the compile_commands.py in the source directory (unless the source tree is read-only) because it is the default location Clang Tools search for the compilation database. Also, move the default parameter to the default= argument of the .add_argument(). Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/gen_compile_commands.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/scripts/gen_compile_commands.py b/scripts/gen_compile_commands.py index f37c1dac8db4..71a0630ae188 100755 --- a/scripts/gen_compile_commands.py +++ b/scripts/gen_compile_commands.py @@ -39,11 +39,13 @@ def parse_arguments(): directory_help = ('specify the output directory used for the kernel build ' '(defaults to the working directory)') - parser.add_argument('-d', '--directory', type=str, help=directory_help) + parser.add_argument('-d', '--directory', type=str, default='.', + help=directory_help) - output_help = ('The location to write compile_commands.json (defaults to ' - 'compile_commands.json in the search directory)') - parser.add_argument('-o', '--output', type=str, help=output_help) + output_help = ('path to the output command database (defaults to ' + + _DEFAULT_OUTPUT + ')') + parser.add_argument('-o', '--output', type=str, default=_DEFAULT_OUTPUT, + help=output_help) log_level_help = ('the level of log messages to produce (defaults to ' + _DEFAULT_LOG_LEVEL + ')') @@ -52,11 +54,9 @@ def parse_arguments(): args = parser.parse_args() - directory = args.directory or os.getcwd() - output = args.output or os.path.join(directory, _DEFAULT_OUTPUT) - directory = os.path.abspath(directory) - - return args.log_level, directory, output + return (args.log_level, + os.path.abspath(args.directory), + args.output) def process_line(root_directory, command_prefix, file_path): From fc2cb22ec61c1a537337cd0eba458863564a0e1f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 22 Aug 2020 23:56:14 +0900 Subject: [PATCH 08/34] gen_compile_commands: move directory walk to a generator function Currently, this script walks under the specified directory (default to the current directory), then parses all .cmd files found. Split it into a separate helper function because the next commit will add more helpers to pick up .cmd files associated with given file(s). There is no point to build and return a huge list at once. I used a generator so it works in the for-loop with less memory. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/gen_compile_commands.py | 44 ++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/scripts/gen_compile_commands.py b/scripts/gen_compile_commands.py index 71a0630ae188..e45f17be8817 100755 --- a/scripts/gen_compile_commands.py +++ b/scripts/gen_compile_commands.py @@ -33,6 +33,7 @@ def parse_arguments(): log_level: A logging level to filter log output. directory: The work directory where the objects were built. output: Where to write the compile-commands JSON file. + paths: The list of directories to handle to find .cmd files. """ usage = 'Creates a compile_commands.json database from kernel .cmd files' parser = argparse.ArgumentParser(description=usage) @@ -56,7 +57,28 @@ def parse_arguments(): return (args.log_level, os.path.abspath(args.directory), - args.output) + args.output, + [args.directory]) + + +def cmdfiles_in_dir(directory): + """Generate the iterator of .cmd files found under the directory. + + Walk under the given directory, and yield every .cmd file found. + + Args: + directory: The directory to search for .cmd files. + + Yields: + The path to a .cmd file. + """ + + filename_matcher = re.compile(_FILENAME_PATTERN) + + for dirpath, _, filenames in os.walk(directory): + for filename in filenames: + if filename_matcher.match(filename): + yield os.path.join(dirpath, filename) def process_line(root_directory, command_prefix, file_path): @@ -95,31 +117,29 @@ def process_line(root_directory, command_prefix, file_path): def main(): """Walks through the directory and finds and parses .cmd files.""" - log_level, directory, output = parse_arguments() + log_level, directory, output, paths = parse_arguments() level = getattr(logging, log_level) logging.basicConfig(format='%(levelname)s: %(message)s', level=level) - filename_matcher = re.compile(_FILENAME_PATTERN) line_matcher = re.compile(_LINE_PATTERN) compile_commands = [] - for dirpath, _, filenames in os.walk(directory): - for filename in filenames: - if not filename_matcher.match(filename): - continue - filepath = os.path.join(dirpath, filename) - with open(filepath, 'rt') as f: + for path in paths: + cmdfiles = cmdfiles_in_dir(path) + + for cmdfile in cmdfiles: + with open(cmdfile, 'rt') as f: result = line_matcher.match(f.readline()) if result: try: - entry = process_line(directory, - result.group(1), result.group(2)) + entry = process_line(directory, result.group(1), + result.group(2)) compile_commands.append(entry) except ValueError as err: logging.info('Could not add line from %s: %s', - filepath, err) + cmdfile, err) with open(output, 'wt') as f: json.dump(compile_commands, f, indent=2, sort_keys=True) From ecca4fea1ede446e9ce3afa0b68b07fd1550f4f5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 22 Aug 2020 23:56:15 +0900 Subject: [PATCH 09/34] gen_compile_commands: support *.o, *.a, modules.order in positional argument This script currently searches the specified directory for .cmd files. One drawback is it may contain stale .cmd files after you rebuild the kernel several times without 'make clean'. This commit supports *.o, *.a, and modules.order as positional parameters. If such files are given, they are parsed to collect associated .cmd files. I added a generator helper for each of them. This feature is useful to get the list of active .cmd files from the last build, and will be used by the next commit to wire up the compile_commands.json rule to the Makefile. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/gen_compile_commands.py | 100 ++++++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 4 deletions(-) diff --git a/scripts/gen_compile_commands.py b/scripts/gen_compile_commands.py index e45f17be8817..92ea0a2ee59e 100755 --- a/scripts/gen_compile_commands.py +++ b/scripts/gen_compile_commands.py @@ -12,6 +12,7 @@ import json import logging import os import re +import subprocess _DEFAULT_OUTPUT = 'compile_commands.json' _DEFAULT_LOG_LEVEL = 'WARNING' @@ -32,8 +33,9 @@ def parse_arguments(): Returns: log_level: A logging level to filter log output. directory: The work directory where the objects were built. + ar: Command used for parsing .a archives. output: Where to write the compile-commands JSON file. - paths: The list of directories to handle to find .cmd files. + paths: The list of files/directories to handle to find .cmd files. """ usage = 'Creates a compile_commands.json database from kernel .cmd files' parser = argparse.ArgumentParser(description=usage) @@ -53,12 +55,21 @@ def parse_arguments(): parser.add_argument('--log_level', choices=_VALID_LOG_LEVELS, default=_DEFAULT_LOG_LEVEL, help=log_level_help) + ar_help = 'command used for parsing .a archives' + parser.add_argument('-a', '--ar', type=str, default='llvm-ar', help=ar_help) + + paths_help = ('directories to search or files to parse ' + '(files should be *.o, *.a, or modules.order). ' + 'If nothing is specified, the current directory is searched') + parser.add_argument('paths', type=str, nargs='*', help=paths_help) + args = parser.parse_args() return (args.log_level, os.path.abspath(args.directory), args.output, - [args.directory]) + args.ar, + args.paths if len(args.paths) > 0 else [args.directory]) def cmdfiles_in_dir(directory): @@ -81,6 +92,73 @@ def cmdfiles_in_dir(directory): yield os.path.join(dirpath, filename) +def to_cmdfile(path): + """Return the path of .cmd file used for the given build artifact + + Args: + Path: file path + + Returns: + The path to .cmd file + """ + dir, base = os.path.split(path) + return os.path.join(dir, '.' + base + '.cmd') + + +def cmdfiles_for_o(obj): + """Generate the iterator of .cmd files associated with the object + + Yield the .cmd file used to build the given object + + Args: + obj: The object path + + Yields: + The path to .cmd file + """ + yield to_cmdfile(obj) + + +def cmdfiles_for_a(archive, ar): + """Generate the iterator of .cmd files associated with the archive. + + Parse the given archive, and yield every .cmd file used to build it. + + Args: + archive: The archive to parse + + Yields: + The path to every .cmd file found + """ + for obj in subprocess.check_output([ar, '-t', archive]).decode().split(): + yield to_cmdfile(obj) + + +def cmdfiles_for_modorder(modorder): + """Generate the iterator of .cmd files associated with the modules.order. + + Parse the given modules.order, and yield every .cmd file used to build the + contained modules. + + Args: + modorder: The modules.order file to parse + + Yields: + The path to every .cmd file found + """ + with open(modorder) as f: + for line in f: + ko = line.rstrip() + base, ext = os.path.splitext(ko) + if ext != '.ko': + sys.exit('{}: module path must end with .ko'.format(ko)) + mod = base + '.mod' + # The first line of *.mod lists the objects that compose the module. + with open(mod) as m: + for obj in m.readline().split(): + yield to_cmdfile(obj) + + def process_line(root_directory, command_prefix, file_path): """Extracts information from a .cmd line and creates an entry from it. @@ -117,7 +195,7 @@ def process_line(root_directory, command_prefix, file_path): def main(): """Walks through the directory and finds and parses .cmd files.""" - log_level, directory, output, paths = parse_arguments() + log_level, directory, output, ar, paths = parse_arguments() level = getattr(logging, log_level) logging.basicConfig(format='%(levelname)s: %(message)s', level=level) @@ -127,7 +205,21 @@ def main(): compile_commands = [] for path in paths: - cmdfiles = cmdfiles_in_dir(path) + # If 'path' is a directory, handle all .cmd files under it. + # Otherwise, handle .cmd files associated with the file. + # Most of built-in objects are linked via archives (built-in.a or lib.a) + # but some objects are linked to vmlinux directly. + # Modules are listed in modules.order. + if os.path.isdir(path): + cmdfiles = cmdfiles_in_dir(path) + elif path.endswith('.o'): + cmdfiles = cmdfiles_for_o(path) + elif path.endswith('.a'): + cmdfiles = cmdfiles_for_a(path, ar) + elif path.endswith('modules.order'): + cmdfiles = cmdfiles_for_modorder(path) + else: + sys.exit('{}: unknown file type'.format(path)) for cmdfile in cmdfiles: with open(cmdfile, 'rt') as f: From 3d32285fa99598f1885ac7022785b9c343407e62 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 22 Aug 2020 23:56:16 +0900 Subject: [PATCH 10/34] kbuild: wire up the build rule of compile_commands.json to Makefile Currently, you need to manually run scripts/gen_compile_commands.py to create compile_commands.json. It parses all the .*.cmd files found under the specified directory. If you rebuild the kernel over again without 'make clean', .*.cmd files from older builds will create stale entries in compile_commands.json. This commit wires up the compile_commands.json rule to Makefile, and makes it parse only the .*.cmd files involved in the current build. Pass $(KBUILD_VMLINUX_OBJS), $(KBUILD_VMLINUX_LIBS), and modules.order to the script. The objects or archives linked to vmlinux are listed in $(KBUILD_VMLINUX_OBJS) or $(KBUILD_VMLINUX_LIBS). All the modules are listed in modules.order. You can create compile_commands.json from Make: $ make -j$(nproc) CC=clang compile_commands.json You can also build vmlinux, modules, and compile_commands.json all together in a single command: $ make -j$(nproc) CC=clang all compile_commands.json It works for M= builds as well. In this case, compile_commands.json is created in the top directory of the external module. This is convenient, but it has a drawback; the coverage of the compile_commands.json is reduced because only the objects linked to vmlinux or modules are handled. For example, the following C files are not included in the compile_commands.json: - Decompressor source files (arch/*/boot/) - VDSO source files - C files used to generate intermediates (e.g. kernel/bounds.c) - Standalone host programs I think it is fine for most developers because our main interest is the kernel-space code. If you want to cover all the compiled C files, please build the kernel, then run the script manually as you did before: $ make clean # if you want to remove stale .cmd files [optional] $ make -j$(nproc) CC=clang $ scripts/gen_compile_commands.py Here is a note for out-of-tree builds. 'make compile_commands.json' works with O= option, but please notice compile_commands.json is created in the object tree instead of the source tree. Some people may want to have compile_commands.json in the source tree because Clang Tools searches for it through all parent paths of the first input source file. However, you cannot do this for O= builds. Kbuild should never generate any build artifact in the source tree when O= is given because the source tree might be read-only. Any write attempt to the source tree is monitored and the violation may be reported. See the commit log of 8ef14c2c41d9. So, the only possible way is to create compile_commands.json in the object tree, then specify '-p ' when you use clang-check, clang-tidy, etc. Signed-off-by: Masahiro Yamada Acked-by: Nick Desaulniers --- Makefile | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index d96f2feddbfb..07fd96a25a20 100644 --- a/Makefile +++ b/Makefile @@ -634,7 +634,7 @@ endif # in addition to whatever we do anyway. # Just "make" or "make all" shall build modules as well -ifneq ($(filter all modules nsdeps,$(MAKECMDGOALS)),) +ifneq ($(filter all modules nsdeps %compile_commands.json,$(MAKECMDGOALS)),) KBUILD_MODULES := 1 endif @@ -1470,7 +1470,8 @@ endif # CONFIG_MODULES # Directories & files removed with 'make clean' CLEAN_FILES += include/ksym vmlinux.symvers \ - modules.builtin modules.builtin.modinfo modules.nsdeps + modules.builtin modules.builtin.modinfo modules.nsdeps \ + compile_commands.json # Directories & files removed with 'make mrproper' MRPROPER_FILES += include/config include/generated \ @@ -1704,9 +1705,12 @@ KBUILD_MODULES := 1 build-dirs := $(KBUILD_EXTMOD) PHONY += modules -modules: descend +modules: $(MODORDER) $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost +$(MODORDER): descend + @: + PHONY += modules_install modules_install: _emodinst_ _emodinst_post @@ -1720,8 +1724,12 @@ PHONY += _emodinst_post _emodinst_post: _emodinst_ $(call cmd,depmod) +compile_commands.json: $(extmod-prefix)compile_commands.json +PHONY += compile_commands.json + clean-dirs := $(KBUILD_EXTMOD) -clean: rm-files := $(KBUILD_EXTMOD)/Module.symvers $(KBUILD_EXTMOD)/modules.nsdeps +clean: rm-files := $(KBUILD_EXTMOD)/Module.symvers $(KBUILD_EXTMOD)/modules.nsdeps \ + $(KBUILD_EXTMOD)/compile_commands.json PHONY += help help: @@ -1834,6 +1842,19 @@ nsdeps: export KBUILD_NSDEPS=1 nsdeps: modules $(Q)$(CONFIG_SHELL) $(srctree)/scripts/nsdeps +# Clang Tooling +# --------------------------------------------------------------------------- + +quiet_cmd_gen_compile_commands = GEN $@ + cmd_gen_compile_commands = $(PYTHON3) $< -a $(AR) -o $@ $(filter-out $<, $(real-prereqs)) + +$(extmod-prefix)compile_commands.json: scripts/gen_compile_commands.py \ + $(if $(KBUILD_EXTMOD),,$(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS)) \ + $(if $(CONFIG_MODULES), $(MODORDER)) FORCE + $(call if_changed,gen_compile_commands) + +targets += $(extmod-prefix)compile_commands.json + # Scripts to check various things for consistency # --------------------------------------------------------------------------- From 8b61f748e2a022f9028c612e44b68ad61caec474 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 22 Aug 2020 23:56:17 +0900 Subject: [PATCH 11/34] gen_compile_commands: remove the warning about too few .cmd files This warning was useful when users previously needed to manually build the kernel and run this script. Now you can simply do 'make compile_commands.json', which updates all the necessary build artifacts and automatically creates the compilation database. There is no more worry for a mistake like "Oh, I forgot to build the kernel". Now, this warning is rather annoying. You can create compile_commands.json for an external module: $ make M=/path/to/your/external/module compile_commands.json Then, this warning is displayed since there are usually less than 300 files in a single module. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/gen_compile_commands.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/scripts/gen_compile_commands.py b/scripts/gen_compile_commands.py index 92ea0a2ee59e..19963708bcf8 100755 --- a/scripts/gen_compile_commands.py +++ b/scripts/gen_compile_commands.py @@ -21,11 +21,6 @@ _FILENAME_PATTERN = r'^\..*\.cmd$' _LINE_PATTERN = r'^cmd_[^ ]*\.o := (.* )([^ ]*\.c)$' _VALID_LOG_LEVELS = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'] -# A kernel build generally has over 2000 entries in its compile_commands.json -# database. If this code finds 300 or fewer, then warn the user that they might -# not have all the .cmd files, and they might need to compile the kernel. -_LOW_COUNT_THRESHOLD = 300 - def parse_arguments(): """Sets up and parses command-line arguments. @@ -236,11 +231,6 @@ def main(): with open(output, 'wt') as f: json.dump(compile_commands, f, indent=2, sort_keys=True) - count = len(compile_commands) - if count < _LOW_COUNT_THRESHOLD: - logging.warning( - 'Found %s entries. Have you compiled the kernel?', count) - if __name__ == '__main__': main() From 6ad7cbc01527223f3f92baac9b122f15651cf76b Mon Sep 17 00:00:00 2001 From: Nathan Huckleberry Date: Sat, 22 Aug 2020 23:56:18 +0900 Subject: [PATCH 12/34] Makefile: Add clang-tidy and static analyzer support to makefile This patch adds clang-tidy and the clang static-analyzer as make targets. The goal of this patch is to make static analysis tools usable and extendable by any developer or researcher who is familiar with basic c++. The current static analysis tools require intimate knowledge of the internal workings of the static analysis. Clang-tidy and the clang static analyzers expose an easy to use api and allow users unfamiliar with clang to write new checks with relative ease. ===Clang-tidy=== Clang-tidy is an easily extendable 'linter' that runs on the AST. Clang-tidy checks are easy to write and understand. A check consists of two parts, a matcher and a checker. The matcher is created using a domain specific language that acts on the AST (https://clang.llvm.org/docs/LibASTMatchersReference.html). When AST nodes are found by the matcher a callback is made to the checker. The checker can then execute additional checks and issue warnings. Here is an example clang-tidy check to report functions that have calls to local_irq_disable without calls to local_irq_enable and vice-versa. Functions flagged with __attribute((annotation("ignore_irq_balancing"))) are ignored for analysis. (https://reviews.llvm.org/D65828) ===Clang static analyzer=== The clang static analyzer is a more powerful static analysis tool that uses symbolic execution to find bugs. Currently there is a check that looks for potential security bugs from invalid uses of kmalloc and kfree. There are several more general purpose checks that are useful for the kernel. The clang static analyzer is well documented and designed to be extensible. (https://clang-analyzer.llvm.org/checker_dev_manual.html) (https://github.com/haoNoQ/clang-analyzer-guide/releases/download/v0.1/clang-analyzer-guide-v0.1.pdf) The main draw of the clang tools is how accessible they are. The clang documentation is very nice and these tools are built specifically to be easily extendable by any developer. They provide an accessible method of bug-finding and research to people who are not overly familiar with the kernel codebase. Signed-off-by: Nathan Huckleberry Reviewed-by: Nick Desaulniers Tested-by: Nick Desaulniers Tested-by: Lukas Bulwahn Signed-off-by: Masahiro Yamada --- MAINTAINERS | 1 + Makefile | 20 ++++- .../{ => clang-tools}/gen_compile_commands.py | 0 scripts/clang-tools/run-clang-tools.py | 74 +++++++++++++++++++ 4 files changed, 93 insertions(+), 2 deletions(-) rename scripts/{ => clang-tools}/gen_compile_commands.py (100%) create mode 100755 scripts/clang-tools/run-clang-tools.py diff --git a/MAINTAINERS b/MAINTAINERS index f0068bceeb61..05bebba204cf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4247,6 +4247,7 @@ W: https://clangbuiltlinux.github.io/ B: https://github.com/ClangBuiltLinux/linux/issues C: irc://chat.freenode.net/clangbuiltlinux F: Documentation/kbuild/llvm.rst +F: scripts/clang-tools/ K: \b(?i:clang|llvm)\b CLEANCACHE API diff --git a/Makefile b/Makefile index 07fd96a25a20..37739ee53f27 100644 --- a/Makefile +++ b/Makefile @@ -634,7 +634,7 @@ endif # in addition to whatever we do anyway. # Just "make" or "make all" shall build modules as well -ifneq ($(filter all modules nsdeps %compile_commands.json,$(MAKECMDGOALS)),) +ifneq ($(filter all modules nsdeps %compile_commands.json clang-%,$(MAKECMDGOALS)),) KBUILD_MODULES := 1 endif @@ -1583,6 +1583,8 @@ help: @echo ' export_report - List the usages of all exported symbols' @echo ' headerdep - Detect inclusion cycles in headers' @echo ' coccicheck - Check with Coccinelle' + @echo ' clang-analyzer - Check with clang static analyzer' + @echo ' clang-tidy - Check with clang-tidy' @echo '' @echo 'Tools:' @echo ' nsdeps - Generate missing symbol namespace dependencies' @@ -1848,13 +1850,27 @@ nsdeps: modules quiet_cmd_gen_compile_commands = GEN $@ cmd_gen_compile_commands = $(PYTHON3) $< -a $(AR) -o $@ $(filter-out $<, $(real-prereqs)) -$(extmod-prefix)compile_commands.json: scripts/gen_compile_commands.py \ +$(extmod-prefix)compile_commands.json: scripts/clang-tools/gen_compile_commands.py \ $(if $(KBUILD_EXTMOD),,$(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS)) \ $(if $(CONFIG_MODULES), $(MODORDER)) FORCE $(call if_changed,gen_compile_commands) targets += $(extmod-prefix)compile_commands.json +PHONY += clang-tidy clang-analyzer + +ifdef CONFIG_CC_IS_CLANG +quiet_cmd_clang_tools = CHECK $< + cmd_clang_tools = $(PYTHON3) $(srctree)/scripts/clang-tools/run-clang-tools.py $@ $< + +clang-tidy clang-analyzer: $(extmod-prefix)compile_commands.json + $(call cmd,clang_tools) +else +clang-tidy clang-analyzer: + @echo "$@ requires CC=clang" >&2 + @false +endif + # Scripts to check various things for consistency # --------------------------------------------------------------------------- diff --git a/scripts/gen_compile_commands.py b/scripts/clang-tools/gen_compile_commands.py similarity index 100% rename from scripts/gen_compile_commands.py rename to scripts/clang-tools/gen_compile_commands.py diff --git a/scripts/clang-tools/run-clang-tools.py b/scripts/clang-tools/run-clang-tools.py new file mode 100755 index 000000000000..fa7655c7cec0 --- /dev/null +++ b/scripts/clang-tools/run-clang-tools.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) Google LLC, 2020 +# +# Author: Nathan Huckleberry +# +"""A helper routine run clang-tidy and the clang static-analyzer on +compile_commands.json. +""" + +import argparse +import json +import multiprocessing +import os +import subprocess +import sys + + +def parse_arguments(): + """Set up and parses command-line arguments. + Returns: + args: Dict of parsed args + Has keys: [path, type] + """ + usage = """Run clang-tidy or the clang static-analyzer on a + compilation database.""" + parser = argparse.ArgumentParser(description=usage) + + type_help = "Type of analysis to be performed" + parser.add_argument("type", + choices=["clang-tidy", "clang-analyzer"], + help=type_help) + path_help = "Path to the compilation database to parse" + parser.add_argument("path", type=str, help=path_help) + + return parser.parse_args() + + +def init(l, a): + global lock + global args + lock = l + args = a + + +def run_analysis(entry): + # Disable all checks, then re-enable the ones we want + checks = "-checks=-*," + if args.type == "clang-tidy": + checks += "linuxkernel-*" + else: + checks += "clang-analyzer-*" + p = subprocess.run(["clang-tidy", "-p", args.path, checks, entry["file"]], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + cwd=entry["directory"]) + with lock: + sys.stderr.buffer.write(p.stdout) + + +def main(): + args = parse_arguments() + + lock = multiprocessing.Lock() + pool = multiprocessing.Pool(initializer=init, initargs=(lock, args)) + # Read JSON data into the datastore variable + with open(args.path, "r") as f: + datastore = json.load(f) + pool.map(run_analysis, datastore) + + +if __name__ == "__main__": + main() From 887af6d7c99e963c6f92af8e985f9aa6f4f9eac2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 1 Sep 2020 03:22:39 +0900 Subject: [PATCH 13/34] arch: vdso: add vdso linker script to 'targets' instead of extra-y The vdso linker script is preprocessed on demand. Adding it to 'targets' is enough to include the .cmd file. Signed-off-by: Masahiro Yamada Acked-by: Catalin Marinas Acked-by: Greentime Hu --- arch/arm64/kernel/vdso/Makefile | 2 +- arch/arm64/kernel/vdso32/Makefile | 2 +- arch/nds32/kernel/vdso/Makefile | 2 +- arch/powerpc/kernel/vdso32/Makefile | 2 +- arch/powerpc/kernel/vdso64/Makefile | 2 +- arch/s390/kernel/vdso64/Makefile | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile index 45d5cfe46429..7cd8aafbe96e 100644 --- a/arch/arm64/kernel/vdso/Makefile +++ b/arch/arm64/kernel/vdso/Makefile @@ -54,7 +54,7 @@ endif GCOV_PROFILE := n obj-y += vdso.o -extra-y += vdso.lds +targets += vdso.lds CPPFLAGS_vdso.lds += -P -C -U$(ARCH) # Force dependency (incbin is bad) diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile index d6adb4677c25..572475b7b7ed 100644 --- a/arch/arm64/kernel/vdso32/Makefile +++ b/arch/arm64/kernel/vdso32/Makefile @@ -155,7 +155,7 @@ asm-obj-vdso := $(addprefix $(obj)/, $(asm-obj-vdso)) obj-vdso := $(c-obj-vdso) $(c-obj-vdso-gettimeofday) $(asm-obj-vdso) obj-y += vdso.o -extra-y += vdso.lds +targets += vdso.lds CPPFLAGS_vdso.lds += -P -C -U$(ARCH) # Force dependency (vdso.s includes vdso.so through incbin) diff --git a/arch/nds32/kernel/vdso/Makefile b/arch/nds32/kernel/vdso/Makefile index 7c3c1ccb196e..55df25ef0057 100644 --- a/arch/nds32/kernel/vdso/Makefile +++ b/arch/nds32/kernel/vdso/Makefile @@ -20,7 +20,7 @@ GCOV_PROFILE := n obj-y += vdso.o -extra-y += vdso.lds +targets += vdso.lds CPPFLAGS_vdso.lds += -P -C -U$(ARCH) # Force dependency diff --git a/arch/powerpc/kernel/vdso32/Makefile b/arch/powerpc/kernel/vdso32/Makefile index 87ab1152d5ce..fd5072a4c73c 100644 --- a/arch/powerpc/kernel/vdso32/Makefile +++ b/arch/powerpc/kernel/vdso32/Makefile @@ -29,7 +29,7 @@ ccflags-y := -shared -fno-common -fno-builtin -nostdlib \ asflags-y := -D__VDSO32__ -s obj-y += vdso32_wrapper.o -extra-y += vdso32.lds +targets += vdso32.lds CPPFLAGS_vdso32.lds += -P -C -Upowerpc # Force dependency (incbin is bad) diff --git a/arch/powerpc/kernel/vdso64/Makefile b/arch/powerpc/kernel/vdso64/Makefile index 38c317f25141..c737b3ea3207 100644 --- a/arch/powerpc/kernel/vdso64/Makefile +++ b/arch/powerpc/kernel/vdso64/Makefile @@ -17,7 +17,7 @@ ccflags-y := -shared -fno-common -fno-builtin -nostdlib \ asflags-y := -D__VDSO64__ -s obj-y += vdso64_wrapper.o -extra-y += vdso64.lds +targets += vdso64.lds CPPFLAGS_vdso64.lds += -P -C -U$(ARCH) # Force dependency (incbin is bad) diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile index 4a66a1cb919b..d0d406cfffa9 100644 --- a/arch/s390/kernel/vdso64/Makefile +++ b/arch/s390/kernel/vdso64/Makefile @@ -25,7 +25,7 @@ $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_64) $(targets:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_64) obj-y += vdso64_wrapper.o -extra-y += vdso64.lds +targets += vdso64.lds CPPFLAGS_vdso64.lds += -P -C -U$(ARCH) # Disable gcov profiling, ubsan and kasan for VDSO code From 596b0474d3d9b1242eab713f84d8873f9887d980 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 8 Sep 2020 13:27:08 +0900 Subject: [PATCH 14/34] kbuild: preprocess module linker script There was a request to preprocess the module linker script like we do for the vmlinux one. (https://lkml.org/lkml/2020/8/21/512) The difference between vmlinux.lds and module.lds is that the latter is needed for external module builds, thus must be cleaned up by 'make mrproper' instead of 'make clean'. Also, it must be created by 'make modules_prepare'. You cannot put it in arch/$(SRCARCH)/kernel/, which is cleaned up by 'make clean'. I moved arch/$(SRCARCH)/kernel/module.lds to arch/$(SRCARCH)/include/asm/module.lds.h, which is included from scripts/module.lds.S. scripts/module.lds is fine because 'make clean' keeps all the build artifacts under scripts/. You can add arch-specific sections in . Signed-off-by: Masahiro Yamada Tested-by: Jessica Yu Acked-by: Will Deacon Acked-by: Geert Uytterhoeven Acked-by: Palmer Dabbelt Reviewed-by: Kees Cook Acked-by: Jessica Yu --- Makefile | 10 ++++++---- arch/arm/Makefile | 4 ---- .../{kernel/module.lds => include/asm/module.lds.h} | 2 ++ arch/arm64/Makefile | 4 ---- .../{kernel/module.lds => include/asm/module.lds.h} | 2 ++ arch/ia64/Makefile | 1 - arch/ia64/{module.lds => include/asm/module.lds.h} | 0 arch/m68k/Makefile | 1 - .../{kernel/module.lds => include/asm/module.lds.h} | 0 arch/powerpc/Makefile | 1 - .../{kernel/module.lds => include/asm/module.lds.h} | 0 arch/riscv/Makefile | 3 --- .../{kernel/module.lds => include/asm/module.lds.h} | 3 ++- arch/um/include/asm/Kbuild | 1 + include/asm-generic/Kbuild | 1 + include/asm-generic/module.lds.h | 10 ++++++++++ scripts/.gitignore | 1 + scripts/Makefile | 3 +++ scripts/Makefile.modfinal | 5 ++--- scripts/{module-common.lds => module.lds.S} | 3 +++ scripts/package/builddeb | 2 +- 21 files changed, 34 insertions(+), 23 deletions(-) rename arch/arm/{kernel/module.lds => include/asm/module.lds.h} (72%) rename arch/arm64/{kernel/module.lds => include/asm/module.lds.h} (76%) rename arch/ia64/{module.lds => include/asm/module.lds.h} (100%) rename arch/m68k/{kernel/module.lds => include/asm/module.lds.h} (100%) rename arch/powerpc/{kernel/module.lds => include/asm/module.lds.h} (100%) rename arch/riscv/{kernel/module.lds => include/asm/module.lds.h} (84%) create mode 100644 include/asm-generic/module.lds.h rename scripts/{module-common.lds => module.lds.S} (93%) diff --git a/Makefile b/Makefile index 37739ee53f27..97b1dae1783b 100644 --- a/Makefile +++ b/Makefile @@ -505,7 +505,6 @@ KBUILD_CFLAGS_KERNEL := KBUILD_AFLAGS_MODULE := -DMODULE KBUILD_CFLAGS_MODULE := -DMODULE KBUILD_LDFLAGS_MODULE := -export KBUILD_LDS_MODULE := $(srctree)/scripts/module-common.lds KBUILD_LDFLAGS := CLANG_FLAGS := @@ -1395,7 +1394,7 @@ endif # using awk while concatenating to the final file. PHONY += modules -modules: $(if $(KBUILD_BUILTIN),vmlinux) modules_check +modules: $(if $(KBUILD_BUILTIN),vmlinux) modules_check modules_prepare $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost PHONY += modules_check @@ -1412,6 +1411,7 @@ targets += modules.order # Target to prepare building external modules PHONY += modules_prepare modules_prepare: prepare + $(Q)$(MAKE) $(build)=scripts scripts/module.lds # Target to install modules PHONY += modules_install @@ -1743,7 +1743,9 @@ help: @echo ' clean - remove generated files in module directory only' @echo '' -PHONY += prepare +# no-op for external module builds +PHONY += prepare modules_prepare + endif # KBUILD_EXTMOD # Single targets @@ -1776,7 +1778,7 @@ MODORDER := .modules.tmp endif PHONY += single_modpost -single_modpost: $(single-no-ko) +single_modpost: $(single-no-ko) modules_prepare $(Q){ $(foreach m, $(single-ko), echo $(extmod-prefix)$m;) } > $(MODORDER) $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 4e877354515f..a0cb15de9677 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -16,10 +16,6 @@ LDFLAGS_vmlinux += --be8 KBUILD_LDFLAGS_MODULE += --be8 endif -ifeq ($(CONFIG_ARM_MODULE_PLTS),y) -KBUILD_LDS_MODULE += $(srctree)/arch/arm/kernel/module.lds -endif - GZFLAGS :=-9 #KBUILD_CFLAGS +=-pipe diff --git a/arch/arm/kernel/module.lds b/arch/arm/include/asm/module.lds.h similarity index 72% rename from arch/arm/kernel/module.lds rename to arch/arm/include/asm/module.lds.h index 79cb6af565e5..0e7cb4e314b4 100644 --- a/arch/arm/kernel/module.lds +++ b/arch/arm/include/asm/module.lds.h @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ +#ifdef CONFIG_ARM_MODULE_PLTS SECTIONS { .plt : { BYTE(0) } .init.plt : { BYTE(0) } } +#endif diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index b45f0124cc16..76667ad47980 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -115,10 +115,6 @@ endif CHECKFLAGS += -D__aarch64__ -ifeq ($(CONFIG_ARM64_MODULE_PLTS),y) -KBUILD_LDS_MODULE += $(srctree)/arch/arm64/kernel/module.lds -endif - ifeq ($(CONFIG_DYNAMIC_FTRACE_WITH_REGS),y) KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY CC_FLAGS_FTRACE := -fpatchable-function-entry=2 diff --git a/arch/arm64/kernel/module.lds b/arch/arm64/include/asm/module.lds.h similarity index 76% rename from arch/arm64/kernel/module.lds rename to arch/arm64/include/asm/module.lds.h index 22e36a21c113..691f15af788e 100644 --- a/arch/arm64/kernel/module.lds +++ b/arch/arm64/include/asm/module.lds.h @@ -1,5 +1,7 @@ +#ifdef CONFIG_ARM64_MODULE_PLTS SECTIONS { .plt (NOLOAD) : { BYTE(0) } .init.plt (NOLOAD) : { BYTE(0) } .text.ftrace_trampoline (NOLOAD) : { BYTE(0) } } +#endif diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index 2876a7df1b0a..703b1c4f6d12 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -20,7 +20,6 @@ CHECKFLAGS += -D__ia64=1 -D__ia64__=1 -D_LP64 -D__LP64__ OBJCOPYFLAGS := --strip-all LDFLAGS_vmlinux := -static -KBUILD_LDS_MODULE += $(srctree)/arch/ia64/module.lds KBUILD_AFLAGS_KERNEL := -mconstant-gp EXTRA := diff --git a/arch/ia64/module.lds b/arch/ia64/include/asm/module.lds.h similarity index 100% rename from arch/ia64/module.lds rename to arch/ia64/include/asm/module.lds.h diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile index 4438ffb4bbe1..ea14f2046fb4 100644 --- a/arch/m68k/Makefile +++ b/arch/m68k/Makefile @@ -75,7 +75,6 @@ KBUILD_CPPFLAGS += -D__uClinux__ endif KBUILD_LDFLAGS := -m m68kelf -KBUILD_LDS_MODULE += $(srctree)/arch/m68k/kernel/module.lds ifdef CONFIG_SUN3 LDFLAGS_vmlinux = -N diff --git a/arch/m68k/kernel/module.lds b/arch/m68k/include/asm/module.lds.h similarity index 100% rename from arch/m68k/kernel/module.lds rename to arch/m68k/include/asm/module.lds.h diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 3e8da9cf2eb9..8935658fcd06 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -65,7 +65,6 @@ UTS_MACHINE := $(subst $(space),,$(machine-y)) ifdef CONFIG_PPC32 KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o else -KBUILD_LDS_MODULE += $(srctree)/arch/powerpc/kernel/module.lds ifeq ($(call ld-ifversion, -ge, 225000000, y),y) # Have the linker provide sfpr if possible. # There is a corresponding test in arch/powerpc/lib/Makefile diff --git a/arch/powerpc/kernel/module.lds b/arch/powerpc/include/asm/module.lds.h similarity index 100% rename from arch/powerpc/kernel/module.lds rename to arch/powerpc/include/asm/module.lds.h diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index fb6e37db836d..8edaa8bd86d6 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -53,9 +53,6 @@ endif ifeq ($(CONFIG_CMODEL_MEDANY),y) KBUILD_CFLAGS += -mcmodel=medany endif -ifeq ($(CONFIG_MODULE_SECTIONS),y) - KBUILD_LDS_MODULE += $(srctree)/arch/riscv/kernel/module.lds -endif ifeq ($(CONFIG_PERF_EVENTS),y) KBUILD_CFLAGS += -fno-omit-frame-pointer endif diff --git a/arch/riscv/kernel/module.lds b/arch/riscv/include/asm/module.lds.h similarity index 84% rename from arch/riscv/kernel/module.lds rename to arch/riscv/include/asm/module.lds.h index 295ecfb341a2..4254ff2ff049 100644 --- a/arch/riscv/kernel/module.lds +++ b/arch/riscv/include/asm/module.lds.h @@ -1,8 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2017 Andes Technology Corporation */ - +#ifdef CONFIG_MODULE_SECTIONS SECTIONS { .plt (NOLOAD) : { BYTE(0) } .got (NOLOAD) : { BYTE(0) } .got.plt (NOLOAD) : { BYTE(0) } } +#endif diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild index 8d435f8a6dec..1c63b260ecc4 100644 --- a/arch/um/include/asm/Kbuild +++ b/arch/um/include/asm/Kbuild @@ -16,6 +16,7 @@ generic-y += kdebug.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h generic-y += mmiowb.h +generic-y += module.lds.h generic-y += param.h generic-y += pci.h generic-y += percpu.h diff --git a/include/asm-generic/Kbuild b/include/asm-generic/Kbuild index 74b0612601dd..7cd4e627e00e 100644 --- a/include/asm-generic/Kbuild +++ b/include/asm-generic/Kbuild @@ -40,6 +40,7 @@ mandatory-y += mmiowb.h mandatory-y += mmu.h mandatory-y += mmu_context.h mandatory-y += module.h +mandatory-y += module.lds.h mandatory-y += msi.h mandatory-y += pci.h mandatory-y += percpu.h diff --git a/include/asm-generic/module.lds.h b/include/asm-generic/module.lds.h new file mode 100644 index 000000000000..f210d5c1b78b --- /dev/null +++ b/include/asm-generic/module.lds.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __ASM_GENERIC_MODULE_LDS_H +#define __ASM_GENERIC_MODULE_LDS_H + +/* + * can specify arch-specific sections for linking modules. + * Empty for the asm-generic header. + */ + +#endif /* __ASM_GENERIC_MODULE_LDS_H */ diff --git a/scripts/.gitignore b/scripts/.gitignore index 0d1c8e217cd7..a6c11316c969 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore @@ -8,3 +8,4 @@ asn1_compiler extract-cert sign-file insert-sys-cert +/module.lds diff --git a/scripts/Makefile b/scripts/Makefile index bc018e4b733e..b5418ec587fb 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -29,6 +29,9 @@ endif # The following programs are only built on demand hostprogs += unifdef +# The module linker script is preprocessed on demand +targets += module.lds + subdir-$(CONFIG_GCC_PLUGINS) += gcc-plugins subdir-$(CONFIG_MODVERSIONS) += genksyms subdir-$(CONFIG_SECURITY_SELINUX) += selinux diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 411c1e600e7d..ae01baf96f4e 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -33,11 +33,10 @@ quiet_cmd_ld_ko_o = LD [M] $@ cmd_ld_ko_o = \ $(LD) -r $(KBUILD_LDFLAGS) \ $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ - $(addprefix -T , $(KBUILD_LDS_MODULE)) \ - -o $@ $(filter %.o, $^); \ + -T scripts/module.lds -o $@ $(filter %.o, $^); \ $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) -$(modules): %.ko: %.o %.mod.o $(KBUILD_LDS_MODULE) FORCE +$(modules): %.ko: %.o %.mod.o scripts/module.lds FORCE +$(call if_changed,ld_ko_o) targets += $(modules) $(modules:.ko=.mod.o) diff --git a/scripts/module-common.lds b/scripts/module.lds.S similarity index 93% rename from scripts/module-common.lds rename to scripts/module.lds.S index d61b9e8678e8..69b9b71a6a47 100644 --- a/scripts/module-common.lds +++ b/scripts/module.lds.S @@ -24,3 +24,6 @@ SECTIONS { __jump_table 0 : ALIGN(8) { KEEP(*(__jump_table)) } } + +/* bring in arch-specific sections */ +#include diff --git a/scripts/package/builddeb b/scripts/package/builddeb index 6df3c9f8b2da..44f212e37935 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -55,7 +55,7 @@ deploy_kernel_headers () { cd $srctree find . arch/$SRCARCH -maxdepth 1 -name Makefile\* find include scripts -type f -o -type l - find arch/$SRCARCH -name module.lds -o -name Kbuild.platforms -o -name Platform + find arch/$SRCARCH -name Kbuild.platforms -o -name Platform find $(find arch/$SRCARCH -name include -o -name scripts -type d) -type f ) > debian/hdrsrcfiles From 6212804f2d78e86f15dba5b46a4065cbf1403cde Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 9 Sep 2020 05:55:57 +0900 Subject: [PATCH 15/34] kbuild: do not create built-in objects for external module builds 'make M=/path/to/your/external/module' creates a pointless built-in.a in the top of the external module directory because KBUILD_BUILTIN is set to 1. Clear KBUILD_BUILTIN when we are building external modules so that 'make M=...' and 'make M=... modules' work equivalently. Signed-off-by: Masahiro Yamada --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 97b1dae1783b..744b6c664404 100644 --- a/Makefile +++ b/Makefile @@ -1702,7 +1702,8 @@ else # KBUILD_EXTMOD # Install the modules built in the module directory # Assumes install directory is already created -# We are always building modules +# We are always building only modules. +KBUILD_BUILTIN := KBUILD_MODULES := 1 build-dirs := $(KBUILD_EXTMOD) From 9909b7681222299dcb6f3b0613c30a65498b6c72 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 10 Sep 2020 22:44:28 +0900 Subject: [PATCH 16/34] kbuild: remove redundant CONFIG_KASAN check from scripts/Makefile.kasan Since commit e0fe0bbe57b8 ("kbuild: include scripts/Makefile.* only when relevant CONFIG is enabled"), this file is included only when CONFIG_KASAN=y. This ifdef is redundant. Signed-off-by: Masahiro Yamada Acked-by: Marco Elver --- scripts/Makefile.kasan | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan index f4beee1b0013..1532f1a41a8f 100644 --- a/scripts/Makefile.kasan +++ b/scripts/Makefile.kasan @@ -1,8 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 -ifdef CONFIG_KASAN CFLAGS_KASAN_NOSANITIZE := -fno-builtin KASAN_SHADOW_OFFSET ?= $(CONFIG_KASAN_SHADOW_OFFSET) -endif ifdef CONFIG_KASAN_GENERIC From bb2732112bc52bed7b20b9fc59d7246e4e7ce5ed Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 10 Sep 2020 22:44:29 +0900 Subject: [PATCH 17/34] kbuild: move CFLAGS_{KASAN,UBSAN,KCSAN} exports to relevant Makefiles Move CFLAGS_KASAN*, CFLAGS_UBSAN, CFLAGS_KCSAN to Makefile.kasan, Makefile.ubsan, Makefile.kcsan, respectively. This commit also avoids the same -fsanitize=* flags being added to CFLAGS_UBSAN multiple times. Prior to this commit, the ubsan flags were appended by the '+=' operator, without any initialization. Some build targets such as 'make bindeb-pkg' recurses to the top Makefile, and ended up with adding the same flags to CFLAGS_UBSAN twice. Clear CFLAGS_UBSAN with ':=' to make it a simply expanded variable. This is better than a recursively expanded variable, which evaluates $(call cc-option, ...) multiple times before Kbuild starts descending to subdirectories. Signed-off-by: Masahiro Yamada Acked-by: Marco Elver --- Makefile | 1 - scripts/Makefile.kasan | 2 ++ scripts/Makefile.kcsan | 2 +- scripts/Makefile.ubsan | 3 +++ 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 744b6c664404..06890bb0e011 100644 --- a/Makefile +++ b/Makefile @@ -516,7 +516,6 @@ export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE -export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE CFLAGS_UBSAN CFLAGS_KCSAN export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan index 1532f1a41a8f..1e000cc2e7b4 100644 --- a/scripts/Makefile.kasan +++ b/scripts/Makefile.kasan @@ -47,3 +47,5 @@ CFLAGS_KASAN := -fsanitize=kernel-hwaddress \ $(instrumentation_flags) endif # CONFIG_KASAN_SW_TAGS + +export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE diff --git a/scripts/Makefile.kcsan b/scripts/Makefile.kcsan index c50f27b3ac56..cec50d74e0d0 100644 --- a/scripts/Makefile.kcsan +++ b/scripts/Makefile.kcsan @@ -9,7 +9,7 @@ endif # Keep most options here optional, to allow enabling more compilers if absence # of some options does not break KCSAN nor causes false positive reports. -CFLAGS_KCSAN := -fsanitize=thread \ +export CFLAGS_KCSAN := -fsanitize=thread \ $(call cc-option,$(call cc-param,tsan-instrument-func-entry-exit=0) -fno-optimize-sibling-calls) \ $(call cc-option,$(call cc-param,tsan-instrument-read-before-write=1)) \ $(call cc-param,tsan-distinguish-volatile=1) diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan index 27348029b2b8..c661484ee01f 100644 --- a/scripts/Makefile.ubsan +++ b/scripts/Makefile.ubsan @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 + +export CFLAGS_UBSAN := + ifdef CONFIG_UBSAN_ALIGNMENT CFLAGS_UBSAN += $(call cc-option, -fsanitize=alignment) endif From 8b42cf2fde0ee8b63d71d4bc442a03b6ea55b00b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 10 Sep 2020 22:51:17 +0900 Subject: [PATCH 18/34] kbuild: remove cc-option test of -fno-strict-overflow The minimal compiler versions, GCC 4.9 and Clang 10 support this flag. Here is the godbolt: https://godbolt.org/z/odq8h9 Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor Acked-by: Will Deacon --- Makefile | 2 +- arch/arm64/kernel/vdso32/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 06890bb0e011..7036dcb99cdf 100644 --- a/Makefile +++ b/Makefile @@ -928,7 +928,7 @@ KBUILD_CFLAGS += $(call cc-disable-warning, restrict) KBUILD_CFLAGS += $(call cc-disable-warning, maybe-uninitialized) # disable invalid "can't wrap" optimizations for signed / pointers -KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow) +KBUILD_CFLAGS += -fno-strict-overflow # clang sets -fmerge-all-constants by default as optimization, but this # is non-conforming behavior for C and in fact breaks the kernel, so we diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile index 572475b7b7ed..3d99a9a249e3 100644 --- a/arch/arm64/kernel/vdso32/Makefile +++ b/arch/arm64/kernel/vdso32/Makefile @@ -90,7 +90,7 @@ VDSO_CFLAGS += -O2 # Some useful compiler-dependent flags from top-level Makefile VDSO_CFLAGS += $(call cc32-option,-Wdeclaration-after-statement,) VDSO_CFLAGS += $(call cc32-option,-Wno-pointer-sign) -VDSO_CFLAGS += $(call cc32-option,-fno-strict-overflow) +VDSO_CFLAGS += -fno-strict-overflow VDSO_CFLAGS += $(call cc32-option,-Werror=strict-prototypes) VDSO_CFLAGS += $(call cc32-option,-Werror=date-time) VDSO_CFLAGS += $(call cc32-option,-Werror=incompatible-pointer-types) From 7d4eb0d8e229fa51e14f0f85de03c02880e7d742 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 10 Sep 2020 22:51:19 +0900 Subject: [PATCH 19/34] kbuild: remove cc-option test of -fno-stack-check The minimal compiler version, GCC 4.9 supports this flag. Nathan Chancellor pointed out: "This flag is technically ignored by clang (see commit 05b0798916f01690b5903302e51f3136274e291f) but that obviously does not matter for the sake of this." Here is the godbolt: https://godbolt.org/z/59cK6o Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7036dcb99cdf..3722b42fd01e 100644 --- a/Makefile +++ b/Makefile @@ -940,7 +940,7 @@ KBUILD_CFLAGS += $(call cc-option,-fno-merge-all-constants) KBUILD_CFLAGS += $(call cc-option,-fmerge-constants) # Make sure -fstack-check isn't enabled (like gentoo apparently did) -KBUILD_CFLAGS += $(call cc-option,-fno-stack-check,) +KBUILD_CFLAGS += -fno-stack-check # conserve stack if available KBUILD_CFLAGS += $(call cc-option,-fconserve-stack) From 87de84c9140e1ccb221c68bb7e4939e880b3f2bb Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 10 Sep 2020 22:51:20 +0900 Subject: [PATCH 20/34] kbuild: remove cc-option test of -Werror=date-time The minimal compiler versions, GCC 4.9 and Clang 10 support this flag. Here is the godbolt: https://godbolt.org/z/xvjcMa Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor Acked-by: Will Deacon --- Makefile | 2 +- arch/arm64/kernel/vdso32/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 3722b42fd01e..e39ed7967cd6 100644 --- a/Makefile +++ b/Makefile @@ -946,7 +946,7 @@ KBUILD_CFLAGS += -fno-stack-check KBUILD_CFLAGS += $(call cc-option,-fconserve-stack) # Prohibit date/time macros, which would make the build non-deterministic -KBUILD_CFLAGS += $(call cc-option,-Werror=date-time) +KBUILD_CFLAGS += -Werror=date-time # enforce correct pointer usage KBUILD_CFLAGS += $(call cc-option,-Werror=incompatible-pointer-types) diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile index 3d99a9a249e3..1259e5bd0fab 100644 --- a/arch/arm64/kernel/vdso32/Makefile +++ b/arch/arm64/kernel/vdso32/Makefile @@ -92,7 +92,7 @@ VDSO_CFLAGS += $(call cc32-option,-Wdeclaration-after-statement,) VDSO_CFLAGS += $(call cc32-option,-Wno-pointer-sign) VDSO_CFLAGS += -fno-strict-overflow VDSO_CFLAGS += $(call cc32-option,-Werror=strict-prototypes) -VDSO_CFLAGS += $(call cc32-option,-Werror=date-time) +VDSO_CFLAGS += -Werror=date-time VDSO_CFLAGS += $(call cc32-option,-Werror=incompatible-pointer-types) # The 32-bit compiler does not provide 128-bit integers, which are used in From 548b8b5168c90c42e88f70fcf041b4ce0b8e7aa8 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Thu, 17 Sep 2020 08:56:11 +0200 Subject: [PATCH 21/34] scripts/setlocalversion: make git describe output more reliable When building for an embedded target using Yocto, we're sometimes observing that the version string that gets built into vmlinux (and thus what uname -a reports) differs from the path under /lib/modules/ where modules get installed in the rootfs, but only in the length of the -gabc123def suffix. Hence modprobe always fails. The problem is that Yocto has the concept of "sstate" (shared state), which allows different developers/buildbots/etc. to share build artifacts, based on a hash of all the metadata that went into building that artifact - and that metadata includes all dependencies (e.g. the compiler used etc.). That normally works quite well; usually a clean build (without using any sstate cache) done by one developer ends up being binary identical to a build done on another host. However, one thing that can cause two developers to end up with different builds [and thus make one's vmlinux package incompatible with the other's kernel-dev package], which is not captured by the metadata hashing, is this `git describe`: The output of that can be affected by (1) git version: before 2.11 git defaulted to a minimum of 7, since 2.11 (git.git commit e6c587) the default is dynamic based on the number of objects in the repo (2) hence even if both run the same git version, the output can differ based on how many remotes are being tracked (or just lots of local development branches or plain old garbage) (3) and of course somebody could have a core.abbrev config setting in ~/.gitconfig So in order to avoid `uname -a` output relying on such random details of the build environment which are rather hard to ensure are consistent between developers and buildbots, make sure the abbreviated sha1 always consists of exactly 12 hex characters. That is consistent with the current rule for -stable patches, and is almost always enough to identify the head commit unambigously - in the few cases where it does not, the v5.4.3-00021- prefix would certainly nail it down. Signed-off-by: Rasmus Villemoes Signed-off-by: Masahiro Yamada --- scripts/setlocalversion | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/scripts/setlocalversion b/scripts/setlocalversion index 20f2efd57b11..bb709eda96cd 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -45,7 +45,7 @@ scm_version() # Check for git and a git repo. if test -z "$(git rev-parse --show-cdup 2>/dev/null)" && - head=$(git rev-parse --verify --short HEAD 2>/dev/null); then + head=$(git rev-parse --verify HEAD 2>/dev/null); then # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore # it, because this version is defined in the top level Makefile. @@ -59,11 +59,22 @@ scm_version() fi # If we are past a tagged commit (like # "v2.6.30-rc5-302-g72357d5"), we pretty print it. - if atag="$(git describe 2>/dev/null)"; then - echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}' + # + # Ensure the abbreviated sha1 has exactly 12 + # hex characters, to make the output + # independent of git version, local + # core.abbrev settings and/or total number of + # objects in the current repository - passing + # --abbrev=12 ensures a minimum of 12, and the + # awk substr() then picks the 'g' and first 12 + # hex chars. + if atag="$(git describe --abbrev=12 2>/dev/null)"; then + echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),substr($(NF),0,13))}' - # If we don't have a tag at all we print -g{commitish}. + # If we don't have a tag at all we print -g{commitish}, + # again using exactly 12 hex chars. else + head="$(echo $head | cut -c1-12)" printf '%s%s' -g $head fi fi From a968433723310f35898b4a2f635a7991aeef66b1 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 22 Sep 2020 16:21:40 -0700 Subject: [PATCH 22/34] kbuild: explicitly specify the build id style ld's --build-id defaults to "sha1" style, while lld defaults to "fast". The build IDs are very different between the two, which may confuse programs that reference them. Signed-off-by: Bill Wendling Acked-by: David S. Miller Signed-off-by: Masahiro Yamada --- Makefile | 4 ++-- arch/arm/vdso/Makefile | 2 +- arch/arm64/kernel/vdso/Makefile | 2 +- arch/arm64/kernel/vdso32/Makefile | 2 +- arch/mips/vdso/Makefile | 2 +- arch/riscv/kernel/vdso/Makefile | 2 +- arch/s390/kernel/vdso64/Makefile | 2 +- arch/sparc/vdso/Makefile | 2 +- arch/x86/entry/vdso/Makefile | 2 +- tools/testing/selftests/bpf/Makefile | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index e39ed7967cd6..088fb7d49dd7 100644 --- a/Makefile +++ b/Makefile @@ -982,8 +982,8 @@ KBUILD_CPPFLAGS += $(KCPPFLAGS) KBUILD_AFLAGS += $(KAFLAGS) KBUILD_CFLAGS += $(KCFLAGS) -KBUILD_LDFLAGS_MODULE += --build-id -LDFLAGS_vmlinux += --build-id +KBUILD_LDFLAGS_MODULE += --build-id=sha1 +LDFLAGS_vmlinux += --build-id=sha1 ifeq ($(CONFIG_STRIP_ASM_SYMS),y) LDFLAGS_vmlinux += $(call ld-option, -X,) diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile index a54f70731d9f..150ce6e6a5d3 100644 --- a/arch/arm/vdso/Makefile +++ b/arch/arm/vdso/Makefile @@ -19,7 +19,7 @@ ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO32 ldflags-$(CONFIG_CPU_ENDIAN_BE8) := --be8 ldflags-y := -Bsymbolic --no-undefined -soname=linux-vdso.so.1 \ -z max-page-size=4096 -nostdlib -shared $(ldflags-y) \ - --hash-style=sysv --build-id \ + --hash-style=sysv --build-id=sha1 \ -T obj-$(CONFIG_VDSO) += vdso.o diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile index 7cd8aafbe96e..3dc4b65da99d 100644 --- a/arch/arm64/kernel/vdso/Makefile +++ b/arch/arm64/kernel/vdso/Makefile @@ -24,7 +24,7 @@ btildflags-$(CONFIG_ARM64_BTI_KERNEL) += -z force-bti # routines, as x86 does (see 6f121e548f83 ("x86, vdso: Reimplement vdso.so # preparation in build-time C")). ldflags-y := -shared -nostdlib -soname=linux-vdso.so.1 --hash-style=sysv \ - -Bsymbolic $(call ld-option, --no-eh-frame-hdr) --build-id -n \ + -Bsymbolic $(call ld-option, --no-eh-frame-hdr) --build-id=sha1 -n \ $(btildflags-y) -T ccflags-y := -fno-common -fno-builtin -fno-stack-protector -ffixed-x18 diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile index 1259e5bd0fab..7f96a1a9f68c 100644 --- a/arch/arm64/kernel/vdso32/Makefile +++ b/arch/arm64/kernel/vdso32/Makefile @@ -128,7 +128,7 @@ VDSO_LDFLAGS += -Wl,-Bsymbolic -Wl,--no-undefined -Wl,-soname=linux-vdso.so.1 VDSO_LDFLAGS += -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 VDSO_LDFLAGS += -nostdlib -shared -mfloat-abi=soft VDSO_LDFLAGS += -Wl,--hash-style=sysv -VDSO_LDFLAGS += -Wl,--build-id +VDSO_LDFLAGS += -Wl,--build-id=sha1 VDSO_LDFLAGS += $(call cc32-ldoption,-fuse-ld=bfd) diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile index 57fe83235281..5810cc12bc1d 100644 --- a/arch/mips/vdso/Makefile +++ b/arch/mips/vdso/Makefile @@ -61,7 +61,7 @@ endif # VDSO linker flags. ldflags-y := -Bsymbolic --no-undefined -soname=linux-vdso.so.1 \ $(filter -E%,$(KBUILD_CFLAGS)) -nostdlib -shared \ - -G 0 --eh-frame-hdr --hash-style=sysv --build-id -T + -G 0 --eh-frame-hdr --hash-style=sysv --build-id=sha1 -T CFLAGS_REMOVE_vdso.o = -pg diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile index 478e7338ddc1..7d6a94d45ec9 100644 --- a/arch/riscv/kernel/vdso/Makefile +++ b/arch/riscv/kernel/vdso/Makefile @@ -49,7 +49,7 @@ $(obj)/vdso.so.dbg: $(src)/vdso.lds $(obj-vdso) FORCE # refer to these symbols in the kernel code rather than hand-coded addresses. SYSCFLAGS_vdso.so.dbg = -shared -s -Wl,-soname=linux-vdso.so.1 \ - -Wl,--build-id -Wl,--hash-style=both + -Wl,--build-id=sha1 -Wl,--hash-style=both $(obj)/vdso-dummy.o: $(src)/vdso.lds $(obj)/rt_sigreturn.o FORCE $(call if_changed,vdsold) diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile index d0d406cfffa9..9acad762456d 100644 --- a/arch/s390/kernel/vdso64/Makefile +++ b/arch/s390/kernel/vdso64/Makefile @@ -19,7 +19,7 @@ KBUILD_AFLAGS_64 += -m64 -s KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS)) KBUILD_CFLAGS_64 += -m64 -fPIC -shared -fno-common -fno-builtin ldflags-y := -fPIC -shared -nostdlib -soname=linux-vdso64.so.1 \ - --hash-style=both --build-id -T + --hash-style=both --build-id=sha1 -T $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_64) $(targets:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_64) diff --git a/arch/sparc/vdso/Makefile b/arch/sparc/vdso/Makefile index f44355e46f31..469dd23887ab 100644 --- a/arch/sparc/vdso/Makefile +++ b/arch/sparc/vdso/Makefile @@ -115,7 +115,7 @@ quiet_cmd_vdso = VDSO $@ -T $(filter %.lds,$^) $(filter %.o,$^) && \ sh $(srctree)/$(src)/checkundef.sh '$(OBJDUMP)' '$@' -VDSO_LDFLAGS = -shared --hash-style=both --build-id -Bsymbolic +VDSO_LDFLAGS = -shared --hash-style=both --build-id=sha1 -Bsymbolic GCOV_PROFILE := n # diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile index 215376d975a2..ebba25ed9a38 100644 --- a/arch/x86/entry/vdso/Makefile +++ b/arch/x86/entry/vdso/Makefile @@ -176,7 +176,7 @@ quiet_cmd_vdso = VDSO $@ -T $(filter %.lds,$^) $(filter %.o,$^) && \ sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@' -VDSO_LDFLAGS = -shared --hash-style=both --build-id \ +VDSO_LDFLAGS = -shared --hash-style=both --build-id=sha1 \ $(call ld-option, --eh-frame-hdr) -Bsymbolic GCOV_PROFILE := n diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index fc946b7ac288..daf186f88a63 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -133,7 +133,7 @@ $(OUTPUT)/%:%.c $(OUTPUT)/urandom_read: urandom_read.c $(call msg,BINARY,,$@) - $(Q)$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS) -Wl,--build-id + $(Q)$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS) -Wl,--build-id=sha1 $(OUTPUT)/test_stub.o: test_stub.c $(BPFOBJ) $(call msg,CC,,$@) From 08beb669cb3f11ff5e05055bcab5e29385e69f98 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 25 Sep 2020 00:45:46 +0900 Subject: [PATCH 23/34] kbuild: split the build log of kallsyms Currently, the build log shows KSYM + object name. Precisely speaking, kallsyms generates a .S file and then the compiler compiles it into a .o file. Split the build log into two. [Before] GEN modules.builtin LD .tmp_vmlinux.kallsyms1 KSYM .tmp_vmlinux.kallsyms1.o LD .tmp_vmlinux.kallsyms2 KSYM .tmp_vmlinux.kallsyms2.o LD vmlinux [After] GEN modules.builtin LD .tmp_vmlinux.kallsyms1 KSYMS .tmp_vmlinux.kallsyms1.S AS .tmp_vmlinux.kallsyms1.o LD .tmp_vmlinux.kallsyms2 KSYMS .tmp_vmlinux.kallsyms2.S AS .tmp_vmlinux.kallsyms2.o LD vmlinux Signed-off-by: Masahiro Yamada --- scripts/link-vmlinux.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index e6e2d9e5ff48..d9bcf36a1583 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -169,10 +169,9 @@ gen_btf() printf '\1' | dd of=${2} conv=notrunc bs=1 seek=16 status=none } -# Create ${2} .o file with all symbols from the ${1} object file +# Create ${2} .S file with all symbols from the ${1} object file kallsyms() { - info KSYM ${2} local kallsymopt; if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then @@ -187,13 +186,8 @@ kallsyms() kallsymopt="${kallsymopt} --base-relative" fi - local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \ - ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}" - - local afile="`basename ${2} .o`.S" - - ${NM} -n ${1} | scripts/kallsyms ${kallsymopt} > ${afile} - ${CC} ${aflags} -c -o ${2} ${afile} + info KSYMS ${2} + ${NM} -n ${1} | scripts/kallsyms ${kallsymopt} > ${2} } # Perform one step in kallsyms generation, including temporary linking of @@ -203,9 +197,15 @@ kallsyms_step() kallsymso_prev=${kallsymso} kallsyms_vmlinux=.tmp_vmlinux.kallsyms${1} kallsymso=${kallsyms_vmlinux}.o + kallsyms_S=${kallsyms_vmlinux}.S vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" ${btf_vmlinux_bin_o} - kallsyms ${kallsyms_vmlinux} ${kallsymso} + kallsyms ${kallsyms_vmlinux} ${kallsyms_S} + + info AS ${kallsyms_S} + ${CC} ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS} \ + ${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \ + -c -o ${kallsymso} ${kallsyms_S} } # Create map file with all symbols from ${1} From 51ccdbfbed79bae4b9c2529ec980de4508455a47 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Mon, 21 Sep 2020 00:25:50 +0200 Subject: [PATCH 24/34] builddeb: Pass -n to gzip for reproducible packages We should not be encoding the timestamp, otherwise we end up generating unreproducible files that cascade into unreproducible packages. Signed-off-by: Guillem Jover Signed-off-by: Masahiro Yamada --- scripts/package/builddeb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/package/builddeb b/scripts/package/builddeb index 44f212e37935..30e8c6a20171 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -31,7 +31,7 @@ create_package() { mkdir -p "$pdir/usr/share/doc/$pname" cp debian/copyright "$pdir/usr/share/doc/$pname/" cp debian/changelog "$pdir/usr/share/doc/$pname/changelog.Debian" - gzip -9 "$pdir/usr/share/doc/$pname/changelog.Debian" + gzip -n -9 "$pdir/usr/share/doc/$pname/changelog.Debian" sh -c "cd '$pdir'; find . -type f ! -path './DEBIAN/*' -printf '%P\0' \ | xargs -r0 md5sum > DEBIAN/md5sums" From 3e8541803624678925a477a03e19e3c155b5fc12 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Mon, 21 Sep 2020 00:25:54 +0200 Subject: [PATCH 25/34] builddeb: Enable rootless builds This makes it possible to build the Debian packages without requiring (pseudo-)root privileges, when the build drivers support this mode of operation. See-Also: /usr/share/doc/dpkg/rootless-builds.txt.gz Signed-off-by: Guillem Jover Signed-off-by: Masahiro Yamada --- scripts/package/builddeb | 9 +++++++-- scripts/package/mkdebian | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/scripts/package/builddeb b/scripts/package/builddeb index 30e8c6a20171..6474084c32a4 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -26,6 +26,7 @@ if_enabled_echo() { create_package() { local pname="$1" pdir="$2" + local dpkg_deb_opts mkdir -m 755 -p "$pdir/DEBIAN" mkdir -p "$pdir/usr/share/doc/$pname" @@ -36,14 +37,18 @@ create_package() { | xargs -r0 md5sum > DEBIAN/md5sums" # Fix ownership and permissions - chown -R root:root "$pdir" + if [ "$DEB_RULES_REQUIRES_ROOT" = "no" ]; then + dpkg_deb_opts="--root-owner-group" + else + chown -R root:root "$pdir" + fi chmod -R go-w "$pdir" # in case we are in a restrictive umask environment like 0077 chmod -R a+rX "$pdir" # Create the package dpkg-gencontrol -p$pname -P"$pdir" - dpkg-deb ${KDEB_COMPRESS:+-Z$KDEB_COMPRESS} --build "$pdir" .. + dpkg-deb $dpkg_deb_opts ${KDEB_COMPRESS:+-Z$KDEB_COMPRESS} --build "$pdir" .. } deploy_kernel_headers () { diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian index 48fbd3d0284a..dbe42500084c 100755 --- a/scripts/package/mkdebian +++ b/scripts/package/mkdebian @@ -174,6 +174,7 @@ Source: $sourcename Section: kernel Priority: optional Maintainer: $maintainer +Rules-Requires-Root: no Build-Depends: bc, rsync, kmod, cpio, bison, flex | flex:native $extra_build_depends Homepage: https://www.kernel.org/ From 76c37668768464a6c2d5c49abd36ba0b48a0b131 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Mon, 21 Sep 2020 00:25:53 +0200 Subject: [PATCH 26/34] builddeb: Add support for all required debian/rules targets These have been required by the Debian policy for a while, even though the tooling can detect and workaround their omission, but are a hard requirement when using rootless builds. [masahiro: The following Debian policy is particularly important for rootless builds: "Both binary-* targets should depend on the build target, or on the appropriate build-arch or build-indep target, so that the package is built if it has not been already." ] Signed-off-by: Guillem Jover Signed-off-by: Masahiro Yamada --- scripts/package/mkdebian | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian index dbe42500084c..3a13b834f281 100755 --- a/scripts/package/mkdebian +++ b/scripts/package/mkdebian @@ -218,11 +218,15 @@ cat < debian/rules srctree ?= . -build: +build-indep: +build-arch: \$(MAKE) KERNELRELEASE=${version} ARCH=${ARCH} \ KBUILD_BUILD_VERSION=${revision} -f \$(srctree)/Makefile -binary-arch: +build: build-arch + +binary-indep: +binary-arch: build-arch \$(MAKE) KERNELRELEASE=${version} ARCH=${ARCH} \ KBUILD_BUILD_VERSION=${revision} -f \$(srctree)/Makefile intdeb-pkg From 7dfbea4c468cfbc7e1ceb619fe337e7582eb1d2d Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Fri, 9 Oct 2020 17:18:44 -0700 Subject: [PATCH 27/34] scripts: remove namespace.pl namespace.pl is intended to help locate symbols which are defined but are not used externally. The goal is to avoid bloat of the namespace in the resulting kernel image. The script relies on object data, and only finds unused symbols for the configuration used to generate that object data. This results in a lot of false positive warnings such as symbols only used by a single architecture, or symbols which are used externally only under certain configurations. Running namespace.pl using allyesconfig, allmodconfig, and x86_64_defconfig yields the following results: * allmodconfig * 11122 unique symbol names with no external reference * 1194 symbols listed as multiply defined * 214 symbols it can't resolve * allyesconfig * 10997 unique symbol names with no external reference * 1194 symbols listed as multiply defined * 214 symbols it can't resolve * x86_64_defconfig * 5757 unique symbol names with no external reference * 528 symbols listed as multiply defined * 154 symbols it can't resolve The script also has no way to easily limit the scope of the checks to a given subset of the kernel, such as only checking for symbols defined within a module or subsystem. Discussion on public mailing lists seems to indicate that many view the tool output as suspect or not very useful (see discussions at [1] and [2] for further context). As described by Masahiro Yamada at [2], namespace.pl provides 3 types of checks: listing multiply defined symbols, resolving external symbols, and warnings about symbols with no reference. The first category of issues is easily caught by the linker as any set of multiply defined symbols should fail to link. The second category of issues is also caught by linking, as undefined symbols would cause issues. Even with modules, these types of issues where a module relies on an external symbol are caught by modpost. The remaining category of issues reported is the list of symbols with no external reference, and is the primary motivation of this script. However, it ought to be clear from the above examples that the output is difficult to sort through. Even allyesconfig has ~10000 entries. The current submit-checklist indicates that patches ought to go through namespacecheck and fix any new issues arising. But that itself presents problems. As described at [1], many cases of reports are due to configuration where a function is used externally by some configuration settings. Prominent maintainers appear to dislike changes modify code such that symbols become static based on CONFIG_* flags ([3], and [4]) One possible solution is to adjust the advice and indicate that we only care about the output of namespacecheck on allyesconfig or allmodconfig builds... However, given the discussion at [2], I suspect that few people are actively using this tool. It doesn't have a maintainer in the MAINTAINERS flie, and it produces so many warnings for unused symbols that it is difficult to use effectively. Thus, I propose we simply remove it. [1] https://lore.kernel.org/netdev/20200708164812.384ae8ea@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com/ [2] https://lore.kernel.org/lkml/20190129204319.15238-1-jacob.e.keller@intel.com/ [3] https://lore.kernel.org/netdev/20190828.154744.2058157956381129672.davem@davemloft.net/ [4] https://lore.kernel.org/netdev/20190827210928.576c5fef@cakuba.netronome.com/ Signed-off-by: Jacob Keller Acked-by: Randy Dunlap Acked-by: Jakub Kicinski Signed-off-by: Masahiro Yamada --- Documentation/process/submit-checklist.rst | 3 +- Makefile | 6 +- scripts/namespace.pl | 473 --------------------- 3 files changed, 2 insertions(+), 480 deletions(-) delete mode 100755 scripts/namespace.pl diff --git a/Documentation/process/submit-checklist.rst b/Documentation/process/submit-checklist.rst index 3f8e9d5d95c2..e201a6033469 100644 --- a/Documentation/process/submit-checklist.rst +++ b/Documentation/process/submit-checklist.rst @@ -49,8 +49,7 @@ and elsewhere regarding submitting Linux kernel patches. 9) Check cleanly with sparse. -10) Use ``make checkstack`` and ``make namespacecheck`` and fix any problems - that they find. +10) Use ``make checkstack`` and fix any problems that it finds. .. note:: diff --git a/Makefile b/Makefile index 088fb7d49dd7..ddadab2f2e8b 100644 --- a/Makefile +++ b/Makefile @@ -1576,7 +1576,6 @@ help: echo '' @echo 'Static analysers:' @echo ' checkstack - Generate a list of stack hogs' - @echo ' namespacecheck - Name space analysis on compiled kernel' @echo ' versioncheck - Sanity check on version.h usage' @echo ' includecheck - Check for duplicate included header files' @echo ' export_report - List the usages of all exported symbols' @@ -1876,7 +1875,7 @@ endif # Scripts to check various things for consistency # --------------------------------------------------------------------------- -PHONY += includecheck versioncheck coccicheck namespacecheck export_report +PHONY += includecheck versioncheck coccicheck export_report includecheck: find $(srctree)/* $(RCS_FIND_IGNORE) \ @@ -1891,9 +1890,6 @@ versioncheck: coccicheck: $(Q)$(BASH) $(srctree)/scripts/$@ -namespacecheck: - $(PERL) $(srctree)/scripts/namespace.pl - export_report: $(PERL) $(srctree)/scripts/export_report.pl diff --git a/scripts/namespace.pl b/scripts/namespace.pl deleted file mode 100755 index 1da7bca201a4..000000000000 --- a/scripts/namespace.pl +++ /dev/null @@ -1,473 +0,0 @@ -#!/usr/bin/env perl -# -# namespace.pl. Mon Aug 30 2004 -# -# Perform a name space analysis on the linux kernel. -# -# Copyright Keith Owens . GPL. -# -# Invoke by changing directory to the top of the kernel object -# tree then namespace.pl, no parameters. -# -# Tuned for 2.1.x kernels with the new module handling, it will -# work with 2.0 kernels as well. -# -# Last change 2.6.9-rc1, adding support for separate source and object -# trees. -# -# The source must be compiled/assembled first, the object files -# are the primary input to this script. Incomplete or missing -# objects will result in a flawed analysis. Compile both vmlinux -# and modules. -# -# Even with complete objects, treat the result of the analysis -# with caution. Some external references are only used by -# certain architectures, others with certain combinations of -# configuration parameters. Ideally the source should include -# something like -# -# #ifndef CONFIG_... -# static -# #endif -# symbol_definition; -# -# so the symbols are defined as static unless a particular -# CONFIG_... requires it to be external. -# -# A symbol that is suffixed with '(export only)' has these properties -# -# * It is global. -# * It is marked EXPORT_SYMBOL or EXPORT_SYMBOL_GPL, either in the same -# source file or a different source file. -# * Given the current .config, nothing uses the symbol. -# -# The symbol is a candidate for conversion to static, plus removal of the -# export. But be careful that a different .config might use the symbol. -# -# -# Name space analysis and cleanup is an iterative process. You cannot -# expect to find all the problems in a single pass. -# -# * Identify possibly unnecessary global declarations, verify that they -# really are unnecessary and change them to static. -# * Compile and fix up gcc warnings about static, removing dead symbols -# as necessary. -# * make clean and rebuild with different configs (especially -# CONFIG_MODULES=n) to see which symbols are being defined when the -# config does not require them. These symbols bloat the kernel object -# for no good reason, which is frustrating for embedded systems. -# * Wrap config sensitive symbols in #ifdef CONFIG_foo, as long as the -# code does not get too ugly. -# * Repeat the name space analysis until you can live with with the -# result. -# - -use warnings; -use strict; -use File::Find; -use File::Spec; - -my $nm = ($ENV{'NM'} || "nm") . " -p"; -my $objdump = ($ENV{'OBJDUMP'} || "objdump") . " -s -j .comment"; -my $srctree = File::Spec->curdir(); -my $objtree = File::Spec->curdir(); -$srctree = File::Spec->rel2abs($ENV{'srctree'}) if (exists($ENV{'srctree'})); -$objtree = File::Spec->rel2abs($ENV{'objtree'}) if (exists($ENV{'objtree'})); - -if ($#ARGV != -1) { - print STDERR "usage: $0 takes no parameters\n"; - die("giving up\n"); -} - -my %nmdata = (); # nm data for each object -my %def = (); # all definitions for each name -my %ksymtab = (); # names that appear in __ksymtab_ -my %ref = (); # $ref{$name} exists if there is a true external reference to $name -my %export = (); # $export{$name} exists if there is an EXPORT_... of $name - -my %nmexception = ( - 'fs/ext3/bitmap' => 1, - 'fs/ext4/bitmap' => 1, - 'arch/x86/lib/thunk_32' => 1, - 'arch/x86/lib/cmpxchg' => 1, - 'arch/x86/vdso/vdso32/note' => 1, - 'lib/irq_regs' => 1, - 'usr/initramfs_data' => 1, - 'drivers/scsi/aic94xx/aic94xx_dump' => 1, - 'drivers/scsi/libsas/sas_dump' => 1, - 'lib/dec_and_lock' => 1, - 'drivers/ide/ide-probe-mini' => 1, - 'usr/initramfs_data' => 1, - 'drivers/acpi/acpia/exdump' => 1, - 'drivers/acpi/acpia/rsdump' => 1, - 'drivers/acpi/acpia/nsdumpdv' => 1, - 'drivers/acpi/acpia/nsdump' => 1, - 'arch/ia64/sn/kernel/sn2/io' => 1, - 'arch/ia64/kernel/gate-data' => 1, - 'security/capability' => 1, - 'fs/ntfs/sysctl' => 1, - 'fs/jfs/jfs_debug' => 1, -); - -my %nameexception = ( - 'mod_use_count_' => 1, - '__initramfs_end' => 1, - '__initramfs_start' => 1, - '_einittext' => 1, - '_sinittext' => 1, - 'kallsyms_names' => 1, - 'kallsyms_num_syms' => 1, - 'kallsyms_addresses'=> 1, - 'kallsyms_offsets' => 1, - 'kallsyms_relative_base'=> 1, - '__this_module' => 1, - '_etext' => 1, - '_edata' => 1, - '_end' => 1, - '__bss_start' => 1, - '_text' => 1, - '_stext' => 1, - '__gp' => 1, - 'ia64_unw_start' => 1, - 'ia64_unw_end' => 1, - '__init_begin' => 1, - '__init_end' => 1, - '__bss_stop' => 1, - '__nosave_begin' => 1, - '__nosave_end' => 1, - 'pg0' => 1, - 'vdso_enabled' => 1, - '__stack_chk_fail' => 1, - 'VDSO32_PRELINK' => 1, - 'VDSO32_vsyscall' => 1, - 'VDSO32_rt_sigreturn'=>1, - 'VDSO32_sigreturn' => 1, -); - - -&find(\&linux_objects, '.'); # find the objects and do_nm on them -&list_multiply_defined(); -&resolve_external_references(); -&list_extra_externals(); - -exit(0); - -sub linux_objects -{ - # Select objects, ignoring objects which are only created by - # merging other objects. Also ignore all of modules, scripts - # and compressed. Most conglomerate objects are handled by do_nm, - # this list only contains the special cases. These include objects - # that are linked from just one other object and objects for which - # there is really no permanent source file. - my $basename = $_; - $_ = $File::Find::name; - s:^\./::; - if (/.*\.o$/ && - ! ( - m:/built-in.a$: - || m:arch/x86/vdso/: - || m:arch/x86/boot/: - || m:arch/ia64/ia32/ia32.o$: - || m:arch/ia64/kernel/gate-syms.o$: - || m:arch/ia64/lib/__divdi3.o$: - || m:arch/ia64/lib/__divsi3.o$: - || m:arch/ia64/lib/__moddi3.o$: - || m:arch/ia64/lib/__modsi3.o$: - || m:arch/ia64/lib/__udivdi3.o$: - || m:arch/ia64/lib/__udivsi3.o$: - || m:arch/ia64/lib/__umoddi3.o$: - || m:arch/ia64/lib/__umodsi3.o$: - || m:arch/ia64/scripts/check_gas_for_hint.o$: - || m:arch/ia64/sn/kernel/xp.o$: - || m:boot/bbootsect.o$: - || m:boot/bsetup.o$: - || m:/bootsect.o$: - || m:/boot/setup.o$: - || m:/compressed/: - || m:drivers/cdrom/driver.o$: - || m:drivers/char/drm/tdfx_drv.o$: - || m:drivers/ide/ide-detect.o$: - || m:drivers/ide/pci/idedriver-pci.o$: - || m:drivers/media/media.o$: - || m:drivers/scsi/sd_mod.o$: - || m:drivers/video/video.o$: - || m:fs/devpts/devpts.o$: - || m:fs/exportfs/exportfs.o$: - || m:fs/hugetlbfs/hugetlbfs.o$: - || m:fs/msdos/msdos.o$: - || m:fs/nls/nls.o$: - || m:fs/ramfs/ramfs.o$: - || m:fs/romfs/romfs.o$: - || m:fs/vfat/vfat.o$: - || m:init/mounts.o$: - || m:^modules/: - || m:net/netlink/netlink.o$: - || m:net/sched/sched.o$: - || m:/piggy.o$: - || m:^scripts/: - || m:sound/.*/snd-: - || m:^.*/\.tmp_: - || m:^\.tmp_: - || m:/vmlinux-obj.o$: - || m:^tools/: - ) - ) { - do_nm($basename, $_); - } - $_ = $basename; # File::Find expects $_ untouched (undocumented) -} - -sub do_nm -{ - my ($basename, $fullname) = @_; - my ($source, $type, $name); - if (! -e $basename) { - printf STDERR "$basename does not exist\n"; - return; - } - if ($fullname !~ /\.o$/) { - printf STDERR "$fullname is not an object file\n"; - return; - } - ($source = $basename) =~ s/\.o$//; - if (-e "$source.c" || -e "$source.S") { - $source = File::Spec->catfile($objtree, $File::Find::dir, $source) - } else { - $source = File::Spec->catfile($srctree, $File::Find::dir, $source) - } - if (! -e "$source.c" && ! -e "$source.S") { - # No obvious source, exclude the object if it is conglomerate - open(my $objdumpdata, "$objdump $basename|") - or die "$objdump $fullname failed $!\n"; - - my $comment; - while (<$objdumpdata>) { - chomp(); - if (/^In archive/) { - # Archives are always conglomerate - $comment = "GCC:GCC:"; - last; - } - next if (! /^[ 0-9a-f]{5,} /); - $comment .= substr($_, 43); - } - close($objdumpdata); - - if (!defined($comment) || $comment !~ /GCC\:.*GCC\:/m) { - printf STDERR "No source file found for $fullname\n"; - } - return; - } - open (my $nmdata, "$nm $basename|") - or die "$nm $fullname failed $!\n"; - - my @nmdata; - while (<$nmdata>) { - chop; - ($type, $name) = (split(/ +/, $_, 3))[1..2]; - # Expected types - # A absolute symbol - # B weak external reference to data that has been resolved - # C global variable, uninitialised - # D global variable, initialised - # G global variable, initialised, small data section - # R global array, initialised - # S global variable, uninitialised, small bss - # T global label/procedure - # U external reference - # W weak external reference to text that has been resolved - # V similar to W, but the value of the weak symbol becomes zero with no error. - # a assembler equate - # b static variable, uninitialised - # d static variable, initialised - # g static variable, initialised, small data section - # r static array, initialised - # s static variable, uninitialised, small bss - # t static label/procedures - # w weak external reference to text that has not been resolved - # v similar to w - # ? undefined type, used a lot by modules - if ($type !~ /^[ABCDGRSTUWVabdgrstwv?]$/) { - printf STDERR "nm output for $fullname contains unknown type '$_'\n"; - } - elsif ($name =~ /\./) { - # name with '.' is local static - } - else { - $type = 'R' if ($type eq '?'); # binutils replaced ? with R at one point - # binutils keeps changing the type for exported symbols, force it to R - $type = 'R' if ($name =~ /^__ksymtab/ || $name =~ /^__kstrtab/); - $name =~ s/_R[a-f0-9]{8}$//; # module versions adds this - if ($type =~ /[ABCDGRSTWV]/ && - $name ne 'init_module' && - $name ne 'cleanup_module' && - $name ne 'Using_Versions' && - $name !~ /^Version_[0-9]+$/ && - $name !~ /^__parm_/ && - $name !~ /^__kstrtab/ && - $name !~ /^__ksymtab/ && - $name !~ /^__kcrctab_/ && - $name !~ /^__exitcall_/ && - $name !~ /^__initcall_/ && - $name !~ /^__kdb_initcall_/ && - $name !~ /^__kdb_exitcall_/ && - $name !~ /^__module_/ && - $name !~ /^__mod_/ && - $name !~ /^__crc_/ && - $name ne '__this_module' && - $name ne 'kernel_version') { - if (!exists($def{$name})) { - $def{$name} = []; - } - push(@{$def{$name}}, $fullname); - } - push(@nmdata, "$type $name"); - if ($name =~ /^__ksymtab_/) { - $name = substr($name, 10); - if (!exists($ksymtab{$name})) { - $ksymtab{$name} = []; - } - push(@{$ksymtab{$name}}, $fullname); - } - } - } - close($nmdata); - - if ($#nmdata < 0) { - printf "No nm data for $fullname\n" - unless $nmexception{$fullname}; - return; - } - $nmdata{$fullname} = \@nmdata; -} - -sub drop_def -{ - my ($object, $name) = @_; - my $nmdata = $nmdata{$object}; - my ($i, $j); - for ($i = 0; $i <= $#{$nmdata}; ++$i) { - if ($name eq (split(' ', $nmdata->[$i], 2))[1]) { - splice(@{$nmdata{$object}}, $i, 1); - my $def = $def{$name}; - for ($j = 0; $j < $#{$def{$name}}; ++$j) { - if ($def{$name}[$j] eq $object) { - splice(@{$def{$name}}, $j, 1); - } - } - last; - } - } -} - -sub list_multiply_defined -{ - foreach my $name (keys(%def)) { - if ($#{$def{$name}} > 0) { - # Special case for cond_syscall - if ($#{$def{$name}} == 1 && - ($name =~ /^sys_/ || $name =~ /^compat_sys_/ || - $name =~ /^sys32_/)) { - if($def{$name}[0] eq "kernel/sys_ni.o" || - $def{$name}[1] eq "kernel/sys_ni.o") { - &drop_def("kernel/sys_ni.o", $name); - next; - } - } - - printf "$name is multiply defined in :-\n"; - foreach my $module (@{$def{$name}}) { - printf "\t$module\n"; - } - } - } -} - -sub resolve_external_references -{ - my ($kstrtab, $ksymtab, $export); - - printf "\n"; - foreach my $object (keys(%nmdata)) { - my $nmdata = $nmdata{$object}; - for (my $i = 0; $i <= $#{$nmdata}; ++$i) { - my ($type, $name) = split(' ', $nmdata->[$i], 2); - if ($type eq "U" || $type eq "w") { - if (exists($def{$name}) || exists($ksymtab{$name})) { - # add the owning object to the nmdata - $nmdata->[$i] = "$type $name $object"; - # only count as a reference if it is not EXPORT_... - $kstrtab = "R __kstrtab_$name"; - $ksymtab = "R __ksymtab_$name"; - $export = 0; - for (my $j = 0; $j <= $#{$nmdata}; ++$j) { - if ($nmdata->[$j] eq $kstrtab || - $nmdata->[$j] eq $ksymtab) { - $export = 1; - last; - } - } - if ($export) { - $export{$name} = ""; - } - else { - $ref{$name} = "" - } - } - elsif ( ! $nameexception{$name} - && $name !~ /^__sched_text_/ - && $name !~ /^__start_/ - && $name !~ /^__end_/ - && $name !~ /^__stop_/ - && $name !~ /^__scheduling_functions_.*_here/ - && $name !~ /^__.*initcall_/ - && $name !~ /^__.*per_cpu_start/ - && $name !~ /^__.*per_cpu_end/ - && $name !~ /^__alt_instructions/ - && $name !~ /^__setup_/ - && $name !~ /^__mod_timer/ - && $name !~ /^__mod_page_state/ - && $name !~ /^init_module/ - && $name !~ /^cleanup_module/ - ) { - printf "Cannot resolve "; - printf "weak " if ($type eq "w"); - printf "reference to $name from $object\n"; - } - } - } - } -} - -sub list_extra_externals -{ - my %noref = (); - - foreach my $name (keys(%def)) { - if (! exists($ref{$name})) { - my @module = @{$def{$name}}; - foreach my $module (@module) { - if (! exists($noref{$module})) { - $noref{$module} = []; - } - push(@{$noref{$module}}, $name); - } - } - } - if (%noref) { - printf "\nExternally defined symbols with no external references\n"; - foreach my $module (sort(keys(%noref))) { - printf " $module\n"; - foreach (sort(@{$noref{$module}})) { - my $export; - if (exists($export{$_})) { - $export = " (export only)"; - } else { - $export = ""; - } - printf " $_$export\n"; - } - } - } -} From 172aad81a882443eefe1bd860c4eddc81b14dd5b Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Sun, 11 Oct 2020 20:54:31 +0200 Subject: [PATCH 28/34] kbuild: enforce -Werror=return-type Catch errors which at least gcc tolerates by default: warning: 'return' with no value, in function returning non-void [-Wreturn-type] Signed-off-by: Olaf Hering Signed-off-by: Masahiro Yamada --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ddadab2f2e8b..b76c4122c967 100644 --- a/Makefile +++ b/Makefile @@ -497,7 +497,7 @@ KBUILD_AFLAGS := -D__ASSEMBLY__ -fno-PIE KBUILD_CFLAGS := -Wall -Wundef -Werror=strict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE \ -Werror=implicit-function-declaration -Werror=implicit-int \ - -Wno-format-security \ + -Werror=return-type -Wno-format-security \ -std=gnu89 KBUILD_CPPFLAGS := -D__KERNEL__ KBUILD_AFLAGS_KERNEL := From bac977cbc0d6731fb8e67c2be0e4acbd959e10b3 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 14 Oct 2020 03:38:19 +0900 Subject: [PATCH 29/34] kbuild: deb-pkg: do not build linux-headers package if CONFIG_MODULES=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit 269a535ca931 ("modpost: generate vmlinux.symvers and reuse it for the second modpost"), with CONFIG_MODULES disabled, "make deb-pkg" (or "make bindeb-pkg") fails with: find: ‘Module.symvers’: No such file or directory If CONFIG_MODULES is disabled, it doesn't really make sense to build the linux-headers package. Fixes: 269a535ca931 ("modpost: generate vmlinux.symvers and reuse it for the second modpost") Reported-by: Josh Triplett Signed-off-by: Masahiro Yamada --- scripts/package/builddeb | 6 ++++-- scripts/package/mkdebian | 19 ++++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/scripts/package/builddeb b/scripts/package/builddeb index 6474084c32a4..1b11f8993629 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -207,8 +207,10 @@ EOF done if [ "$ARCH" != "um" ]; then - deploy_kernel_headers debian/linux-headers - create_package linux-headers-$version debian/linux-headers + if is_enabled CONFIG_MODULES; then + deploy_kernel_headers debian/linux-headers + create_package linux-headers-$version debian/linux-headers + fi deploy_libc_headers debian/linux-libc-dev create_package linux-libc-dev debian/linux-libc-dev diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian index 3a13b834f281..273fd6ed790e 100755 --- a/scripts/package/mkdebian +++ b/scripts/package/mkdebian @@ -184,13 +184,6 @@ Description: Linux kernel, version $version This package contains the Linux kernel, modules and corresponding other files, version: $version. -Package: $kernel_headers_packagename -Architecture: $debarch -Description: Linux kernel headers for $version on $debarch - This package provides kernel header files for $version on $debarch - . - This is useful for people who need to build external modules - Package: linux-libc-dev Section: devel Provides: linux-kernel-headers @@ -201,6 +194,18 @@ Description: Linux support headers for userspace development Multi-Arch: same EOF +if is_enabled CONFIG_MODULES; then +cat <> debian/control + +Package: $kernel_headers_packagename +Architecture: $debarch +Description: Linux kernel headers for $version on $debarch + This package provides kernel header files for $version on $debarch + . + This is useful for people who need to build external modules +EOF +fi + if is_enabled CONFIG_DEBUG_INFO; then cat <> debian/control From 0fa21cf4489fe11737d56f8056dda1ba0257bd8d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 14 Oct 2020 03:38:20 +0900 Subject: [PATCH 30/34] kbuild: deb-pkg: clean up package name variables Hard-code the names of linux-headers and debug packages in the control file. The kernel package is different for ARCH=um. Change the code for better readability. Signed-off-by: Masahiro Yamada --- scripts/package/mkdebian | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian index 273fd6ed790e..60a2a63a5e90 100755 --- a/scripts/package/mkdebian +++ b/scripts/package/mkdebian @@ -94,16 +94,16 @@ else packageversion=$version-$revision fi sourcename=$KDEB_SOURCENAME -packagename=linux-image-$version -kernel_headers_packagename=linux-headers-$version -dbg_packagename=$packagename-dbg -debarch= -set_debarch if [ "$ARCH" = "um" ] ; then - packagename=user-mode-linux-$version + packagename=user-mode-linux +else + packagename=linux-image fi +debarch= +set_debarch + email=${DEBEMAIL-$EMAIL} # use email string directly if it contains @@ -178,7 +178,7 @@ Rules-Requires-Root: no Build-Depends: bc, rsync, kmod, cpio, bison, flex | flex:native $extra_build_depends Homepage: https://www.kernel.org/ -Package: $packagename +Package: $packagename-$version Architecture: $debarch Description: Linux kernel, version $version This package contains the Linux kernel, modules and corresponding other @@ -197,7 +197,7 @@ EOF if is_enabled CONFIG_MODULES; then cat <> debian/control -Package: $kernel_headers_packagename +Package: linux-headers-$version Architecture: $debarch Description: Linux kernel headers for $version on $debarch This package provides kernel header files for $version on $debarch @@ -209,7 +209,7 @@ fi if is_enabled CONFIG_DEBUG_INFO; then cat <> debian/control -Package: $dbg_packagename +Package: linux-image-$version-dbg Section: debug Architecture: $debarch Description: Linux kernel debugging symbols for $version From 0f6372e522237f39aff63f2e158d629038f26238 Mon Sep 17 00:00:00 2001 From: Sami Tolvanen Date: Mon, 12 Oct 2020 17:31:45 -0700 Subject: [PATCH 31/34] treewide: remove DISABLE_LTO This change removes all instances of DISABLE_LTO from Makefiles, as they are currently unused, and the preferred method of disabling LTO is to filter out the flags instead. Note added by Masahiro Yamada: DISABLE_LTO was added as preparation for GCC LTO, but GCC LTO was not pulled into the mainline. (https://lkml.org/lkml/2014/4/8/272) Suggested-by: Kees Cook Signed-off-by: Sami Tolvanen Reviewed-by: Kees Cook Signed-off-by: Masahiro Yamada --- arch/arm64/kernel/vdso/Makefile | 1 - arch/sparc/vdso/Makefile | 2 -- arch/x86/entry/vdso/Makefile | 2 -- kernel/Makefile | 3 --- scripts/Makefile.build | 2 +- 5 files changed, 1 insertion(+), 9 deletions(-) diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile index 3dc4b65da99d..ce2bb6270a4e 100644 --- a/arch/arm64/kernel/vdso/Makefile +++ b/arch/arm64/kernel/vdso/Makefile @@ -31,7 +31,6 @@ ccflags-y := -fno-common -fno-builtin -fno-stack-protector -ffixed-x18 ccflags-y += -DDISABLE_BRANCH_PROFILING CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) $(GCC_PLUGINS_CFLAGS) -KBUILD_CFLAGS += $(DISABLE_LTO) KASAN_SANITIZE := n UBSAN_SANITIZE := n OBJECT_FILES_NON_STANDARD := y diff --git a/arch/sparc/vdso/Makefile b/arch/sparc/vdso/Makefile index 469dd23887ab..c5e1545bc5cf 100644 --- a/arch/sparc/vdso/Makefile +++ b/arch/sparc/vdso/Makefile @@ -3,8 +3,6 @@ # Building vDSO images for sparc. # -KBUILD_CFLAGS += $(DISABLE_LTO) - VDSO64-$(CONFIG_SPARC64) := y VDSOCOMPAT-$(CONFIG_COMPAT) := y diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile index ebba25ed9a38..21243747965d 100644 --- a/arch/x86/entry/vdso/Makefile +++ b/arch/x86/entry/vdso/Makefile @@ -9,8 +9,6 @@ ARCH_REL_TYPE_ABS := R_X86_64_JUMP_SLOT|R_X86_64_GLOB_DAT|R_X86_64_RELATIVE| ARCH_REL_TYPE_ABS += R_386_GLOB_DAT|R_386_JMP_SLOT|R_386_RELATIVE include $(srctree)/lib/vdso/Makefile -KBUILD_CFLAGS += $(DISABLE_LTO) - # Sanitizer runtimes are unavailable and cannot be linked here. KASAN_SANITIZE := n UBSAN_SANITIZE := n diff --git a/kernel/Makefile b/kernel/Makefile index 9a20016d4900..347254f07dab 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -38,9 +38,6 @@ KASAN_SANITIZE_kcov.o := n KCSAN_SANITIZE_kcov.o := n CFLAGS_kcov.o := $(call cc-option, -fno-conserve-stack) -fno-stack-protector -# cond_syscall is currently not LTO compatible -CFLAGS_sys_ni.o = $(DISABLE_LTO) - obj-y += sched/ obj-y += locking/ obj-y += power/ diff --git a/scripts/Makefile.build b/scripts/Makefile.build index a467b9323442..ae647379b579 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -111,7 +111,7 @@ endif # --------------------------------------------------------------------------- quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ - cmd_cc_s_c = $(CC) $(filter-out $(DEBUG_CFLAGS), $(c_flags)) $(DISABLE_LTO) -fverbose-asm -S -o $@ $< + cmd_cc_s_c = $(CC) $(filter-out $(DEBUG_CFLAGS), $(c_flags)) -fverbose-asm -S -o $@ $< $(obj)/%.s: $(src)/%.c FORCE $(call if_changed_dep,cc_s_c) From 8402ee182c417a32d5e5a702f2fa2b01e76dc220 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Fri, 16 Oct 2020 14:58:46 +0200 Subject: [PATCH 32/34] kbuild: remove leftover comment for filechk utility After commit 43fee2b23895 ("kbuild: do not redirect the first prerequisite for filechk"), the rule is no longer automatically passed $< as stdin, so remove the stale comment. Fixes: 43fee2b23895 ("kbuild: do not redirect the first prerequisite for filechk") Signed-off-by: Rasmus Villemoes Signed-off-by: Masahiro Yamada --- scripts/Kbuild.include | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 83a1637417e5..08e011175b4c 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -56,8 +56,6 @@ kecho := $($(quiet)kecho) # - If no file exist it is created # - If the content differ the new file is used # - If they are equal no change, and no timestamp update -# - stdin is piped in from the first prerequisite ($<) so one has -# to specify a valid file as first prerequisite (often the kbuild file) define filechk $(Q)set -e; \ mkdir -p $(dir $@); \ From 121c5d08d53cb1f95d9881838523b0305c3f3bef Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sat, 17 Oct 2020 14:01:35 +0200 Subject: [PATCH 33/34] kbuild: Only add -fno-var-tracking-assignments for old GCC versions Some old GCC versions between 4.5.0 and 4.9.1 might miscompile code with -fvar-tracking-assingments (which is enabled by default with -g -O2). Commit 2062afb4f804 ("Fix gcc-4.9.0 miscompilation of load_balance() in scheduler") added -fno-var-tracking-assignments unconditionally to work around this. But newer versions of GCC no longer have this bug, so only add it for versions of GCC before 5.0. This allows various tools such as a perf probe or gdb debuggers or systemtap to resolve variable locations using dwarf locations in more code. Signed-off-by: Mark Wielaard Acked-by: Ian Rogers Reviewed-by: Andi Kleen Signed-off-by: Masahiro Yamada --- Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b76c4122c967..17a62e365a38 100644 --- a/Makefile +++ b/Makefile @@ -814,7 +814,11 @@ KBUILD_CFLAGS += -ftrivial-auto-var-init=zero KBUILD_CFLAGS += -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang endif -DEBUG_CFLAGS := $(call cc-option, -fno-var-tracking-assignments) +# Workaround for GCC versions < 5.0 +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61801 +ifdef CONFIG_CC_IS_GCC +DEBUG_CFLAGS := $(call cc-ifversion, -lt, 0500, $(call cc-option, -fno-var-tracking-assignments)) +endif ifdef CONFIG_DEBUG_INFO From 1e66d50ad3a1dbf0169b14d502be59a4b1213149 Mon Sep 17 00:00:00 2001 From: Chris Down Date: Tue, 20 Oct 2020 10:34:59 +0100 Subject: [PATCH 34/34] kbuild: Use uname for LINUX_COMPILE_HOST detection `hostname` may not be present on some systems as it's not mandated by POSIX/SUSv4. This isn't just a theoretical problem: on Arch Linux, `hostname` is provided by `inetutils`, which isn't part of the base distribution. ./scripts/mkcompile_h: line 38: hostname: command not found Use `uname -n` instead, which is more likely to be available (and mandated by standards). Signed-off-by: Chris Down Signed-off-by: Masahiro Yamada --- scripts/mkcompile_h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h index baf3ab8d9d49..4ae735039daf 100755 --- a/scripts/mkcompile_h +++ b/scripts/mkcompile_h @@ -35,7 +35,7 @@ else LINUX_COMPILE_BY=$KBUILD_BUILD_USER fi if test -z "$KBUILD_BUILD_HOST"; then - LINUX_COMPILE_HOST=`hostname` + LINUX_COMPILE_HOST=`uname -n` else LINUX_COMPILE_HOST=$KBUILD_BUILD_HOST fi