From 10e9510a6d238a8e6c994b81748b00b9c696c48b Mon Sep 17 00:00:00 2001 From: Sami Tolvanen Date: Mon, 3 Feb 2025 21:26:32 +0000 Subject: [PATCH 01/40] gendwarfksyms: Add a separate pass to resolve FQNs Using dwarf_getscopes_die to resolve fully-qualified names turns out to be rather slow, and also results in duplicate scopes being processed, which doesn't help. Simply adding an extra pass to resolve names for all DIEs before processing exports is noticeably faster. For the object files with the most exports in a defconfig+Rust build, the performance improvement is consistently >50%: rust/bindings.o: 1038 exports before: 9.5980 +- 0.0183 seconds time elapsed ( +- 0.19% ) after: 4.3116 +- 0.0287 seconds time elapsed ( +- 0.67% ) rust/core.o: 424 exports before: 5.3584 +- 0.0204 seconds time elapsed ( +- 0.38% ) after: 0.05348 +- 0.00129 seconds time elapsed ( +- 2.42% ) ^ Not a mistake. net/core/dev.o: 190 exports before: 9.0507 +- 0.0297 seconds time elapsed ( +- 0.33% ) after: 3.2882 +- 0.0165 seconds time elapsed ( +- 0.50% ) rust/kernel.o: 129 exports before: 6.8571 +- 0.0317 seconds time elapsed ( +- 0.46% ) after: 2.9096 +- 0.0316 seconds time elapsed ( +- 1.09% ) net/core/skbuff.o: 120 exports before: 5.4805 +- 0.0291 seconds time elapsed ( +- 0.53% ) after: 2.0339 +- 0.0231 seconds time elapsed ( +- 1.14% ) drivers/gpu/drm/display/drm_dp_helper.o: 101 exports before: 1.7877 +- 0.0187 seconds time elapsed ( +- 1.05% ) after: 0.69245 +- 0.00994 seconds time elapsed ( +- 1.44% ) net/core/sock.o: 97 exports before: 5.8327 +- 0.0653 seconds time elapsed ( +- 1.12% ) after: 2.0784 +- 0.0291 seconds time elapsed ( +- 1.40% ) drivers/net/phy/phy_device.o: 95 exports before: 3.0671 +- 0.0371 seconds time elapsed ( +- 1.21% ) after: 1.2127 +- 0.0207 seconds time elapsed ( +- 1.70% ) drivers/pci/pci.o: 93 exports before: 1.1130 +- 0.0113 seconds time elapsed ( +- 1.01% ) after: 0.4848 +- 0.0127 seconds time elapsed ( +- 2.63% ) kernel/sched/core.o: 83 exports before: 3.5092 +- 0.0223 seconds time elapsed ( +- 0.64% ) after: 1.1231 +- 0.0145 seconds time elapsed ( +- 1.29% ) Overall, a defconfig+DWARF5 build with gendwarfksyms and Rust is 14.8% faster with this patch applied on my test system. Without Rust, there's still a 10.4% improvement in build time when gendwarfksyms is used. Note that symbol versions are unchanged with this patch. Suggested-by: Giuliano Procida Signed-off-by: Sami Tolvanen Signed-off-by: Masahiro Yamada --- scripts/gendwarfksyms/die.c | 2 +- scripts/gendwarfksyms/dwarf.c | 154 ++++++++++++++------------ scripts/gendwarfksyms/gendwarfksyms.h | 2 + scripts/gendwarfksyms/types.c | 2 +- 4 files changed, 87 insertions(+), 73 deletions(-) diff --git a/scripts/gendwarfksyms/die.c b/scripts/gendwarfksyms/die.c index 66bd4c9bc952..6183bbbe7b54 100644 --- a/scripts/gendwarfksyms/die.c +++ b/scripts/gendwarfksyms/die.c @@ -6,7 +6,7 @@ #include #include "gendwarfksyms.h" -#define DIE_HASH_BITS 15 +#define DIE_HASH_BITS 16 /* {die->addr, state} -> struct die * */ static HASHTABLE_DEFINE(die_map, 1 << DIE_HASH_BITS); diff --git a/scripts/gendwarfksyms/dwarf.c b/scripts/gendwarfksyms/dwarf.c index 534d9aa7c114..eed247d8abfc 100644 --- a/scripts/gendwarfksyms/dwarf.c +++ b/scripts/gendwarfksyms/dwarf.c @@ -3,6 +3,7 @@ * Copyright (C) 2024 Google LLC */ +#define _GNU_SOURCE #include #include #include @@ -193,79 +194,17 @@ static void process_fmt(struct die *cache, const char *fmt, ...) va_end(args); } -#define MAX_FQN_SIZE 64 - -/* Get a fully qualified name from DWARF scopes */ -static char *get_fqn(Dwarf_Die *die) -{ - const char *list[MAX_FQN_SIZE]; - Dwarf_Die *scopes = NULL; - bool has_name = false; - char *fqn = NULL; - char *p; - int count = 0; - int len = 0; - int res; - int i; - - res = checkp(dwarf_getscopes_die(die, &scopes)); - if (!res) { - list[count] = get_name_attr(die); - - if (!list[count]) - return NULL; - - len += strlen(list[count]); - count++; - - goto done; - } - - for (i = res - 1; i >= 0 && count < MAX_FQN_SIZE; i--) { - if (dwarf_tag(&scopes[i]) == DW_TAG_compile_unit) - continue; - - list[count] = get_name_attr(&scopes[i]); - - if (list[count]) { - has_name = true; - } else { - list[count] = ""; - has_name = false; - } - - len += strlen(list[count]); - count++; - - if (i > 0) { - list[count++] = "::"; - len += 2; - } - } - - free(scopes); - - if (count == MAX_FQN_SIZE) - warn("increase MAX_FQN_SIZE: reached the maximum"); - - /* Consider the DIE unnamed if the last scope doesn't have a name */ - if (!has_name) - return NULL; -done: - fqn = xmalloc(len + 1); - *fqn = '\0'; - - p = fqn; - for (i = 0; i < count; i++) - p = stpcpy(p, list[i]); - - return fqn; -} - static void update_fqn(struct die *cache, Dwarf_Die *die) { - if (!cache->fqn) - cache->fqn = get_fqn(die) ?: ""; + struct die *fqn; + + if (!cache->fqn) { + if (!__die_map_get((uintptr_t)die->addr, DIE_FQN, &fqn) && + *fqn->fqn) + cache->fqn = xstrdup(fqn->fqn); + else + cache->fqn = ""; + } } static void process_fqn(struct die *cache, Dwarf_Die *die) @@ -1148,8 +1087,81 @@ static void process_symbol_ptr(struct symbol *sym, void *arg) cache_free(&state.expansion_cache); } +static int resolve_fqns(struct state *parent, struct die *unused, + Dwarf_Die *die) +{ + struct state state; + struct die *cache; + const char *name; + bool use_prefix; + char *prefix = NULL; + char *fqn = ""; + int tag; + + if (!__die_map_get((uintptr_t)die->addr, DIE_FQN, &cache)) + return 0; + + tag = dwarf_tag(die); + + /* + * Only namespaces and structures need to pass a prefix to the next + * scope. + */ + use_prefix = tag == DW_TAG_namespace || tag == DW_TAG_class_type || + tag == DW_TAG_structure_type; + + state.expand.current_fqn = NULL; + name = get_name_attr(die); + + if (parent && parent->expand.current_fqn && (use_prefix || name)) { + /* + * The fqn for the current DIE, and if needed, a prefix for the + * next scope. + */ + if (asprintf(&prefix, "%s::%s", parent->expand.current_fqn, + name ? name : "") < 0) + error("asprintf failed"); + + if (use_prefix) + state.expand.current_fqn = prefix; + + /* + * Use fqn only if the DIE has a name. Otherwise fqn will + * remain empty. + */ + if (name) { + fqn = prefix; + /* prefix will be freed by die_map. */ + prefix = NULL; + } + } else if (name) { + /* No prefix from the previous scope. Use only the name. */ + fqn = xstrdup(name); + + if (use_prefix) + state.expand.current_fqn = fqn; + } + + /* If the DIE has a non-empty name, cache it. */ + if (*fqn) { + cache = die_map_get(die, DIE_FQN); + /* Move ownership of fqn to die_map. */ + cache->fqn = fqn; + cache->state = DIE_FQN; + } + + check(process_die_container(&state, NULL, die, resolve_fqns, + match_all)); + + free(prefix); + return 0; +} + void process_cu(Dwarf_Die *cudie) { + check(process_die_container(NULL, NULL, cudie, resolve_fqns, + match_all)); + check(process_die_container(NULL, NULL, cudie, process_exported_symbols, match_all)); diff --git a/scripts/gendwarfksyms/gendwarfksyms.h b/scripts/gendwarfksyms/gendwarfksyms.h index 197a1a8123c6..2feec168bf73 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.h +++ b/scripts/gendwarfksyms/gendwarfksyms.h @@ -139,6 +139,7 @@ void symbol_free(void); enum die_state { DIE_INCOMPLETE, + DIE_FQN, DIE_UNEXPANDED, DIE_COMPLETE, DIE_SYMBOL, @@ -170,6 +171,7 @@ static inline const char *die_state_name(enum die_state state) { switch (state) { CASE_CONST_TO_STR(DIE_INCOMPLETE) + CASE_CONST_TO_STR(DIE_FQN) CASE_CONST_TO_STR(DIE_UNEXPANDED) CASE_CONST_TO_STR(DIE_COMPLETE) CASE_CONST_TO_STR(DIE_SYMBOL) diff --git a/scripts/gendwarfksyms/types.c b/scripts/gendwarfksyms/types.c index 6c03265f4d10..6f37289104ff 100644 --- a/scripts/gendwarfksyms/types.c +++ b/scripts/gendwarfksyms/types.c @@ -248,7 +248,7 @@ static char *get_type_name(struct die *cache) warn("found incomplete cache entry: %p", cache); return NULL; } - if (cache->state == DIE_SYMBOL) + if (cache->state == DIE_SYMBOL || cache->state == DIE_FQN) return NULL; if (!cache->fqn || !*cache->fqn) return NULL; From e966ad0edd0056c7491b8f23992c11734ab61ddf Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 6 Feb 2025 01:39:38 +0900 Subject: [PATCH 02/40] kbuild: remove EXTRA_*FLAGS support Commit f77bf01425b1 ("kbuild: introduce ccflags-y, asflags-y and ldflags-y") deprecated these in 2007. The migration should have been completed by now. Signed-off-by: Masahiro Yamada Reviewed-by: Kees Cook Reviewed-by: Nathan Chancellor --- Documentation/dev-tools/checkpatch.rst | 18 ------------------ Documentation/kbuild/makefiles.rst | 3 --- scripts/Makefile.build | 4 ---- scripts/Makefile.lib | 5 ----- scripts/checkpatch.pl | 14 -------------- 5 files changed, 44 deletions(-) diff --git a/Documentation/dev-tools/checkpatch.rst b/Documentation/dev-tools/checkpatch.rst index abb3ff682076..76bd0ddb0041 100644 --- a/Documentation/dev-tools/checkpatch.rst +++ b/Documentation/dev-tools/checkpatch.rst @@ -342,24 +342,6 @@ API usage See: https://www.kernel.org/doc/html/latest/RCU/whatisRCU.html#full-list-of-rcu-apis - **DEPRECATED_VARIABLE** - EXTRA_{A,C,CPP,LD}FLAGS are deprecated and should be replaced by the new - flags added via commit f77bf01425b1 ("kbuild: introduce ccflags-y, - asflags-y and ldflags-y"). - - The following conversion scheme maybe used:: - - EXTRA_AFLAGS -> asflags-y - EXTRA_CFLAGS -> ccflags-y - EXTRA_CPPFLAGS -> cppflags-y - EXTRA_LDFLAGS -> ldflags-y - - See: - - 1. https://lore.kernel.org/lkml/20070930191054.GA15876@uranus.ravnborg.org/ - 2. https://lore.kernel.org/lkml/1313384834-24433-12-git-send-email-lacombar@gmail.com/ - 3. https://www.kernel.org/doc/html/latest/kbuild/makefiles.html#compilation-flags - **DEVICE_ATTR_FUNCTIONS** The function names used in DEVICE_ATTR is unusual. Typically, the store and show functions are used with _store and diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst index d36519f194dc..25e04e47faff 100644 --- a/Documentation/kbuild/makefiles.rst +++ b/Documentation/kbuild/makefiles.rst @@ -318,9 +318,6 @@ ccflags-y, asflags-y and ldflags-y These three flags apply only to the kbuild makefile in which they are assigned. They are used for all the normal cc, as and ld invocations happening during a recursive build. - Note: Flags with the same behaviour were previously named: - EXTRA_CFLAGS, EXTRA_AFLAGS and EXTRA_LDFLAGS. - They are still supported but their usage is deprecated. ccflags-y specifies options for compiling with $(CC). diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 993708d11874..a59650ba140b 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -20,10 +20,6 @@ always-m := targets := subdir-y := subdir-m := -EXTRA_AFLAGS := -EXTRA_CFLAGS := -EXTRA_CPPFLAGS := -EXTRA_LDFLAGS := asflags-y := ccflags-y := rustflags-y := diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index cad20f0e66ee..47f56ef71937 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -1,9 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -# Backward compatibility -asflags-y += $(EXTRA_AFLAGS) -ccflags-y += $(EXTRA_CFLAGS) -cppflags-y += $(EXTRA_CPPFLAGS) -ldflags-y += $(EXTRA_LDFLAGS) # flags that take effect in current and sub directories KBUILD_AFLAGS += $(subdir-asflags-y) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 7b28ad331742..8f70bedc18be 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3689,20 +3689,6 @@ sub process { } } - if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && - ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { - my $flag = $1; - my $replacement = { - 'EXTRA_AFLAGS' => 'asflags-y', - 'EXTRA_CFLAGS' => 'ccflags-y', - 'EXTRA_CPPFLAGS' => 'cppflags-y', - 'EXTRA_LDFLAGS' => 'ldflags-y', - }; - - WARN("DEPRECATED_VARIABLE", - "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); - } - # check for DT compatible documentation if (defined $root && (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || From 90efe2b9119ff8a83a67eb5323e52311a1a49de9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 6 Feb 2025 02:18:02 +0900 Subject: [PATCH 03/40] gen_compile_commands.py: remove code for '\#' replacement Since commit 9564a8cf422d ("Kbuild: fix # escaping in .cmd files for future Make"), '#' in the build command is replaced with $(pound) rather than '\#'. Calling .replace(r'\#', '#') is only necessary when this tool is used to parse .*.cmd files generated by Linux 4.16 or earlier, which is unlikely to happen. Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor --- scripts/clang-tools/gen_compile_commands.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/clang-tools/gen_compile_commands.py b/scripts/clang-tools/gen_compile_commands.py index e4fb686dfaa9..96e6e46ad1a7 100755 --- a/scripts/clang-tools/gen_compile_commands.py +++ b/scripts/clang-tools/gen_compile_commands.py @@ -167,10 +167,10 @@ def process_line(root_directory, command_prefix, file_path): root_directory or file_directory. """ # The .cmd files are intended to be included directly by Make, so they - # escape the pound sign '#', either as '\#' or '$(pound)' (depending on the - # kernel version). The compile_commands.json file is not interepreted - # by Make, so this code replaces the escaped version with '#'. - prefix = command_prefix.replace(r'\#', '#').replace('$(pound)', '#') + # escape the pound sign '#' as '$(pound)'. The compile_commands.json file + # is not interepreted by Make, so this code replaces the escaped version + # with '#'. + prefix = command_prefix.replace('$(pound)', '#') # Return the canonical path, eliminating any symbolic links encountered in the path. abs_path = os.path.realpath(os.path.join(root_directory, file_path)) From 6c3fb0bb4d4f1173f32cc26d077b151d72226a2f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 6 Feb 2025 02:45:28 +0900 Subject: [PATCH 04/40] genksyms: factor out APP for the ST_NORMAL state For the ST_NORMAL state, APP is called regardless of the token type. Factor it out. Signed-off-by: Masahiro Yamada --- scripts/genksyms/lex.l | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/scripts/genksyms/lex.l b/scripts/genksyms/lex.l index 22aeb57649d9..f81033af1528 100644 --- a/scripts/genksyms/lex.l +++ b/scripts/genksyms/lex.l @@ -176,10 +176,10 @@ repeat: switch (lexstate) { case ST_NORMAL: + APP; switch (token) { case IDENT: - APP; { int r = is_reserved_word(yytext, yyleng); if (r >= 0) @@ -224,13 +224,11 @@ repeat: break; case '[': - APP; lexstate = ST_BRACKET; count = 1; goto repeat; case '{': - APP; if (dont_want_brace_phrase) break; lexstate = ST_BRACE; @@ -238,12 +236,10 @@ repeat: goto repeat; case '=': case ':': - APP; lexstate = ST_EXPRESSION; break; default: - APP; break; } break; From 226ac19c217f24f0927d0a73cf9ee613971a188d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 8 Feb 2025 03:41:55 +0900 Subject: [PATCH 05/40] kconfig: do not clear SYMBOL_VALID when reading include/config/auto.conf When conf_read_simple() is called with S_DEF_AUTO, it is meant to read previous symbol values from include/config/auto.conf to determine which include/config/* files should be touched. This process should not modify the current symbol status in any way. However, conf_touch_deps() currently invalidates all symbol values and recalculates them, which is totally unneeded. Signed-off-by: Masahiro Yamada --- scripts/kconfig/confdata.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 3b55e7a4131d..ac95661a1c9d 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -385,7 +385,7 @@ load: def_flags = SYMBOL_DEF << def; for_all_symbols(sym) { - sym->flags &= ~(def_flags|SYMBOL_VALID); + sym->flags &= ~def_flags; switch (sym->type) { case S_INT: case S_HEX: @@ -398,7 +398,11 @@ load: } } - expr_invalidate_all(); + if (def == S_DEF_USER) { + for_all_symbols(sym) + sym->flags &= ~SYMBOL_VALID; + expr_invalidate_all(); + } while (getline_stripped(&line, &line_asize, in) != -1) { struct menu *choice; @@ -464,6 +468,9 @@ load: if (conf_set_sym_val(sym, def, def_flags, val)) continue; + if (def != S_DEF_USER) + continue; + /* * If this is a choice member, give it the highest priority. * If conflicting CONFIG options are given from an input file, @@ -967,10 +974,8 @@ static int conf_touch_deps(void) depfile_path[depfile_prefix_len] = 0; conf_read_simple(name, S_DEF_AUTO); - sym_calc_value(modules_sym); for_all_symbols(sym) { - sym_calc_value(sym); if (sym_is_choice(sym)) continue; if (sym->flags & SYMBOL_WRITE) { @@ -1084,12 +1089,12 @@ int conf_write_autoconf(int overwrite) if (ret) return -1; - if (conf_touch_deps()) - return 1; - for_all_symbols(sym) sym_calc_value(sym); + if (conf_touch_deps()) + return 1; + ret = __conf_write_autoconf(conf_get_autoheader_name(), print_symbol_for_c, &comment_style_c); From ab5bc764bdc270d1c55aaf9d238e0986ff301355 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 8 Feb 2025 03:42:48 +0900 Subject: [PATCH 06/40] kconfig: remove unnecessary cast in sym_get_string() The explicit casting from (char *) to (const char *) is unneeded. Signed-off-by: Masahiro Yamada --- scripts/kconfig/symbol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 7beb59dec5a0..d57f8cbba291 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -879,7 +879,7 @@ const char *sym_get_string_value(struct symbol *sym) default: ; } - return (const char *)sym->curr.val; + return sym->curr.val; } bool sym_is_changeable(const struct symbol *sym) From 59d60d26a58be75e9e3b813104c2dfd3b58eb662 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 8 Feb 2025 02:50:13 +0900 Subject: [PATCH 07/40] modpost: introduce get_basename() helper The logic to retrieve the basename appears multiple times. Factor out the common pattern into a helper function. I copied kbasename() from include/linux/string.h and renamed it to get_basename(). Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- scripts/mod/modpost.c | 41 ++++++++++++++++++---------------------- scripts/mod/modpost.h | 1 + scripts/mod/sumversion.c | 13 ++++--------- 3 files changed, 23 insertions(+), 32 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index c35d22607978..7f4c72eca72c 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -98,6 +98,18 @@ static inline bool strends(const char *str, const char *postfix) return strcmp(str + strlen(str) - strlen(postfix), postfix) == 0; } +/** + * get_basename - return the last part of a pathname. + * + * @path: path to extract the filename from. + */ +const char *get_basename(const char *path) +{ + const char *tail = strrchr(path, '/'); + + return tail ? tail + 1 : path; +} + char *read_text_file(const char *filename) { struct stat st; @@ -1461,14 +1473,8 @@ static void extract_crcs_for_object(const char *object, struct module *mod) const char *base; int dirlen, ret; - base = strrchr(object, '/'); - if (base) { - base++; - dirlen = base - object; - } else { - dirlen = 0; - base = object; - } + base = get_basename(object); + dirlen = base - object; ret = snprintf(cmd_file, sizeof(cmd_file), "%.*s.%s.cmd", dirlen, object, base); @@ -1703,11 +1709,7 @@ static void check_exports(struct module *mod) s->crc_valid = exp->crc_valid; s->crc = exp->crc; - basename = strrchr(mod->name, '/'); - if (basename) - basename++; - else - basename = mod->name; + basename = get_basename(mod->name); if (!contains_namespace(&mod->imported_namespaces, exp->namespace)) { modpost_log(!allow_missing_ns_imports, @@ -1765,11 +1767,8 @@ static void check_modname_len(struct module *mod) { const char *mod_name; - mod_name = strrchr(mod->name, '/'); - if (mod_name == NULL) - mod_name = mod->name; - else - mod_name++; + mod_name = get_basename(mod->name); + if (strlen(mod_name) >= MODULE_NAME_LEN) error("module name is too long [%s.ko]\n", mod->name); } @@ -1946,11 +1945,7 @@ static void add_depends(struct buffer *b, struct module *mod) continue; s->module->seen = true; - p = strrchr(s->module->name, '/'); - if (p) - p++; - else - p = s->module->name; + p = get_basename(s->module->name); buf_printf(b, "%s%s", first ? "" : ",", p); first = 0; } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 59366f456b76..9133e4c3803f 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -216,6 +216,7 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen); /* from modpost.c */ extern bool target_is_big_endian; extern bool host_is_big_endian; +const char *get_basename(const char *path); char *read_text_file(const char *filename); char *get_line(char **stringp); void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym); diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c index 6de9af17599d..e79fc40d852f 100644 --- a/scripts/mod/sumversion.c +++ b/scripts/mod/sumversion.c @@ -309,15 +309,10 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) cmd = xmalloc(strlen(objfile) + sizeof("..cmd")); - base = strrchr(objfile, '/'); - if (base) { - base++; - dirlen = base - objfile; - sprintf(cmd, "%.*s.%s.cmd", dirlen, objfile, base); - } else { - dirlen = 0; - sprintf(cmd, ".%s.cmd", objfile); - } + base = get_basename(objfile); + dirlen = base - objfile; + sprintf(cmd, "%.*s.%s.cmd", dirlen, objfile, base); + dir = xmalloc(dirlen + 1); strncpy(dir, objfile, dirlen); dir[dirlen] = '\0'; From 144fced6852ba11c90560c996e986b4563f089af Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 8 Feb 2025 02:50:55 +0900 Subject: [PATCH 08/40] modpost: use strstarts() to clean up parse_source_files() No functional changes are intended. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- scripts/mod/sumversion.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c index e79fc40d852f..3dd28b4d0099 100644 --- a/scripts/mod/sumversion.c +++ b/scripts/mod/sumversion.c @@ -330,7 +330,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) line++; p = line; - if (strncmp(line, "source_", sizeof("source_")-1) == 0) { + if (strstarts(line, "source_")) { p = strrchr(line, ' '); if (!p) { warn("malformed line: %s\n", line); @@ -344,7 +344,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) } continue; } - if (strncmp(line, "deps_", sizeof("deps_")-1) == 0) { + if (strstarts(line, "deps_")) { check_files = 1; continue; } From ac954145e1ee3f72033161cbe4ac0b16b5354ae7 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Mon, 10 Feb 2025 17:42:45 +0100 Subject: [PATCH 09/40] kbuild: rust: add rustc-min-version support function Introduce `rustc-min-version` support function that mimics `{gcc,clang}-min-version` ones, following commit 88b61e3bff93 ("Makefile.compiler: replace cc-ifversion with compiler-specific macros"). In addition, use it in the first use case we have in the kernel (which was done independently to minimize the changes needed for the fix). Signed-off-by: Miguel Ojeda Reviewed-by: Fiona Behrens Reviewed-by: Nicolas Schier Signed-off-by: Masahiro Yamada --- Documentation/kbuild/makefiles.rst | 14 ++++++++++++++ arch/arm64/Makefile | 2 +- scripts/Makefile.compiler | 4 ++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst index 25e04e47faff..3b9a8bc671e2 100644 --- a/Documentation/kbuild/makefiles.rst +++ b/Documentation/kbuild/makefiles.rst @@ -667,6 +667,20 @@ cc-cross-prefix endif endif +$(RUSTC) support functions +-------------------------- + +rustc-min-version + rustc-min-version tests if the value of $(CONFIG_RUSTC_VERSION) is greater + than or equal to the provided value and evaluates to y if so. + + Example:: + + rustflags-$(call rustc-min-version, 108500) := -Cfoo + + In this example, rustflags-y will be assigned the value -Cfoo if + $(CONFIG_RUSTC_VERSION) is >= 1.85.0. + $(LD) support functions ----------------------- diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 2b25d671365f..1d5dfcd1c13e 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -48,7 +48,7 @@ KBUILD_CFLAGS += $(CC_FLAGS_NO_FPU) \ KBUILD_CFLAGS += $(call cc-disable-warning, psabi) KBUILD_AFLAGS += $(compat_vdso) -ifeq ($(call test-ge, $(CONFIG_RUSTC_VERSION), 108500),y) +ifeq ($(call rustc-min-version, 108500),y) KBUILD_RUSTFLAGS += --target=aarch64-unknown-none-softfloat else KBUILD_RUSTFLAGS += --target=aarch64-unknown-none -Ctarget-feature="-neon" diff --git a/scripts/Makefile.compiler b/scripts/Makefile.compiler index 8c1029687e2e..8956587b8547 100644 --- a/scripts/Makefile.compiler +++ b/scripts/Makefile.compiler @@ -67,6 +67,10 @@ gcc-min-version = $(call test-ge, $(CONFIG_GCC_VERSION), $1) # Usage: cflags-$(call clang-min-version, 110000) += -foo clang-min-version = $(call test-ge, $(CONFIG_CLANG_VERSION), $1) +# rustc-min-version +# Usage: rustc-$(call rustc-min-version, 108500) += -Cfoo +rustc-min-version = $(call test-ge, $(CONFIG_RUSTC_VERSION), $1) + # ld-option # Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y) ld-option = $(call try-run, $(LD) $(KBUILD_LDFLAGS) $(1) -v,$(1),$(2),$(3)) From 9d702bb1d3c03bb78d4fd2b3424169e3ef4cd402 Mon Sep 17 00:00:00 2001 From: Uday Shankar Date: Mon, 10 Feb 2025 18:11:54 -0700 Subject: [PATCH 10/40] scripts: make python shebangs specific about desired version The RPM packaging tools like to make sure that all packaged python scripts have version-unambiguous shebangs. Be more specific about the desired python version in a couple of places to avoid having to disable these checks in make rpm-pkg. Signed-off-by: Uday Shankar Signed-off-by: Masahiro Yamada --- scripts/show_delta | 2 +- scripts/tracing/draw_functrace.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/show_delta b/scripts/show_delta index 291ad65e3089..3755b6c6e557 100755 --- a/scripts/show_delta +++ b/scripts/show_delta @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0-only # # show_deltas: Read list of printk messages instrumented with diff --git a/scripts/tracing/draw_functrace.py b/scripts/tracing/draw_functrace.py index 42fa87300941..97594b65f8ce 100755 --- a/scripts/tracing/draw_functrace.py +++ b/scripts/tracing/draw_functrace.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0-only """ From c15253494fd98cd76250c9faaebbc8b45f7d0072 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 16 Feb 2025 01:15:52 +0900 Subject: [PATCH 11/40] kbuild: move -fzero-init-padding-bits=all to the top-level Makefile The -fzero-init-padding-bits=all option is not a warning flag, so defining it in scripts/Makefile.extrawarn is inconsistent. Move it to the top-level Makefile for consistency. Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor Reviewed-by: Kees Cook --- Makefile | 3 +++ scripts/Makefile.extrawarn | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 1d6a9ec8a2ac..7cd80ff2d69b 100644 --- a/Makefile +++ b/Makefile @@ -928,6 +928,9 @@ KBUILD_CFLAGS += $(CC_AUTO_VAR_INIT_ZERO_ENABLER) endif endif +# Explicitly clear padding bits during variable initialization +KBUILD_CFLAGS += $(call cc-option,-fzero-init-padding-bits=all) + # While VLAs have been removed, GCC produces unreachable stack probes # for the randomize_kstack_offset feature. Disable it for all compilers. KBUILD_CFLAGS += $(call cc-option, -fno-stack-clash-protection) diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index dc081cf46d21..d75897559d18 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -82,9 +82,6 @@ KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init) # Warn if there is an enum types mismatch KBUILD_CFLAGS += $(call cc-option,-Wenum-conversion) -# Explicitly clear padding bits during variable initialization -KBUILD_CFLAGS += $(call cc-option,-fzero-init-padding-bits=all) - KBUILD_CFLAGS += -Wextra KBUILD_CFLAGS += -Wunused From d0beb73d1d8a89c6c6830d8d873ac9d3163132dc Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 17 Feb 2025 20:36:48 +0900 Subject: [PATCH 12/40] kbuild: remove KBUILD_ENABLE_EXTRA_GCC_CHECKS support Commit e27128db6283 ("kbuild: rename KBUILD_ENABLE_EXTRA_GCC_CHECKS to KBUILD_EXTRA_WARN") renamed KBUILD_ENABLE_EXTRA_GCC_CHECKS in 2019. The migration in downstream code should be complete. Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor --- Makefile | 3 --- 1 file changed, 3 deletions(-) diff --git a/Makefile b/Makefile index 7cd80ff2d69b..3428e4630069 100644 --- a/Makefile +++ b/Makefile @@ -151,9 +151,6 @@ endif export KBUILD_EXTMOD -# backward compatibility -KBUILD_EXTRA_WARN ?= $(KBUILD_ENABLE_EXTRA_GCC_CHECKS) - ifeq ("$(origin W)", "command line") KBUILD_EXTRA_WARN := $(W) endif From 700bd25bd4f47a0f4e02e0a25dde05f1a6b16eea Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 17 Feb 2025 12:31:53 +0100 Subject: [PATCH 13/40] docs: kconfig: Mention IS_REACHABLE as way for optional dependency Several drivers express optional Kconfig dependency with FOO || !FOO, but for many choices this is not suitable: lack of stubs for !FOO like in HWMON. Describe the second, less favorable way of optional dependency with IS_REACHABLE by moving the code from "imply" chapter to "Optional dependencies". Signed-off-by: Krzysztof Kozlowski Acked-by: Arnd Bergmann Signed-off-by: Masahiro Yamada --- Documentation/kbuild/kconfig-language.rst | 29 ++++++++++++++--------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/Documentation/kbuild/kconfig-language.rst b/Documentation/kbuild/kconfig-language.rst index 2619fdf56e68..a91abb8f6840 100644 --- a/Documentation/kbuild/kconfig-language.rst +++ b/Documentation/kbuild/kconfig-language.rst @@ -194,16 +194,6 @@ applicable everywhere (see syntax). ability to hook into a secondary subsystem while allowing the user to configure that subsystem out without also having to unset these drivers. - Note: If the combination of FOO=y and BAZ=m causes a link error, - you can guard the function call with IS_REACHABLE():: - - foo_init() - { - if (IS_REACHABLE(CONFIG_BAZ)) - baz_register(&foo); - ... - } - Note: If the feature provided by BAZ is highly desirable for FOO, FOO should imply not only BAZ, but also its dependency BAR:: @@ -588,7 +578,9 @@ uses the slightly counterintuitive:: depends on BAR || !BAR This means that there is either a dependency on BAR that disallows -the combination of FOO=y with BAR=m, or BAR is completely disabled. +the combination of FOO=y with BAR=m, or BAR is completely disabled. The BAR +module must provide all the stubs for !BAR case. + For a more formalized approach if there are multiple drivers that have the same dependency, a helper symbol can be used, like:: @@ -599,6 +591,21 @@ the same dependency, a helper symbol can be used, like:: config BAR_OPTIONAL def_tristate BAR || !BAR +Much less favorable way to express optional dependency is IS_REACHABLE() within +the module code, useful for example when the module BAR does not provide +!BAR stubs:: + + foo_init() + { + if (IS_REACHABLE(CONFIG_BAR)) + bar_register(&foo); + ... + } + +IS_REACHABLE() is generally discouraged, because the code will be silently +discarded, when CONFIG_BAR=m and this code is built-in. This is not what users +usually expect when enabling BAR as module. + Kconfig recursive dependency limitations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 268d191abc57a89f4ed92efcb276aae54f86c88c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Mon, 17 Feb 2025 11:59:21 +0100 Subject: [PATCH 14/40] kbuild: implement CONFIG_HEADERS_INSTALL for Usermode Linux MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit userprogs sometimes need access to UAPI headers. This is currently not possible for Usermode Linux, as UM is only a pseudo architecture built on top of a regular architecture and does not have its own UAPI. Instead use the UAPI headers from the underlying regular architecture. Signed-off-by: Thomas Weißschuh Signed-off-by: Masahiro Yamada --- Makefile | 5 ++++- lib/Kconfig.debug | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 3428e4630069..f2ec8d05c0f5 100644 --- a/Makefile +++ b/Makefile @@ -1361,9 +1361,12 @@ hdr-inst := -f $(srctree)/scripts/Makefile.headersinst obj PHONY += headers headers: $(version_h) scripts_unifdef uapi-asm-generic archheaders archscripts - $(if $(filter um, $(SRCARCH)), $(error Headers not exportable for UML)) +ifdef HEADER_ARCH + $(Q)$(MAKE) -f $(srctree)/Makefile HEADER_ARCH= SRCARCH=$(HEADER_ARCH) headers +else $(Q)$(MAKE) $(hdr-inst)=include/uapi $(Q)$(MAKE) $(hdr-inst)=arch/$(SRCARCH)/include/uapi +endif ifdef CONFIG_HEADERS_INSTALL prepare: headers diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 35796c290ca3..17ccd913975d 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -473,7 +473,6 @@ config READABLE_ASM config HEADERS_INSTALL bool "Install uapi headers to usr/include" - depends on !UML help This option will install uapi headers (headers exported to user-space) into the usr/include directory for use during the kernel build. From dbdffaf50ff9cee3259a7cef8a7bd9e0f0ba9f13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Wed, 19 Feb 2025 22:22:13 +0100 Subject: [PATCH 15/40] kbuild, rust: use -fremap-path-prefix to make paths relative MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remap source path prefixes in all output, including compiler diagnostics, debug information, macro expansions, etc. This removes a few absolute paths from the binary and also makes it possible to use core::panic::Location properly. Equivalent to the same configuration done for C sources in commit 1d3730f0012f ("kbuild: support -fmacro-prefix-map for external modules") and commit a73619a845d5 ("kbuild: use -fmacro-prefix-map to make __FILE__ a relative path"). Link: https://doc.rust-lang.org/rustc/command-line-arguments.html#--remap-path-prefix-remap-source-names-in-output Acked-by: Miguel Ojeda Signed-off-by: Thomas Weißschuh Tested-by: Gary Guo Signed-off-by: Masahiro Yamada --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index f2ec8d05c0f5..30242e731a0d 100644 --- a/Makefile +++ b/Makefile @@ -1068,6 +1068,7 @@ endif # change __FILE__ to the relative path to the source directory ifdef building_out_of_srctree KBUILD_CPPFLAGS += $(call cc-option,-fmacro-prefix-map=$(srcroot)/=) +KBUILD_RUSTFLAGS += --remap-path-prefix=$(srcroot)/= endif # include additional Makefiles when needed From 1195306ee359ced2cb9d7a192e973872571cb93a Mon Sep 17 00:00:00 2001 From: WangYuli Date: Tue, 25 Feb 2025 02:26:19 +0800 Subject: [PATCH 16/40] kbuild: deb-pkg: add debarch for ARCH=loongarch64 Fix follow warning when 'make ARCH=loongarch64 bindeb-pkg': ** ** ** WARNING ** ** ** Your architecture doesn't have its equivalent Debian userspace architecture defined! Falling back to the current host architecture (loong64). Please add support for loongarch64 to ./scripts/package/mkdebian ... Reported-by: Shiwei Liu Signed-off-by: WangYuli Reviewed-by: Nathan Chancellor Signed-off-by: Masahiro Yamada --- scripts/package/mkdebian | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian index b6dd98ca860b..0178000197fe 100755 --- a/scripts/package/mkdebian +++ b/scripts/package/mkdebian @@ -77,6 +77,8 @@ set_debarch() { debarch=i386 fi ;; + loongarch64) + debarch=loong64 ;; esac if [ -z "$debarch" ]; then debarch=$(dpkg-architecture -qDEB_HOST_ARCH) From 82c09de2d4c472ab1b973e6e033671020691e637 Mon Sep 17 00:00:00 2001 From: Xi Ruoyao Date: Wed, 26 Feb 2025 21:30:14 +0800 Subject: [PATCH 17/40] kbuild: add dependency from vmlinux to sorttable Without this dependency it's really puzzling when we bisect for a "bad" commit in a series of sorttable change: when "git bisect" switches to another commit, "make" just does nothing to vmlinux. Signed-off-by: Xi Ruoyao Acked-by: Steven Rostedt (Google) Signed-off-by: Masahiro Yamada --- scripts/Makefile.vmlinux | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index 873caaa55313..fb79fd6b2465 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -79,6 +79,10 @@ ifdef CONFIG_DEBUG_INFO_BTF vmlinux: $(RESOLVE_BTFIDS) endif +ifdef CONFIG_BUILDTIME_TABLE_SORT +vmlinux: scripts/sorttable +endif + # module.builtin.ranges # --------------------------------------------------------------------------- ifdef CONFIG_BUILTIN_MODULE_RANGES From f757f6011c92b5a01db742c39149bed9e526478f Mon Sep 17 00:00:00 2001 From: Seyediman Seyedarab Date: Sat, 1 Mar 2025 17:21:37 -0500 Subject: [PATCH 18/40] kbuild: fix argument parsing in scripts/config The script previously assumed --file was always the first argument, which caused issues when it appeared later. This patch updates the parsing logic to scan all arguments to find --file, sets the config file correctly, and resets the argument list with the remaining commands. It also fixes --refresh to respect --file by passing KCONFIG_CONFIG=$FN to make oldconfig. Signed-off-by: Seyediman Seyedarab Signed-off-by: Masahiro Yamada --- scripts/config | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/scripts/config b/scripts/config index ff88e2faefd3..ea475c07de28 100755 --- a/scripts/config +++ b/scripts/config @@ -32,6 +32,7 @@ commands: Disable option directly after other option --module-after|-M beforeopt option Turn option into module directly after other option + --refresh Refresh the config using old settings commands can be repeated multiple times @@ -124,16 +125,22 @@ undef_var() { txt_delete "^# $name is not set" "$FN" } -if [ "$1" = "--file" ]; then - FN="$2" - if [ "$FN" = "" ] ; then - usage +FN=.config +CMDS=() +while [[ $# -gt 0 ]]; do + if [ "$1" = "--file" ]; then + if [ "$2" = "" ]; then + usage + fi + FN="$2" + shift 2 + else + CMDS+=("$1") + shift fi - shift 2 -else - FN=.config -fi +done +set -- "${CMDS[@]}" if [ "$1" = "" ] ; then usage fi @@ -217,9 +224,8 @@ while [ "$1" != "" ] ; do set_var "${CONFIG_}$B" "${CONFIG_}$B=m" "${CONFIG_}$A" ;; - # undocumented because it ignores --file (fixme) --refresh) - yes "" | make oldconfig + yes "" | make oldconfig KCONFIG_CONFIG=$FN ;; *) From eb47ee018173f144f10eb38a3f7bd9f17ec6329e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 7 Mar 2025 00:56:22 +0900 Subject: [PATCH 19/40] kbuild: add Kbuild bash completion Kernel build commands can sometimes be long, particularly when cross-compiling, making them tedious to type and prone to mistypes. This commit introduces bash completion support for common variables and targets in Kbuild. For installation instructions, please refer to the documentation in Documentation/kbuild/bash-completion.rst. The following examples demonstrate how this saves typing. [Example 1] a long command line for cross-compiling $ make A -> completes 'A' to 'ARCH=' $ make ARCH= -> displays all supported architectures $ make ARCH=arm64 CR -> completes 'CR' to 'CROSS_COMPILE=' $ make ARCH=arm64 CROSS_COMPILE= -> displays installed toolchains $ make ARCH=arm64 CROSS_COMPILE=aa -> completes 'CROSS_COMPILE=aa' to 'CROSS_COMPILE=aarch64-linux-gnu-' $ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- def -> completes 'def' to 'defconfig' [Example 2] a single build target $ make f -> completes 'f' to 'fs/' $ make fs/ -> displays objects and sub-directories in fs/ $ make fs/xf -> completes 'fs/xf' to 'fs/xfs/' $ make fs/xfs/l -> completes 'fs/xfs/l' to 'fs/xfs/libxfs/xfs_' $ make fs/xfs/libxfs/xfs_g -> completes 'fs/xfs/libxfs/xfs_g' to 'fs/xfs/libxfs/xfs_group.o' This does not aim to provide a complete list of variables and targets, as there are too many. However, it covers variables and targets used in common scenarios, and I hope this is useful enough. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier Tested-by: Nicolas Schier --- Documentation/kbuild/bash-completion.rst | 65 ++++ Documentation/kbuild/index.rst | 2 + MAINTAINERS | 1 + scripts/bash-completion/make | 451 +++++++++++++++++++++++ 4 files changed, 519 insertions(+) create mode 100644 Documentation/kbuild/bash-completion.rst create mode 100644 scripts/bash-completion/make diff --git a/Documentation/kbuild/bash-completion.rst b/Documentation/kbuild/bash-completion.rst new file mode 100644 index 000000000000..2b52dbcd0933 --- /dev/null +++ b/Documentation/kbuild/bash-completion.rst @@ -0,0 +1,65 @@ +.. SPDX-License-Identifier: GPL-2.0-only + +========================== +Bash completion for Kbuild +========================== + +The kernel build system is written using Makefiles, and Bash completion +for the `make` command is available through the `bash-completion`_ project. + +However, the Makefiles for the kernel build are complex. The generic completion +rules for the `make` command do not provide meaningful suggestions for the +kernel build system, except for the options of the `make` command itself. + +To enhance completion for various variables and targets, the kernel source +includes its own completion script at `scripts/bash-completion/make`. + +This script provides additional completions when working within the kernel tree. +Outside the kernel tree, it defaults to the generic completion rules for the +`make` command. + +Prerequisites +============= + +The script relies on helper functions provided by `bash-completion`_ project. +Please ensure it is installed on your system. On most distributions, you can +install the `bash-completion` package through the standard package manager. + +How to use +========== + +You can source the script directly:: + + $ source scripts/bash-completion/make + +Or, you can copy it into the search path for Bash completion scripts. +For example:: + + $ mkdir -p ~/.local/share/bash-completion/completions + $ cp scripts/bash-completion/make ~/.local/share/bash-completion/completions/ + +Details +======= + +The additional completion for Kbuild is enabled in the following cases: + + - You are in the root directory of the kernel source. + - You are in the top-level build directory created by the O= option + (checked via the `source` symlink pointing to the kernel source). + - The -C make option specifies the kernel source or build directory. + - The -f make option specifies a file in the kernel source or build directory. + +If none of the above are met, it falls back to the generic completion rules. + +The completion supports: + + - Commonly used targets, such as `all`, `menuconfig`, `dtbs`, etc. + - Make (or environment) variables, such as `ARCH`, `LLVM`, etc. + - Single-target builds (`foo/bar/baz.o`) + - Configuration files (`*_defconfig` and `*.config`) + +Some variables offer intelligent behavior. For instance, `CROSS_COMPILE=` +followed by a TAB displays installed toolchains. The list of defconfig files +shown depends on the value of the `ARCH=` variable. + +.. _bash-completion: https://github.com/scop/bash-completion/ diff --git a/Documentation/kbuild/index.rst b/Documentation/kbuild/index.rst index e82af05cd652..3731ab22bfe7 100644 --- a/Documentation/kbuild/index.rst +++ b/Documentation/kbuild/index.rst @@ -23,6 +23,8 @@ Kernel Build System llvm gendwarfksyms + bash-completion + .. only:: subproject and html Indices diff --git a/MAINTAINERS b/MAINTAINERS index ed7aa6867674..e4849f6ebc98 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12566,6 +12566,7 @@ F: Makefile F: scripts/*vmlinux* F: scripts/Kbuild* F: scripts/Makefile* +F: scripts/bash-completion/ F: scripts/basic/ F: scripts/clang-tools/ F: scripts/dummy-tools/ diff --git a/scripts/bash-completion/make b/scripts/bash-completion/make new file mode 100644 index 000000000000..42e8dcead25a --- /dev/null +++ b/scripts/bash-completion/make @@ -0,0 +1,451 @@ +# SPDX-License-Identifier: GPL-2.0-only +# bash completion for GNU make with kbuild extension -*- shell-script -*- + +# Load the default completion script for make. It is typically located at +# /usr/share/bash-completion/completions/make, but we do not rely on it. +__kbuild_load_default_make_completion() +{ + local -a dirs=("${BASH_COMPLETION_USER_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion}/completions") + local ifs=$IFS IFS=: dir compfile this_dir + + for dir in ${XDG_DATA_DIRS:-/usr/local/share:/usr/share}; do + dirs+=("$dir"/bash-completion/completions) + done + IFS=$ifs + + this_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" + + for dir in "${dirs[@]}"; do + if [[ ! -d ${dir} || ${dir} = "${this_dir}" ]]; then + continue + fi + + for compfile in make make.bash _make; do + compfile=$dir/$compfile + # Avoid trying to source dirs; https://bugzilla.redhat.com/903540 + if [[ -f ${compfile} ]] && . "${compfile}" &>/dev/null; then + + __kbuild_default_make_completion=$( + # shellcheck disable=SC2046 # word splitting is the point here + set -- $(complete -p make) + + while [[ $# -gt 1 && "$1" != -F ]]; do + shift + done + + if [[ "$1" = -F ]]; then + echo "$2" + fi + ) + + return + fi + done + done +} + +__kbuild_load_default_make_completion + +__kbuild_handle_variable() +{ + local var=${1%%=*} + local cur=${cur#"${var}"=} + local srctree=$2 + local keywords=() + + case $var in + ARCH) + # sub-directories under arch/ + keywords+=($(find "${srctree}/arch" -mindepth 1 -maxdepth 1 -type d -printf '%P\n')) + # architectures hard-coded in the top Makefile + keywords+=(i386 x86_64 sparc32 sparc64 parisc64) + ;; + CROSS_COMPILE) + # toolchains with a full path + local cross_compile=() + local c c2 + _filedir + + for c in "${COMPREPLY[@]}"; do + # eval for tilde expansion + # suppress error, as this fails when it contains a space + eval "c2=${c}" 2>/dev/null || continue + if [[ ${c} == *-elfedit && ! -d ${c2} && -x ${c2} ]]; then + cross_compile+=("${c%elfedit}") + fi + done + + # toolchains in the PATH environment + while read -r c; do + if [[ ${c} == *-elfedit ]]; then + keywords+=("${c%elfedit}") + fi + done < <(compgen -c) + + COMPREPLY=() + _filedir -d + + # Add cross_compile directly without passing it to compgen. + # Otherwise, toolchain paths with a tilde do not work. + # e.g.) + # CROSS_COMPILE=~/0day/gcc-14.2.0-nolibc/aarch64-linux/bin/aarch64-linux- + COMPREPLY+=("${cross_compile[@]}") + ;; + LLVM) + # LLVM=1 uses the default 'clang' etc. + keywords+=(1) + + # suffix for a particular version. LLVM=-18 uses 'clang-18' etc. + while read -r c; do + if [[ ${c} == clang-[0-9]* ]]; then + keywords+=("${c#clang}") + fi + done < <(compgen -c) + + # directory path to LLVM toolchains + _filedir -d + ;; + KCONFIG_ALLCONFIG) + # KCONFIG_ALLCONFIG=1 selects the default fragment + keywords+=(1) + # or the path to a fragment file + _filedir + ;; + C | KBUILD_CHECKSRC) + keywords+=(1 2) + ;; + V | KBUILD_VERBOSE) + keywords+=({,1}{,2}) + ;; + W | KBUILD_EXTRA_WARN) + keywords+=({,1}{,2}{,3}{,c}{,e}) + ;; + KBUILD_ABS_SRCTREE | KBUILD_MODPOST_NOFINAL | KBUILD_MODPOST_WARN | \ + CLIPPY | KBUILD_CLIPPY | KCONFIG_NOSILENTUPDATE | \ + KCONFIG_OVERWRITECONFIG | KCONFIG_WARN_UNKNOWN_SYMBOL | \ + KCONFIG_WERROR ) + keywords+=(1) + ;; + INSTALL_MOD_STRIP) + keywords+=(1 --strip-debug --strip-unneeded) + ;; + O | KBUILD_OUTPUT | M | KBUILD_EXTMOD | MO | KBUILD_EXTMOD_OUTPUT | *_PATH) + # variables that take a directory. + _filedir -d + return + ;; + KBUILD_EXTRA_SYMBOL | KBUILD_KCONFIG | KCONFIG_CONFIG) + # variables that take a file. + _filedir + return + esac + + COMPREPLY+=($(compgen -W "${keywords[*]}" -- "${cur}")) +} + +# Check the -C, -f options and 'source' symlink. Return the source tree we are +# working in. +__kbuild_get_srctree() +{ + local words=("$@") + local cwd makef_dir + + # see if a path was specified with -C/--directory + for ((i = 1; i < ${#words[@]}; i++)); do + if [[ ${words[i]} == -@(C|-directory) ]]; then + # eval for tilde expansion. + # suppress error, as this fails when it contains a space + eval "cwd=${words[i + 1]}" 2>/dev/null + break + fi + done + + if [[ -z ${cwd} ]]; then + cwd=. + fi + + # see if a Makefile was specified with -f/--file/--makefile + for ((i = 1; i < ${#words[@]}; i++)); do + if [[ ${words[i]} == -@(f|-?(make)file) ]]; then + # eval for tilde expansion + # suppress error, as this fails when it contains a space + eval "makef_dir=${words[i + 1]%/*}" 2>/dev/null + break + fi + done + + if [ -z "${makef_dir}" ]; then + makef_dir=${cwd} + elif [[ ${makef_dir} != /* ]]; then + makef_dir=${cwd}/${makef_dir} + fi + + # If ${makef_dir} is a build directory created by the O= option, there + # is a symbolic link 'source', which points to the kernel source tree. + if [[ -L ${makef_dir}/source ]]; then + makef_dir=$(readlink "${makef_dir}/source") + fi + + echo "${makef_dir}" +} + +# Get SRCARCH to do a little more clever things +__kbuild_get_srcarch() +{ + local words=("$@") + local arch srcarch uname_m + + # see if ARCH= is explicitly specified + for ((i = 1; i < ${#words[@]}; i++)); do + if [[ ${words[i]} == ARCH=* ]]; then + arch=${words[i]#ARCH=} + break + fi + done + + # If ARCH= is not specified, check the build marchine's architecture + if [[ -z ${arch} ]]; then + uname_m=$(uname -m) + + # shellcheck disable=SC2209 # 'sh' is SuperH, not a shell command + case ${uname_m} in + arm64 | aarch64*) arch=arm64 ;; + arm* | sa110) arch=arm ;; + i?86 | x86_64) arch=x86 ;; + loongarch*) arch=loongarch ;; + mips*) arch=mips ;; + ppc*) arch=powerpc ;; + riscv*) arch=riscv ;; + s390x) arch=s390 ;; + sh[234]*) arch=sh ;; + sun4u) arch=sparc64 ;; + *) arch=${uname_m} ;; + esac + fi + + case ${arch} in + parisc64) srcarch=parisc ;; + sparc32 | sparc64) srcarch=sparc ;; + i386 | x86_64) srcarch=x86 ;; + *) srcarch=${arch} ;; + esac + + echo "$srcarch" +} + +# small Makefile to parse obj-* syntax +__kbuild_tmp_makefile() +{ +cat <<'EOF' +.PHONY: __default +__default: + $(foreach m,$(obj-y) $(obj-m) $(obj-),$(foreach s, -objs -y -m -,$($(m:%.o=%$s))) $(m)) +EOF +echo "include ${1}" +} + +_make_for_kbuild () +{ + # shellcheck disable=SC2034 # these are set by _init_completion + local cur prev words cword split + _init_completion -s || return + + local srctree + srctree=$(__kbuild_get_srctree "${words[@]}") + + # If 'kernel' and 'Documentation' directories are found, we assume this + # is a kernel tree. Otherwise, we fall back to the generic rule provided + # by the bash-completion project. + if [[ ! -d ${srctree}/kernel || ! -d ${srctree}/Documentation ]]; then + if [ -n "${__kbuild_default_make_completion}" ]; then + "${__kbuild_default_make_completion}" "$@" + fi + return + fi + + # make options with a parameter (copied from the bash-completion project) + case ${prev} in + --file | --makefile | --old-file | --assume-old | --what-if | --new-file | \ + --assume-new | -!(-*)[foW]) + _filedir + return + ;; + --include-dir | --directory | -!(-*)[ICm]) + _filedir -d + return + ;; + -!(-*)E) + COMPREPLY=($(compgen -v -- "$cur")) + return + ;; + --eval | -!(-*)[DVx]) + return + ;; + --jobs | -!(-*)j) + COMPREPLY=($(compgen -W "{1..$(($(_ncpus) * 2))}" -- "$cur")) + return + ;; + esac + + local keywords=() + + case ${cur} in + -*) + # make options (copied from the bash-completion project) + local opts + opts="$(_parse_help "$1")" + COMPREPLY=($(compgen -W "${opts:-$(_parse_usage "$1")}" -- "$cur")) + if [[ ${COMPREPLY-} == *= ]]; then + compopt -o nospace + fi + return + ;; + *=*) + __kbuild_handle_variable "${cur}" "${srctree}" + return + ;; + KBUILD_*) + # There are many variables prefixed with 'KBUILD_'. + # Display them only when 'KBUILD_' is entered. + # shellcheck disable=SC2191 # '=' is appended for variables + keywords+=( + KBUILD_{CHECKSRC,EXTMOD,EXTMOD_OUTPUT,OUTPUT,VERBOSE,EXTRA_WARN,CLIPPY}= + KBUILD_BUILD_{USER,HOST,TIMESTAMP}= + KBUILD_MODPOST_{NOFINAL,WARN}= + KBUILD_{ABS_SRCTREE,EXTRA_SYMBOLS,KCONFIG}= + ) + ;; + KCONFIG_*) + # There are many variables prefixed with 'KCONFIG_'. + # Display them only when 'KCONFIG_' is entered. + # shellcheck disable=SC2191 # '=' is appended for variables + keywords+=( + KCONFIG_{CONFIG,ALLCONFIG,NOSILENTUPDATE,OVERWRITECONFIG}= + KCONFIG_{SEED,PROBABILITY}= + KCONFIG_WARN_UNKNOWN_SYMBOL= + KCONFIG_WERROR= + ) + ;; + *) + # By default, hide KBUILD_* and KCONFIG_* variables. + # Instead, display only the prefix parts. + keywords+=(KBUILD_ KCONFIG_) + ;; + esac + + if [[ ${cur} != /* && ${cur} != *//* ]]; then + local dir srcarch kbuild_file tmp + srcarch=$(__kbuild_get_srcarch "${words[@]}") + + # single build + dir=${cur} + while true; do + if [[ ${dir} == */* ]]; then + dir=${dir%/*} + else + dir=. + fi + + # Search for 'Kbuild' or 'Makefile' in the parent + # directories (may not be a direct parent) + if [[ -f ${srctree}/${dir}/Kbuild ]]; then + kbuild_file=${srctree}/${dir}/Kbuild + break + fi + if [[ -f ${srctree}/${dir}/Makefile ]]; then + kbuild_file=${srctree}/${dir}/Makefile + break + fi + + if [[ ${dir} == . ]]; then + break + fi + done + + if [[ -n ${kbuild_file} ]]; then + tmp=($(__kbuild_tmp_makefile "${kbuild_file}" | + SRCARCH=${srcarch} obj=${dir} src=${srctree}/${dir} \ + "${1}" -n -f - 2>/dev/null)) + + # Add $(obj)/ prefix + if [[ ${dir} != . ]]; then + tmp=("${tmp[@]/#/${dir}\/}") + fi + + keywords+=("${tmp[@]}") + fi + + # *_defconfig and *.config files. These might be grouped into + # subdirectories, e.g., arch/powerpc/configs/*/*_defconfig. + if [[ ${cur} == */* ]]; then + dir=${cur%/*} + else + dir=. + fi + + tmp=($(find "${srctree}/arch/${srcarch}/configs/${dir}" \ + "${srctree}/kernel/configs/${dir}" \ + -mindepth 1 -maxdepth 1 -type d -printf '%P/\n' \ + -o -printf '%P\n' 2>/dev/null)) + + if [[ ${dir} != . ]]; then + tmp=("${tmp[@]/#/${dir}\/}") + fi + + keywords+=("${tmp[@]}") + fi + + # shellcheck disable=SC2191 # '=' is appended for variables + keywords+=( + # + # variables (append =) + # + ARCH= + CROSS_COMPILE= + LLVM= + C= M= MO= O= V= W= + INSTALL{,_MOD,_HDR,_DTBS}_PATH= + KERNELRELEASE= + + # + # targets + # + all help + clean mrproper distclean + clang-{tidy,analyzer} compile_commands.json + coccicheck + dtbs{,_check,_install} dt_binding_{check,schemas} + headers{,_install} + vmlinux install + modules{,_prepare,_install,_sign} + vdso_install + tags TAGS cscope gtags + rust{available,fmt,fmtcheck} + kernel{version,release} image_name + kselftest{,-all,-install,-clean,-merge} + + # configuration + {,old,olddef,sync,def,savedef,rand,listnew,helpnew,test,tiny}config + {,build_}{menu,n,g,x}config + local{mod,yes}config + all{no,yes,mod,def}config + {yes2mod,mod2yes,mod2no}config + + # docs + {html,textinfo,info,latex,pdf,epub,xml,linkcheck,refcheck,clean}docs + + # package + {,bin,src}{rpm,deb}-pkg + {pacman,dir,tar}-pkg + tar{,gz,bz2,xz,zst}-pkg + perf-tar{,gz,bz2,xz,zst}-src-pkg + ) + + COMPREPLY=($(compgen -W "${keywords[*]}" -- "${cur}")) + + # Do not append a space for variables, subdirs, "KBUILD_", "KCONFIG_". + if [[ ${COMPREPLY-} == *[=/] || ${COMPREPLY-} =~ ^(KBUILD|KCONFIG)_$ ]]; then + compopt -o nospace + fi + +} && complete -F _make_for_kbuild make From 87bb368d0637c466a8a77433837056f981d01991 Mon Sep 17 00:00:00 2001 From: Kris Van Hees Date: Fri, 7 Mar 2025 11:53:28 -0500 Subject: [PATCH 20/40] kbuild: exclude .rodata.(cst|str)* when building ranges The .rodata.(cst|str)* sections are often resized during the final linking and since these sections do not cover actual symbols there is no need to include them in the modules.builtin.ranges data. When these sections were included in processing and resizing occurred, modules were reported with ranges that extended beyond their true end, causing subsequent symbols (in address order) to be associated with the wrong module. Fixes: 5f5e7344322f ("kbuild: generate offset range data for builtin modules") Cc: stable@vger.kernel.org Signed-off-by: Kris Van Hees Reviewed-by: Jack Vogel Signed-off-by: Masahiro Yamada --- scripts/generate_builtin_ranges.awk | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/generate_builtin_ranges.awk b/scripts/generate_builtin_ranges.awk index b9ec761b3bef..d4bd5c2b998c 100755 --- a/scripts/generate_builtin_ranges.awk +++ b/scripts/generate_builtin_ranges.awk @@ -282,6 +282,11 @@ ARGIND == 2 && !anchor && NF == 2 && $1 ~ /^0x/ && $2 !~ /^0x/ { # section. # ARGIND == 2 && sect && NF == 4 && /^ [^ \*]/ && !($1 in sect_addend) { + # There are a few sections with constant data (without symbols) that + # can get resized during linking, so it is best to ignore them. + if ($1 ~ /^\.rodata\.(cst|str)[0-9]/) + next; + if (!($1 in sect_base)) { sect_base[$1] = base; From 479fde496586efa1105496c536c4c65bed43fe2b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 3 Mar 2025 01:42:54 +0900 Subject: [PATCH 21/40] Revert "kheaders: Ignore silly-rename files" This reverts commit 973b710b8821c3401ad7a25360c89e94b26884ac. As I mentioned in the review [1], I do not believe this was the correct fix. Commit 41a00051283e ("kheaders: prevent `find` from seeing perl temp files") addressed the root cause of the issue. I asked David to test it but received no response. Commit 973b710b8821 ("kheaders: Ignore silly-rename files") merely worked around the issue by excluding such files, rather than preventing their creation. I have reverted the latter commit, hoping the issue has already been resolved by the former. If the silly-rename files come back, I will restore this change (or preferably, investigate the root cause). [1]: https://lore.kernel.org/lkml/CAK7LNAQndCMudAtVRAbfSfnV+XhSMDcnP-s1_GAQh8UiEdLBSg@mail.gmail.com/ Signed-off-by: Masahiro Yamada --- kernel/gen_kheaders.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/gen_kheaders.sh b/kernel/gen_kheaders.sh index 00529c81cc40..c9e5dc068e85 100755 --- a/kernel/gen_kheaders.sh +++ b/kernel/gen_kheaders.sh @@ -89,7 +89,6 @@ rm -f "${tmpdir}.contents.txt" # Create archive and try to normalize metadata for reproducibility. tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \ - --exclude=".__afs*" --exclude=".nfs*" \ --owner=0 --group=0 --sort=name --numeric-owner --mode=u=rw,go=r,a+X \ -I $XZ -cf $tarfile -C "${tmpdir}/" . > /dev/null From ba4d705046fb568bad4aeffeb79db78d4e835a1f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 13 Mar 2025 19:26:03 +0900 Subject: [PATCH 22/40] kbuild: do not generate .tmp_vmlinux*.map when CONFIG_VMLINUX_MAP=y Commit 5cc124720461 ("kbuild: add CONFIG_VMLINUX_MAP expert option") mentioned that "the .map file can be rather large (several MB), and that's a waste of space when one isn't interested in these things." If that is the case, generating map files for the intermediate tmp_vmlinux* files is also a waste of space. It is unlikely that anyone would be interested in the .tmp_vmlinux*.map files. This commit stops passing the -Map= option when linking the .tmp_vmlinux* intermediates. I also hard-coded the file name 'vmlinux.map' instead of ${output}.map because a later commit will introduce vmlinux.unstripped but I want to keep the current name of the map file. Signed-off-by: Masahiro Yamada Acked-by: Ard Biesheuvel --- scripts/link-vmlinux.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 56a077d204cf..96ae0bb65308 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -97,8 +97,8 @@ vmlinux_link() ldflags="${ldflags} ${wl}--strip-debug" fi - if is_enabled CONFIG_VMLINUX_MAP; then - ldflags="${ldflags} ${wl}-Map=${output}.map" + if [ -n "${generate_map}" ]; then + ldflags="${ldflags} ${wl}-Map=vmlinux.map" fi ${ld} ${ldflags} -o ${output} \ @@ -210,6 +210,7 @@ fi btf_vmlinux_bin_o= kallsymso= strip_debug= +generate_map= if is_enabled CONFIG_KALLSYMS; then true > .tmp_vmlinux0.syms @@ -278,6 +279,10 @@ fi strip_debug= +if is_enabled CONFIG_VMLINUX_MAP; then + generate_map=1 +fi + vmlinux_link vmlinux # fill in BTF IDs From e22bbb8e97846bfb5a6942a2322f0237ff13df0f Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 11 Mar 2025 12:06:18 +0100 Subject: [PATCH 23/40] kbuild: link-vmlinux.sh: Make output file name configurable In order to introduce an intermediate, non-stripped vmlinux build that can be used by other build steps as an input, pass the output file name to link-vmlinux.sh via its command line. Signed-off-by: Ard Biesheuvel Signed-off-by: Masahiro Yamada --- scripts/Makefile.vmlinux | 2 +- scripts/link-vmlinux.sh | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index fb79fd6b2465..487f0bf716ad 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -69,7 +69,7 @@ ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) # Final link of vmlinux with optional arch pass after final link cmd_link_vmlinux = \ - $< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)"; \ + $< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)" "$@"; \ $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) targets += vmlinux diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 96ae0bb65308..b3d928925598 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -31,6 +31,7 @@ set -e LD="$1" KBUILD_LDFLAGS="$2" LDFLAGS_vmlinux="$3" +VMLINUX="$4" is_enabled() { grep -q "^$1=y" include/config/auto.conf @@ -283,23 +284,23 @@ if is_enabled CONFIG_VMLINUX_MAP; then generate_map=1 fi -vmlinux_link vmlinux +vmlinux_link "${VMLINUX}" # fill in BTF IDs if is_enabled CONFIG_DEBUG_INFO_BTF; then - info BTFIDS vmlinux + info BTFIDS "${VMLINUX}" RESOLVE_BTFIDS_ARGS="" if is_enabled CONFIG_WERROR; then RESOLVE_BTFIDS_ARGS=" --fatal_warnings " fi - ${RESOLVE_BTFIDS} ${RESOLVE_BTFIDS_ARGS} vmlinux + ${RESOLVE_BTFIDS} ${RESOLVE_BTFIDS_ARGS} "${VMLINUX}" fi -mksysmap vmlinux System.map +mksysmap "${VMLINUX}" System.map if is_enabled CONFIG_BUILDTIME_TABLE_SORT; then - info SORTTAB vmlinux - if ! sorttable vmlinux; then + info SORTTAB "${VMLINUX}" + if ! sorttable "${VMLINUX}"; then echo >&2 Failed to sort kernel tables exit 1 fi @@ -315,4 +316,4 @@ if is_enabled CONFIG_KALLSYMS; then fi # For fixdep -echo "vmlinux: $0" > .vmlinux.d +echo "${VMLINUX}: $0" > ".${VMLINUX}.d" From 9b400d17259b70d1d68585028e96b30152d0796a Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 11 Mar 2025 12:06:19 +0100 Subject: [PATCH 24/40] kbuild: Introduce Kconfig symbol for linking vmlinux with relocations Some architectures build vmlinux with static relocations preserved, but strip them again from the final vmlinux image. Arch specific tools consume these static relocations in order to construct relocation tables for KASLR. The fact that vmlinux is created, consumed and subsequently updated goes against the typical, declarative paradigm used by Make, which is based on rules and dependencies. So as a first step towards cleaning this up, introduce a Kconfig symbol to declare that the arch wants to consume the static relocations emitted into vmlinux. This will be wired up further in subsequent patches. Signed-off-by: Ard Biesheuvel Signed-off-by: Masahiro Yamada --- Makefile | 4 ++++ arch/Kconfig | 7 +++++++ arch/mips/Kconfig | 1 + arch/mips/Makefile | 4 ---- arch/riscv/Kconfig | 1 + arch/riscv/Makefile | 2 +- arch/s390/Kconfig | 1 + arch/s390/Makefile | 2 +- arch/x86/Kconfig | 1 + arch/x86/Makefile | 6 ------ 10 files changed, 17 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 30242e731a0d..0904b73872cb 100644 --- a/Makefile +++ b/Makefile @@ -1120,6 +1120,10 @@ ifdef CONFIG_LD_ORPHAN_WARN LDFLAGS_vmlinux += --orphan-handling=$(CONFIG_LD_ORPHAN_WARN_LEVEL) endif +ifneq ($(CONFIG_ARCH_VMLINUX_NEEDS_RELOCS),) +LDFLAGS_vmlinux += --emit-relocs --discard-none +endif + # Align the bit size of userspace programs with the kernel KBUILD_USERCFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS)) KBUILD_USERLDFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS)) diff --git a/arch/Kconfig b/arch/Kconfig index b8a4ff365582..101a13fcde8e 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -1695,6 +1695,13 @@ config ARCH_HAS_KERNEL_FPU_SUPPORT Architectures that select this option can run floating-point code in the kernel, as described in Documentation/core-api/floating-point.rst. +config ARCH_VMLINUX_NEEDS_RELOCS + bool + help + Whether the architecture needs vmlinux to be built with static + relocations preserved. This is used by some architectures to + construct bespoke relocation tables for KASLR. + source "kernel/gcov/Kconfig" source "scripts/gcc-plugins/Kconfig" diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 1924f2d83932..5aedbd7afadb 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -2617,6 +2617,7 @@ config RELOCATABLE CPU_MIPS32_R6 || CPU_MIPS64_R6 || \ CPU_P5600 || CAVIUM_OCTEON_SOC || \ CPU_LOONGSON64 + select ARCH_VMLINUX_NEEDS_RELOCS help This builds a kernel image that retains relocation information so it can be loaded someplace besides the default 1MB. diff --git a/arch/mips/Makefile b/arch/mips/Makefile index be8cb44a89fd..d9057e29bc62 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -100,10 +100,6 @@ LDFLAGS_vmlinux += -G 0 -static -n -nostdlib KBUILD_AFLAGS_MODULE += -mlong-calls KBUILD_CFLAGS_MODULE += -mlong-calls -ifeq ($(CONFIG_RELOCATABLE),y) -LDFLAGS_vmlinux += --emit-relocs -endif - cflags-y += -ffreestanding cflags-$(CONFIG_CPU_BIG_ENDIAN) += -EB diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 7612c52e9b1e..6f5800114416 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -1077,6 +1077,7 @@ config RELOCATABLE bool "Build a relocatable kernel" depends on MMU && 64BIT && !XIP_KERNEL select MODULE_SECTIONS if MODULES + select ARCH_VMLINUX_NEEDS_RELOCS help This builds a kernel as a Position Independent Executable (PIE), which retains all relocation metadata required to relocate the diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 13fbc0f94238..6ef0d10e0c50 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -8,7 +8,7 @@ LDFLAGS_vmlinux := -z norelro ifeq ($(CONFIG_RELOCATABLE),y) - LDFLAGS_vmlinux += -shared -Bsymbolic -z notext --emit-relocs + LDFLAGS_vmlinux += -shared -Bsymbolic -z notext KBUILD_CFLAGS += -fPIE endif ifeq ($(CONFIG_DYNAMIC_FTRACE),y) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 9c9ec08d78c7..ea67b7317138 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -630,6 +630,7 @@ endchoice config RELOCATABLE def_bool y + select ARCH_VMLINUX_NEEDS_RELOCS help This builds a kernel image that retains relocation information so it can be loaded at an arbitrary address. diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 5fae311203c2..d5f4be440879 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -15,7 +15,7 @@ KBUILD_CFLAGS_MODULE += -fPIC KBUILD_AFLAGS += -m64 KBUILD_CFLAGS += -m64 KBUILD_CFLAGS += -fPIC -LDFLAGS_vmlinux := -no-pie --emit-relocs --discard-none +LDFLAGS_vmlinux := -no-pie extra_tools := relocs aflags_dwarf := -Wa,-gdwarf-2 KBUILD_AFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -D__ASSEMBLY__ diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 0e27ebd7e36a..57fc0e7635c9 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2200,6 +2200,7 @@ config RANDOMIZE_BASE config X86_NEED_RELOCS def_bool y depends on RANDOMIZE_BASE || (X86_32 && RELOCATABLE) + select ARCH_VMLINUX_NEEDS_RELOCS config PHYSICAL_ALIGN hex "Alignment value to which kernel should be aligned" diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 5b773b34768d..f65ed6dcd6fb 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -251,12 +251,6 @@ endif KBUILD_LDFLAGS += -m elf_$(UTS_MACHINE) -ifdef CONFIG_X86_NEED_RELOCS -LDFLAGS_vmlinux := --emit-relocs --discard-none -else -LDFLAGS_vmlinux := -endif - # # The 64-bit kernel must be aligned to 2MB. Pass -z max-page-size=0x200000 to # the linker to force 2MB page size regardless of the default page size used From ac4f06789b4f9c17357e81e918879c6e2ffdd075 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 11 Mar 2025 12:06:20 +0100 Subject: [PATCH 25/40] kbuild: Create intermediate vmlinux build with relocations preserved The imperative paradigm used to build vmlinux, extract some info from it or perform some checks on it, and subsequently modify it again goes against the declarative paradigm that is usually employed for defining make rules. In particular, the Makefile.postlink files that consume their input via an output rule result in some dodgy logic in the decompressor makefiles for RISC-V and x86, given that the vmlinux.relocs input file needed to generate the arch-specific relocation tables may not exist or be out of date, but cannot be constructed using the ordinary Make dependency based rules, because the info needs to be extracted while vmlinux is in its ephemeral, non-stripped form. So instead, for architectures that require the static relocations that are emitted into vmlinux when passing --emit-relocs to the linker, and are subsequently stripped out again, introduce an intermediate vmlinux target called vmlinux.unstripped, and organize the reset of the build logic accordingly: - vmlinux.unstripped is created only once, and not updated again - build rules under arch/*/boot can depend on vmlinux.unstripped without running the risk of the data disappearing or being out of date - the final vmlinux generated by the build is not bloated with static relocations that are never needed again after the build completes. Signed-off-by: Ard Biesheuvel Signed-off-by: Masahiro Yamada --- .gitignore | 1 + Makefile | 2 +- arch/mips/Makefile.postlink | 2 +- arch/riscv/Makefile.postlink | 11 +---------- arch/riscv/boot/Makefile | 5 +---- arch/s390/Makefile.postlink | 4 +--- arch/x86/Makefile.postlink | 8 +++----- scripts/Makefile.lib | 3 --- scripts/Makefile.vmlinux | 28 +++++++++++++++++++++------- 9 files changed, 30 insertions(+), 34 deletions(-) diff --git a/.gitignore b/.gitignore index 5937c74d3dc1..f2f63e47fb88 100644 --- a/.gitignore +++ b/.gitignore @@ -65,6 +65,7 @@ modules.order /vmlinux.32 /vmlinux.map /vmlinux.symvers +/vmlinux.unstripped /vmlinux-gdb.py /vmlinuz /System.map diff --git a/Makefile b/Makefile index 0904b73872cb..22593a774cf6 100644 --- a/Makefile +++ b/Makefile @@ -1569,7 +1569,7 @@ endif # CONFIG_MODULES # Directories & files removed with 'make clean' CLEAN_FILES += vmlinux.symvers modules-only.symvers \ modules.builtin modules.builtin.modinfo modules.nsdeps \ - modules.builtin.ranges vmlinux.o.map \ + modules.builtin.ranges vmlinux.o.map vmlinux.unstripped \ compile_commands.json rust/test \ rust-project.json .vmlinux.objs .vmlinux.export.c \ .builtin-dtbs-list .builtin-dtb.S diff --git a/arch/mips/Makefile.postlink b/arch/mips/Makefile.postlink index 6cfdc149d3bc..ea0add7d56b2 100644 --- a/arch/mips/Makefile.postlink +++ b/arch/mips/Makefile.postlink @@ -22,7 +22,7 @@ quiet_cmd_relocs = RELOCS $@ # `@true` prevents complaint when there is nothing to be done -vmlinux: FORCE +vmlinux vmlinux.unstripped: FORCE @true ifeq ($(CONFIG_CPU_LOONGSON3_WORKAROUNDS),y) $(call if_changed,ls3_llsc) diff --git a/arch/riscv/Makefile.postlink b/arch/riscv/Makefile.postlink index 6b0580949b6a..0e4cf8ad2f14 100644 --- a/arch/riscv/Makefile.postlink +++ b/arch/riscv/Makefile.postlink @@ -10,26 +10,17 @@ __archpost: -include include/config/auto.conf include $(srctree)/scripts/Kbuild.include -include $(srctree)/scripts/Makefile.lib quiet_cmd_relocs_check = CHKREL $@ cmd_relocs_check = \ $(CONFIG_SHELL) $(srctree)/arch/riscv/tools/relocs_check.sh "$(OBJDUMP)" "$(NM)" "$@" -ifdef CONFIG_RELOCATABLE -quiet_cmd_cp_vmlinux_relocs = CPREL vmlinux.relocs -cmd_cp_vmlinux_relocs = cp vmlinux vmlinux.relocs - -endif - # `@true` prevents complaint when there is nothing to be done -vmlinux: FORCE +vmlinux vmlinux.unstripped: FORCE @true ifdef CONFIG_RELOCATABLE $(call if_changed,relocs_check) - $(call if_changed,cp_vmlinux_relocs) - $(call if_changed,strip_relocs) endif clean: diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile index b25d524ce5eb..bfc3d0b75b9b 100644 --- a/arch/riscv/boot/Makefile +++ b/arch/riscv/boot/Makefile @@ -32,10 +32,7 @@ $(obj)/xipImage: vmlinux FORCE endif ifdef CONFIG_RELOCATABLE -vmlinux.relocs: vmlinux - @ (! [ -f vmlinux.relocs ] && echo "vmlinux.relocs can't be found, please remove vmlinux and try again") || true - -$(obj)/Image: vmlinux.relocs FORCE +$(obj)/Image: vmlinux.unstripped FORCE else $(obj)/Image: vmlinux FORCE endif diff --git a/arch/s390/Makefile.postlink b/arch/s390/Makefile.postlink index 1ae5478cd6ac..c2b737500a91 100644 --- a/arch/s390/Makefile.postlink +++ b/arch/s390/Makefile.postlink @@ -11,7 +11,6 @@ __archpost: -include include/config/auto.conf include $(srctree)/scripts/Kbuild.include -include $(srctree)/scripts/Makefile.lib CMD_RELOCS=arch/s390/tools/relocs OUT_RELOCS = arch/s390/boot @@ -20,9 +19,8 @@ quiet_cmd_relocs = RELOCS $(OUT_RELOCS)/relocs.S mkdir -p $(OUT_RELOCS); \ $(CMD_RELOCS) $@ > $(OUT_RELOCS)/relocs.S -vmlinux: FORCE +vmlinux.unstripped: FORCE $(call cmd,relocs) - $(call cmd,strip_relocs) clean: @rm -f $(OUT_RELOCS)/relocs.S diff --git a/arch/x86/Makefile.postlink b/arch/x86/Makefile.postlink index 8b8a68162c94..445fce66630f 100644 --- a/arch/x86/Makefile.postlink +++ b/arch/x86/Makefile.postlink @@ -11,23 +11,21 @@ __archpost: -include include/config/auto.conf include $(srctree)/scripts/Kbuild.include -include $(srctree)/scripts/Makefile.lib CMD_RELOCS = arch/x86/tools/relocs OUT_RELOCS = arch/x86/boot/compressed -quiet_cmd_relocs = RELOCS $(OUT_RELOCS)/$@.relocs +quiet_cmd_relocs = RELOCS $(OUT_RELOCS)/vmlinux.relocs cmd_relocs = \ mkdir -p $(OUT_RELOCS); \ - $(CMD_RELOCS) $@ > $(OUT_RELOCS)/$@.relocs; \ + $(CMD_RELOCS) $@ > $(OUT_RELOCS)/vmlinux.relocs; \ $(CMD_RELOCS) --abs-relocs $@ # `@true` prevents complaint when there is nothing to be done -vmlinux: FORCE +vmlinux vmlinux.unstripped: FORCE @true ifeq ($(CONFIG_X86_NEED_RELOCS),y) $(call cmd,relocs) - $(call cmd,strip_relocs) endif clean: diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 47f56ef71937..d1856a70c919 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -371,9 +371,6 @@ quiet_cmd_ar = AR $@ quiet_cmd_objcopy = OBJCOPY $@ cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@ -quiet_cmd_strip_relocs = RSTRIP $@ -cmd_strip_relocs = $(OBJCOPY) --remove-section='.rel*' $@ - # Gzip # --------------------------------------------------------------------------- diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index 487f0bf716ad..b0a6cd5b818c 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -9,6 +9,20 @@ include $(srctree)/scripts/Makefile.lib targets := +ifdef CONFIG_ARCH_VMLINUX_NEEDS_RELOCS +vmlinux-final := vmlinux.unstripped + +quiet_cmd_strip_relocs = RSTRIP $@ + cmd_strip_relocs = $(OBJCOPY) --remove-section='.rel*' $< $@ + +vmlinux: $(vmlinux-final) FORCE + $(call if_changed,strip_relocs) + +targets += vmlinux +else +vmlinux-final := vmlinux +endif + %.o: %.c FORCE $(call if_changed_rule,cc_o_c) @@ -47,7 +61,7 @@ targets += .builtin-dtbs-list ifdef CONFIG_GENERIC_BUILTIN_DTB targets += .builtin-dtbs.S .builtin-dtbs.o -vmlinux: .builtin-dtbs.o +$(vmlinux-final): .builtin-dtbs.o endif # vmlinux @@ -55,11 +69,11 @@ endif ifdef CONFIG_MODULES targets += .vmlinux.export.o -vmlinux: .vmlinux.export.o +$(vmlinux-final): .vmlinux.export.o endif ifdef CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX -vmlinux: arch/$(SRCARCH)/tools/vmlinux.arch.o +$(vmlinux-final): arch/$(SRCARCH)/tools/vmlinux.arch.o arch/$(SRCARCH)/tools/vmlinux.arch.o: vmlinux.o FORCE $(Q)$(MAKE) $(build)=arch/$(SRCARCH)/tools $@ @@ -72,11 +86,11 @@ cmd_link_vmlinux = \ $< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)" "$@"; \ $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) -targets += vmlinux -vmlinux: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE +targets += $(vmlinux-final) +$(vmlinux-final): scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE +$(call if_changed_dep,link_vmlinux) ifdef CONFIG_DEBUG_INFO_BTF -vmlinux: $(RESOLVE_BTFIDS) +$(vmlinux-final): $(RESOLVE_BTFIDS) endif ifdef CONFIG_BUILDTIME_TABLE_SORT @@ -96,7 +110,7 @@ modules.builtin.ranges: $(srctree)/scripts/generate_builtin_ranges.awk \ modules.builtin vmlinux.map vmlinux.o.map FORCE $(call if_changed,modules_builtin_ranges) -vmlinux.map: vmlinux +vmlinux.map: $(vmlinux-final) @: endif From e6a03a666995a6b64cd8a28cb5e5b9c6a162444a Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 11 Mar 2025 12:06:21 +0100 Subject: [PATCH 26/40] x86: Get rid of Makefile.postlink Instead of generating the vmlinux.relocs file (needed by the decompressor build to construct the KASLR relocation tables) as a vmlinux postlink step, which is dubious because it depends on data that is stripped from vmlinux before the build completes, generate it from vmlinux.unstripped, which has been introduced specifically for this purpose. This ensures that each artifact is rebuilt as needed, rather than as a side effect of another build rule. This effectively reverts commit 9d9173e9ceb6 ("x86/build: Avoid relocation information in final vmlinux") Signed-off-by: Ard Biesheuvel Signed-off-by: Masahiro Yamada --- arch/x86/Makefile.postlink | 38 ------------------------------- arch/x86/boot/compressed/Makefile | 9 +++++--- 2 files changed, 6 insertions(+), 41 deletions(-) delete mode 100644 arch/x86/Makefile.postlink diff --git a/arch/x86/Makefile.postlink b/arch/x86/Makefile.postlink deleted file mode 100644 index 445fce66630f..000000000000 --- a/arch/x86/Makefile.postlink +++ /dev/null @@ -1,38 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# =========================================================================== -# Post-link x86 pass -# =========================================================================== -# -# 1. Separate relocations from vmlinux into vmlinux.relocs. -# 2. Strip relocations from vmlinux. - -PHONY := __archpost -__archpost: - --include include/config/auto.conf -include $(srctree)/scripts/Kbuild.include - -CMD_RELOCS = arch/x86/tools/relocs -OUT_RELOCS = arch/x86/boot/compressed -quiet_cmd_relocs = RELOCS $(OUT_RELOCS)/vmlinux.relocs - cmd_relocs = \ - mkdir -p $(OUT_RELOCS); \ - $(CMD_RELOCS) $@ > $(OUT_RELOCS)/vmlinux.relocs; \ - $(CMD_RELOCS) --abs-relocs $@ - -# `@true` prevents complaint when there is nothing to be done - -vmlinux vmlinux.unstripped: FORCE - @true -ifeq ($(CONFIG_X86_NEED_RELOCS),y) - $(call cmd,relocs) -endif - -clean: - @rm -f $(OUT_RELOCS)/vmlinux.relocs - -PHONY += FORCE clean - -FORCE: - -.PHONY: $(PHONY) diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 606c74f27459..5edee7a9786c 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -117,9 +117,12 @@ $(obj)/vmlinux.bin: vmlinux FORCE targets += $(patsubst $(obj)/%,%,$(vmlinux-objs-y)) vmlinux.bin.all vmlinux.relocs -# vmlinux.relocs is created by the vmlinux postlink step. -$(obj)/vmlinux.relocs: vmlinux - @true +CMD_RELOCS = arch/x86/tools/relocs +quiet_cmd_relocs = RELOCS $@ + cmd_relocs = $(CMD_RELOCS) $< > $@;$(CMD_RELOCS) --abs-relocs $< + +$(obj)/vmlinux.relocs: vmlinux.unstripped FORCE + $(call if_changed,relocs) vmlinux.bin.all-y := $(obj)/vmlinux.bin vmlinux.bin.all-$(CONFIG_X86_NEED_RELOCS) += $(obj)/vmlinux.relocs From 82e7a5997170f105dc5452f83f349e6e625e61f5 Mon Sep 17 00:00:00 2001 From: Kefan Liu Date: Tue, 11 Mar 2025 23:45:35 +0800 Subject: [PATCH 27/40] Documentation/kbuild: Fix indentation in modules.rst example Correct the indentation in an example within the `modules.rst` file to improve readability. Signed-off-by: Kefan Liu Signed-off-by: Masahiro Yamada --- Documentation/kbuild/modules.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/kbuild/modules.rst b/Documentation/kbuild/modules.rst index a42f00d8cb90..d0703605bfa4 100644 --- a/Documentation/kbuild/modules.rst +++ b/Documentation/kbuild/modules.rst @@ -318,7 +318,7 @@ Several Subdirectories | |__ include | |__ hardwareif.h |__ include - |__ complex.h + |__ complex.h To build the module complex.ko, we then need the following kbuild file:: From 7e752910b8acd1527af34b51851998feb33cc028 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 12 Mar 2025 04:01:33 +0900 Subject: [PATCH 28/40] kbuild: deb-pkg: fix versioning for -rc releases The version number with -rc should be considered older than the final release. For example, 6.14-rc1 should be older than 6.14, but to handle this correctly (just like Debian kernel), "-rc" must be replace with "~rc". $ dpkg --compare-versions 6.14-rc1 lt 6.14 $ echo $? 1 $ dpkg --compare-versions 6.14~rc1 lt 6.14 $ echo $? 0 Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor --- scripts/package/mkdebian | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian index 0178000197fe..07ca3528e8ea 100755 --- a/scripts/package/mkdebian +++ b/scripts/package/mkdebian @@ -161,7 +161,9 @@ version=$KERNELRELEASE if [ "${KDEB_PKGVERSION:+set}" ]; then packageversion=$KDEB_PKGVERSION else - packageversion=$(${srctree}/scripts/setlocalversion --no-local ${srctree})-$($srctree/scripts/build-version) + upstream_version=$("${srctree}/scripts/setlocalversion" --no-local "${srctree}" | sed 's/-\(rc[1-9]\)/~\1/') + debian_revision=$("${srctree}/scripts/build-version") + packageversion=${upstream_version}-${debian_revision} fi sourcename=${KDEB_SOURCENAME:-linux-upstream} From 1c3107ec73921088e55b7ff35861b9303962fd34 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 12 Mar 2025 04:02:24 +0900 Subject: [PATCH 29/40] kbuild: deb-pkg: remove "version" variable in mkdebian ${version} and ${KERNELRELEASE} are the same. Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor --- scripts/package/mkdebian | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian index 07ca3528e8ea..744ddba01d93 100755 --- a/scripts/package/mkdebian +++ b/scripts/package/mkdebian @@ -157,7 +157,6 @@ while [ $# -gt 0 ]; do done # Some variables and settings used throughout the script -version=$KERNELRELEASE if [ "${KDEB_PKGVERSION:+set}" ]; then packageversion=$KDEB_PKGVERSION else @@ -216,11 +215,11 @@ Build-Depends-Arch: bc, bison, flex, python3:native, rsync Homepage: https://www.kernel.org/ -Package: $packagename-$version +Package: $packagename-${KERNELRELEASE} Architecture: $debarch -Description: Linux kernel, version $version +Description: Linux kernel, version ${KERNELRELEASE} This package contains the Linux kernel, modules and corresponding other - files, version: $version. + files, version: ${KERNELRELEASE}. EOF if [ "${SRCARCH}" != um ]; then @@ -239,11 +238,11 @@ EOF if is_enabled CONFIG_MODULES; then cat <> debian/control -Package: linux-headers-$version +Package: linux-headers-${KERNELRELEASE} Architecture: $debarch Build-Profiles: -Description: Linux kernel headers for $version on $debarch - This package provides kernel header files for $version on $debarch +Description: Linux kernel headers for ${KERNELRELEASE} on $debarch + This package provides kernel header files for ${KERNELRELEASE} on $debarch . This is useful for people who need to build external modules EOF @@ -253,11 +252,11 @@ fi if is_enabled CONFIG_DEBUG_INFO; then cat <> debian/control -Package: linux-image-$version-dbg +Package: linux-image-${KERNELRELEASE}-dbg Section: debug Architecture: $debarch Build-Profiles: -Description: Linux kernel debugging symbols for $version +Description: Linux kernel debugging symbols for ${KERNELRELEASE} This package will come in handy if you need to debug the kernel. It provides all the necessary debug symbols for the kernel and its modules. EOF From 00e81f4fc15aff8efef529ce9a4dc020686ab854 Mon Sep 17 00:00:00 2001 From: "Xin Li (Intel)" Date: Tue, 11 Mar 2025 20:34:21 -0700 Subject: [PATCH 30/40] kbuild: Add a help message for "headers" Meanwhile explicitly state that the headers are uapi headers. Suggested-by: Borislav Petkov Signed-off-by: Xin Li (Intel) Signed-off-by: Masahiro Yamada --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 22593a774cf6..5c333682dc91 100644 --- a/Makefile +++ b/Makefile @@ -1672,7 +1672,8 @@ help: @echo ' kernelrelease - Output the release version string (use with make -s)' @echo ' kernelversion - Output the version stored in Makefile (use with make -s)' @echo ' image_name - Output the image name (use with make -s)' - @echo ' headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH'; \ + @echo ' headers - Build ready-to-install UAPI headers in usr/include' + @echo ' headers_install - Install sanitised kernel UAPI headers to INSTALL_HDR_PATH'; \ echo ' (default: $(INSTALL_HDR_PATH))'; \ echo '' @echo 'Static analysers:' From a7a05b1b2739b94870b499818986b82974839fe0 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 14 Mar 2025 18:53:35 +0900 Subject: [PATCH 31/40] kbuild: deb-pkg: add comment about future removal of KDEB_COMPRESS 'man dpkg-deb' describes as follows: DPKG_DEB_COMPRESSOR_TYPE Sets the compressor type to use (since dpkg 1.21.10). The -Z option overrides this value. When commit 1a7f0a34ea7d ("builddeb: allow selection of .deb compressor") was applied, dpkg-deb did not support this environment variable. Later, dpkg commit c10aeffc6d71 ("dpkg-deb: Add support for DPKG_DEB_COMPRESSOR_TYPE/LEVEL") introduced support for DPKG_DEB_COMPRESSOR_TYPE, which provides the same functionality as KDEB_COMPRESS. KDEB_COMPRESS is still useful for users of older dpkg versions, but I would like to remove this redundant functionality in the future. This commit adds comments to notify users of the planned removal and to encourage migration to DPKG_DEB_COMPRESSOR_TYPE where possible. Signed-off-by: Masahiro Yamada --- lib/Kconfig.debug | 6 +++--- scripts/package/debian/rules | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 17ccd913975d..be9f5af4c05c 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -335,12 +335,12 @@ config DEBUG_INFO_COMPRESSED_ZLIB Compress the debug information using zlib. Requires GCC 5.0+ or Clang 5.0+, binutils 2.26+, and zlib. - Users of dpkg-deb via scripts/package/builddeb may find an increase in + Users of dpkg-deb via debian/rules may find an increase in size of their debug .deb packages with this config set, due to the debug info being compressed with zlib, then the object files being recompressed with a different compression scheme. But this is still - preferable to setting $KDEB_COMPRESS to "none" which would be even - larger. + preferable to setting KDEB_COMPRESS or DPKG_DEB_COMPRESSOR_TYPE to + "none" which would be even larger. config DEBUG_INFO_COMPRESSED_ZSTD bool "Compress debugging information with zstd" diff --git a/scripts/package/debian/rules b/scripts/package/debian/rules index ca07243bd5cd..33bfd00974b3 100755 --- a/scripts/package/debian/rules +++ b/scripts/package/debian/rules @@ -41,6 +41,10 @@ package = $($(@:binary-%=%-package)) # which package is being processed in the build log. DH_OPTIONS = -p$(package) +# Note: future removal of KDEB_COMPRESS +# dpkg-deb >= 1.21.10 supports the DPKG_DEB_COMPRESSOR_TYPE environment +# variable, which provides the same functionality as KDEB_COMPRESS. The +# KDEB_COMPRESS variable will be removed in the future. define binary $(Q)dh_testdir $(DH_OPTIONS) $(Q)dh_testroot $(DH_OPTIONS) From 97282e6d380db8a07120fe1b794ac969ee4a3b5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Sat, 22 Mar 2025 10:03:16 +0100 Subject: [PATCH 32/40] x86: drop unnecessary prefix map configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The toplevel Makefile already provides -fmacro-prefix-map as part of KBUILD_CPPFLAGS. In contrast to the KBUILD_CFLAGS and KBUILD_AFLAGS variables, KBUILD_CPPFLAGS is not redefined in the architecture specific Makefiles. Therefore the toplevel KBUILD_CPPFLAGS do apply just fine, to both C and ASM sources. The custom configuration was necessary when it was added in commit 9e2276fa6eb3 ("arch/x86/boot: Use prefix map to avoid embedded paths") but has since become unnecessary in commit a716bd743210 ("kbuild: use -fmacro-prefix-map for .S sources"). Drop the now unnecessary custom prefix map configuration. Signed-off-by: Thomas Weißschuh Signed-off-by: Masahiro Yamada --- arch/x86/boot/Makefile | 1 - arch/x86/boot/compressed/Makefile | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile index 9cc0ff6e9067..75e7a76deee1 100644 --- a/arch/x86/boot/Makefile +++ b/arch/x86/boot/Makefile @@ -54,7 +54,6 @@ targets += cpustr.h KBUILD_CFLAGS := $(REALMODE_CFLAGS) -D_SETUP KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ -KBUILD_CFLAGS += $(call cc-option,-fmacro-prefix-map=$(srctree)/=) KBUILD_CFLAGS += -fno-asynchronous-unwind-tables KBUILD_CFLAGS += $(CONFIG_CC_IMPLICIT_FALLTHROUGH) diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 5edee7a9786c..4d3f714ad871 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -38,7 +38,6 @@ KBUILD_CFLAGS += -fno-stack-protector KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) KBUILD_CFLAGS += $(call cc-disable-warning, gnu) KBUILD_CFLAGS += -Wno-pointer-sign -KBUILD_CFLAGS += $(call cc-option,-fmacro-prefix-map=$(srctree)/=) KBUILD_CFLAGS += -fno-asynchronous-unwind-tables KBUILD_CFLAGS += -D__DISABLE_EXPORTS # Disable relocation relaxation in case the link is not PIE. From cacd22ce69585a91c386243cd662ada962431e63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Sat, 15 Mar 2025 14:20:14 +0100 Subject: [PATCH 33/40] kbuild: make all file references relative to source root MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -fmacro-prefix-map only affects __FILE__ and __BASE_FILE__. Other references, for example in debug information, are not affected. This makes handling of file references in the compiler outputs harder to use and creates problems for reproducible builds. Switch to -ffile-prefix map which affects all references. Also drop the documentation section advising manual specification of -fdebug-prefix-map for reproducible builds, as it is not necessary anymore. Suggested-by: Ben Hutchings Link: https://lore.kernel.org/lkml/c49cc967294f9a3a4a34f69b6a8727a6d3959ed8.camel@decadent.org.uk/ Signed-off-by: Thomas Weißschuh Signed-off-by: Masahiro Yamada --- Documentation/kbuild/reproducible-builds.rst | 17 ----------------- Makefile | 2 +- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/Documentation/kbuild/reproducible-builds.rst b/Documentation/kbuild/reproducible-builds.rst index f2dcc39044e6..a7762486c93f 100644 --- a/Documentation/kbuild/reproducible-builds.rst +++ b/Documentation/kbuild/reproducible-builds.rst @@ -46,21 +46,6 @@ The kernel embeds the building user and host names in `KBUILD_BUILD_USER and KBUILD_BUILD_HOST`_ variables. If you are building from a git commit, you could use its committer address. -Absolute filenames ------------------- - -When the kernel is built out-of-tree, debug information may include -absolute filenames for the source files. This must be overridden by -including the ``-fdebug-prefix-map`` option in the `KCFLAGS`_ variable. - -Depending on the compiler used, the ``__FILE__`` macro may also expand -to an absolute filename in an out-of-tree build. Kbuild automatically -uses the ``-fmacro-prefix-map`` option to prevent this, if it is -supported. - -The Reproducible Builds web site has more information about these -`prefix-map options`_. - Generated files in source packages ---------------------------------- @@ -131,7 +116,5 @@ See ``scripts/setlocalversion`` for details. .. _KBUILD_BUILD_TIMESTAMP: kbuild.html#kbuild-build-timestamp .. _KBUILD_BUILD_USER and KBUILD_BUILD_HOST: kbuild.html#kbuild-build-user-kbuild-build-host -.. _KCFLAGS: kbuild.html#kcflags -.. _prefix-map options: https://reproducible-builds.org/docs/build-path/ .. _Reproducible Builds project: https://reproducible-builds.org/ .. _SOURCE_DATE_EPOCH: https://reproducible-builds.org/docs/source-date-epoch/ diff --git a/Makefile b/Makefile index 5c333682dc91..4f920187cee6 100644 --- a/Makefile +++ b/Makefile @@ -1067,7 +1067,7 @@ endif # change __FILE__ to the relative path to the source directory ifdef building_out_of_srctree -KBUILD_CPPFLAGS += $(call cc-option,-fmacro-prefix-map=$(srcroot)/=) +KBUILD_CPPFLAGS += $(call cc-option,-ffile-prefix-map=$(srcroot)/=) KBUILD_RUSTFLAGS += --remap-path-prefix=$(srcroot)/= endif From 6c6c1fc09de35f409f6971cb9e881103afe5dbe0 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Tue, 11 Mar 2025 12:49:02 -0700 Subject: [PATCH 34/40] modpost: require a MODULE_DESCRIPTION() Since commit 1fffe7a34c89 ("script: modpost: emit a warning when the description is missing"), a module without a MODULE_DESCRIPTION() has resulted in a warning with make W=1. Since that time, all known instances of this issue have been fixed. Therefore, now make it an error if a MODULE_DESCRIPTION() is not present. Signed-off-by: Jeff Johnson Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 7f4c72eca72c..92627e8d0e16 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1602,8 +1602,8 @@ static void read_symbols(const char *modname) namespace); } - if (extra_warn && !get_modinfo(&info, "description")) - warn("missing MODULE_DESCRIPTION() in %s\n", modname); + if (!get_modinfo(&info, "description")) + error("missing MODULE_DESCRIPTION() in %s\n", modname); } for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { From 62604063621fb075c7966286bdddcb057d883fa8 Mon Sep 17 00:00:00 2001 From: Alexandru Gagniuc Date: Fri, 14 Mar 2025 13:10:53 +0000 Subject: [PATCH 35/40] kbuild: deb-pkg: don't set KBUILD_BUILD_VERSION unconditionally In ThinPro, we use the convention +hp for the kernel package. This does not have a dash in the name or version. This is built by editing ".version" before a build, and setting EXTRAVERSION="+hp" and KDEB_PKGVERSION make variables: echo 68 > .version make -j EXTRAVERSION="+hp" bindeb-pkg KDEB_PKGVERSION=6.12.2+hp69 .deb name: linux-image-6.12.2+hp_6.12.2+hp69_amd64.deb Since commit 7d4f07d5cb71 ("kbuild: deb-pkg: squash scripts/package/deb-build-option to debian/rules"), this no longer works. The deb build logic changed, even though, the commit message implies that the logic should be unmodified. Before, KBUILD_BUILD_VERSION was not set if the KDEB_PKGVERSION did not contain a dash. After the change KBUILD_BUILD_VERSION is always set to KDEB_PKGVERSION. Since this determines UTS_VERSION, the uname output to look off: (now) uname -a: version 6.12.2+hp ... #6.12.2+hp69 (expected) uname -a: version 6.12.2+hp ... #69 Update the debian/rules logic to restore the original behavior. Fixes: 7d4f07d5cb71 ("kbuild: deb-pkg: squash scripts/package/deb-build-option to debian/rules") Signed-off-by: Alexandru Gagniuc Reviewed-by: Nicolas Schier Signed-off-by: Masahiro Yamada --- scripts/package/debian/rules | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/package/debian/rules b/scripts/package/debian/rules index 33bfd00974b3..a417a7f8bbc1 100755 --- a/scripts/package/debian/rules +++ b/scripts/package/debian/rules @@ -21,9 +21,11 @@ ifeq ($(origin KBUILD_VERBOSE),undefined) endif endif -revision = $(lastword $(subst -, ,$(shell dpkg-parsechangelog -S Version))) +revision = $(shell dpkg-parsechangelog -S Version | sed -n 's/.*-//p') CROSS_COMPILE ?= $(filter-out $(DEB_BUILD_GNU_TYPE)-, $(DEB_HOST_GNU_TYPE)-) -make-opts = ARCH=$(ARCH) KERNELRELEASE=$(KERNELRELEASE) KBUILD_BUILD_VERSION=$(revision) $(addprefix CROSS_COMPILE=,$(CROSS_COMPILE)) +make-opts = ARCH=$(ARCH) KERNELRELEASE=$(KERNELRELEASE) \ + $(addprefix KBUILD_BUILD_VERSION=,$(revision)) \ + $(addprefix CROSS_COMPILE=,$(CROSS_COMPILE)) binary-targets := $(addprefix binary-, image image-dbg headers libc-dev) From 8bdd53e066012bed431667393676d1b5e8cce153 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 16 Mar 2025 00:15:20 +0900 Subject: [PATCH 36/40] kbuild: pacman-pkg: hardcode module installation path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'make pacman-pkg' for architectures with device tree support (i.e., arm, arm64, etc.) shows logs like follows: Installing dtbs... INSTALL /home/masahiro/linux/pacman/linux-upstream/pkg/linux-upstream/usr//lib/modules/6.14.0-rc6+/dtb/actions/s700-cubieboard7.dtb INSTALL /home/masahiro/linux/pacman/linux-upstream/pkg/linux-upstream/usr//lib/modules/6.14.0-rc6+/dtb/actions/s900-bubblegum-96.dtb INSTALL /home/masahiro/linux/pacman/linux-upstream/pkg/linux-upstream/usr//lib/modules/6.14.0-rc6+/dtb/airoha/en7581-evb.dtb ... The double slashes ('//') between 'usr' and 'lib' are somewhat ugly. Let's hardcode the module installation path because the package contents should remain unaffected even if ${MODLIB} is overridden. Please note that scripts/packages/{builddeb,kernel.spec} also hardcode the module installation path. With this change, the log will look better, as follows: Installing dtbs... INSTALL /home/masahiro/linux/pacman/linux-upstream/pkg/linux-upstream/usr/lib/modules/6.14.0-rc6+/dtb/actions/s700-cubieboard7.dtb INSTALL /home/masahiro/linux/pacman/linux-upstream/pkg/linux-upstream/usr/lib/modules/6.14.0-rc6+/dtb/actions/s900-bubblegum-96.dtb INSTALL /home/masahiro/linux/pacman/linux-upstream/pkg/linux-upstream/usr/lib/modules/6.14.0-rc6+/dtb/airoha/en7581-evb.dtb ... Signed-off-by: Masahiro Yamada Acked-by: Thomas Weißschuh Reviewed-by: Nathan Chancellor --- scripts/package/PKGBUILD | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/package/PKGBUILD b/scripts/package/PKGBUILD index 0cf3a55b05e1..452374d63c24 100644 --- a/scripts/package/PKGBUILD +++ b/scripts/package/PKGBUILD @@ -53,7 +53,7 @@ build() { _package() { pkgdesc="The ${pkgdesc} kernel and modules" - local modulesdir="${pkgdir}/usr/${MODLIB}" + local modulesdir="${pkgdir}/usr/lib/modules/${KERNELRELEASE}" _prologue @@ -81,7 +81,7 @@ _package() { _package-headers() { pkgdesc="Headers and scripts for building modules for the ${pkgdesc} kernel" - local builddir="${pkgdir}/usr/${MODLIB}/build" + local builddir="${pkgdir}/usr/lib/modules/${KERNELRELEASE}/build" _prologue @@ -114,7 +114,7 @@ _package-debug(){ pkgdesc="Non-stripped vmlinux file for the ${pkgdesc} kernel" local debugdir="${pkgdir}/usr/src/debug/${pkgbase}" - local builddir="${pkgdir}/usr/${MODLIB}/build" + local builddir="${pkgdir}/usr/lib/modules/${KERNELRELEASE}/build" _prologue From 2c8725c1dca3de043670b38592b1b43105322496 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Sat, 15 Mar 2025 20:40:45 +0100 Subject: [PATCH 37/40] rust: kbuild: skip `--remap-path-prefix` for `rustdoc` `rustdoc` only recognizes `--remap-path-prefix` starting with Rust 1.81.0, which is later than on minimum, so we cannot pass it unconditionally. Otherwise, we get: error: Unrecognized option: 'remap-path-prefix' Note that `rustc` (the compiler) does recognize the flag since a long time ago (1.26.0). Moreover, `rustdoc` since Rust 1.82.0 ICEs in out-of-tree builds when using `--remap-path-prefix`. The issue has been reduced and reported upstream [1]. Thus workaround both issues by simply skipping the flag when generating the docs -- it is not critical there anyway. The ICE does not reproduce under `--test`, but we still need to skip the flag as well for `RUSTDOC TK` since it is not recognized. Fixes: dbdffaf50ff9 ("kbuild, rust: use -fremap-path-prefix to make paths relative") Link: https://github.com/rust-lang/rust/issues/138520 [1] Signed-off-by: Miguel Ojeda Reviewed-by: Tamir Duberstein Signed-off-by: Masahiro Yamada --- rust/Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rust/Makefile b/rust/Makefile index ea3849eb78f6..089473a89d46 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -57,10 +57,14 @@ endif core-cfgs = \ --cfg no_fp_fmt_parse +# `rustc` recognizes `--remap-path-prefix` since 1.26.0, but `rustdoc` only +# since Rust 1.81.0. Moreover, `rustdoc` ICEs on out-of-tree builds since Rust +# 1.82.0 (https://github.com/rust-lang/rust/issues/138520). Thus workaround both +# issues skipping the flag. The former also applies to `RUSTDOC TK`. quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $< cmd_rustdoc = \ OBJTREE=$(abspath $(objtree)) \ - $(RUSTDOC) $(filter-out $(skip_flags),$(if $(rustdoc_host),$(rust_common_flags),$(rust_flags))) \ + $(RUSTDOC) $(filter-out $(skip_flags) --remap-path-prefix=%,$(if $(rustdoc_host),$(rust_common_flags),$(rust_flags))) \ $(rustc_target_flags) -L$(objtree)/$(obj) \ -Zunstable-options --generate-link-to-definition \ --output $(rustdoc_output) \ @@ -171,7 +175,7 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC TK $< rm -rf $(objtree)/$(obj)/test/doctests/kernel; \ mkdir -p $(objtree)/$(obj)/test/doctests/kernel; \ OBJTREE=$(abspath $(objtree)) \ - $(RUSTDOC) --test $(rust_flags) \ + $(RUSTDOC) --test $(filter-out --remap-path-prefix=%,$(rust_flags)) \ -L$(objtree)/$(obj) --extern ffi --extern kernel \ --extern build_error --extern macros \ --extern bindings --extern uapi \ From 3b8241f64c469e449e862cf2bdc50b879fa18f93 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 22 Dec 2024 09:30:53 +0900 Subject: [PATCH 38/40] nios2: migrate to the generic rule for built-in DTB Commit 654102df2ac2 ("kbuild: add generic support for built-in boot DTBs") introduced generic support for built-in DTBs. Select GENERIC_BUILTIN_DTB when built-in DTB support is enabled. To keep consistency across architectures, this commit also renames CONFIG_NIOS2_DTB_SOURCE_BOOL to CONFIG_BUILTIN_DTB, and CONFIG_NIOS2_DTB_SOURCE to CONFIG_BUILTIN_DTB_NAME. Signed-off-by: Masahiro Yamada --- arch/nios2/Kbuild | 2 +- arch/nios2/boot/dts/Makefile | 4 ++-- arch/nios2/kernel/prom.c | 2 +- arch/nios2/platform/Kconfig.platform | 11 ++++++----- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/arch/nios2/Kbuild b/arch/nios2/Kbuild index fc2952edd2de..fa64c5954b20 100644 --- a/arch/nios2/Kbuild +++ b/arch/nios2/Kbuild @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-y += kernel/ mm/ platform/ boot/dts/ +obj-y += kernel/ mm/ platform/ # for cleaning subdir- += boot diff --git a/arch/nios2/boot/dts/Makefile b/arch/nios2/boot/dts/Makefile index 1a2e8996bec7..1b8f41c4154f 100644 --- a/arch/nios2/boot/dts/Makefile +++ b/arch/nios2/boot/dts/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -obj-y := $(patsubst %.dts,%.dtb.o,$(CONFIG_NIOS2_DTB_SOURCE)) +dtb-y := $(addsuffix .dtb, $(CONFIG_BUILTIN_DTB_NAME)) -dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(src)/%.dts,%.dtb, $(wildcard $(src)/*.dts)) +dtb-$(CONFIG_OF_ALL_DTBS) += $(patsubst $(src)/%.dts,%.dtb, $(wildcard $(src)/*.dts)) diff --git a/arch/nios2/kernel/prom.c b/arch/nios2/kernel/prom.c index db049249766f..4f8c14da6490 100644 --- a/arch/nios2/kernel/prom.c +++ b/arch/nios2/kernel/prom.c @@ -32,7 +32,7 @@ void __init early_init_devtree(void *params) } #endif -#ifdef CONFIG_NIOS2_DTB_SOURCE_BOOL +#ifdef CONFIG_BUILTIN_DTB if (be32_to_cpu((__be32) *dtb) == OF_DT_HEADER) params = (void *)__dtb_start; #endif diff --git a/arch/nios2/platform/Kconfig.platform b/arch/nios2/platform/Kconfig.platform index e849daff6fd1..c75cadd92388 100644 --- a/arch/nios2/platform/Kconfig.platform +++ b/arch/nios2/platform/Kconfig.platform @@ -35,19 +35,20 @@ config NIOS2_DTB_PHYS_ADDR help Physical address of a dtb blob. -config NIOS2_DTB_SOURCE_BOOL +config BUILTIN_DTB bool "Compile and link device tree into kernel image" depends on !COMPILE_TEST + select GENERIC_BUILTIN_DTB help This allows you to specify a dts (device tree source) file which will be compiled and linked into the kernel image. -config NIOS2_DTB_SOURCE - string "Device tree source file" - depends on NIOS2_DTB_SOURCE_BOOL +config BUILTIN_DTB_NAME + string "Built-in device tree name" + depends on BUILTIN_DTB default "" help - Absolute path to the device tree source (dts) file describing your + Relative path to the device tree without suffix describing your system. comment "Nios II instructions" From a26fe287eed112b4e21e854f173c8918a6a8596d Mon Sep 17 00:00:00 2001 From: Daniel Gomez Date: Fri, 28 Mar 2025 14:28:37 +0000 Subject: [PATCH 39/40] kconfig: merge_config: use an empty file as initfile The scripts/kconfig/merge_config.sh script requires an existing $INITFILE (or the $1 argument) as a base file for merging Kconfig fragments. However, an empty $INITFILE can serve as an initial starting point, later referenced by the KCONFIG_ALLCONFIG Makefile variable if -m is not used. This variable can point to any configuration file containing preset config symbols (the merged output) as stated in Documentation/kbuild/kconfig.rst. When -m is used $INITFILE will contain just the merge output requiring the user to run make (i.e. KCONFIG_ALLCONFIG=<$INITFILE> make or make olddefconfig). Instead of failing when `$INITFILE` is missing, create an empty file and use it as the starting point for merges. Signed-off-by: Daniel Gomez Signed-off-by: Masahiro Yamada --- scripts/kconfig/merge_config.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh index 0b7952471c18..79c09b378be8 100755 --- a/scripts/kconfig/merge_config.sh +++ b/scripts/kconfig/merge_config.sh @@ -112,8 +112,8 @@ INITFILE=$1 shift; if [ ! -r "$INITFILE" ]; then - echo "The base file '$INITFILE' does not exist. Exit." >&2 - exit 1 + echo "The base file '$INITFILE' does not exist. Creating one..." >&2 + touch "$INITFILE" fi MERGE_LIST=$* From a7c699d090a1f3795c3271c2b399230e182db06e Mon Sep 17 00:00:00 2001 From: Uday Shankar Date: Mon, 31 Mar 2025 16:46:32 -0600 Subject: [PATCH 40/40] kbuild: rpm-pkg: build a debuginfo RPM The rpm-pkg make target currently suffers from a few issues related to debuginfo: 1. debuginfo for things built into the kernel (vmlinux) is not available in any RPM produced by make rpm-pkg. This makes using tools like systemtap against a make rpm-pkg kernel impossible. 2. debug source for the kernel is not available. This means that commands like 'disas /s' in gdb, which display source intermixed with assembly, can only print file names/line numbers which then must be painstakingly resolved to actual source in a separate editor. 3. debuginfo for modules is available, but it remains bundled with the .ko files that contain module code, in the main kernel RPM. This is a waste of space for users who do not need to debug the kernel (i.e. most users). Address all of these issues by additionally building a debuginfo RPM when the kernel configuration allows for it, in line with standard patterns followed by RPM distributors. With these changes: 1. systemtap now works (when these changes are backported to 6.11, since systemtap lags a bit behind in compatibility), as verified by the following simple test script: # stap -e 'probe kernel.function("do_sys_open").call { printf("%s\n", $$parms); }' dfd=0xffffffffffffff9c filename=0x7fe18800b160 flags=0x88800 mode=0x0 ... 2. disas /s works correctly in gdb, with source and disassembly interspersed: # gdb vmlinux --batch -ex 'disas /s blk_op_str' Dump of assembler code for function blk_op_str: block/blk-core.c: 125 { 0xffffffff814c8740 <+0>: endbr64 127 128 if (op < ARRAY_SIZE(blk_op_name) && blk_op_name[op]) 0xffffffff814c8744 <+4>: mov $0xffffffff824a7378,%rax 0xffffffff814c874b <+11>: cmp $0x23,%edi 0xffffffff814c874e <+14>: ja 0xffffffff814c8768 0xffffffff814c8750 <+16>: mov %edi,%edi 126 const char *op_str = "UNKNOWN"; 0xffffffff814c8752 <+18>: mov $0xffffffff824a7378,%rdx 127 128 if (op < ARRAY_SIZE(blk_op_name) && blk_op_name[op]) 0xffffffff814c8759 <+25>: mov -0x7dfa0160(,%rdi,8),%rax 126 const char *op_str = "UNKNOWN"; 0xffffffff814c8761 <+33>: test %rax,%rax 0xffffffff814c8764 <+36>: cmove %rdx,%rax 129 op_str = blk_op_name[op]; 130 131 return op_str; 132 } 0xffffffff814c8768 <+40>: jmp 0xffffffff81d01360 <__x86_return_thunk> End of assembler dump. 3. The size of the main kernel package goes down substantially, especially if many modules are built (quite typical). Here is a comparison of installed size of the kernel package (configured with allmodconfig, dwarf4 debuginfo, and module compression turned off) before and after this patch: # rpm -qi kernel-6.13* | grep -E '^(Version|Size)' Version : 6.13.0postpatch+ Size : 1382874089 Version : 6.13.0prepatch+ Size : 17870795887 This is a ~92% size reduction. Note that a debuginfo package can only be produced if the following configs are set: - CONFIG_DEBUG_INFO=y - CONFIG_MODULE_COMPRESS=n - CONFIG_DEBUG_INFO_SPLIT=n The first of these is obvious - we can't produce debuginfo if the build does not generate it. The second two requirements can in principle be removed, but doing so is difficult with the current approach, which uses a generic rpmbuild script find-debuginfo.sh that processes all packaged executables. If we want to remove those requirements the best path forward is likely to add some debuginfo extraction/installation logic to the modules_install target (controllable by flags). That way, it's easier to operate on modules before they're compressed, and the logic can be reused by all packaging targets. Signed-off-by: Uday Shankar Signed-off-by: Masahiro Yamada --- scripts/package/kernel.spec | 46 +++++++++++++++++++++++++++++++++++-- scripts/package/mkspec | 10 ++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/scripts/package/kernel.spec b/scripts/package/kernel.spec index ac3e5ac01d8a..726f34e11960 100644 --- a/scripts/package/kernel.spec +++ b/scripts/package/kernel.spec @@ -2,8 +2,6 @@ %{!?_arch: %define _arch dummy} %{!?make: %define make make} %define makeflags %{?_smp_mflags} ARCH=%{ARCH} -%define __spec_install_post /usr/lib/rpm/brp-compress || : -%define debug_package %{nil} Name: kernel Summary: The Linux Kernel @@ -46,6 +44,36 @@ This package provides kernel headers and makefiles sufficient to build modules against the %{version} kernel package. %endif +%if %{with_debuginfo} +# list of debuginfo-related options taken from distribution kernel.spec +# files +%undefine _include_minidebuginfo +%undefine _find_debuginfo_dwz_opts +%undefine _unique_build_ids +%undefine _unique_debug_names +%undefine _unique_debug_srcs +%undefine _debugsource_packages +%undefine _debuginfo_subpackages +%global _find_debuginfo_opts -r +%global _missing_build_ids_terminate_build 1 +%global _no_recompute_build_ids 1 +%{debug_package} +%endif +# some (but not all) versions of rpmbuild emit %%debug_package with +# %%install. since we've already emitted it manually, that would cause +# a package redefinition error. ensure that doesn't happen +%define debug_package %{nil} + +# later, we make all modules executable so that find-debuginfo.sh strips +# them up. but they don't actually need to be executable, so remove the +# executable bit, taking care to do it _after_ find-debuginfo.sh has run +%define __spec_install_post \ + %{?__debug_package:%{__debug_install_post}} \ + %{__arch_install_post} \ + %{__os_install_post} \ + find %{buildroot}/lib/modules/%{KERNELRELEASE} -name "*.ko" -type f \\\ + | xargs --no-run-if-empty chmod u-x + %prep %setup -q -n linux cp %{SOURCE1} .config @@ -89,8 +117,22 @@ ln -fns /usr/src/kernels/%{KERNELRELEASE} %{buildroot}/lib/modules/%{KERNELRELEA echo "%exclude /lib/modules/%{KERNELRELEASE}/build" } > %{buildroot}/kernel.list +# make modules executable so that find-debuginfo.sh strips them. this +# will be undone later in %%__spec_install_post +find %{buildroot}/lib/modules/%{KERNELRELEASE} -name "*.ko" -type f \ + | xargs --no-run-if-empty chmod u+x + +%if %{with_debuginfo} +# copying vmlinux directly to the debug directory means it will not get +# stripped (but its source paths will still be collected + fixed up) +mkdir -p %{buildroot}/usr/lib/debug/lib/modules/%{KERNELRELEASE} +cp vmlinux %{buildroot}/usr/lib/debug/lib/modules/%{KERNELRELEASE} +%endif + %clean rm -rf %{buildroot} +rm -f debugfiles.list debuglinks.list debugsourcefiles.list debugsources.list \ + elfbins.list %post if [ -x /usr/bin/kernel-install ]; then diff --git a/scripts/package/mkspec b/scripts/package/mkspec index 4dc1466dfc81..c7375bfc25a9 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -23,6 +23,16 @@ else echo '%define with_devel 0' fi +# debuginfo package generation uses find-debuginfo.sh under the hood, +# which only works on uncompressed modules that contain debuginfo +if grep -q CONFIG_DEBUG_INFO=y include/config/auto.conf && + (! grep -q CONFIG_MODULE_COMPRESS=y include/config/auto.conf) && + (! grep -q CONFIG_DEBUG_INFO_SPLIT=y include/config/auto.conf); then +echo '%define with_debuginfo %{?_without_debuginfo: 0} %{?!_without_debuginfo: 1}' +else +echo '%define with_debuginfo 0' +fi + cat<