Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild
authorLinus Torvalds <torvalds@g5.osdl.org>
Sat, 1 Jul 2006 16:58:43 +0000 (09:58 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Sat, 1 Jul 2006 16:58:43 +0000 (09:58 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild:
  kbuild: documentation change on allowing checkers besides sparse
  kbuild: warn when a moduled uses a symbol marked UNUSED
  kbuild: fix segv in modpost
  kconfig: enhancing accessibility of lxdialog
  kbuild: fix ia64 breakage after introducing make -rR

Makefile
arch/um/scripts/Makefile.rules
scripts/Kbuild.include
scripts/Makefile.build
scripts/Makefile.host
scripts/Makefile.lib
scripts/Makefile.modpost
scripts/kconfig/lxdialog/checklist.c
scripts/mod/modpost.c
scripts/mod/modpost.h

index e9560c6..4dcf25d 100644 (file)
--- 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 $@ $<
index 1347dc6..813077f 100644 (file)
@@ -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)__
 
index b0d067b..2180c88 100644 (file)
@@ -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)
index 02a7eea..3cb445c 100644 (file)
@@ -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)
index 2b066d1..18ecd4d 100644 (file)
@@ -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)
index 2cb4935..fc498fe 100644 (file)
@@ -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
index 576cce5..a495502 100644 (file)
@@ -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)   \
index be0200e..7988641 100644 (file)
@@ -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);
index 0dd1617..dfde0e8 100644 (file)
@@ -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:
- * 0x12345678<tab>symbol<tab>module[<tab>export]
+ * 0x12345678<tab>symbol<tab>module[[<tab>export]<tab>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) {
index 2b00c60..d398c61 100644 (file)
@@ -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;