diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2007-10-12 21:27:47 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2007-10-12 21:27:47 -0400 |
commit | b981d8b3f5e008ff10d993be633ad00564fc22cd (patch) | |
tree | e292dc07b22308912cf6a58354a608b9e5e8e1fd /scripts/mod | |
parent | b11d2127c4893a7315d1e16273bc8560049fa3ca (diff) | |
parent | 2b9e0aae1d50e880c58d46788e5e3ebd89d75d62 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
drivers/macintosh/adbhid.c
Diffstat (limited to 'scripts/mod')
-rw-r--r-- | scripts/mod/file2alias.c | 50 | ||||
-rw-r--r-- | scripts/mod/modpost.c | 456 | ||||
-rw-r--r-- | scripts/mod/modpost.h | 3 |
3 files changed, 324 insertions, 185 deletions
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index f646381dc015..36e3754db53a 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c | |||
@@ -290,6 +290,14 @@ static int do_serio_entry(const char *filename, | |||
290 | return 1; | 290 | return 1; |
291 | } | 291 | } |
292 | 292 | ||
293 | /* looks like: "acpi:ACPI0003 or acpi:PNP0C0B" or "acpi:LNXVIDEO" */ | ||
294 | static int do_acpi_entry(const char *filename, | ||
295 | struct acpi_device_id *id, char *alias) | ||
296 | { | ||
297 | sprintf(alias, "acpi*:%s:", id->id); | ||
298 | return 1; | ||
299 | } | ||
300 | |||
293 | /* looks like: "pnp:dD" */ | 301 | /* looks like: "pnp:dD" */ |
294 | static int do_pnp_entry(const char *filename, | 302 | static int do_pnp_entry(const char *filename, |
295 | struct pnp_device_id *id, char *alias) | 303 | struct pnp_device_id *id, char *alias) |
@@ -476,6 +484,36 @@ static int do_parisc_entry(const char *filename, struct parisc_device_id *id, | |||
476 | return 1; | 484 | return 1; |
477 | } | 485 | } |
478 | 486 | ||
487 | /* Looks like: sdio:cNvNdN. */ | ||
488 | static int do_sdio_entry(const char *filename, | ||
489 | struct sdio_device_id *id, char *alias) | ||
490 | { | ||
491 | id->class = TO_NATIVE(id->class); | ||
492 | id->vendor = TO_NATIVE(id->vendor); | ||
493 | id->device = TO_NATIVE(id->device); | ||
494 | |||
495 | strcpy(alias, "sdio:"); | ||
496 | ADD(alias, "c", id->class != (__u8)SDIO_ANY_ID, id->class); | ||
497 | ADD(alias, "v", id->vendor != (__u16)SDIO_ANY_ID, id->vendor); | ||
498 | ADD(alias, "d", id->device != (__u16)SDIO_ANY_ID, id->device); | ||
499 | return 1; | ||
500 | } | ||
501 | |||
502 | /* Looks like: ssb:vNidNrevN. */ | ||
503 | static int do_ssb_entry(const char *filename, | ||
504 | struct ssb_device_id *id, char *alias) | ||
505 | { | ||
506 | id->vendor = TO_NATIVE(id->vendor); | ||
507 | id->coreid = TO_NATIVE(id->coreid); | ||
508 | id->revision = TO_NATIVE(id->revision); | ||
509 | |||
510 | strcpy(alias, "ssb:"); | ||
511 | ADD(alias, "v", id->vendor != SSB_ANY_VENDOR, id->vendor); | ||
512 | ADD(alias, "id", id->coreid != SSB_ANY_ID, id->coreid); | ||
513 | ADD(alias, "rev", id->revision != SSB_ANY_REV, id->revision); | ||
514 | return 1; | ||
515 | } | ||
516 | |||
479 | /* Ignore any prefix, eg. v850 prepends _ */ | 517 | /* Ignore any prefix, eg. v850 prepends _ */ |
480 | static inline int sym_is(const char *symbol, const char *name) | 518 | static inline int sym_is(const char *symbol, const char *name) |
481 | { | 519 | { |
@@ -551,6 +589,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, | |||
551 | do_table(symval, sym->st_size, | 589 | do_table(symval, sym->st_size, |
552 | sizeof(struct serio_device_id), "serio", | 590 | sizeof(struct serio_device_id), "serio", |
553 | do_serio_entry, mod); | 591 | do_serio_entry, mod); |
592 | else if (sym_is(symname, "__mod_acpi_device_table")) | ||
593 | do_table(symval, sym->st_size, | ||
594 | sizeof(struct acpi_device_id), "acpi", | ||
595 | do_acpi_entry, mod); | ||
554 | else if (sym_is(symname, "__mod_pnp_device_table")) | 596 | else if (sym_is(symname, "__mod_pnp_device_table")) |
555 | do_table(symval, sym->st_size, | 597 | do_table(symval, sym->st_size, |
556 | sizeof(struct pnp_device_id), "pnp", | 598 | sizeof(struct pnp_device_id), "pnp", |
@@ -587,6 +629,14 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, | |||
587 | do_table(symval, sym->st_size, | 629 | do_table(symval, sym->st_size, |
588 | sizeof(struct parisc_device_id), "parisc", | 630 | sizeof(struct parisc_device_id), "parisc", |
589 | do_parisc_entry, mod); | 631 | do_parisc_entry, mod); |
632 | else if (sym_is(symname, "__mod_sdio_device_table")) | ||
633 | do_table(symval, sym->st_size, | ||
634 | sizeof(struct sdio_device_id), "sdio", | ||
635 | do_sdio_entry, mod); | ||
636 | else if (sym_is(symname, "__mod_ssb_device_table")) | ||
637 | do_table(symval, sym->st_size, | ||
638 | sizeof(struct ssb_device_id), "ssb", | ||
639 | do_ssb_entry, mod); | ||
590 | } | 640 | } |
591 | 641 | ||
592 | /* Now add out buffered information to the generated C source */ | 642 | /* Now add out buffered information to the generated C source */ |
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 3645e980da71..0a4051fbd34e 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
@@ -23,6 +23,8 @@ int have_vmlinux = 0; | |||
23 | static int all_versions = 0; | 23 | static int all_versions = 0; |
24 | /* If we are modposting external module set to 1 */ | 24 | /* If we are modposting external module set to 1 */ |
25 | static int external_module = 0; | 25 | static int external_module = 0; |
26 | /* Warn about section mismatch in vmlinux if set to 1 */ | ||
27 | static int vmlinux_section_warnings = 1; | ||
26 | /* Only warn about unresolved symbols */ | 28 | /* Only warn about unresolved symbols */ |
27 | static int warn_unresolved = 0; | 29 | static int warn_unresolved = 0; |
28 | /* How a symbol is exported */ | 30 | /* How a symbol is exported */ |
@@ -75,7 +77,8 @@ static int is_vmlinux(const char *modname) | |||
75 | else | 77 | else |
76 | myname = modname; | 78 | myname = modname; |
77 | 79 | ||
78 | return strcmp(myname, "vmlinux") == 0; | 80 | return (strcmp(myname, "vmlinux") == 0) || |
81 | (strcmp(myname, "vmlinux.o") == 0); | ||
79 | } | 82 | } |
80 | 83 | ||
81 | void *do_nofail(void *ptr, const char *expr) | 84 | void *do_nofail(void *ptr, const char *expr) |
@@ -374,6 +377,7 @@ static int parse_elf(struct elf_info *info, const char *filename) | |||
374 | hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx); | 377 | hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx); |
375 | hdr->e_shnum = TO_NATIVE(hdr->e_shnum); | 378 | hdr->e_shnum = TO_NATIVE(hdr->e_shnum); |
376 | hdr->e_machine = TO_NATIVE(hdr->e_machine); | 379 | hdr->e_machine = TO_NATIVE(hdr->e_machine); |
380 | hdr->e_type = TO_NATIVE(hdr->e_type); | ||
377 | sechdrs = (void *)hdr + hdr->e_shoff; | 381 | sechdrs = (void *)hdr + hdr->e_shoff; |
378 | info->sechdrs = sechdrs; | 382 | info->sechdrs = sechdrs; |
379 | 383 | ||
@@ -384,6 +388,8 @@ static int parse_elf(struct elf_info *info, const char *filename) | |||
384 | sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size); | 388 | sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size); |
385 | sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link); | 389 | sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link); |
386 | sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name); | 390 | sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name); |
391 | sechdrs[i].sh_info = TO_NATIVE(sechdrs[i].sh_info); | ||
392 | sechdrs[i].sh_addr = TO_NATIVE(sechdrs[i].sh_addr); | ||
387 | } | 393 | } |
388 | /* Find symbol table. */ | 394 | /* Find symbol table. */ |
389 | for (i = 1; i < hdr->e_shnum; i++) { | 395 | for (i = 1; i < hdr->e_shnum; i++) { |
@@ -580,13 +586,61 @@ static int strrcmp(const char *s, const char *sub) | |||
580 | return memcmp(s + slen - sublen, sub, sublen); | 586 | return memcmp(s + slen - sublen, sub, sublen); |
581 | } | 587 | } |
582 | 588 | ||
589 | /* | ||
590 | * Functions used only during module init is marked __init and is stored in | ||
591 | * a .init.text section. Likewise data is marked __initdata and stored in | ||
592 | * a .init.data section. | ||
593 | * If this section is one of these sections return 1 | ||
594 | * See include/linux/init.h for the details | ||
595 | */ | ||
596 | static int init_section(const char *name) | ||
597 | { | ||
598 | if (strcmp(name, ".init") == 0) | ||
599 | return 1; | ||
600 | if (strncmp(name, ".init.", strlen(".init.")) == 0) | ||
601 | return 1; | ||
602 | return 0; | ||
603 | } | ||
604 | |||
605 | /* | ||
606 | * Functions used only during module exit is marked __exit and is stored in | ||
607 | * a .exit.text section. Likewise data is marked __exitdata and stored in | ||
608 | * a .exit.data section. | ||
609 | * If this section is one of these sections return 1 | ||
610 | * See include/linux/init.h for the details | ||
611 | **/ | ||
612 | static int exit_section(const char *name) | ||
613 | { | ||
614 | if (strcmp(name, ".exit.text") == 0) | ||
615 | return 1; | ||
616 | if (strcmp(name, ".exit.data") == 0) | ||
617 | return 1; | ||
618 | return 0; | ||
619 | |||
620 | } | ||
621 | |||
622 | /* | ||
623 | * Data sections are named like this: | ||
624 | * .data | .data.rel | .data.rel.* | ||
625 | * Return 1 if the specified section is a data section | ||
626 | */ | ||
627 | static int data_section(const char *name) | ||
628 | { | ||
629 | if ((strcmp(name, ".data") == 0) || | ||
630 | (strcmp(name, ".data.rel") == 0) || | ||
631 | (strncmp(name, ".data.rel.", strlen(".data.rel.")) == 0)) | ||
632 | return 1; | ||
633 | else | ||
634 | return 0; | ||
635 | } | ||
636 | |||
583 | /** | 637 | /** |
584 | * Whitelist to allow certain references to pass with no warning. | 638 | * Whitelist to allow certain references to pass with no warning. |
585 | * | 639 | * |
586 | * Pattern 0: | 640 | * Pattern 0: |
587 | * Do not warn if funtion/data are marked with __init_refok/__initdata_refok. | 641 | * Do not warn if funtion/data are marked with __init_refok/__initdata_refok. |
588 | * The pattern is identified by: | 642 | * The pattern is identified by: |
589 | * fromsec = .text.init.refok | .data.init.refok | 643 | * fromsec = .text.init.refok* | .data.init.refok* |
590 | * | 644 | * |
591 | * Pattern 1: | 645 | * Pattern 1: |
592 | * If a module parameter is declared __initdata and permissions=0 | 646 | * If a module parameter is declared __initdata and permissions=0 |
@@ -604,19 +658,15 @@ static int strrcmp(const char *s, const char *sub) | |||
604 | * These functions may often be marked __init and we do not want to | 658 | * These functions may often be marked __init and we do not want to |
605 | * warn here. | 659 | * warn here. |
606 | * the pattern is identified by: | 660 | * the pattern is identified by: |
607 | * tosec = .init.text | .exit.text | .init.data | 661 | * tosec = init or exit section |
608 | * fromsec = .data | 662 | * fromsec = data section |
609 | * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console | 663 | * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console, *_timer |
610 | * | 664 | * |
611 | * Pattern 3: | 665 | * Pattern 3: |
612 | * Whitelist all references from .pci_fixup* section to .init.text | ||
613 | * This is part of the PCI init when built-in | ||
614 | * | ||
615 | * Pattern 4: | ||
616 | * Whitelist all refereces from .text.head to .init.data | 666 | * Whitelist all refereces from .text.head to .init.data |
617 | * Whitelist all refereces from .text.head to .init.text | 667 | * Whitelist all refereces from .text.head to .init.text |
618 | * | 668 | * |
619 | * Pattern 5: | 669 | * Pattern 4: |
620 | * Some symbols belong to init section but still it is ok to reference | 670 | * Some symbols belong to init section but still it is ok to reference |
621 | * these from non-init sections as these symbols don't have any memory | 671 | * these from non-init sections as these symbols don't have any memory |
622 | * allocated for them and symbol address and value are same. So even | 672 | * allocated for them and symbol address and value are same. So even |
@@ -625,42 +675,28 @@ static int strrcmp(const char *s, const char *sub) | |||
625 | * This pattern is identified by | 675 | * This pattern is identified by |
626 | * refsymname = __init_begin, _sinittext, _einittext | 676 | * refsymname = __init_begin, _sinittext, _einittext |
627 | * | 677 | * |
628 | * Pattern 7: | 678 | * Pattern 5: |
629 | * Logos used in drivers/video/logo reside in __initdata but the | 679 | * Xtensa uses literal sections for constants that are accessed PC-relative. |
630 | * funtion that references them are EXPORT_SYMBOL() so cannot be | 680 | * Literal sections may safely reference their text sections. |
631 | * marker __init. So we whitelist them here. | 681 | * (Note that the name for the literal section omits any trailing '.text') |
632 | * The pattern is: | 682 | * tosec = <section>[.text] |
633 | * tosec = .init.data | 683 | * fromsec = <section>.literal |
634 | * fromsec = .text* | ||
635 | * refsymname = logo_ | ||
636 | * | ||
637 | * Pattern 8: | ||
638 | * Symbols contained in .paravirtprobe may safely reference .init.text. | ||
639 | * The pattern is: | ||
640 | * tosec = .init.text | ||
641 | * fromsec = .paravirtprobe | ||
642 | * | ||
643 | * Pattern 10: | ||
644 | * ia64 has machvec table for each platform and | ||
645 | * powerpc has a machine desc table for each platform. | ||
646 | * It is mixture of function pointers of .init.text and .text. | ||
647 | * fromsec = .machvec | .machine.desc | ||
648 | **/ | 684 | **/ |
649 | static int secref_whitelist(const char *modname, const char *tosec, | 685 | static int secref_whitelist(const char *modname, const char *tosec, |
650 | const char *fromsec, const char *atsym, | 686 | const char *fromsec, const char *atsym, |
651 | const char *refsymname) | 687 | const char *refsymname) |
652 | { | 688 | { |
653 | int f1 = 1, f2 = 1; | 689 | int len; |
654 | const char **s; | 690 | const char **s; |
655 | const char *pat2sym[] = { | 691 | const char *pat2sym[] = { |
656 | "driver", | 692 | "driver", |
657 | "_template", /* scsi uses *_template a lot */ | 693 | "_template", /* scsi uses *_template a lot */ |
694 | "_timer", /* arm uses ops structures named _timer a lot */ | ||
658 | "_sht", /* scsi also used *_sht to some extent */ | 695 | "_sht", /* scsi also used *_sht to some extent */ |
659 | "_ops", | 696 | "_ops", |
660 | "_probe", | 697 | "_probe", |
661 | "_probe_one", | 698 | "_probe_one", |
662 | "_console", | 699 | "_console", |
663 | "apic_es7000", | ||
664 | NULL | 700 | NULL |
665 | }; | 701 | }; |
666 | 702 | ||
@@ -672,65 +708,41 @@ static int secref_whitelist(const char *modname, const char *tosec, | |||
672 | }; | 708 | }; |
673 | 709 | ||
674 | /* Check for pattern 0 */ | 710 | /* Check for pattern 0 */ |
675 | if ((strcmp(fromsec, ".text.init.refok") == 0) || | 711 | if ((strncmp(fromsec, ".text.init.refok", strlen(".text.init.refok")) == 0) || |
676 | (strcmp(fromsec, ".data.init.refok") == 0)) | 712 | (strncmp(fromsec, ".exit.text.refok", strlen(".exit.text.refok")) == 0) || |
713 | (strncmp(fromsec, ".data.init.refok", strlen(".data.init.refok")) == 0)) | ||
677 | return 1; | 714 | return 1; |
678 | 715 | ||
679 | /* Check for pattern 1 */ | 716 | /* Check for pattern 1 */ |
680 | if (strcmp(tosec, ".init.data") != 0) | 717 | if ((strcmp(tosec, ".init.data") == 0) && |
681 | f1 = 0; | 718 | (strncmp(fromsec, ".data", strlen(".data")) == 0) && |
682 | if (strncmp(fromsec, ".data", strlen(".data")) != 0) | 719 | (strncmp(atsym, "__param", strlen("__param")) == 0)) |
683 | f1 = 0; | 720 | return 1; |
684 | if (strncmp(atsym, "__param", strlen("__param")) != 0) | ||
685 | f1 = 0; | ||
686 | |||
687 | if (f1) | ||
688 | return f1; | ||
689 | 721 | ||
690 | /* Check for pattern 2 */ | 722 | /* Check for pattern 2 */ |
691 | if ((strcmp(tosec, ".init.text") != 0) && | 723 | if ((init_section(tosec) || exit_section(tosec)) && data_section(fromsec)) |
692 | (strcmp(tosec, ".exit.text") != 0) && | 724 | for (s = pat2sym; *s; s++) |
693 | (strcmp(tosec, ".init.data") != 0)) | 725 | if (strrcmp(atsym, *s) == 0) |
694 | f2 = 0; | 726 | return 1; |
695 | if (strcmp(fromsec, ".data") != 0) | ||
696 | f2 = 0; | ||
697 | |||
698 | for (s = pat2sym; *s; s++) | ||
699 | if (strrcmp(atsym, *s) == 0) | ||
700 | f1 = 1; | ||
701 | if (f1 && f2) | ||
702 | return 1; | ||
703 | 727 | ||
704 | /* Check for pattern 3 */ | 728 | /* Check for pattern 3 */ |
705 | if ((strncmp(fromsec, ".pci_fixup", strlen(".pci_fixup")) == 0) && | ||
706 | (strcmp(tosec, ".init.text") == 0)) | ||
707 | return 1; | ||
708 | |||
709 | /* Check for pattern 4 */ | ||
710 | if ((strcmp(fromsec, ".text.head") == 0) && | 729 | if ((strcmp(fromsec, ".text.head") == 0) && |
711 | ((strcmp(tosec, ".init.data") == 0) || | 730 | ((strcmp(tosec, ".init.data") == 0) || |
712 | (strcmp(tosec, ".init.text") == 0))) | 731 | (strcmp(tosec, ".init.text") == 0))) |
713 | return 1; | 732 | return 1; |
714 | 733 | ||
715 | /* Check for pattern 5 */ | 734 | /* Check for pattern 4 */ |
716 | for (s = pat3refsym; *s; s++) | 735 | for (s = pat3refsym; *s; s++) |
717 | if (strcmp(refsymname, *s) == 0) | 736 | if (strcmp(refsymname, *s) == 0) |
718 | return 1; | 737 | return 1; |
719 | 738 | ||
720 | /* Check for pattern 7 */ | 739 | /* Check for pattern 5 */ |
721 | if ((strcmp(tosec, ".init.data") == 0) && | 740 | if (strrcmp(tosec, ".text") == 0) |
722 | (strncmp(fromsec, ".text", strlen(".text")) == 0) && | 741 | len = strlen(tosec) - strlen(".text"); |
723 | (strncmp(refsymname, "logo_", strlen("logo_")) == 0)) | 742 | else |
724 | return 1; | 743 | len = strlen(tosec); |
725 | 744 | if ((strncmp(tosec, fromsec, len) == 0) && (strlen(fromsec) > len) && | |
726 | /* Check for pattern 8 */ | 745 | (strcmp(fromsec + len, ".literal") == 0)) |
727 | if ((strcmp(tosec, ".init.text") == 0) && | ||
728 | (strcmp(fromsec, ".paravirtprobe") == 0)) | ||
729 | return 1; | ||
730 | |||
731 | /* Check for pattern 10 */ | ||
732 | if ((strcmp(fromsec, ".machvec") == 0) || | ||
733 | (strcmp(fromsec, ".machine.desc") == 0)) | ||
734 | return 1; | 746 | return 1; |
735 | 747 | ||
736 | return 0; | 748 | return 0; |
@@ -753,6 +765,8 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf_Addr addr, | |||
753 | for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { | 765 | for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { |
754 | if (sym->st_shndx != relsym->st_shndx) | 766 | if (sym->st_shndx != relsym->st_shndx) |
755 | continue; | 767 | continue; |
768 | if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) | ||
769 | continue; | ||
756 | if (sym->st_value == addr) | 770 | if (sym->st_value == addr) |
757 | return sym; | 771 | return sym; |
758 | } | 772 | } |
@@ -859,14 +873,9 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec, | |||
859 | refsymname = elf->strtab + refsym->st_name; | 873 | refsymname = elf->strtab + refsym->st_name; |
860 | 874 | ||
861 | /* check whitelist - we may ignore it */ | 875 | /* check whitelist - we may ignore it */ |
862 | if (before && | 876 | if (secref_whitelist(modname, secname, fromsec, |
863 | secref_whitelist(modname, secname, fromsec, | 877 | before ? elf->strtab + before->st_name : "", |
864 | elf->strtab + before->st_name, refsymname)) | 878 | refsymname)) |
865 | return; | ||
866 | |||
867 | /* fromsec whitelist - without a valid 'before' | ||
868 | * powerpc has a GOT table in .got2 section */ | ||
869 | if (strcmp(fromsec, ".got2") == 0) | ||
870 | return; | 879 | return; |
871 | 880 | ||
872 | if (before && after) { | 881 | if (before && after) { |
@@ -895,6 +904,78 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec, | |||
895 | } | 904 | } |
896 | } | 905 | } |
897 | 906 | ||
907 | static unsigned int *reloc_location(struct elf_info *elf, | ||
908 | int rsection, Elf_Rela *r) | ||
909 | { | ||
910 | Elf_Shdr *sechdrs = elf->sechdrs; | ||
911 | int section = sechdrs[rsection].sh_info; | ||
912 | |||
913 | return (void *)elf->hdr + sechdrs[section].sh_offset + | ||
914 | (r->r_offset - sechdrs[section].sh_addr); | ||
915 | } | ||
916 | |||
917 | static int addend_386_rel(struct elf_info *elf, int rsection, Elf_Rela *r) | ||
918 | { | ||
919 | unsigned int r_typ = ELF_R_TYPE(r->r_info); | ||
920 | unsigned int *location = reloc_location(elf, rsection, r); | ||
921 | |||
922 | switch (r_typ) { | ||
923 | case R_386_32: | ||
924 | r->r_addend = TO_NATIVE(*location); | ||
925 | break; | ||
926 | case R_386_PC32: | ||
927 | r->r_addend = TO_NATIVE(*location) + 4; | ||
928 | /* For CONFIG_RELOCATABLE=y */ | ||
929 | if (elf->hdr->e_type == ET_EXEC) | ||
930 | r->r_addend += r->r_offset; | ||
931 | break; | ||
932 | } | ||
933 | return 0; | ||
934 | } | ||
935 | |||
936 | static int addend_arm_rel(struct elf_info *elf, int rsection, Elf_Rela *r) | ||
937 | { | ||
938 | unsigned int r_typ = ELF_R_TYPE(r->r_info); | ||
939 | |||
940 | switch (r_typ) { | ||
941 | case R_ARM_ABS32: | ||
942 | /* From ARM ABI: (S + A) | T */ | ||
943 | r->r_addend = (int)(long)(elf->symtab_start + ELF_R_SYM(r->r_info)); | ||
944 | break; | ||
945 | case R_ARM_PC24: | ||
946 | /* From ARM ABI: ((S + A) | T) - P */ | ||
947 | r->r_addend = (int)(long)(elf->hdr + elf->sechdrs[rsection].sh_offset + | ||
948 | (r->r_offset - elf->sechdrs[rsection].sh_addr)); | ||
949 | break; | ||
950 | default: | ||
951 | return 1; | ||
952 | } | ||
953 | return 0; | ||
954 | } | ||
955 | |||
956 | static int addend_mips_rel(struct elf_info *elf, int rsection, Elf_Rela *r) | ||
957 | { | ||
958 | unsigned int r_typ = ELF_R_TYPE(r->r_info); | ||
959 | unsigned int *location = reloc_location(elf, rsection, r); | ||
960 | unsigned int inst; | ||
961 | |||
962 | if (r_typ == R_MIPS_HI16) | ||
963 | return 1; /* skip this */ | ||
964 | inst = TO_NATIVE(*location); | ||
965 | switch (r_typ) { | ||
966 | case R_MIPS_LO16: | ||
967 | r->r_addend = inst & 0xffff; | ||
968 | break; | ||
969 | case R_MIPS_26: | ||
970 | r->r_addend = (inst & 0x03ffffff) << 2; | ||
971 | break; | ||
972 | case R_MIPS_32: | ||
973 | r->r_addend = inst; | ||
974 | break; | ||
975 | } | ||
976 | return 0; | ||
977 | } | ||
978 | |||
898 | /** | 979 | /** |
899 | * A module includes a number of sections that are discarded | 980 | * A module includes a number of sections that are discarded |
900 | * either when loaded or when used as built-in. | 981 | * either when loaded or when used as built-in. |
@@ -938,8 +1019,11 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
938 | r.r_offset = TO_NATIVE(rela->r_offset); | 1019 | r.r_offset = TO_NATIVE(rela->r_offset); |
939 | #if KERNEL_ELFCLASS == ELFCLASS64 | 1020 | #if KERNEL_ELFCLASS == ELFCLASS64 |
940 | if (hdr->e_machine == EM_MIPS) { | 1021 | if (hdr->e_machine == EM_MIPS) { |
1022 | unsigned int r_typ; | ||
941 | r_sym = ELF64_MIPS_R_SYM(rela->r_info); | 1023 | r_sym = ELF64_MIPS_R_SYM(rela->r_info); |
942 | r_sym = TO_NATIVE(r_sym); | 1024 | r_sym = TO_NATIVE(r_sym); |
1025 | r_typ = ELF64_MIPS_R_TYPE(rela->r_info); | ||
1026 | r.r_info = ELF64_R_INFO(r_sym, r_typ); | ||
943 | } else { | 1027 | } else { |
944 | r.r_info = TO_NATIVE(rela->r_info); | 1028 | r.r_info = TO_NATIVE(rela->r_info); |
945 | r_sym = ELF_R_SYM(r.r_info); | 1029 | r_sym = ELF_R_SYM(r.r_info); |
@@ -972,8 +1056,11 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
972 | r.r_offset = TO_NATIVE(rel->r_offset); | 1056 | r.r_offset = TO_NATIVE(rel->r_offset); |
973 | #if KERNEL_ELFCLASS == ELFCLASS64 | 1057 | #if KERNEL_ELFCLASS == ELFCLASS64 |
974 | if (hdr->e_machine == EM_MIPS) { | 1058 | if (hdr->e_machine == EM_MIPS) { |
1059 | unsigned int r_typ; | ||
975 | r_sym = ELF64_MIPS_R_SYM(rel->r_info); | 1060 | r_sym = ELF64_MIPS_R_SYM(rel->r_info); |
976 | r_sym = TO_NATIVE(r_sym); | 1061 | r_sym = TO_NATIVE(r_sym); |
1062 | r_typ = ELF64_MIPS_R_TYPE(rel->r_info); | ||
1063 | r.r_info = ELF64_R_INFO(r_sym, r_typ); | ||
977 | } else { | 1064 | } else { |
978 | r.r_info = TO_NATIVE(rel->r_info); | 1065 | r.r_info = TO_NATIVE(rel->r_info); |
979 | r_sym = ELF_R_SYM(r.r_info); | 1066 | r_sym = ELF_R_SYM(r.r_info); |
@@ -983,6 +1070,20 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
983 | r_sym = ELF_R_SYM(r.r_info); | 1070 | r_sym = ELF_R_SYM(r.r_info); |
984 | #endif | 1071 | #endif |
985 | r.r_addend = 0; | 1072 | r.r_addend = 0; |
1073 | switch (hdr->e_machine) { | ||
1074 | case EM_386: | ||
1075 | if (addend_386_rel(elf, i, &r)) | ||
1076 | continue; | ||
1077 | break; | ||
1078 | case EM_ARM: | ||
1079 | if(addend_arm_rel(elf, i, &r)) | ||
1080 | continue; | ||
1081 | break; | ||
1082 | case EM_MIPS: | ||
1083 | if (addend_mips_rel(elf, i, &r)) | ||
1084 | continue; | ||
1085 | break; | ||
1086 | } | ||
986 | sym = elf->symtab_start + r_sym; | 1087 | sym = elf->symtab_start + r_sym; |
987 | /* Skip special sections */ | 1088 | /* Skip special sections */ |
988 | if (sym->st_shndx >= SHN_LORESERVE) | 1089 | if (sym->st_shndx >= SHN_LORESERVE) |
@@ -998,23 +1099,69 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
998 | } | 1099 | } |
999 | } | 1100 | } |
1000 | 1101 | ||
1001 | /** | 1102 | /* |
1002 | * Functions used only during module init is marked __init and is stored in | 1103 | * Identify sections from which references to either a |
1003 | * a .init.text section. Likewise data is marked __initdata and stored in | 1104 | * .init or a .exit section is OK. |
1004 | * a .init.data section. | 1105 | * |
1005 | * If this section is one of these sections return 1 | 1106 | * [OPD] Keith Ownes <kaos@sgi.com> commented: |
1006 | * See include/linux/init.h for the details | 1107 | * For our future {in}sanity, add a comment that this is the ppc .opd |
1007 | **/ | 1108 | * section, not the ia64 .opd section. |
1008 | static int init_section(const char *name) | 1109 | * ia64 .opd should not point to discarded sections. |
1110 | * [.rodata] like for .init.text we ignore .rodata references -same reason | ||
1111 | */ | ||
1112 | static int initexit_section_ref_ok(const char *name) | ||
1009 | { | 1113 | { |
1010 | if (strcmp(name, ".init") == 0) | 1114 | const char **s; |
1011 | return 1; | 1115 | /* Absolute section names */ |
1012 | if (strncmp(name, ".init.", strlen(".init.")) == 0) | 1116 | const char *namelist1[] = { |
1013 | return 1; | 1117 | "__bug_table", /* used by powerpc for BUG() */ |
1118 | "__ex_table", | ||
1119 | ".altinstructions", | ||
1120 | ".cranges", /* used by sh64 */ | ||
1121 | ".fixup", | ||
1122 | ".machvec", /* ia64 + powerpc uses these */ | ||
1123 | ".machine.desc", | ||
1124 | ".opd", /* See comment [OPD] */ | ||
1125 | "__dbe_table", | ||
1126 | ".parainstructions", | ||
1127 | ".pdr", | ||
1128 | ".plt", /* seen on ARCH=um build on x86_64. Harmless */ | ||
1129 | ".smp_locks", | ||
1130 | ".stab", | ||
1131 | ".m68k_fixup", | ||
1132 | ".xt.prop", /* xtensa informational section */ | ||
1133 | ".xt.lit", /* xtensa informational section */ | ||
1134 | NULL | ||
1135 | }; | ||
1136 | /* Start of section names */ | ||
1137 | const char *namelist2[] = { | ||
1138 | ".debug", | ||
1139 | ".eh_frame", | ||
1140 | ".note", /* ignore ELF notes - may contain anything */ | ||
1141 | ".got", /* powerpc - global offset table */ | ||
1142 | ".toc", /* powerpc - table of contents */ | ||
1143 | NULL | ||
1144 | }; | ||
1145 | /* part of section name */ | ||
1146 | const char *namelist3 [] = { | ||
1147 | ".unwind", /* Sample: IA_64.unwind.exit.text */ | ||
1148 | NULL | ||
1149 | }; | ||
1150 | |||
1151 | for (s = namelist1; *s; s++) | ||
1152 | if (strcmp(*s, name) == 0) | ||
1153 | return 1; | ||
1154 | for (s = namelist2; *s; s++) | ||
1155 | if (strncmp(*s, name, strlen(*s)) == 0) | ||
1156 | return 1; | ||
1157 | for (s = namelist3; *s; s++) | ||
1158 | if (strstr(name, *s) != NULL) | ||
1159 | return 1; | ||
1014 | return 0; | 1160 | return 0; |
1015 | } | 1161 | } |
1016 | 1162 | ||
1017 | /** | 1163 | |
1164 | /* | ||
1018 | * Identify sections from which references to a .init section is OK. | 1165 | * Identify sections from which references to a .init section is OK. |
1019 | * | 1166 | * |
1020 | * Unfortunately references to read only data that referenced .init | 1167 | * Unfortunately references to read only data that referenced .init |
@@ -1028,48 +1175,31 @@ static int init_section(const char *name) | |||
1028 | * | 1175 | * |
1029 | * where vgacon_startup is __init. If you want to wade through the false | 1176 | * where vgacon_startup is __init. If you want to wade through the false |
1030 | * positives, take out the check for rodata. | 1177 | * positives, take out the check for rodata. |
1031 | **/ | 1178 | */ |
1032 | static int init_section_ref_ok(const char *name) | 1179 | static int init_section_ref_ok(const char *name) |
1033 | { | 1180 | { |
1034 | const char **s; | 1181 | const char **s; |
1035 | /* Absolute section names */ | 1182 | /* Absolute section names */ |
1036 | const char *namelist1[] = { | 1183 | const char *namelist1[] = { |
1037 | ".init", | 1184 | "__dbe_table", /* MIPS generate these */ |
1038 | ".opd", /* see comment [OPD] at exit_section_ref_ok() */ | ||
1039 | ".toc1", /* used by ppc64 */ | ||
1040 | ".stab", | ||
1041 | ".data.rel.ro", /* used by parisc64 */ | ||
1042 | ".parainstructions", | ||
1043 | ".text.lock", | ||
1044 | "__bug_table", /* used by powerpc for BUG() */ | ||
1045 | ".pci_fixup_header", | ||
1046 | ".pci_fixup_final", | ||
1047 | ".pdr", | ||
1048 | "__param", | ||
1049 | "__ex_table", | ||
1050 | ".fixup", | ||
1051 | ".smp_locks", | ||
1052 | ".plt", /* seen on ARCH=um build on x86_64. Harmless */ | ||
1053 | "__ftr_fixup", /* powerpc cpu feature fixup */ | 1185 | "__ftr_fixup", /* powerpc cpu feature fixup */ |
1054 | "__fw_ftr_fixup", /* powerpc firmware feature fixup */ | 1186 | "__fw_ftr_fixup", /* powerpc firmware feature fixup */ |
1055 | ".cranges", /* used by sh64 */ | 1187 | "__param", |
1188 | ".data.rel.ro", /* used by parisc64 */ | ||
1189 | ".init", | ||
1190 | ".text.lock", | ||
1056 | NULL | 1191 | NULL |
1057 | }; | 1192 | }; |
1058 | /* Start of section names */ | 1193 | /* Start of section names */ |
1059 | const char *namelist2[] = { | 1194 | const char *namelist2[] = { |
1060 | ".init.", | 1195 | ".init.", |
1061 | ".altinstructions", | 1196 | ".pci_fixup", |
1062 | ".eh_frame", | ||
1063 | ".debug", | ||
1064 | ".parainstructions", | ||
1065 | ".rodata", | 1197 | ".rodata", |
1066 | NULL | 1198 | NULL |
1067 | }; | 1199 | }; |
1068 | /* part of section name */ | 1200 | |
1069 | const char *namelist3 [] = { | 1201 | if (initexit_section_ref_ok(name)) |
1070 | ".unwind", /* sample: IA_64.unwind.init.text */ | 1202 | return 1; |
1071 | NULL | ||
1072 | }; | ||
1073 | 1203 | ||
1074 | for (s = namelist1; *s; s++) | 1204 | for (s = namelist1; *s; s++) |
1075 | if (strcmp(*s, name) == 0) | 1205 | if (strcmp(*s, name) == 0) |
@@ -1077,85 +1207,36 @@ static int init_section_ref_ok(const char *name) | |||
1077 | for (s = namelist2; *s; s++) | 1207 | for (s = namelist2; *s; s++) |
1078 | if (strncmp(*s, name, strlen(*s)) == 0) | 1208 | if (strncmp(*s, name, strlen(*s)) == 0) |
1079 | return 1; | 1209 | return 1; |
1080 | for (s = namelist3; *s; s++) | ||
1081 | if (strstr(name, *s) != NULL) | ||
1082 | return 1; | ||
1083 | if (strrcmp(name, ".init") == 0) | ||
1084 | return 1; | ||
1085 | return 0; | ||
1086 | } | ||
1087 | 1210 | ||
1088 | /* | 1211 | /* If section name ends with ".init" we allow references |
1089 | * Functions used only during module exit is marked __exit and is stored in | 1212 | * as is the case with .initcallN.init, .early_param.init, .taglist.init etc |
1090 | * a .exit.text section. Likewise data is marked __exitdata and stored in | 1213 | */ |
1091 | * a .exit.data section. | 1214 | if (strrcmp(name, ".init") == 0) |
1092 | * If this section is one of these sections return 1 | ||
1093 | * See include/linux/init.h for the details | ||
1094 | **/ | ||
1095 | static int exit_section(const char *name) | ||
1096 | { | ||
1097 | if (strcmp(name, ".exit.text") == 0) | ||
1098 | return 1; | ||
1099 | if (strcmp(name, ".exit.data") == 0) | ||
1100 | return 1; | 1215 | return 1; |
1101 | return 0; | 1216 | return 0; |
1102 | |||
1103 | } | 1217 | } |
1104 | 1218 | ||
1105 | /* | 1219 | /* |
1106 | * Identify sections from which references to a .exit section is OK. | 1220 | * Identify sections from which references to a .exit section is OK. |
1107 | * | 1221 | */ |
1108 | * [OPD] Keith Ownes <kaos@sgi.com> commented: | ||
1109 | * For our future {in}sanity, add a comment that this is the ppc .opd | ||
1110 | * section, not the ia64 .opd section. | ||
1111 | * ia64 .opd should not point to discarded sections. | ||
1112 | * [.rodata] like for .init.text we ignore .rodata references -same reason | ||
1113 | **/ | ||
1114 | static int exit_section_ref_ok(const char *name) | 1222 | static int exit_section_ref_ok(const char *name) |
1115 | { | 1223 | { |
1116 | const char **s; | 1224 | const char **s; |
1117 | /* Absolute section names */ | 1225 | /* Absolute section names */ |
1118 | const char *namelist1[] = { | 1226 | const char *namelist1[] = { |
1119 | ".exit.text", | ||
1120 | ".exit.data", | 1227 | ".exit.data", |
1121 | ".init.text", | 1228 | ".exit.text", |
1122 | ".rodata", | ||
1123 | ".opd", /* See comment [OPD] */ | ||
1124 | ".toc1", /* used by ppc64 */ | ||
1125 | ".altinstructions", | ||
1126 | ".pdr", | ||
1127 | "__bug_table", /* used by powerpc for BUG() */ | ||
1128 | ".exitcall.exit", | 1229 | ".exitcall.exit", |
1129 | ".eh_frame", | 1230 | ".rodata", |
1130 | ".parainstructions", | ||
1131 | ".stab", | ||
1132 | "__ex_table", | ||
1133 | ".fixup", | ||
1134 | ".smp_locks", | ||
1135 | ".plt", /* seen on ARCH=um build on x86_64. Harmless */ | ||
1136 | ".cranges", /* used by sh64 */ | ||
1137 | NULL | ||
1138 | }; | ||
1139 | /* Start of section names */ | ||
1140 | const char *namelist2[] = { | ||
1141 | ".debug", | ||
1142 | NULL | ||
1143 | }; | ||
1144 | /* part of section name */ | ||
1145 | const char *namelist3 [] = { | ||
1146 | ".unwind", /* Sample: IA_64.unwind.exit.text */ | ||
1147 | NULL | 1231 | NULL |
1148 | }; | 1232 | }; |
1149 | 1233 | ||
1234 | if (initexit_section_ref_ok(name)) | ||
1235 | return 1; | ||
1236 | |||
1150 | for (s = namelist1; *s; s++) | 1237 | for (s = namelist1; *s; s++) |
1151 | if (strcmp(*s, name) == 0) | 1238 | if (strcmp(*s, name) == 0) |
1152 | return 1; | 1239 | return 1; |
1153 | for (s = namelist2; *s; s++) | ||
1154 | if (strncmp(*s, name, strlen(*s)) == 0) | ||
1155 | return 1; | ||
1156 | for (s = namelist3; *s; s++) | ||
1157 | if (strstr(name, *s) != NULL) | ||
1158 | return 1; | ||
1159 | return 0; | 1240 | return 0; |
1160 | } | 1241 | } |
1161 | 1242 | ||
@@ -1198,8 +1279,10 @@ static void read_symbols(char *modname) | |||
1198 | handle_modversions(mod, &info, sym, symname); | 1279 | handle_modversions(mod, &info, sym, symname); |
1199 | handle_moddevtable(mod, &info, sym, symname); | 1280 | handle_moddevtable(mod, &info, sym, symname); |
1200 | } | 1281 | } |
1201 | check_sec_ref(mod, modname, &info, init_section, init_section_ref_ok); | 1282 | if (is_vmlinux(modname) && vmlinux_section_warnings) { |
1202 | check_sec_ref(mod, modname, &info, exit_section, exit_section_ref_ok); | 1283 | check_sec_ref(mod, modname, &info, init_section, init_section_ref_ok); |
1284 | check_sec_ref(mod, modname, &info, exit_section, exit_section_ref_ok); | ||
1285 | } | ||
1203 | 1286 | ||
1204 | version = get_modinfo(info.modinfo, info.modinfo_len, "version"); | 1287 | version = get_modinfo(info.modinfo, info.modinfo_len, "version"); |
1205 | if (version) | 1288 | if (version) |
@@ -1567,7 +1650,7 @@ int main(int argc, char **argv) | |||
1567 | int opt; | 1650 | int opt; |
1568 | int err; | 1651 | int err; |
1569 | 1652 | ||
1570 | while ((opt = getopt(argc, argv, "i:I:mo:aw")) != -1) { | 1653 | while ((opt = getopt(argc, argv, "i:I:mso:aw")) != -1) { |
1571 | switch(opt) { | 1654 | switch(opt) { |
1572 | case 'i': | 1655 | case 'i': |
1573 | kernel_read = optarg; | 1656 | kernel_read = optarg; |
@@ -1585,6 +1668,9 @@ int main(int argc, char **argv) | |||
1585 | case 'a': | 1668 | case 'a': |
1586 | all_versions = 1; | 1669 | all_versions = 1; |
1587 | break; | 1670 | break; |
1671 | case 's': | ||
1672 | vmlinux_section_warnings = 0; | ||
1673 | break; | ||
1588 | case 'w': | 1674 | case 'w': |
1589 | warn_unresolved = 1; | 1675 | warn_unresolved = 1; |
1590 | break; | 1676 | break; |
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 0858caa9c03f..4156dd34c5de 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h | |||
@@ -60,6 +60,9 @@ typedef union | |||
60 | #define ELF64_MIPS_R_SYM(i) \ | 60 | #define ELF64_MIPS_R_SYM(i) \ |
61 | ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym) | 61 | ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym) |
62 | 62 | ||
63 | #define ELF64_MIPS_R_TYPE(i) \ | ||
64 | ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_type1) | ||
65 | |||
63 | #if KERNEL_ELFDATA != HOST_ELFDATA | 66 | #if KERNEL_ELFDATA != HOST_ELFDATA |
64 | 67 | ||
65 | static inline void __endian(const void *src, void *dest, unsigned int size) | 68 | static inline void __endian(const void *src, void *dest, unsigned int size) |