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!
 
 Cheers,
 Rusty.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.12 (GNU/Linux)
 
 iQIcBAABAgAGBQJRgbGEAAoJENkgDmzRrbjx2+QP/jXs93K/sXw3rL0vBklwCFv6
 IPZmqYZiGjrzqlB4coWkgYRwW1oOsREfAjF5MmfPdykS3fO5kXfdxN4FBdfKp+IZ
 RdsycdGDuSxWomgYsivrrxLBDxDAX1VuBOjr6mu5Uuk/pCjFa61cfJDiErsu0jKz
 2EMTc98A+E71XamJdvbtal5MUIu9yeluJWG2ux2+VbCul4MSpMc//0n2nrws/RCB
 AoC96AT/Xf4U10a8zT8RfCJ29M5Vvx/KfTIcFiZvtCQxEaHNNmj831gDNiw/3jFI
 ndRph+VLHBsMoBMxfzNRrM+evqkq8+AGEGRj3ycQy5Pa6DunPyzMafWOVGBGnmaS
 tl9hATGx1438048i5tUn8ieAYG1YL1HM83hQovpCThfUKQMiq186iDt1SYYmlq3g
 0thj3znQqZDYhboPtgWzOMUdqOG/iBIKjhGQjjHZs+MInFgxL2hmax0gBNkvEtQb
 oLyfGbF6UjS7I/Md/HohnUQ4xr9kYa3MQeqPjKbRwgHRkdXhzTEZtI+MYDJBxOnW
 QGVQ97aJ2WA7vC7sz/1VhTcZqmU5zfrSc8lF+Ea+H8dQGHHbz8HxKQacEvKcMrXl
 OJyEkRUWDA0MTjeIHzn2fff9Q6/qqA1QejRiFofGJrpxopcJS84/7yA0repxvuMG
 yaMPsLq53UW37/AXYsho
 =MPiD
 -----END PGP SIGNATURE-----

Merge tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux

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.
This commit is contained in:
Linus Torvalds 2013-05-05 10:58:06 -07:00
commit f8ce1faf55
23 changed files with 202 additions and 140 deletions

View File

@ -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 # Run depmod only if we have System.map and depmod is executable
quiet_cmd_depmod = DEPMOD $(KERNELRELEASE) quiet_cmd_depmod = DEPMOD $(KERNELRELEASE)
cmd_depmod = $(CONFIG_SHELL) $(srctree)/scripts/depmod.sh $(DEPMOD) \ 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 # Create temporary dir for module support files
# clean it up only when building all modules # clean it up only when building all modules

View File

@ -381,6 +381,12 @@ config MODULES_USE_ELF_REL
Modules only use ELF REL relocations. Modules with ELF RELA Modules only use ELF REL relocations. Modules with ELF RELA
relocations will give an error. 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 # ABI hall of shame
# #

View File

@ -1,7 +1,3 @@
config SYMBOL_PREFIX
string
default "_"
config MMU config MMU
def_bool n def_bool n
@ -33,6 +29,7 @@ config BLACKFIN
select ARCH_HAVE_CUSTOM_GPIO_H select ARCH_HAVE_CUSTOM_GPIO_H
select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_WANT_OPTIONAL_GPIOLIB
select HAVE_UID16 select HAVE_UID16
select HAVE_UNDERSCORE_SYMBOL_PREFIX
select VIRT_TO_BUS select VIRT_TO_BUS
select ARCH_WANT_IPC_PARSE_VERSION select ARCH_WANT_IPC_PARSE_VERSION
select HAVE_GENERIC_HARDIRQS select HAVE_GENERIC_HARDIRQS

View File

@ -12,10 +12,7 @@ config H8300
select MODULES_USE_ELF_RELA select MODULES_USE_ELF_RELA
select OLD_SIGSUSPEND3 select OLD_SIGSUSPEND3
select OLD_SIGACTION select OLD_SIGACTION
select HAVE_UNDERSCORE_SYMBOL_PREFIX
config SYMBOL_PREFIX
string
default "_"
config MMU config MMU
bool bool

