Merge tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 5 May 2013 17:58:06 +0000 (10:58 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 5 May 2013 17:58:06 +0000 (10:58 -0700)
Pull mudule updates from Rusty Russell:
 "We get rid of the general module prefix confusion with a binary config
  option, fix a remove/insert race which Never Happens, and (my
  favorite) handle the case when we have too many modules for a single
  commandline.  Seriously, the kernel is full, please go away!"

* tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux:
  modpost: fix unwanted VMLINUX_SYMBOL_STR expansion
  X.509: Support parse long form of length octets in Authority Key Identifier
  module: don't unlink the module until we've removed all exposure.
  kernel: kallsyms: memory override issue, need check destination buffer length
  MODSIGN: do not send garbage to stderr when enabling modules signature
  modpost: handle huge numbers of modules.
  modpost: add -T option to read module names from file/stdin.
  modpost: minor cleanup.
  genksyms: pass symbol-prefix instead of arch
  module: fix symbol versioning with symbol prefixes
  CONFIG_SYMBOL_PREFIX: cleanup.

23 files changed:
Makefile
arch/Kconfig
arch/blackfin/Kconfig
arch/h8300/Kconfig
arch/metag/Kconfig
crypto/asymmetric_keys/x509_cert_parser.c
drivers/mtd/chips/gen_probe.c
include/asm-generic/unistd.h
include/asm-generic/vmlinux.lds.h
include/linux/export.h
include/linux/kernel.h
include/linux/linkage.h
include/linux/module.h
kernel/Makefile
kernel/kallsyms.c
kernel/modsign_certificate.S
kernel/module.c
scripts/Makefile.build
scripts/Makefile.lib
scripts/Makefile.modpost
scripts/genksyms/genksyms.c
scripts/link-vmlinux.sh
scripts/mod/modpost.c

index 4572f106e30b69fbd5628088b58fbd54133cc09a..878d7aa3d2dd651651dc90d18fd2d765e4f2d5c8 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1399,7 +1399,7 @@ quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN   $(wildcard $(rm-files))
 # Run depmod only if we have System.map and depmod is executable
 quiet_cmd_depmod = DEPMOD  $(KERNELRELEASE)
       cmd_depmod = $(CONFIG_SHELL) $(srctree)/scripts/depmod.sh $(DEPMOD) \
-                   $(KERNELRELEASE) "$(patsubst "%",%,$(CONFIG_SYMBOL_PREFIX))"
+                   $(KERNELRELEASE) "$(patsubst y,_,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX))"
 
 # Create temporary dir for module support files
 # clean it up only when building all modules
index 99f0e17df4298de7b3be96f13ec1451bdaed2bc2..dd0e8eb8042f746cc7072c0bf67d1fac8c0d4a7e 100644 (file)
@@ -381,6 +381,12 @@ config MODULES_USE_ELF_REL
          Modules only use ELF REL relocations.  Modules with ELF RELA
          relocations will give an error.
 
+config HAVE_UNDERSCORE_SYMBOL_PREFIX
+       bool
+       help
+         Some architectures generate an _ in front of C symbols; things like
+         module loading and assembly files need to know about this.
+
 #
 # ABI hall of shame
 #
index c3f2e0bc644aed0b64e86b7a801424d5cb239b9a..453ebe46b065d01d0afa272528220f9e73aede52 100644 (file)
@@ -1,7 +1,3 @@
-config SYMBOL_PREFIX
-       string
-       default "_"
-
 config MMU
        def_bool n
 
@@ -33,6 +29,7 @@ config BLACKFIN
        select ARCH_HAVE_CUSTOM_GPIO_H
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select HAVE_UID16
+       select HAVE_UNDERSCORE_SYMBOL_PREFIX
        select VIRT_TO_BUS
        select ARCH_WANT_IPC_PARSE_VERSION
        select HAVE_GENERIC_HARDIRQS
index 79250de1b12a434f7b0d945cb6b4b42559a9d101..303e4f9a79d19998452760a913828a64c5773345 100644 (file)
@@ -12,10 +12,7 @@ config H8300
        select MODULES_USE_ELF_RELA
        select OLD_SIGSUSPEND3
        select OLD_SIGACTION
-
-config SYMBOL_PREFIX
-       string
-       default "_"
+       select HAVE_UNDERSCORE_SYMBOL_PREFIX
 
 config MMU
        bool
index b06b41861aaca2fa517f657d92d4ad6a8e572b89..6f16c14693272e593aa0f98d33e6b62d60f8ce79 100644 (file)
@@ -1,7 +1,3 @@
-config SYMBOL_PREFIX
-       string
-       default "_"
-
 config METAG
        def_bool y
        select EMBEDDED
@@ -28,6 +24,7 @@ config METAG
        select HAVE_OPROFILE
        select HAVE_PERF_EVENTS
        select HAVE_SYSCALL_TRACEPOINTS
+       select HAVE_UNDERSCORE_SYMBOL_PREFIX
        select IRQ_DOMAIN
        select MODULES_USE_ELF_RELA
        select OF
index 7fabc4c01993bd92e3fc159ba05ae92b1732f231..facbf26bc6bbbc91eb879b0a5cdf40d01e8f2b05 100644 (file)
@@ -373,6 +373,9 @@ int rsa_extract_mpi(void *context, size_t hdrlen,
        return 0;
 }
 
+/* The keyIdentifier in AuthorityKeyIdentifier SEQUENCE is tag(CONT,PRIM,0) */
+#define SEQ_TAG_KEYID (ASN1_CONT << 6)
+
 /*
  * Process certificate extensions that are used to qualify the certificate.
  */
@@ -407,21 +410,57 @@ int x509_process_extension(void *context, size_t hdrlen,
        }
 
        if (ctx->last_oid == OID_authorityKeyIdentifier) {
+               size_t key_len;
+
                /* Get hold of the CA key fingerprint */
                if (vlen < 5)
                        return -EBADMSG;
-               if (v[0] != (ASN1_SEQ | (ASN1_CONS << 5)) ||
-                   v[1] != vlen - 2 ||
-                   v[2] != (ASN1_CONT << 6) ||
-                   v[3] != vlen - 4)
+
+               /* Authority Key Identifier must be a Constructed SEQUENCE */
+               if (v[0] != (ASN1_SEQ | (ASN1_CONS << 5)))
                        return -EBADMSG;
-               v += 4;
-               vlen -= 4;
 
-               f = kmalloc(vlen * 2 + 1, GFP_KERNEL);
+               /* Authority Key Identifier is not indefinite length */
+               if (unlikely(vlen == ASN1_INDEFINITE_LENGTH))
+                       return -EBADMSG;
+
+               if (vlen < ASN1_INDEFINITE_LENGTH) {
+                       /* Short Form length */
+                       if (v[1] != vlen - 2 ||
+                           v[2] != SEQ_TAG_KEYID ||
+                           v[3] > vlen - 4)
+                               return -EBADMSG;
+
+                       key_len = v[3];
+                       v += 4;
+               } else {
+                       /* Long Form length */
+                       size_t seq_len = 0;
+                       size_t sub = v[1] - ASN1_INDEFINITE_LENGTH;
+
+                       if (sub > 2)
+                               return -EBADMSG;
+
+                       /* calculate the length from subsequent octets */
+                       v += 2;
+                       for (i = 0; i < sub; i++) {
+                               seq_len <<= 8;
+                               seq_len |= v[i];
+                       }
+
+                       if (seq_len != vlen - 2 - sub ||
+                           v[sub] != SEQ_TAG_KEYID ||
+                           v[sub + 1] > vlen - 4 - sub)
+                               return -EBADMSG;
+
+                       key_len = v[sub + 1];
+                       v += (sub + 2);
+               }
+
+               f = kmalloc(key_len * 2 + 1, GFP_KERNEL);
                if (!f)
                        return -ENOMEM;
-               for (i = 0; i < vlen; i++)
+               for (i = 0; i < key_len; i++)
                        sprintf(f + i * 2, "%02x", v[i]);
                pr_debug("authority   %s\n", f);
                ctx->cert->authority = f;
index 3b9a2843c5f8f6da0610b22920918854e70db49f..74dbb6bcf4883a8a0461685ea0f180de7ad3da0d 100644 (file)
@@ -204,14 +204,16 @@ static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map,
        struct cfi_private *cfi = map->fldrv_priv;
        __u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID;
 #ifdef CONFIG_MODULES
-       char probename[16+sizeof(MODULE_SYMBOL_PREFIX)];
+       char probename[sizeof(VMLINUX_SYMBOL_STR(cfi_cmdset_%4.4X))];
        cfi_cmdset_fn_t *probe_function;
 
-       sprintf(probename, MODULE_SYMBOL_PREFIX "cfi_cmdset_%4.4X", type);
+       sprintf(probename, VMLINUX_SYMBOL_STR(cfi_cmdset_%4.4X), type);
 
        probe_function = __symbol_get(probename);
        if (!probe_function) {
-               request_module(probename + sizeof(MODULE_SYMBOL_PREFIX) - 1);
+               char modname[sizeof("cfi_cmdset_%4.4X")];
+               sprintf(modname, "cfi_cmdset_%4.4X", type);
+               request_module(modname);
                probe_function = __symbol_get(probename);
        }
 
index 0501fa3f783ddbc55ed1b12503a4dfaf4cbce6b0..cccc86ecfeaa505a6310f9168bbd71bb952cc8a3 100644 (file)
@@ -1,4 +1,5 @@
 #include <uapi/asm-generic/unistd.h>
+#include <linux/export.h>
 
 /*
  * These are required system calls, we should
index afa12c7a025c4ea72dac8a0d6eb12b9c593536b1..eb58d2d7d9718d0c220387b3c60febf30f324e71 100644 (file)
 #define LOAD_OFFSET 0
 #endif
 
-#ifndef SYMBOL_PREFIX
-#define VMLINUX_SYMBOL(sym) sym
-#else
-#define PASTE2(x,y) x##y
-#define PASTE(x,y) PASTE2(x,y)
-#define VMLINUX_SYMBOL(sym) PASTE(SYMBOL_PREFIX, sym)
-#endif
+#include <linux/export.h>
 
 /* Align . to a 8 byte boundary equals to maximum function alignment. */
 #define ALIGN_FUNCTION()  . = ALIGN(8)
index 696c0f48afc71716f00477ac5a0412804845a66e..412cd509effe0ca3b73e5524e121921457296681 100644 (file)
@@ -5,17 +5,24 @@
  * to reduce the amount of pointless cruft we feed to gcc when only
  * exporting a simple symbol or two.
  *
- * If you feel the need to add #include <linux/foo.h> to this file
- * then you are doing something wrong and should go away silently.
+ * Try not to add #includes here.  It slows compilation and makes kernel
+ * hackers place grumpy comments in header files.
  */
 
 /* Some toolchains use a `_' prefix for all user symbols. */
-#ifdef CONFIG_SYMBOL_PREFIX
-#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX
+#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX
+#define __VMLINUX_SYMBOL(x) _##x
+#define __VMLINUX_SYMBOL_STR(x) "_" #x
 #else
-#define MODULE_SYMBOL_PREFIX ""
+#define __VMLINUX_SYMBOL(x) x
+#define __VMLINUX_SYMBOL_STR(x) #x
 #endif
 
+/* Indirect, so macros are expanded before pasting. */
+#define VMLINUX_SYMBOL(x) __VMLINUX_SYMBOL(x)
+#define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x)
+
+#ifndef __ASSEMBLY__
 struct kernel_symbol
 {
        unsigned long value;
@@ -51,7 +58,7 @@ extern struct module __this_module;
        __CRC_SYMBOL(sym, sec)                                  \
        static const char __kstrtab_##sym[]                     \
        __attribute__((section("__ksymtab_strings"), aligned(1))) \
-       = MODULE_SYMBOL_PREFIX #sym;                            \
+       = VMLINUX_SYMBOL_STR(sym);                              \
        static const struct kernel_symbol __ksymtab_##sym       \
        __used                                                  \
        __attribute__((section("___ksymtab" sec "+" #sym), unused))     \
@@ -85,5 +92,6 @@ extern struct module __this_module;
 #define EXPORT_UNUSED_SYMBOL_GPL(sym)
 
 #endif /* CONFIG_MODULES */
+#endif /* !__ASSEMBLY__ */
 
 #endif /* _LINUX_EXPORT_H */
index 6d1844f393c07dc74fd4c11f877053bbe26920b5..e96329ceb28c8440e470e3e073226ed24995a462 100644 (file)
@@ -786,13 +786,6 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
 /* Trap pasters of __FUNCTION__ at compile-time */
 #define __FUNCTION__ (__func__)
 
-/* This helps us to avoid #ifdef CONFIG_SYMBOL_PREFIX */
-#ifdef CONFIG_SYMBOL_PREFIX
-#define SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX
-#else
-#define SYMBOL_PREFIX ""
-#endif
-
 /* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */
 #ifdef CONFIG_FTRACE_MCOUNT_RECORD
 # define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD
index de09dec25ec3b99372bdc4df356380d7ccc4a939..d3e8ad23a8e0238645fe553f8183a2ad74bf5fc3 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <linux/compiler.h>
 #include <linux/stringify.h>
+#include <linux/export.h>
 #include <asm/linkage.h>
 
 #ifdef __cplusplus
 #define asmlinkage CPP_ASMLINKAGE
 #endif
 
-#ifdef CONFIG_SYMBOL_PREFIX
-#define __SYMBOL_NAME(x) CONFIG_SYMBOL_PREFIX __stringify(x)
-#else
-#define __SYMBOL_NAME(x) __stringify(x)
-#endif
-
 #ifndef cond_syscall
-#define cond_syscall(x) asm(".weak\t" __SYMBOL_NAME(x) \
-       "\n\t.set\t" __SYMBOL_NAME(x) "," __SYMBOL_NAME(sys_ni_syscall));
+#define cond_syscall(x)        asm(                            \
+       ".weak " VMLINUX_SYMBOL_STR(x) "\n\t"           \
+       ".set  " VMLINUX_SYMBOL_STR(x) ","              \
+                VMLINUX_SYMBOL_STR(sys_ni_syscall))
 #endif
 
 #ifndef SYSCALL_ALIAS
-#define SYSCALL_ALIAS(alias, name)                             \
-       asm ("\t.globl " __SYMBOL_NAME(alias)                   \
-       "\n\t.set\t" __SYMBOL_NAME(alias) "," __SYMBOL_NAME(name))
+#define SYSCALL_ALIAS(alias, name) asm(                        \
+       ".globl " VMLINUX_SYMBOL_STR(alias) "\n\t"      \
+       ".set   " VMLINUX_SYMBOL_STR(alias) ","         \
+                 VMLINUX_SYMBOL_STR(name))
 #endif
 
 #define __page_aligned_data    __section(.data..page_aligned) __aligned(PAGE_SIZE)
index ead1b5719a12cbe5ca58ae4e31057add2ba289d5..46f1ea01e6f62161db550b13be8a2ed85246219a 100644 (file)
@@ -190,7 +190,7 @@ extern int modules_disabled; /* for sysctl */
 /* Get/put a kernel symbol (calls must be symmetric) */
 void *__symbol_get(const char *symbol);
 void *__symbol_get_gpl(const char *symbol);
-#define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x)))
+#define symbol_get(x) ((typeof(&x))(__symbol_get(VMLINUX_SYMBOL_STR(x))))
 
 /* modules using other modules: kdb wants to see this. */
 struct module_use {
@@ -453,7 +453,7 @@ extern void __module_put_and_exit(struct module *mod, long code)
 #ifdef CONFIG_MODULE_UNLOAD
 unsigned long module_refcount(struct module *mod);
 void __symbol_put(const char *symbol);
-#define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x)
+#define symbol_put(x) __symbol_put(VMLINUX_SYMBOL_STR(x))
 void symbol_put_addr(void *addr);
 
 /* Sometimes we know we already have a refcount, and it's easier not
index d1574d47cf27ed38890efbfc6526d81ba923adc2..271fd3119af9bac708773e30267077b3a5a5d276 100644 (file)
@@ -176,7 +176,7 @@ signing_key.priv signing_key.x509: x509.genkey
        openssl req -new -nodes -utf8 -$(CONFIG_MODULE_SIG_HASH) -days 36500 \
                -batch -x509 -config x509.genkey \
                -outform DER -out signing_key.x509 \
-               -keyout signing_key.priv
+               -keyout signing_key.priv 2>&1
        @echo "###"
        @echo "### Key pair generated."
        @echo "###"
index 2169feeba529be9843ea844e7281e1cdb31377a2..3127ad52cdb2eb8d61176f873503f62294db3827 100644 (file)
@@ -84,9 +84,11 @@ static int is_ksym_addr(unsigned long addr)
 
 /*
  * Expand a compressed symbol data into the resulting uncompressed string,
+ * if uncompressed string is too long (>= maxlen), it will be truncated,
  * given the offset to where the symbol is in the compressed stream.
  */
-static unsigned int kallsyms_expand_symbol(unsigned int off, char *result)
+static unsigned int kallsyms_expand_symbol(unsigned int off,
+                                          char *result, size_t maxlen)
 {
        int len, skipped_first = 0;
        const u8 *tptr, *data;
@@ -113,15 +115,20 @@ static unsigned int kallsyms_expand_symbol(unsigned int off, char *result)
 
                while (*tptr) {
                        if (skipped_first) {
+                               if (maxlen <= 1)
+                                       goto tail;
                                *result = *tptr;
                                result++;
+                               maxlen--;
                        } else
                                skipped_first = 1;
                        tptr++;
                }
        }
 
-       *result = '\0';
+tail:
+       if (maxlen)
+               *result = '\0';
 
        /* Return to offset to the next symbol. */
        return off;
@@ -176,7 +183,7 @@ unsigned long kallsyms_lookup_name(const char *name)
        unsigned int off;
 
        for (i = 0, off = 0; i < kallsyms_num_syms; i++) {
-               off = kallsyms_expand_symbol(off, namebuf);
+               off = kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf));
 
                if (strcmp(namebuf, name) == 0)
                        return kallsyms_addresses[i];
@@ -195,7 +202,7 @@ int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
        int ret;
 
        for (i = 0, off = 0; i < kallsyms_num_syms; i++) {
-               off = kallsyms_expand_symbol(off, namebuf);
+               off = kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf));
                ret = fn(data, namebuf, NULL, kallsyms_addresses[i]);
                if (ret != 0)
                        return ret;
@@ -294,7 +301,8 @@ const char *kallsyms_lookup(unsigned long addr,
 
                pos = get_symbol_pos(addr, symbolsize, offset);
                /* Grab name */
-               kallsyms_expand_symbol(get_symbol_offset(pos), namebuf);
+               kallsyms_expand_symbol(get_symbol_offset(pos),
+                                      namebuf, KSYM_NAME_LEN);
                if (modname)
                        *modname = NULL;
                return namebuf;
@@ -315,7 +323,8 @@ int lookup_symbol_name(unsigned long addr, char *symname)
 
                pos = get_symbol_pos(addr, NULL, NULL);
                /* Grab name */
-               kallsyms_expand_symbol(get_symbol_offset(pos), symname);
+               kallsyms_expand_symbol(get_symbol_offset(pos),
+                                      symname, KSYM_NAME_LEN);
                return 0;
        }
        /* See if it's in a module. */
@@ -333,7 +342,8 @@ int lookup_symbol_attrs(unsigned long addr, unsigned long *size,
 
                pos = get_symbol_pos(addr, size, offset);
                /* Grab name */
-               kallsyms_expand_symbol(get_symbol_offset(pos), name);
+               kallsyms_expand_symbol(get_symbol_offset(pos),
+                                      name, KSYM_NAME_LEN);
                modname[0] = '\0';
                return 0;
        }
@@ -463,7 +473,7 @@ static unsigned long get_ksymbol_core(struct kallsym_iter *iter)
 
        iter->type = kallsyms_get_symbol_type(off);
 
-       off = kallsyms_expand_symbol(off, iter->name);
+       off = kallsyms_expand_symbol(off, iter->name, ARRAY_SIZE(iter->name));
 
        return off - iter->nameoff;
 }
index 246b4c6e613505740a86b5640af6ff544cbc9a35..4a9a86d12c8b0711efa1420b8c1c80094ee95e17 100644 (file)
@@ -1,15 +1,8 @@
-/* SYMBOL_PREFIX defined on commandline from CONFIG_SYMBOL_PREFIX */
-#ifndef SYMBOL_PREFIX
-#define ASM_SYMBOL(sym) sym
-#else
-#define PASTE2(x,y) x##y
-#define PASTE(x,y) PASTE2(x,y)
-#define ASM_SYMBOL(sym) PASTE(SYMBOL_PREFIX, sym)
-#endif
+#include <linux/export.h>
 
 #define GLOBAL(name)   \
-       .globl ASM_SYMBOL(name);        \
-       ASM_SYMBOL(name):
+       .globl VMLINUX_SYMBOL(name);    \
+       VMLINUX_SYMBOL(name):
 
        .section ".init.data","aw"
 
index 0925c9a719753f19085ee267edfc643205c752aa..b049939177f6d3a4983341b42eb4719c27b4af62 100644 (file)
@@ -1209,10 +1209,11 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
 
        /* Since this should be found in kernel (which can't be removed),
         * no locking is necessary. */
-       if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL,
+       if (!find_symbol(VMLINUX_SYMBOL_STR(module_layout), NULL,
                         &crc, true, false))
                BUG();
-       return check_version(sechdrs, versindex, "module_layout", mod, crc,
+       return check_version(sechdrs, versindex,
+                            VMLINUX_SYMBOL_STR(module_layout), mod, crc,
                             NULL);
 }
 
@@ -1861,12 +1862,12 @@ static void free_module(struct module *mod)
 {
        trace_module_free(mod);
 
-       /* Delete from various lists */
-       mutex_lock(&module_mutex);
-       stop_machine(__unlink_module, mod, NULL);
-       mutex_unlock(&module_mutex);
        mod_sysfs_teardown(mod);
 
+       /* We leave it in list to prevent duplicate loads, but make sure
+        * that noone uses it while it's being deconstructed. */
+       mod->state = MODULE_STATE_UNFORMED;
+
        /* Remove dynamic debug info */
        ddebug_remove_module(mod->name);
 
@@ -1879,6 +1880,11 @@ static void free_module(struct module *mod)
        /* Free any allocated parameters. */
        destroy_params(mod->kp, mod->num_kp);
 
+       /* Now we can delete it from the lists */
+       mutex_lock(&module_mutex);
+       stop_machine(__unlink_module, mod, NULL);
+       mutex_unlock(&module_mutex);
+
        /* This may be NULL, but that's OK */
        unset_module_init_ro_nx(mod);
        module_free(mod, mod->module_init);
index 0e801c3cdaf8f4173ce5abbf9cee0554374bfbc7..d5d859c8072964014971b9b1401b96f83a183e5d 100644 (file)
@@ -211,7 +211,8 @@ $(obj)/%.i: $(src)/%.c FORCE
 
 cmd_gensymtypes =                                                           \
     $(CPP) -D__GENKSYMS__ $(c_flags) $< |                                   \
-    $(GENKSYMS) $(if $(1), -T $(2)) -a $(ARCH)                              \
+    $(GENKSYMS) $(if $(1), -T $(2))                                         \
+     $(patsubst y,-s _,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX))             \
      $(if $(KBUILD_PRESERVE),-p)                                            \
      -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
 
index 3e73dfd838cdcc546f0839f206d703d2d42c6ac2..51bb3de680b67b78071ae7f9dcc03ae387c52b60 100644 (file)
@@ -119,13 +119,6 @@ _c_flags += $(if $(patsubst n%,, \
                $(CFLAGS_GCOV))
 endif
 
-ifdef CONFIG_SYMBOL_PREFIX
-_sym_flags = -DSYMBOL_PREFIX=$(patsubst "%",%,$(CONFIG_SYMBOL_PREFIX))
-_cpp_flags += $(_sym_flags)
-_a_flags += $(_sym_flags)
-endif
-
-
 # If building the kernel in a separate objtree expand all occurrences
 # of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/').
 
index cf82c832458fb036c1269d01c6df0fd8be18bf1c..8dcdca27d8360107f83c2fdfc70087f9464ccedd 100644 (file)
@@ -60,7 +60,8 @@ kernelsymfile := $(objtree)/Module.symvers
 modulesymfile := $(firstword $(KBUILD_EXTMOD))/Module.symvers
 
 # Step 1), find all modules listed in $(MODVERDIR)/
-__modules := $(sort $(shell grep -h '\.ko$$' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
+MODLISTCMD := find $(MODVERDIR) -name '*.mod' | xargs -r grep -h '\.ko$$' | sort -u
+__modules := $(shell $(MODLISTCMD))
 modules   := $(patsubst %.o,%.ko, $(wildcard $(__modules:.ko=.o)))
 
 # Stop after building .o files if NOFINAL is set. Makes compile tests quicker
@@ -78,12 +79,13 @@ modpost = scripts/mod/modpost                    \
  $(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S)      \
  $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w)
 
+# We can go over command line length here, so be careful.
 quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules
-      cmd_modpost = $(modpost) -s
+      cmd_modpost = $(MODLISTCMD) | sed 's/\.ko$$/.o/' | $(modpost) -s -T -
 
 PHONY += __modpost
 __modpost: $(modules:.ko=.o) FORCE
-       $(call cmd,modpost) $(wildcard vmlinux) $(filter-out FORCE,$^)
+       $(call cmd,modpost) $(wildcard vmlinux)
 
 quiet_cmd_kernel-mod = MODPOST $@
       cmd_kernel-mod = $(modpost) $@
index d25e4a118d3783f52d0bfbd3d74c347b7e1d7c08..88632df4381b933a95c91de0e62c5e8648c4f089 100644 (file)
@@ -45,7 +45,6 @@ int in_source_file;
 
 static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types,
           flag_preserve, flag_warnings;
-static const char *arch = "";
 static const char *mod_prefix = "";
 
 static int errors;
@@ -731,7 +730,7 @@ static void genksyms_usage(void)
 {
        fputs("Usage:\n" "genksyms [-adDTwqhV] > /path/to/.tmp_obj.ver\n" "\n"
 #ifdef __GNU_LIBRARY__
-             "  -a, --arch            Select architecture\n"
+             "  -s, --symbol-prefix   Select symbol prefix\n"
              "  -d, --debug           Increment the debug level (repeatable)\n"
              "  -D, --dump            Dump expanded symbol defs (for debugging only)\n"
              "  -r, --reference file  Read reference symbols from a file\n"
@@ -742,7 +741,7 @@ static void genksyms_usage(void)
              "  -h, --help            Print this message\n"
              "  -V, --version         Print the release version\n"
 #else                          /* __GNU_LIBRARY__ */
-             "  -a                    Select architecture\n"
+             "  -s                    Select symbol prefix\n"
              "  -d                    Increment the debug level (repeatable)\n"
              "  -D                    Dump expanded symbol defs (for debugging only)\n"
              "  -r file               Read reference symbols from a file\n"
@@ -763,7 +762,7 @@ int main(int argc, char **argv)
 
 #ifdef __GNU_LIBRARY__
        struct option long_opts[] = {
-               {"arch", 1, 0, 'a'},
+               {"symbol-prefix", 1, 0, 's'},
                {"debug", 0, 0, 'd'},
                {"warnings", 0, 0, 'w'},
                {"quiet", 0, 0, 'q'},
@@ -776,14 +775,14 @@ int main(int argc, char **argv)
                {0, 0, 0, 0}
        };
 
-       while ((o = getopt_long(argc, argv, "a:dwqVDr:T:ph",
+       while ((o = getopt_long(argc, argv, "s:dwqVDr:T:ph",
                                &long_opts[0], NULL)) != EOF)
 #else                          /* __GNU_LIBRARY__ */
-       while ((o = getopt(argc, argv, "a:dwqVDr:T:ph")) != EOF)
+       while ((o = getopt(argc, argv, "s:dwqVDr:T:ph")) != EOF)
 #endif                         /* __GNU_LIBRARY__ */
                switch (o) {
-               case 'a':
-                       arch = optarg;
+               case 's':
+                       mod_prefix = optarg;
                        break;
                case 'd':
                        flag_debug++;
@@ -826,9 +825,6 @@ int main(int argc, char **argv)
                        genksyms_usage();
                        return 1;
                }
-       if ((strcmp(arch, "h8300") == 0) || (strcmp(arch, "blackfin") == 0) ||
-           (strcmp(arch, "metag") == 0))
-               mod_prefix = "_";
        {
                extern int yydebug;
                extern int yy_flex_debug;
index 3d569d6022c296c7bc5ba4e0162279f4c9dc832c..014994936b1c2152c82f793ce646342159d78eb5 100644 (file)
@@ -74,9 +74,8 @@ kallsyms()
        info KSYM ${2}
        local kallsymopt;
 
-       if [ -n "${CONFIG_SYMBOL_PREFIX}" ]; then
-               kallsymopt="${kallsymopt} \
-                           --symbol-prefix=${CONFIG_SYMBOL_PREFIX}"
+       if [ -n "${CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX}" ]; then
+               kallsymopt="${kallsymopt} --symbol-prefix=_"
        fi
 
        if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then
index 78b30c1548e9d19f5827f4ad26f0715be4b040b0..a4be8e112bb63c2ece5baa423e9aef65c92a1ad1 100644 (file)
 #include <stdio.h>
 #include <ctype.h>
 #include <string.h>
+#include <limits.h>
+#include <stdbool.h>
 #include "modpost.h"
 #include "../../include/generated/autoconf.h"
 #include "../../include/linux/license.h"
-
-/* Some toolchains use a `_' prefix for all user symbols. */
-#ifdef CONFIG_SYMBOL_PREFIX
-#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX
-#else
-#define MODULE_SYMBOL_PREFIX ""
-#endif
-
+#include "../../include/linux/export.h"
 
 /* Are we using CONFIG_MODVERSIONS? */
 int modversions = 0;
@@ -85,6 +80,14 @@ PRINTF void merror(const char *fmt, ...)
        va_end(arglist);
 }
 
+static inline bool strends(const char *str, const char *postfix)
+{
+       if (strlen(str) < strlen(postfix))
+               return false;
+
+       return strcmp(str + strlen(str) - strlen(postfix), postfix) == 0;
+}
+
 static int is_vmlinux(const char *modname)
 {
        const char *myname;
@@ -120,22 +123,20 @@ static struct module *find_module(char *modname)
        return mod;
 }
 
-static struct module *new_module(char *modname)
+static struct module *new_module(const char *modname)
 {
        struct module *mod;
-       char *p, *s;
+       char *p;
 
        mod = NOFAIL(malloc(sizeof(*mod)));
        memset(mod, 0, sizeof(*mod));
        p = NOFAIL(strdup(modname));
 
        /* strip trailing .o */
-       s = strrchr(p, '.');
-       if (s != NULL)
-               if (strcmp(s, ".o") == 0) {
-                       *s = '\0';
-                       mod->is_dot_o = 1;
-               }
+       if (strends(p, ".o")) {
+               p[strlen(p) - 2] = '\0';
+               mod->is_dot_o = 1;
+       }
 
        /* add to list */
        mod->name = p;
@@ -562,7 +563,7 @@ static void parse_elf_finish(struct elf_info *info)
 static int ignore_undef_symbol(struct elf_info *info, const char *symname)
 {
        /* ignore __this_module, it will be resolved shortly */
-       if (strcmp(symname, MODULE_SYMBOL_PREFIX "__this_module") == 0)
+       if (strcmp(symname, VMLINUX_SYMBOL_STR(__this_module)) == 0)
                return 1;
        /* ignore global offset table */
        if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0)
@@ -583,8 +584,8 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname)
        return 0;
 }
 
-#define CRC_PFX     MODULE_SYMBOL_PREFIX "__crc_"
-#define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_"
+#define CRC_PFX     VMLINUX_SYMBOL_STR(__crc_)
+#define KSYMTAB_PFX VMLINUX_SYMBOL_STR(__ksymtab_)
 
 static void handle_modversions(struct module *mod, struct elf_info *info,
                               Elf_Sym *sym, const char *symname)
@@ -637,14 +638,15 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
                }
 #endif
 
-               if (memcmp(symname, MODULE_SYMBOL_PREFIX,
-                          strlen(MODULE_SYMBOL_PREFIX)) == 0) {
-                       mod->unres =
-                         alloc_symbol(symname +
-                                      strlen(MODULE_SYMBOL_PREFIX),
-                                      ELF_ST_BIND(sym->st_info) == STB_WEAK,
-                                      mod->unres);
-               }
+#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX
+               if (symname[0] != '_')
+                       break;
+               else
+                       symname++;
+#endif
+               mod->unres = alloc_symbol(symname,
+                                         ELF_ST_BIND(sym->st_info) == STB_WEAK,
+                                         mod->unres);
                break;
        default:
                /* All exported symbols */
@@ -652,9 +654,9 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
                        sym_add_exported(symname + strlen(KSYMTAB_PFX), mod,
                                        export);
                }
-               if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0)
+               if (strcmp(symname, VMLINUX_SYMBOL_STR(init_module)) == 0)
                        mod->has_init = 1;
-               if (strcmp(symname, MODULE_SYMBOL_PREFIX "cleanup_module") == 0)
+               if (strcmp(symname, VMLINUX_SYMBOL_STR(cleanup_module)) == 0)
                        mod->has_cleanup = 1;
                break;
        }
@@ -1762,6 +1764,27 @@ static void read_symbols(char *modname)
                mod->unres = alloc_symbol("module_layout", 0, mod->unres);
 }
 
+static void read_symbols_from_files(const char *filename)
+{
+       FILE *in = stdin;
+       char fname[PATH_MAX];
+
+       if (strcmp(filename, "-") != 0) {
+               in = fopen(filename, "r");
+               if (!in)
+                       fatal("Can't open filenames file %s: %m", filename);
+       }
+
+       while (fgets(fname, PATH_MAX, in) != NULL) {
+               if (strends(fname, "\n"))
+                       fname[strlen(fname)-1] = '\0';
+               read_symbols(fname);
+       }
+
+       if (in != stdin)
+               fclose(in);
+}
+
 #define SZ 500
 
 /* We first write the generated file into memory using the
@@ -1934,7 +1957,8 @@ static int add_versions(struct buffer *b, struct module *mod)
                                s->name, mod->name);
                        continue;
                }
-               buf_printf(b, "\t{ %#8x, \"%s\" },\n", s->crc, s->name);
+               buf_printf(b, "\t{ %#8x, __VMLINUX_SYMBOL_STR(%s) },\n",
+                          s->crc, s->name);
        }
 
        buf_printf(b, "};\n");
@@ -2122,13 +2146,13 @@ int main(int argc, char **argv)
        struct module *mod;
        struct buffer buf = { };
        char *kernel_read = NULL, *module_read = NULL;
-       char *dump_write = NULL;
+       char *dump_write = NULL, *files_source = NULL;
        int opt;
        int err;
        struct ext_sym_list *extsym_iter;
        struct ext_sym_list *extsym_start = NULL;
 
-       while ((opt = getopt(argc, argv, "i:I:e:msSo:awM:K:")) != -1) {
+       while ((opt = getopt(argc, argv, "i:I:e:msST:o:awM:K:")) != -1) {
                switch (opt) {
                case 'i':
                        kernel_read = optarg;
@@ -2160,6 +2184,9 @@ int main(int argc, char **argv)
                case 'S':
                        sec_mismatch_verbose = 0;
                        break;
+               case 'T':
+                       files_source = optarg;
+                       break;
                case 'w':
                        warn_unresolved = 1;
                        break;
@@ -2182,6 +2209,9 @@ int main(int argc, char **argv)
        while (optind < argc)
                read_symbols(argv[optind++]);
 
+       if (files_source)
+               read_symbols_from_files(files_source);
+
        for (mod = modules; mod; mod = mod->next) {
                if (mod->skip)
                        continue;