Merge tag 'kbuild-7.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kbuild/linux

Pull Kbuild/Kconfig updates from Nicolas Schier:
 "Kbuild updates:

   - Use --force-group-allocation when linking modules

     Have the linker resolve the COMDAT groups and place their members
     as regular sections instead of possibly leaving multiple copies in
     the resulting modules and unnecessary group metadata.

   - UAPI header files: Canonicalize __ASSEMBLER__ / __ASSEMBLY__ mixed
     use to __ASSEMBLER__

     There is an ongoing effort to change __ASSEMBLY__ to __ASSEMBLER__
     treewide. For consistency, UAPI headers are normalised to use
     __ASSEMBLER__ only. Normalisation is done in two subsequent patches
     to simplify a revert in the unexpected case of a regression report.

   - link-vmlinux.sh: Improve detection of third pass requirement

   - modpost: Canonicalize format of warnings and errors

   - Minor changes:
      - Remove srctree path from CHECK output
      - Set the initial value of subdir-rustflags-y
      - Remove broken and unused modules.builtin(.modinfo) targets from
        the top-level Makefile
      - Add symbol size for kallsyms symbols that can change size
      - modpost: Prevent leak when early return no suffix .o in
        read_symbols()
      - scripts/config: Update usage of POSIX sed
      - 'make tags': Add support for rust source files and prevent
        binary files from being analysed
      - Several spelling mistakes and rephrasing

  Kconfig updates:

   - Add Julian Braha as Kconfig reviewer

   - Fix submenu rendering of negative dependencies

   - Minor changes:
      - merge_config.sh: Keep temp file in the output dir
      - Abort rather than loop for ever on EOF"

* tag 'kbuild-7.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kbuild/linux: (23 commits)
  modpost: use mod_warn() and mod_error(), clean up logging
  modpost: add module as parameter to modpost_log()
  kconfig: fix submenu rendering of negative dependencies
  kbuild: link-vmlinux.sh: improve detection of third pass requirement
  kallsyms: add symbol size for kallsyms symbols that can change size
  kbuild: fix modules.builtin(.modinfo) targets in the top-level Makefile
  kbuild: set the initial value of subdir-rustflags-y
  scripts/config: Use in-place editing (-i) in sed portably
  scripts/config: Use POSIX standard ERE (-E) in sed
  modpost: prevent leak when early return no suffix .o in read_symbols()
  usr: Correct a spelling by changing a letter
  fixdep: make gendered language gender-neutral
  kconfig: fix minor typos in comments
  scripts: fix spelling mistakes
  kconfig: abort rather than loop for ever on EOF
  scripts/tags.sh: Add support for rust source files
  scripts/tags.sh: Prevent binary files appearing in cscope.files
  MAINTAINERS: add Julian Braha as Kconfig reviewer
  scripts: headers_install.sh: Normalize __ASSEMBLY__ to __ASSEMBLER__
  scripts: headers_install.sh: Normalize __ASSEMBLER__ to __ASSEMBLY__
  ...