View File

@ -1,7 +1,3 @@
config SYMBOL_PREFIX
string
default "_"
config METAG config METAG
def_bool y def_bool y
select EMBEDDED select EMBEDDED
@ -28,6 +24,7 @@ config METAG
select HAVE_OPROFILE select HAVE_OPROFILE
select HAVE_PERF_EVENTS select HAVE_PERF_EVENTS
select HAVE_SYSCALL_TRACEPOINTS select HAVE_SYSCALL_TRACEPOINTS
select HAVE_UNDERSCORE_SYMBOL_PREFIX
select IRQ_DOMAIN select IRQ_DOMAIN
select MODULES_USE_ELF_RELA select MODULES_USE_ELF_RELA
select OF select OF

View File

@ -373,6 +373,9 @@ int rsa_extract_mpi(void *context, size_t hdrlen,
return 0; 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. * 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) { if (ctx->last_oid == OID_authorityKeyIdentifier) {
size_t key_len;
/* Get hold of the CA key fingerprint */ /* Get hold of the CA key fingerprint */
if (vlen < 5) if (vlen < 5)
return -EBADMSG; return -EBADMSG;
if (v[0] != (ASN1_SEQ | (ASN1_CONS << 5)) ||
v[1] != vlen - 2 ||
v[2] != (ASN1_CONT << 6) ||
v[3] != vlen - 4)
return -EBADMSG;
v += 4;
vlen -= 4;
f = kmalloc(vlen * 2 + 1, GFP_KERNEL); /* Authority Key Identifier must be a Constructed SEQUENCE */
if (v[0] != (ASN1_SEQ | (ASN1_CONS << 5)))
return -EBADMSG;
/* 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) if (!f)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < vlen; i++) for (i = 0; i < key_len; i++)
sprintf(f + i * 2, "%02x", v[i]); sprintf(f + i * 2, "%02x", v[i]);
pr_debug("authority %s\n", f); pr_debug("authority %s\n", f);
ctx->cert->authority = f; ctx->cert->authority = f;

View File

@ -204,14 +204,16 @@ static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map,
struct cfi_private *cfi = map->fldrv_priv; struct cfi_private *cfi = map->fldrv_priv;
__u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID; __u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID;
#ifdef CONFIG_MODULES #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; 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); probe_function = __symbol_get(probename);
if (!probe_function) { 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); probe_function = __symbol_get(probename);
} }

View File

@ -1,4 +1,5 @@
#include <uapi/asm-generic/unistd.h> #include <uapi/asm-generic/unistd.h>
#include <linux/export.h>
/* /*
* These are required system calls, we should * These are required system calls, we should

View File

@ -52,13 +52,7 @@
#define LOAD_OFFSET 0 #define LOAD_OFFSET 0
#endif #endif
#ifndef SYMBOL_PREFIX #include <linux/export.h>
#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
/* Align . to a 8 byte boundary equals to maximum function alignment. */ /* Align . to a 8 byte boundary equals to maximum function alignment. */
#define ALIGN_FUNCTION() . = ALIGN(8) #define ALIGN_FUNCTION() . = ALIGN(8)

View File

@ -5,17 +5,24 @@
* to reduce the amount of pointless cruft we feed to gcc when only * to reduce the amount of pointless cruft we feed to gcc when only
* exporting a simple symbol or two. * exporting a simple symbol or two.
* *
* If you feel the need to add #include <linux/foo.h> to this file * Try not to add #includes here. It slows compilation and makes kernel
* then you are doing something wrong and should go away silently. * hackers place grumpy comments in header files.
*/ */
/* Some toolchains use a `_' prefix for all user symbols. */ /* Some toolchains use a `_' prefix for all user symbols. */
#ifdef CONFIG_SYMBOL_PREFIX #ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX
#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX #define __VMLINUX_SYMBOL(x) _##x
#define __VMLINUX_SYMBOL_STR(x) "_" #x
#else #else
#define MODULE_SYMBOL_PREFIX "" #define __VMLINUX_SYMBOL(x) x
#define __VMLINUX_SYMBOL_STR(x) #x
#endif #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 struct kernel_symbol
{ {
unsigned long value; unsigned long value;
@ -51,7 +58,7 @@ extern struct module __this_module;
__CRC_SYMBOL(sym, sec) \ __CRC_SYMBOL(sym, sec) \
static const char __kstrtab_##sym[] \ static const char __kstrtab_##sym[] \
__attribute__((section("__ksymtab_strings"), aligned(1))) \ __attribute__((section("__ksymtab_strings"), aligned(1))) \
= MODULE_SYMBOL_PREFIX #sym; \ = VMLINUX_SYMBOL_STR(sym); \
static const struct kernel_symbol __ksymtab_##sym \ static const struct kernel_symbol __ksymtab_##sym \
__used \ __used \
__attribute__((section("___ksymtab" sec "+" #sym), unused)) \ __attribute__((section("___ksymtab" sec "+" #sym), unused)) \
@ -85,5 +92,6 @@ extern struct module __this_module;
#define EXPORT_UNUSED_SYMBOL_GPL(sym) #define EXPORT_UNUSED_SYMBOL_GPL(sym)
#endif /* CONFIG_MODULES */ #endif /* CONFIG_MODULES */
#endif /* !__ASSEMBLY__ */
#endif /* _LINUX_EXPORT_H */ #endif /* _LINUX_EXPORT_H */

View File

@ -786,13 +786,6 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
/* Trap pasters of __FUNCTION__ at compile-time */ /* Trap pasters of __FUNCTION__ at compile-time */
#define __FUNCTION__ (__func__) #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 */ /* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */
#ifdef CONFIG_FTRACE_MCOUNT_RECORD #ifdef CONFIG_FTRACE_MCOUNT_RECORD
# define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD # define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD

View File

@ -3,6 +3,7 @@
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/stringify.h> #include <linux/stringify.h>
#include <linux/export.h>
#include <asm/linkage.h> #include <asm/linkage.h>
#ifdef __cplusplus #ifdef __cplusplus
@ -15,21 +16,18 @@
#define asmlinkage CPP_ASMLINKAGE #define asmlinkage CPP_ASMLINKAGE
#endif #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 #ifndef cond_syscall
#define cond_syscall(x) asm(".weak\t" __SYMBOL_NAME(x) \ #define cond_syscall(x) asm( \
"\n\t.set\t" __SYMBOL_NAME(x) "," __SYMBOL_NAME(sys_ni_syscall)); ".weak " VMLINUX_SYMBOL_STR(x) "\n\t" \
".set " VMLINUX_SYMBOL_STR(x) "," \
VMLINUX_SYMBOL_STR(sys_ni_syscall))
#endif #endif
#ifndef SYSCALL_ALIAS #ifndef SYSCALL_ALIAS
#define SYSCALL_ALIAS(alias, name) \ #define SYSCALL_ALIAS(alias, name) asm( \
asm ("\t.globl " __SYMBOL_NAME(alias) \ ".globl " VMLINUX_SYMBOL_STR(alias) "\n\t" \
"\n\t.set\t" __SYMBOL_NAME(alias) "," __SYMBOL_NAME(name)) ".set " VMLINUX_SYMBOL_STR(alias) "," \
VMLINUX_SYMBOL_STR(name))
#endif #endif
#define __page_aligned_data __section(.data..page_aligned) __aligned(PAGE_SIZE) #define __page_aligned_data __section(.data..page_aligned) __aligned(PAGE_SIZE)

View File

@ -190,7 +190,7 @@ extern int modules_disabled; /* for sysctl */
/* Get/put a kernel symbol (calls must be symmetric) */ /* Get/put a kernel symbol (calls must be symmetric) */
void *__symbol_get(const char *symbol); void *__symbol_get(const char *symbol);
void *__symbol_get_gpl(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. */ /* modules using other modules: kdb wants to see this. */
struct module_use { struct module_use {
@ -453,7 +453,7 @@ extern void __module_put_and_exit(struct module *mod, long code)
#ifdef CONFIG_MODULE_UNLOAD #ifdef CONFIG_MODULE_UNLOAD
unsigned long module_refcount(struct module *mod); unsigned long module_refcount(struct module *mod);
void __symbol_put(const char *symbol); 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); void symbol_put_addr(void *addr);
/* Sometimes we know we already have a refcount, and it's easier not /* Sometimes we know we already have a refcount, and it's easier not

View File

@ -176,7 +176,7 @@ signing_key.priv signing_key.x509: x509.genkey
openssl req -new -nodes -utf8 -$(CONFIG_MODULE_SIG_HASH) -days 36500 \ openssl req -new -nodes -utf8 -$(CONFIG_MODULE_SIG_HASH) -days 36500 \
-batch -x509 -config x509.genkey \ -batch -x509 -config x509.genkey \
-outform DER -out signing_key.x509 \ -outform DER -out signing_key.x509 \
-keyout signing_key.priv -keyout signing_key.priv 2>&1
@echo "###" @echo "###"
@echo "### Key pair generated." @echo "### Key pair generated."
@echo "###" @echo "###"

View File

@ -84,9 +84,11 @@ static int is_ksym_addr(unsigned long addr)
/* /*
* Expand a compressed symbol data into the resulting uncompressed string, * 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. * 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; int len, skipped_first = 0;
const u8 *tptr, *data; const u8 *tptr, *data;
@ -113,14 +115,19 @@ static unsigned int kallsyms_expand_symbol(unsigned int off, char *result)
while (*tptr) { while (*tptr) {
if (skipped_first) { if (skipped_first) {
if (maxlen <= 1)
goto tail;
*result = *tptr; *result = *tptr;
result++; result++;
maxlen--;
} else } else
skipped_first = 1; skipped_first = 1;
tptr++; tptr++;
} }
} }
tail:
if (maxlen)
*result = '\0'; *result = '\0';
/* Return to offset to the next symbol. */ /* Return to offset to the next symbol. */
@ -176,7 +183,7 @@ unsigned long kallsyms_lookup_name(const char *name)
unsigned int off; unsigned int off;
for (i = 0, off = 0; i < kallsyms_num_syms; i++) { 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) if (strcmp(namebuf, name) == 0)
return kallsyms_addresses[i]; return kallsyms_addresses[i];
@ -195,7 +202,7 @@ int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
int ret; int ret;
for (i = 0, off = 0; i < kallsyms_num_syms; i++) { 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]); ret = fn(data, namebuf, NULL, kallsyms_addresses[i]);
if (ret != 0) if (ret != 0)
return ret; return ret;
@ -294,7 +301,8 @@ const char *kallsyms_lookup(unsigned long addr,
pos = get_symbol_pos(addr, symbolsize, offset); pos = get_symbol_pos(addr, symbolsize, offset);
/* Grab name */ /* Grab name */
kallsyms_expand_symbol(get_symbol_offset(pos), namebuf); kallsyms_expand_symbol(get_symbol_offset(pos),
namebuf, KSYM_NAME_LEN);
if (modname) if (modname)
*modname = NULL; *modname = NULL;
return namebuf; return namebuf;
@ -315,7 +323,8 @@ int lookup_symbol_name(unsigned long addr, char *symname)
pos = get_symbol_pos(addr, NULL, NULL); pos = get_symbol_pos(addr, NULL, NULL);
/* Grab name */ /* Grab name */
kallsyms_expand_symbol(get_symbol_offset(pos), symname); kallsyms_expand_symbol(get_symbol_offset(pos),
symname, KSYM_NAME_LEN);
return 0; return 0;
} }
/* See if it's in a module. */ /* 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); pos = get_symbol_pos(addr, size, offset);
/* Grab name */ /* Grab name */
kallsyms_expand_symbol(get_symbol_offset(pos), name); kallsyms_expand_symbol(get_symbol_offset(pos),
name, KSYM_NAME_LEN);
modname[0] = '\0'; modname[0] = '\0';
return 0; return 0;
} }
@ -463,7 +473,7 @@ static unsigned long get_ksymbol_core(struct kallsym_iter *iter)
iter->type = kallsyms_get_symbol_type(off); 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; return off - iter->nameoff;
} }

