diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-21 15:03:04 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-21 15:03:04 -0400 |
| commit | 080e89270a7bfb7d01fac9a67050f8ac6d6cdd11 (patch) | |
| tree | 489e467292ca06420e85f185095323efb80c75b7 /scripts/mod | |
| parent | 4b85df0419d1fb135d9d845876e8c7ee1393f83c (diff) | |
| parent | 38bdc32af442b6ab09ed61b8b669072098c95dd2 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-fix
* git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-fix:
mm/slab: fix section mismatch warning
mm: fix section mismatch warnings
init/main: use __init_refok to fix section mismatch
kbuild: introduce __init_refok/__initdata_refok to supress section mismatch warnings
all-archs: consolidate .data section definition in asm-generic
all-archs: consolidate .text section definition in asm-generic
kbuild: add "Section mismatch" warning whitelist for powerpc
kbuild: make better section mismatch reports on i386, arm and mips
kbuild: make modpost section warnings clearer
kconfig: search harder for curses library in check-lxdialog.sh
kbuild: include limits.h in sumversion.c for PATH_MAX
powerpc: Fix the MODALIAS generation in modpost for of devices
Diffstat (limited to 'scripts/mod')
| -rw-r--r-- | scripts/mod/file2alias.c | 11 | ||||
| -rw-r--r-- | scripts/mod/modpost.c | 169 | ||||
| -rw-r--r-- | scripts/mod/modpost.h | 3 | ||||
| -rw-r--r-- | scripts/mod/sumversion.c | 1 |
4 files changed, 128 insertions, 56 deletions
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index ed1244dd58d0..f646381dc015 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c | |||
| @@ -353,11 +353,16 @@ static int do_pcmcia_entry(const char *filename, | |||
| 353 | 353 | ||
| 354 | static int do_of_entry (const char *filename, struct of_device_id *of, char *alias) | 354 | static int do_of_entry (const char *filename, struct of_device_id *of, char *alias) |
| 355 | { | 355 | { |
| 356 | int len; | ||
| 356 | char *tmp; | 357 | char *tmp; |
| 357 | sprintf (alias, "of:N%sT%sC%s", | 358 | len = sprintf (alias, "of:N%sT%s", |
| 358 | of->name[0] ? of->name : "*", | 359 | of->name[0] ? of->name : "*", |
| 359 | of->type[0] ? of->type : "*", | 360 | of->type[0] ? of->type : "*"); |
| 360 | of->compatible[0] ? of->compatible : "*"); | 361 | |
| 362 | if (of->compatible[0]) | ||
| 363 | sprintf (&alias[len], "%sC%s", | ||
| 364 | of->type[0] ? "*" : "", | ||
| 365 | of->compatible); | ||
| 361 | 366 | ||
| 362 | /* Replace all whitespace with underscores */ | 367 | /* Replace all whitespace with underscores */ |
| 363 | for (tmp = alias; tmp && *tmp; tmp++) | 368 | for (tmp = alias; tmp && *tmp; tmp++) |
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 113dc77b9f60..8424d1f53bbe 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
| @@ -384,6 +384,7 @@ static int parse_elf(struct elf_info *info, const char *filename) | |||
| 384 | sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size); | 384 | sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size); |
| 385 | sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link); | 385 | sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link); |
| 386 | sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name); | 386 | sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name); |
| 387 | sechdrs[i].sh_info = TO_NATIVE(sechdrs[i].sh_info); | ||
| 387 | } | 388 | } |
| 388 | /* Find symbol table. */ | 389 | /* Find symbol table. */ |
| 389 | for (i = 1; i < hdr->e_shnum; i++) { | 390 | for (i = 1; i < hdr->e_shnum; i++) { |
| @@ -582,6 +583,12 @@ static int strrcmp(const char *s, const char *sub) | |||
| 582 | 583 | ||
| 583 | /** | 584 | /** |
| 584 | * Whitelist to allow certain references to pass with no warning. | 585 | * Whitelist to allow certain references to pass with no warning. |
| 586 | * | ||
| 587 | * Pattern 0: | ||
| 588 | * Do not warn if funtion/data are marked with __init_refok/__initdata_refok. | ||
| 589 | * The pattern is identified by: | ||
| 590 | * fromsec = .text.init.refok | .data.init.refok | ||
| 591 | * | ||
| 585 | * Pattern 1: | 592 | * Pattern 1: |
| 586 | * If a module parameter is declared __initdata and permissions=0 | 593 | * If a module parameter is declared __initdata and permissions=0 |
| 587 | * then this is legal despite the warning generated. | 594 | * then this is legal despite the warning generated. |
| @@ -619,14 +626,6 @@ static int strrcmp(const char *s, const char *sub) | |||
| 619 | * This pattern is identified by | 626 | * This pattern is identified by |
| 620 | * refsymname = __init_begin, _sinittext, _einittext | 627 | * refsymname = __init_begin, _sinittext, _einittext |
| 621 | * | 628 | * |
| 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: | 629 | * Pattern 7: |
| 631 | * Logos used in drivers/video/logo reside in __initdata but the | 630 | * Logos used in drivers/video/logo reside in __initdata but the |
| 632 | * funtion that references them are EXPORT_SYMBOL() so cannot be | 631 | * funtion that references them are EXPORT_SYMBOL() so cannot be |
| @@ -642,16 +641,11 @@ static int strrcmp(const char *s, const char *sub) | |||
| 642 | * tosec = .init.text | 641 | * tosec = .init.text |
| 643 | * fromsec = .paravirtprobe | 642 | * fromsec = .paravirtprobe |
| 644 | * | 643 | * |
| 645 | * Pattern 9: | ||
| 646 | * Some of functions are common code between boot time and hotplug | ||
| 647 | * time. The bootmem allocater is called only boot time in its | ||
| 648 | * functions. So it's ok to reference. | ||
| 649 | * tosec = .init.text | ||
| 650 | * | ||
| 651 | * Pattern 10: | 644 | * Pattern 10: |
| 652 | * ia64 has machvec table for each platform. It is mixture of function | 645 | * ia64 has machvec table for each platform and |
| 653 | * pointer of .init.text and .text. | 646 | * powerpc has a machine desc table for each platform. |
| 654 | * fromsec = .machvec | 647 | * It is mixture of function pointers of .init.text and .text. |
| 648 | * fromsec = .machvec | .machine.desc | ||
| 655 | **/ | 649 | **/ |
| 656 | static int secref_whitelist(const char *modname, const char *tosec, | 650 | static int secref_whitelist(const char *modname, const char *tosec, |
| 657 | const char *fromsec, const char *atsym, | 651 | const char *fromsec, const char *atsym, |
| @@ -678,11 +672,10 @@ static int secref_whitelist(const char *modname, const char *tosec, | |||
| 678 | NULL | 672 | NULL |
| 679 | }; | 673 | }; |
| 680 | 674 | ||
| 681 | const char *pat4sym[] = { | 675 | /* Check for pattern 0 */ |
| 682 | "sparse_index_alloc", | 676 | if ((strcmp(fromsec, ".text.init.refok") == 0) || |
| 683 | "zone_wait_table_init", | 677 | (strcmp(fromsec, ".data.init.refok") == 0)) |
| 684 | NULL | 678 | return 1; |
| 685 | }; | ||
| 686 | 679 | ||
| 687 | /* Check for pattern 1 */ | 680 | /* Check for pattern 1 */ |
| 688 | if (strcmp(tosec, ".init.data") != 0) | 681 | if (strcmp(tosec, ".init.data") != 0) |
| @@ -725,12 +718,6 @@ static int secref_whitelist(const char *modname, const char *tosec, | |||
| 725 | if (strcmp(refsymname, *s) == 0) | 718 | if (strcmp(refsymname, *s) == 0) |
| 726 | return 1; | 719 | return 1; |
| 727 | 720 | ||
| 728 | /* Check for pattern 6 */ | ||
| 729 | if ((strcmp(tosec, ".init.text") == 0) && | ||
| 730 | (strcmp(fromsec, ".text") == 0) && | ||
| 731 | (strcmp(refsymname, "kernel_init") == 0)) | ||
| 732 | return 1; | ||
| 733 | |||
| 734 | /* Check for pattern 7 */ | 721 | /* Check for pattern 7 */ |
| 735 | if ((strcmp(tosec, ".init.data") == 0) && | 722 | if ((strcmp(tosec, ".init.data") == 0) && |
| 736 | (strncmp(fromsec, ".text", strlen(".text")) == 0) && | 723 | (strncmp(fromsec, ".text", strlen(".text")) == 0) && |
| @@ -742,15 +729,9 @@ static int secref_whitelist(const char *modname, const char *tosec, | |||
| 742 | (strcmp(fromsec, ".paravirtprobe") == 0)) | 729 | (strcmp(fromsec, ".paravirtprobe") == 0)) |
| 743 | return 1; | 730 | return 1; |
| 744 | 731 | ||
| 745 | /* Check for pattern 9 */ | ||
| 746 | if ((strcmp(tosec, ".init.text") == 0) && | ||
| 747 | (strcmp(fromsec, ".text") == 0)) | ||
| 748 | for (s = pat4sym; *s; s++) | ||
| 749 | if (strcmp(atsym, *s) == 0) | ||
| 750 | return 1; | ||
| 751 | |||
| 752 | /* Check for pattern 10 */ | 732 | /* Check for pattern 10 */ |
| 753 | if (strcmp(fromsec, ".machvec") == 0) | 733 | if ((strcmp(fromsec, ".machvec") == 0) || |
| 734 | (strcmp(fromsec, ".machine.desc") == 0)) | ||
| 754 | return 1; | 735 | return 1; |
| 755 | 736 | ||
| 756 | return 0; | 737 | return 0; |
| @@ -773,6 +754,8 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf_Addr addr, | |||
| 773 | for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { | 754 | for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { |
| 774 | if (sym->st_shndx != relsym->st_shndx) | 755 | if (sym->st_shndx != relsym->st_shndx) |
| 775 | continue; | 756 | continue; |
| 757 | if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) | ||
| 758 | continue; | ||
| 776 | if (sym->st_value == addr) | 759 | if (sym->st_value == addr) |
| 777 | return sym; | 760 | return sym; |
| 778 | } | 761 | } |
| @@ -884,33 +867,99 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec, | |||
| 884 | elf->strtab + before->st_name, refsymname)) | 867 | elf->strtab + before->st_name, refsymname)) |
| 885 | return; | 868 | return; |
| 886 | 869 | ||
| 870 | /* fromsec whitelist - without a valid 'before' | ||
| 871 | * powerpc has a GOT table in .got2 section */ | ||
| 872 | if (strcmp(fromsec, ".got2") == 0) | ||
| 873 | return; | ||
| 874 | |||
| 887 | if (before && after) { | 875 | if (before && after) { |
| 888 | warn("%s - Section mismatch: reference to %s:%s from %s " | 876 | warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " |
| 889 | "between '%s' (at offset 0x%llx) and '%s'\n", | 877 | "(between '%s' and '%s')\n", |
| 890 | modname, secname, refsymname, fromsec, | 878 | modname, fromsec, (unsigned long long)r.r_offset, |
| 879 | secname, refsymname, | ||
| 891 | elf->strtab + before->st_name, | 880 | elf->strtab + before->st_name, |
| 892 | (long long)r.r_offset, | ||
| 893 | elf->strtab + after->st_name); | 881 | elf->strtab + after->st_name); |
| 894 | } else if (before) { | 882 | } else if (before) { |
| 895 | warn("%s - Section mismatch: reference to %s:%s from %s " | 883 | warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " |
| 896 | "after '%s' (at offset 0x%llx)\n", | 884 | "(after '%s')\n", |
| 897 | modname, secname, refsymname, fromsec, | 885 | modname, fromsec, (unsigned long long)r.r_offset, |
| 898 | elf->strtab + before->st_name, | 886 | secname, refsymname, |
| 899 | (long long)r.r_offset); | 887 | elf->strtab + before->st_name); |
| 900 | } else if (after) { | 888 | } else if (after) { |
| 901 | warn("%s - Section mismatch: reference to %s:%s from %s " | 889 | warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " |
| 902 | "before '%s' (at offset -0x%llx)\n", | 890 | "before '%s' (at offset -0x%llx)\n", |
| 903 | modname, secname, refsymname, fromsec, | 891 | modname, fromsec, (unsigned long long)r.r_offset, |
| 904 | elf->strtab + after->st_name, | 892 | secname, refsymname, |
| 905 | (long long)r.r_offset); | 893 | elf->strtab + after->st_name); |
| 906 | } else { | 894 | } else { |
| 907 | warn("%s - Section mismatch: reference to %s:%s from %s " | 895 | warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s\n", |
| 908 | "(offset 0x%llx)\n", | 896 | modname, fromsec, (unsigned long long)r.r_offset, |
| 909 | modname, secname, fromsec, refsymname, | 897 | secname, refsymname); |
| 910 | (long long)r.r_offset); | ||
| 911 | } | 898 | } |
| 912 | } | 899 | } |
| 913 | 900 | ||
| 901 | static void addend_386_rel(struct elf_info *elf, int section, Elf_Rela *r) | ||
| 902 | { | ||
| 903 | Elf_Shdr *sechdrs = elf->sechdrs; | ||
| 904 | unsigned int r_typ; | ||
| 905 | unsigned int *location; | ||
| 906 | |||
| 907 | r_typ = ELF_R_TYPE(r->r_info); | ||
| 908 | location = (void *)elf->hdr + | ||
| 909 | sechdrs[sechdrs[section].sh_info].sh_offset + r->r_offset; | ||
| 910 | switch (r_typ) { | ||
| 911 | case R_386_32: | ||
| 912 | r->r_addend = TO_NATIVE(*location); | ||
| 913 | break; | ||
| 914 | case R_386_PC32: | ||
| 915 | r->r_addend = TO_NATIVE(*location) + 4; | ||
| 916 | break; | ||
| 917 | } | ||
| 918 | } | ||
| 919 | |||
| 920 | static void addend_arm_rel(struct elf_info *elf, int section, Elf_Rela *r) | ||
| 921 | { | ||
| 922 | Elf_Shdr *sechdrs = elf->sechdrs; | ||
| 923 | unsigned int r_typ; | ||
| 924 | unsigned int *location; | ||
| 925 | |||
| 926 | r_typ = ELF_R_TYPE(r->r_info); | ||
| 927 | location = (void *)elf->hdr + | ||
| 928 | sechdrs[sechdrs[section].sh_info].sh_offset + r->r_offset; | ||
| 929 | switch (r_typ) { | ||
| 930 | case R_ARM_ABS32: | ||
| 931 | r->r_addend = TO_NATIVE(*location); | ||
| 932 | break; | ||
| 933 | case R_ARM_PC24: | ||
| 934 | r->r_addend = ((TO_NATIVE(*location) & 0x00ffffff) << 2) + 8; | ||
| 935 | break; | ||
| 936 | } | ||
| 937 | } | ||
| 938 | |||
| 939 | static int addend_mips_rel(struct elf_info *elf, int section, Elf_Rela *r) | ||
| 940 | { | ||
| 941 | Elf_Shdr *sechdrs = elf->sechdrs; | ||
| 942 | unsigned int r_typ; | ||
| 943 | unsigned int *location; | ||
| 944 | unsigned int inst; | ||
| 945 | |||
| 946 | r_typ = ELF_R_TYPE(r->r_info); | ||
| 947 | if (r_typ == R_MIPS_HI16) | ||
| 948 | return 1; /* skip this */ | ||
| 949 | location = (void *)elf->hdr + | ||
| 950 | sechdrs[sechdrs[section].sh_info].sh_offset + r->r_offset; | ||
| 951 | inst = TO_NATIVE(*location); | ||
| 952 | switch (r_typ) { | ||
| 953 | case R_MIPS_LO16: | ||
| 954 | r->r_addend = ((inst & 0xffff) ^ 0x8000) - 0x8000; | ||
| 955 | break; | ||
| 956 | case R_MIPS_26: | ||
| 957 | r->r_addend = (inst & 0x03ffffff) << 2; | ||
| 958 | break; | ||
| 959 | } | ||
| 960 | return 0; | ||
| 961 | } | ||
| 962 | |||
| 914 | /** | 963 | /** |
| 915 | * A module includes a number of sections that are discarded | 964 | * A module includes a number of sections that are discarded |
| 916 | * either when loaded or when used as built-in. | 965 | * either when loaded or when used as built-in. |
| @@ -954,8 +1003,11 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
| 954 | r.r_offset = TO_NATIVE(rela->r_offset); | 1003 | r.r_offset = TO_NATIVE(rela->r_offset); |
| 955 | #if KERNEL_ELFCLASS == ELFCLASS64 | 1004 | #if KERNEL_ELFCLASS == ELFCLASS64 |
| 956 | if (hdr->e_machine == EM_MIPS) { | 1005 | if (hdr->e_machine == EM_MIPS) { |
| 1006 | unsigned int r_typ; | ||
| 957 | r_sym = ELF64_MIPS_R_SYM(rela->r_info); | 1007 | r_sym = ELF64_MIPS_R_SYM(rela->r_info); |
| 958 | r_sym = TO_NATIVE(r_sym); | 1008 | r_sym = TO_NATIVE(r_sym); |
| 1009 | r_typ = ELF64_MIPS_R_TYPE(rela->r_info); | ||
| 1010 | r.r_info = ELF64_R_INFO(r_sym, r_typ); | ||
| 959 | } else { | 1011 | } else { |
| 960 | r.r_info = TO_NATIVE(rela->r_info); | 1012 | r.r_info = TO_NATIVE(rela->r_info); |
| 961 | r_sym = ELF_R_SYM(r.r_info); | 1013 | r_sym = ELF_R_SYM(r.r_info); |
| @@ -988,8 +1040,11 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
| 988 | r.r_offset = TO_NATIVE(rel->r_offset); | 1040 | r.r_offset = TO_NATIVE(rel->r_offset); |
| 989 | #if KERNEL_ELFCLASS == ELFCLASS64 | 1041 | #if KERNEL_ELFCLASS == ELFCLASS64 |
| 990 | if (hdr->e_machine == EM_MIPS) { | 1042 | if (hdr->e_machine == EM_MIPS) { |
| 1043 | unsigned int r_typ; | ||
| 991 | r_sym = ELF64_MIPS_R_SYM(rel->r_info); | 1044 | r_sym = ELF64_MIPS_R_SYM(rel->r_info); |
| 992 | r_sym = TO_NATIVE(r_sym); | 1045 | r_sym = TO_NATIVE(r_sym); |
| 1046 | r_typ = ELF64_MIPS_R_TYPE(rel->r_info); | ||
| 1047 | r.r_info = ELF64_R_INFO(r_sym, r_typ); | ||
| 993 | } else { | 1048 | } else { |
| 994 | r.r_info = TO_NATIVE(rel->r_info); | 1049 | r.r_info = TO_NATIVE(rel->r_info); |
| 995 | r_sym = ELF_R_SYM(r.r_info); | 1050 | r_sym = ELF_R_SYM(r.r_info); |
| @@ -999,6 +1054,14 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
| 999 | r_sym = ELF_R_SYM(r.r_info); | 1054 | r_sym = ELF_R_SYM(r.r_info); |
| 1000 | #endif | 1055 | #endif |
| 1001 | r.r_addend = 0; | 1056 | r.r_addend = 0; |
| 1057 | if (hdr->e_machine == EM_386) | ||
| 1058 | addend_386_rel(elf, i, &r); | ||
| 1059 | else if (hdr->e_machine == EM_ARM) | ||
| 1060 | addend_arm_rel(elf, i, &r); | ||
| 1061 | else if (hdr->e_machine == EM_MIPS) { | ||
| 1062 | if (addend_mips_rel(elf, i, &r)) | ||
| 1063 | continue; | ||
| 1064 | } | ||
| 1002 | sym = elf->symtab_start + r_sym; | 1065 | sym = elf->symtab_start + r_sym; |
| 1003 | /* Skip special sections */ | 1066 | /* Skip special sections */ |
| 1004 | if (sym->st_shndx >= SHN_LORESERVE) | 1067 | if (sym->st_shndx >= SHN_LORESERVE) |
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) |
diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c index 6873d5af80d5..d9cc6901d680 100644 --- a/scripts/mod/sumversion.c +++ b/scripts/mod/sumversion.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <ctype.h> | 7 | #include <ctype.h> |
| 8 | #include <errno.h> | 8 | #include <errno.h> |
| 9 | #include <string.h> | 9 | #include <string.h> |
| 10 | #include <limits.h> | ||
| 10 | #include "modpost.h" | 11 | #include "modpost.h" |
| 11 | 12 | ||
| 12 | /* | 13 | /* |
