diff --git a/Makefile b/Makefile index e9560c6f8156..4dcf25d43fa6 100644 --- a/Makefile +++ b/Makefile @@ -41,8 +41,9 @@ ifndef KBUILD_VERBOSE KBUILD_VERBOSE = 0 endif -# Call sparse as part of compilation of C files -# Use 'make C=1' to enable sparse checking +# Call checker as part of compilation of C files +# Use 'make C=1' to enable checking (sparse, by default) +# Override with 'make C=1 CHECK=checker_executable CHECKFLAGS=....' ifdef C ifeq ("$(origin C)", "command line") @@ -1060,8 +1061,8 @@ help: @echo ' make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build' @echo ' make O=dir [targets] Locate all output files in "dir", including .config' - @echo ' make C=1 [targets] Check all c source with $$CHECK (sparse)' - @echo ' make C=2 [targets] Force check of all c source with $$CHECK (sparse)' + @echo ' make C=1 [targets] Check all c source with $$CHECK (sparse by default)' + @echo ' make C=2 [targets] Force check of all c source with $$CHECK' @echo '' @echo 'Execute "make" or "make all" to build all targets marked with [*] ' @echo 'For further info see the ./README file' @@ -1352,7 +1353,7 @@ quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN $(wildcard $(rm-files)) a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(AFLAGS_KERNEL) \ $(NOSTDINC_FLAGS) $(CPPFLAGS) \ - $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o) + $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(basetarget).o) quiet_cmd_as_o_S = AS $@ cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index 1347dc6d5218..813077fb1e5b 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules @@ -8,7 +8,7 @@ USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) $(USER_OBJS:.o=.%): \ - c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(*F).o) + c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(basetarget).o) $(USER_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ -Dunix -D__unix__ -D__$(SUBARCH)__ @@ -17,7 +17,7 @@ $(USER_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ UNPROFILE_OBJS := $(foreach file,$(UNPROFILE_OBJS),$(obj)/$(file)) $(UNPROFILE_OBJS:.o=.%): \ - c_flags = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS)) $(CFLAGS_$(*F).o) + c_flags = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS)) $(CFLAGS_$(basetarget).o) $(UNPROFILE_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ -Dunix -D__unix__ -D__$(SUBARCH)__ diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index b0d067be7390..2180c88cfe89 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -12,6 +12,10 @@ space := $(empty) $(empty) # contain a comma depfile = $(subst $(comma),_,$(@D)/.$(@F).d) +### +# filename of target with directory and extension stripped +basetarget = $(basename $(notdir $@)) + ### # Escape single quote for use in echo statements escsq = $(subst $(squote),'\$(squote)',$1) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 02a7eea5fdbc..3cb445cc7432 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -117,7 +117,7 @@ $(real-objs-m:.o=.lst): quiet_modtag := [M] $(obj-m) : quiet_modtag := [M] # Default for not multi-part modules -modname = $(*F) +modname = $(basetarget) $(multi-objs-m) : modname = $(modname-multi) $(multi-objs-m:.o=.i) : modname = $(modname-multi) diff --git a/scripts/Makefile.host b/scripts/Makefile.host index 2b066d12af2c..18ecd4d5df7f 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -80,8 +80,10 @@ obj-dirs += $(host-objdirs) ##### # Handle options to gcc. Support building with separate output directory -_hostc_flags = $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS_$(*F).o) -_hostcxx_flags = $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) $(HOSTCXXFLAGS_$(*F).o) +_hostc_flags = $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) \ + $(HOSTCFLAGS_$(basetarget).o) +_hostcxx_flags = $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \ + $(HOSTCXXFLAGS_$(basetarget).o) ifeq ($(KBUILD_SRC),) __hostc_flags = $(_hostc_flags) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 2cb4935e85d1..fc498fee68ed 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -82,12 +82,12 @@ obj-dirs := $(addprefix $(obj)/,$(obj-dirs)) # than one module. In that case KBUILD_MODNAME will be set to foo_bar, # where foo and bar are the name of the modules. name-fix = $(subst $(comma),_,$(subst -,_,$1)) -basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(*F)))" +basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" modname_flags = $(if $(filter 1,$(words $(modname))),\ -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") -_c_flags = $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) -_a_flags = $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o) +_c_flags = $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(basetarget).o) +_a_flags = $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$(basetarget).o) _cpp_flags = $(CPPFLAGS) $(EXTRA_CPPFLAGS) $(CPPFLAGS_$(@F)) # If building the kernel in a separate objtree expand all occurrences diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 576cce5e387f..a49550205dcc 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -72,7 +72,7 @@ $(modules:.ko=.mod.c): __modpost ; # Step 5), compile all *.mod.c files # modname is set to make c_flags define KBUILD_MODNAME -modname = $(*F) +modname = $(notdir $(@:.mod.o=)) quiet_cmd_cc_o_c = CC $@ cmd_cc_o_c = $(CC) $(c_flags) $(CFLAGS_MODULE) \ diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c index be0200e9cdaf..79886413b6d5 100644 --- a/scripts/kconfig/lxdialog/checklist.c +++ b/scripts/kconfig/lxdialog/checklist.c @@ -187,9 +187,12 @@ int dialog_checklist(const char *title, const char *prompt, int height, /* Print the list */ for (i = 0; i < max_choice; i++) { - print_item(list, items[(scroll + i) * 3 + 1], - status[i + scroll], i, i == choice); + if (i != choice) + print_item(list, items[(scroll + i) * 3 + 1], + status[i + scroll], i, 0); } + print_item(list, items[(scroll + choice) * 3 + 1], + status[choice + scroll], choice, 1); print_arrows(dialog, choice, item_no, scroll, box_y, box_x + check_x + 5, list_height); diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 0dd16177642d..dfde0e87a765 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -24,7 +24,10 @@ static int all_versions = 0; /* If we are modposting external module set to 1 */ static int external_module = 0; /* How a symbol is exported */ -enum export {export_plain, export_gpl, export_gpl_future, export_unknown}; +enum export { + export_plain, export_unused, export_gpl, + export_unused_gpl, export_gpl_future, export_unknown +}; void fatal(const char *fmt, ...) { @@ -191,7 +194,9 @@ static struct { enum export export; } export_list[] = { { .str = "EXPORT_SYMBOL", .export = export_plain }, + { .str = "EXPORT_UNUSED_SYMBOL", .export = export_unused }, { .str = "EXPORT_SYMBOL_GPL", .export = export_gpl }, + { .str = "EXPORT_UNUSED_SYMBOL_GPL", .export = export_unused_gpl }, { .str = "EXPORT_SYMBOL_GPL_FUTURE", .export = export_gpl_future }, { .str = "(unknown)", .export = export_unknown }, }; @@ -205,6 +210,8 @@ static const char *export_str(enum export ex) static enum export export_no(const char * s) { int i; + if (!s) + return export_unknown; for (i = 0; export_list[i].export != export_unknown; i++) { if (strcmp(export_list[i].str, s) == 0) return export_list[i].export; @@ -216,8 +223,12 @@ static enum export export_from_sec(struct elf_info *elf, Elf_Section sec) { if (sec == elf->export_sec) return export_plain; + else if (sec == elf->export_unused_sec) + return export_unused; else if (sec == elf->export_gpl_sec) return export_gpl; + else if (sec == elf->export_unused_gpl_sec) + return export_unused_gpl; else if (sec == elf->export_gpl_future_sec) return export_gpl_future; else @@ -366,8 +377,12 @@ static void parse_elf(struct elf_info *info, const char *filename) info->modinfo_len = sechdrs[i].sh_size; } else if (strcmp(secname, "__ksymtab") == 0) info->export_sec = i; + else if (strcmp(secname, "__ksymtab_unused") == 0) + info->export_unused_sec = i; else if (strcmp(secname, "__ksymtab_gpl") == 0) info->export_gpl_sec = i; + else if (strcmp(secname, "__ksymtab_unused_gpl") == 0) + info->export_unused_gpl_sec = i; else if (strcmp(secname, "__ksymtab_gpl_future") == 0) info->export_gpl_future_sec = i; @@ -1085,38 +1100,64 @@ void buf_write(struct buffer *buf, const char *s, int len) buf->pos += len; } -void check_license(struct module *mod) +static void check_for_gpl_usage(enum export exp, const char *m, const char *s) +{ + const char *e = is_vmlinux(m) ?"":".ko"; + + switch (exp) { + case export_gpl: + fatal("modpost: GPL-incompatible module %s%s " + "uses GPL-only symbol '%s'\n", m, e, s); + break; + case export_unused_gpl: + fatal("modpost: GPL-incompatible module %s%s " + "uses GPL-only symbol marked UNUSED '%s'\n", m, e, s); + break; + case export_gpl_future: + warn("modpost: GPL-incompatible module %s%s " + "uses future GPL-only symbol '%s'\n", m, e, s); + break; + case export_plain: + case export_unused: + case export_unknown: + /* ignore */ + break; + } +} + +static void check_for_unused(enum export exp, const char* m, const char* s) +{ + const char *e = is_vmlinux(m) ?"":".ko"; + + switch (exp) { + case export_unused: + case export_unused_gpl: + warn("modpost: module %s%s " + "uses symbol '%s' marked UNUSED\n", m, e, s); + break; + default: + /* ignore */ + break; + } +} + +static void check_exports(struct module *mod) { struct symbol *s, *exp; for (s = mod->unres; s; s = s->next) { const char *basename; - if (mod->gpl_compatible == 1) { - /* GPL-compatible modules may use all symbols */ - continue; - } exp = find_symbol(s->name); if (!exp || exp->module == mod) continue; basename = strrchr(mod->name, '/'); if (basename) basename++; - switch (exp->export) { - case export_gpl: - fatal("modpost: GPL-incompatible module %s " - "uses GPL-only symbol '%s'\n", - basename ? basename : mod->name, - exp->name); - break; - case export_gpl_future: - warn("modpost: GPL-incompatible module %s " - "uses future GPL-only symbol '%s'\n", - basename ? basename : mod->name, - exp->name); - break; - case export_plain: /* ignore */ break; - case export_unknown: /* ignore */ break; - } + else + basename = mod->name; + if (!mod->gpl_compatible) + check_for_gpl_usage(exp->export, basename, exp->name); + check_for_unused(exp->export, basename, exp->name); } } @@ -1271,7 +1312,7 @@ static void write_if_changed(struct buffer *b, const char *fname) } /* parse Module.symvers file. line format: - * 0x12345678symbolmodule[export] + * 0x12345678symbolmodule[[export]something] **/ static void read_dump(const char *fname, unsigned int kernel) { @@ -1284,7 +1325,7 @@ static void read_dump(const char *fname, unsigned int kernel) return; while ((line = get_next_line(&pos, file, size))) { - char *symname, *modname, *d, *export; + char *symname, *modname, *d, *export, *end; unsigned int crc; struct module *mod; struct symbol *s; @@ -1297,7 +1338,8 @@ static void read_dump(const char *fname, unsigned int kernel) *modname++ = '\0'; if ((export = strchr(modname, '\t')) != NULL) *export++ = '\0'; - + if (export && ((end = strchr(export, '\t')) != NULL)) + *end = '\0'; crc = strtoul(line, &d, 16); if (*symname == '\0' || *modname == '\0' || *d != '\0') goto fail; @@ -1396,7 +1438,7 @@ int main(int argc, char **argv) for (mod = modules; mod; mod = mod->next) { if (mod->skip) continue; - check_license(mod); + check_exports(mod); } for (mod = modules; mod; mod = mod->next) { diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 2b00c6062844..d398c61e55ef 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -117,7 +117,9 @@ struct elf_info { Elf_Sym *symtab_start; Elf_Sym *symtab_stop; Elf_Section export_sec; + Elf_Section export_unused_sec; Elf_Section export_gpl_sec; + Elf_Section export_unused_gpl_sec; Elf_Section export_gpl_future_sec; const char *strtab; char *modinfo;