View File

@ -1,15 +1,8 @@
/* SYMBOL_PREFIX defined on commandline from CONFIG_SYMBOL_PREFIX */ #include <linux/export.h>
#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
#define GLOBAL(name) \ #define GLOBAL(name) \
.globl ASM_SYMBOL(name); \ .globl VMLINUX_SYMBOL(name); \
ASM_SYMBOL(name): VMLINUX_SYMBOL(name):
.section ".init.data","aw" .section ".init.data","aw"

View 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), /* Since this should be found in kernel (which can't be removed),
* no locking is necessary. */ * 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)) &crc, true, false))
BUG(); BUG();
return check_version(sechdrs, versindex, "module_layout", mod, crc, return check_version(sechdrs, versindex,
VMLINUX_SYMBOL_STR(module_layout), mod, crc,
NULL); NULL);
} }
@ -1861,12 +1862,12 @@ static void free_module(struct module *mod)
{ {
trace_module_free(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); 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 */ /* Remove dynamic debug info */
ddebug_remove_module(mod->name); ddebug_remove_module(mod->name);
@ -1879,6 +1880,11 @@ static void free_module(struct module *mod)
/* Free any allocated parameters. */ /* Free any allocated parameters. */
destroy_params(mod->kp, mod->num_kp); 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 */ /* This may be NULL, but that's OK */
unset_module_init_ro_nx(mod); unset_module_init_ro_nx(mod);
module_free(mod, mod->module_init); module_free(mod, mod->module_init);

View File

@ -211,7 +211,8 @@ $(obj)/%.i: $(src)/%.c FORCE
cmd_gensymtypes = \ cmd_gensymtypes = \
$(CPP) -D__GENKSYMS__ $(c_flags) $< | \ $(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) \ $(if $(KBUILD_PRESERVE),-p) \
-r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null)) -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))