This commit is contained in:
Linus Torvalds
2026-08-18 09:26:31 -07:00
18 changed files with 225 additions and 120 deletions
+3 -2
View File
@@ -28,6 +28,7 @@ ldflags-y :=
subdir-asflags-y :=
subdir-ccflags-y :=
subdir-rustflags-y :=
# Read auto.conf if it exists, otherwise ignore
-include $(objtree)/include/config/auto.conf
@@ -159,10 +160,10 @@ targets += $(targets-for-builtin) $(targets-for-modules)
# Linus' kernel sanity checking tool
ifeq ($(KBUILD_CHECKSRC),1)
quiet_cmd_checksrc = CHECK $<
quiet_cmd_checksrc = CHECK $(patsubst $(srctree)/%,%,$<)
cmd_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $<
else ifeq ($(KBUILD_CHECKSRC),2)
quiet_cmd_force_checksrc = CHECK $<
quiet_cmd_force_checksrc = CHECK $(patsubst $(srctree)/%,%,$<)
cmd_force_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $<
endif
+5 -5
View File
@@ -15,13 +15,13 @@
* gcc produces a very nice and correct list of dependencies which
* tells make when to remake a file.
*
* To use this list as-is however has the drawback that virtually
* However, to use this list as-is has the drawback that virtually
* every file in the kernel includes autoconf.h.
*
* If the user re-runs make *config, autoconf.h will be
* regenerated. make notices that and will rebuild every file which
* includes autoconf.h, i.e. basically all files. This is extremely
* annoying if the user just changed CONFIG_HIS_DRIVER from n to m.
* annoying if the user just changed CONFIG_USER_DRIVER from n to m.
*
* So we play the same trick that "mkdep" played before. We replace
* the dependency on autoconf.h by a dependency on every config
@@ -33,9 +33,9 @@
* which then let make pick up the changes and the files that use
* the config symbols are rebuilt.
*
* So if the user changes his CONFIG_HIS_DRIVER option, only the objects
* which depend on "include/config/HIS_DRIVER" will be rebuilt,
* so most likely only his driver ;-)
* So if the user changes their CONFIG_USER_DRIVER option, only the objects
* which depend on "include/config/USER_DRIVER" will be rebuilt,
* so most likely only the user's driver ;-)
*
* The idea above dates, by the way, back to Michael E Chastain, AFAIK.
*
+24 -20
View File
@@ -38,7 +38,7 @@ commands:
options:
--file config-file .config file to change (default .config)
--keep-case|-k Keep next symbols' case (dont' upper-case it)
--keep-case|-k Keep next symbols' case (don't upper-case it)
$myname doesn't check the validity of the .config file. This is done at next
make time.
@@ -71,48 +71,45 @@ txt_append() {
local anchor="$1"
local insert="$2"
local infile="$3"
local tmpfile="$infile.swp"
# sed append cmd: 'a\' + newline + text + newline
cmd="$(printf "a\\%b$insert" "\n")"
sed -e "/$anchor/$cmd" "$infile" >"$tmpfile"
# replace original file with the edited one
mv "$tmpfile" "$infile"
# We don't really need a backup file, but in-place editing with backup
# skipped is not portable due to different implementations parsing
# arguments in incompatible manners.
# Create a backup file anyway to ensure portability. The file will be
# deleted on exit.
sed -E -i.swp -e "/$anchor/$cmd" "$infile"
SED_EDITED=1
}
txt_subst() {
local before="$1"
local after="$2"
local infile="$3"
local tmpfile="$infile.swp"
sed -e "s$SED_DELIM$before$SED_DELIM$after$SED_DELIM" "$infile" >"$tmpfile"
# replace original file with the edited one
mv "$tmpfile" "$infile"
sed -E -i.swp -e "s$SED_DELIM$before$SED_DELIM$after$SED_DELIM" "$infile"
SED_EDITED=1
}
txt_delete() {
local text="$1"
local infile="$2"
local tmpfile="$infile.swp"
sed -e "/$text/d" "$infile" >"$tmpfile"
# replace original file with the edited one
mv "$tmpfile" "$infile"
sed -E -i.swp -e "/$text/d" "$infile"
SED_EDITED=1
}
set_var() {
local name=$1 new=$2 before=$3
name_re="^($name=|# $name is not set)"
name_re="^($name=.*|# $name is not set)"
before_re="^($before=|# $before is not set)"
if test -n "$before" && grep -Eq "$before_re" "$FN"; then
txt_append "^$before=" "$new" "$FN"
txt_append "^# $before is not set" "$new" "$FN"
txt_append "$before_re" "$new" "$FN"
elif grep -Eq "$name_re" "$FN"; then
txt_subst "^$name=.*" "$new" "$FN"
txt_subst "^# $name is not set" "$new" "$FN"
txt_subst "$name_re" "$new" "$FN"
else
echo "$new" >>"$FN"
fi
@@ -121,10 +118,17 @@ set_var() {
undef_var() {
local name=$1
txt_delete "^$name=" "$FN"
txt_delete "^# $name is not set" "$FN"
txt_delete "^($name=|# $name is not set)" "$FN"
}
SED_EDITED=0
on_exit() {
if [ "$SED_EDITED" -ge 1 ]; then
rm -f "$FN.swp"
fi
}
trap on_exit EXIT
FN=.config
CMDS=()
while [[ $# -gt 0 ]]; do
+1
View File
@@ -36,6 +36,7 @@ sed -E -e '
s/(^|[^a-zA-Z0-9])__packed([^a-zA-Z0-9_]|$)/\1__attribute__((packed))\2/g
s/(^|[[:space:](])(inline|asm|volatile)([[:space:](]|$)/\1__\2__\3/g
s@#(ifndef|define|endif[[:space:]]*/[*])[[:space:]]*_UAPI@#\1 @
s/__ASSEMBLY__/__ASSEMBLER__/g
' $INFILE > $TMPFILE || exit 1
scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__ $TMPFILE > $OUTFILE
+4
View File
@@ -398,11 +398,13 @@ static void write_src(void)
strcpy((char *)table[i]->sym, buf);
printf("\t/* %s */\n", table[i]->sym);
}
printf(".size kallsyms_names, . - kallsyms_names\n");
printf("\n");
output_label("kallsyms_markers");
for (i = 0; i < markers_cnt; i++)
printf("\t.long\t%u\n", markers[i]);
printf(".size kallsyms_markers, . - kallsyms_markers\n");
printf("\n");
free(markers);
@@ -415,6 +417,7 @@ static void write_src(void)
printf("\t.asciz\t\"%s\"\n", buf);
off += strlen(buf) + 1;
}
printf(".size kallsyms_token_table, . - kallsyms_token_table\n");
printf("\n");
output_label("kallsyms_token_index");
@@ -441,6 +444,7 @@ static void write_src(void)
(unsigned int)table[i]->addr, table[i]->sym);
}
}
printf(".size kallsyms_offsets, . - kallsyms_offsets\n");
printf("\n");
sort_symbols_by_name();
+17
View File
@@ -348,6 +348,23 @@ static int conf_string(struct menu *menu)
}
if (def && sym_set_string_value(sym, def))
return 0;
/*
* A new int or hex symbol whose default fails validation
* cannot be set from an empty answer. When standard input is
* exhausted, as it is for a non-interactive oldconfig or
* syncconfig, re-asking would loop forever and grow the output
* until it exhausts memory. Stop with an error that names the
* symbol instead. String symbols accept any text, and bool and
* tristate symbols (conf_sym()) and choices (conf_choice())
* accept the default on an empty line, so they are unaffected.
*/
if (feof(stdin)) {
fprintf(stderr,
"\nerror: no value for new symbol '%s' at end of input\n",
sym->name);
exit(1);
}
}
}
+33
View File
@@ -738,6 +738,39 @@ bool expr_contains_symbol(struct expr *dep, struct symbol *sym)
return false;
}
/*
* Check if the expression references 'sym' in a way that is satisfiable
* with 'sym' disabled, e.g.'sym!=y'.
*
* Expects that expr_transform() was already called on 'expr'.
*/
bool expr_contains_symbol_negated(struct expr *dep, struct symbol *sym)
{
if (!dep)
return false;
switch (dep->type) {
case E_AND:
case E_OR:
return expr_contains_symbol_negated(dep->left.expr, sym) ||
expr_contains_symbol_negated(dep->right.expr, sym);
case E_NOT:
return dep->left.expr->type == E_SYMBOL &&
dep->left.expr->left.sym == sym;
case E_EQUAL:
/* sym=n */
return dep->left.sym == sym && dep->right.sym == &symbol_no;
case E_UNEQUAL:
/* sym!=y, sym!=m */
return dep->left.sym == sym &&
(dep->right.sym == &symbol_yes ||
dep->right.sym == &symbol_mod);
default:
break;
}
return false;
}
bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
{
if (!dep)
+3 -2
View File
@@ -38,7 +38,7 @@ union expr_data {
* struct expr - expression
*
* @node: link node for the hash table
* @type: expressoin type
* @type: expression type
* @val: calculated tristate value
* @val_is_valid: indicate whether the value is valid
* @left: left node
@@ -160,7 +160,7 @@ struct symbol {
#define SYMBOL_MAXLENGTH 256
/* A property represent the config options that can be associated
/* A property represents the config options that can be associated
* with a config "symbol".
* Sample:
* config FOO
@@ -307,6 +307,7 @@ tristate expr_calc_value(struct expr *e);
struct expr *expr_eliminate_dups(struct expr *e);
struct expr *expr_transform(struct expr *e);
bool expr_contains_symbol(struct expr *dep, struct symbol *sym);
bool expr_contains_symbol_negated(struct expr *dep, struct symbol *sym);
bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
+10
View File
@@ -428,9 +428,19 @@ static void _menu_finalize(struct menu *parent, bool inside_choice)
if (!expr_contains_symbol(dep, sym))
/* No dependency, quit */
break;
/*
* Note that it's actually possible to depend on both
* 'SYM!=y' and 'SYM=y', so we need to first check if
* it's a positive dependency before checking if it's
* a negative dependency. See example:
* 'SFC && MTD && !(SFC=y && MTD=m)'
*/
if (expr_depends_symbol(dep, sym))
/* Absolute dependency, put in submenu */
goto next;
if (expr_contains_symbol_negated(dep, sym))
/* Negative dependency, quit */
break;
/*
* Also consider it a dependency on sym if our
+1 -1
View File
@@ -122,7 +122,7 @@ fi
MERGE_LIST=$*
TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX)
TMP_FILE=$(mktemp --tmpdir="$OUTPUT" .tmp.config.XXXXXXXXXX)
echo "Using $INITFILE as base"
+20 -2
View File
@@ -38,7 +38,7 @@ is_enabled() {
}
# Nice output in kbuild format
# Will be supressed by "make -s"
# Will be suppressed by "make -s"
info()
{
printf " %-7s %s\n" "${1}" "${2}"
@@ -106,6 +106,18 @@ vmlinux_link()
${kallsymso} ${btf_vmlinux_bin_o} ${arch_vmlinux_o} ${ldlibs}
}
# Check if kallsymso_prev and kallsymso differ
# If symbol sizes within ${kallsymso} change, any symbols within vmlinux are
# likely to shift, invalidating ${kallsymso}.
# Since file size can remain unchanged even if symbol sizes change, compare the
# actual symbols instead of relying on file size only.
kallsymso_changed()
{
${NM} -n "${kallsymso_prev}" > "${kallsymso_prev}.sym"
${NM} -n "${kallsymso}" > "${kallsymso}.sym"
! cmp -s "${kallsymso_prev}.sym" "${kallsymso}.sym"
}
# Create ${2}.o file with all symbols from the ${1} object file
kallsyms()
{
@@ -126,6 +138,7 @@ kallsyms()
${CC} ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS} \
${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} -c -o "${2}.o" "${2}.S"
kallsymso_prev="${kallsymso:-}"
kallsymso=${2}.o
}
@@ -255,7 +268,12 @@ if is_enabled CONFIG_KALLSYMS; then
sysmap_and_kallsyms .tmp_vmlinux2
size2=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" ${kallsymso})
if [ $size1 -ne $size2 ] || [ -n "${KALLSYMS_EXTRA_PASS}" ]; then
# Due to alignment, file size of the kallsymso object file might remain
# unchanged even if individual symbols within change size. Changed
# symbol sizes can still shift other symbols, though. Therefore, don't
# rely on file size alone.
if [ $size1 -ne $size2 ] || kallsymso_changed || \
[ -n "${KALLSYMS_EXTRA_PASS}" ]; then
vmlinux_link .tmp_vmlinux3
sysmap_and_kallsyms .tmp_vmlinux3
fi
+59 -59
View File
@@ -74,7 +74,7 @@ static unsigned int nr_unresolved;
#define MODULE_NAME_LEN (64 - sizeof(Elf_Addr))
void modpost_log(bool is_error, const char *fmt, ...)
void modpost_log(bool is_error, struct module *mod, const char *fmt, ...)
{
va_list arglist;
@@ -87,11 +87,17 @@ void modpost_log(bool is_error, const char *fmt, ...)
fprintf(stderr, "modpost: ");
if (mod)
fprintf(stderr, "%s%s: ", mod->name, mod->is_vmlinux ? "" : ".ko");
va_start(arglist, fmt);
vfprintf(stderr, fmt, arglist);
va_end(arglist);
}
#define mod_warn(mod, fmt, args...) modpost_log(false, mod, fmt, ##args)
#define mod_error(mod, fmt, args...) modpost_log(true, mod, fmt, ##args)
static inline bool strends(const char *str, const char *postfix)
{
if (strlen(str) < strlen(postfix))
@@ -359,9 +365,8 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod,
struct symbol *s = find_symbol(name);
if (s && (!external_module || s->module->is_vmlinux || s->module == mod)) {
error("%s: '%s' exported twice. Previous export was in %s%s\n",
mod->name, name, s->module->name,
s->module->is_vmlinux ? "" : ".ko");
mod_error(mod, "symbol '%s' exported twice. Previous export was in %s%s\n",
name, s->module->name, s->module->is_vmlinux ? "" : ".ko");
}
s = alloc_symbol(name);
@@ -632,7 +637,7 @@ static void handle_symbol(struct module *mod, struct elf_info *info,
if (strstarts(symname, "__gnu_lto_")) {
/* Should warn here, but modpost runs before the linker */
} else
warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name);
mod_warn(mod, "'%s' is COMMON symbol\n", symname);
break;
case SHN_UNDEF:
/* undefined symbol */
@@ -775,7 +780,7 @@ static const char *const section_white_list[] =
* The cause of this is often a section specified in assembler
* without "ax" / "aw".
*/
static void check_section(const char *modname, struct elf_info *elf,
static void check_section(struct module *mod, struct elf_info *elf,
Elf_Shdr *sechdr)
{
const char *sec = sech_name(elf, sechdr);
@@ -783,11 +788,11 @@ static void check_section(const char *modname, struct elf_info *elf,
if (sechdr->sh_type == SHT_PROGBITS &&
!(sechdr->sh_flags & SHF_ALLOC) &&
!match(sec, section_white_list)) {
warn("%s (%s): unexpected non-allocatable section.\n"
"Did you forget to use \"ax\"/\"aw\" in a .S file?\n"
"Note that for example <linux/init.h> contains\n"
"section definitions for use in .S files.\n\n",
modname, sec);
mod_warn(mod, "unexpected non-allocatable section '%s'.\n"
"Did you forget to use \"ax\"/\"aw\" in a .S file?\n"
"Note that for example <linux/init.h> contains\n"
"section definitions for use in .S files.\n\n",
sec);
}
}
@@ -1021,7 +1026,7 @@ static bool is_executable_section(struct elf_info *elf, unsigned int secndx)
return (elf->sechdrs[secndx].sh_flags & SHF_EXECINSTR) != 0;
}
static void default_mismatch_handler(const char *modname, struct elf_info *elf,
static void default_mismatch_handler(struct module *mod, struct elf_info *elf,
const struct sectioncheck* const mismatch,
Elf_Sym *tsym,
unsigned int fsecndx, const char *fromsec, Elf_Addr faddr,
@@ -1051,10 +1056,10 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf,
* The format for the reference source: <symbol_name>+<offset> or <address>
* The format for the reference destination: <symbol_name> or <address>
*/
warn("%s: section mismatch in reference: %s%s0x%x (section: %s) -> %s (section: %s)\n",
modname, fromsym, fromsym[0] ? "+" : "",
(unsigned int)(faddr - (fromsym[0] ? from->st_value : 0)),
fromsec, tosym[0] ? tosym : taddr_str, tosec);
mod_warn(mod, "section mismatch in reference: %s%s0x%x (section: %s) -> %s (section: %s)\n",
fromsym, fromsym[0] ? "+" : "",
(unsigned int)(faddr - (fromsym[0] ? from->st_value : 0)),
fromsec, tosym[0] ? tosym : taddr_str, tosec);
if (mismatch->mismatch == EXTABLE_TO_NON_TEXT) {
if (match(tosec, mismatch->bad_tosec))
@@ -1063,7 +1068,7 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf,
"Something is seriously wrong and should be fixed.\n"
"You might get more information about where this is\n"
"coming from by using scripts/check_extable.sh %s\n",
fromsec, (long)faddr, tosec, modname);
fromsec, (long)faddr, tosec, mod->name);
else if (is_executable_section(elf, get_secindex(elf, tsym)))
warn("The relocation at %s+0x%lx references\n"
"section \"%s\" which is not in the list of\n"
@@ -1093,22 +1098,22 @@ static void check_export_symbol(struct module *mod, struct elf_info *elf,
label_name = sym_name(elf, label);
if (!strstarts(label_name, prefix)) {
error("%s: .export_symbol section contains strange symbol '%s'\n",
mod->name, label_name);
mod_error(mod, ".export_symbol section contains strange symbol '%s'\n",
label_name);
return;
}
if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL &&
ELF_ST_BIND(sym->st_info) != STB_WEAK) {
error("%s: local symbol '%s' was exported\n", mod->name,
label_name + strlen(prefix));
mod_error(mod, "local symbol '%s' was exported\n",
label_name + strlen(prefix));
return;
}
name = sym_name(elf, sym);
if (strcmp(label_name + strlen(prefix), name)) {
error("%s: .export_symbol section references '%s', but it does not seem to be an export symbol\n",
mod->name, name);
mod_error(mod, ".export_symbol section references '%s', but it does not seem to be an export symbol\n",
name);
return;
}
@@ -1118,8 +1123,8 @@ static void check_export_symbol(struct module *mod, struct elf_info *elf,
} else if (!strcmp(data, "")) {
is_gpl = false;
} else {
error("%s: unknown license '%s' was specified for '%s'\n",
mod->name, data, name);
mod_error(mod, "unknown license '%s' was specified for '%s'\n",
data, name);
return;
}
@@ -1142,11 +1147,11 @@ static void check_export_symbol(struct module *mod, struct elf_info *elf,
s->is_func = true;
if (match(secname, PATTERNS(ALL_INIT_SECTIONS)))
warn("%s: %s: EXPORT_SYMBOL used for init symbol. Remove __init or EXPORT_SYMBOL.\n",
mod->name, name);
mod_warn(mod, "EXPORT_SYMBOL used for init symbol '%s'. Remove __init or EXPORT_SYMBOL.\n",
name);
else if (match(secname, PATTERNS(ALL_EXIT_SECTIONS)))
warn("%s: %s: EXPORT_SYMBOL used for exit symbol. Remove __exit or EXPORT_SYMBOL.\n",
mod->name, name);
mod_warn(mod, "EXPORT_SYMBOL used for exit symbol '%s'. Remove __exit or EXPORT_SYMBOL.\n",
name);
}
static void check_section_mismatch(struct module *mod, struct elf_info *elf,
@@ -1166,7 +1171,7 @@ static void check_section_mismatch(struct module *mod, struct elf_info *elf,
if (!mismatch)
return;
default_mismatch_handler(mod->name, elf, mismatch, sym,
default_mismatch_handler(mod, elf, mismatch, sym,
fsecndx, fromsec, faddr,
tosec, taddr);
}
@@ -1443,7 +1448,7 @@ static void check_sec_ref(struct module *mod, struct elf_info *elf)
for (i = 0; i < elf->num_sections; i++) {
Elf_Shdr *sechdr = &elf->sechdrs[i];
check_section(mod->name, elf, sechdr);
check_section(mod, elf, sechdr);
/* We want to process only relocation sections and not .init */
if (sechdr->sh_type == SHT_REL || sechdr->sh_type == SHT_RELA) {
/* section to which the relocation applies */
@@ -1591,14 +1596,14 @@ static void read_symbols(const char *modname)
struct elf_info info = { };
Elf_Sym *sym;
if (!parse_elf(&info, modname))
return;
if (!strends(modname, ".o")) {
error("%s: filename must be suffixed with .o\n", modname);
return;
}
if (!parse_elf(&info, modname))
return;
/* strip trailing .o */
mod = new_module(modname, strlen(modname) - strlen(".o"));
@@ -1613,7 +1618,7 @@ static void read_symbols(const char *modname)
if (!mod->is_vmlinux) {
license = get_modinfo(&info, "license");
if (!license)
error("missing MODULE_LICENSE() in %s\n", modname);
mod_error(mod, "missing MODULE_LICENSE()\n");
while (license) {
if (!license_is_gpl_compatible(license)) {
mod->is_gpl_compatible = false;
@@ -1626,14 +1631,14 @@ static void read_symbols(const char *modname)
namespace;
namespace = get_next_modinfo(&info, "import_ns", namespace)) {
if (strstarts(namespace, MODULE_NS_PREFIX))
error("%s: explicitly importing namespace \"%s\" is not allowed.\n",
mod->name, namespace);
mod_error(mod, "explicitly importing namespace '%s' is not allowed.\n",
namespace);
add_namespace(&mod->imported_namespaces, namespace);
}
if (!get_modinfo(&info, "description"))
warn("missing MODULE_DESCRIPTION() in %s\n", modname);
mod_warn(mod, "missing MODULE_DESCRIPTION()\n");
}
for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
@@ -1772,14 +1777,13 @@ static void check_exports(struct module *mod)
exp = find_symbol(s->name);
if (!exp) {
if (!s->weak && nr_unresolved++ < MAX_UNRESOLVED_REPORTS)
modpost_log(!warn_unresolved,
"\"%s\" [%s.ko] undefined!\n",
s->name, mod->name);
modpost_log(!warn_unresolved, mod,
"symbol '%s' undefined!\n",
s->name);
continue;
}
if (exp->module == mod) {
error("\"%s\" [%s.ko] was exported without definition\n",
s->name, mod->name);
mod_error(mod, "symbol '%s' was exported without definition\n", s->name);
continue;
}
@@ -1792,15 +1796,15 @@ static void check_exports(struct module *mod)
if (!verify_module_namespace(exp->namespace, basename) &&
!contains_namespace(&mod->imported_namespaces, exp->namespace)) {
modpost_log(!allow_missing_ns_imports,
"module %s uses symbol %s from namespace %s, but does not import it.\n",
basename, exp->name, exp->namespace);
modpost_log(!allow_missing_ns_imports, mod,
"module uses symbol '%s' from namespace '%s', but does not import it.\n",
exp->name, exp->namespace);
add_namespace(&mod->missing_namespaces, exp->namespace);
}
if (!mod->is_gpl_compatible && exp->is_gpl_only)
error("GPL-incompatible module %s.ko uses GPL-only symbol '%s'\n",
basename, exp->name);
mod_error(mod, "GPL-incompatible module uses GPL-only symbol '%s'\n",
exp->name);
}
}
@@ -1850,7 +1854,7 @@ static void check_modname_len(struct module *mod)
mod_name = get_basename(mod->name);
if (strlen(mod_name) >= MODULE_NAME_LEN)
error("module name is too long [%s.ko]\n", mod->name);
mod_error(mod, "module name is too long\n");
}
/**
@@ -1914,10 +1918,9 @@ static void add_exported_symbols(struct buffer *buf, struct module *mod)
continue;
if (!sym->crc_valid)
warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n"
"Is \"%s\" prototyped in <asm/asm-prototypes.h>?\n",
sym->name, mod->name, mod->is_vmlinux ? "" : ".ko",
sym->name);
mod_warn(mod, "EXPORT symbol '%s' version generation failed, symbol will not be versioned.\n"
"Is '%s' prototyped in <asm/asm-prototypes.h>?\n",
sym->name, sym->name);
buf_printf(buf, "SYMBOL_CRC(%s, 0x%08x);\n",
sym->name, sym->crc);
@@ -1941,8 +1944,7 @@ static void add_extended_versions(struct buffer *b, struct module *mod)
if (!s->module)
continue;
if (!s->crc_valid) {
warn("\"%s\" [%s.ko] has no CRC!\n",
s->name, mod->name);
mod_warn(mod, "symbol '%s' has no CRC!\n", s->name);
continue;
}
buf_printf(b, "\t0x%08x,\n", s->crc);
@@ -1985,8 +1987,7 @@ static void add_versions(struct buffer *b, struct module *mod)
if (!s->module)
continue;
if (!s->crc_valid) {
warn("\"%s\" [%s.ko] has no CRC!\n",
s->name, mod->name);
mod_warn(mod, "symbol '%s' has no CRC!\n", s->name);
continue;
}
if (strlen(s->name) >= MODULE_NAME_LEN) {
@@ -1994,8 +1995,7 @@ static void add_versions(struct buffer *b, struct module *mod)
/* this symbol will only be in the extended info */
continue;
} else {
error("too long symbol \"%s\" [%s.ko]\n",
s->name, mod->name);
mod_error(mod, "too long symbol '%s'\n", s->name);
break;
}
}
+4 -4
View File
@@ -223,8 +223,8 @@ 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);
void __attribute__((format(printf, 2, 3)))
modpost_log(bool is_error, const char *fmt, ...);
void __attribute__((format(printf, 3, 4)))
modpost_log(bool is_error, struct module *mod, const char *fmt, ...);
/*
* warn - show the given message, then let modpost continue running, still
@@ -239,6 +239,6 @@ modpost_log(bool is_error, const char *fmt, ...);
* fatal - show the given message, and bail out immediately. This should be
* used when there is no point to continue running modpost.
*/
#define warn(fmt, args...) modpost_log(false, fmt, ##args)
#define error(fmt, args...) modpost_log(true, fmt, ##args)
#define warn(fmt, args...) modpost_log(false, NULL, fmt, ##args)
#define error(fmt, args...) modpost_log(true, NULL, fmt, ##args)
#define fatal(fmt, args...) do { error(fmt, ##args); exit(1); } while (1)
+32 -10
View File
@@ -46,13 +46,31 @@ elif [ "${ALLSOURCE_ARCHS}" = "all" ]; then
ALLSOURCE_ARCHS=$(find ${tree}arch/ -mindepth 1 -maxdepth 1 -type d -printf '%f ')
fi
setup_name_pattern()
{
pattern=()
for ext; do
if [ ${#pattern[@]} -gt 0 ]; then
pattern+=("-o" "-name" "$ext")
else
pattern+=("(" "-name" "$ext")
fi
done
if [ ${#pattern[@]} -gt 0 ]; then
pattern+=(")")
fi
}
# find sources in arch/$1
find_arch_sources()
{
for i in $archincludedir; do
local prune="$prune ( -path $i ) -prune -o"
done
find ${tree}arch/$1 $ignore $prune -name "$2" -not -type l -print;
local src=${tree}arch/$1
shift
setup_name_pattern "$@"
find $src $ignore $prune "${pattern[@]}" -not -type l -print;
}
# find sources in arch/$1/include
@@ -61,14 +79,17 @@ find_arch_include_sources()
local include=$(find ${tree}arch/$1/ -name include -type d -print);
if [ -n "$include" ]; then
archincludedir="$archincludedir $include"
find $include $ignore -name "$2" -not -type l -print;
shift
setup_name_pattern "$@"
find $include $ignore "${pattern[@]}" -not -type l -print;
fi
}
# find sources in include/
find_include_sources()
{
find ${tree}include $ignore -name config -prune -o -name "$1" \
setup_name_pattern "$@"
find ${tree}include $ignore -name config -prune -o "${pattern[@]}" \
-not -type l -print;
}
@@ -76,23 +97,24 @@ find_include_sources()
# we could benefit from a list of dirs to search in here
find_other_sources()
{
setup_name_pattern "$@"
find ${tree}* $ignore \
\( -path ${tree}include -o -path ${tree}arch -o -name '.tmp_*' \) -prune -o \
-name "$1" -not -type l -print;
"${pattern[@]}" -not -type l -print;
}
all_sources()
{
find_arch_include_sources ${SRCARCH} '*.[chS]'
find_arch_include_sources ${SRCARCH} '*.[chS]' '*.rs'
if [ -n "$archinclude" ]; then
find_arch_include_sources $archinclude '*.[chS]'
find_arch_include_sources $archinclude '*.[chS]' '*.rs'
fi
find_include_sources '*.[chS]'
find_include_sources '*.[chS]' '*.rs'
for arch in $ALLSOURCE_ARCHS
do
find_arch_sources $arch '*.[chS]'
find_arch_sources $arch '*.[chS]' '*.rs'
done
find_other_sources '*.[chS]'
find_other_sources '*.[chS]' '*.rs'
}
all_compiled_sources()
@@ -100,7 +122,7 @@ all_compiled_sources()
{
echo include/generated/autoconf.h
find $ignore -name "*.cmd" -exec \
grep -Poh '(?<=^ )\S+|(?<== )\S+[^\\](?=$)' {} \+ |
grep -Poh '(?<=^ )\S+\.([chS]|rs)(?=\s)|(?<== )\S+\.(?1)(?=$)' {} \+ |
awk '!a[$0]++'
} | xargs realpath -esq $([ -z "$KBUILD_ABS_SRCTREE" ] && echo --relative-to=.) |
sort -u