aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/mod
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/mod')
-rw-r--r--scripts/mod/file2alias.c21
-rw-r--r--scripts/mod/modpost.c141
-rw-r--r--scripts/mod/modpost.h1
-rw-r--r--scripts/mod/sumversion.c5
4 files changed, 122 insertions, 46 deletions
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index b2f73ffb40bd..ed1244dd58d0 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -37,7 +37,6 @@ typedef unsigned char __u8;
37 * even potentially has different endianness and word sizes, since 37 * even potentially has different endianness and word sizes, since
38 * we handle those differences explicitly below */ 38 * we handle those differences explicitly below */
39#include "../../include/linux/mod_devicetable.h" 39#include "../../include/linux/mod_devicetable.h"
40#include "../../include/linux/input.h"
41 40
42#define ADD(str, sep, cond, field) \ 41#define ADD(str, sep, cond, field) \
43do { \ 42do { \
@@ -416,31 +415,33 @@ static int do_input_entry(const char *filename, struct input_device_id *id,
416 415
417 sprintf(alias + strlen(alias), "-e*"); 416 sprintf(alias + strlen(alias), "-e*");
418 if (id->flags & INPUT_DEVICE_ID_MATCH_EVBIT) 417 if (id->flags & INPUT_DEVICE_ID_MATCH_EVBIT)
419 do_input(alias, id->evbit, 0, EV_MAX); 418 do_input(alias, id->evbit, 0, INPUT_DEVICE_ID_EV_MAX);
420 sprintf(alias + strlen(alias), "k*"); 419 sprintf(alias + strlen(alias), "k*");
421 if (id->flags & INPUT_DEVICE_ID_MATCH_KEYBIT) 420 if (id->flags & INPUT_DEVICE_ID_MATCH_KEYBIT)
422 do_input(alias, id->keybit, KEY_MIN_INTERESTING, KEY_MAX); 421 do_input(alias, id->keybit,
422 INPUT_DEVICE_ID_KEY_MIN_INTERESTING,
423 INPUT_DEVICE_ID_KEY_MAX);
423 sprintf(alias + strlen(alias), "r*"); 424 sprintf(alias + strlen(alias), "r*");
424 if (id->flags & INPUT_DEVICE_ID_MATCH_RELBIT) 425 if (id->flags & INPUT_DEVICE_ID_MATCH_RELBIT)
425 do_input(alias, id->relbit, 0, REL_MAX); 426 do_input(alias, id->relbit, 0, INPUT_DEVICE_ID_REL_MAX);
426 sprintf(alias + strlen(alias), "a*"); 427 sprintf(alias + strlen(alias), "a*");
427 if (id->flags & INPUT_DEVICE_ID_MATCH_ABSBIT) 428 if (id->flags & INPUT_DEVICE_ID_MATCH_ABSBIT)
428 do_input(alias, id->absbit, 0, ABS_MAX); 429 do_input(alias, id->absbit, 0, INPUT_DEVICE_ID_ABS_MAX);
429 sprintf(alias + strlen(alias), "m*"); 430 sprintf(alias + strlen(alias), "m*");
430 if (id->flags & INPUT_DEVICE_ID_MATCH_MSCIT) 431 if (id->flags & INPUT_DEVICE_ID_MATCH_MSCIT)
431 do_input(alias, id->mscbit, 0, MSC_MAX); 432 do_input(alias, id->mscbit, 0, INPUT_DEVICE_ID_MSC_MAX);
432 sprintf(alias + strlen(alias), "l*"); 433 sprintf(alias + strlen(alias), "l*");
433 if (id->flags & INPUT_DEVICE_ID_MATCH_LEDBIT) 434 if (id->flags & INPUT_DEVICE_ID_MATCH_LEDBIT)
434 do_input(alias, id->ledbit, 0, LED_MAX); 435 do_input(alias, id->ledbit, 0, INPUT_DEVICE_ID_LED_MAX);
435 sprintf(alias + strlen(alias), "s*"); 436 sprintf(alias + strlen(alias), "s*");
436 if (id->flags & INPUT_DEVICE_ID_MATCH_SNDBIT) 437 if (id->flags & INPUT_DEVICE_ID_MATCH_SNDBIT)
437 do_input(alias, id->sndbit, 0, SND_MAX); 438 do_input(alias, id->sndbit, 0, INPUT_DEVICE_ID_SND_MAX);
438 sprintf(alias + strlen(alias), "f*"); 439 sprintf(alias + strlen(alias), "f*");
439 if (id->flags & INPUT_DEVICE_ID_MATCH_FFBIT) 440 if (id->flags & INPUT_DEVICE_ID_MATCH_FFBIT)
440 do_input(alias, id->ffbit, 0, FF_MAX); 441 do_input(alias, id->ffbit, 0, INPUT_DEVICE_ID_FF_MAX);
441 sprintf(alias + strlen(alias), "w*"); 442 sprintf(alias + strlen(alias), "w*");
442 if (id->flags & INPUT_DEVICE_ID_MATCH_SWBIT) 443 if (id->flags & INPUT_DEVICE_ID_MATCH_SWBIT)
443 do_input(alias, id->swbit, 0, SW_MAX); 444 do_input(alias, id->swbit, 0, INPUT_DEVICE_ID_SW_MAX);
444 return 1; 445 return 1;
445} 446}
446 447
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 78d659cbb36a..4ab36de45aa2 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -55,6 +55,17 @@ void warn(const char *fmt, ...)
55 va_end(arglist); 55 va_end(arglist);
56} 56}
57 57
58void merror(const char *fmt, ...)
59{
60 va_list arglist;
61
62 fprintf(stderr, "ERROR: ");
63
64 va_start(arglist, fmt);
65 vfprintf(stderr, fmt, arglist);
66 va_end(arglist);
67}
68
58static int is_vmlinux(const char *modname) 69static int is_vmlinux(const char *modname)
59{ 70{
60 const char *myname; 71 const char *myname;
@@ -333,10 +344,10 @@ void release_file(void *file, unsigned long size)
333 munmap(file, size); 344 munmap(file, size);
334} 345}
335 346
336static void parse_elf(struct elf_info *info, const char *filename) 347static int parse_elf(struct elf_info *info, const char *filename)
337{ 348{
338 unsigned int i; 349 unsigned int i;
339 Elf_Ehdr *hdr = info->hdr; 350 Elf_Ehdr *hdr;
340 Elf_Shdr *sechdrs; 351 Elf_Shdr *sechdrs;
341 Elf_Sym *sym; 352 Elf_Sym *sym;
342 353
@@ -346,9 +357,18 @@ static void parse_elf(struct elf_info *info, const char *filename)
346 exit(1); 357 exit(1);
347 } 358 }
348 info->hdr = hdr; 359 info->hdr = hdr;
349 if (info->size < sizeof(*hdr)) 360 if (info->size < sizeof(*hdr)) {
350 goto truncated; 361 /* file too small, assume this is an empty .o file */
351 362 return 0;
363 }
364 /* Is this a valid ELF file? */
365 if ((hdr->e_ident[EI_MAG0] != ELFMAG0) ||
366 (hdr->e_ident[EI_MAG1] != ELFMAG1) ||
367 (hdr->e_ident[EI_MAG2] != ELFMAG2) ||
368 (hdr->e_ident[EI_MAG3] != ELFMAG3)) {
369 /* Not an ELF file - silently ignore it */
370 return 0;
371 }
352 /* Fix endianness in ELF header */ 372 /* Fix endianness in ELF header */
353 hdr->e_shoff = TO_NATIVE(hdr->e_shoff); 373 hdr->e_shoff = TO_NATIVE(hdr->e_shoff);
354 hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx); 374 hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx);
@@ -371,8 +391,10 @@ static void parse_elf(struct elf_info *info, const char *filename)
371 = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; 391 = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
372 const char *secname; 392 const char *secname;
373 393
374 if (sechdrs[i].sh_offset > info->size) 394 if (sechdrs[i].sh_offset > info->size) {
375 goto truncated; 395 fatal("%s is truncated. sechdrs[i].sh_offset=%u > sizeof(*hrd)=%ul\n", filename, (unsigned int)sechdrs[i].sh_offset, sizeof(*hdr));
396 return 0;
397 }
376 secname = secstrings + sechdrs[i].sh_name; 398 secname = secstrings + sechdrs[i].sh_name;
377 if (strcmp(secname, ".modinfo") == 0) { 399 if (strcmp(secname, ".modinfo") == 0) {
378 info->modinfo = (void *)hdr + sechdrs[i].sh_offset; 400 info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
@@ -407,10 +429,7 @@ static void parse_elf(struct elf_info *info, const char *filename)
407 sym->st_value = TO_NATIVE(sym->st_value); 429 sym->st_value = TO_NATIVE(sym->st_value);
408 sym->st_size = TO_NATIVE(sym->st_size); 430 sym->st_size = TO_NATIVE(sym->st_size);
409 } 431 }
410 return; 432 return 1;
411
412 truncated:
413 fatal("%s is truncated.\n", filename);
414} 433}
415 434
416static void parse_elf_finish(struct elf_info *info) 435static void parse_elf_finish(struct elf_info *info)
@@ -581,9 +600,17 @@ static int strrcmp(const char *s, const char *sub)
581 * the pattern is identified by: 600 * the pattern is identified by:
582 * tosec = .init.text | .exit.text | .init.data 601 * tosec = .init.text | .exit.text | .init.data
583 * fromsec = .data 602 * fromsec = .data
584 * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one 603 * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console
585 * 604 *
586 * Pattern 3: 605 * Pattern 3:
606 * Whitelist all references from .pci_fixup* section to .init.text
607 * This is part of the PCI init when built-in
608 *
609 * Pattern 4:
610 * Whitelist all refereces from .text.head to .init.data
611 * Whitelist all refereces from .text.head to .init.text
612 *
613 * Pattern 5:
587 * Some symbols belong to init section but still it is ok to reference 614 * Some symbols belong to init section but still it is ok to reference
588 * these from non-init sections as these symbols don't have any memory 615 * these from non-init sections as these symbols don't have any memory
589 * allocated for them and symbol address and value are same. So even 616 * allocated for them and symbol address and value are same. So even
@@ -591,6 +618,30 @@ static int strrcmp(const char *s, const char *sub)
591 * For ex. symbols marking the init section boundaries. 618 * For ex. symbols marking the init section boundaries.
592 * This pattern is identified by 619 * This pattern is identified by
593 * refsymname = __init_begin, _sinittext, _einittext 620 * refsymname = __init_begin, _sinittext, _einittext
621 *
622 * Pattern 6:
623 * During the early init phase we have references from .init.text to
624 * .text we have an intended section mismatch - do not warn about it.
625 * See kernel_init() in init/main.c
626 * tosec = .init.text
627 * fromsec = .text
628 * atsym = kernel_init
629 *
630 * Pattern 7:
631 * Logos used in drivers/video/logo reside in __initdata but the
632 * funtion that references them are EXPORT_SYMBOL() so cannot be
633 * marker __init. So we whitelist them here.
634 * The pattern is:
635 * tosec = .init.data
636 * fromsec = .text*
637 * refsymname = logo_
638 *
639 * Pattern 8:
640 * Symbols contained in .paravirtprobe may safely reference .init.text.
641 * The pattern is:
642 * tosec = .init.text
643 * fromsec = .paravirtprobe
644 *
594 **/ 645 **/
595static int secref_whitelist(const char *modname, const char *tosec, 646static int secref_whitelist(const char *modname, const char *tosec,
596 const char *fromsec, const char *atsym, 647 const char *fromsec, const char *atsym,
@@ -642,25 +693,39 @@ static int secref_whitelist(const char *modname, const char *tosec,
642 if (f1 && f2) 693 if (f1 && f2)
643 return 1; 694 return 1;
644 695
645 /* Whitelist all references from .pci_fixup section if vmlinux 696 /* Check for pattern 3 */
646 * Whitelist all refereces from .text.head to .init.data if vmlinux 697 if ((strncmp(fromsec, ".pci_fixup", strlen(".pci_fixup")) == 0) &&
647 * Whitelist all refereces from .text.head to .init.text if vmlinux 698 (strcmp(tosec, ".init.text") == 0))
648 */ 699 return 1;
649 if (is_vmlinux(modname)) { 700
650 if ((strcmp(fromsec, ".pci_fixup") == 0) && 701 /* Check for pattern 4 */
651 (strcmp(tosec, ".init.text") == 0)) 702 if ((strcmp(fromsec, ".text.head") == 0) &&
703 ((strcmp(tosec, ".init.data") == 0) ||
704 (strcmp(tosec, ".init.text") == 0)))
705 return 1;
706
707 /* Check for pattern 5 */
708 for (s = pat3refsym; *s; s++)
709 if (strcmp(refsymname, *s) == 0)
710 return 1;
711
712 /* Check for pattern 6 */
713 if ((strcmp(tosec, ".init.text") == 0) &&
714 (strcmp(fromsec, ".text") == 0) &&
715 (strcmp(refsymname, "kernel_init") == 0))
652 return 1; 716 return 1;
653 717
654 if ((strcmp(fromsec, ".text.head") == 0) && 718 /* Check for pattern 7 */
655 ((strcmp(tosec, ".init.data") == 0) || 719 if ((strcmp(tosec, ".init.data") == 0) &&
656 (strcmp(tosec, ".init.text") == 0))) 720 (strncmp(fromsec, ".text", strlen(".text")) == 0) &&
721 (strncmp(refsymname, "logo_", strlen("logo_")) == 0))
722 return 1;
723
724 /* Check for pattern 8 */
725 if ((strcmp(tosec, ".init.text") == 0) &&
726 (strcmp(fromsec, ".paravirtprobe") == 0))
657 return 1; 727 return 1;
658 728
659 /* Check for pattern 3 */
660 for (s = pat3refsym; *s; s++)
661 if (strcmp(refsymname, *s) == 0)
662 return 1;
663 }
664 return 0; 729 return 0;
665} 730}
666 731
@@ -1090,7 +1155,8 @@ static void read_symbols(char *modname)
1090 struct elf_info info = { }; 1155 struct elf_info info = { };
1091 Elf_Sym *sym; 1156 Elf_Sym *sym;
1092 1157
1093 parse_elf(&info, modname); 1158 if (!parse_elf(&info, modname))
1159 return;
1094 1160
1095 mod = new_module(modname); 1161 mod = new_module(modname);
1096 1162
@@ -1265,9 +1331,14 @@ static int add_versions(struct buffer *b, struct module *mod)
1265 exp = find_symbol(s->name); 1331 exp = find_symbol(s->name);
1266 if (!exp || exp->module == mod) { 1332 if (!exp || exp->module == mod) {
1267 if (have_vmlinux && !s->weak) { 1333 if (have_vmlinux && !s->weak) {
1268 warn("\"%s\" [%s.ko] undefined!\n", 1334 if (warn_unresolved) {
1269 s->name, mod->name); 1335 warn("\"%s\" [%s.ko] undefined!\n",
1270 err = warn_unresolved ? 0 : 1; 1336 s->name, mod->name);
1337 } else {
1338 merror("\"%s\" [%s.ko] undefined!\n",
1339 s->name, mod->name);
1340 err = 1;
1341 }
1271 } 1342 }
1272 continue; 1343 continue;
1273 } 1344 }
@@ -1318,6 +1389,7 @@ static void add_depends(struct buffer *b, struct module *mod,
1318 buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n"); 1389 buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n");
1319 buf_printf(b, "\"depends="); 1390 buf_printf(b, "\"depends=");
1320 for (s = mod->unres; s; s = s->next) { 1391 for (s = mod->unres; s; s = s->next) {
1392 const char *p;
1321 if (!s->module) 1393 if (!s->module)
1322 continue; 1394 continue;
1323 1395
@@ -1325,8 +1397,11 @@ static void add_depends(struct buffer *b, struct module *mod,
1325 continue; 1397 continue;
1326 1398
1327 s->module->seen = 1; 1399 s->module->seen = 1;
1328 buf_printf(b, "%s%s", first ? "" : ",", 1400 if ((p = strrchr(s->module->name, '/')) != NULL)
1329 strrchr(s->module->name, '/') + 1); 1401 p++;
1402 else
1403 p = s->module->name;
1404 buf_printf(b, "%s%s", first ? "" : ",", p);
1330 first = 0; 1405 first = 0;
1331 } 1406 }
1332 buf_printf(b, "\";\n"); 1407 buf_printf(b, "\";\n");
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index d398c61e55ef..0858caa9c03f 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -145,3 +145,4 @@ void release_file(void *file, unsigned long size);
145 145
146void fatal(const char *fmt, ...); 146void fatal(const char *fmt, ...);
147void warn(const char *fmt, ...); 147void warn(const char *fmt, ...);
148void merror(const char *fmt, ...);
diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c
index 8a2875689e4d..6873d5af80d5 100644
--- a/scripts/mod/sumversion.c
+++ b/scripts/mod/sumversion.c
@@ -397,10 +397,9 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen)
397 (int) strlen(basename) - 2, basename); 397 (int) strlen(basename) - 2, basename);
398 398
399 file = grab_file(filelist, &len); 399 file = grab_file(filelist, &len);
400 if (!file) { 400 if (!file)
401 warn("could not find versions for %s\n", filelist); 401 /* not a module or .mod file missing - ignore */
402 return; 402 return;
403 }
404 403
405 sources = strchr(file, '\n'); 404 sources = strchr(file, '\n');
406 if (!sources) { 405 if (!sources) {