View File

@ -119,13 +119,6 @@ _c_flags += $(if $(patsubst n%,, \
$(CFLAGS_GCOV)) $(CFLAGS_GCOV))
endif 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 # If building the kernel in a separate objtree expand all occurrences
# of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/'). # of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/').

View File

@ -60,7 +60,8 @@ kernelsymfile := $(objtree)/Module.symvers
modulesymfile := $(firstword $(KBUILD_EXTMOD))/Module.symvers modulesymfile := $(firstword $(KBUILD_EXTMOD))/Module.symvers
# Step 1), find all modules listed in $(MODVERDIR)/ # 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))) modules := $(patsubst %.o,%.ko, $(wildcard $(__modules:.ko=.o)))
# Stop after building .o files if NOFINAL is set. Makes compile tests quicker # 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 $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \
$(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) $(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 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 PHONY += __modpost
__modpost: $(modules:.ko=.o) FORCE __modpost: $(modules:.ko=.o) FORCE
$(call cmd,modpost) $(wildcard vmlinux) $(filter-out FORCE,$^) $(call cmd,modpost) $(wildcard vmlinux)
quiet_cmd_kernel-mod = MODPOST $@ quiet_cmd_kernel-mod = MODPOST $@
cmd_kernel-mod = $(modpost) $@ cmd_kernel-mod = $(modpost) $@

View File

@ -45,7 +45,6 @@ int in_source_file;
static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types, static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types,
flag_preserve, flag_warnings; flag_preserve, flag_warnings;
static const char *arch = "";
static const char *mod_prefix = ""; static const char *mod_prefix = "";
static int errors; static int errors;
@ -731,7 +730,7 @@ static void genksyms_usage(void)
{ {
fputs("Usage:\n" "genksyms [-adDTwqhV] > /path/to/.tmp_obj.ver\n" "\n" fputs("Usage:\n" "genksyms [-adDTwqhV] > /path/to/.tmp_obj.ver\n" "\n"
#ifdef __GNU_LIBRARY__ #ifdef __GNU_LIBRARY__
" -a, --arch Select architecture\n" " -s, --symbol-prefix Select symbol prefix\n"
" -d, --debug Increment the debug level (repeatable)\n" " -d, --debug Increment the debug level (repeatable)\n"
" -D, --dump Dump expanded symbol defs (for debugging only)\n" " -D, --dump Dump expanded symbol defs (for debugging only)\n"
" -r, --reference file Read reference symbols from a file\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" " -h, --help Print this message\n"
" -V, --version Print the release version\n" " -V, --version Print the release version\n"
#else /* __GNU_LIBRARY__ */ #else /* __GNU_LIBRARY__ */
" -a Select architecture\n" " -s Select symbol prefix\n"
" -d Increment the debug level (repeatable)\n" " -d Increment the debug level (repeatable)\n"
" -D Dump expanded symbol defs (for debugging only)\n" " -D Dump expanded symbol defs (for debugging only)\n"
" -r file Read reference symbols from a file\n" " -r file Read reference symbols from a file\n"
@ -763,7 +762,7 @@ int main(int argc, char **argv)
#ifdef __GNU_LIBRARY__ #ifdef __GNU_LIBRARY__
struct option long_opts[] = { struct option long_opts[] = {
{"arch", 1, 0, 'a'}, {"symbol-prefix", 1, 0, 's'},
{"debug", 0, 0, 'd'}, {"debug", 0, 0, 'd'},
{"warnings", 0, 0, 'w'}, {"warnings", 0, 0, 'w'},
{"quiet", 0, 0, 'q'}, {"quiet", 0, 0, 'q'},
@ -776,14 +775,14 @@ int main(int argc, char **argv)
{0, 0, 0, 0} {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) &long_opts[0], NULL)) != EOF)
#else /* __GNU_LIBRARY__ */ #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__ */ #endif /* __GNU_LIBRARY__ */
switch (o) { switch (o) {
case 'a': case 's':
arch = optarg; mod_prefix = optarg;
break; break;
case 'd': case 'd':
flag_debug++; flag_debug++;
@ -826,9 +825,6 @@ int main(int argc, char **argv)
genksyms_usage(); genksyms_usage();
return 1; return 1;
} }
if ((strcmp(arch, "h8300") == 0) || (strcmp(arch, "blackfin") == 0) ||
(strcmp(arch, "metag") == 0))
mod_prefix = "_";
{ {
extern int yydebug; extern int yydebug;
extern int yy_flex_debug; extern int yy_flex_debug;

View File

@ -74,9 +74,8 @@ kallsyms()
info KSYM ${2} info KSYM ${2}
local kallsymopt; local kallsymopt;
if [ -n "${CONFIG_SYMBOL_PREFIX}" ]; then if [ -n "${CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX}" ]; then
kallsymopt="${kallsymopt} \ kallsymopt="${kallsymopt} --symbol-prefix=_"
--symbol-prefix=${CONFIG_SYMBOL_PREFIX}"
fi fi
if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then

View File

@ -15,17 +15,12 @@
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <limits.h>
#include <stdbool.h>
#include "modpost.h" #include "modpost.h"
#include "../../include/generated/autoconf.h" #include "../../include/generated/autoconf.h"
#include "../../include/linux/license.h" #include "../../include/linux/license.h"
#include "../../include/linux/export.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
/* Are we using CONFIG_MODVERSIONS? */ /* Are we using CONFIG_MODVERSIONS? */
int modversions = 0; int modversions = 0;
@ -85,6 +80,14 @@ PRINTF void merror(const char *fmt, ...)
va_end(arglist); 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) static int is_vmlinux(const char *modname)
{ {
const char *myname; const char *myname;
@ -120,20 +123,18 @@ static struct module *find_module(char *modname)
return mod; return mod;
} }
static struct module *new_module(char *modname) static struct module *new_module(const char *modname)
{ {
struct module *mod; struct module *mod;
char *p, *s; char *p;
mod = NOFAIL(malloc(sizeof(*mod))); mod = NOFAIL(malloc(sizeof(*mod)));
memset(mod, 0, sizeof(*mod)); memset(mod, 0, sizeof(*mod));
p = NOFAIL(strdup(modname)); p = NOFAIL(strdup(modname));
/* strip trailing .o */ /* strip trailing .o */
s = strrchr(p, '.'); if (strends(p, ".o")) {
if (s != NULL) p[strlen(p) - 2] = '\0';
if (strcmp(s, ".o") == 0) {
*s = '\0';
mod->is_dot_o = 1; mod->is_dot_o = 1;
} }
@ -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) static int ignore_undef_symbol(struct elf_info *info, const char *symname)
{ {
/* ignore __this_module, it will be resolved shortly */ /* 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; return 1;
/* ignore global offset table */ /* ignore global offset table */
if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0) 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; return 0;
} }
#define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_" #define CRC_PFX VMLINUX_SYMBOL_STR(__crc_)
#define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_" #define KSYMTAB_PFX VMLINUX_SYMBOL_STR(__ksymtab_)
static void handle_modversions(struct module *mod, struct elf_info *info, static void handle_modversions(struct module *mod, struct elf_info *info,
Elf_Sym *sym, const char *symname) Elf_Sym *sym, const char *symname)
@ -637,14 +638,15 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
} }
#endif #endif
if (memcmp(symname, MODULE_SYMBOL_PREFIX, #ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX
strlen(MODULE_SYMBOL_PREFIX)) == 0) { if (symname[0] != '_')
mod->unres = break;
alloc_symbol(symname + else
strlen(MODULE_SYMBOL_PREFIX), symname++;
#endif
mod->unres = alloc_symbol(symname,
ELF_ST_BIND(sym->st_info) == STB_WEAK, ELF_ST_BIND(sym->st_info) == STB_WEAK,
mod->unres); mod->unres);
}
break; break;
default: default:
/* All exported symbols */ /* 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, sym_add_exported(symname + strlen(KSYMTAB_PFX), mod,
export); export);
} }
if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0) if (strcmp(symname, VMLINUX_SYMBOL_STR(init_module)) == 0)
mod->has_init = 1; 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; mod->has_cleanup = 1;
break; break;
} }
@ -1762,6 +1764,27 @@ static void read_symbols(char *modname)
mod->unres = alloc_symbol("module_layout", 0, mod->unres); 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 #define SZ 500
/* We first write the generated file into memory using the /* 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); s->name, mod->name);
continue; 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"); buf_printf(b, "};\n");
@ -2122,13 +2146,13 @@ int main(int argc, char **argv)
struct module *mod; struct module *mod;
struct buffer buf = { }; struct buffer buf = { };
char *kernel_read = NULL, *module_read = NULL; char *kernel_read = NULL, *module_read = NULL;
char *dump_write = NULL; char *dump_write = NULL, *files_source = NULL;
int opt; int opt;
int err; int err;
struct ext_sym_list *extsym_iter; struct ext_sym_list *extsym_iter;
struct ext_sym_list *extsym_start = NULL; 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) { switch (opt) {
case 'i': case 'i':
kernel_read = optarg; kernel_read = optarg;
@ -2160,6 +2184,9 @@ int main(int argc, char **argv)
case 'S': case 'S':
sec_mismatch_verbose = 0; sec_mismatch_verbose = 0;
break; break;
case 'T':
files_source = optarg;
break;
case 'w': case 'w':
warn_unresolved = 1; warn_unresolved = 1;
break; break;
@ -2182,6 +2209,9 @@ int main(int argc, char **argv)
while (optind < argc) while (optind < argc)
read_symbols(argv[optind++]); read_symbols(argv[optind++]);
if (files_source)
read_symbols_from_files(files_source);
for (mod = modules; mod; mod = mod->next) { for (mod = modules; mod; mod = mod->next) {
if (mod->skip) if (mod->skip)
continue; continue;