diff options
Diffstat (limited to 'scripts/mod/modpost.c')
-rw-r--r-- | scripts/mod/modpost.c | 312 |
1 files changed, 185 insertions, 127 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 3645e980da71..04579a517900 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
@@ -75,7 +75,8 @@ static int is_vmlinux(const char *modname) | |||
75 | else | 75 | else |
76 | myname = modname; | 76 | myname = modname; |
77 | 77 | ||
78 | return strcmp(myname, "vmlinux") == 0; | 78 | return (strcmp(myname, "vmlinux") == 0) || |
79 | (strcmp(myname, "vmlinux.o") == 0); | ||
79 | } | 80 | } |
80 | 81 | ||
81 | void *do_nofail(void *ptr, const char *expr) | 82 | void *do_nofail(void *ptr, const char *expr) |
@@ -374,6 +375,7 @@ static int parse_elf(struct elf_info *info, const char *filename) | |||
374 | hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx); | 375 | hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx); |
375 | hdr->e_shnum = TO_NATIVE(hdr->e_shnum); | 376 | hdr->e_shnum = TO_NATIVE(hdr->e_shnum); |
376 | hdr->e_machine = TO_NATIVE(hdr->e_machine); | 377 | hdr->e_machine = TO_NATIVE(hdr->e_machine); |
378 | hdr->e_type = TO_NATIVE(hdr->e_type); | ||
377 | sechdrs = (void *)hdr + hdr->e_shoff; | 379 | sechdrs = (void *)hdr + hdr->e_shoff; |
378 | info->sechdrs = sechdrs; | 380 | info->sechdrs = sechdrs; |
379 | 381 | ||
@@ -384,6 +386,8 @@ static int parse_elf(struct elf_info *info, const char *filename) | |||
384 | sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size); | 386 | sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size); |
385 | sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link); | 387 | sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link); |
386 | sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name); | 388 | sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name); |
389 | sechdrs[i].sh_info = TO_NATIVE(sechdrs[i].sh_info); | ||
390 | sechdrs[i].sh_addr = TO_NATIVE(sechdrs[i].sh_addr); | ||
387 | } | 391 | } |
388 | /* Find symbol table. */ | 392 | /* Find symbol table. */ |
389 | for (i = 1; i < hdr->e_shnum; i++) { | 393 | for (i = 1; i < hdr->e_shnum; i++) { |
@@ -605,18 +609,14 @@ static int strrcmp(const char *s, const char *sub) | |||
605 | * warn here. | 609 | * warn here. |
606 | * the pattern is identified by: | 610 | * the pattern is identified by: |
607 | * tosec = .init.text | .exit.text | .init.data | 611 | * tosec = .init.text | .exit.text | .init.data |
608 | * fromsec = .data | 612 | * fromsec = .data | .data.rel | .data.rel.* |
609 | * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console | 613 | * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console, *_timer |
610 | * | 614 | * |
611 | * Pattern 3: | 615 | * 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 | 616 | * Whitelist all refereces from .text.head to .init.data |
617 | * Whitelist all refereces from .text.head to .init.text | 617 | * Whitelist all refereces from .text.head to .init.text |
618 | * | 618 | * |
619 | * Pattern 5: | 619 | * Pattern 4: |
620 | * Some symbols belong to init section but still it is ok to reference | 620 | * 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 | 621 | * 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 | 622 | * allocated for them and symbol address and value are same. So even |
@@ -625,26 +625,6 @@ static int strrcmp(const char *s, const char *sub) | |||
625 | * This pattern is identified by | 625 | * This pattern is identified by |
626 | * refsymname = __init_begin, _sinittext, _einittext | 626 | * refsymname = __init_begin, _sinittext, _einittext |
627 | * | 627 | * |
628 | * Pattern 7: | ||
629 | * Logos used in drivers/video/logo reside in __initdata but the | ||
630 | * funtion that references them are EXPORT_SYMBOL() so cannot be | ||
631 | * marker __init. So we whitelist them here. | ||
632 | * The pattern is: | ||
633 | * tosec = .init.data | ||
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 | **/ | 628 | **/ |
649 | static int secref_whitelist(const char *modname, const char *tosec, | 629 | static int secref_whitelist(const char *modname, const char *tosec, |
650 | const char *fromsec, const char *atsym, | 630 | const char *fromsec, const char *atsym, |
@@ -655,12 +635,12 @@ static int secref_whitelist(const char *modname, const char *tosec, | |||
655 | const char *pat2sym[] = { | 635 | const char *pat2sym[] = { |
656 | "driver", | 636 | "driver", |
657 | "_template", /* scsi uses *_template a lot */ | 637 | "_template", /* scsi uses *_template a lot */ |
638 | "_timer", /* arm uses ops structures named _timer a lot */ | ||
658 | "_sht", /* scsi also used *_sht to some extent */ | 639 | "_sht", /* scsi also used *_sht to some extent */ |
659 | "_ops", | 640 | "_ops", |
660 | "_probe", | 641 | "_probe", |
661 | "_probe_one", | 642 | "_probe_one", |
662 | "_console", | 643 | "_console", |
663 | "apic_es7000", | ||
664 | NULL | 644 | NULL |
665 | }; | 645 | }; |
666 | 646 | ||
@@ -692,7 +672,9 @@ static int secref_whitelist(const char *modname, const char *tosec, | |||
692 | (strcmp(tosec, ".exit.text") != 0) && | 672 | (strcmp(tosec, ".exit.text") != 0) && |
693 | (strcmp(tosec, ".init.data") != 0)) | 673 | (strcmp(tosec, ".init.data") != 0)) |
694 | f2 = 0; | 674 | f2 = 0; |
695 | if (strcmp(fromsec, ".data") != 0) | 675 | if ((strcmp(fromsec, ".data") != 0) && |
676 | (strcmp(fromsec, ".data.rel") != 0) && | ||
677 | (strncmp(fromsec, ".data.rel.", strlen(".data.rel.")) != 0)) | ||
696 | f2 = 0; | 678 | f2 = 0; |
697 | 679 | ||
698 | for (s = pat2sym; *s; s++) | 680 | for (s = pat2sym; *s; s++) |
@@ -702,37 +684,16 @@ static int secref_whitelist(const char *modname, const char *tosec, | |||
702 | return 1; | 684 | return 1; |
703 | 685 | ||
704 | /* Check for pattern 3 */ | 686 | /* 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) && | 687 | if ((strcmp(fromsec, ".text.head") == 0) && |
711 | ((strcmp(tosec, ".init.data") == 0) || | 688 | ((strcmp(tosec, ".init.data") == 0) || |
712 | (strcmp(tosec, ".init.text") == 0))) | 689 | (strcmp(tosec, ".init.text") == 0))) |
713 | return 1; | 690 | return 1; |
714 | 691 | ||
715 | /* Check for pattern 5 */ | 692 | /* Check for pattern 4 */ |
716 | for (s = pat3refsym; *s; s++) | 693 | for (s = pat3refsym; *s; s++) |
717 | if (strcmp(refsymname, *s) == 0) | 694 | if (strcmp(refsymname, *s) == 0) |
718 | return 1; | 695 | return 1; |
719 | 696 | ||
720 | /* Check for pattern 7 */ | ||
721 | if ((strcmp(tosec, ".init.data") == 0) && | ||
722 | (strncmp(fromsec, ".text", strlen(".text")) == 0) && | ||
723 | (strncmp(refsymname, "logo_", strlen("logo_")) == 0)) | ||
724 | return 1; | ||
725 | |||
726 | /* Check for pattern 8 */ | ||
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; | ||
735 | |||
736 | return 0; | 697 | return 0; |
737 | } | 698 | } |
738 | 699 | ||
@@ -753,6 +714,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++) { | 714 | for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { |
754 | if (sym->st_shndx != relsym->st_shndx) | 715 | if (sym->st_shndx != relsym->st_shndx) |
755 | continue; | 716 | continue; |
717 | if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) | ||
718 | continue; | ||
756 | if (sym->st_value == addr) | 719 | if (sym->st_value == addr) |
757 | return sym; | 720 | return sym; |
758 | } | 721 | } |
@@ -864,11 +827,6 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec, | |||
864 | elf->strtab + before->st_name, refsymname)) | 827 | elf->strtab + before->st_name, refsymname)) |
865 | return; | 828 | return; |
866 | 829 | ||
867 | /* fromsec whitelist - without a valid 'before' | ||
868 | * powerpc has a GOT table in .got2 section */ | ||
869 | if (strcmp(fromsec, ".got2") == 0) | ||
870 | return; | ||
871 | |||
872 | if (before && after) { | 830 | if (before && after) { |
873 | warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " | 831 | warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " |
874 | "(between '%s' and '%s')\n", | 832 | "(between '%s' and '%s')\n", |
@@ -895,6 +853,78 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec, | |||
895 | } | 853 | } |
896 | } | 854 | } |
897 | 855 | ||
856 | static unsigned int *reloc_location(struct elf_info *elf, | ||
857 | int rsection, Elf_Rela *r) | ||
858 | { | ||
859 | Elf_Shdr *sechdrs = elf->sechdrs; | ||
860 | int section = sechdrs[rsection].sh_info; | ||
861 | |||
862 | return (void *)elf->hdr + sechdrs[section].sh_offset + | ||
863 | (r->r_offset - sechdrs[section].sh_addr); | ||
864 | } | ||
865 | |||
866 | static int addend_386_rel(struct elf_info *elf, int rsection, Elf_Rela *r) | ||
867 | { | ||
868 | unsigned int r_typ = ELF_R_TYPE(r->r_info); | ||
869 | unsigned int *location = reloc_location(elf, rsection, r); | ||
870 | |||
871 | switch (r_typ) { | ||
872 | case R_386_32: | ||
873 | r->r_addend = TO_NATIVE(*location); | ||
874 | break; | ||
875 | case R_386_PC32: | ||
876 | r->r_addend = TO_NATIVE(*location) + 4; | ||
877 | /* For CONFIG_RELOCATABLE=y */ | ||
878 | if (elf->hdr->e_type == ET_EXEC) | ||
879 | r->r_addend += r->r_offset; | ||
880 | break; | ||
881 | } | ||
882 | return 0; | ||
883 | } | ||
884 | |||
885 | static int addend_arm_rel(struct elf_info *elf, int rsection, Elf_Rela *r) | ||
886 | { | ||
887 | unsigned int r_typ = ELF_R_TYPE(r->r_info); | ||
888 | |||
889 | switch (r_typ) { | ||
890 | case R_ARM_ABS32: | ||
891 | /* From ARM ABI: (S + A) | T */ | ||
892 | r->r_addend = (int)(long)(elf->symtab_start + ELF_R_SYM(r->r_info)); | ||
893 | break; | ||
894 | case R_ARM_PC24: | ||
895 | /* From ARM ABI: ((S + A) | T) - P */ | ||
896 | r->r_addend = (int)(long)(elf->hdr + elf->sechdrs[rsection].sh_offset + | ||
897 | (r->r_offset - elf->sechdrs[rsection].sh_addr)); | ||
898 | break; | ||
899 | default: | ||
900 | return 1; | ||
901 | } | ||
902 | return 0; | ||
903 | } | ||
904 | |||
905 | static int addend_mips_rel(struct elf_info *elf, int rsection, Elf_Rela *r) | ||
906 | { | ||
907 | unsigned int r_typ = ELF_R_TYPE(r->r_info); | ||
908 | unsigned int *location = reloc_location(elf, rsection, r); | ||
909 | unsigned int inst; | ||
910 | |||
911 | if (r_typ == R_MIPS_HI16) | ||
912 | return 1; /* skip this */ | ||
913 | inst = TO_NATIVE(*location); | ||
914 | switch (r_typ) { | ||
915 | case R_MIPS_LO16: | ||
916 | r->r_addend = inst & 0xffff; | ||
917 | break; | ||
918 | case R_MIPS_26: | ||
919 | r->r_addend = (inst & 0x03ffffff) << 2; | ||
920 | break; | ||
921 | case R_MIPS_32: | ||
922 | r->r_addend = inst; | ||
923 | break; | ||
924 | } | ||
925 | return 0; | ||
926 | } | ||
927 | |||
898 | /** | 928 | /** |
899 | * A module includes a number of sections that are discarded | 929 | * A module includes a number of sections that are discarded |
900 | * either when loaded or when used as built-in. | 930 | * either when loaded or when used as built-in. |
@@ -938,8 +968,11 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
938 | r.r_offset = TO_NATIVE(rela->r_offset); | 968 | r.r_offset = TO_NATIVE(rela->r_offset); |
939 | #if KERNEL_ELFCLASS == ELFCLASS64 | 969 | #if KERNEL_ELFCLASS == ELFCLASS64 |
940 | if (hdr->e_machine == EM_MIPS) { | 970 | if (hdr->e_machine == EM_MIPS) { |
971 | unsigned int r_typ; | ||
941 | r_sym = ELF64_MIPS_R_SYM(rela->r_info); | 972 | r_sym = ELF64_MIPS_R_SYM(rela->r_info); |
942 | r_sym = TO_NATIVE(r_sym); | 973 | r_sym = TO_NATIVE(r_sym); |
974 | r_typ = ELF64_MIPS_R_TYPE(rela->r_info); | ||
975 | r.r_info = ELF64_R_INFO(r_sym, r_typ); | ||
943 | } else { | 976 | } else { |
944 | r.r_info = TO_NATIVE(rela->r_info); | 977 | r.r_info = TO_NATIVE(rela->r_info); |
945 | r_sym = ELF_R_SYM(r.r_info); | 978 | r_sym = ELF_R_SYM(r.r_info); |
@@ -972,8 +1005,11 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
972 | r.r_offset = TO_NATIVE(rel->r_offset); | 1005 | r.r_offset = TO_NATIVE(rel->r_offset); |
973 | #if KERNEL_ELFCLASS == ELFCLASS64 | 1006 | #if KERNEL_ELFCLASS == ELFCLASS64 |
974 | if (hdr->e_machine == EM_MIPS) { | 1007 | if (hdr->e_machine == EM_MIPS) { |
1008 | unsigned int r_typ; | ||
975 | r_sym = ELF64_MIPS_R_SYM(rel->r_info); | 1009 | r_sym = ELF64_MIPS_R_SYM(rel->r_info); |
976 | r_sym = TO_NATIVE(r_sym); | 1010 | r_sym = TO_NATIVE(r_sym); |
1011 | r_typ = ELF64_MIPS_R_TYPE(rel->r_info); | ||
1012 | r.r_info = ELF64_R_INFO(r_sym, r_typ); | ||
977 | } else { | 1013 | } else { |
978 | r.r_info = TO_NATIVE(rel->r_info); | 1014 | r.r_info = TO_NATIVE(rel->r_info); |
979 | r_sym = ELF_R_SYM(r.r_info); | 1015 | r_sym = ELF_R_SYM(r.r_info); |
@@ -983,6 +1019,20 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
983 | r_sym = ELF_R_SYM(r.r_info); | 1019 | r_sym = ELF_R_SYM(r.r_info); |
984 | #endif | 1020 | #endif |
985 | r.r_addend = 0; | 1021 | r.r_addend = 0; |
1022 | switch (hdr->e_machine) { | ||
1023 | case EM_386: | ||
1024 | if (addend_386_rel(elf, i, &r)) | ||
1025 | continue; | ||
1026 | break; | ||
1027 | case EM_ARM: | ||
1028 | if(addend_arm_rel(elf, i, &r)) | ||
1029 | continue; | ||
1030 | break; | ||
1031 | case EM_MIPS: | ||
1032 | if (addend_mips_rel(elf, i, &r)) | ||
1033 | continue; | ||
1034 | break; | ||
1035 | } | ||
986 | sym = elf->symtab_start + r_sym; | 1036 | sym = elf->symtab_start + r_sym; |
987 | /* Skip special sections */ | 1037 | /* Skip special sections */ |
988 | if (sym->st_shndx >= SHN_LORESERVE) | 1038 | if (sym->st_shndx >= SHN_LORESERVE) |
@@ -998,6 +1048,63 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
998 | } | 1048 | } |
999 | } | 1049 | } |
1000 | 1050 | ||
1051 | /* | ||
1052 | * Identify sections from which references to either a | ||
1053 | * .init or a .exit section is OK. | ||
1054 | * | ||
1055 | * [OPD] Keith Ownes <kaos@sgi.com> commented: | ||
1056 | * For our future {in}sanity, add a comment that this is the ppc .opd | ||
1057 | * section, not the ia64 .opd section. | ||
1058 | * ia64 .opd should not point to discarded sections. | ||
1059 | * [.rodata] like for .init.text we ignore .rodata references -same reason | ||
1060 | */ | ||
1061 | static int initexit_section_ref_ok(const char *name) | ||
1062 | { | ||
1063 | const char **s; | ||
1064 | /* Absolute section names */ | ||
1065 | const char *namelist1[] = { | ||
1066 | "__bug_table", /* used by powerpc for BUG() */ | ||
1067 | "__ex_table", | ||
1068 | ".altinstructions", | ||
1069 | ".cranges", /* used by sh64 */ | ||
1070 | ".fixup", | ||
1071 | ".machvec", /* ia64 + powerpc uses these */ | ||
1072 | ".machine.desc", | ||
1073 | ".opd", /* See comment [OPD] */ | ||
1074 | ".parainstructions", | ||
1075 | ".pdr", | ||
1076 | ".plt", /* seen on ARCH=um build on x86_64. Harmless */ | ||
1077 | ".smp_locks", | ||
1078 | ".stab", | ||
1079 | NULL | ||
1080 | }; | ||
1081 | /* Start of section names */ | ||
1082 | const char *namelist2[] = { | ||
1083 | ".debug", | ||
1084 | ".eh_frame", | ||
1085 | ".note", /* ignore ELF notes - may contain anything */ | ||
1086 | ".got", /* powerpc - global offset table */ | ||
1087 | ".toc", /* powerpc - table of contents */ | ||
1088 | NULL | ||
1089 | }; | ||
1090 | /* part of section name */ | ||
1091 | const char *namelist3 [] = { | ||
1092 | ".unwind", /* Sample: IA_64.unwind.exit.text */ | ||
1093 | NULL | ||
1094 | }; | ||
1095 | |||
1096 | for (s = namelist1; *s; s++) | ||
1097 | if (strcmp(*s, name) == 0) | ||
1098 | return 1; | ||
1099 | for (s = namelist2; *s; s++) | ||
1100 | if (strncmp(*s, name, strlen(*s)) == 0) | ||
1101 | return 1; | ||
1102 | for (s = namelist3; *s; s++) | ||
1103 | if (strstr(name, *s) != NULL) | ||
1104 | return 1; | ||
1105 | return 0; | ||
1106 | } | ||
1107 | |||
1001 | /** | 1108 | /** |
1002 | * Functions used only during module init is marked __init and is stored in | 1109 | * Functions used only during module init is marked __init and is stored in |
1003 | * a .init.text section. Likewise data is marked __initdata and stored in | 1110 | * a .init.text section. Likewise data is marked __initdata and stored in |
@@ -1014,7 +1121,7 @@ static int init_section(const char *name) | |||
1014 | return 0; | 1121 | return 0; |
1015 | } | 1122 | } |
1016 | 1123 | ||
1017 | /** | 1124 | /* |
1018 | * Identify sections from which references to a .init section is OK. | 1125 | * Identify sections from which references to a .init section is OK. |
1019 | * | 1126 | * |
1020 | * Unfortunately references to read only data that referenced .init | 1127 | * Unfortunately references to read only data that referenced .init |
@@ -1028,48 +1135,31 @@ static int init_section(const char *name) | |||
1028 | * | 1135 | * |
1029 | * where vgacon_startup is __init. If you want to wade through the false | 1136 | * where vgacon_startup is __init. If you want to wade through the false |
1030 | * positives, take out the check for rodata. | 1137 | * positives, take out the check for rodata. |
1031 | **/ | 1138 | */ |
1032 | static int init_section_ref_ok(const char *name) | 1139 | static int init_section_ref_ok(const char *name) |
1033 | { | 1140 | { |
1034 | const char **s; | 1141 | const char **s; |
1035 | /* Absolute section names */ | 1142 | /* Absolute section names */ |
1036 | const char *namelist1[] = { | 1143 | const char *namelist1[] = { |
1037 | ".init", | 1144 | "__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 */ | 1145 | "__ftr_fixup", /* powerpc cpu feature fixup */ |
1054 | "__fw_ftr_fixup", /* powerpc firmware feature fixup */ | 1146 | "__fw_ftr_fixup", /* powerpc firmware feature fixup */ |
1055 | ".cranges", /* used by sh64 */ | 1147 | "__param", |
1148 | ".data.rel.ro", /* used by parisc64 */ | ||
1149 | ".init", | ||
1150 | ".text.lock", | ||
1056 | NULL | 1151 | NULL |
1057 | }; | 1152 | }; |
1058 | /* Start of section names */ | 1153 | /* Start of section names */ |
1059 | const char *namelist2[] = { | 1154 | const char *namelist2[] = { |
1060 | ".init.", | 1155 | ".init.", |
1061 | ".altinstructions", | 1156 | ".pci_fixup", |
1062 | ".eh_frame", | ||
1063 | ".debug", | ||
1064 | ".parainstructions", | ||
1065 | ".rodata", | 1157 | ".rodata", |
1066 | NULL | 1158 | NULL |
1067 | }; | 1159 | }; |
1068 | /* part of section name */ | 1160 | |
1069 | const char *namelist3 [] = { | 1161 | if (initexit_section_ref_ok(name)) |
1070 | ".unwind", /* sample: IA_64.unwind.init.text */ | 1162 | return 1; |
1071 | NULL | ||
1072 | }; | ||
1073 | 1163 | ||
1074 | for (s = namelist1; *s; s++) | 1164 | for (s = namelist1; *s; s++) |
1075 | if (strcmp(*s, name) == 0) | 1165 | if (strcmp(*s, name) == 0) |
@@ -1077,9 +1167,10 @@ static int init_section_ref_ok(const char *name) | |||
1077 | for (s = namelist2; *s; s++) | 1167 | for (s = namelist2; *s; s++) |
1078 | if (strncmp(*s, name, strlen(*s)) == 0) | 1168 | if (strncmp(*s, name, strlen(*s)) == 0) |
1079 | return 1; | 1169 | return 1; |
1080 | for (s = namelist3; *s; s++) | 1170 | |
1081 | if (strstr(name, *s) != NULL) | 1171 | /* If section name ends with ".init" we allow references |
1082 | return 1; | 1172 | * as is the case with .initcallN.init, .early_param.init, .taglist.init etc |
1173 | */ | ||
1083 | if (strrcmp(name, ".init") == 0) | 1174 | if (strrcmp(name, ".init") == 0) |
1084 | return 1; | 1175 | return 1; |
1085 | return 0; | 1176 | return 0; |
@@ -1104,58 +1195,25 @@ static int exit_section(const char *name) | |||
1104 | 1195 | ||
1105 | /* | 1196 | /* |
1106 | * Identify sections from which references to a .exit section is OK. | 1197 | * Identify sections from which references to a .exit section is OK. |
1107 | * | 1198 | */ |
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) | 1199 | static int exit_section_ref_ok(const char *name) |
1115 | { | 1200 | { |
1116 | const char **s; | 1201 | const char **s; |
1117 | /* Absolute section names */ | 1202 | /* Absolute section names */ |
1118 | const char *namelist1[] = { | 1203 | const char *namelist1[] = { |
1119 | ".exit.text", | ||
1120 | ".exit.data", | 1204 | ".exit.data", |
1121 | ".init.text", | 1205 | ".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", | 1206 | ".exitcall.exit", |
1129 | ".eh_frame", | 1207 | ".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 | 1208 | NULL |
1148 | }; | 1209 | }; |
1149 | 1210 | ||
1211 | if (initexit_section_ref_ok(name)) | ||
1212 | return 1; | ||
1213 | |||
1150 | for (s = namelist1; *s; s++) | 1214 | for (s = namelist1; *s; s++) |
1151 | if (strcmp(*s, name) == 0) | 1215 | if (strcmp(*s, name) == 0) |
1152 | return 1; | 1216 | 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; | 1217 | return 0; |
1160 | } | 1218 | } |
1161 | 1219 | ||