Commit f8ce1faf55955de62e0a12e330c6d9a526071f65
Exists in
master
and in
20 other branches
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.
Showing 23 changed files Side-by-side Diff
- 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
Makefile
... | ... | @@ -1399,7 +1399,7 @@ |
1399 | 1399 | # Run depmod only if we have System.map and depmod is executable |
1400 | 1400 | quiet_cmd_depmod = DEPMOD $(KERNELRELEASE) |
1401 | 1401 | cmd_depmod = $(CONFIG_SHELL) $(srctree)/scripts/depmod.sh $(DEPMOD) \ |
1402 | - $(KERNELRELEASE) "$(patsubst "%",%,$(CONFIG_SYMBOL_PREFIX))" | |
1402 | + $(KERNELRELEASE) "$(patsubst y,_,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX))" | |
1403 | 1403 | |
1404 | 1404 | # Create temporary dir for module support files |
1405 | 1405 | # clean it up only when building all modules |
arch/Kconfig
... | ... | @@ -381,6 +381,12 @@ |
381 | 381 | Modules only use ELF REL relocations. Modules with ELF RELA |
382 | 382 | relocations will give an error. |
383 | 383 | |
384 | +config HAVE_UNDERSCORE_SYMBOL_PREFIX | |
385 | + bool | |
386 | + help | |
387 | + Some architectures generate an _ in front of C symbols; things like | |
388 | + module loading and assembly files need to know about this. | |
389 | + | |
384 | 390 | # |
385 | 391 | # ABI hall of shame |
386 | 392 | # |
arch/blackfin/Kconfig
1 | -config SYMBOL_PREFIX | |
2 | - string | |
3 | - default "_" | |
4 | - | |
5 | 1 | config MMU |
6 | 2 | def_bool n |
7 | 3 | |
... | ... | @@ -33,6 +29,7 @@ |
33 | 29 | select ARCH_HAVE_CUSTOM_GPIO_H |
34 | 30 | select ARCH_WANT_OPTIONAL_GPIOLIB |
35 | 31 | select HAVE_UID16 |
32 | + select HAVE_UNDERSCORE_SYMBOL_PREFIX | |
36 | 33 | select VIRT_TO_BUS |
37 | 34 | select ARCH_WANT_IPC_PARSE_VERSION |
38 | 35 | select HAVE_GENERIC_HARDIRQS |
arch/h8300/Kconfig
arch/metag/Kconfig
1 | -config SYMBOL_PREFIX | |
2 | - string | |
3 | - default "_" | |
4 | - | |
5 | 1 | config METAG |
6 | 2 | def_bool y |
7 | 3 | select EMBEDDED |
... | ... | @@ -28,6 +24,7 @@ |
28 | 24 | select HAVE_OPROFILE |
29 | 25 | select HAVE_PERF_EVENTS |
30 | 26 | select HAVE_SYSCALL_TRACEPOINTS |
27 | + select HAVE_UNDERSCORE_SYMBOL_PREFIX | |
31 | 28 | select IRQ_DOMAIN |
32 | 29 | select MODULES_USE_ELF_RELA |
33 | 30 | select OF |
crypto/asymmetric_keys/x509_cert_parser.c
... | ... | @@ -373,6 +373,9 @@ |
373 | 373 | return 0; |
374 | 374 | } |
375 | 375 | |
376 | +/* The keyIdentifier in AuthorityKeyIdentifier SEQUENCE is tag(CONT,PRIM,0) */ | |
377 | +#define SEQ_TAG_KEYID (ASN1_CONT << 6) | |
378 | + | |
376 | 379 | /* |
377 | 380 | * Process certificate extensions that are used to qualify the certificate. |
378 | 381 | */ |
379 | 382 | |
380 | 383 | |
381 | 384 | |
382 | 385 | |
... | ... | @@ -407,21 +410,57 @@ |
407 | 410 | } |
408 | 411 | |
409 | 412 | if (ctx->last_oid == OID_authorityKeyIdentifier) { |
413 | + size_t key_len; | |
414 | + | |
410 | 415 | /* Get hold of the CA key fingerprint */ |
411 | 416 | if (vlen < 5) |
412 | 417 | return -EBADMSG; |
413 | - if (v[0] != (ASN1_SEQ | (ASN1_CONS << 5)) || | |
414 | - v[1] != vlen - 2 || | |
415 | - v[2] != (ASN1_CONT << 6) || | |
416 | - v[3] != vlen - 4) | |
418 | + | |
419 | + /* Authority Key Identifier must be a Constructed SEQUENCE */ | |
420 | + if (v[0] != (ASN1_SEQ | (ASN1_CONS << 5))) | |
417 | 421 | return -EBADMSG; |
418 | - v += 4; | |
419 | - vlen -= 4; | |
420 | 422 | |
421 | - f = kmalloc(vlen * 2 + 1, GFP_KERNEL); | |
423 | + /* Authority Key Identifier is not indefinite length */ | |
424 | + if (unlikely(vlen == ASN1_INDEFINITE_LENGTH)) | |
425 | + return -EBADMSG; | |
426 | + | |
427 | + if (vlen < ASN1_INDEFINITE_LENGTH) { | |
428 | + /* Short Form length */ | |
429 | + if (v[1] != vlen - 2 || | |
430 | + v[2] != SEQ_TAG_KEYID || | |
431 | + v[3] > vlen - 4) | |
432 | + return -EBADMSG; | |
433 | + | |
434 | + key_len = v[3]; | |
435 | + v += 4; | |
436 | + } else { | |
437 | + /* Long Form length */ | |
438 | + size_t seq_len = 0; | |
439 | + size_t sub = v[1] - ASN1_INDEFINITE_LENGTH; | |
440 | + | |
441 | + if (sub > 2) | |
442 | + return -EBADMSG; | |
443 | + | |
444 | + /* calculate the length from subsequent octets */ | |
445 | + v += 2; | |
446 | + for (i = 0; i < sub; i++) { | |
447 | + seq_len <<= 8; | |
448 | + seq_len |= v[i]; | |
449 | + } | |
450 | + | |
451 | + if (seq_len != vlen - 2 - sub || | |
452 | + v[sub] != SEQ_TAG_KEYID || | |
453 | + v[sub + 1] > vlen - 4 - sub) | |
454 | + return -EBADMSG; | |
455 | + | |
456 | + key_len = v[sub + 1]; | |
457 | + v += (sub + 2); | |
458 | + } | |
459 | + | |
460 | + f = kmalloc(key_len * 2 + 1, GFP_KERNEL); | |
422 | 461 | if (!f) |
423 | 462 | return -ENOMEM; |
424 | - for (i = 0; i < vlen; i++) | |
463 | + for (i = 0; i < key_len; i++) | |
425 | 464 | sprintf(f + i * 2, "%02x", v[i]); |
426 | 465 | pr_debug("authority %s\n", f); |
427 | 466 | ctx->cert->authority = f; |
drivers/mtd/chips/gen_probe.c
... | ... | @@ -204,14 +204,16 @@ |
204 | 204 | struct cfi_private *cfi = map->fldrv_priv; |
205 | 205 | __u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID; |
206 | 206 | #ifdef CONFIG_MODULES |
207 | - char probename[16+sizeof(MODULE_SYMBOL_PREFIX)]; | |
207 | + char probename[sizeof(VMLINUX_SYMBOL_STR(cfi_cmdset_%4.4X))]; | |
208 | 208 | cfi_cmdset_fn_t *probe_function; |
209 | 209 | |
210 | - sprintf(probename, MODULE_SYMBOL_PREFIX "cfi_cmdset_%4.4X", type); | |
210 | + sprintf(probename, VMLINUX_SYMBOL_STR(cfi_cmdset_%4.4X), type); | |
211 | 211 | |
212 | 212 | probe_function = __symbol_get(probename); |
213 | 213 | if (!probe_function) { |
214 | - request_module(probename + sizeof(MODULE_SYMBOL_PREFIX) - 1); | |
214 | + char modname[sizeof("cfi_cmdset_%4.4X")]; | |
215 | + sprintf(modname, "cfi_cmdset_%4.4X", type); | |
216 | + request_module(modname); | |
215 | 217 | probe_function = __symbol_get(probename); |
216 | 218 | } |
217 | 219 |
include/asm-generic/unistd.h
include/asm-generic/vmlinux.lds.h
... | ... | @@ -52,13 +52,7 @@ |
52 | 52 | #define LOAD_OFFSET 0 |
53 | 53 | #endif |
54 | 54 | |
55 | -#ifndef SYMBOL_PREFIX | |
56 | -#define VMLINUX_SYMBOL(sym) sym | |
57 | -#else | |
58 | -#define PASTE2(x,y) x##y | |
59 | -#define PASTE(x,y) PASTE2(x,y) | |
60 | -#define VMLINUX_SYMBOL(sym) PASTE(SYMBOL_PREFIX, sym) | |
61 | -#endif | |
55 | +#include <linux/export.h> | |
62 | 56 | |
63 | 57 | /* Align . to a 8 byte boundary equals to maximum function alignment. */ |
64 | 58 | #define ALIGN_FUNCTION() . = ALIGN(8) |
include/linux/export.h
... | ... | @@ -5,17 +5,24 @@ |
5 | 5 | * to reduce the amount of pointless cruft we feed to gcc when only |
6 | 6 | * exporting a simple symbol or two. |
7 | 7 | * |
8 | - * If you feel the need to add #include <linux/foo.h> to this file | |
9 | - * then you are doing something wrong and should go away silently. | |
8 | + * Try not to add #includes here. It slows compilation and makes kernel | |
9 | + * hackers place grumpy comments in header files. | |
10 | 10 | */ |
11 | 11 | |
12 | 12 | /* Some toolchains use a `_' prefix for all user symbols. */ |
13 | -#ifdef CONFIG_SYMBOL_PREFIX | |
14 | -#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX | |
13 | +#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX | |
14 | +#define __VMLINUX_SYMBOL(x) _##x | |
15 | +#define __VMLINUX_SYMBOL_STR(x) "_" #x | |
15 | 16 | #else |
16 | -#define MODULE_SYMBOL_PREFIX "" | |
17 | +#define __VMLINUX_SYMBOL(x) x | |
18 | +#define __VMLINUX_SYMBOL_STR(x) #x | |
17 | 19 | #endif |
18 | 20 | |
21 | +/* Indirect, so macros are expanded before pasting. */ | |
22 | +#define VMLINUX_SYMBOL(x) __VMLINUX_SYMBOL(x) | |
23 | +#define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) | |
24 | + | |
25 | +#ifndef __ASSEMBLY__ | |
19 | 26 | struct kernel_symbol |
20 | 27 | { |
21 | 28 | unsigned long value; |
... | ... | @@ -51,7 +58,7 @@ |
51 | 58 | __CRC_SYMBOL(sym, sec) \ |
52 | 59 | static const char __kstrtab_##sym[] \ |
53 | 60 | __attribute__((section("__ksymtab_strings"), aligned(1))) \ |
54 | - = MODULE_SYMBOL_PREFIX #sym; \ | |
61 | + = VMLINUX_SYMBOL_STR(sym); \ | |
55 | 62 | static const struct kernel_symbol __ksymtab_##sym \ |
56 | 63 | __used \ |
57 | 64 | __attribute__((section("___ksymtab" sec "+" #sym), unused)) \ |
... | ... | @@ -85,6 +92,7 @@ |
85 | 92 | #define EXPORT_UNUSED_SYMBOL_GPL(sym) |
86 | 93 | |
87 | 94 | #endif /* CONFIG_MODULES */ |
95 | +#endif /* !__ASSEMBLY__ */ | |
88 | 96 | |
89 | 97 | #endif /* _LINUX_EXPORT_H */ |
include/linux/kernel.h
... | ... | @@ -786,13 +786,6 @@ |
786 | 786 | /* Trap pasters of __FUNCTION__ at compile-time */ |
787 | 787 | #define __FUNCTION__ (__func__) |
788 | 788 | |
789 | -/* This helps us to avoid #ifdef CONFIG_SYMBOL_PREFIX */ | |
790 | -#ifdef CONFIG_SYMBOL_PREFIX | |
791 | -#define SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX | |
792 | -#else | |
793 | -#define SYMBOL_PREFIX "" | |
794 | -#endif | |
795 | - | |
796 | 789 | /* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */ |
797 | 790 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD |
798 | 791 | # define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD |
include/linux/linkage.h
... | ... | @@ -3,6 +3,7 @@ |
3 | 3 | |
4 | 4 | #include <linux/compiler.h> |
5 | 5 | #include <linux/stringify.h> |
6 | +#include <linux/export.h> | |
6 | 7 | #include <asm/linkage.h> |
7 | 8 | |
8 | 9 | #ifdef __cplusplus |
9 | 10 | |
10 | 11 | |
... | ... | @@ -15,21 +16,18 @@ |
15 | 16 | #define asmlinkage CPP_ASMLINKAGE |
16 | 17 | #endif |
17 | 18 | |
18 | -#ifdef CONFIG_SYMBOL_PREFIX | |
19 | -#define __SYMBOL_NAME(x) CONFIG_SYMBOL_PREFIX __stringify(x) | |
20 | -#else | |
21 | -#define __SYMBOL_NAME(x) __stringify(x) | |
22 | -#endif | |
23 | - | |
24 | 19 | #ifndef cond_syscall |
25 | -#define cond_syscall(x) asm(".weak\t" __SYMBOL_NAME(x) \ | |
26 | - "\n\t.set\t" __SYMBOL_NAME(x) "," __SYMBOL_NAME(sys_ni_syscall)); | |
20 | +#define cond_syscall(x) asm( \ | |
21 | + ".weak " VMLINUX_SYMBOL_STR(x) "\n\t" \ | |
22 | + ".set " VMLINUX_SYMBOL_STR(x) "," \ | |
23 | + VMLINUX_SYMBOL_STR(sys_ni_syscall)) | |
27 | 24 | #endif |
28 | 25 | |
29 | 26 | #ifndef SYSCALL_ALIAS |
30 | -#define SYSCALL_ALIAS(alias, name) \ | |
31 | - asm ("\t.globl " __SYMBOL_NAME(alias) \ | |
32 | - "\n\t.set\t" __SYMBOL_NAME(alias) "," __SYMBOL_NAME(name)) | |
27 | +#define SYSCALL_ALIAS(alias, name) asm( \ | |
28 | + ".globl " VMLINUX_SYMBOL_STR(alias) "\n\t" \ | |
29 | + ".set " VMLINUX_SYMBOL_STR(alias) "," \ | |
30 | + VMLINUX_SYMBOL_STR(name)) | |
33 | 31 | #endif |
34 | 32 | |
35 | 33 | #define __page_aligned_data __section(.data..page_aligned) __aligned(PAGE_SIZE) |
include/linux/module.h
... | ... | @@ -190,7 +190,7 @@ |
190 | 190 | /* Get/put a kernel symbol (calls must be symmetric) */ |
191 | 191 | void *__symbol_get(const char *symbol); |
192 | 192 | void *__symbol_get_gpl(const char *symbol); |
193 | -#define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x))) | |
193 | +#define symbol_get(x) ((typeof(&x))(__symbol_get(VMLINUX_SYMBOL_STR(x)))) | |
194 | 194 | |
195 | 195 | /* modules using other modules: kdb wants to see this. */ |
196 | 196 | struct module_use { |
... | ... | @@ -453,7 +453,7 @@ |
453 | 453 | #ifdef CONFIG_MODULE_UNLOAD |
454 | 454 | unsigned long module_refcount(struct module *mod); |
455 | 455 | void __symbol_put(const char *symbol); |
456 | -#define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x) | |
456 | +#define symbol_put(x) __symbol_put(VMLINUX_SYMBOL_STR(x)) | |
457 | 457 | void symbol_put_addr(void *addr); |
458 | 458 | |
459 | 459 | /* Sometimes we know we already have a refcount, and it's easier not |
kernel/Makefile
... | ... | @@ -176,7 +176,7 @@ |
176 | 176 | openssl req -new -nodes -utf8 -$(CONFIG_MODULE_SIG_HASH) -days 36500 \ |
177 | 177 | -batch -x509 -config x509.genkey \ |
178 | 178 | -outform DER -out signing_key.x509 \ |
179 | - -keyout signing_key.priv | |
179 | + -keyout signing_key.priv 2>&1 | |
180 | 180 | @echo "###" |
181 | 181 | @echo "### Key pair generated." |
182 | 182 | @echo "###" |
kernel/kallsyms.c
... | ... | @@ -84,9 +84,11 @@ |
84 | 84 | |
85 | 85 | /* |
86 | 86 | * Expand a compressed symbol data into the resulting uncompressed string, |
87 | + * if uncompressed string is too long (>= maxlen), it will be truncated, | |
87 | 88 | * given the offset to where the symbol is in the compressed stream. |
88 | 89 | */ |
89 | -static unsigned int kallsyms_expand_symbol(unsigned int off, char *result) | |
90 | +static unsigned int kallsyms_expand_symbol(unsigned int off, | |
91 | + char *result, size_t maxlen) | |
90 | 92 | { |
91 | 93 | int len, skipped_first = 0; |
92 | 94 | const u8 *tptr, *data; |
93 | 95 | |
94 | 96 | |
... | ... | @@ -113,15 +115,20 @@ |
113 | 115 | |
114 | 116 | while (*tptr) { |
115 | 117 | if (skipped_first) { |
118 | + if (maxlen <= 1) | |
119 | + goto tail; | |
116 | 120 | *result = *tptr; |
117 | 121 | result++; |
122 | + maxlen--; | |
118 | 123 | } else |
119 | 124 | skipped_first = 1; |
120 | 125 | tptr++; |
121 | 126 | } |
122 | 127 | } |
123 | 128 | |
124 | - *result = '\0'; | |
129 | +tail: | |
130 | + if (maxlen) | |
131 | + *result = '\0'; | |
125 | 132 | |
126 | 133 | /* Return to offset to the next symbol. */ |
127 | 134 | return off; |
... | ... | @@ -176,7 +183,7 @@ |
176 | 183 | unsigned int off; |
177 | 184 | |
178 | 185 | for (i = 0, off = 0; i < kallsyms_num_syms; i++) { |
179 | - off = kallsyms_expand_symbol(off, namebuf); | |
186 | + off = kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf)); | |
180 | 187 | |
181 | 188 | if (strcmp(namebuf, name) == 0) |
182 | 189 | return kallsyms_addresses[i]; |
... | ... | @@ -195,7 +202,7 @@ |
195 | 202 | int ret; |
196 | 203 | |
197 | 204 | for (i = 0, off = 0; i < kallsyms_num_syms; i++) { |
198 | - off = kallsyms_expand_symbol(off, namebuf); | |
205 | + off = kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf)); | |
199 | 206 | ret = fn(data, namebuf, NULL, kallsyms_addresses[i]); |
200 | 207 | if (ret != 0) |
201 | 208 | return ret; |
... | ... | @@ -294,7 +301,8 @@ |
294 | 301 | |
295 | 302 | pos = get_symbol_pos(addr, symbolsize, offset); |
296 | 303 | /* Grab name */ |
297 | - kallsyms_expand_symbol(get_symbol_offset(pos), namebuf); | |
304 | + kallsyms_expand_symbol(get_symbol_offset(pos), | |
305 | + namebuf, KSYM_NAME_LEN); | |
298 | 306 | if (modname) |
299 | 307 | *modname = NULL; |
300 | 308 | return namebuf; |
... | ... | @@ -315,7 +323,8 @@ |
315 | 323 | |
316 | 324 | pos = get_symbol_pos(addr, NULL, NULL); |
317 | 325 | /* Grab name */ |
318 | - kallsyms_expand_symbol(get_symbol_offset(pos), symname); | |
326 | + kallsyms_expand_symbol(get_symbol_offset(pos), | |
327 | + symname, KSYM_NAME_LEN); | |
319 | 328 | return 0; |
320 | 329 | } |
321 | 330 | /* See if it's in a module. */ |
... | ... | @@ -333,7 +342,8 @@ |
333 | 342 | |
334 | 343 | pos = get_symbol_pos(addr, size, offset); |
335 | 344 | /* Grab name */ |
336 | - kallsyms_expand_symbol(get_symbol_offset(pos), name); | |
345 | + kallsyms_expand_symbol(get_symbol_offset(pos), | |
346 | + name, KSYM_NAME_LEN); | |
337 | 347 | modname[0] = '\0'; |
338 | 348 | return 0; |
339 | 349 | } |
... | ... | @@ -463,7 +473,7 @@ |
463 | 473 | |
464 | 474 | iter->type = kallsyms_get_symbol_type(off); |
465 | 475 | |
466 | - off = kallsyms_expand_symbol(off, iter->name); | |
476 | + off = kallsyms_expand_symbol(off, iter->name, ARRAY_SIZE(iter->name)); | |
467 | 477 | |
468 | 478 | return off - iter->nameoff; |
469 | 479 | } |
kernel/modsign_certificate.S
1 | -/* SYMBOL_PREFIX defined on commandline from CONFIG_SYMBOL_PREFIX */ | |
2 | -#ifndef SYMBOL_PREFIX | |
3 | -#define ASM_SYMBOL(sym) sym | |
4 | -#else | |
5 | -#define PASTE2(x,y) x##y | |
6 | -#define PASTE(x,y) PASTE2(x,y) | |
7 | -#define ASM_SYMBOL(sym) PASTE(SYMBOL_PREFIX, sym) | |
8 | -#endif | |
1 | +#include <linux/export.h> | |
9 | 2 | |
10 | 3 | #define GLOBAL(name) \ |
11 | - .globl ASM_SYMBOL(name); \ | |
12 | - ASM_SYMBOL(name): | |
4 | + .globl VMLINUX_SYMBOL(name); \ | |
5 | + VMLINUX_SYMBOL(name): | |
13 | 6 | |
14 | 7 | .section ".init.data","aw" |
15 | 8 |
kernel/module.c
... | ... | @@ -1209,10 +1209,11 @@ |
1209 | 1209 | |
1210 | 1210 | /* Since this should be found in kernel (which can't be removed), |
1211 | 1211 | * no locking is necessary. */ |
1212 | - if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL, | |
1212 | + if (!find_symbol(VMLINUX_SYMBOL_STR(module_layout), NULL, | |
1213 | 1213 | &crc, true, false)) |
1214 | 1214 | BUG(); |
1215 | - return check_version(sechdrs, versindex, "module_layout", mod, crc, | |
1215 | + return check_version(sechdrs, versindex, | |
1216 | + VMLINUX_SYMBOL_STR(module_layout), mod, crc, | |
1216 | 1217 | NULL); |
1217 | 1218 | } |
1218 | 1219 | |
1219 | 1220 | |
... | ... | @@ -1861,12 +1862,12 @@ |
1861 | 1862 | { |
1862 | 1863 | trace_module_free(mod); |
1863 | 1864 | |
1864 | - /* Delete from various lists */ | |
1865 | - mutex_lock(&module_mutex); | |
1866 | - stop_machine(__unlink_module, mod, NULL); | |
1867 | - mutex_unlock(&module_mutex); | |
1868 | 1865 | mod_sysfs_teardown(mod); |
1869 | 1866 | |
1867 | + /* We leave it in list to prevent duplicate loads, but make sure | |
1868 | + * that noone uses it while it's being deconstructed. */ | |
1869 | + mod->state = MODULE_STATE_UNFORMED; | |
1870 | + | |
1870 | 1871 | /* Remove dynamic debug info */ |
1871 | 1872 | ddebug_remove_module(mod->name); |
1872 | 1873 | |
... | ... | @@ -1878,6 +1879,11 @@ |
1878 | 1879 | |
1879 | 1880 | /* Free any allocated parameters. */ |
1880 | 1881 | destroy_params(mod->kp, mod->num_kp); |
1882 | + | |
1883 | + /* Now we can delete it from the lists */ | |
1884 | + mutex_lock(&module_mutex); | |
1885 | + stop_machine(__unlink_module, mod, NULL); | |
1886 | + mutex_unlock(&module_mutex); | |
1881 | 1887 | |
1882 | 1888 | /* This may be NULL, but that's OK */ |
1883 | 1889 | unset_module_init_ro_nx(mod); |
scripts/Makefile.build
... | ... | @@ -211,7 +211,8 @@ |
211 | 211 | |
212 | 212 | cmd_gensymtypes = \ |
213 | 213 | $(CPP) -D__GENKSYMS__ $(c_flags) $< | \ |
214 | - $(GENKSYMS) $(if $(1), -T $(2)) -a $(ARCH) \ | |
214 | + $(GENKSYMS) $(if $(1), -T $(2)) \ | |
215 | + $(patsubst y,-s _,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX)) \ | |
215 | 216 | $(if $(KBUILD_PRESERVE),-p) \ |
216 | 217 | -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null)) |
217 | 218 |
scripts/Makefile.lib
... | ... | @@ -119,13 +119,6 @@ |
119 | 119 | $(CFLAGS_GCOV)) |
120 | 120 | endif |
121 | 121 | |
122 | -ifdef CONFIG_SYMBOL_PREFIX | |
123 | -_sym_flags = -DSYMBOL_PREFIX=$(patsubst "%",%,$(CONFIG_SYMBOL_PREFIX)) | |
124 | -_cpp_flags += $(_sym_flags) | |
125 | -_a_flags += $(_sym_flags) | |
126 | -endif | |
127 | - | |
128 | - | |
129 | 122 | # If building the kernel in a separate objtree expand all occurrences |
130 | 123 | # of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/'). |
131 | 124 |
scripts/Makefile.modpost
... | ... | @@ -60,7 +60,8 @@ |
60 | 60 | modulesymfile := $(firstword $(KBUILD_EXTMOD))/Module.symvers |
61 | 61 | |
62 | 62 | # Step 1), find all modules listed in $(MODVERDIR)/ |
63 | -__modules := $(sort $(shell grep -h '\.ko$$' /dev/null $(wildcard $(MODVERDIR)/*.mod))) | |
63 | +MODLISTCMD := find $(MODVERDIR) -name '*.mod' | xargs -r grep -h '\.ko$$' | sort -u | |
64 | +__modules := $(shell $(MODLISTCMD)) | |
64 | 65 | modules := $(patsubst %.o,%.ko, $(wildcard $(__modules:.ko=.o))) |
65 | 66 | |
66 | 67 | # Stop after building .o files if NOFINAL is set. Makes compile tests quicker |
67 | 68 | |
68 | 69 | |
... | ... | @@ -78,12 +79,13 @@ |
78 | 79 | $(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \ |
79 | 80 | $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) |
80 | 81 | |
82 | +# We can go over command line length here, so be careful. | |
81 | 83 | quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules |
82 | - cmd_modpost = $(modpost) -s | |
84 | + cmd_modpost = $(MODLISTCMD) | sed 's/\.ko$$/.o/' | $(modpost) -s -T - | |
83 | 85 | |
84 | 86 | PHONY += __modpost |
85 | 87 | __modpost: $(modules:.ko=.o) FORCE |
86 | - $(call cmd,modpost) $(wildcard vmlinux) $(filter-out FORCE,$^) | |
88 | + $(call cmd,modpost) $(wildcard vmlinux) | |
87 | 89 | |
88 | 90 | quiet_cmd_kernel-mod = MODPOST $@ |
89 | 91 | cmd_kernel-mod = $(modpost) $@ |
scripts/genksyms/genksyms.c
... | ... | @@ -45,7 +45,6 @@ |
45 | 45 | |
46 | 46 | static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types, |
47 | 47 | flag_preserve, flag_warnings; |
48 | -static const char *arch = ""; | |
49 | 48 | static const char *mod_prefix = ""; |
50 | 49 | |
51 | 50 | static int errors; |
... | ... | @@ -731,7 +730,7 @@ |
731 | 730 | { |
732 | 731 | fputs("Usage:\n" "genksyms [-adDTwqhV] > /path/to/.tmp_obj.ver\n" "\n" |
733 | 732 | #ifdef __GNU_LIBRARY__ |
734 | - " -a, --arch Select architecture\n" | |
733 | + " -s, --symbol-prefix Select symbol prefix\n" | |
735 | 734 | " -d, --debug Increment the debug level (repeatable)\n" |
736 | 735 | " -D, --dump Dump expanded symbol defs (for debugging only)\n" |
737 | 736 | " -r, --reference file Read reference symbols from a file\n" |
... | ... | @@ -742,7 +741,7 @@ |
742 | 741 | " -h, --help Print this message\n" |
743 | 742 | " -V, --version Print the release version\n" |
744 | 743 | #else /* __GNU_LIBRARY__ */ |
745 | - " -a Select architecture\n" | |
744 | + " -s Select symbol prefix\n" | |
746 | 745 | " -d Increment the debug level (repeatable)\n" |
747 | 746 | " -D Dump expanded symbol defs (for debugging only)\n" |
748 | 747 | " -r file Read reference symbols from a file\n" |
... | ... | @@ -763,7 +762,7 @@ |
763 | 762 | |
764 | 763 | #ifdef __GNU_LIBRARY__ |
765 | 764 | struct option long_opts[] = { |
766 | - {"arch", 1, 0, 'a'}, | |
765 | + {"symbol-prefix", 1, 0, 's'}, | |
767 | 766 | {"debug", 0, 0, 'd'}, |
768 | 767 | {"warnings", 0, 0, 'w'}, |
769 | 768 | {"quiet", 0, 0, 'q'}, |
770 | 769 | |
771 | 770 | |
... | ... | @@ -776,14 +775,14 @@ |
776 | 775 | {0, 0, 0, 0} |
777 | 776 | }; |
778 | 777 | |
779 | - while ((o = getopt_long(argc, argv, "a:dwqVDr:T:ph", | |
778 | + while ((o = getopt_long(argc, argv, "s:dwqVDr:T:ph", | |
780 | 779 | &long_opts[0], NULL)) != EOF) |
781 | 780 | #else /* __GNU_LIBRARY__ */ |
782 | - while ((o = getopt(argc, argv, "a:dwqVDr:T:ph")) != EOF) | |
781 | + while ((o = getopt(argc, argv, "s:dwqVDr:T:ph")) != EOF) | |
783 | 782 | #endif /* __GNU_LIBRARY__ */ |
784 | 783 | switch (o) { |
785 | - case 'a': | |
786 | - arch = optarg; | |
784 | + case 's': | |
785 | + mod_prefix = optarg; | |
787 | 786 | break; |
788 | 787 | case 'd': |
789 | 788 | flag_debug++; |
... | ... | @@ -826,9 +825,6 @@ |
826 | 825 | genksyms_usage(); |
827 | 826 | return 1; |
828 | 827 | } |
829 | - if ((strcmp(arch, "h8300") == 0) || (strcmp(arch, "blackfin") == 0) || | |
830 | - (strcmp(arch, "metag") == 0)) | |
831 | - mod_prefix = "_"; | |
832 | 828 | { |
833 | 829 | extern int yydebug; |
834 | 830 | extern int yy_flex_debug; |
scripts/link-vmlinux.sh
... | ... | @@ -74,9 +74,8 @@ |
74 | 74 | info KSYM ${2} |
75 | 75 | local kallsymopt; |
76 | 76 | |
77 | - if [ -n "${CONFIG_SYMBOL_PREFIX}" ]; then | |
78 | - kallsymopt="${kallsymopt} \ | |
79 | - --symbol-prefix=${CONFIG_SYMBOL_PREFIX}" | |
77 | + if [ -n "${CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX}" ]; then | |
78 | + kallsymopt="${kallsymopt} --symbol-prefix=_" | |
80 | 79 | fi |
81 | 80 | |
82 | 81 | if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then |
scripts/mod/modpost.c
... | ... | @@ -15,18 +15,13 @@ |
15 | 15 | #include <stdio.h> |
16 | 16 | #include <ctype.h> |
17 | 17 | #include <string.h> |
18 | +#include <limits.h> | |
19 | +#include <stdbool.h> | |
18 | 20 | #include "modpost.h" |
19 | 21 | #include "../../include/generated/autoconf.h" |
20 | 22 | #include "../../include/linux/license.h" |
23 | +#include "../../include/linux/export.h" | |
21 | 24 | |
22 | -/* Some toolchains use a `_' prefix for all user symbols. */ | |
23 | -#ifdef CONFIG_SYMBOL_PREFIX | |
24 | -#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX | |
25 | -#else | |
26 | -#define MODULE_SYMBOL_PREFIX "" | |
27 | -#endif | |
28 | - | |
29 | - | |
30 | 25 | /* Are we using CONFIG_MODVERSIONS? */ |
31 | 26 | int modversions = 0; |
32 | 27 | /* Warn about undefined symbols? (do so if we have vmlinux) */ |
... | ... | @@ -85,6 +80,14 @@ |
85 | 80 | va_end(arglist); |
86 | 81 | } |
87 | 82 | |
83 | +static inline bool strends(const char *str, const char *postfix) | |
84 | +{ | |
85 | + if (strlen(str) < strlen(postfix)) | |
86 | + return false; | |
87 | + | |
88 | + return strcmp(str + strlen(str) - strlen(postfix), postfix) == 0; | |
89 | +} | |
90 | + | |
88 | 91 | static int is_vmlinux(const char *modname) |
89 | 92 | { |
90 | 93 | const char *myname; |
91 | 94 | |
92 | 95 | |
... | ... | @@ -120,22 +123,20 @@ |
120 | 123 | return mod; |
121 | 124 | } |
122 | 125 | |
123 | -static struct module *new_module(char *modname) | |
126 | +static struct module *new_module(const char *modname) | |
124 | 127 | { |
125 | 128 | struct module *mod; |
126 | - char *p, *s; | |
129 | + char *p; | |
127 | 130 | |
128 | 131 | mod = NOFAIL(malloc(sizeof(*mod))); |
129 | 132 | memset(mod, 0, sizeof(*mod)); |
130 | 133 | p = NOFAIL(strdup(modname)); |
131 | 134 | |
132 | 135 | /* strip trailing .o */ |
133 | - s = strrchr(p, '.'); | |
134 | - if (s != NULL) | |
135 | - if (strcmp(s, ".o") == 0) { | |
136 | - *s = '\0'; | |
137 | - mod->is_dot_o = 1; | |
138 | - } | |
136 | + if (strends(p, ".o")) { | |
137 | + p[strlen(p) - 2] = '\0'; | |
138 | + mod->is_dot_o = 1; | |
139 | + } | |
139 | 140 | |
140 | 141 | /* add to list */ |
141 | 142 | mod->name = p; |
... | ... | @@ -562,7 +563,7 @@ |
562 | 563 | static int ignore_undef_symbol(struct elf_info *info, const char *symname) |
563 | 564 | { |
564 | 565 | /* ignore __this_module, it will be resolved shortly */ |
565 | - if (strcmp(symname, MODULE_SYMBOL_PREFIX "__this_module") == 0) | |
566 | + if (strcmp(symname, VMLINUX_SYMBOL_STR(__this_module)) == 0) | |
566 | 567 | return 1; |
567 | 568 | /* ignore global offset table */ |
568 | 569 | if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0) |
... | ... | @@ -583,8 +584,8 @@ |
583 | 584 | return 0; |
584 | 585 | } |
585 | 586 | |
586 | -#define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_" | |
587 | -#define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_" | |
587 | +#define CRC_PFX VMLINUX_SYMBOL_STR(__crc_) | |
588 | +#define KSYMTAB_PFX VMLINUX_SYMBOL_STR(__ksymtab_) | |
588 | 589 | |
589 | 590 | static void handle_modversions(struct module *mod, struct elf_info *info, |
590 | 591 | Elf_Sym *sym, const char *symname) |
... | ... | @@ -637,14 +638,15 @@ |
637 | 638 | } |
638 | 639 | #endif |
639 | 640 | |
640 | - if (memcmp(symname, MODULE_SYMBOL_PREFIX, | |
641 | - strlen(MODULE_SYMBOL_PREFIX)) == 0) { | |
642 | - mod->unres = | |
643 | - alloc_symbol(symname + | |
644 | - strlen(MODULE_SYMBOL_PREFIX), | |
645 | - ELF_ST_BIND(sym->st_info) == STB_WEAK, | |
646 | - mod->unres); | |
647 | - } | |
641 | +#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX | |
642 | + if (symname[0] != '_') | |
643 | + break; | |
644 | + else | |
645 | + symname++; | |
646 | +#endif | |
647 | + mod->unres = alloc_symbol(symname, | |
648 | + ELF_ST_BIND(sym->st_info) == STB_WEAK, | |
649 | + mod->unres); | |
648 | 650 | break; |
649 | 651 | default: |
650 | 652 | /* All exported symbols */ |
651 | 653 | |
... | ... | @@ -652,9 +654,9 @@ |
652 | 654 | sym_add_exported(symname + strlen(KSYMTAB_PFX), mod, |
653 | 655 | export); |
654 | 656 | } |
655 | - if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0) | |
657 | + if (strcmp(symname, VMLINUX_SYMBOL_STR(init_module)) == 0) | |
656 | 658 | mod->has_init = 1; |
657 | - if (strcmp(symname, MODULE_SYMBOL_PREFIX "cleanup_module") == 0) | |
659 | + if (strcmp(symname, VMLINUX_SYMBOL_STR(cleanup_module)) == 0) | |
658 | 660 | mod->has_cleanup = 1; |
659 | 661 | break; |
660 | 662 | } |
... | ... | @@ -1762,6 +1764,27 @@ |
1762 | 1764 | mod->unres = alloc_symbol("module_layout", 0, mod->unres); |
1763 | 1765 | } |
1764 | 1766 | |
1767 | +static void read_symbols_from_files(const char *filename) | |
1768 | +{ | |
1769 | + FILE *in = stdin; | |
1770 | + char fname[PATH_MAX]; | |
1771 | + | |
1772 | + if (strcmp(filename, "-") != 0) { | |
1773 | + in = fopen(filename, "r"); | |
1774 | + if (!in) | |
1775 | + fatal("Can't open filenames file %s: %m", filename); | |
1776 | + } | |
1777 | + | |
1778 | + while (fgets(fname, PATH_MAX, in) != NULL) { | |
1779 | + if (strends(fname, "\n")) | |
1780 | + fname[strlen(fname)-1] = '\0'; | |
1781 | + read_symbols(fname); | |
1782 | + } | |
1783 | + | |
1784 | + if (in != stdin) | |
1785 | + fclose(in); | |
1786 | +} | |
1787 | + | |
1765 | 1788 | #define SZ 500 |
1766 | 1789 | |
1767 | 1790 | /* We first write the generated file into memory using the |
... | ... | @@ -1934,7 +1957,8 @@ |
1934 | 1957 | s->name, mod->name); |
1935 | 1958 | continue; |
1936 | 1959 | } |
1937 | - buf_printf(b, "\t{ %#8x, \"%s\" },\n", s->crc, s->name); | |
1960 | + buf_printf(b, "\t{ %#8x, __VMLINUX_SYMBOL_STR(%s) },\n", | |
1961 | + s->crc, s->name); | |
1938 | 1962 | } |
1939 | 1963 | |
1940 | 1964 | buf_printf(b, "};\n"); |
1941 | 1965 | |
... | ... | @@ -2122,13 +2146,13 @@ |
2122 | 2146 | struct module *mod; |
2123 | 2147 | struct buffer buf = { }; |
2124 | 2148 | char *kernel_read = NULL, *module_read = NULL; |
2125 | - char *dump_write = NULL; | |
2149 | + char *dump_write = NULL, *files_source = NULL; | |
2126 | 2150 | int opt; |
2127 | 2151 | int err; |
2128 | 2152 | struct ext_sym_list *extsym_iter; |
2129 | 2153 | struct ext_sym_list *extsym_start = NULL; |
2130 | 2154 | |
2131 | - while ((opt = getopt(argc, argv, "i:I:e:msSo:awM:K:")) != -1) { | |
2155 | + while ((opt = getopt(argc, argv, "i:I:e:msST:o:awM:K:")) != -1) { | |
2132 | 2156 | switch (opt) { |
2133 | 2157 | case 'i': |
2134 | 2158 | kernel_read = optarg; |
... | ... | @@ -2160,6 +2184,9 @@ |
2160 | 2184 | case 'S': |
2161 | 2185 | sec_mismatch_verbose = 0; |
2162 | 2186 | break; |
2187 | + case 'T': | |
2188 | + files_source = optarg; | |
2189 | + break; | |
2163 | 2190 | case 'w': |
2164 | 2191 | warn_unresolved = 1; |
2165 | 2192 | break; |
... | ... | @@ -2181,6 +2208,9 @@ |
2181 | 2208 | |
2182 | 2209 | while (optind < argc) |
2183 | 2210 | read_symbols(argv[optind++]); |
2211 | + | |
2212 | + if (files_source) | |
2213 | + read_symbols_from_files(files_source); | |
2184 | 2214 | |
2185 | 2215 | for (mod = modules; mod; mod = mod->next) { |
2186 | 2216 | if (mod->skip) |